diff --git a/cpp/Makefile b/cpp/Makefile new file mode 100644 index 0000000..0ad0c17 --- /dev/null +++ b/cpp/Makefile @@ -0,0 +1,12 @@ +.PHONY: clean bundle + +CC=g++ +generator: main.cpp + $(CC) -o generator `sdl-config --cflags --libs` main.cpp + +bundle: generator + sh makeAppBundle + +clean: + $(RM) generator + diff --git a/cpp/generator b/cpp/generator new file mode 100755 index 0000000..c2315d2 Binary files /dev/null and b/cpp/generator differ diff --git a/cpp/main.cpp b/cpp/main.cpp new file mode 100644 index 0000000..525ef70 --- /dev/null +++ b/cpp/main.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include + +const int AMPLITUDE = 28000; +const int FREQUENCY = 44100; + +struct BeepObject +{ + double freq; + int samplesLeft; +}; + +class Beeper +{ +private: + double v; + std::queue beeps; +public: + Beeper(); + ~Beeper(); + void beep(double freq, int duration); + void generateSamples(Sint16 *stream, int length); + void wait(); +}; + +void audio_callback(void*, Uint8*, int); + +Beeper::Beeper() +{ + SDL_AudioSpec desiredSpec; + + desiredSpec.freq = FREQUENCY; + desiredSpec.format = AUDIO_S16SYS; + desiredSpec.channels = 1; + desiredSpec.samples = 2048; + desiredSpec.callback = audio_callback; + desiredSpec.userdata = this; + + SDL_AudioSpec obtainedSpec; + + // you might want to look for errors here + SDL_OpenAudio(&desiredSpec, &obtainedSpec); + + // start play audio + SDL_PauseAudio(0); +} + +Beeper::~Beeper() +{ + SDL_CloseAudio(); +} + +void Beeper::generateSamples(Sint16 *stream, int length) +{ + int i = 0; + while (i < length) { + + if (beeps.empty()) { + while (i < length) { + stream[i] = 0; + i++; + } + return; + } + BeepObject& bo = beeps.front(); + + int samplesToDo = std::min(i + bo.samplesLeft, length); + bo.samplesLeft -= samplesToDo - i; + + while (i < samplesToDo) { + stream[i] = AMPLITUDE * std::sin(v * 2 * M_PI / FREQUENCY); + i++; + v += bo.freq; + } + + if (bo.samplesLeft == 0) { + beeps.pop(); + } + } +} + +void Beeper::beep(double freq, int duration) +{ + BeepObject bo; + bo.freq = freq; + bo.samplesLeft = duration * FREQUENCY / 1000; + + SDL_LockAudio(); + beeps.push(bo); + SDL_UnlockAudio(); +} + +void Beeper::wait() +{ + int size; + do { + SDL_Delay(20); + SDL_LockAudio(); + size = beeps.size(); + SDL_UnlockAudio(); + } while (size > 0); + +} + +void audio_callback(void *_beeper, Uint8 *_stream, int _length) +{ + Sint16 *stream = (Sint16*) _stream; + int length = _length / 2; + Beeper* beeper = (Beeper*) _beeper; + + beeper->generateSamples(stream, length); +} + +int main(int argc, char* argv[]) +{ + SDL_Init(SDL_INIT_AUDIO); + + int duration = 1000; + double Hz = 440; + + Beeper b; + b.beep(Hz, duration); + b.wait(); + + return 0; +} diff --git a/generator b/generator new file mode 100755 index 0000000..2fb532e Binary files /dev/null and b/generator differ diff --git a/generator.c b/generator.c index ee66a7f..84f8aa2 100644 --- a/generator.c +++ b/generator.c @@ -31,6 +31,7 @@ void usage() { } int main(int argc, char* argv[]) { + errno = 0; /* This will hold our data */ SDL_AudioSpec spec; /* This will hold the requested frequency */