When a playing mp3 is deinitted, it's possible to reach get_buffer,
but all the internal pointers are NULL. This would lead to a hard fault.
Avoid it by returning GET_BUFFER_ERROR instead.
It's extremely dubious that we have these handles that we think
are to GC'd memory at a time when the gc pool may not be initialized.
Hopefully, they WERE valid GC memory and are undisturbed by the teardown
of the interpreter that can lead to this state.
In this case, don't try to m_free them, the memory will become free when
the GC heap is reinitialized.
Closes: #2338 (together with previous commit)
.. a requirement that oofatfs needs to be taught to respect.
This problem can be demonstrated with the following snippet, except
that the related file ("test.bin") must also be contiguous on the
filesystem. You can ensure this by reformatting your device's filesystem
before testing, then copying any single file bigger than 4kB to test.bin.
f = open("test.bin", "rb")
f.seek(2048)
b = bytearray(2048)
v = memoryview(b)
f.readinto(v[909:])
Closes: #2332
The "spacing" of "buffer structure" is confusing, use the "channel count"
instead.
Testing performed on nrf52840 feather:
Play stereo and mono, 8- and 16-bit, 8kHz RawSamples representing 333.33Hz
square waves.
Use both mono and stereo PWMAudioOut instances.
Scope the RC-filtered signal and use the scope's frequency
measurement function, verify the frequency is 333 or 334Hz in all tested
cases.
In the "stereo output" cases, verify both the L and R channels. Verify
the output amplitude is the same in both channels.
In the "stereo output" cases, run a second test where the L channel's
amplitude is attenuated 50%. Verify the output amplitude is correct
in each channel.
This adapts the "inline assembler" code from the UF2 bootloader, which
in turn is said to be adapted from the arduino neopixel library.
This requires the cache remain ON when using M0, and be turned OFF on M4
(determined by trial and error)
Testing performed on a Metro M4:
* measured timings using o'scope and found all values within
datasheet tolerance.
* Drove a string of 96 neopixels without visible glitches
* on-board neopixel worked
Testing performed on a Circuit Playground Express (M0):
* Color wheel code works on built-in neopixels
* Color wheel code works on 96 neopixel strip
As a bonus, this may have freed up a bit of flash on M0 targets. (2988 ->
3068 bytes free on Trinket M0)
Closes: #2297