![](/media/cache/profiles/4b4edc2630fe75800ddc29a7b4070add.50x50_q85.jpg)
Auduino port
Embed:
(wiki syntax)
Show/hide line numbers
auduino.cpp
00001 #include <math.h> 00002 #include "mbed.h" 00003 00004 #define FEATURE_ORIGINAL_AUDUINO 00005 00006 // Auduino for mbed 00007 // Ported and arranged by Kaoru Shoji 00008 00009 // Original source code: 00010 // Auduino, the Lo-Fi granular synthesiser 00011 // 00012 // by Peter Knight, Tinker.it http://tinker.it 00013 // 00014 // Help: http://code.google.com/p/tinkerit/wiki/Auduino 00015 // More help: http://groups.google.com/group/auduino 00016 // 00017 // Changelog: 00018 // 19 Nov 2008: Added support for ATmega8 boards 00019 // 21 Mar 2009: Added support for ATmega328 boards 00020 // 7 Apr 2009: Fixed interrupt vector for ATmega328 boards 00021 // 8 Apr 2009: Added support for ATmega1280 boards (Arduino Mega) 00022 00023 // Analog in p16: Grain 1 pitch 00024 // Analog in p17: Grain 1 decay 00025 // Analog in p19: Grain 2 pitch 00026 // Analog in p20: Grain 2 decay 00027 // Analog in p15: Grain repetition frequency 00028 // Analog out p18: Audio out 00029 00030 Ticker interrupt; 00031 AnalogIn SYNC_CONTROL(p15); 00032 AnalogIn GRAIN_FREQ_CONTROL(p16); 00033 AnalogIn GRAIN_DECAY_CONTROL(p17); 00034 AnalogIn GRAIN2_FREQ_CONTROL(p19); 00035 AnalogIn GRAIN2_DECAY_CONTROL(p20); 00036 AnalogOut OUTPUT(p18); 00037 DigitalOut LED_PIN(LED1); 00038 00039 float syncPhaseAcc; 00040 float syncPhaseInc; 00041 00042 float grainPhaseAcc; 00043 float grainPhaseInc; 00044 float grainAmp; 00045 float grainDecay; 00046 00047 float grain2PhaseAcc; 00048 float grain2PhaseInc; 00049 float grain2Amp; 00050 float grain2Decay; 00051 00052 // Smooth logarithmic mapping 00053 // 00054 float mapPhaseInc(double input) { 00055 return pow(65536.0, 1.0 - input); 00056 } 00057 00058 // Stepped chromatic mapping 00059 // 00060 uint16_t midiTable[] = { 00061 17,18,19,20,22,23,24,26,27,29,31,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73, 00062 77,82,86,92,97,103,109,115,122,129,137,145,154,163,173,183,194,206,218,231, 00063 244,259,274,291,308,326,346,366,388,411,435,461,489,518,549,581,616,652,691, 00064 732,776,822,871,923,978,1036,1097,1163,1232,1305,1383,1465,1552,1644,1742, 00065 1845,1955,2071,2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143, 00066 4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286,8779,9301,9854, 00067 10440,11060,11718,12415,13153,13935,14764,15642,16572,17557,18601,19708,20879, 00068 22121,23436,24830,26306 00069 }; 00070 uint16_t mapMidi(float input) { 00071 return midiTable[(int)(127.9 - input * 127.9)]; 00072 } 00073 00074 // Stepped Pentatonic mapping 00075 // 00076 uint16_t pentatonicTable[54] = { 00077 0,19,22,26,29,32,38,43,51,58,65,77,86,103,115,129,154,173,206,231,259,308,346, 00078 411,461,518,616,691,822,923,1036,1232,1383,1644,1845,2071,2463,2765,3288, 00079 3691,4143,4927,5530,6577,7382,8286,9854,11060,13153,14764,16572,19708,22121,26306 00080 }; 00081 00082 uint16_t mapPentatonic(float input) { 00083 uint8_t value = ((int)(1023.9 - input * 1023.9)) / (1024/53); 00084 return pentatonicTable[value]; 00085 } 00086 00087 void updateLatestInputValue() { 00088 // The loop is pretty simple - it just updates the parameters for the oscillators. 00089 // 00090 // Avoid using any functions that make extensive use of interrupts, or turn interrupts off. 00091 // They will cause clicks and poops in the audio. 00092 00093 #ifndef FEATURE_ORIGINAL_AUDUINO 00094 // Smooth frequency mapping 00095 syncPhaseInc = mapPhaseInc(SYNC_CONTROL) * 4.0; 00096 #endif 00097 00098 // Stepped mapping to MIDI notes: C, Db, D, Eb, E, F... 00099 //syncPhaseInc = mapMidi(SYNC_CONTROL); 00100 00101 #ifdef FEATURE_ORIGINAL_AUDUINO 00102 // Stepped pentatonic mapping: D, E, G, A, B 00103 syncPhaseInc = mapPentatonic(SYNC_CONTROL); 00104 00105 grainPhaseInc = mapPhaseInc(GRAIN_FREQ_CONTROL) * 2.0; 00106 grainDecay = GRAIN_DECAY_CONTROL * 128.0; 00107 grain2PhaseInc = mapPhaseInc(GRAIN2_FREQ_CONTROL) * 2.0; 00108 grain2Decay = GRAIN2_DECAY_CONTROL * 256.0; 00109 #else 00110 grainPhaseInc = mapPhaseInc(GRAIN_FREQ_CONTROL) * 4.0; 00111 grainDecay = GRAIN_DECAY_CONTROL * 16.0; 00112 grain2PhaseInc = mapPhaseInc(GRAIN2_FREQ_CONTROL) * 4.0; 00113 grain2Decay = GRAIN2_DECAY_CONTROL * 32.0; 00114 #endif 00115 } 00116 00117 float adjustPhaseValue(float phaseAcc) { 00118 float value = phaseAcc / 128.0; 00119 value = ((value / 256.0) - (int)(value / 256.0)) * 256.0; 00120 if (value > 256) value = 256; 00121 if (phaseAcc > 32768) value = 256 - value; 00122 return value; 00123 } 00124 00125 void interruptHandler() { 00126 float value; 00127 float output; 00128 00129 updateLatestInputValue(); 00130 00131 syncPhaseAcc += syncPhaseInc; 00132 if (syncPhaseAcc > 65536.0) { 00133 syncPhaseAcc -= 65536.0; 00134 } 00135 if (syncPhaseAcc < syncPhaseInc) { 00136 // Time to start the next grain 00137 grainPhaseAcc = 0; 00138 grainAmp = 32768.0; 00139 grain2PhaseAcc = 0; 00140 grain2Amp = 32768.0; 00141 LED_PIN = !LED_PIN; 00142 } 00143 00144 // Increment the phase of the grain oscillators 00145 grainPhaseAcc += grainPhaseInc; 00146 grain2PhaseAcc += grain2PhaseInc; 00147 if (grainPhaseAcc > 65536) grainPhaseAcc -= 65536; 00148 if (grain2PhaseAcc > 65536) grain2PhaseAcc -= 65536; 00149 00150 // Convert phase into a triangle wave 00151 value = adjustPhaseValue(grainPhaseAcc); 00152 // Multiply by current grain amplitude to get sample 00153 output = value * (grainAmp / 512.0); 00154 00155 // Repeat for second grain 00156 value = adjustPhaseValue(grain2PhaseAcc); 00157 output += value * (grain2Amp / 512.0); 00158 00159 // Make the grain amplitudes decay by a factor every sample (exponential decay) 00160 grainAmp -= (grainAmp / 256.0) * grainDecay; 00161 grain2Amp -= (grain2Amp / 256.0) * grain2Decay; 00162 00163 OUTPUT.write_u16(output); 00164 } 00165 00166 int main() { 00167 interrupt.attach_us(&interruptHandler, 32); 00168 }
Generated on Thu Jul 14 2022 23:16:07 by
![doxygen](doxygen.png)