Scheme playground.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 

76 lines
2.0 KiB

  1. // Generate a tone. Generating multiple tones in a row
  2. // will not be extremely accurate, so it's better as just
  3. // a 'bell' or 'notification' tone generator (not music)
  4. // Most of the generic math was taken from an anonymous pastebin post:
  5. // https://pastebin.com/Uq9rcsJz
  6. #include <SDL2/SDL.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <math.h>
  10. float runUntil = 0.0; // Counts to runFor then exits
  11. // Audio sampling rate. 48k on the Reform.
  12. // TODO: Find a way to get SDL to detect
  13. // current system's sampling rate.
  14. float sampleRate = 44100.0;
  15. float phase = 0.0;
  16. float frequency = 523.25; // Generate a C tone.
  17. float nextSampleSquare() {
  18. phase += (1.0 / sampleRate) * frequency;
  19. if (phase > 1.0) phase -= 1.0;
  20. return phase > 0.5 ? 1.0 : -1.0;
  21. }
  22. void SDLAudioCallback(void *udata, Uint8 *stream, int len) {
  23. unsigned int i;
  24. float *str = (float *) stream;
  25. for (i = 0; i < len / sizeof(float) / 2; i++) {
  26. float smp = nextSampleSquare();
  27. str[i * 2] = smp;
  28. str[i * 2 + 1] = smp;
  29. // Uncommenting this line gives the tone a "rising / sweeping"
  30. // effect.
  31. //frequency += frequency * 0.00001;
  32. runUntil += 1.0 / sampleRate;
  33. }
  34. }
  35. int sdl_generate_tone(float freq, float duration) {
  36. // 44.1k is constant and cannot be changed.
  37. // This is because 44.1 is a perfect sinewave and
  38. // calculating anything higher is redundant anyway.
  39. frequency = freq; //Set user-defined frequency.
  40. if (SDL_Init(SDL_INIT_AUDIO) < 0) {
  41. printf("Can't initialize SDL: \n%s\n", SDL_GetError());
  42. return 1;
  43. }
  44. SDL_AudioSpec audioSpec;
  45. audioSpec.freq = (int)sampleRate;
  46. audioSpec.format = AUDIO_F32SYS;
  47. audioSpec.channels = 2;
  48. audioSpec. samples = 8192;
  49. audioSpec.callback = SDLAudioCallback;
  50. if (SDL_OpenAudio(&audioSpec, 0) < 0) {
  51. printf("Can't open SDL audio: \n%s\n", SDL_GetError());
  52. return 1;
  53. }
  54. SDL_PauseAudio(0);
  55. // TODO: This code freezes the program in a busyloop.
  56. // Find a better way to do this.
  57. while (runUntil < duration);
  58. SDL_CloseAudio();
  59. runUntil = 0.0;
  60. return 0;
  61. }