Skip to content

Commit b0babcf

Browse files
committed
fixed audio 'pop'
1 parent e34b242 commit b0babcf

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

micropython/examples/cosmic_unicorn/audio/audio.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(self, id, sck_pin, ws_pin, sd_pin, ibuf_len=INTERNAL_BUFFER_LENGTH,
6262
self.__tone_samples = None
6363
self.__queued_samples = None
6464

65+
6566
def set_root(self, root):
6667
self.__root = root.rstrip("/") + "/"
6768

@@ -75,7 +76,10 @@ def play_wav(self, wav_file, loop=False):
7576
self.__loop_wav = loop # Record if the user wants the file to loop
7677

7778
# Parse the WAV file, returning the necessary parameters to initialise I2S communication
78-
format, sample_rate, bits_per_sample, self.__first_sample_offset = WavPlayer.__parse_wav(self.__wav_file)
79+
format, sample_rate, bits_per_sample, self.__first_sample_offset, self.sample_size = WavPlayer.__parse_wav(self.__wav_file)
80+
81+
# Keep a track of total bytes read from WAV File
82+
self.total_bytes_read = 0
7983

8084
self.__wav_file.seek(self.__first_sample_offset) # Advance to first byte of sample data
8185

@@ -179,7 +183,7 @@ def __i2s_callback(self, arg):
179183
if self.__state == WavPlayer.PLAY:
180184
if self.__mode == WavPlayer.MODE_WAV:
181185
num_read = self.__wav_file.readinto(self.__wav_samples_mv) # Read the next section of the WAV file
182-
186+
self.total_bytes_read += num_read
183187
# Have we reached the end of the file?
184188
if num_read == 0:
185189
# Do we want to loop the WAV playback?
@@ -191,6 +195,8 @@ def __i2s_callback(self, arg):
191195

192196
self.__audio_out.write(self.__silence_samples) # In both cases play silence to end this callback
193197
else:
198+
if num_read > 0 and num_read < self.WAV_BUFFER_LENGTH:
199+
num_read = num_read - (self.total_bytes_read - self.sample_size)
194200
self.__audio_out.write(self.__wav_samples_mv[: num_read]) # We are within the file, so write out the next audio samples
195201
else:
196202
if self.__queued_samples is not None:
@@ -255,4 +261,7 @@ def __parse_wav(wav_file):
255261
if offset == -1:
256262
raise ValueError("WAV sub chunk 2 ID not found")
257263

258-
return (format, sample_rate, bits_per_sample, 44 + offset)
264+
wav_file.seek(40)
265+
sub_chunk2_size = struct.unpack("<I", wav_file.read(4))[0]
266+
267+
return (format, sample_rate, bits_per_sample, 44 + offset, sub_chunk2_size)

micropython/examples/galactic_unicorn/audio/audio.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(self, id, sck_pin, ws_pin, sd_pin, ibuf_len=INTERNAL_BUFFER_LENGTH,
6262
self.__tone_samples = None
6363
self.__queued_samples = None
6464

65+
6566
def set_root(self, root):
6667
self.__root = root.rstrip("/") + "/"
6768

@@ -75,7 +76,10 @@ def play_wav(self, wav_file, loop=False):
7576
self.__loop_wav = loop # Record if the user wants the file to loop
7677

7778
# Parse the WAV file, returning the necessary parameters to initialise I2S communication
78-
format, sample_rate, bits_per_sample, self.__first_sample_offset = WavPlayer.__parse_wav(self.__wav_file)
79+
format, sample_rate, bits_per_sample, self.__first_sample_offset, self.sample_size = WavPlayer.__parse_wav(self.__wav_file)
80+
81+
# Keep a track of total bytes read from WAV File
82+
self.total_bytes_read = 0
7983

8084
self.__wav_file.seek(self.__first_sample_offset) # Advance to first byte of sample data
8185

@@ -179,7 +183,7 @@ def __i2s_callback(self, arg):
179183
if self.__state == WavPlayer.PLAY:
180184
if self.__mode == WavPlayer.MODE_WAV:
181185
num_read = self.__wav_file.readinto(self.__wav_samples_mv) # Read the next section of the WAV file
182-
186+
self.total_bytes_read += num_read
183187
# Have we reached the end of the file?
184188
if num_read == 0:
185189
# Do we want to loop the WAV playback?
@@ -191,6 +195,8 @@ def __i2s_callback(self, arg):
191195

192196
self.__audio_out.write(self.__silence_samples) # In both cases play silence to end this callback
193197
else:
198+
if num_read > 0 and num_read < self.WAV_BUFFER_LENGTH:
199+
num_read = num_read - (self.total_bytes_read - self.sample_size)
194200
self.__audio_out.write(self.__wav_samples_mv[: num_read]) # We are within the file, so write out the next audio samples
195201
else:
196202
if self.__queued_samples is not None:
@@ -255,4 +261,7 @@ def __parse_wav(wav_file):
255261
if offset == -1:
256262
raise ValueError("WAV sub chunk 2 ID not found")
257263

258-
return (format, sample_rate, bits_per_sample, 44 + offset)
264+
wav_file.seek(40)
265+
sub_chunk2_size = struct.unpack("<I", wav_file.read(4))[0]
266+
267+
return (format, sample_rate, bits_per_sample, 44 + offset, sub_chunk2_size)

micropython/examples/stellar_unicorn/audio/audio.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(self, id, sck_pin, ws_pin, sd_pin, ibuf_len=INTERNAL_BUFFER_LENGTH,
6262
self.__tone_samples = None
6363
self.__queued_samples = None
6464

65+
6566
def set_root(self, root):
6667
self.__root = root.rstrip("/") + "/"
6768

@@ -75,7 +76,10 @@ def play_wav(self, wav_file, loop=False):
7576
self.__loop_wav = loop # Record if the user wants the file to loop
7677

7778
# Parse the WAV file, returning the necessary parameters to initialise I2S communication
78-
format, sample_rate, bits_per_sample, self.__first_sample_offset = WavPlayer.__parse_wav(self.__wav_file)
79+
format, sample_rate, bits_per_sample, self.__first_sample_offset, self.sample_size = WavPlayer.__parse_wav(self.__wav_file)
80+
81+
# Keep a track of total bytes read from WAV File
82+
self.total_bytes_read = 0
7983

8084
self.__wav_file.seek(self.__first_sample_offset) # Advance to first byte of sample data
8185

@@ -179,7 +183,7 @@ def __i2s_callback(self, arg):
179183
if self.__state == WavPlayer.PLAY:
180184
if self.__mode == WavPlayer.MODE_WAV:
181185
num_read = self.__wav_file.readinto(self.__wav_samples_mv) # Read the next section of the WAV file
182-
186+
self.total_bytes_read += num_read
183187
# Have we reached the end of the file?
184188
if num_read == 0:
185189
# Do we want to loop the WAV playback?
@@ -191,6 +195,8 @@ def __i2s_callback(self, arg):
191195

192196
self.__audio_out.write(self.__silence_samples) # In both cases play silence to end this callback
193197
else:
198+
if num_read > 0 and num_read < self.WAV_BUFFER_LENGTH:
199+
num_read = num_read - (self.total_bytes_read - self.sample_size)
194200
self.__audio_out.write(self.__wav_samples_mv[: num_read]) # We are within the file, so write out the next audio samples
195201
else:
196202
if self.__queued_samples is not None:
@@ -255,4 +261,7 @@ def __parse_wav(wav_file):
255261
if offset == -1:
256262
raise ValueError("WAV sub chunk 2 ID not found")
257263

258-
return (format, sample_rate, bits_per_sample, 44 + offset)
264+
wav_file.seek(40)
265+
sub_chunk2_size = struct.unpack("<I", wav_file.read(4))[0]
266+
267+
return (format, sample_rate, bits_per_sample, 44 + offset, sub_chunk2_size)

0 commit comments

Comments
 (0)