Skip to content

Instantly share code, notes, and snippets.

@MasterQ32
Last active December 8, 2020 13:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterQ32/46ffd78a6cf261c73a1fddb93a478ebe to your computer and use it in GitHub Desktop.
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
#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();
}
#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