|
- // Generate a tone. Generating multiple tones in a row
- // will not be extremely accurate, so it's better as just
- // a 'bell' or 'notification' tone generator (not music)
-
- // Most of the generic math was taken from an anonymous pastebin post:
- // https://pastebin.com/Uq9rcsJz
-
- #include <SDL2/SDL.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
-
- float runUntil = 0.0; // Counts to runFor then exits
-
- // Audio sampling rate. 48k on the Reform.
- // TODO: Find a way to get SDL to detect
- // current system's sampling rate.
- float sampleRate = 44100.0;
-
- float phase = 0.0;
- float frequency = 523.25; // Generate a C tone.
-
- float nextSampleSquare() {
- phase += (1.0 / sampleRate) * frequency;
- if (phase > 1.0) phase -= 1.0;
- return phase > 0.5 ? 1.0 : -1.0;
- }
-
- void SDLAudioCallback(void *udata, Uint8 *stream, int len) {
- unsigned int i;
- float *str = (float *) stream;
- for (i = 0; i < len / sizeof(float) / 2; i++) {
- float smp = nextSampleSquare();
- str[i * 2] = smp;
- str[i * 2 + 1] = smp;
-
- // Uncommenting this line gives the tone a "rising / sweeping"
- // effect.
- //frequency += frequency * 0.00001;
-
-
- runUntil += 1.0 / sampleRate;
- }
- }
-
- int sdl_generate_tone(float freq, float duration) {
- // 44.1k is constant and cannot be changed.
- // This is because 44.1 is a perfect sinewave and
- // calculating anything higher is redundant anyway.
- frequency = freq; //Set user-defined frequency.
- if (SDL_Init(SDL_INIT_AUDIO) < 0) {
- printf("Can't initialize SDL: \n%s\n", SDL_GetError());
- return 1;
- }
- SDL_AudioSpec audioSpec;
- audioSpec.freq = (int)sampleRate;
- audioSpec.format = AUDIO_F32SYS;
- audioSpec.channels = 2;
- audioSpec. samples = 8192;
- audioSpec.callback = SDLAudioCallback;
-
- if (SDL_OpenAudio(&audioSpec, 0) < 0) {
- printf("Can't open SDL audio: \n%s\n", SDL_GetError());
- return 1;
- }
-
- SDL_PauseAudio(0);
-
- // TODO: This code freezes the program in a busyloop.
- // Find a better way to do this.
- while (runUntil < duration);
- SDL_CloseAudio();
- runUntil = 0.0;
- return 0;
- }
|