AUDUINO
Autor: calebML | Publicado: 2015-09-02T16:56:00-07:00




// Auduino, the Lo-Fi granular synthesiser
//
// by Peter Knight, Tinker.it http://tinker.it
//
// Help: &nbsp; &nbsp; &nbsp;http://code.google.com/p/tinkerit/wiki/Auduino
// More help: http://groups.google.com/group/auduino
//
// Analog in 0: Grain 1 pitch
// Analog in 1: Grain 2 decay
// Analog in 2: Grain 1 decay
// Analog in 3: Grain 2 pitch
// Analog in 4: Grain repetition frequency
//
// Digital 3: Audio out (Digital 11 on ATmega8)
//
// Changelog:
// 19 Nov 2008: Added support for ATmega8 boards
// 21 Mar 2009: Added support for ATmega328 boards
// 7 Apr 2009: Fixed interrupt vector for ATmega328 boards
// 8 Apr 2009: Added support for ATmega1280 boards (Arduino Mega)

#include &lt;avr/io.h&gt;
#include &lt;avr/interrupt.h&gt;

uint16_t syncPhaseAcc;
uint16_t syncPhaseInc;
uint16_t grainPhaseAcc;
uint16_t grainPhaseInc;
uint16_t grainAmp;
uint8_t grainDecay;
uint16_t grain2PhaseAcc;
uint16_t grain2PhaseInc;
uint16_t grain2Amp;
uint8_t grain2Decay;

// Map Analogue channels
#define SYNC_CONTROL &nbsp; &nbsp; &nbsp; &nbsp; (4)
#define GRAIN_FREQ_CONTROL &nbsp; (0)
#define GRAIN_DECAY_CONTROL &nbsp;(2)
#define GRAIN2_FREQ_CONTROL &nbsp;(3)
#define GRAIN2_DECAY_CONTROL (1)


// Changing these will also requires rewriting audioOn()

#if defined(__AVR_ATmega8__)
//
// On old ATmega8 boards.
// &nbsp; &nbsp;Output is on pin 11
//
#define LED_PIN &nbsp; &nbsp; &nbsp; 13
#define LED_PORT &nbsp; &nbsp; &nbsp;PORTB
#define LED_BIT &nbsp; &nbsp; &nbsp; 5
#define PWM_PIN &nbsp; &nbsp; &nbsp; 11
#define PWM_VALUE &nbsp; &nbsp; OCR2
#define PWM_INTERRUPT TIMER2_OVF_vect
#elif defined(__AVR_ATmega1280__)
//
// On the Arduino Mega
// &nbsp; &nbsp;Output is on pin 3
//
#define LED_PIN &nbsp; &nbsp; &nbsp; 13
#define LED_PORT &nbsp; &nbsp; &nbsp;PORTB
#define LED_BIT &nbsp; &nbsp; &nbsp; 7
#define PWM_PIN &nbsp; &nbsp; &nbsp; 3
#define PWM_VALUE &nbsp; &nbsp; OCR3C
#define PWM_INTERRUPT TIMER3_OVF_vect
#else
//
// For modern ATmega168 and ATmega328 boards
// &nbsp; &nbsp;Output is on pin 3
//
#define PWM_PIN &nbsp; &nbsp; &nbsp; 3
#define PWM_VALUE &nbsp; &nbsp; OCR2B
#define LED_PIN &nbsp; &nbsp; &nbsp; 13
#define LED_PORT &nbsp; &nbsp; &nbsp;PORTB
#define LED_BIT &nbsp; &nbsp; &nbsp; 5
#define PWM_INTERRUPT TIMER2_OVF_vect
#endif

// Smooth logarithmic mapping
//
uint16_t antilogTable[] = {
&nbsp; 64830,64132,63441,62757,62081,61413,60751,60097,59449,58809,58176,57549,56929,56316,55709,55109,
&nbsp; 54515,53928,53347,52773,52204,51642,51085,50535,49991,49452,48920,48393,47871,47356,46846,46341,
&nbsp; 45842,45348,44859,44376,43898,43425,42958,42495,42037,41584,41136,40693,40255,39821,39392,38968,
&nbsp; 38548,38133,37722,37316,36914,36516,36123,35734,35349,34968,34591,34219,33850,33486,33125,32768
};
uint16_t mapPhaseInc(uint16_t input) {
&nbsp; return (antilogTable[input &amp; 0x3f]) &gt;&gt; (input &gt;&gt; 6);
}

// Stepped chromatic mapping
//
uint16_t midiTable[] = {
&nbsp; 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,
&nbsp; 77,82,86,92,97,103,109,115,122,129,137,145,154,163,173,183,194,206,218,231,
&nbsp; 244,259,274,291,308,326,346,366,388,411,435,461,489,518,549,581,616,652,691,
&nbsp; 732,776,822,871,923,978,1036,1097,1163,1232,1305,1383,1465,1552,1644,1742,
&nbsp; 1845,1955,2071,2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143,
&nbsp; 4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286,8779,9301,9854,
&nbsp; 10440,11060,11718,12415,13153,13935,14764,15642,16572,17557,18601,19708,20879,
&nbsp; 22121,23436,24830,26306
};
uint16_t mapMidi(uint16_t input) {
&nbsp; return (midiTable[(1023-input) &gt;&gt; 3]);
}

// Stepped Pentatonic mapping
//
uint16_t pentatonicTable[54] = {
&nbsp; 0,19,22,26,29,32,38,43,51,58,65,77,86,103,115,129,154,173,206,231,259,308,346,
&nbsp; 411,461,518,616,691,822,923,1036,1232,1383,1644,1845,2071,2463,2765,3288,
&nbsp; 3691,4143,4927,5530,6577,7382,8286,9854,11060,13153,14764,16572,19708,22121,26306
};

uint16_t mapPentatonic(uint16_t input) {
&nbsp; uint8_t value = (1023-input) / (1024/53);
&nbsp; return (pentatonicTable[value]);
}


void audioOn() {
#if defined(__AVR_ATmega8__)
&nbsp; // ATmega8 has different registers
&nbsp; TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
&nbsp; TIMSK = _BV(TOIE2);
#elif defined(__AVR_ATmega1280__)
&nbsp; TCCR3A = _BV(COM3C1) | _BV(WGM30);
&nbsp; TCCR3B = _BV(CS30);
&nbsp; TIMSK3 = _BV(TOIE3);
#else
&nbsp; // Set up PWM to 31.25kHz, phase accurate
&nbsp; TCCR2A = _BV(COM2B1) | _BV(WGM20);
&nbsp; TCCR2B = _BV(CS20);
&nbsp; TIMSK2 = _BV(TOIE2);
#endif
}


void setup() {
&nbsp; pinMode(PWM_PIN,OUTPUT);
&nbsp; audioOn();
&nbsp; pinMode(LED_PIN,OUTPUT);
}

void loop() {
&nbsp; // The loop is pretty simple - it just updates the parameters for the oscillators.
&nbsp; //
&nbsp; // Avoid using any functions that make extensive use of interrupts, or turn interrupts off.
&nbsp; // They will cause clicks and poops in the audio.
&nbsp;
&nbsp; // Smooth frequency mapping
&nbsp; //syncPhaseInc = mapPhaseInc(analogRead(SYNC_CONTROL)) / 4;
&nbsp;
&nbsp; // Stepped mapping to MIDI notes: C, Db, D, Eb, E, F...
&nbsp; //syncPhaseInc = mapMidi(analogRead(SYNC_CONTROL));
&nbsp;
&nbsp; // Stepped pentatonic mapping: D, E, G, A, B
&nbsp; syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL));

&nbsp; grainPhaseInc &nbsp;= mapPhaseInc(analogRead(GRAIN_FREQ_CONTROL)) / 2;
&nbsp; grainDecay &nbsp; &nbsp; = analogRead(GRAIN_DECAY_CONTROL) / 8;
&nbsp; grain2PhaseInc = mapPhaseInc(analogRead(GRAIN2_FREQ_CONTROL)) / 2;
&nbsp; grain2Decay &nbsp; &nbsp;= analogRead(GRAIN2_DECAY_CONTROL) / 4;
}

SIGNAL(PWM_INTERRUPT)
{
&nbsp; uint8_t value;
&nbsp; uint16_t output;

&nbsp; syncPhaseAcc += syncPhaseInc;
&nbsp; if (syncPhaseAcc &lt; syncPhaseInc) {
&nbsp; &nbsp; // Time to start the next grain
&nbsp; &nbsp; grainPhaseAcc = 0;
&nbsp; &nbsp; grainAmp = 0x7fff;
&nbsp; &nbsp; grain2PhaseAcc = 0;
&nbsp; &nbsp; grain2Amp = 0x7fff;
&nbsp; &nbsp; LED_PORT ^= 1 &lt;&lt; LED_BIT; // Faster than using digitalWrite
&nbsp; }
&nbsp;
&nbsp; // Increment the phase of the grain oscillators
&nbsp; grainPhaseAcc += grainPhaseInc;
&nbsp; grain2PhaseAcc += grain2PhaseInc;

&nbsp; // Convert phase into a triangle wave
&nbsp; value = (grainPhaseAcc &gt;&gt; 7) &amp; 0xff;
&nbsp; if (grainPhaseAcc &amp; 0x8000) value = ~value;
&nbsp; // Multiply by current grain amplitude to get sample
&nbsp; output = value * (grainAmp &gt;&gt; 8);

&nbsp; // Repeat for second grain
&nbsp; value = (grain2PhaseAcc &gt;&gt; 7) &amp; 0xff;
&nbsp; if (grain2PhaseAcc &amp; 0x8000) value = ~value;
&nbsp; output += value * (grain2Amp &gt;&gt; 8);

&nbsp; // Make the grain amplitudes decay by a factor every sample (exponential decay)
&nbsp; grainAmp -= (grainAmp &gt;&gt; 8) * grainDecay;
&nbsp; grain2Amp -= (grain2Amp &gt;&gt; 8) * grain2Decay;

&nbsp; // Scale output to the available range, clipping if necessary
&nbsp; output &gt;&gt;= 9;
&nbsp; if (output &gt; 255) output = 255;

&nbsp; // Output to PWM (this is faster than using analogWrite) 
&nbsp; PWM_VALUE = output;
}