.. based on some tasks I found that caused stuttering:
# Test SD and printing
while True: os.listdir('.')
# Test bulk I/O
while True: len(open('somefile.wav', 'rb').read())
Each of these tasks *WAS* worse and I am improving them in a separate
PR by adding RUN_BACKGROUND_TASKS to them.
This enables the highest level of debug symbols, and all optimizations
except lto that do NOT interfere with debugging, in the view of the gcc
maintainers.
Testing performed: I used a Particle Xenon with a HDA1334 I2S DAC.
I played a variety of mono 16-bit samples at 11025 and 22050Hz nominal
bit rates. With this setup, all the 11025Hz samples sound good.
I tested play, pause, and loop functionality.
During some runs with 22050Hz samples, there were glitches. However,
these may have only occurred during runs where I had set breakpoints
and watchpoints in gdb.
I also tested with a MAX98357A I2S amplifier. On this device, everything
sounded "scratchy". I was powering it from 5V and the 5V rail seemed
steady, so I don't have an explanation for this. However, I haven't
tried it with a SAMD board.
So far, this supports only 16kHz and 16-bit samples with a fixed gain.
This is enough to support the basic functionality of e.g., sensing
ambient audio levels.
The original formulation was because I saw the need to avoid a transition
from playing to stopped exactly when a resume was taking place. However,
@tannewt was concerned about this pause causing trouble, because it could
be relatively lengthy (several ms even in a typical case).
After reflection, I've convinced myself that updating the registers
in this order in resume avoids a window where a "stopped" event can
be missed as long as the shortcut is updated first.
Testing re-performed: pause/resume testing of looped RawSample and
WaveFile audio sources.
Testing performed: installed freshly built .uf2 on a Particle Xenon.
Checked that circuitpython still starts.
Checked that the size of all .uf2 files for nrf builds are plausible.
Aside from memory savings, the performance of Python code (pystone)
increased by about +14%.
However, this adds about 12-16 seconds to each nrf build.
Timings & Sizes (build system: i5-3320M, -j5 parallelism on 4 threads):
Before:
$ make -j5 BOARD=particle_xenon
765004 bytes free in flash out of 1048576 bytes ( 1024.0 kb ).
232076 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ).
68.54user 11.83system 0:34.34elapsed 234%CPU
pystones before: 570
After:
$ make -j5 BOARD=particle_xenon
804284 bytes free in flash out of 1048576 bytes ( 1024.0 kb ).
232072 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ).
71.06user 11.77system 0:46.91elapsed 176%CPU
pystones after: 650
Timings on travis:
Before:
Build feather_nrf52840_express for pl took 55.79s and succeeded
Build feather_nrf52840_express for zh_Latn_pinyin took 3.18s and succeeded
After:
Build feather_nrf52840_express for pl took 62.72s and succeeded
Build feather_nrf52840_express for zh_Latn_pinyin took 19.10s
Closes: #1396
This implements AudioOut, with known caveats:
* pause/resume are not yet implemented (this is just a bug)
* at best, the sample fidelity is 8 bits (this is a hardware limitation)
Testing performed:
My test system is a Particle Xenon with a PAM8302 op-amp
https://www.adafruit.com/product/2130 and 8-ohm speaker. There's no
analog filtering between the Xenon's PWM pin and the "A+" input of
the amplifier; the "A-" pin is disconnected. It is powered from
VUSB.
I used pin D4, which is *NOT* listed as a low-speed-only pin, but
the code does NOT switch the pin to high drive. This is related to
an open issue for general inability to set drive level for pins
being used by a "special function" on nrf:
https://github.com/adafruit/circuitpython/issues/1270
Nothing about the code I've written should limit the usable pins.
All samples I played were 16-bit, generally monophonic at 11025Hz
and 22050Hz from the Debian LibreOffice package.
This also improves Palette so it stores the original RGB888 colors.
Lastly, it adds I2CDisplay as a display bus to talk over I2C. Particularly
useful for the SSD1306.
Fixes#1828. Fixes#1956