3636#include < arduinoFFT.h>
3737#include < driver/i2s.h>
3838#include < driver/adc.h>
39- // #include <driver/adc_deprecated.h>
40-
41- #define SUPERSAMPLES 1 // How many supersamples to take
42- #define SAMPLE_BITS 12 // Sample resolution (0-4095)
43- #define MAX_ANALOG_IN ((1 << SAMPLE_BITS) * SUPERSAMPLES) // What our max analog input value is on all analog pins (4096 is default 12 bit resolution)
44- #ifndef MAX_VU
45- #define MAX_VU (MAX_ANALOG_IN / 2 )
46- #endif
4739
4840#define MS_PER_SECOND 1000
4941
@@ -77,8 +69,6 @@ class SoundAnalyzer : public AudioVariables // Non-audio case. Inherits only th
7769
7870#define EXAMPLE_I2S_NUM (I2S_NUM_0)
7971#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT) // I2S data format
80- #define I2S_ADC_UNIT ADC_UNIT_1 // I2S built-in ADC unit
81- #define I2S_ADC_CHANNEL ADC1_CHANNEL_0 // I2S built-in ADC channel
8272
8373void IRAM_ATTR AudioSamplerTaskEntry (void *);
8474void IRAM_ATTR AudioSerialTaskEntry (void *);
@@ -89,7 +79,7 @@ void IRAM_ATTR AudioSerialTaskEntry(void *);
8979// results are simplified down to this small class of band peaks.
9080
9181#ifndef MIN_VU
92- #define MIN_VU 180 // Minimum VU value to use for the span when computing VURatio. Contributes to
82+ #define MIN_VU 2 // Minimum VU value to use for the span when computing VURatio. Contributes to
9383#endif // how dynamic the music is (smaller values == more dynamic)
9484
9585
@@ -155,26 +145,26 @@ class PeakData
155145 case MESMERIZERMIC:
156146 {
157147 static constexpr std::array<float , 16 > Scalars16 = {0.4 , .5 , 0.75 , 1.0 , 0.6 , 0.6 , 0.8 , 0.8 , 1.2 , 1.5 , 3.0 , 3.0 , 3.0 , 3.0 , 3.5 , 2.5 }; // {0.08, 0.12, 0.3, 0.35, 0.35, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.4, 1.0, 1.0, 1.0};
158- float result = (NUM_BANDS == 16 ) ? Scalars16[i] : map (i, 0 , NUM_BANDS - 1 , 1.0 , 1.0 ) ;
148+ float result = (NUM_BANDS == 16 ) ? Scalars16[i] : 1.0 ;
159149 return result;
160150 }
161151 case PCREMOTE:
162152 {
163153
164154 static constexpr std::array<float , 16 > Scalars16 = {1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 };
165- float result = (NUM_BANDS == 16 ) ? Scalars16[i] : map (i, 0 , NUM_BANDS - 1 , 1.0 , 1.0 ) ;
155+ float result = (NUM_BANDS == 16 ) ? Scalars16[i] : 1.0 ;
166156 return result;
167157 }
168158 case M5PLUS2:
169159 {
170- static constexpr std::array<float , 16 > Scalars16 = {0.3 , . 5 , 0.8 , 1.0 , 1.0 , 1 .0 , 1 .0 , 1 .0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 0.7 , 0.7 , 0.7 };
171- float result = (NUM_BANDS == 16 ) ? Scalars16[i] : map (i, 0 , NUM_BANDS - 1 , 1.0 , 1.0 ) ;
160+ static constexpr std::array<float , 16 > Scalars16 = {0.5 , 1.0 , 2.5 , 2.2 , 1.5 , 2 .0 , 2 .0 , 2 .0 , 1.5 , 1.5 , 1.5 , 1.5 , 1.0 , 0.8 , 1.0 , 1.0 };
161+ float result = (NUM_BANDS == 16 ) ? Scalars16[i] : 1.0 ;
172162 return result;
173163 }
174164 default :
175165 {
176166 static constexpr std::array<float , 16 > Scalars16 = {0.5 , .5 , 0.8 , 1.0 , 1.5 , 1.2 , 1.5 , 1.6 , 2.0 , 2.0 , 2.0 , 3.0 , 3.0 , 3.0 , 5.0 , 2.5 };
177- float result = (NUM_BANDS == 16 ) ? Scalars16[i] : map (i, 0 , NUM_BANDS - 1 , 1.0 , 1.0 ) ;
167+ float result = (NUM_BANDS == 16 ) ? Scalars16[i] : 1.0 ;
178168 return result;
179169 }
180170 }
@@ -202,13 +192,13 @@ class PeakData
202192class SoundAnalyzer : public AudioVariables
203193{
204194 static constexpr size_t MAX_SAMPLES = 256 ;
205- std::unique_ptr<uint16_t []> ptrSampleBuffer;
195+ std::unique_ptr<int16_t []> ptrSampleBuffer;
206196
207197 // I'm old enough I can only hear up to about 12K, but feel free to adjust. Remember from
208198 // school that you need to sample at double the frequency you want to process, so 24000 is 12K
209199
210200 static constexpr size_t SAMPLING_FREQUENCY = 20000 ;
211- static constexpr size_t LOWEST_FREQ = 40 ;
201+ static constexpr size_t LOWEST_FREQ = 100 ;
212202 static constexpr size_t HIGHEST_FREQ = SAMPLING_FREQUENCY / 2 ;
213203
214204 static constexpr size_t _sampling_period_us = PERIOD_FROM_FREQ(SAMPLING_FREQUENCY);
@@ -288,9 +278,9 @@ class SoundAnalyzer : public AudioVariables
288278 if (M5.Mic .record ((int16_t *)ptrSampleBuffer.get (), MAX_SAMPLES, SAMPLING_FREQUENCY, false ))
289279 bytesRead = bytesExpected;
290280 #else
291- ESP_ERROR_CHECK (i2s_start (EXAMPLE_I2S_NUM ));
292- ESP_ERROR_CHECK (i2s_read (EXAMPLE_I2S_NUM , (void *) ptrSampleBuffer.get (), bytesExpected, &bytesRead, 100 / portTICK_RATE_MS ));
293- ESP_ERROR_CHECK (i2s_stop (EXAMPLE_I2S_NUM ));
281+ ESP_ERROR_CHECK (i2s_start (I2S_NUM_0 ));
282+ ESP_ERROR_CHECK (i2s_read (I2S_NUM_0 , (void *) ptrSampleBuffer.get (), bytesExpected, &bytesRead, 100 / portTICK_PERIOD_MS ));
283+ ESP_ERROR_CHECK (i2s_stop (I2S_NUM_0 ));
294284 #endif
295285
296286 if (bytesRead != bytesExpected)
@@ -364,10 +354,7 @@ class SoundAnalyzer : public AudioVariables
364354
365355 for (int i = 2 ; i < MAX_SAMPLES / 2 ; i++)
366356 {
367- #if USE_M5
368- // The M5 Mic returns some large vales, so we normalize here
369- _vReal[i] = _vReal[i] / MAX_SAMPLES;
370- #endif
357+ _vReal[i] = _vReal[i] / MAX_SAMPLES * AUDIO_MIC_SCALAR;
371358
372359 int freq = GetBucketFrequency (i-2 );
373360 if (freq >= LOWEST_FREQ)
@@ -468,16 +455,19 @@ class SoundAnalyzer : public AudioVariables
468455 }
469456 else
470457 {
471- // uses geometric spacing to calculate the upper frequency for each of the 12 bands, starting with a frequency of 200 Hz
472- // and ending with a frequency of 12.5 kHz. The spacing ratio r is calculated as the 11th root of the ratio of the maximum
473- // frequency to the minimum frequency, and each upper frequency is calculated as f1 * r^(i+1).
474-
458+ // Calculate the logarithmic spacing for the frequency bands
475459 float f1 = LOWEST_FREQ;
476460 float f2 = HIGHEST_FREQ;
477- float r = pow (f2 / f1, 1.0 / (NUM_BANDS - 1 ));
461+
462+ // Calculate the ratio based on logarithmic scale
463+ float log_f1 = log10 (f1);
464+ float log_f2 = log10 (f2);
465+ float delta = (log_f2 - log_f1) / (NUM_BANDS - 1 );
466+
478467 for (int i = 0 ; i < NUM_BANDS; i++)
479468 {
480- _cutOffsBand[i] = round (f1 * pow (r, i + 1 ));
469+ // Calculate the upper frequency for each band
470+ _cutOffsBand[i] = round (pow (10 , log_f1 + delta * (i + 1 )));
481471 debugV (" BAND %d: %d\n " , i, _cutOffsBand[i]);
482472 }
483473 }
@@ -489,7 +479,10 @@ class SoundAnalyzer : public AudioVariables
489479
490480 SoundAnalyzer ()
491481 {
492- ptrSampleBuffer = make_unique_psram_array<uint16_t >(MAX_SAMPLES);
482+ ptrSampleBuffer.reset ( (int16_t *)heap_caps_malloc (MAX_SAMPLES * sizeof (int16_t ), MALLOC_CAP_8BIT) );
483+ if (!ptrSampleBuffer)
484+ throw std::runtime_error (" Failed to allocate sample buffer" );
485+
493486 _vReal = (double *)PreferPSRAMAlloc (MAX_SAMPLES * sizeof (_vReal[0 ]));
494487 _vImaginary = (double *)PreferPSRAMAlloc (MAX_SAMPLES * sizeof (_vImaginary[0 ]));
495488 _vPeaks = (double *)PreferPSRAMAlloc (NUM_BANDS * sizeof (_vPeaks[0 ]));
@@ -530,17 +523,13 @@ class SoundAnalyzer : public AudioVariables
530523
531524 #if USE_M5
532525
533- auto miccfg = M5.Mic .config ();
534- miccfg.over_sampling = 4 ;
535- miccfg.magnification = 1 ;
536- miccfg.dma_buf_count = 2 ;
537- miccfg.dma_buf_len = MAX_SAMPLES;
538- miccfg.sample_rate = SAMPLING_FREQUENCY;
539- miccfg.use_adc = false ;
540- M5.Mic .config (miccfg);
541-
526+
527+ // Can't use speaker and mic at the same time, and speaker defaults on, so turn it off
528+
529+ M5.Speaker .setVolume (255 );
530+ M5.Speaker .end ();
542531 M5.Mic .begin ();
543-
532+
544533 #elif ELECROW
545534
546535 const i2s_config_t i2s_config = {
@@ -582,8 +571,8 @@ class SoundAnalyzer : public AudioVariables
582571
583572 ESP_ERROR_CHECK (adc1_config_width (ADC_WIDTH_BIT_12));
584573 ESP_ERROR_CHECK (adc1_config_channel_atten (ADC1_CHANNEL_0, ADC_ATTEN_DB_0));
585- ESP_ERROR_CHECK (i2s_driver_install (EXAMPLE_I2S_NUM , &i2s_config, 0 , NULL ));
586- ESP_ERROR_CHECK (i2s_set_adc_mode (I2S_ADC_UNIT, I2S_ADC_CHANNEL ));
574+ ESP_ERROR_CHECK (i2s_driver_install (I2S_NUM_0 , &i2s_config, 0 , NULL ));
575+ ESP_ERROR_CHECK (i2s_set_adc_mode (ADC_UNIT_1, ADC1_CHANNEL_0 ));
587576
588577 #else
589578
@@ -600,8 +589,8 @@ class SoundAnalyzer : public AudioVariables
600589
601590 ESP_ERROR_CHECK (adc1_config_width (ADC_WIDTH_BIT_12));
602591 ESP_ERROR_CHECK (adc1_config_channel_atten (ADC1_CHANNEL_0, ADC_ATTEN_DB_0));
603- ESP_ERROR_CHECK (i2s_driver_install (EXAMPLE_I2S_NUM , &i2s_config, 0 , NULL ));
604- ESP_ERROR_CHECK (i2s_set_adc_mode (I2S_ADC_UNIT, I2S_ADC_CHANNEL ));
592+ ESP_ERROR_CHECK (i2s_driver_install (I2S_NUM_0 , &i2s_config, 0 , NULL ));
593+ ESP_ERROR_CHECK (i2s_set_adc_mode (ADC_UNIT_1, ADC1_CHANNEL_0 ));
605594
606595 #endif
607596
0 commit comments