From 360475e26618cba98522d5dd86d0051d3a296fb3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 23 Feb 2021 15:50:00 -0800 Subject: Implement audiobusio and enhance PIO for it This adds I2SOut and PDMIn support via PIO. StateMachines can now: * read and read while writing * transfer in 1, 2 or 4 byte increments * init pins based on expected defaults automatically * be stopped and restarted * rxfifo can be cleared and rxstalls detected (good for tracking when the reading code isn't keeping up) Fixes #4162 --- .../audiobusio/i2s_sample_loop.py | 36 ++++++++++++++++++ tests/circuitpython-manual/audiobusio/pdmin_rms.py | 44 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/circuitpython-manual/audiobusio/i2s_sample_loop.py create mode 100644 tests/circuitpython-manual/audiobusio/pdmin_rms.py (limited to 'tests/circuitpython-manual') diff --git a/tests/circuitpython-manual/audiobusio/i2s_sample_loop.py b/tests/circuitpython-manual/audiobusio/i2s_sample_loop.py new file mode 100644 index 000000000..c0ee5de31 --- /dev/null +++ b/tests/circuitpython-manual/audiobusio/i2s_sample_loop.py @@ -0,0 +1,36 @@ +import audiocore +import audiobusio +import board +import digitalio +import array +import time +import math +import rp2pio +import adafruit_pioasm + +time.sleep(10) + +trigger = digitalio.DigitalInOut(board.D4) +trigger.switch_to_output(True) + +# Generate one period of sine wav. +length = 8000 // 440 + +# signed 16 bit +s16 = array.array("h", [0] * length) +for i in range(length): + s16[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15)) + print(s16[i]) + +sample = audiocore.RawSample(s16, sample_rate=8000) + +dac = audiobusio.I2SOut(bit_clock=board.D10, + word_select=board.D11, data=board.D12) + +trigger.value = False +dac.play(sample, loop=True) +time.sleep(1) +dac.stop() +trigger.value = True + +print("done") diff --git a/tests/circuitpython-manual/audiobusio/pdmin_rms.py b/tests/circuitpython-manual/audiobusio/pdmin_rms.py new file mode 100644 index 000000000..8d1595752 --- /dev/null +++ b/tests/circuitpython-manual/audiobusio/pdmin_rms.py @@ -0,0 +1,44 @@ +import audiobusio +import board +import digitalio +import array +import time +import math + +trigger = digitalio.DigitalInOut(board.D4) +trigger.switch_to_output(True) + +def mean(values): + return sum(values) / len(values) + + +def normalized_rms(values): + minbuf = int(mean(values)) + samples_sum = sum( + float(sample - minbuf) * (sample - minbuf) + for sample in values + ) + + return math.sqrt(samples_sum / len(values)) + +# signed 16 bit +s16 = array.array("H", [0] * 10000) + +pdm = audiobusio.PDMIn(clock_pin=board.D11, data_pin=board.D12, sample_rate=24000, bit_depth=16) + +print("starting read") +trigger.value = False +count = pdm.record(s16, len(s16)) +trigger.value = True +print("read done") +print("recorded {} samples".format(count)) +for v in s16[:count]: + print(v) + + +magnitude = normalized_rms(s16) +print("magnitude", magnitude) + +print("count", count) + +print("done") -- cgit v1.2.3