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.

245 lines
6.8KB

  1. // Copyright 2012 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (olivier@mutable-instruments.net)
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. #include "avrlibx/system/init.h"
  16. #include "avrlibx/system/time.h"
  17. #include "avrlibx/system/timer.h"
  18. #include "avrlibx/utils/op.h"
  19. #include "edges/adc_acquisition.h"
  20. #include "edges/audio_buffer.h"
  21. #include "edges/digital_oscillator.h"
  22. #include "edges/hardware_config.h"
  23. #include "edges/midi.h"
  24. #include "edges/midi_handler.h"
  25. #include "edges/settings.h"
  26. #include "edges/timer_oscillator.h"
  27. #include "edges/ui.h"
  28. using namespace avrlibx;
  29. using namespace edges;
  30. MidiIO midi_io;
  31. MidiBuffer midi_in_buffer;
  32. midi::MidiStreamParser<MidiHandler> midi_parser;
  33. GateInputs gate_inputs;
  34. DACSS dac_ss;
  35. AudioDACInterface audio_dac;
  36. ADCSS adc_ss;
  37. ADCInterface adc;
  38. AudioRateTimer audio_rate_timer;
  39. SyncSwitch sync_switch;
  40. TimerOscillator channel_0;
  41. TimerOscillator channel_1;
  42. TimerOscillator channel_2;
  43. TimerOscillator channel_3;
  44. DigitalOscillator channel_4;
  45. // Channel 1 overflow. If sync is enabled, reset the phase of the channel 2.
  46. ISR(TCD0_OVF_vect) {
  47. Channel2Timer::Restart();
  48. }
  49. volatile uint16_t audio_interrupt_count = 0;
  50. uint8_t channel_remapping[] = { 0, 1, 4, 5, 2, 3, 6, 7};
  51. // Audio rate interrupt (48.048kHz).
  52. ISR(TCE0_OVF_vect) {
  53. // Shove a sample to the DAC.
  54. uint16_t sample = audio_buffer.ImmediateRead();
  55. audio_dac.Strobe();
  56. Word sample_12bits;
  57. sample_12bits.value = sample | 0x3000;
  58. audio_dac.Overwrite(sample_12bits.bytes[1]);
  59. audio_dac.Overwrite(sample_12bits.bytes[0]);
  60. // Step through the ADC pipeline.
  61. int8_t result = adc_acquisition.Cycle();
  62. if (result != -1) {
  63. uint16_t value = adc_acquisition.channel(result);
  64. #ifdef OCTAL_ADC
  65. value = 4095 - value;
  66. result = channel_remapping[result];
  67. #endif // OCTAL_ADC
  68. ui.set_cv(result, value);
  69. }
  70. // When a conversion is finished, update the corresponding channel
  71. // Note that the UI can take over the value read from the DAC, for example
  72. // When programming an arpeggio
  73. switch (result) {
  74. case 0:
  75. channel_1.UpdatePitch<Channel1Timer>(
  76. midi_handler.shift_pitch(0,
  77. settings.dac_to_pitch(0, ui.cv(0))) +
  78. settings.dac_to_fm(0, ui.cv(4)),
  79. settings.pw(0));
  80. channel_0.SubFollow<Channel0Timer>(channel_1);
  81. break;
  82. case 1:
  83. channel_2.UpdatePitch<Channel2Timer>(
  84. midi_handler.shift_pitch(1,
  85. settings.dac_to_pitch(1, ui.cv(1))) +
  86. settings.dac_to_fm(1, ui.cv(5)),
  87. settings.pw(1));
  88. break;
  89. case 2:
  90. channel_3.UpdatePitch<Channel3Timer>(
  91. midi_handler.shift_pitch(2,
  92. settings.dac_to_pitch(2, ui.cv(2))) +
  93. settings.dac_to_fm(2, ui.cv(6)),
  94. settings.pw(2));
  95. break;
  96. case 3:
  97. {
  98. channel_4.UpdatePitch(
  99. midi_handler.shift_pitch(3,
  100. settings.dac_to_pitch(3, ui.cv(3))) +
  101. settings.dac_to_fm(3, ui.cv(7)),
  102. settings.shape(3));
  103. #ifndef OCTAL_ADC
  104. uint8_t cv_controlled_pw_8bit = U16ShiftRight4(ui.cv(3));
  105. channel_1.set_cv_pw(cv_controlled_pw_8bit);
  106. channel_2.set_cv_pw(cv_controlled_pw_8bit);
  107. channel_3.set_cv_pw(cv_controlled_pw_8bit);
  108. #endif // #ifndef OCTAL_ADC
  109. }
  110. break;
  111. #ifdef OCTAL_ADC
  112. case 4:
  113. channel_1.set_cv_pw(U16ShiftRight4(ui.cv(4)));
  114. break;
  115. case 5:
  116. channel_2.set_cv_pw(U16ShiftRight4(ui.cv(5)));
  117. break;
  118. case 6:
  119. channel_3.set_cv_pw(U16ShiftRight4(ui.cv(6)));
  120. break;
  121. case 7:
  122. channel_4.set_cv_pw(U16ShiftRight4(ui.cv(7)));
  123. break;
  124. #endif // #ifdef OCTAL_ADC
  125. default:
  126. {
  127. // Otherwise, scan the gate.
  128. uint8_t gate = ~gate_inputs.value();
  129. bool g_1 = (gate & 1) || midi_handler.gate(0) || settings.arpeggio(0);
  130. channel_0.Gate<Channel0>(g_1);
  131. channel_1.Gate<Channel1>(g_1);
  132. bool g_2 = (gate & 2) || midi_handler.gate(1) || settings.arpeggio(1);
  133. channel_2.Gate<Channel2>(g_2);
  134. bool g_3 = (gate & 4) || midi_handler.gate(2) || settings.arpeggio(2);
  135. channel_3.Gate<Channel3>(g_3);
  136. bool g_4 = (gate & 8) || midi_handler.gate(3) || settings.arpeggio(3);
  137. channel_4.Gate(g_4);
  138. // Read some MIDI bytes, but process them later.
  139. if (midi_io.readable()) {
  140. midi_in_buffer.NonBlockingWrite(midi_io.ImmediateRead());
  141. }
  142. }
  143. break;
  144. }
  145. ++audio_interrupt_count;
  146. }
  147. inline void Init() {
  148. SysInit();
  149. sync_switch.set_direction(INPUT);
  150. sync_switch.set_mode(PORT_MODE_PULL_UP);
  151. gate_inputs.set_direction(INPUT);
  152. gate_inputs.set_mode(PORT_MODE_PULL_UP);
  153. ui.Init();
  154. // Reset to factory default if any switch is pressed during boot.
  155. settings.Init(!(Switches::Read() & 8));
  156. midi_io.Init();
  157. midi_handler.Init();
  158. audio_dac.Init();
  159. audio_dac.Strobe();
  160. audio_dac.Overwrite(0x1f);
  161. audio_dac.Overwrite(0xff);
  162. channel_0.Init<Channel0, Channel0Timer>();
  163. channel_1.Init<Channel1, Channel1Timer>();
  164. channel_2.Init<Channel2, Channel2Timer>();
  165. channel_3.Init<Channel3, Channel3Timer>();
  166. channel_4.Init();
  167. adc_acquisition.Init();
  168. audio_rate_timer.set_prescaler(TIMER_PRESCALER_CLK);
  169. audio_rate_timer.set_period(665); // 48kHz
  170. audio_rate_timer.set_mode(TIMER_MODE_NORMAL);
  171. audio_rate_timer.EnableOverflowInterrupt(2);
  172. }
  173. int main(void) {
  174. Init();
  175. while (1) {
  176. // Render audio.
  177. channel_4.Render();
  178. // Scan MIDI in.
  179. while (midi_in_buffer.readable()) {
  180. midi_parser.PushByte(midi_in_buffer.ImmediateRead());
  181. }
  182. // Do some UI stuff.
  183. if (audio_interrupt_count >= 48) {
  184. audio_interrupt_count -= 48;
  185. uint8_t gate = ~gate_inputs.value();
  186. // Detect new notes and forward to UI subsystem for calibration functions.
  187. uint8_t mask = 1;
  188. for (uint8_t channel = 0; channel < kNumChannels; ++channel) {
  189. if ((gate & mask) && !(ui.gate() & mask)) {
  190. settings.StepArpeggio(channel);
  191. }
  192. mask <<= 1;
  193. }
  194. ui.set_gate(gate);
  195. ui.Poll();
  196. }
  197. // Check the status of the sync switch
  198. if (sync_switch.value()) {
  199. Channel1Timer::EnableOverflowInterrupt(3);
  200. } else {
  201. Channel1Timer::DisableOverflowInterrupt();
  202. }
  203. }
  204. }