Last active
December 8, 2020 13:15
-
-
Save MasterQ32/46ffd78a6cf261c73a1fddb93a478ebe to your computer and use it in GitHub Desktop.
Getting started with SDL2 sound generation: Simple sine wave synth with moving the freq up and down
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SDL.h> | |
#include "stb_vorbis.h" | |
short audiodata[4096]; | |
volatile bool needsData = true; // poor mans semaphore | |
void callback(void* userdata, Uint8* stream, int len) | |
{ | |
printf("%p,%d\n", stream, len); | |
while(needsData); // yay | |
short * snd = reinterpret_cast<short*>(stream); | |
len /= sizeof(*snd); | |
for(int i = 0; i < len; i++) | |
{ | |
snd[i] = audiodata[i]; | |
} | |
needsData = true; | |
} | |
int main(int argc, char ** argv) | |
{ | |
SDL_Init(SDL_INIT_AUDIO); | |
// the specs of our piece of music | |
// this MUST match the ogg file we're playing, | |
// we don't do bitrate conversions | |
SDL_AudioSpec spec, aspec; | |
SDL_zero(spec); | |
spec.freq = 44100; | |
spec.format = AUDIO_S16SYS; | |
spec.channels = 1; | |
spec.samples = 4096; | |
spec.callback = callback; | |
spec.userdata = NULL; | |
int id; | |
if ((id = SDL_OpenAudioDevice(nullptr, 0, &spec, &aspec, SDL_AUDIO_ALLOW_ANY_CHANGE)) <= 0 ) | |
{ | |
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); | |
exit(-1); | |
} | |
printf("freq = %d\n", aspec.freq); | |
printf("chan = %d\n", aspec.channels); | |
printf("samp = %d\n", aspec.samples); | |
printf("fmt = %d\n", aspec.format); | |
printf("dev = %d\n", id); | |
stb_vorbis * ogg = stb_vorbis_open_filename( | |
"music.ogg", //const char *filename, | |
nullptr, // int *error, | |
nullptr // const stb_vorbis_alloc *alloc_buffer | |
); | |
if(!ogg) | |
return 1; | |
stb_vorbis_info info = stb_vorbis_get_info(ogg); | |
printf("freq = %d\n", info.sample_rate); | |
printf("chan = %d\n", info.channels); | |
stb_vorbis_seek(ogg, 0); | |
unsigned int len = stb_vorbis_stream_length_in_samples(ogg); | |
/* Start playing */ | |
SDL_PauseAudioDevice(id, 0); | |
while(true) | |
{ | |
if(needsData) | |
{ | |
short * data[] = { audiodata }; | |
memset(audiodata, 0, sizeof(audiodata)); | |
len = stb_vorbis_get_samples_short( | |
ogg, // stb_vorbis *f, | |
1, // int channels, | |
data, | |
4096); | |
needsData = false; | |
if(len == 0) | |
break; | |
} | |
} | |
stb_vorbis_close(ogg); | |
SDL_Quit(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SDL.h> | |
#include "stb_vorbis.h" | |
#define PI2 6.28318530718 | |
float time = 0; | |
float freq = 440; | |
void callback(void* userdata, Uint8* stream, int len) | |
{ | |
printf("%p,%d\n", stream, len); | |
short * snd = reinterpret_cast<short*>(stream); | |
len /= sizeof(*snd); | |
for(int i = 0; i < len; i++) | |
{ | |
snd[i] = 32000 * sin(time); | |
time += freq * PI2 / 48000.0; | |
if(time >= PI2) | |
time -= PI2; | |
} | |
} | |
int main(int argc, char ** argv) | |
{ | |
SDL_Init(SDL_INIT_AUDIO); | |
for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i) { | |
const char* driver_name = SDL_GetAudioDriver(i); | |
printf("[%d] %s\n", i, driver_name); | |
} | |
int devs = SDL_GetNumAudioDevices(0); | |
for(int i = 0; i < devs; i++) | |
{ | |
printf("[%d] %s\n", i, SDL_GetAudioDeviceName(i,0)); | |
} | |
SDL_AudioSpec spec, aspec; // the specs of our piece of "music" | |
SDL_zero(spec); | |
spec.freq = 48000; | |
spec.format = AUDIO_S16SYS; | |
spec.channels = 1; | |
spec.samples = 4096; | |
spec.callback = callback; | |
spec.userdata = NULL; | |
int id; | |
if ((id = SDL_OpenAudioDevice(nullptr, 0, &spec, &aspec, SDL_AUDIO_ALLOW_ANY_CHANGE)) <= 0 ) | |
{ | |
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); | |
exit(-1); | |
} | |
printf("freq = %d\n", aspec.freq); | |
printf("chan = %d\n", aspec.channels); | |
printf("samp = %d\n", aspec.samples); | |
printf("fmt = %d\n", aspec.format); | |
printf("dev = %d\n", id); | |
/* Start playing */ | |
SDL_PauseAudioDevice(id, 0); | |
while(true) | |
{ | |
for(freq = 440; freq < 880; freq += 10) | |
SDL_Delay(10); | |
for(freq = 870; freq > 450; freq -= 10) | |
SDL_Delay(10); | |
} | |
SDL_Quit(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment