Skip to content

Commit 92f3b58

Browse files
authored
Merge pull request #8 from MichaelBell/adjust-for-loudness
Loudness compensate the display
2 parents d5a8f94 + 013aeb2 commit 92f3b58

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

src/btstack_audio_pico.cpp

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,50 @@
6060
#include "fixed_fft.hpp"
6161

6262
#define DRIVER_POLL_INTERVAL_MS 5
63-
#define FFT_SKIP_BINS 4 // Number of FFT bins to skip on the left, the low frequencies tend to be pretty boring visually
63+
#define FFT_SKIP_BINS 1 // Number of FFT bins to skip on the left, the low frequencies tend to be pretty boring visually
6464

6565
constexpr unsigned int BUFFERS_PER_FFT_SAMPLE = 2;
6666
constexpr unsigned int SAMPLES_PER_AUDIO_BUFFER = SAMPLE_COUNT / BUFFERS_PER_FFT_SAMPLE;
6767

68+
struct LoudnessLookup {
69+
int freq;
70+
float multiplier;
71+
};
72+
73+
// Amplitude to loudness lookup at 20 phons
74+
constexpr LoudnessLookup loudness_lookup[] = {
75+
{ 20, 0.2232641215f },
76+
{ 25, 0.241984271f },
77+
{ 31, 0.263227165f },
78+
{ 40, 0.2872737719f },
79+
{ 50, 0.3124023743f },
80+
{ 63, 0.341588386f },
81+
{ 80, 0.3760105283f },
82+
{ 100, 0.4133939644f },
83+
{ 125, 0.4551661356f },
84+
{ 160, 0.508001016f },
85+
{ 200, 0.5632216277f },
86+
{ 250, 0.6251953736f },
87+
{ 315, 0.6971070059f },
88+
{ 400, 0.7791195949f },
89+
{ 500, 0.8536064874f },
90+
{ 630, 0.9310986965f },
91+
{ 800, 0.9950248756f },
92+
{ 1000, 0.9995002499f },
93+
{ 1250, 0.9319664492f },
94+
{ 1600, 0.9345794393f },
95+
{ 2000, 1.101928375f },
96+
{ 2500, 1.300390117f },
97+
{ 3150, 1.402524544f },
98+
{ 4000, 1.321003963f },
99+
{ 5000, 1.073537305f },
100+
{ 6300, 0.7993605116f },
101+
{ 8000, 0.6345177665f },
102+
{ 10000, 0.5808887598f },
103+
{ 12500, 0.6053268765f },
104+
{ 20000, 0 }
105+
};
106+
68107
struct RGB {
69108
uint8_t r, g, b;
70109

@@ -96,6 +135,7 @@ Display display;
96135
constexpr int HISTORY_LEN = 21; // About 0.25s
97136
static uint history_idx = 0;
98137
static uint8_t eq_history[display.WIDTH][HISTORY_LEN] = {{0}};
138+
static fix15 loudness_adjust[display.WIDTH];
99139

100140
FIX_FFT fft;
101141

@@ -105,10 +145,24 @@ RGB palette_main[display.WIDTH];
105145
// client
106146
static void (*playback_callback)(int16_t * buffer, uint16_t num_samples);
107147

148+
static void init_loudness(uint32_t sample_frequency) {
149+
float scale = float(display.HEIGHT) * .318f;
150+
151+
for (int i = 0; i < display.WIDTH; ++i) {
152+
int freq = (sample_frequency * 2) * (i + FFT_SKIP_BINS) / SAMPLE_COUNT;
153+
int j = 0;
154+
while (loudness_lookup[j+1].freq < freq) {
155+
++j;
156+
}
157+
float t = float(freq - loudness_lookup[j].freq) / float(loudness_lookup[j+1].freq - loudness_lookup[j].freq);
158+
loudness_adjust[i] = float_to_fix15(scale * (t * loudness_lookup[j+1].multiplier + (1.f - t) * loudness_lookup[j].multiplier));
159+
printf("%d %d %f\n", i, freq, fix15_to_float(loudness_adjust[i]));
160+
}
161+
}
162+
108163
// timer to fill output ring buffer
109164
static btstack_timer_source_t driver_timer_sink;
110165

111-
112166
static bool btstack_audio_pico_sink_active;
113167

114168
// from pico-playground/audio/sine_wave/sine_wave.c
@@ -136,6 +190,7 @@ static audio_buffer_pool_t *init_audio(uint32_t sample_frequency, uint8_t channe
136190
btstack_last_sample_idx = 0;
137191

138192
btstack_volume = 127;
193+
init_loudness(sample_frequency);
139194

140195
audio_buffer_pool_t * producer_pool = audio_new_producer_pool(&btstack_audio_pico_producer_format, 3, SAMPLES_PER_AUDIO_BUFFER); // todo correct size
141196

@@ -198,9 +253,8 @@ static void btstack_audio_pico_sink_fill_buffers(void){
198253
}
199254

200255
fft.update();
201-
float scale = float(display.HEIGHT) * .318;
202256
for (auto i = 0u; i < display.WIDTH; i++) {
203-
uint16_t sample = std::min((int16_t)(display.HEIGHT * 255), (int16_t)fft.get_scaled_fix15(i + FFT_SKIP_BINS, float_to_fix15(scale)));
257+
uint16_t sample = std::min((int16_t)(display.HEIGHT * 255), (int16_t)fft.get_scaled_fix15(i + FFT_SKIP_BINS, loudness_adjust[i]));
204258
uint8_t maxy = 0;
205259

206260
for (int j = 0; j < HISTORY_LEN; ++j) {

0 commit comments

Comments
 (0)