blob: 5db9daaabf3472fcee06a8e8f8f19cbb0b8d3a4d [file] [log] [blame] [edit]
// simple audio for the PicoSystem's piezo buzzer
#include "audio.hpp"
#include "config.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"
static const uint32_t PWM_WRAP = 65535;
static uint32_t slice_num = 0;
static float clock_hz = 0.0;
static uint32_t beep_time = 0;
#include "audio/audio.hpp"
void init_audio() {
clock_hz = clock_get_hz(clk_sys);
gpio_set_function(AUDIO_BEEP_PIN, GPIO_FUNC_PWM);
slice_num = pwm_gpio_to_slice_num(AUDIO_BEEP_PIN);
pwm_set_wrap(slice_num, PWM_WRAP);
}
void update_audio(uint32_t time) {
bool on = false;
uint32_t elapsed = time - beep_time;
beep_time = time;
for(auto f = 0u; f < elapsed * blit::sample_rate / 1000; f++) {
blit::get_audio_frame();
}
// Find the first square wave enabled channel and use freq/pulse width to drive the beeper
for(int c = 0; c < CHANNEL_COUNT; c++) {
auto &channel = blit::channels[c];
if(channel.waveforms & blit::Waveform::SQUARE) {
on = channel.volume
&& channel.adsr_phase != blit::ADSRPhase::RELEASE
&& channel.adsr_phase != blit::ADSRPhase::OFF;
if(on) {
pwm_set_clkdiv(slice_num, (clock_hz / PWM_WRAP) / channel.frequency);
pwm_set_gpio_level(AUDIO_BEEP_PIN, channel.pulse_width);
break;
}
}
}
pwm_set_enabled(slice_num, on);
}