80 lines
2.3 KiB
C++
80 lines
2.3 KiB
C++
#include <Arduino.h>
|
|
#include <driver/i2s.h>
|
|
#include <MP3DecoderHelix.h>
|
|
#include "positive_sound_mp3.h"
|
|
|
|
using namespace libhelix;
|
|
|
|
constexpr i2s_port_t I2S_PORT = I2S_NUM_0;
|
|
constexpr int I2S_BCLK = 6;
|
|
constexpr int I2S_LRC = 7;
|
|
constexpr int I2S_DIN = 5;
|
|
constexpr float OUTPUT_GAIN = 0.35f;
|
|
|
|
MP3DecoderHelix mp3;
|
|
|
|
bool i2s_initialized = false;
|
|
int current_sample_rate = 0;
|
|
int current_channels = 0;
|
|
|
|
void configureI2s(int sample_rate, int channels) {
|
|
if (!i2s_initialized) {
|
|
i2s_config_t i2s_config = {};
|
|
i2s_config.mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_TX);
|
|
i2s_config.sample_rate = sample_rate;
|
|
i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
|
|
i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
|
|
i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
|
|
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
|
|
i2s_config.dma_buf_count = 8;
|
|
i2s_config.dma_buf_len = 256;
|
|
i2s_config.use_apll = false;
|
|
i2s_config.tx_desc_auto_clear = true;
|
|
i2s_config.fixed_mclk = 0;
|
|
|
|
i2s_pin_config_t pin_config = {};
|
|
pin_config.bck_io_num = I2S_BCLK;
|
|
pin_config.ws_io_num = I2S_LRC;
|
|
pin_config.data_out_num = I2S_DIN;
|
|
pin_config.data_in_num = I2S_PIN_NO_CHANGE;
|
|
|
|
i2s_driver_install(I2S_PORT, &i2s_config, 0, nullptr);
|
|
i2s_set_pin(I2S_PORT, &pin_config);
|
|
i2s_zero_dma_buffer(I2S_PORT);
|
|
i2s_initialized = true;
|
|
}
|
|
|
|
if (sample_rate != current_sample_rate || channels != current_channels) {
|
|
i2s_channel_t channel_mode =
|
|
channels == 1 ? I2S_CHANNEL_MONO : I2S_CHANNEL_STEREO;
|
|
i2s_set_clk(I2S_PORT, sample_rate, I2S_BITS_PER_SAMPLE_16BIT, channel_mode);
|
|
current_sample_rate = sample_rate;
|
|
current_channels = channels;
|
|
}
|
|
}
|
|
|
|
void audioDataCallback(MP3FrameInfo &info, int16_t *pcm_buffer, size_t len, void *) {
|
|
configureI2s(info.samprate, info.nChans);
|
|
|
|
for (size_t i = 0; i < len; ++i) {
|
|
pcm_buffer[i] = static_cast<int16_t>(pcm_buffer[i] * OUTPUT_GAIN);
|
|
}
|
|
|
|
size_t bytes_written = 0;
|
|
i2s_write(I2S_PORT, pcm_buffer, len * sizeof(int16_t), &bytes_written,
|
|
portMAX_DELAY);
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
mp3.setDataCallback(audioDataCallback);
|
|
mp3.begin();
|
|
Serial.println("MP3 playback started");
|
|
}
|
|
|
|
void loop() {
|
|
mp3.write(positive_sound_short_mp3, positive_sound_short_mp3_len);
|
|
mp3.begin();
|
|
delay(20);
|
|
}
|