#include #include #include #include #define CHUNK_SIZE 4096 #if 1 #define FLANGER_BUFFER_SIZE 88200 #else #define FLANGER_BUFFER_SIZE 2000 #endif void handle_exit(void) { Mix_Quit(); SDL_Quit(); puts("Shutdown complete."); } static struct flanger { int samples; int frequency; int start_ms, stop_ms; int cur_delay; int sweep_dir; int sweep_speed; Sint16 buf[FLANGER_BUFFER_SIZE]; } flange_chan; /* Perform flanging effect */ void flanger_func(int chan, void *stream, int len, void *udata) { int i; Sint16 *sbuf = stream; struct flanger *flanger = udata; int local_len = len / sizeof(Sint16); /*printf("Samples: %d, Local Len: %d, Len: %d\n", flanger->samples, local_len, len);*/ for (i = 0; i < local_len; i++) { flanger->buf[(flanger->samples + i) % FLANGER_BUFFER_SIZE] = sbuf[i]; sbuf[i] = sbuf[i] / 2 + flanger->buf[(flanger->samples + (FLANGER_BUFFER_SIZE - flanger->cur_delay / 1000 * 2) + i) % FLANGER_BUFFER_SIZE] / 2; if (!(i%2)) { if (flanger->cur_delay >= flanger->frequency / (1000 / flanger->stop_ms) * 1000) { flanger->sweep_dir = -flanger->sweep_speed; } else if (flanger->cur_delay <= flanger->frequency / (1000 / flanger->start_ms) * 1000) { flanger->sweep_dir = flanger->sweep_speed; } flanger->cur_delay += flanger->sweep_dir; } /*sbuf[i] = 0;*/ } flanger->samples = (flanger->samples + local_len) % FLANGER_BUFFER_SIZE; return; } int main(int argc, char *argv[]) { char *mp3_file; Mix_Music *mp3_stream; /* Audio settings */ int frequency = 44100; Uint16 format = AUDIO_S16; int channels = 2; if (argc != 2) { printf("Usage %s: \n", argv[0]); return EXIT_SUCCESS; } mp3_file = argv[1]; /* Setup shutdown sequence */ atexit(handle_exit); /* Setup SDL & friends */ SDL_Init(SDL_INIT_AUDIO); Mix_Init(MIX_INIT_MP3); /* Open audio */ if (Mix_OpenAudio(frequency, format, channels, CHUNK_SIZE)) { printf("Mix_OpenAudio failed: %s\n", Mix_GetError()); /* Mix_FreeMusic(mp3_stream); */ return EXIT_FAILURE; } /* Verify audio compatibility */ Mix_QuerySpec(&frequency, &format, &channels); printf("Device settings are: %d, %hd, %d\n", frequency, format, channels); if (format != AUDIO_S16) { puts("Selected device format incompatible :-(\n"); return EXIT_FAILURE; } /* Load MP3 file */ mp3_stream = Mix_LoadMUS(mp3_file); if (!mp3_stream) { printf("Mix_LoadMUS failed: %s\n", Mix_GetError()); return EXIT_FAILURE; } /* Setup flangers */ memset(flange_chan.buf, 0x0, sizeof(short) * FLANGER_BUFFER_SIZE); flange_chan.frequency = frequency; flange_chan.samples = 0; flange_chan.start_ms = 1; flange_chan.stop_ms = 20; flange_chan.sweep_speed = 5; flange_chan.cur_delay = 0; flange_chan.sweep_dir = 1; if (!Mix_RegisterEffect(MIX_CHANNEL_POST, flanger_func, NULL, &flange_chan)) { printf("Mix_RegisterEffect failed: %s\n", Mix_GetError()); return EXIT_FAILURE; } /* Start playback */ if (Mix_PlayMusic(mp3_stream, 0) < 0) { printf("Mix_PlayMusic failed: %s\n", Mix_GetError()); Mix_FreeMusic(mp3_stream); return EXIT_FAILURE; } while (Mix_PlayingMusic()) SDL_Delay(100); return EXIT_SUCCESS; }