97 lines
2.3 KiB
C
97 lines
2.3 KiB
C
/**
|
|
* @file audio.c
|
|
* @brief Audio driver implementation
|
|
*/
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "driver/ledc.h"
|
|
#include "esp_log.h"
|
|
#include "audio.h"
|
|
|
|
static const char *TAG = "audio";
|
|
|
|
static uint8_t audio_volume = 50;
|
|
|
|
esp_err_t audio_init(int gpio)
|
|
{
|
|
/* Configure LEDC PWM for audio output */
|
|
ledc_timer_config_t timer_cfg = {
|
|
.speed_mode = LEDC_LOW_SPEED_MODE,
|
|
.duty_resolution = LEDC_TIMER_8_BIT,
|
|
.timer_num = LEDC_TIMER_0,
|
|
.freq_hz = AUDIO_SAMPLE_RATE,
|
|
.clk_cfg = LEDC_AUTO_CLK,
|
|
};
|
|
ESP_ERROR_CHECK(ledc_timer_config(&timer_cfg));
|
|
|
|
ledc_channel_config_t channel_cfg = {
|
|
.gpio_num = gpio,
|
|
.speed_mode = LEDC_LOW_SPEED_MODE,
|
|
.channel = LEDC_CHANNEL_0,
|
|
.timer_sel = LEDC_TIMER_0,
|
|
.duty = 0,
|
|
.hpoint = 0,
|
|
};
|
|
ESP_ERROR_CHECK(ledc_channel_config(&channel_cfg));
|
|
|
|
ESP_LOGI(TAG, "Audio initialized on GPIO %d", gpio);
|
|
return ESP_OK;
|
|
}
|
|
|
|
void audio_beep(uint16_t freq_hz, uint16_t duration_ms)
|
|
{
|
|
if (freq_hz == 0) return;
|
|
|
|
/* Set PWM frequency for the beep */
|
|
ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, freq_hz);
|
|
|
|
/* Set duty cycle based on volume */
|
|
uint32_t duty = (audio_volume * 128) / 100;
|
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
|
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(duration_ms));
|
|
|
|
/* Stop */
|
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0);
|
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
|
|
}
|
|
|
|
void audio_play_startup(void)
|
|
{
|
|
audio_beep(880, 100);
|
|
vTaskDelay(pdMS_TO_TICKS(50));
|
|
audio_beep(1320, 150);
|
|
}
|
|
|
|
void audio_play_warning(void)
|
|
{
|
|
for (int i = 0; i < 3; i++) {
|
|
audio_beep(440, 100);
|
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
}
|
|
}
|
|
|
|
void audio_set_volume(uint8_t volume)
|
|
{
|
|
if (volume > 100) volume = 100;
|
|
audio_volume = volume;
|
|
}
|
|
|
|
uint8_t audio_get_volume(void)
|
|
{
|
|
return audio_volume;
|
|
}
|
|
|
|
void audio_task(void *pvParameters)
|
|
{
|
|
ESP_LOGI(TAG, "Audio task started");
|
|
|
|
/* Audio processing loop - handles audio queue */
|
|
while (1) {
|
|
/* TODO: Process audio queue for WAV playback */
|
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
}
|
|
}
|