Added some small boring scripts and programs writen in few last years
[mirrors/Programs.git] / c / sampler / sdl.c
1 /* Ghetto Sound - Sampler
2 * by: Harvie 2o1o
3 *
4 * TODO:
5 * - port unbuffered getchar to windows
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <termio.h>
13 #include "SDL.h"
14 #include "SDL_mixer.h"
15 //Docs: http://www.libsdl.org/projects/SDL_mixer/docs/
16 //example http://www.kekkai.org/roger/sdl/mixer/
17
18 static struct termios stored_settings;
19 void tc_reset() { tcsetattr(0,TCSANOW,&stored_settings); }
20 void icanon_off() {
21 struct termios new_settings;
22 tcgetattr(0,&stored_settings);
23 new_settings = stored_settings;
24 new_settings.c_lflag &= (~ICANON);
25 new_settings.c_lflag &= (~ECHO);
26 new_settings.c_cc[VTIME] = 0;
27 new_settings.c_cc[VMIN] = 1;
28 tcsetattr(0,TCSANOW,&new_settings);
29 atexit(tc_reset);
30 }
31
32 /*char gethit() {
33 icanon_off();
34 char c = getchar();
35 tc_reset();
36 return c;
37 }*/
38
39 Mix_Chunk **sample = NULL;
40 int samplec = 0;
41
42 void cleanUp() {
43 int i;
44 for(i=0;i<samplec;i++) { Mix_FreeChunk(sample[i]); }
45 Mix_CloseAudio();
46 SDL_Quit();
47 }
48
49 char *keymap = "xcvbnmasdfghjklwertuiop789456123zy";
50 int i;
51 int main(int argc, char* argv[]) {
52 if(argc == 1) {
53 printf("\n\tUsage:\t%s *.wav *.ogg [...]\n", argv[0]);
54 printf("\t\t%s --keys 7894561230 *.wav *.ogg [...] #to use own key-bindings\n", argv[0]);
55 puts("\t\t- lowercase: play sample once; uppercase: loop sample;");
56 puts("");
57 puts("\t- currently supported formats: WAVE, AIFF, RIFF, OGG(libvorbis), VOC, MOD(libmikmod), MIDI, MP3(smpeg)");
58 puts("\t- currently there are issues with mp3s - you should convert it:");
59 puts("\t\t- mp3 to wav: ffmpeg -i in.mp3 out.wav");
60 puts("\t\t- mp3 to ogg: ffmpeg -i in.mp3 -acodec vorbis -ac 2 -aq 60 out.ogg");
61 puts("");
62 exit(-1);
63 }
64
65 //Init SDL:
66 if(SDL_Init(SDL_INIT_AUDIO)) {
67 perror("Cannot initialize SDL using SDL_Init!\n");
68 exit(1);
69 }
70 atexit(cleanUp);
71 //Open audio
72 if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 256)) { //sampl.freq(def22050), format, 2stereo/1mono, chunksize(default 4095)
73 perror("Cannot open audio using Mix_OpenAudio!\n");
74 exit(2);
75 }
76 //alloc enough mixer channels
77 Mix_AllocateChannels(argc*2);
78 //set volume
79 Mix_Volume(-1,MIX_MAX_VOLUME/2);
80
81 //alloc enough samples
82 sample = malloc(sizeof(Mix_Chunk)*argc);
83 samplec = 0;
84
85
86 i = 1;
87 argv++; argc--; //get rid of argv[0]
88 while(argc) { //loop through args (load samples and parse options)
89 if(!strcmp(argv[0], "--keys")) { //alternative keymap
90 if(samplec > 0) {
91 puts("\nERR: Cannot specify keys after loading first sample!");
92 break;
93 }
94 if(--argc) { argv++; }
95 else { break; }
96 keymap = argv[0];
97 argv++; argc--; continue;
98 }
99 if(samplec < strlen(keymap)) {
100 sample[samplec] = Mix_LoadWAV(argv[0]);
101 if(sample[samplec]) {
102 printf("[%c]: %s%c", keymap[samplec], argv[0], (samplec+1)%4==0?'\n':'\t');
103 samplec++;
104 } else {
105 printf("\nERR: Mix_LoadWAV(%s): %s\n", argv[0], Mix_GetError());
106 }
107 } else {
108 if(i) puts("\nERR: Not enough keys on keyboard (or in keymap)!");
109 i = 0;
110 }
111
112 argv++; argc--;
113 }
114 puts("");
115
116 //Main loop:
117 puts("[Q]: exit!\t[SPACE]: silence!\t[ENTER]: delay\t[-]: halucination");
118 int keymaplen = strlen(keymap);
119 //freopen("test.seq", "r", stdin);
120
121 icanon_off();
122 char c; while(c = getchar()) {
123 //lowercase: play sample once
124 for(i=0;i<keymaplen && i < samplec;i++) if(c == keymap[i]) {
125 if(Mix_PlayChannel(samplec+i, sample[i], 0) == -1) printf("ERR: Mix_PlayChannel(sample #%d): %s\n", i, Mix_GetError());
126 }
127 //uppercase: start/stop loop
128 for(i=0;i<keymaplen && i < samplec;i++) if(c == keymap[i]-'a'+'A') {
129 if(Mix_Playing(i)) {
130 Mix_HaltChannel(i);
131 } else {
132 if(Mix_PlayChannel(i, sample[i], -1) == -1) printf("ERR: Mix_PlayChannel(sample #%d, loop): %s\n", i, Mix_GetError());
133 }
134 }
135 if(c == ' ') Mix_HaltChannel(-1);
136 if(c == '\n') sleep(1);
137 if(c == '#') while(getchar() != '\n');
138 if(c == '?') while(Mix_Playing(-1)) usleep(1000);
139 if(c == '}') rewind(stdin);
140 if(c == 'Q' || c == 'q') break;
141 if(c == '-') for(i=360;i>=0;i--) { //halucination
142 Mix_SetPosition(MIX_CHANNEL_POST, i, 0);
143 usleep(2000);
144 }
145 }
146
147 exit(0);
148 }
149
This page took 0.314456 seconds and 4 git commands to generate.