neingeist
/
arduinisten
Archived
1
0
Fork 0

3 of 8 bit

master
entropia 14 years ago
parent 1d5191aafd
commit cef4f78b3c

@ -0,0 +1,163 @@
/*
* Soundcode von: Michael Smith <michael@hurts.ca> - 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 <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/delay.h>
// 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);
}
}
}

@ -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