Files
twang-mp/sound.h

98 lines
2.1 KiB
C
Raw Normal View History

/*
* This creates sound tones by outputting a square wave on a DAC pin. The
* volume of the tone is the level of the DAC pin.
*
* The square wave is created by a timer. The timer runs at 2x the freq, because
* it needs to transition high and then low.
*
*
*/
#ifndef SOUND_H
#define SOUND_H
#include "esp32-hal-timer.h";
#define ESP32_F_CPU 80000000 // the speed of the processor
#define AUDIO_INTERRUPT_PRESCALER 80
#define SOUND_TIMER_NO 0
//#define AUDIO_PIN 25
#define MIN_FREQ 20
#define MAX_FREQ 16000
hw_timer_t * sndTimer = NULL;
bool sound_on = true;
bool sound_wave_high = true; // this toggles to create the high/low transitions of the wave
uint8_t sound_volume = 0;
void sound_init(int pin);
bool sound(uint16_t freq, uint8_t volume);
void soundOff();
int dac_pin;
void IRAM_ATTR onSoundTimer()
{
if (sound_on) {
dacWrite(dac_pin, (sound_wave_high?sound_volume:0));
sound_wave_high = ! sound_wave_high;
}
else
dacWrite(dac_pin, 0);
}
void sound_init(int pin){ // pin must be a DAC pin number !! (typically 25 or 26)
dac_pin = pin;
sound_on = false;
pinMode(dac_pin, OUTPUT);
sound_volume = 0;
sndTimer = timerBegin(SOUND_TIMER_NO, AUDIO_INTERRUPT_PRESCALER, true);
timerAttachInterrupt(sndTimer, &onSoundTimer, true);
timerAlarmWrite(sndTimer, ESP32_F_CPU/AUDIO_INTERRUPT_PRESCALER/MIN_FREQ, true); // lower timer freq
timerAlarmEnable(sndTimer);
}
void sound_pause() // this prevents the interrupt from firing ... use during eeprom write
{
timerStop(sndTimer);
}
void sound_resume() // resume from pause ... after eeprom write
{
timerRestart(sndTimer);
}
bool sound(uint16_t freq, uint8_t volume){
if (volume == 0) {
soundOff();
return false;
}
if (freq < MIN_FREQ || freq > MAX_FREQ) {
return false;
}
sound_on = true;
sound_volume = volume;
timerAlarmWrite(sndTimer, ESP32_F_CPU/AUDIO_INTERRUPT_PRESCALER/(freq * 2), true);
return true;
}
void soundOff(){
sound_on = false;
sound_volume = 0;
timerAlarmWrite(sndTimer, ESP32_F_CPU/AUDIO_INTERRUPT_PRESCALER/(MIN_FREQ), true); // lower timer freq
}
#endif