From c9584b9b3c8c83decfda3712ad61ca13eb04d94f Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 28 Aug 2020 19:42:12 +0100 Subject: using the i2c-to-internal-dac functions, it sounds a bit better --- esp32/lego-piano.ino | 63 +++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/esp32/lego-piano.ino b/esp32/lego-piano.ino index 7901279..8991f07 100644 --- a/esp32/lego-piano.ino +++ b/esp32/lego-piano.ino @@ -17,6 +17,7 @@ */ #include +#include #define TSF_IMPLEMENTATION #define TSF_NO_STDIO @@ -39,27 +40,12 @@ const int ampEnable = 32; const int octave_shift = 2; +const int sampleRate = 8000; + char pressed[row_count*col_count] = { 0 }; -hw_timer_t * timer = NULL; -portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; tsf* g_TinySoundFont = 0; -bool playing = false; - -RingBuf buffer; - -void IRAM_ATTR onTimer() { - if (!g_TinySoundFont) return; - - portENTER_CRITICAL_ISR(&timerMux); - - short sample; - if (buffer.pop(sample)) { - dac_output_voltage(DAC_CHANNEL_1, sample >> 8); - } - - portEXIT_CRITICAL_ISR(&timerMux); -} +const i2s_port_t i2sPort = I2S_NUM_0; void setup() { Serial.begin(115200); @@ -67,9 +53,24 @@ void setup() { pinMode(ampEnable, OUTPUT); digitalWrite(ampEnable, LOW); - dac_i2s_disable(); + dac_i2s_enable(); dac_output_enable(DAC_CHANNEL_1); + static const i2s_config_t i2s_config = { + .mode = (i2s_mode_t)( I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN ), + .sample_rate = sampleRate, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_ALL_RIGHT, + .intr_alloc_flags = 0, // default interrupt priority + .dma_buf_count = 8, + .dma_buf_len = 64, + .use_apll = false + }; + + i2s_driver_install(i2sPort, &i2s_config, 0, NULL); + i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN); // only dac1 + i2s_set_sample_rates(i2sPort, sampleRate); // ?? + for (int i=0;i buffer; short intermediateBuffer[5000]; void loop() { @@ -159,15 +153,24 @@ void loop() { enableLed(currentLed); unsigned long t = millis(); + size_t written=100; + short value; + // fill the I2S buffer + while (written > 0) { + // we don't want to drop an element from the buffer if we then + // can't write it! so we peek at the buffer, try to write, and pop + // if successful + value=buffer[0]; + i2s_write(i2sPort, &value, sizeof(value), &written, 0); + if (written > 0) buffer.pop(value); + } int toFill = buffer.maxSize() - buffer.size(); if (toFill > 100) { tsf_render_short(g_TinySoundFont, intermediateBuffer, toFill, 0); - noInterrupts(); for (int i=0;i