We weren't correctly collecting the start and stop sequences. As
a result, the GC would free the space and allocate other info
there.
Thanks to JacobT on Discord for the bug report!
Whenever there is more than one argument, delegate the operation to
namedtuple_make_new. This allows other circuitpython-compatible
idioms, like with keywords
time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0,
tm_min=0, tm_sec=14, tm_wday=5, tm_yday=5, tm_isdst=-1)
with 9 positional arguments, etc.
The only vaguely plausible CPython behavior still not permitted in
CircuitPython that I found is constructing a timetuple from a length-9
list, a la
time.struct_time(list(time.localtime())
Even better, by getting rid of an error message, the build shrinks a
tiny bit.
This doesn't cover ALL the cases that CPython permits for construction
of a struct_time, but it at least makes constructing from any namedtuple
work.
Closes: #2326
The sample width register was never set, so all samples were played
as though they were 16 bit.
After this change, 8-bit samples no longer produce audio on the MAX 98357A
BOB, because only 16-, 24-, and 32-bit samples are supported by the
hardware. This will be addressed by a future change to pad samples to
16 bits; see #2323 and the 98357A datasheet page 6.
The meaning of the "single channel" parameter is not well-documented,
but in fact it seems that "true" must be passed or else the returned
channel_count is always 1. This caused stereo samples to be played
incorrectly.
(or deinitialized, for those of us on this side of the pond)
Otherwise, a sequence like
```
audio = audiobusio.I2SOut(bit_clock=board.D6, word_select=board.D9, data=board.D10)
sine_wave_sample = audiocore.RawSample(sine_wave)
audio.play(sine_wave_sample, loop=True)
del audio
```
could free the memory associated with audio without stopping the
related background task. Later, when fresh objects are allocated within
a now-freed memory region, they can get overwritten in the background
task, leading to a hard crash.
This presumably can affect multiple I2S implementations, but it was
reported against the nRF one.
This caused two problems when playing unsigned samples:
* When an even number of samples were present, it "worked" but only
every other sample was copied into the output, changing the waveform
* When an odd number of samples were present, the copy continued beyond
the end of the buffers and caused a hard fault
If we put no samples into the buffer, then there is no last
sample to fill out hold_value with. (and, in fact, the expression such
as *(uint32_t*)(buffer-4) is outside an allocated region)
Detect this condition, and leave the prior value in place.
This improves clicks heard when pausing and resuming a waveform.