Skip to content

Commit 22abf2d

Browse files
committed
MP3Decoder: clear out DSP data when opening a new stream
The new test verifies that the first part of an MP3 decodes as expected even when the "open" method is used. Closes: adafruit#9705
1 parent 407a31f commit 22abf2d

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

shared-module/audiomp3/MP3Decoder.c

+12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "shared-module/audiomp3/MP3Decoder.h"
2121
#include "supervisor/background_callback.h"
2222
#include "lib/mp3/src/mp3common.h"
23+
#include "lib/mp3/src/coder.h"
2324

2425
#define MAX_BUFFER_LEN (MAX_NSAMP * MAX_NGRAN * MAX_NCHAN * sizeof(int16_t))
2526

@@ -360,6 +361,17 @@ void common_hal_audiomp3_mp3file_set_file(audiomp3_mp3file_obj_t *self, mp_obj_t
360361
// get_buffer() that I didn't understand.
361362
memset(self->pcm_buffer[0], 0, MAX_BUFFER_LEN);
362363
memset(self->pcm_buffer[1], 0, MAX_BUFFER_LEN);
364+
365+
/* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */
366+
struct _MP3DecInfo *decoder = self->decoder;
367+
memset(decoder->FrameHeaderPS, 0, sizeof(FrameHeader));
368+
memset(decoder->SideInfoPS, 0, sizeof(SideInfo));
369+
memset(decoder->ScaleFactorInfoPS, 0, sizeof(ScaleFactorInfo));
370+
memset(decoder->HuffmanInfoPS, 0, sizeof(HuffmanInfo));
371+
memset(decoder->DequantInfoPS, 0, sizeof(DequantInfo));
372+
memset(decoder->IMDCTInfoPS, 0, sizeof(IMDCTInfo));
373+
memset(decoder->SubbandInfoPS, 0, sizeof(SubbandInfo));
374+
363375
MP3FrameInfo fi;
364376
bool result = mp3file_get_next_frame_info(self, &fi, true);
365377
background_callback_allow();

tests/circuitpython/issue9705.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import audiomp3, audiocore
2+
import ulab.numpy as np
3+
4+
TEST_FILE = __file__.rsplit("/", 1)[0] + "/../circuitpython-manual/audiocore/jeplayer-splash-44100-stereo.mp3"
5+
6+
def normalized_rms_ulab(values):
7+
values = np.frombuffer(values, dtype=np.int16)
8+
# this function works with ndarrays only
9+
minbuf = np.mean(values)
10+
values = values - minbuf
11+
samples_sum = np.sum(values * values)
12+
return (samples_sum / len(values))**.5
13+
14+
def print_frame_loudness(decoder, n):
15+
for i in range(n):
16+
result, buf = audiocore.get_buffer(decoder)
17+
print(f"{i} {result} {normalized_rms_ulab(buf):5.0f}")
18+
print()
19+
20+
# First frames
21+
decoder = audiomp3.MP3Decoder(TEST_FILE)
22+
print_frame_loudness(decoder, 8)
23+
24+
# First frames (fresh decoder)
25+
decoder = audiomp3.MP3Decoder(TEST_FILE)
26+
print_frame_loudness(decoder, 2)
27+
28+
# First frames (reopen)
29+
decoder.open(TEST_FILE)
30+
print_frame_loudness(decoder, 3)

tests/circuitpython/issue9705.py.exp

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
0 1 0
2+
1 1 4730
3+
2 1 27914
4+
3 1 28737
5+
4 1 29251
6+
5 1 29219
7+
6 1 28672
8+
7 1 28213
9+
10+
0 1 0
11+
1 1 4730
12+
13+
0 1 0
14+
1 1 4730
15+
2 1 27914
16+

0 commit comments

Comments
 (0)