Audio wave functions
I started implementing a small audio library for Arduino. It uses the PWM to generate different kinds of waves:
- square
- sinus
- saw
- white noise
The sinus wave sounds quite bad, but the rest is pretty good, especially the saw wav.
Here is the code with a small example:
<code>
void audioInit();
void playWhiteNoise(int amp, unsigned long t, int pin);
void playSine(int amp, int freq, unsigned long t, int pin);
void playSaw(boolean up, int amp, int freq, unsigned long t, int pin);
void playSquare(int amp, int freq, unsigned long t, int pin);
- define AUDIO_OUTPUT 9
void setup() {
audioInit();
randomSeed(analogRead(9));
}
void loop() {
Serial.println("SAW up");
playSaw(true, 127, currentFrequency, 1000, AUDIO_OUTPUT);
delay(1000);
Serial.println("SAW down");
playSaw(false, 127, currentFrequency, 1000, AUDIO_OUTPUT);
delay(1000);
Serial.println("SINE");
playSine(127, currentFrequency, 1000, AUDIO_OUTPUT);
delay(1000);
Serial.println("SQUARE");
playSquare(127, currentFrequency, 1000, AUDIO_OUTPUT);
delay(1000);
}
void audioInit() {
// Make sure the PWM is at its maximum frequency.
TCCR1A = 1;
TCCR1B = 9;
}
- define WAVE_RESOLUTION 32
void playWhiteNoise(int amp, unsigned long t, int pin) {
unsigned long startTime = millis();
while (startTime + t >= millis()) {
analogWrite(pin, (int)random(255));
}
}
unsigned char valueTable[WAVE_RESOLUTION];
void playSine(int amp, int freq, unsigned long t, int pin) {
amp = constrain(amp, 0, 127);
// reuse t -> convert to number of cycles
t = ((long)freq * (long)t) / 1000;
// reuse freq -> convert to period
freq = (1000000 / freq) - 7; // subtract 7 us to make up for digitalWrite overhead - determined empirically
int i;
for (i=0; i<WAVE_RESOLUTION; i++) {
valueTable[i] = (unsigned char) ( ( (sin((2 * PI * i) / (float) (WAVE_RESOLUTION-1))) + 1.0) * amp );
}
while (t--) {
for (i=0; i<WAVE_RESOLUTION; i++) {
analogWrite(pin, (int)valueTable[i]);
delayMicroseconds(freq / WAVE_RESOLUTION);
}
}
}
void playSaw(boolean up, int amp, int freq, unsigned long t, int pin) {
amp = constrain(amp, 0, 127);
// reuse t -> convert to number of cycles
t = ((long)freq * (long)t) / 1000;
// reuse freq -> convert to period
freq = (1000000 / freq) - 7; // subtract 7 us to make up for digitalWrite overhead - determined empirically
int i;
for (i=0; i<WAVE_RESOLUTION; i++) {
valueTable[i] = (unsigned char) ( (up ? i : WAVE_RESOLUTION - i - 1) * 2 * amp / (WAVE_RESOLUTION-1));
// Serial.println((int)valueTable[i]);
}
while (t--) {
for (i=0; i<WAVE_RESOLUTION; i++) {
analogWrite(pin, (int)valueTable[i]);
delayMicroseconds(freq / WAVE_RESOLUTION);
}
}
}
{
amp = constrain(amp, 0, 127);
// reuse t -> convert to number of cycles
t = ((long)freq * (long)t) / 1000;
// reuse freq -> convert to period
freq = (500000 / freq) - 7; // subtract 7 us to make up for digitalWrite overhead - determined empirically
while (t--) {
analogWrite(pin, 127 + amp);
delayMicroseconds(freq);
analogWrite(pin, 127 - amp);
delayMicroseconds(freq - 1); // - 1 to make up for fractional microsecond in digitaWrite overhead
}
}
</code>



Audio favorites
My favorites are the white noise and the saw wave. However, we can't really "mix" them. It would be great to be able to add/multiply those waves. I'm thinking about a real audio processing library... wouldn't that be nice?