These protocol operations should not raise exceptions, but sometimes
they do. Catch the exception and extract the errno value if available.
At the same time, harmonize the argument types for the underlying C
routines
You can now, e.g.,
```
with open("/whatever.mp3") as mp3_file:
mp3_file.seek(16000*30)
decoder.file = mp3_file
i2s.play(decoder)
```
to start about 30 seconds into a 128kbit/s CBR track.
If a track is looped, the loop will start at the beginning.
This also changes the behavior if the track is started & stopped: it will
continue from where it left off, except if it had prevously run to
completion. To get other behavior, you can seek the file and then re-assign
the file property.
An mp3 decoder (note that this needs `audiocore.get_buffer`, not
enabled on devices):
```py
import sys
import audiomp3
import audiocore
GET_BUFFER_DONE, GET_BUFFER_MORE_DATA, GET_BUFFER_ERROR = range(3)
with audiomp3.MP3Decoder(sys.argv[1]) as decoder, open(sys.argv[2], "wb") as target:
while True:
res, samples = audiocore.get_buffer(decoder)
if res != GET_BUFFER_ERROR:
target.write(samples)
if res != GET_BUFFER_MORE_DATA:
break
```
this doesn't actually add any tests though
This can sort-of play MP3s from a http request, but the buffering is
not good enough to play glitch-free. A new kind of buffer that can
read ahead further without blocking is needed.
Enable BLE where we can. Switch 4MB, non-USB board default partitioning
over to a single 2MB firmware bank. Old boards override this setting to
keep the same behavior.
This also adds alpha support for the ESP32-C2 (aka ESP8684).
Fixes#5926 and fixes#7170
Originally, the only (non-debug) way to make an LFO calculate its value
was to associate it with a playing synthesizer.
This posed a problem for LFOs that had "power on values" other than 0,
and where the value was used other than to internally drive a note
property.
Now, an initial, possibly non-zero value is calculated at object
construction time:
```py
>>> l = synthio.LFO(offset = 1)
>>> l.value
1.0
```
Note that this happens just once at construction; it does not happen when
updating LFO properties:
```py
>>> l.offset = 2
>>> l.value
1.0
```
.. so that the underlying allocations will be freed. This is not
important now but will be if the underlying allocator is changed
to something else like `port_malloc` in the future.
This runs in the Renode simulator and enables easier tracing and
debugging of the CircuitPython core. This port can also serve as
a starting point for new ports because it implements the minimal
necessary for the CP core to run.