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.

145 lines
3.8KB

  1. // Copyright 2016 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. #include <stm32f37x_conf.h>
  25. #include "plaits/drivers/audio_dac.h"
  26. #include "plaits/drivers/debug_pin.h"
  27. #include "plaits/drivers/debug_port.h"
  28. #include "plaits/dsp/dsp.h"
  29. #include "plaits/dsp/voice.h"
  30. #include "plaits/settings.h"
  31. #include "plaits/ui.h"
  32. using namespace plaits;
  33. using namespace stmlib;
  34. // #define PROFILE_INTERRUPT 1
  35. const bool test_adc_noise = false;
  36. AudioDac audio_dac;
  37. DebugPort debug_port;
  38. Modulations modulations;
  39. Patch patch;
  40. Settings settings;
  41. Ui ui;
  42. Voice voice;
  43. char shared_buffer[16384];
  44. uint32_t test_ramp;
  45. // Default interrupt handlers.
  46. extern "C" {
  47. void NMI_Handler() { }
  48. void HardFault_Handler() { while (1); }
  49. void MemManage_Handler() { while (1); }
  50. void BusFault_Handler() { while (1); }
  51. void UsageFault_Handler() { while (1); }
  52. void SVC_Handler() { }
  53. void DebugMon_Handler() { }
  54. void PendSV_Handler() { }
  55. void __cxa_pure_virtual() { while (1); }
  56. }
  57. void FillBuffer(AudioDac::Frame* output, size_t size) {
  58. #ifdef PROFILE_INTERRUPT
  59. TIC
  60. #endif // PROFILE_INTERRUPT
  61. IWDG_ReloadCounter();
  62. ui.Poll();
  63. if (test_adc_noise) {
  64. static float note_lp = 0.0f;
  65. float note = modulations.note;
  66. ONE_POLE(note_lp, note, 0.0001f);
  67. float cents = (note - note_lp) * 100.0f;
  68. CONSTRAIN(cents, -8.0f, +8.0f);
  69. while (size--) {
  70. output->r = output->l = static_cast<int16_t>(cents * 4040.0f);
  71. ++output;
  72. }
  73. } else if (ui.test_mode()) {
  74. // 100 Hz ascending and descending ramps.
  75. while (size--) {
  76. output->l = ~test_ramp >> 16;
  77. output->r = test_ramp >> 16;
  78. test_ramp += 8947848;
  79. ++output;
  80. }
  81. } else {
  82. voice.Render(patch, modulations, (Voice::Frame*)(output), size);
  83. ui.set_active_engine(voice.active_engine());
  84. }
  85. if (debug_port.readable()) {
  86. uint8_t command = debug_port.Read();
  87. uint8_t response = ui.HandleFactoryTestingRequest(command);
  88. debug_port.Write(response);
  89. }
  90. #ifdef PROFILE_INTERRUPT
  91. TOC
  92. #endif // PROFILE_INTERRUPT
  93. }
  94. void Init() {
  95. NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);
  96. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  97. IWDG_SetPrescaler(IWDG_Prescaler_16);
  98. BufferAllocator allocator(shared_buffer, 16384);
  99. voice.Init(&allocator);
  100. volatile size_t counter = 1000000;
  101. while (counter--);
  102. bool freshly_baked = !settings.Init();
  103. if (freshly_baked) {
  104. #ifdef PROFILE_INTERRUPT
  105. DebugPin::Init();
  106. #else
  107. debug_port.Init();
  108. #endif // PROFILE_INTERRUPT
  109. }
  110. ui.Init(&patch, &modulations, &settings);
  111. audio_dac.Init(48000, kBlockSize);
  112. audio_dac.Start(&FillBuffer);
  113. IWDG_Enable();
  114. }
  115. int main(void) {
  116. Init();
  117. while (1) { }
  118. }