notanorgan.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "common/sketchbook.hpp"
  2. using namespace std::literals;
  3. using namespace musical;
  4. using namespace common;
  5. using support::wrap;
  6. constexpr std::array<std::array<float,19>,4> notes {{
  7. {
  8. 51.91, 55.00, 58.27, 61.74, 65.41, 69.30,
  9. 73.42, 77.78, 82.41, 87.31, 92.50, 98.00,
  10. 103.83, 110.00, 116.54, 123.47, 130.81,
  11. 138.59, 146.83,
  12. },
  13. {
  14. 155.56, 164.81, 174.61, 185.00, 196.00,
  15. 207.65, 220.00, 233.08, 246.94, 261.63,
  16. 277.18, 293.66, 311.13, 329.63, 349.23,
  17. 369.99, 392.00, 415.30, 440.00,
  18. },
  19. {
  20. 466.16, 493.88, 523.25, 554.37, 587.33,
  21. 622.25, 659.25, 698.46, 739.99, 783.99,
  22. 830.61, 880.00, 932.33, 987.77, 1046.50,
  23. 1108.73, 1174.66, 1244.51, 1318.51,
  24. },
  25. {
  26. 1396.91, 1479.98, 1567.98, 1661.22,
  27. 1760.00, 1864.66, 1975.53, 2093.00,
  28. 2217.46, 2349.32, 2489.02, 2637.02,
  29. 2793.83, 2959.96, 3135.96, 3322.44,
  30. 3520.00, 3729.31, 3951.07,
  31. },
  32. }};
  33. constexpr std::array<scancode,19> keys {
  34. scancode::a,
  35. scancode::w,
  36. scancode::s,
  37. scancode::e,
  38. scancode::d,
  39. scancode::r,
  40. scancode::f,
  41. scancode::t,
  42. scancode::g,
  43. scancode::y,
  44. scancode::h,
  45. scancode::u,
  46. scancode::j,
  47. scancode::i,
  48. scancode::k,
  49. scancode::o,
  50. scancode::l,
  51. scancode::p,
  52. scancode::semicolon
  53. };
  54. auto get_key_index(scancode key)
  55. {
  56. auto it = std::find(keys.begin(), keys.end(), key);
  57. return keys.end() != it ? std::optional(it - keys.begin()) : std::nullopt;
  58. };
  59. void start(Program& program)
  60. {
  61. program.key_down = [&program](scancode key, auto){
  62. auto level =
  63. pressed(scancode::lshift) ? 1 :
  64. pressed(scancode::lctrl) ? 2 :
  65. pressed(scancode::lalt) ? 3 :
  66. 0;
  67. auto index = get_key_index(key);
  68. if(index)
  69. {
  70. auto wave = [note=notes[level][*index]](auto ratio)
  71. {
  72. // low value of fade creates this nice effect, but it was originally implemented to get rid of loud pop caused by an instantenous aplitude drop to 0 at the end of the generated wave and for this purpose a much higher value can be used to not affect the waveform as much (for example 200, corresponding to 5ms fade)
  73. constexpr float fade_in = 2;
  74. constexpr float fade_out = 2;
  75. float fade = std::min(ratio*fade_in, (1-ratio)*fade_out);
  76. return way(0.f,sinus(ratio * note), std::min(fade, 1.f));
  77. };
  78. program.request_wave({std::move(wave), 1000ms});
  79. }
  80. };
  81. }