Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Downsample4x for 96Khz sample rate in I2S slave mode #71

Draft
wants to merge 15 commits into
base: mdev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion usermods/audioreactive/audio_reactive.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ static float lastFftCalc[NUM_GEQ_CHANNELS] = {0.0f}; // backup

#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// audio source parameters and constant
constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms
constexpr SRate_t SAMPLE_RATE = 96000; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms
//constexpr SRate_t SAMPLE_RATE = 16000; // 16kHz - use if FFTtask takes more than 20ms. Physical sample time -> 32ms
//constexpr SRate_t SAMPLE_RATE = 20480; // Base sample rate in Hz - 20Khz is experimental. Physical sample time -> 25ms
//constexpr SRate_t SAMPLE_RATE = 10240; // Base sample rate in Hz - previous default. Physical sample time -> 50ms
Expand Down
26 changes: 22 additions & 4 deletions usermods/audioreactive/audio_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ class AudioSource {
bool _i2sMaster; // when false, ESP32 will be in I2S SLAVE mode (for devices that only operate in MASTER mode). Only works in newer IDF >= 4.4.x
float _sampleScale; // pre-scaling factor for I2S samples
I2S_datatype newSampleBuffer[I2S_SAMPLES_MAX+4] = { 0 }; // global buffer for i2s_read
I2S_datatype newSampleBuffer4x[(I2S_SAMPLES_MAX*4)+4] = { 0 }; // global buffer for i2s_read
};

/* Basic I2S microphone source
Expand All @@ -195,12 +196,12 @@ class AudioSource {
*/
class I2SSource : public AudioSource {
public:
I2SSource(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=true) :
I2SSource(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=false) :
AudioSource(sampleRate, blockSize, sampleScale, i2sMaster) {
_config = {
.mode = i2sMaster ? i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX) : i2s_mode_t(I2S_MODE_SLAVE | I2S_MODE_RX),
.sample_rate = _sampleRate,
.bits_per_sample = I2S_SAMPLE_RESOLUTION, // slave mode: may help to set this to 96000, as the other side (master) controls sample rates
.sample_rate = _sampleRate, // slave mode: may help to set this to 96000, as the other side (master) controls sample rates
.bits_per_sample = I2S_SAMPLE_RESOLUTION,
.channel_format = I2S_MIC_CHANNEL,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
Expand Down Expand Up @@ -383,9 +384,17 @@ class I2SSource : public AudioSource {

memset(buffer, 0, sizeof(float) * num_samples); // clear output buffer
I2S_datatype *newSamples = newSampleBuffer; // use global input buffer
I2S_datatype *newSamples_buff = newSampleBuffer4x; // use oversampling global input buffer

if (num_samples > I2S_SAMPLES_MAX) num_samples = I2S_SAMPLES_MAX; // protect the buffer from overflow

err = i2s_read(I2S_NUM_0, (void *)newSamples, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY);
if (_sampleRate == 96000) {
num_samples *= 4;
err = i2s_read(I2S_NUM_0, (void *)newSamples_buff, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY);
} else {
err = i2s_read(I2S_NUM_0, (void *)newSamples, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY);
}

if (err != ESP_OK) {
DEBUGSR_PRINTF("Failed to get samples: %d\n", err);
return;
Expand All @@ -397,6 +406,15 @@ class I2SSource : public AudioSource {
return;
}

if (_sampleRate == 96000) {
int current = 0;
for (int i = 0; i < 2048; i += 4) {
newSamples[current] = newSamples_buff[i];
current++;
}
num_samples /= 4; // back to 512 samples
}

// Store samples in sample buffer and update DC offset
for (int i = 0; i < num_samples; i++) {

Expand Down
Loading