De Octo-phonic Synthesizer (6 / 11 stap)

Stap 6: Code


Je arduino verbinden met uw computer. De onderstaande code naar je arduino uploaden.

OCTOSynth-0.2
//
Joe Marshall 2011
Resonant filter gebaseerd op Meeblip (meeblip.noisepages.com)
Onderbreken van de code van de verzoekinstellingen gebaseerd op code door Martin Nawrath (http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/)
oscillatoren en inline assembler optimalisatie door mij.
//
belangrijkste input is van 8 capacitieve ingangen van de digitale ingang 6,7 en analoge ingangen 0-6
elke invoerwaarde is een enkele draad, gonna iets metalen te raken
(Ik gebruikte een bos van grote vervoer bouten)
//
Sensing van dit wordt gedaan door getNoteKeys, met behulp van de methode beschreven op:
http://www.Arduino.CC/Playground/code/CapacitiveSensor
//
Ik gebruik assembler met een uitgerolde lus met 16 registers om te sporen dit
Dit maakt dingen veel nauwkeuriger dan de C lus beschreven op de bovenstaande link
Als we zijn het meten van de relevante vertraging in één processorcycli.
Het lijkt gelukkig zelfs met accu-energie, maximaal 8 gelijktijdige opsporen
raakt.

De golven zijn al gedefinieerd op de top, omdat we hen uitgelijnd op 256 byte grenzen dwingen
Daarmee maakt u de oscillator code sneller (als het berekenen van een verschuiving van de Golf is gewoon
een kwestie van de vervanging van de lage byte van het adres).
Hebben gezegdd dat, andere arduino dingen waarschijnlijk wordt eerst hier geladen
omdat de uitgelijnde kenmerk lijkt het toevoegen van een paar honderd bytes aan de code

#define TEST_PATTERN_INTRO

#define FILTER_LPF_NONE
#define FILTER_LPF_HACK

tabel van 256 waarden sinus / één sinus periode / opgeslagen in flash-geheugen
char sine256 [256] __attribute__ ((aligned(256))) = {}
0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45,
48, 51, 54, 57, 59, 62, 65, 67, 70, 73, 75, 78, 80, 82, 85, 87,
89, 91, 94, 96, 98, 100, 102, 103, 105, 107, 108, 110, 112, 113, 114, 116,
117, 118, 119, 120, 121, 122, 123, 123, 124, 125, 125, 126, 126, 126, 126, 126,
127 126 126, 126, 126, 126, 125, 125, 124, 123, 123, 122, 121, 120, 119, 118,
117, 116, 114, 113, 112, 110, 108, 107, 105, 103, 102, 100, 98, 96, 94, 91,
89 87, 85, 82, 80, 78, 75, 73, 70, 67, 65, 62, 59, 57, 54, 51,
48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3,
0 -3, -6, -9, -12, -15, -18,-21,-24,-27, -30, -33,-36,-39,-42,-45,
-48,-51,-54,-57,-59,-62,-65, -67,-70,-73,-75,-78, -80,-82,-85,-87,
-89,-91,-94,-96,-98,-100,-102,-103,-105,-107,-108,-110,-112,-113,-114,-116,
-117,-118,-119,-120,-121,-122,-123,-123,-124,-125,-125,-126,-126,-126,-126,-126,
-127,-126,-126,-126,-126,-126,-125,-125,-124,-123,-123,-122,-121,-120,-119,-118,
-117,-116,-114,-113,-112,-110,-108,-107,-105,-103,-102,-100,-98,-96,-94,-91,
-89,-87,-85,-82, -80,-78,-75,-73,-70, -67,-65,-62,-59,-57,-54,-51,
-48,-45,-42,-39,-36, -33, -30,-27,-24,-21, -18, -15, -12, -9, -6, -3
};

char square256 [256] __attribute__ ((aligned(256))) = {}
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127
};
char triangle256 [256] __attribute__ ((aligned(256))) = {}
-127,-125,-123,-121,-119,-117,-115,-113,-111,-109,-107,-105,-103,-101,-99,-97,
-95,-93,-91,-89,-87,-85,-83,-81,-79,-77,-75,-73,-71,-69, -67,-65,
-63,-61,-59,-57, -55,-53,-51,-49,-47,-45,-43,-41,-39,-37,-35, -33,
-31,-29,-27, -25, -23,-21, -19,-17, -15,-13, -11, -9, -7, -5, -3, -1,
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127,
129, 127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99,
97 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67,
65 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35,
33, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3,
1 -1 -3, -5, -7, -9, -11,-13, -15,-17, -19,-21, -23, -25,-27,-29,
-31 -33,-35,-37,-39,-41,-43,-45,-47,-49,-51,-53, -55,-57,-59,-61,
-63,-65 -67,-69,-71,-73,-75,-77,-79,-81,-83,-85,-87,-89,-91,-93,
-95,-97,-99,-101,-103,-105,-107,-109,-111,-113,-115,-117,-119,-121,-123,-125
};
char sawtooth256 [256] __attribute__ ((aligned(256))) = {}
-127,-127,-126,-125,-124,-123,-122,-121,-120,-119,-118,-117,-116,-115,-114,-113,
-112,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-101,-100,-99,-98,-97,
-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-84,-83,-82,-81,
-80,-79,-78,-77,-76,-75,-74,-73, -72,-71,-70,-69,-68, -67,-66,-65,
-64,-63,-62,-61, -60,-59, -58,-57,-56, -55,-54,-53,-52,-51, -50,-49,
-48,-47,-46,-45,-44,-43,-42,-41, -40,-39,-38,-37,-36,-35,-34, -33,
-32,-31 -30,-29, -28,-27,-26, -25,-24, -23, -22,-21, -20, -19, -18,-17,
-16 -15,-14,-13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127
};

#include "avr/pgmspace.h"

logboektabel voor 128 filter cutoffs
unsigned char logCutoffs[128] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x08,0x08,0x08,0x09,0x09,0x0A,0x0A,0x0A,0x0A,0x0B ,0x0C,0x0C,0x0C,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1E,0x20,0x21,0x22,0x23,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,0x32,0x34,0x36,0x38,0x3A,0x40,0x42,0x44,0x48,0x4C,0x4F,0x52,0x55,0x58,0x5D,0x61,0x65,0x68,0x6C,0x70,0x76,0x7E,0x85,0x8A,0x90,0x96,0x9D,0xA4 0xAB, 0xB0, 0xBA, 0xC4, 0xCE, 0xD8, 0xE0, 0xE8, 0xF4, 0xFF};

vluchtige unsigned int WAIT_curTime;
#define WAIT_UNTIL_INTERRUPT() WAIT_curTime = loopSteps;    while(WAIT_curTime==loopSteps) {}

#define SERIAL_OUT 0

aanval, verval zijn in 1/64ths per 125th van een seconde - ie. 1 = 0 - > 1 in een halve seconde
Const int verval = 3;
Const int aanval = 4;

vluchtige char * curWave = square256;

#define cbi (sfr, bit) (_SFR_BYTE(sfr) & ~_BV(bit)) =
#define sbi (sfr, bit) (_SFR_BYTE(sfr) | = _BV(bit))

Dit is vermoedelijk de audio klokfrequentie - als
u kunt zien, gemeten freq kan een beetje variëren van vermeende klokfrequentie
Ik ben niet helemaal zeker waarom
Const dubbele refclk = 31372.549;  = 16MHz / 510
Const dubbele refclk = 31376.6;      gemeten

variabelen die worden gebruikt binnen interrupt service aangegeven als voilatile
deze variabelen kunt u houden track van tijd - als vertraging / millis etc. zijn
inactief als gevolg van interrupts zijnde verminkte gemaakt.
volatile unsigned char loopSteps = 0; eenmaal per monster
volatile unsigned int loopStepsHigh = 0; eenmaal per 256 monsters

informatie over de huidige status van een interne oscillator
struct oscillatorPhase
{
unsigned int phaseStep;
char volume;
unsigned int phaseAccu;
};

de oscillatoren (8 van hen)
struct oscillatorPhase oscillatoren [8];

tword_m = pow (2,32) * dfreq/refclk;  calulate DDS nieuwe tuning woord
hz te krijgen -> tuning woord doen: (pow(2,16) * frequentie) / 31376.6
Const unsigned int NOTE_FREQS [25] = {273,289,307,325,344,365,386,409,434,460,487,516,546,579,613,650,688,729,773,819,867,919,974,1032,1093};

drempels voor de capacitieve sensing knoppen
int calibrationThresholds [8] = {0,0,0,0,0,0,0,0};

inline int getNoteKeys (boolean kalibreren = false)
{

char PORTD_PINS = 0b11000000; (pinnen 6-7 - Vermijd pinnen 0,1 aangezien zij worden gebruikt voor de seriële poort comms)
char PORTC_PINS = 0b111111; (analoge pins 0-5)

Const int MAX_LOOPS = 16;
char port_values [MAX_LOOPS * 2];

WAIT_UNTIL_INTERRUPT();
ASM vluchtige (
poort D lezing lus:
DDRD & = ~(PORTD_PINS = 0x3f);          pinnen 8-12 om input modus instellen
"in % [temp], 0x0a" "\n\t"
"andi % [temp], van 0x3f" "\n\t"
"out 0x0a, % [temp]" "\n\t"
PORTD | = (PORTD_PINS);          pinnen op 8-12 pullup instellen
"in % [temp], 0x0b" "\n\t"
"ori % [temp], van 0xC0" "\n\t"
"uit 0x0b, % [temp]" "\n\t"
"in %0, 0x09" "\n\t"
"in %1, 0x09" "\n\t"
"in"%2 0x09, "\n\t"
"in %3, 0x09" "\n\t"
"in %4, 0x09" "\n\t"
"in 5 %, 0x09" "\n\t"
"in 6 %, 0x09" "\n\t"
"in %7, 0x09" "\n\t"
"in %8, 0x09" "\n\t"
"in %9, 0x09" "\n\t"
"in 10%, 0x09" "\n\t"
"in % 11, 0x09" "\n\t"
"in % 12, 0x09" "\n\t"
"in % 13, 0x09" "\n\t"
"in % 14, 0x09" "\n\t"
"in % 15, 0x09" "\n\t"
:
uitgangen
"= r" (port_values[0]),
"= r" (port_values[2]),
"= r" (port_values[4]),
"= r" (port_values[6]),
"= r" (port_values[8]),
"= r" (port_values[10]),
"= r" (port_values[12]),
"= r" (port_values[14]),
"= r" (port_values[16]),
"= r" (port_values[18]),
"= r" (port_values[20]),
"= r" (port_values[22]),
"= r" (port_values[24]),
"= r" (port_values[26]),
"= r" (port_values[28]),
"= r" (port_values[30])
: [temp] "d" (0));

WAIT_UNTIL_INTERRUPT();
ASM vluchtige (
poort C lezing lus:
DDRC & = ~(PORTC_PINS = 0xc0);          pinnen 5-7 voor invoergegevens modus instellen
"in % [temp], 0x07" "\n\t"
"andi % [temp], van 0xc0" "\n\t"
"uit 0x07, % [temp]" "\n\t"
PORTC | = (PORTC_PINS);          aangezet pinnen 5-7 pullup
"in % [temp], 0x08" "\n\t"
"ori % [temp], van 0x3F" "\n\t"
"out 0x08, % [temp]" "\n\t"
"in %0, 0x06" "\n\t"
"in %1, 0x06" "\n\t"
"in"%2 0x06, "\n\t"
"in %3, 0x06" "\n\t"
"in %4, 0x06" "\n\t"
"in 5 %, 0x06" "\n\t"
"in 6 %, 0x06" "\n\t"
"in %7, 0x06" "\n\t"
"in %8, 0x06" "\n\t"
"in %9, 0x06" "\n\t"
"in 10%, 0x06" "\n\t"
"in % 11, 0x06" "\n\t"
"in % 12, 0x06" "\n\t"
"in % 13, 0x06" "\n\t"
"in % 14, 0x06" "\n\t"
"in % 15, 0x06" "\n\t"
:
uitgangen
"= r" (port_values[1]),
"= r" (port_values[3]),
"= r" (port_values[5]),
"= r" (port_values[7]),
"= r" (port_values[9]),
"= r" (port_values[11]),
"= r" (port_values[13]),
"= r" (port_values[15]),
"= r" (port_values[17]),
"= r" (port_values[19]),
"= r" (port_values[21]),
"= r" (port_values[23]),
"= r" (port_values[25]),
"= r" (port_values[27]),
"= r" (port_values[29]),
"= r" (port_values[31])
: [temp] "d" (0));

PORTC & = ~ (PORTC_PINS); pullup uit pinnen 8-12
PORTD & = ~ (PORTD_PINS); pullup uit pinnen 5-7
DDRC | = (PORTC_PINS); kwijting
DDRD | = (PORTD_PINS); kwijting

if(Calibrate)
{
voor (int c = 0, c < 8; c ++)
{
voor (int d = 0; d < MAX_LOOPS; d ++)
{
int liveNotes=((int*)port_values) [d];
liveNotes & = 0x3fc0;
liveNotes >> = 6;
Als (liveNotes & (1 << c))
{
Als (calibrationThresholds [c] < = d)
{
calibrationThresholds [c] = d + 1;
}
breken;
}
}
}
}
int liveNotes = 0;
voor (int c = 0, c < 8; c ++)
{
int val = ((int*)-port_values) [calibrationThresholds [c] + 1];
Val & = 0x3fc0;
Val >> = 6;
Als ((val & (1 << c)) == 0)
{
liveNotes| = (1 << c);
}
}
Return liveNotes;
}

krijgen Capacitieve touch op de input 4- en 3-uitgang
gebruikt voor filter modulator
inline int getfiltermodulationtime()
{
statische int running_average = 0;
statische int running_min = 1024;
statische int running_min_inc_count = 0;
statische Boole initialise_running_min = waar;

unsigned int delayTime = 0;
char PINNUM_OUT = 3;
char PINNUM_IN = 4;
char PIN_OUT = 1 << PINNUM_OUT;
char PIN_IN = 1 << PINNUM_IN;
Zorg ervoor dat ingangen / uitgangen zijn ingesteld recht
DDRD| = PIN_OUT;
DDRD & = ~ (PIN_IN);
WAIT_UNTIL_INTERRUPT();
PORTD| = PIN_OUT;
ASM vluchtige (
"loopstart % =:" "\n\t"
"sbic 0x09, [PINNUM_IN] %" "\n\t"
"rjmp outloop % =" "\n\t"
"adiw % [delayTime], van 0x01" "\n\t"
"cpi %B [delayTime], 0x02" "\n\t"
"Brně loopstart % =" "\n\t"
"% outloop =:" "\n\t"
: [delayTime] "+ & w" (delayTime)
: [PINNUM_IN] "I" (PINNUM_IN));
pin vastgelegd - misschien don't bother timing, als het lijkt niet om toe te voegen
veel nauwkeurigheid?
WAIT_UNTIL_INTERRUPT();
PORTD & = ~ PIN_OUT;
ASM)
"loopstart % =:" "\n\t"
"sbis 0x09, % [PINNUM_IN]" "\n\t"
"rjmp outloop % =" "\n\t"
"adiw % [delayTime], van 0x01" "\n\t"
"cpi %B [delayTime], 0x02" "\n\t"
"Brně loopstart % =" "\n\t"
"% outloop =:" "\n\t"
: [delayTime] "+ & w" (delayTime)
: [PINNUM_IN] "I" (PINNUM_IN));
running_average = (running_average-(running_average >> 4)) + (delayTime >> 4);
running_min_inc_count ++;
if(running_min_inc_count==255)
{
if(initialise_running_min)
{
running_min = running_average;
running_min_inc_count = 0;
initialise_running_min = false;
} else {}
running_min_inc_count = 0;
running_min ++;
}
}
if(running_average<running_min)
{
running_min = running_average;
}
int touchVal = running_average-running_min;
if(touchVal>15)
{
touchVal-= 15;
if(touchVal>99)
{
touchVal = 99;
}
} else {}
touchVal = 0;
}
Return touchVal;
}

krijgen Capacitieve touch input 5 en uitgang 3
gebruikt voor Pitchbend
inline int getpitchbendtime()
{
statische int running_average = 0;
statische int running_min = 1024;
statische int running_min_inc_count = 0;
statische Boole initialise_running_min = waar;

unsigned int delayTime = 0;
char PINNUM_OUT = 3;
char PINNUM_IN = 5;
char PIN_OUT = 1 << PINNUM_OUT;
char PIN_IN = 1 << PINNUM_IN;
Zorg ervoor dat ingangen / uitgangen zijn ingesteld recht
DDRD| = PIN_OUT;
DDRD & = ~ (PIN_IN);
WAIT_UNTIL_INTERRUPT();
PORTD| = PIN_OUT;
ASM vluchtige (
"loopstart % =:" "\n\t"
"sbic 0x09, [PINNUM_IN] %" "\n\t"
"rjmp outloop % =" "\n\t"
"adiw % [delayTime], van 0x01" "\n\t"
"cpi %B [delayTime], 0x02" "\n\t"
"Brně loopstart % =" "\n\t"
"% outloop =:" "\n\t"
: [delayTime] "+ & w" (delayTime)
: [PINNUM_IN] "I" (PINNUM_IN));
pin vastgelegd - misschien don't bother timing, als het lijkt niet om toe te voegen
veel nauwkeurigheid?
WAIT_UNTIL_INTERRUPT();
PORTD & = ~ PIN_OUT;
ASM)
"loopstart % =:" "\n\t"
"sbis 0x09, % [PINNUM_IN]" "\n\t"
"rjmp outloop % =" "\n\t"
"adiw % [delayTime], van 0x01" "\n\t"
"cpi %B [delayTime], 0x02" "\n\t"
"Brně loopstart % =" "\n\t"
"% outloop =:" "\n\t"
: [delayTime] "+ & w" (delayTime)
: [PINNUM_IN] "I" (PINNUM_IN));
running_average = (running_average-(running_average >> 4)) + (delayTime >> 4);
running_min_inc_count ++;
if(running_min_inc_count==255)
{
if(initialise_running_min)
{
running_min = running_average;
running_min_inc_count = 0;
initialise_running_min = false;
} else {}
running_min_inc_count = 0;
running_min ++;
}
}
if(running_average<running_min)
{
running_min = running_average;
}
int touchVal = running_average-running_min;
if(touchVal>15)
{
touchVal-= 15;
if(touchVal>99)
{
touchVal = 99;
}
} else {}
touchVal = 0;
}
Return touchVal;
}

unsigned int pitchBendTable [201] = {241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 249 , 249, 249, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 256,
256,256, 256, 256, 256, 256, 256, 256, 257, 257, 257, 257, 257, 257, 257, 258, 258, 258, 258, 258, 258, 259, 259, 259, 259, 259, 259, 259, 260, 260, 260, 260, 260, 260, 260, 261, 261, 261, 261, 261, 261, 262, 262, 262, 262, 262, 262, 262, 263, 263, 263, 263, 263, 263, 264, 264, 264, 264, 264, 264, 264, 265 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, 266, 267, 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 269, 269, 269, 269, 269, 269, 269, 270, 270, 270, 270, 270, 270, 271, 271};

VOID setupNoteFrequencies (int baseNote, int pitchBendVal / *-100 -> 100 * /)
{
oscillatoren [0] .phaseStep = NOTE_FREQS [baseNote];
oscillatoren [1] .phaseStep = NOTE_FREQS [baseNote + 2];
oscillatoren [2] .phaseStep = NOTE_FREQS [baseNote + 4];
oscillatoren [3] .phaseStep = NOTE_FREQS [baseNote + 5];
oscillatoren [4] .phaseStep = NOTE_FREQS [baseNote + 7];
oscillatoren [5] .phaseStep = NOTE_FREQS [baseNote + 9];
oscillatoren [6] .phaseStep = NOTE_FREQS [baseNote + 11];
oscillatoren [7] .phaseStep = NOTE_FREQS [baseNote + 12];

Als (pitchBendVal <-99)
{
pitchBendVal =-99;
} anders if(pitchBendVal>99)
{
pitchBendVal = 99;
}
Serial.Print("*");
Serial.Print(pitchBendVal);
unsigned int pitchBendMultiplier pitchBendTable = [pitchBendVal + 100];
Serial.Print(":");
Serial.Print(pitchBendMultiplier);
voor (int c = 0, c < 8; c ++)
{
vermenigvuldigen van 2 getallen van het 16-bits en 8 zonder verlies van de precisie verschuiven
vereist echt assembler
volatile unsigned char zeroReg = 0;
volatile unsigned int multipliedCounter = oscillatoren [c] .phaseStep;
ASM vluchtige
(
hoge bytes mult samen = hoge byte
"ldi %A [outVal], 0" "\n\t"
"mul %B [phaseStep], %B [pitchBend]" "\n\t"
"mov %B [outVal], r0" "\n\t"
overloop in r1 (moet nooit overloop) negeren
lage byte * hoge byte -> beide bytes
"mul %A [phaseStep], %B [pitchBend]" "\n\t"
"add %A [outVal], r0" "\n\t"
voeren in hoge byte
"adc %B [outVal], r1" "\n\t"
hoge byte * lage byte -> beide bytes
"mul %B [phaseStep], %A [pitchBend]" "\n\t"
"add %A [outVal], r0" "\n\t"
voeren in hoge byte
"adc %B [outVal], r1" "\n\t"
lage byte * lage byte -> eerste ronde
"mul %A [phaseStep], %A [pitchBend]" "\n\t"
de adc hieronder is te ronden op basis van hoge bit van lage * laag:
"adc %A [outVal], r1" "\n\t"
"adc %B [outVal], [nul] %" "\n\t"
"clr r1" "\n\t"
: [outVal] "= & d" (multipliedCounter)
: [phaseStep] "d" (.phaseStep van de oscillatoren [c]), [pitchBend] "d" (pitchBendMultiplier), [nul] "d" (zeroReg)
: "r1", "r0"
);
oscillatoren [c] .phaseStep = multipliedCounter;
}
Serial.Print(":");
Serial.Print(NOTE_FREQS[baseNote]);
Serial.Print(":");
Serial.println(Oscillators[0].phaseStep);

}

VOID Setup
{
Serial.begin(9600);        Sluit aan op de seriële poort
#ifndef FILTER_LPF_NONE
setFilter (127, 0);
#endif

pinMode (11, OUTPUT);     pin11 = PWM-uitgang / frequentie output

setupNoteFrequencies(12,0);

voor (int c = 0, c < 8; c ++)
{
oscillatoren [c] .volume = 0;
}

Setup_timer2();

uitschakelen onderbreekt om te voorkomen dat timing
CBI (TIMSK0, TOIE0);              uitschakelen van Timer0!!! delay() is nu niet beschikbaar
SBI (TIMSK2, TOIE2);              inschakelen Timer2 onderbreken

kalibreren van de ongeperst sleutelwaarden

voor (int x = 0; x < 1024; x ++)
{
getNoteKeys(true);
int stappen = loopSteps;
WAIT_UNTIL_INTERRUPT();
int afterSteps = loopSteps;
Serial.println(afterSteps-Steps);
}
test patroon intro
#ifdef TEST_PATTERN_INTRO
int filtValue = 255;
byte notes[]={0x1,0x4,0x10,0x80,0x80,0x80,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1,0x1,0x1,0x00,0x00,0x1,0x1,0x1,0x1,0x00,0x00,0x5,0x5,0x5,0x5,0x00,0x00,0x15,0x15,0x15,0x15,0x15,0x00,0x00,0x95,0x95,0x95,0x95,0x95,0x95,0x00};
voor (int Opmerking = 0; Opmerking < sizeof(notes)/sizeof(byte);note++)
{

int noteCount = 0;
voor (int c = 0, c < 8; c ++)
{
Als (notities [Opmerking] & (1 << c))
{
noteCount += 1;
}
}
voor (int c = 0, c < 8; c ++)
{
Als (notities [Opmerking] & (1 << c))
{
oscillatoren [c] .volume = 63/noteCount;
} else
{
oscillatoren [c] .volume = 0;
}
}
voor (int c = 0, c < 50; c ++)
{
misschien ook hier houden kalibreren
NB: elke kalibratie-lus = ten minste 1 interrupt

getNoteKeys(true);
#ifndef FILTER_LPF_NONE
setFilter (127-c, 64);
#endif

}
}
#else
gewoon piept om aan te tonen van de kalibratie wordt gedaan
oscillatoren [0] .volume = 63;
voor (int c = 0, c < 20; c ++)
{
WAIT_UNTIL_INTERRUPT();
}
oscillatoren [0] .volume = 63;

#endif
Serial.println("Calibrations:");
voor (int c = 0, c < 8; c ++)
{
Serial.Print(c);
Serial.Print(":");
Serial.println(calibrationThresholds[c]);
}

}

void loop
{
Wij houden een lijst bij van de 'ruwe' volumes - en het volume lager zet, als een snaar neemt > 64 volume totaal
Dit is om chording zonder vermindering van het volume van losse noten
int rawVolumes [8] = {0,0,0,0,0,0,0,0};
int curNote = 0;
unsigned int filterSweep = 64;
Const int MIN_SWEEP = 64;
Const int MAX_SWEEP = 127;
Const int SWEEP_SPEED = 3;
int sweepDir = SWEEP_SPEED;
unsigned int lastStep = loopStepsHigh;
niet-ondertekende curStep = loopStepsHigh;
while(1)
{
lastStep = curStep;
curStep = loopStepsHigh;
Opmerking: timers werken niet in deze code (interrupts uitgeschakeld / snelheden veranderd), dus denk niet zelfs over bellen: delay(), millis / micros enz.
elke loopstep is ongeveer 31250 / seconde
Deze hoofdlus zal krijgen genaamd eenmaal elke 3 of 4 samples als de uitgang voor seriële is uitgeschakeld, misschien trager anders

int liveNotes=getNoteKeys();
We zijn direct na een interrupt (zoals loopStep is gewoon opgehoogd)
we moeten dus genoeg tijd om te doen van de capacitative belangrijke controles

if(lastStep!=curStep)
{
int Zowelhettotale = 0;
voor (int c = 0, c < 8; c ++)
{
Als ((liveNotes & (1 << c)) == 0)
{
rawVolumes [c]-= DECAY*(curStep-lastStep);
Als (rawVolumes [c] < 0) rawVolumes [c] = 0;
if(SERIAL_OUT)Serial.Print(".");
}
anders
{
rawVolumes [c] += ATTACK*(curStep-lastStep);
Als (rawVolumes [c] > 63) rawVolumes [c] = 63;
if(SERIAL_OUT)Serial.Print(c);
}
Zowelhettotale += rawVolumes [c];
}
WAIT_UNTIL_INTERRUPT();
Als (Zowelhettotale < 64)
{
voor (int c = 0, c < 8; c ++)
{
oscillatoren [c] .volume = rawVolumes [c];
}
} else
{
totale volume teveel, verkleinen om Oversturing voorkomen
voor (int c = 0, c < 8; c ++)
{
oscillatoren [c] .volume =(rawVolumes[c]*63)/Zowelhettotale;
}
}
}
if(SERIAL_OUT)Serial.println("");
#ifndef FILTER_LPF_NONE
/ * if(liveNotes==0)
{
filterSweep = 64;
sweepDir = SWEEP_SPEED;
}
filterSweep += sweepDir;
Als (filterSweep > = MAX_SWEEP)
{
filterSweep = MAX_SWEEP;
sweepDir =-sweepDir;
}
else if (filterSweep < = MIN_SWEEP)
{
sweepDir =-sweepDir;
filterSweep = MIN_SWEEP;
}*/
Serial.println((int)filterValue);
filterSweep=127-(getpitchbendtime() >> 1);
WAIT_UNTIL_INTERRUPT();
setFilter(150-(getfiltermodulationtime()),220);
#endif
WAIT_UNTIL_INTERRUPT();
setupNoteFrequencies(12,-getpitchbendtime());

We zijn direct na een interrupt weer (zoals loopStep is gewoon opgehoogd)
dus we moeten het hebben van genoeg tijd om te controleren de pitch bend capaciteit zonder over een ander monster, is timing heel belangrijk hier
moet in evenwicht brengen met behulp van een groot genoeg weerstand om fatsoenlijk sensing afstand met te lang duurt om te proeven
Controleer de pitch bend-ingang

}
}
//******************************************************************
timer2 setup
prscaler ingesteld op 1, PWM-modus om de juiste PWM, 16000000/510 fase = 31372.55 Hz klok
VOID Setup_timer2() {}

Timer2 klok Prescaler aan: 1
SBI (TCCR2B, CS20);
CBI (TCCR2B, CS21);
CBI (TCCR2B, CS22);

Timer2 PWM modus ingesteld op de juiste PWM fase
CBI (TCCR2A, COM2A0);  duidelijk vergelijk Match
SBI (TCCR2A, COM2A1);

SBI (TCCR2A, WGM20);  Modus 1 / fase Correct PWM
CBI (TCCR2A, WGM21);
CBI (TCCR2B, WGM22);
}

#ifdef FILTER_LPF_BIQUAD
char filtValueA1 = 0, filtValueA2 = 0, filtValueA3 = 0, filtValueB1 = 0, filtValueB2 = 0;
volatile unsigned char filtCoeffA1 = 255;
vluchtige char filtCoeffB1 = 127;
volatile unsigned char filtCoeffB2 = 255;
#endif
#ifdef FILTER_LPF_HACK
gehackte low-pass filter - 2 polig resonant-
een += f*((in-a) + q*(a-b)
b += f * (a-b)
int filterA = 0;
int filterB = 0;
unsigned char filterQ = 0;
unsigned char filterF = 255;

inline void setFilterRaw (unsigned char filterF, unsigned char resonantie)
{
unsigned char tempReg = 0, tempReg2 = 0;
ASM vluchtige ("ldi % [tempReg], 0xff" "\n\t"
"sub % [tempReg], [filtF] %" "\n\t"
"lsr % [tempReg]" "\n\t"
"ldi % [tempReg2], van 0x04" "\n\t"
"add % [tempReg], [tempReg2] %" "\n\t"
"sub % [reso], [tempReg] %" "\n\t"
"brcc Res_Overflow % =" "\n\t"
"ldi % [reso], 0x00" "\n\t"
"Res_Overflow % =:" "\n\t"
"mov % [filtQ], van % [reso]" "\n\t"
: [tempReg] "= & d" (tempReg), [tempReg2] "= & d" (tempReg2), [filtQ] "= & d" (filterQ): [reso] "d" (resonantie), [filtF] "d" (filterF));
}

inline void setFilter (unsigned char f, unsigned char resonantie)
{
if(f>127) f = 127;
filterF = logCutoffs [f];
setFilterRaw(filterF,resonance);
}
#endif

#define HIBYTE(__x) ((char) (((unsigned int) __x) >> 8))
#define LOBYTE(__x) ((char) (((unsigned int) __x) & 0xff))

de hoofdlus oscillator (verhogen wavetable aanwijzer, en toe te voegen aan de uitgang-registers)
de instructies van het 13 - moet 14 processorcycli volgens het gegevensblad nemen
in theorie ik denk dat dit betekent dat elke oscillator 1,5% van cpu moet nemen
(plus een constante overhead voor interrupt roept enz.)
Opmerking: dit placht te doen van alle de stepvolume geladen in de buurt van het begin, maar ze zijn nu interleaved in de
code, dit is omdat ldd ("load" met offset) 2 instructies duurt
versus ld, + 1 ("load" met post increment) en st, + 1 die 1 instructie - dat kunnen we omdat:
//
a) de stap (die niet hoeven te worden opgeslagen terug) is in het geheugen voordat de
fase-accu (dat hoeft te worden opgeslagen terug zodra de stap is toegevoegd
//
b) de assumulator fase wordt opgeslagen in de lage byte, hoge bytevolgorde, betekenis dat wij
kan de eerste bytes bij elkaar optelt, dan slaan dit byte-bereik verhogen de aanwijzer,
laden van de hoge byte, voeg vervolgens de hoge bytes samen en slaan de aanwijzer te verhogen
//
Ik denk dat dit is het minimum aantal operaties mogelijk code dit oscillator in, omdat
1) er zijn 6 laden-handelingen verrichten die nodig (om te laden stepHigh/Low, phaseH/L, volume en de waarde van de Golf)
2) er zijn 2 handelingen die nodig zijn om toe te voegen aan de fase accumulator toevoegen
3) er zijn 2 winkel bewerkingen die nodig zijn om op te slaan van de fase-accumulator
4) er is 1 vermenigvuldigen (2 instructie cycli) moeten doen van het volume
5) er zijn 2 handelingen die nodig zijn om toe te voegen aan de uiteindelijke uitvoer toevoegen
//
6 + 2 + 2 + 2 + 2 = 14 instructie cycli

#define OSCILLATOR_ASM \
/ * laden fase stap en volume / \
"ld %A [tempStep], % een [stepVolume] +" "\n\t" \
"ld [tempStep], %B % een [stepVolume] +" "\n\t" \
"ld % [tempVolume], % een [stepVolume] +" "\n\t" \
/ * belasting fase accumulator - hoge byte gaat rechte * / \
/ * in de opzoekmatrix Golf (Golf is op 256 byte grens * / \
/ * zodat we dit doen kunnen zonder om het even welk toegevoegd * / \
/ * Ken de fase wordt toegevoegd tussen de twee ladingen, zoals belasting met offset langzamer dan is
gewoon een normale belasting
*/\
"ld %A [tempPhaseLow], % een [stepVolume]" "\n\t" \
/ * fase stap toevoegen lage * / \
"add % [tempPhaseLow], %A [tempStep]" "\n\t"\
/ * slaan fase accu laag * / \
"st %a [stepVolume] +, % [tempPhaseLow]" "\n\t" \
/ * laden fase accumulator hoge * / \
"ld %A [waveBase], % een [stepVolume]" "\n\t" \
/ * fase stap hoog - met carry uit de bovenstaande toevoegen toevoegen * / \
"adc %A [waveBase], %B [tempStep]" "\n\t"\
/ * slaan fase stap hoge * / \
"st %a [stepVolume] +, %A [waveBase]" "\n\t" \
/ * nu opzoeken van de Golf - hoge byte = Golf pointer, lage byte = offset * / \
"ld % [tempPhaseLow], van % een [waveBase]" "\n\t" \
/ * Nu vermenigvuldig met volume * / \
"muls % [tempPhaseLow], [tempVolume] %" "\n\t" \
/ * r0 bevat nu een sample - toevoegen als u wilt output waarde * / \
"%A toevoegen [outValue], r0" "\n\t" \
"adc %B [outValue], r1" "\n\t" \
/ * Ga naar volgende oscillator - stepVolume in het volgende wijst / \
/ * oscillator al * / \

//******************************************************************
Timer2 Interrupt Service op 31372,550 KHz = 32uSec
Dit is de tijdbasis REFCLOCK voor de DDS-generator
FOUT = (M (REFCLK)) / (2 exp 32)
runtime:?
ISR(TIMER2_OVF_vect) {}

nu het opzetten van de volgende waarde
deze lus neemt ongeveer 172 cycli (214 met inbegrip van de push/pop's) - we hebben 510, zo ongeveer 50% van de processor gaan reserve voor niet-audio taken
het low-pass filter neemt ook sommige cycli

int outValue;

verwijzingen:
X = oscillator fase accumulator
Y = oscillator stap en volume
Z = Golf pos - moet toevoegen als u wilt baseren
int tempStep = 0;
char tempPhaseLow = 0, tempVolume = 0;
int tempWaveBase = 0;
ASM vluchtige (
"ldi %A [outValue], 0" "\n\t"
"ldi %B [outValue], 0" "\n\t"
oscillator 0
uncomment de code hieronder te controleren
dat registers dubbele niet krijgen toegewezen
/ * "lds %A [outValue], 0x00" "\n\t"
"lds %B [outValue], 0x01" "\n\t"
"lds %A [tempPhaseLow], 0x02" "\n\t"
"lds %B [tempPhase], 0x03" "\n\t"
"lds %A [tempStep], 0x04" "\n\t"
"lds %B [tempStep], 0x05" "\n\t"
"lds % [tempVolume], van 0x06" "\n\t"
"lds % [nul], van 0x07" "\n\t"
"lds %A [tempWaveBase], 0x08" "\n\t"
"lds %B [tempWaveBase], 0x09" "\n\t"
"lds %A [phaseAccu], 0x0a" "\n\t"
"lds %B [phaseAccu], 0x0b" "\n\t"
"lds %A [stepVolume], 0x0c" "\n\t"
"lds %B [stepVolume], 0x0d" "\n\t"
"lds %A [waveBase], 0x0e" "\n\t"
"lds %B [waveBase], 0x0f" "\n\t"*/
OSCILLATOR_ASM
OSCILLATOR_ASM
OSCILLATOR_ASM
OSCILLATOR_ASM
OSCILLATOR_ASM
OSCILLATOR_ASM
OSCILLATOR_ASM
OSCILLATOR_ASM
:
uitgangen
[tempPhaseLow] "= & d" (tempPhaseLow),
[tempStep] "= & d" (tempStep),
[tempVolume] "= & d" (tempVolume),
[outValue] "= & d" (outValue)
:
ingangen
[stepVolume] "y" (& oscillators[0].phaseStep),
[waveBase] "z" (256 * (((unsigned int) curWave) >> 8))
:
andere registers die we wissen (door het doen van vermenigvuldigingen)
"r1"
);

op dit punt outValue = oscillator waarde
het is op dit moment op vol volume maxed / 4
dat sommige stahoogte voor het filteren


#ifdef FILTER_LPF_HACK

een low pass filter op basis van de definitie van MeeBlip (http://meeblip.noisepages.com)
een += f*((in-a) + q*(a-b)
b += f * (a-b)
outValue >> = 3;
begon op 4700
4686
int tempReg, tempReg2 = 0;
unsigned char zeroRegFilt = 0;
de-volatilisati
unsigned char filtF = filterF;
unsigned char filtQ = filterQ;
ASM vluchtige (
"sub %A [outVal], %A [filtA]" "\n\t"
"sbc %B [outVal], %B [filtA]" "\n\t"
"brvc No_overflow1% =" "\n\t"
"ldi %A [outVal], 0b00000001" "\n\t"
"ldi %B [outVal], 0b10000000" "\n\t"
"No_overflow1% =:" "\n\t"
outVal = (in - filtA)
"mov %A [tempReg], %A [filtA]" "\n\t"
"mov %B [tempReg], %B [filtA]" "\n\t"
"sub %A [tempReg], %A [filtB]" "\n\t"
"sbc %B [tempReg], %B [filtB]" "\n\t"
"brvc No_overflow3% =" "\n\t"
"ldi %A [tempReg], 0b00000001" "\n\t"
"ldi %B [tempReg], 0b10000000" "\n\t"
"No_overflow3% =:" "\n\t"
tempReg = (a-b)
"mulsu %B [tempReg], [filtQ] %" "\n\t"
"movw %A [tempReg2], r0" "\n\t"
tempReg2 = (HIBYTE(a-b)) * Q
"mul %A [tempReg], [filtQ] %" "\n\t"
"add %A [tempReg2], r1" "\n\t"
"adc %B [tempReg2], [nul] %" "\n\t"
"rol r0" "\n\t"
"brcc No_Round1% =" "\n\t"
"incl. %A [tempReg2]" "\n\t"
"No_Round1% =:" "\n\t"
op dit punt tempReg2 = (a-b) * Q (verschoven naar behoren en afgerond)
"clc" "\n\t"
"lsl %A [tempReg2]" "\n\t"
"rol %B [tempReg2]" "\n\t"
"clc" "\n\t"
"lsl %A [tempReg2]" "\n\t"
"rol %B [tempReg2]" "\n\t"
tempReg2 = (a-b) * Q * 4
"add %A [outVal], %A [tempReg2]" "\n\t"
"adc %B [outVal], %B [tempReg2]" "\n\t"
"brvc No_overflow4% =" "\n\t"
"ldi %A [outVal], 0b11111111" "\n\t"
"ldi %B [outVal], 0b01111111" "\n\t"
"No_overflow4% =:" "\n\t"
outVal = ((in-a) + (a-b) * (Q >> 8) * 4) - geknipte enz
"mulsu %B [outVal], [filtF] %" "\n\t"
"movw %A [tempReg], r0" "\n\t"
"mul %A [outVal], [filtF] %" "\n\t"
"add %A [tempReg], r1" "\n\t"
"adc %B [tempReg], [nul] %" "\n\t"
"rol r0" "\n\t"
"brcc No_Round2% =" "\n\t"
"incl. %A [tempReg]" "\n\t"
tempReg = f * ((in-a) + (a-b) * (Q >> 8) * 4)
"No_Round2% =:" "\n\t"
"add %A [filtA], %A [tempReg]" "\n\t"
"adc %B [filtA], %B [tempReg]" "\n\t"
A = A + f * ((in-a) + (a-b) * (Q >> 8) * 4)
"brvc No_overflow5% =" "\n\t"
"ldi %A [outVal], 0b11111111" "\n\t"
"ldi %B [outVal], 0b01111111" "\n\t"
"No_overflow5% =:" "\n\t"
Nu berekenen B = f * (a - b)

"mov %A [tempReg], %A [filtA]" "\n\t"
"mov %B [tempReg], %B [filtA]" "\n\t"
"sub %A [tempReg], %A [filtB]" "\n\t"
"sbc %B [tempReg], %B [filtB]" "\n\t"
"brvc No_overflow6% =" "\n\t"
"ldi %A [tempReg], 0b00000001" "\n\t"
"ldi %B [tempReg], 0b10000000" "\n\t"
"No_overflow6% =:" "\n\t"
tempReg = (a-b)
"mulsu %B [tempReg], [filtF] %" "\n\t"
"movw %A [tempReg2], r0" "\n\t"
"mul %A [tempReg], [filtF] %" "\n\t"
"add %A [tempReg2], r1" "\n\t"
"adc %B [tempReg2], [nul] %" "\n\t"
tempReg2 = f*(a-b)
"add %A [filtB], %A [tempReg2]" "\n\t"
"adc %B [filtB], %B [tempReg2]" "\n\t"
"brvc No_overflow7% =" "\n\t"
"ldi %A [filtB], 0b11111111" "\n\t"
"ldi %B [filtB], 0b01111111" "\n\t"
"No_overflow7% =:" "\n\t"
nu b = b+f*(a-b)
"mov %A [outVal], %A [filtB]" "\n\t"
"mov %B [outVal], %B [filtB]" "\n\t"

vermenigvuldigen van outval door 4 en clip
"add %A [outVal], %A [filtB]" "\n\t"
"adc %B [outVal], %B [filtB]" "\n\t"
"brbs 3, Overflow_End % =" "\n\t"

"add %A [outVal], %A [filtB]" "\n\t"
"adc %B [outVal], %B [filtB]" "\n\t"
"brbs 3, Overflow_End % =" "\n\t"

"add %A [outVal], %A [filtB]" "\n\t"
"adc %B [outVal], %B [filtB]" "\n\t"
"brbs 3, Overflow_End % =" "\n\t"
"rjmp No_overflow % =" "\n\t"
"Overflow_End % =:" "\n\t"
"brbs 2, Overflow_High % =" "\n\t"
"ldi %A [outVal], 0b00000001" "\n\t"
"ldi %B [outVal], 0b10000000" "\n\t"
"rjmp No_overflow % =" "\n\t"
"Overflow_High % =:" "\n\t"
"ldi %A [outVal], 0b11111111" "\n\t"
"ldi %B [outVal], 0b01111111" "\n\t"
"No_overflow % =:" "\n\t"
char valOut = ((niet-ondertekende int)(outValue)) >> 8;
valOut += 128;
OCR2A = (byte) valOut;
"subi %B [outVal], 0x80" "\n\t"
"St 0x00b3, %B [outVal]" "\n\t"
uncomment de regels hieronder om te zien de register-toewijzingen
/*
"lds %A [filtA], 0x01" "\n\t"
"lds %B [filtA], 0x02" "\n\t"
"lds %A [filtB], 0x03" "\n\t"
"lds %B [filtB], 0x04" "\n\t"
"lds % [filtQ], van 0x05" "\n\t"
"lds % [filtF], van 0x06" "\n\t"
"lds %A [outVal], 0x07" "\n\t"
"lds %B [outVal], 0x08" "\n\t"
"lds %A [tempReg], 0x09" "\n\t"
"lds %B [tempReg], 0x0a" "\n\t"
"lds %A [tempReg2], 0x0b" "\n\t"
"lds %B [tempReg2], 0x0c" "\n\t"
"lds % [nul], van 0x0d" "\n\t"*/
:
uitgangen / lees/schrijf argumenten
[filtA] "+ & w" (filterA),
[filtB] "+ & w" (filterB),
[tempReg] "= & een" (tempReg),
[tempReg2] "= & d" (tempReg2)
:
[filtQ] "a" (filtQ),
[filtF] "a" (filtF),
[outVal] 'a' outValue (),
[NUL] "d" (zeroRegFilt)
ingangen
: "r1");

#endif

output is gedaan in de filter assembler code als filters op
anders uitvoeren wij met de hand hier
#ifdef FILTER_LPF_NONE
volle winst
outValue * = 4;
op dit punt, outValue is een 16-bits ondertekende versie van wat we ie willen. 0 -> 32767, dan-32768 -> -1 (0xffff)
Wij willen 0 -> 32767 Ga naar 32768-65535 en-32768 -> -1 naar 0-32767, dan we willen alleen de hoogste byte
hoogste byte, neem dan toevoegen van 128, dan verdrijft naar niet-ondertekende. De (unsigned int) in het hieronder is vermijden moetend verschuiven (ie.just neemt top byte)
char valOut = ((niet-ondertekende int)(outValue)) >> 8;
valOut += 128;
OCR2A = (byte) valOut;
#endif
_ / / verhogen de lus stap counter (en hoge teller)
deze worden gebruikt omdat we stoppen met de timer
Interrupt uitgevoerd, dus geen andere manier tijd te vertellen hebben
Deze asm is waarschijnlijk niet echt nodig, maar het slaat ongeveer 10 instructies
omdat de variabelen moeten vluchtige
ASM)
"inc % [loopSteps]" "\n\t"
"brbc 1, loopend % =" "\n\t"
"incl. %A [loopStepsHigh]" "\n\t"
"brbc 1, loopend % =" "\n\t"
"incl. %B [loopStepsHigh]" "\n\t"
"loopend % =:" "\n\t"
: [loopSteps] "+ a" (loopSteps), [loopStepsHigh] "+ a" (loopStepsHigh):);
}

Gerelateerde Artikelen

Eurorack modulaire synthesizer base

Eurorack modulaire synthesizer base

Ik had een base nodig voor mijn eurorack modulaire synthesizer. Mijn eisen waren: 3 rijen van 84hp, en het moeten passen goed recht onder mijn geval Doepfer A - 100P 9. Ik wilde proberen lasersnijden voor enige tijd. Mijn lokale fablab biedt bovendie
NE555 timer synthesizer

NE555 timer synthesizer

Hallo, zie ik je wan't te weten hoe maak je een NE555 timer op basis van 3 octave synthesizer die past in een trommeltje. Nou, kwam u aan het juiste adres :)Voor dit project zal u het volgende nodig:1. 36 voelbare knoppen (knoppen van de zelfde soort
Synthesizer: Een toetsenbord UI met Audio uitgang

Synthesizer: Een toetsenbord UI met Audio uitgang

We bouwden een toetsenbord UI met vijf synthese wijzen allemaal in Javascript, zodat de kracht van het gebruik van de audio-uitgang hardware pinnen van Kinoma maken. U kunt het open source project nu downloaden als u wilt uitvoeren in de simulator Ki
De Arduino Synthesizer

De Arduino Synthesizer

De Arduino vermag geluid afspelen via een library die heeft ontwikkeld, genaamd de Tone Library.Door het creëren van een interface en een programma dat bepaalde waarden om te worden uitgevoerd naar een audio-uitgang kan bellen, is de Synthesizer van
Octo-Light: LED Camera Ring

Octo-Light: LED Camera Ring

De Octo-Light is een camera-ring-lamp die is opgebouwd uit LED licht strips. Het is goedkoop om te maken en perfect voor beginner macrofotografie en video!Deze lamp is uitstekend op overstromingen scènes met uniforme licht, dat verzacht harde schaduw
Ontwerpen en bouwen van een synthesizer met Meeblip en Arduino, video's toegevoegd!

Ontwerpen en bouwen van een synthesizer met Meeblip en Arduino, video's toegevoegd!

Voor mijn stage bij Digitale muziek maken/Meeblip heb ik een heel leuke kleine synthesizer. Dit ding is bedoeld om te worden flexibeler dan andere synthesizer doordat het volledig onafhankelijk is; het is op batterijen, heeft een eigen versterker/lui
Menselijke Synthesizer/Game Controller

Menselijke Synthesizer/Game Controller

IntroductieU kunt leren hoe te spelen van een toetsenbord solo door het geven van uw vrienden een high-five! Door het geven van uw vrienden een high-five, ook kunt u een Tetromino of eekhoorn kampioen worden! Volg dan de instructies hieronder om een
Hoe maak je een Arduino sound synthesizer met MIDI-interface

Hoe maak je een Arduino sound synthesizer met MIDI-interface

Met deze synthesizer kun je Arduino reproduceren van volledig aangepaste golfvormen. Als gevolg van de MIDI-interface, kan het worden aangesloten op alle instrumenten die dergelijke functie en spelen met het gewenste geluid.Stap 1: materialen(In dit
Directe digitale Synthesizer gebaseerd op gewone Arduino

Directe digitale Synthesizer gebaseerd op gewone Arduino

Microcontroller is bedoeld om spullen en niet te genereren periodiekesignalen - hiervoor stellen dat we een speciale hardware - zoiets als Atmega328 en AD9850 zou gebruiken.Maar aan de andere kant zou dit een interessant project - niet erg nuttig, ma
Na vak Synthesizer

Na vak Synthesizer

In dit project, neem een oude post doos en een Arduino, maken een ongelooflijk functionele monofone synthesizer. Deze synthesizer omvat dergelijke functies als:-Dual oscillatoren-6 Golf vormen (zonde, driehoek, links zag, recht zag, Square, Flat)-Rui
Ontwerpen en bouwen van een 'akoestische' synthesizer

Ontwerpen en bouwen van een 'akoestische' synthesizer

voor mijn stage bij Digitale muziek maken/Meeblip heb ik een heel leuke kleine synthesizer. Dit ding is bedoeld om te worden flexibeler dan andere synthesizer doordat het volledig onafhankelijk is; het is op batterijen, heeft een eigen versterker/lui
Pocket Sized Synthesizer

Pocket Sized Synthesizer

deze kleine-maar-machtige zak synthesizer kan worden gebruikt om te spelen die tune die in uw hoofd on-the-go, paniek weg ongewenste dieren vastzit, of te ergeren de heck van uw vrienden en familie. De Toon is een blokgolf en afhankelijk van welke wa
Protosynth: Prototyping Synthesizer!

Protosynth: Prototyping Synthesizer!

Er zijn zoveel verschillende soorten synthesizers die er die zijn premade voorgeprogrammeerd en relatief vergrendeld op het gebied van effecten. We dachten mensen om te experimenteren met meer analoge effecten, met eigen circuits maken een synthesize
Mijn eerste synthesizer

Mijn eerste synthesizer

de jong geitje synth kwam over als ik gebogen over een verwarde puinhoop van synthesizer draden zat. Mijn vriend kwam Oliver, de situatie beoordeeld, en zei: "Je weet dat je geslaagd in het maken van's werelds meest gecompliceerde Kinder speelgoed.&q