|
|
@ -23,54 +23,98 @@ void setup() {
|
|
|
|
|
|
|
|
|
|
|
|
// Set initial pulse width to the first sample.
|
|
|
|
// Set initial pulse width to the first sample.
|
|
|
|
OCR2A = 0;
|
|
|
|
OCR2A = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DEBUG
|
|
|
|
|
|
|
|
Serial.begin(9600);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Frequencies (in Hz) of notes
|
|
|
|
|
|
|
|
#define FSH_4 370
|
|
|
|
|
|
|
|
#define A_4 440
|
|
|
|
|
|
|
|
#define B_4 494
|
|
|
|
|
|
|
|
#define E_4 330
|
|
|
|
|
|
|
|
#define CSH_5 554
|
|
|
|
|
|
|
|
#define D_5 587
|
|
|
|
|
|
|
|
#define FSH_5 740
|
|
|
|
|
|
|
|
#define CSH_4 277
|
|
|
|
|
|
|
|
#define GSH_4 415
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define REST 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int play (uint16_t f, uint8_t T) {
|
|
|
|
int play (uint16_t f, uint8_t T) {
|
|
|
|
sendKarplusStrongSound(f, T);
|
|
|
|
#define MAGIC_TUNE_FAC 3
|
|
|
|
|
|
|
|
if (f == REST) {
|
|
|
|
|
|
|
|
_delay_ms(T*1000/16*MAGIC_TUNE_FAC);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sendKarplusStrongSound(f, T*MAGIC_TUNE_FAC);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1249193795
|
|
|
|
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1249193795
|
|
|
|
int sendKarplusStrongSound(const uint16_t f /*Hz*/, const uint8_t T /*sec*/) {
|
|
|
|
int sendKarplusStrongSound(uint16_t f /*Hz*/, uint8_t T /* 1/16 sec*/) {
|
|
|
|
const uint8_t N = 32;
|
|
|
|
uint32_t sr = 11025;
|
|
|
|
const uint32_t sr = f * N; // sample rate: 800(25Hz)..47619(1488Hz)
|
|
|
|
uint8_t N = sr/f;
|
|
|
|
|
|
|
|
//uint8_t N=32;
|
|
|
|
|
|
|
|
//uint32_t sr = (uint32_t) N*f;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial.print("N = ");
|
|
|
|
|
|
|
|
Serial.print(N, DEC);
|
|
|
|
|
|
|
|
Serial.println();
|
|
|
|
|
|
|
|
|
|
|
|
int16_t buf[N];
|
|
|
|
unsigned long millis_alt = millis();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int buf[N];
|
|
|
|
for (uint8_t i=0; i<N; i++)
|
|
|
|
for (uint8_t i=0; i<N; i++)
|
|
|
|
buf[i] = (int16_t) random(-32768,32767);
|
|
|
|
buf[i] = random(65536);
|
|
|
|
uint8_t bh = 0;
|
|
|
|
uint8_t bh = 0;
|
|
|
|
|
|
|
|
|
|
|
|
const int Tloop = 60; // or is it more?
|
|
|
|
int Tloop = 18
|
|
|
|
const int dt = 16000000/sr - Tloop;
|
|
|
|
; // FIXME: tune
|
|
|
|
|
|
|
|
int dt = (1000000ul)/sr - Tloop;
|
|
|
|
for (uint32_t i=sr*T/2; i>0; i--) {
|
|
|
|
Serial.print("dt = ");
|
|
|
|
const int8_t v = (int8_t) (buf[bh] >> 8);
|
|
|
|
Serial.print(dt, DEC);
|
|
|
|
|
|
|
|
Serial.println();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i=sr*T/16; i>0; i--) {
|
|
|
|
|
|
|
|
// current amplitude to play is the highest byte of buf[bh]
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
|
|
|
OCR2A = buf[bh] >> 8;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
OCR2A = buf[bh];
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// delay or do something else for <dt> usecs
|
|
|
|
|
|
|
|
_delay_us(dt);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// calculate avg between current buf[bh] and next sample buf[nbh]
|
|
|
|
|
|
|
|
uint8_t nbh;
|
|
|
|
|
|
|
|
if (bh < N-1) {
|
|
|
|
|
|
|
|
nbh = bh + 1;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
nbh = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OCR2A = v;
|
|
|
|
// calculate avg
|
|
|
|
_delay_us(dt); // or do something else for <dt> usecs
|
|
|
|
unsigned long avg = ((unsigned long) buf[bh] + (unsigned long) buf[nbh])/2;
|
|
|
|
|
|
|
|
// with gain<1 (1020/1024 ~ 0.996)
|
|
|
|
|
|
|
|
avg *= 1020;
|
|
|
|
|
|
|
|
avg /= 1024;
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t nbh = bh!=N-1 ? bh+1 : 0;
|
|
|
|
// put back in buffer
|
|
|
|
int32_t avg = buf[bh] + (int32_t)buf[nbh];
|
|
|
|
buf[bh] = (int) avg;
|
|
|
|
//avg = (avg << 10) - avg; // subtract avg more than once to get faster volume decrease
|
|
|
|
|
|
|
|
avg = (avg << 10) - avg -avg;
|
|
|
|
|
|
|
|
buf[bh] = avg >> 11; // no division, just shift
|
|
|
|
|
|
|
|
bh = nbh;
|
|
|
|
bh = nbh;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial.print("T_real = ");
|
|
|
|
|
|
|
|
Serial.print(millis() - millis_alt, DEC);
|
|
|
|
|
|
|
|
Serial.print(", T/16 = ");
|
|
|
|
|
|
|
|
Serial.print(T*1000/16, DEC);
|
|
|
|
|
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Frequencies (in Hz) of notes
|
|
|
|
|
|
|
|
#define FSH_4 370
|
|
|
|
|
|
|
|
#define A_4 440
|
|
|
|
|
|
|
|
#define B_4 494
|
|
|
|
|
|
|
|
#define E_4 330
|
|
|
|
|
|
|
|
#define CSH_5 554
|
|
|
|
|
|
|
|
#define D_5 587
|
|
|
|
|
|
|
|
#define FSH_5 740
|
|
|
|
|
|
|
|
#define CSH_4 277
|
|
|
|
|
|
|
|
#define GSH_4 415
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define REST 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
void loop() {
|
|
|
|
// Axel F
|
|
|
|
// Axel F
|
|
|
@ -100,5 +144,4 @@ void loop() {
|
|
|
|
play(GSH_4, 2);
|
|
|
|
play(GSH_4, 2);
|
|
|
|
play(FSH_4, 6);
|
|
|
|
play(FSH_4, 6);
|
|
|
|
play(REST, 12);
|
|
|
|
play(REST, 12);
|
|
|
|
delay(100);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|