Advertisement
degu234

ChordOrgan Synthvoice

Sep 9th, 2021
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 20.00 KB | None | 0 0
  1. /* custom firmware for the chord organ module from music thing modular designed and created by Tom Whitwell
  2.     aviable at thonk
  3.     with alot of help from "Wolle Wer". Thank you once again at this point
  4.     this Firmware trys to be several synthvoices in one with nice audio-modulation and FX abilty.
  5.     in the system are 4 waveformgenrators, 2 filters in series, wavefolder, bitcrusher and delay.
  6.     the first filter is controled by the signal coming from stationCV Jack, the second filter is controlled
  7.     by the stationknob aviable at page 0. You may control the first filters resonance with startknob also on page 0
  8.     stationKnob = A9
  9.     stationCV = A8
  10.     startKnob = A7
  11.     startCV = A6
  12.     tasterButton = Pin 8
  13.     triggerCV = Pin 9
  14.     Output = dac1
  15.  
  16.     startCV changes Pitch within a range of 3.3V equal 40 Notes, notes are quantized
  17.     stationCV changes filter1.frequency i.E. external envelope
  18.     with tasterButton you can switch thru different pages.
  19.     Each Page has the two knobs Station- and startKnob to change different parameters
  20.  
  21.     page (stationKnob, startKnob)
  22.     initial page 0 (filter2.frequency, filter1.resonance)
  23.     page 1 (mixer1.gain(Note1), (mixer1.gain(note2,3,4)
  24.     page 2 (chord selection, waveform1,2,3,4.selection)
  25.     page 3 (wavefolder1, bitcrusher1)
  26.     page 4 (delay1.time <200ms, delay1.feedback)
  27.  
  28.   //todo:
  29.   //EnvelopeGenerator with trigger in that actually sends a control value (dc2) to the filter (dc2 * 8184)
  30.   //Envelopegenerator Attack/Release control on a new page controlled by stationKnob/startKnob
  31.   //
  32.   //
  33. */
  34.  
  35. #include <synth_waveform.h>
  36.  
  37. #include <Audio.h>
  38. #include <Wire.h>
  39. #include <SPI.h>
  40. #include <SD.h>
  41. #include <SerialFlash.h>
  42.  
  43. // GUItool: begin automatically generated code
  44. AudioSynthWaveform       waveform3;      //xy=195.80627059936523,430.00000762939453
  45. AudioSynthWaveform       waveform1;      //xy=198.80627059936523,334.00000762939453
  46. AudioSynthWaveform       waveform2;      //xy=199.80627059936523,383.00000762939453
  47. AudioSynthWaveform       waveform4;      //xy=208.80627059936523,480.00000762939453
  48. AudioSynthWaveformDc     dc2;            //xy=319.80625915527344,548.8250045776367
  49. AudioMixer4              mixer1;         //xy=358.80627059936523,371.00000762939453
  50. AudioEffectEnvelope      envelope1;      //xy=447,485
  51. AudioFilterStateVariable filter1;        //xy=511.8062438964844,386.9999885559082
  52. AudioSynthWaveformDc     dc1;            //xy=549.8062744140625,614.0000114440918
  53. AudioMixer4              mixer2;         //xy=648.8062744140625,397.0000114440918
  54. AudioFilterStateVariable filter2;        //xy=659.8062705993652,278.00000762939453
  55. AudioEffectWaveFolder    wavefolder1;    //xy=815.8062744140625,460.0000114440918
  56. AudioEffectBitcrusher    bitcrusher1;    //xy=846.8062744140625,350.0000114440918
  57. AudioEffectDelay         delay1;         //xy=1016.8062744140625,601.0000114440918
  58. AudioMixer4              mixer3;         //xy=1020.8062744140625,418.0000114440918
  59. AudioFilterStateVariable filter3;        //xy=1020.8062744140625,493.0000114440918
  60. AudioMixer4              mixer5;         //xy=1186.8062744140625,413.00000762939453
  61. AudioOutputAnalog        dac1;           //xy=1322.8063125610352,418.9999885559082
  62. AudioConnection          patchCord1(waveform3, 0, mixer1, 2);
  63. AudioConnection          patchCord2(waveform1, 0, mixer1, 0);
  64. AudioConnection          patchCord3(waveform2, 0, mixer1, 1);
  65. AudioConnection          patchCord4(waveform4, 0, mixer1, 3);
  66. AudioConnection          patchCord5(dc2, envelope1);
  67. AudioConnection          patchCord6(mixer1, 0, filter1, 0);
  68. AudioConnection          patchCord7(envelope1, 0, filter1, 1);
  69. AudioConnection          patchCord8(filter1, 0, filter2, 0);
  70. AudioConnection          patchCord9(dc1, 0, wavefolder1, 1);
  71. AudioConnection          patchCord10(mixer2, 0, wavefolder1, 0);
  72. AudioConnection          patchCord11(filter2, 0, mixer2, 0);
  73. AudioConnection          patchCord12(wavefolder1, bitcrusher1);
  74. AudioConnection          patchCord13(bitcrusher1, 0, mixer3, 0);
  75. AudioConnection          patchCord14(delay1, 0, filter3, 0);
  76. AudioConnection          patchCord15(mixer3, delay1);
  77. AudioConnection          patchCord16(mixer3, 0, mixer5, 0);
  78. AudioConnection          patchCord17(filter3, 2, mixer3, 1);
  79. AudioConnection          patchCord18(mixer5, dac1);
  80. AudioControlSGTL5000     sgtl5000_1;     //xy=896.8062744140625,740.0000114440918
  81. // GUItool: end automatically generated code
  82.  
  83.  
  84. //Constants
  85. const int tasterPin = 8;     //taster at Pin 8
  86. const int triggerPin = 9;    //Jack for Gate at Pin 9
  87.  
  88. const int L1Pin = 3;       // LED1 at Pin 3
  89. const int L2Pin = 4;      // LED2 at Pin 4
  90. const int L3Pin = 5;      // LED3 at Pin 5
  91. const int L4Pin = 6;      // LED4 at Pin 6
  92. const int L5Pin = 11;     // LED5 at Pin 11
  93.  
  94. //Variables
  95. int mode = 0;                // Variable for case switching
  96. int DetectionMode = 0;       //detection for stationKnob hook up
  97. int DetectionMode2 = 0;       //detection for startKnob hook up
  98. int tasterState = 0;         // Variable to save tasterstate
  99. int triggerState = 0;     // Variable to save triggerstate
  100. float Note2[8] = {1.25992, 1.18920, 1.25992, 1.33484, 1.33484, 1.25992, 1.33484, 1.33484};  //{4, 3, 4, 3, 5, 4, 3, 3}Frequency proportion to 2nd note
  101. float Note3[8] = {1.49830, 1.49830, 1.49830, 1.49830, 1.49830, 1.49830, 1.49830, 1.41421};  //{7, 7, 7, 7, 7, 7, 7, 6};Frequency proportion to 3rd note
  102. float Note4[8] = {2.00000, 2.00000, 1.88775, 1.78179, 1.88775, 1.58739, 1.58739, 2.00000};  //{12, 12, 11, 10, 12, 8, 8, 12};Frequency proportion to 4th note
  103. int noteArray;
  104. float Hertz[61] = {65.4064, 69.957, 73.41619, 77.78175, 82.40689, 87.30706, 92.49861, 97.99886, 103.8262, 110.0000, 116.5409, 123.4708,
  105.                    130.8128, 138.5913, 146.8324, 155.5635, 164.8138, 174.6141, 184.9972, 195.9977, 207.6523, 220.0000, 233.0819, 246.9417,
  106.                    261.6256, 277.1826, 293.6648, 311.1270, 329.6276, 349.2282, 369.9944, 391.9954, 415.3047, 440.0000, 466.1638, 493.8833,
  107.                    523.2511, 554.3653, 587.3295, 622.2540, 659.2551, 698.4565, 739.9888, 783.9909, 830.6094, 880.0000, 932.3275, 987.7666,
  108.                    1046.502, 1108.731, 1174.659, 1244.508, 1318.510, 1396.913, 1479.978, 1567.982, 1661.219, 1760.000, 1864.655, 1975.533, 2093.005
  109.                   };
  110.  
  111. //variables to handle each´s page last knob position
  112. int filterCutoff = 512;
  113. int resoNance = 0;
  114. int volume1 = 1023;
  115. int volume234 = 1023;
  116. int chordSelect = 0;
  117. int wfSelect = 439;
  118. int waveFolder = 307;
  119. int bitCrusher = 1023;
  120. int delayTime = 0;
  121. int feedBack = 0;
  122.  
  123.  
  124. void setup() {
  125.   Serial.begin(19200); // USB is always 12 or 480 Mbit/sec
  126.   //setting up the audio components
  127.   //===========================================================================
  128.   //analogReadResolution(12);
  129.   AudioMemory(200);
  130.  
  131.   waveform1.begin(WAVEFORM_SAWTOOTH);
  132.   waveform1.amplitude(1);
  133.   waveform1.frequency(65.41);
  134.   waveform1.pulseWidth(0.15);
  135.  
  136.   waveform2.begin(WAVEFORM_SAWTOOTH);
  137.   waveform2.amplitude(1);
  138.   waveform2.frequency(65.41);
  139.   waveform2.pulseWidth(0.15);
  140.  
  141.   waveform3.begin(WAVEFORM_SAWTOOTH);
  142.   waveform3.amplitude(1);
  143.   waveform3.frequency(65.41);
  144.   waveform3.pulseWidth(0.15);
  145.  
  146.   waveform4.begin(WAVEFORM_SAWTOOTH);
  147.   waveform4.amplitude(1);
  148.   waveform4.frequency(65.41);
  149.   waveform4.pulseWidth(0.15);
  150.  
  151.   //mixer1 to controll Waveform1 with stationKnob; Waveform2-4 with startKnob on page 1
  152.   mixer1.gain(0, 0.25);
  153.   mixer1.gain(1, 0.25);
  154.   mixer1.gain(2, 0.25);
  155.   mixer1.gain(3, 0.25);
  156.  
  157.   envelope1.delay(0);
  158.   envelope1.attack(20);
  159.   envelope1.hold(0);
  160.   envelope1.decay(5000);
  161.   envelope1.sustain(0.7);
  162.   envelope1.release(500);
  163.  
  164.   dc2.amplitude(1);
  165.  
  166.   //filter1 is controlled by the stationCV input
  167.   filter1.frequency(110);                                                  //set initial Filter1 freq to 16000Hz
  168.   filter1.resonance(0);                                                      //set Resonance to 0
  169.   filter1.octaveControl(5);
  170.  
  171.   //filter2 is controlled by the stationKnob on page 0
  172.   filter2.frequency(16000);                                                  //set initial Filter2 freq to 16000Hz
  173.   filter2.resonance(0);                                                      //set Resonance to 0
  174.  
  175.   //mixer2 is just there, no need for it actually
  176.   mixer2.gain(0, 1);                                                         //set Mixer2(Channel, Gain) (0-3, 0-1)
  177.   mixer2.gain(1, 1);
  178.  
  179.   //dc1 for wavefolder input controlled by stationKnob on page 3
  180.   dc1.amplitude(0.05);                                                       //set dc1 for Wavefolder Input
  181.  
  182.   //bitcrusher1 controlled by startKnob on page 3
  183.   bitcrusher1.bits(16);
  184.   bitcrusher1.sampleRate(44100);
  185.  
  186.   //delay1 time controlled by stationKnob; feedback controlled by startKnob on page 4
  187.   delay1.delay(0, 3);                                                        //set Delay(OutChannel, saved Samples) (0-7, 3-449*) *maximum
  188.  
  189.   //filter3 HighPassfilter to get rid of the muddy sound in feedbackloop
  190.   filter3.frequency(200);                                                   //set initial Filter3 freq to 16000Hz
  191.   filter3.resonance(0);                                                      //set Resonance to 0
  192.  
  193.   //mixer3 for feedback controlled by startKnob on page 4
  194.   mixer3.gain(0, 1);                                                         //setze Mixer2(Kanal, Gain) (0-3, 0-1)
  195.   mixer3.gain(1, 0);
  196.  
  197.   //mixer4.gain(1, 0);
  198.   //mixer4.gain(0, 0);
  199.  
  200.   //mixer5 again just a mixer to pass audio thru
  201.   mixer5.gain(0, 0.5);
  202.   //mixer5.gain(1, 0.5);
  203.  
  204.  
  205.   //setting up the audio components DONE!!
  206.   //===========================================================================
  207.  
  208.   //setting up the Pins as In´s n Out´s
  209.   //============================================================================
  210.   pinMode(tasterPin, INPUT);                                                 //taster is input
  211.   pinMode(triggerPin, INPUT);                                             //trigger is input
  212.   pinMode(L1Pin, OUTPUT);                                                    // Set LEDPin as output
  213.   pinMode(L2Pin, OUTPUT);                                                    // Set LEDPin as output
  214.   pinMode(L3Pin, OUTPUT);                                                    // Set LEDPin as output
  215.   pinMode(L4Pin, OUTPUT);                                                    // Set LEDPin as output
  216.   pinMode(L5Pin, OUTPUT);                                                    // Set LEDPin as output
  217.  
  218.  
  219. }
  220.  
  221.  
  222.  
  223.  
  224. void loop() {
  225.   tasterState = digitalRead(tasterPin);                                       //read tasterPin and set tasterState
  226.   triggerState = digitalRead(triggerPin);                                  //read triggerPin and set triggerState
  227.  
  228.   int startCV = analogRead(A8);
  229.   int startKnob = analogRead(A7);                                             //lies Analog7 und setze auf startKnob
  230.   int stationKnob = analogRead(A9);                                           //lies Analog9 und setze auf stationKnob
  231.   int stationCV = analogRead(A6);                                             //lies Analog6 und setze auf stationCV
  232.  
  233.  
  234.   //1V/Octave works, though only till 3.3V so its a 40 Note Range beginning from C1 65.4064Hz Hertzarray goes to 60, so you could transpose those 40 Notes :)
  235.   //works independently from pageselection
  236.   //PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
  237.   int hertzseriell = map(startCV, 0, 1023, 0, 40);
  238.   waveform1.frequency(Hertz[hertzseriell]); //WF1 plays rootnote
  239.   waveform2.frequency(Hertz[hertzseriell] * Note2[noteArray]); //WF2 plays rootnote * Frequencyproportionn from "Note2"-array
  240.   waveform3.frequency(Hertz[hertzseriell] * Note3[noteArray]); //WF3 plays rootnote * Frequencyproportionn from "Note3"-array
  241.   waveform4.frequency(Hertz[hertzseriell] * Note4[noteArray]); //WF4 plays rootnote * Frequencyproportionn from "Note4"-array
  242.   //PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
  243.  
  244.   //filter1 freuquency modulation from station CV Jack, independently from pageselection
  245.   //filter1.frequency(map(stationCV, 0, 1023, 0, 8184));
  246.   //mixer3.gain(0, map(stationCV, 0, 511, 0, 1));
  247.  
  248.   if (triggerState == HIGH) {
  249.     envelope1.noteOn();
  250.   }
  251.   else {
  252.     envelope1.noteOff();
  253.   }
  254.   digitalWrite(L5Pin, triggerState );
  255.   //TasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTaster
  256.   //=======================================================================================================
  257.   if (tasterState == HIGH)                                                    //when tasterState is High
  258.   {
  259.     mode++;                                                                   //count case mode + 1
  260.     DetectionMode = 0;                                                        //everytime we press the button, ddetectionmode is resetted to 0
  261.     DetectionMode2 = 0;
  262.     delay(200);                                                               //delay zur Entprellung
  263.   }
  264.   //=======================================================================================================
  265.   //TasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTasterTaster
  266.  
  267.  
  268.   digitalWrite(L1Pin, LOW);                                               //Led 1 aus
  269.   digitalWrite(L2Pin, LOW);                                               //Led 2 aus
  270.   digitalWrite(L3Pin, LOW);                                               //Led 3 aus
  271.   digitalWrite(L4Pin, LOW);                                               //Led 4 aus
  272.  
  273.   //begin of page switching and what happens in each page
  274.   //==========================================================================
  275.  
  276.   switch (mode) {
  277.     //00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  278.     case 0: //Filter5 + Resonance
  279.  
  280.       if ((DetectionMode == 0) && (abs(stationKnob - filterCutoff) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  281.         DetectionMode = 1;
  282.       }
  283.       if (DetectionMode == 1) {
  284.         filterCutoff = stationKnob;
  285.       }
  286.       filter2.frequency((float)map(filterCutoff, 0, 1023, 65.41, 8184));       //Filter1 filters cutoff
  287.  
  288.       //--------------------------------------------------------------------------
  289.       if ((DetectionMode2 == 0) && (abs(startKnob - resoNance) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  290.         DetectionMode2 = 1;
  291.       }
  292.       if (DetectionMode2 == 1) {
  293.         resoNance = startKnob;
  294.       }
  295.       filter2.resonance((float)map(resoNance, 0, 1023, 0, 5));                //controls Resonance
  296.       break;
  297.     case 1: //Volume1 + 2,3,4
  298.       //1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
  299.       digitalWrite(L1Pin, HIGH);                                              //Led 1 an
  300.  
  301.       if ((DetectionMode == 0) && (abs(stationKnob - volume1) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  302.         DetectionMode = 1;
  303.       }
  304.       if (DetectionMode == 1) {
  305.         volume1 = stationKnob;
  306.       }
  307.       mixer1.gain(0, ((float)volume1 / 3069));                            //Gain Mixer1 Eingang 0
  308.       //---------------------------------------------------------------------------------------------------------------
  309.       if ((DetectionMode2 == 0) && (abs(startKnob - volume234) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  310.         DetectionMode2 = 1;
  311.       }
  312.       if (DetectionMode2 == 1) {
  313.         volume234 = startKnob;
  314.       }
  315.       mixer1.gain(1, ((float)volume234 / 3069));                              //Gain Mixer1 Eingang 1
  316.       mixer1.gain(2, ((float)volume234 / 3069));                              //Gain Mixer1 Eingang 2
  317.       mixer1.gain(3, ((float)volume234 / 3069));                              //Gain Mixer1 Eingang 3
  318.       break;
  319.  
  320.     //2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
  321.     case 2: //Chordtype + Waveformtype
  322.       digitalWrite(L2Pin, HIGH);                                              //Led 2 an
  323.       if ((DetectionMode == 0) && (abs(stationKnob - chordSelect) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  324.         DetectionMode = 1;
  325.       }
  326.       if (DetectionMode == 1) {
  327.         chordSelect = stationKnob;
  328.       }
  329.       noteArray = map(chordSelect, 0, 1023, 0, 7);                       //stationKnob stores value 0-7 into noteArray
  330.       //----------------------------------------------------------------------------------------------------------------------------------------
  331.       if ((DetectionMode2 == 0) && (abs(startKnob - wfSelect) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  332.         DetectionMode2 = 1;
  333.       }
  334.       if (DetectionMode2 == 1) {
  335.         wfSelect = startKnob;
  336.       }
  337.       waveform1.begin(map(wfSelect, 0, 1023, 0, 12));                        //waveform selection with startKnob
  338.       waveform2.begin(map(wfSelect, 0, 1023, 0, 12));                        //waveform selection with startKnob
  339.       waveform3.begin(map(wfSelect, 0, 1023, 0, 12));                        //waveform selection with startKnob
  340.       waveform4.begin(map(wfSelect, 0, 1023, 0, 12));                        //waveform selection with startKnob
  341.       break;
  342.  
  343.     //3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
  344.     case 3: //wavefolder + bitcrusher
  345.       digitalWrite(L3Pin, HIGH);                                              //Led 3 an
  346.       if ((DetectionMode == 0) && (abs(stationKnob - waveFolder) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  347.         DetectionMode = 1;
  348.       }
  349.       if (DetectionMode == 1) {
  350.         waveFolder = stationKnob;
  351.       }
  352.       dc1.amplitude((float)waveFolder / 1023);                              //dc-value 0-1 for Wavefolder controlled by stationKnob
  353.       //-----------------------------------------------------------------------------------------------------------------------------
  354.       if ((DetectionMode2 == 0) && (abs(startKnob - bitCrusher) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  355.         DetectionMode2 = 1;
  356.       }
  357.       if (DetectionMode2 == 1) {
  358.         bitCrusher = startKnob;
  359.       }
  360.       bitcrusher1.sampleRate(map(bitCrusher, 0, 1023, 1, 44100));              //samplerate 1-44100Hz controlled by startKnob
  361.       break;
  362.  
  363.     //4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
  364.     case 4: //delaytime + feedback
  365.       digitalWrite(L4Pin, HIGH);                                              //Led 4 aus
  366.       if ((DetectionMode == 0) && (abs(stationKnob - delayTime) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  367.         DetectionMode = 1;
  368.       }
  369.       if (DetectionMode == 1) {
  370.         delayTime = stationKnob;
  371.       }
  372.       delay1.delay(0, map(delayTime, 0, 1023, 3, 200));                     //delaytime 3-200ms controlled by stationknob
  373.       //--------------------------------------------------------------------------------------------------------------------------------------
  374.       if ((DetectionMode2 == 0) && (abs(startKnob - feedBack) < 10)) {         // Potiwert muss in die Naehe des letzten Wertes kommen
  375.         DetectionMode2 = 1;
  376.       }
  377.       if (DetectionMode2 == 1) {
  378.         feedBack = startKnob;
  379.       }
  380.       mixer3.gain(1, ((float)feedBack / 1023));                              //delayfeedback 0-1 controlled by startknob
  381.       break;
  382.  
  383.     default:                                                                  //next taster push brings us back to page 0
  384.       mode = 0;
  385.   }
  386.   //end of page switching
  387.   //==================================================================================================
  388.  
  389.  
  390.  
  391. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement