diff --git a/projekte/soundz/_8bit/_8bit.pde b/projekte/soundz/_8bit/_8bit.pde new file mode 100644 index 0000000..6e4d5a7 --- /dev/null +++ b/projekte/soundz/_8bit/_8bit.pde @@ -0,0 +1,163 @@ +/* + * Soundcode von: Michael Smith - http://www.arduino.cc/playground/Code/PCMAudio + * CapSense: http://www.arduino.cc/playground/Main/CapSense + * basierend auf code von Alex Wenger 2009 ("Arduino Physical Computing ...") + */ +#include +#include +#include +#include +#include + +// Audioausgabe +#define SAMPLE_RATE 8000 + +// Auf welchem PIN soll Audio ausgegeben werden? (nicht Ändern!!!) +int speakerPin = 11; + +const unsigned char sintab[] PROGMEM = { + 0x01,0x01,0x01,0x01,0x02,0x03,0x05,0x07, + 0x09,0x0c,0x0f,0x12,0x15,0x19,0x1c,0x21, + 0x25,0x29,0x2e,0x33,0x38,0x3d,0x43,0x48, + 0x4e,0x54,0x5a,0x60,0x66,0x6c,0x73,0x79, + 0x7f,0x85,0x8b,0x92,0x98,0x9e,0xa4,0xaa, + 0xb0,0xb6,0xbb,0xc1,0xc6,0xcb,0xd0,0xd5, + 0xd9,0xdd,0xe2,0xe5,0xe9,0xec,0xef,0xf2, + 0xf5,0xf7,0xf9,0xfb,0xfc,0xfd,0xfe,0xfe, + 0xfe,0xfe,0xfe,0xfd,0xfc,0xfb,0xf9,0xf7, + 0xf5,0xf2,0xef,0xec,0xe9,0xe5,0xe2,0xdd, + 0xd9,0xd5,0xd0,0xcb,0xc6,0xc1,0xbb,0xb6, + 0xb0,0xaa,0xa4,0x9e,0x98,0x92,0x8b,0x85, + 0x7f,0x79,0x73,0x6c,0x66,0x60,0x5a,0x54, + 0x4e,0x48,0x43,0x3d,0x38,0x33,0x2e,0x29, + 0x25,0x21,0x1c,0x19,0x15,0x12,0x0f,0x0c, + 0x09,0x07,0x05,0x03,0x02,0x01,0x01,0x01 +}; + + +volatile uint16_t sample1; // welches ist das nächste Sample aus der Sinustabelle +// die oberen 7 bit zeigen in die Tabelle, die restlichen +// bits sind kommastellen +volatile uint16_t sample2; +volatile uint16_t sample3; + +uint16_t vol; // aktuelle Lautstärke +volatile uint16_t set_vol; // gewuenschte Lautstärke +volatile uint16_t tone1; // Tonhöhe in "Inkrementiereinheiten" +volatile uint16_t tone2; // Tonhöhe in "Inkrementiereinheiten" +volatile uint16_t tone3; // Tonhöhe in "Inkrementiereinheiten" + + +// Interruptroutine, diese wird 8000 mal pro Sekunde aufgerufen und berechnet den nächsten +// Wert für die Tonausgabe +ISR(TIMER1_COMPA_vect) { + static int timer1counter; // Zähler um Lautstärkeänderung langsamer zu machen + int wert; + + // Wert an der Stelle sample1/512 aus der sinus-Tabelle lesen + wert = pgm_read_byte(&sintab[(sample1 >> 9)])+ + pgm_read_byte(&sintab[(sample2 >> 9)])+ + pgm_read_byte(&sintab[(sample3 >> 9)]); + // Wert mit der aktuellen Lautstärke multiplizieren + wert = (wert * vol) / 256; + // PWM Hardware anweisen ab jetzt diesen Wert auszugeben + OCR2A = wert; + + // nächstes Sample in der Sinustabelle abhängig vom gewünschten + // Ton auswählen. + sample1 += tone1; + sample2 += tone2; + sample3 += tone3; + + // Lautstärke anpassen wen gewünscht (nur alle 50 Interrupts, damit + // es schön langsam passiert. + timer1counter++; + if (timer1counter > 50) + { + timer1counter = 0; + if (vol < set_vol) vol++; + if (vol > set_vol) vol--; + } +} + +void startPlayback() +{ + pinMode(speakerPin, OUTPUT); + + // Initialisiere den Timer 2 für die schnelle PWM zur + // Soundausgabe auf Pin 11 + + // Verwende den internen Takt (Datenblatt Seite 160) + ASSR &= ~(_BV(EXCLK) | _BV(AS2)); + + // Fast PWM mode (Seite 157) + TCCR2A |= _BV(WGM21) | _BV(WGM20); + TCCR2B &= ~_BV(WGM22); + + // Wähle die nicht invertierende PWM für pin OC2A und OC2B + // Am Arduino ist das Pin 11 und 3 + TCCR2A = (TCCR2A | _BV(COM2A1) | _BV(COM2B1)); + + // Keine Vorteiler / wir wollen es schnell! (Seite 158) + TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); + + // Start Wert = 0, sonst gibt es ein hässliches Ploppgeräusch + OCR2A = 0; + OCR2B = 0; + + // Initialisiere Timer 1 für 8000 Interrupts/Sekunde + cli(); + + // Set CTC mode (Clear Timer on Compare Match) (Seite 133) + TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12); + TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10)); + + // Kein Vorteiler (Seite 134) + TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); + + // Gewünschte Frequenz = 8000kHz + OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000 + + // Aktiviere den Interrupt für TCNT1 == OCR1A (Seite 136) + TIMSK1 |= _BV(OCIE1A); + + // Startwerte + sample1 = 0; + sample2 = 0; + sample3 = 0; + + // Global Interrupts wieder einschalten. + sei(); +} + +// Aendert Ton und Lautstärke +// ton (50-4000Hz) +// volume (0-256); +void SetFreq(int ton1,int ton2, int ton3, int volume) +{ + tone1 = (128ul*512ul*ton1)/8000; + tone2 = (128ul*512ul*ton2)/8000; + tone3 = (128ul*512ul*ton3)/8000; + set_vol = volume; +} + +void setup() +{ + startPlayback(); +} + +#include "pitches.h" +void loop() +{ + for(int counter = 0; counter<256; counter++) { + SetFreq((counter & _BV(0))?(NOTE_C4):0, + (counter & _BV(1))?(NOTE_A3):0, + (counter & _BV(2))?(NOTE_F3):0, + 80); + if ((counter % 8) != 0) { + _delay_ms(500); + } + } +} + + diff --git a/projekte/soundz/_8bit/pitches.h b/projekte/soundz/_8bit/pitches.h new file mode 100644 index 0000000..55c7d54 --- /dev/null +++ b/projekte/soundz/_8bit/pitches.h @@ -0,0 +1,95 @@ +/************************************************* + * Public Constants + *************************************************/ + +#define NOTE_B0 31 +#define NOTE_C1 33 +#define NOTE_CS1 35 +#define NOTE_D1 37 +#define NOTE_DS1 39 +#define NOTE_E1 41 +#define NOTE_F1 44 +#define NOTE_FS1 46 +#define NOTE_G1 49 +#define NOTE_GS1 52 +#define NOTE_A1 55 +#define NOTE_AS1 58 +#define NOTE_B1 62 +#define NOTE_C2 65 +#define NOTE_CS2 69 +#define NOTE_D2 73 +#define NOTE_DS2 78 +#define NOTE_E2 82 +#define NOTE_F2 87 +#define NOTE_FS2 93 +#define NOTE_G2 98 +#define NOTE_GS2 104 +#define NOTE_A2 110 +#define NOTE_AS2 117 +#define NOTE_B2 123 +#define NOTE_C3 131 +#define NOTE_CS3 139 +#define NOTE_D3 147 +#define NOTE_DS3 156 +#define NOTE_E3 165 +#define NOTE_F3 175 +#define NOTE_FS3 185 +#define NOTE_G3 196 +#define NOTE_GS3 208 +#define NOTE_A3 220 +#define NOTE_AS3 233 +#define NOTE_B3 247 +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 +#define NOTE_C6 1047 +#define NOTE_CS6 1109 +#define NOTE_D6 1175 +#define NOTE_DS6 1245 +#define NOTE_E6 1319 +#define NOTE_F6 1397 +#define NOTE_FS6 1480 +#define NOTE_G6 1568 +#define NOTE_GS6 1661 +#define NOTE_A6 1760 +#define NOTE_AS6 1865 +#define NOTE_B6 1976 +#define NOTE_C7 2093 +#define NOTE_CS7 2217 +#define NOTE_D7 2349 +#define NOTE_DS7 2489 +#define NOTE_E7 2637 +#define NOTE_F7 2794 +#define NOTE_FS7 2960 +#define NOTE_G7 3136 +#define NOTE_GS7 3322 +#define NOTE_A7 3520 +#define NOTE_AS7 3729 +#define NOTE_B7 3951 +#define NOTE_C8 4186 +#define NOTE_CS8 4435 +#define NOTE_D8 4699 +#define NOTE_DS8 4978 + +