diff options
| -rw-r--r-- | shared-bindings/analogio/AnalogIn.c | 70 | ||||
| -rw-r--r-- | shared-bindings/analogio/AnalogOut.c | 63 | ||||
| -rw-r--r-- | shared-bindings/analogio/__init__.c | 4 | ||||
| -rw-r--r-- | shared-bindings/audiobusio/I2SOut.c | 161 | ||||
| -rw-r--r-- | shared-bindings/audiobusio/PDMIn.c | 151 | ||||
| -rw-r--r-- | shared-bindings/audiobusio/__init__.c | 4 | ||||
| -rw-r--r-- | shared-bindings/audiocore/RawSample.c | 104 | ||||
| -rw-r--r-- | shared-bindings/audiocore/WaveFile.c | 103 | ||||
| -rw-r--r-- | shared-bindings/audiocore/__init__.c | 4 |
9 files changed, 351 insertions, 313 deletions
diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index 9b6ac086b..2fb5051eb 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -36,25 +36,28 @@ #include "shared-bindings/analogio/AnalogIn.h" #include "shared-bindings/util.h" -//|class AnalogIn: -//|""":class:`AnalogIn` -- read analog voltage -//|============================================ +//| class AnalogIn: +//| """.. currentmodule:: analogio //| -//|Usage:: +//| :class:`AnalogIn` -- read analog voltage +//| ============================================ //| -//|import analogio -//|from board import * +//| Usage:: //| -//|adc = analogio.AnalogIn(A1) -//|val = adc.value""" +//| import analogio +//| from board import * //| -//|def __init__(self, pin: microcontroller.Pin): +//| adc = analogio.AnalogIn(A1) +//| val = adc.value""" //| -//|"""Use the AnalogIn on the given pin. The reference voltage varies by -//|platform so use ``reference_voltage`` to read the configured setting. + +//| def __init__(self, pin: microcontroller.Pin): +//| """Use the AnalogIn on the given pin. The reference voltage varies by +//| platform so use ``reference_voltage`` to read the configured setting. +//| +//| :param ~microcontroller.Pin pin: the pin to read from""" +//| ... //| -//|:param ~microcontroller.Pin pin: the pin to read from""" -//|... STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check number of arguments @@ -70,9 +73,10 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, return MP_OBJ_FROM_PTR(self); } -//|def deinit(self, ) -> Any: -//|"""Turn off the AnalogIn and release the pin for other use.""" -//|... +//| def deinit(self, ) -> Any: +//| """Turn off the AnalogIn and release the pin for other use.""" +//| ... +//| STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_analogio_analogin_deinit(self); @@ -85,15 +89,17 @@ STATIC void check_for_deinit(analogio_analogin_obj_t *self) { raise_deinited_error(); } } -//|def __enter__(self, ) -> Any: -//|"""No-op used by Context Managers.""" -//|... +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... +//| // Provided by context manager helper. -//|def __exit__(self, ) -> Any: -//|"Automatically deinitializes the hardware when exiting a context. See -//|:ref:`lifetime-and-contextmanagers` for more info.""" -//|... +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| STATIC mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_analogio_analogin_deinit(args[0]); @@ -101,12 +107,12 @@ STATIC mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, analogio_analogin___exit__); -//|value: Any = -//|"""The value on the analog pin between 0 and 65535 inclusive (16-bit). (read-only) +//| value: Any = ... +//| """The value on the analog pin between 0 and 65535 inclusive (16-bit). (read-only) +//| +//| Even if the underlying analog to digital converter (ADC) is lower +//| resolution, the value is 16-bit.""" //| -//|Even if the underlying analog to digital converter (ADC) is lower -//|resolution, the value is 16-bit.""" -//|... STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -121,10 +127,10 @@ const mp_obj_property_t analogio_analogin_value_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//|reference_voltage: Any = -//|"""The maximum voltage measurable (also known as the reference voltage) as a -//|`float` in Volts.""" -//|... +//| reference_voltage: Any = ... +//| """The maximum voltage measurable (also known as the reference voltage) as a +//| `float` in Volts.""" +//| STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 231668290..9064bb5dc 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -36,26 +36,28 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//|class AnalogOut: -//|""".. currentmodule:: analogio +//| class AnalogOut: +//| """.. currentmodule:: analogio //| -//|:class:`AnalogOut` -- output analog voltage -//|============================================ +//| :class:`AnalogOut` -- output analog voltage +//| ============================================ //| -//|The AnalogOut is used to output analog values (a specific voltage). +//| The AnalogOut is used to output analog values (a specific voltage). //| -//|Example usage:: +//| Example usage:: //| -//|import analogio -//|from microcontroller import pin +//| import analogio +//| from microcontroller import pin //| -//|dac = analogio.AnalogOut(pin.PA02) # output on pin PA02 -//|dac.value = 32768 # makes PA02 1.65V""" -//|def __init__(self, pin: microcontroller.Pin): -//|"""Use the AnalogOut on the given pin. +//| dac = analogio.AnalogOut(pin.PA02) # output on pin PA02 +//| dac.value = 32768 # makes PA02 1.65V""" +//| +//| def __init__(self, pin: microcontroller.Pin): +//| """Use the AnalogOut on the given pin. +//| +//| :param ~microcontroller.Pin pin: the pin to output to""" +//| ... //| -//|:param ~microcontroller.Pin pin: the pin to output to""" -//|... STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check arguments mp_arg_check_num(n_args, kw_args, 1, 1, false); @@ -69,9 +71,10 @@ STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t return MP_OBJ_FROM_PTR(self); } -//|def deinit(self, ) -> Any: -//|"""Turn off the AnalogOut and release the pin for other use.""" -//|... +//| def deinit(self, ) -> Any: +//| """Turn off the AnalogOut and release the pin for other use.""" +//| ... +//| STATIC mp_obj_t analogio_analogout_deinit(mp_obj_t self_in) { analogio_analogout_obj_t *self = self_in; @@ -81,15 +84,17 @@ STATIC mp_obj_t analogio_analogout_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogout_deinit_obj, analogio_analogout_deinit); -//|def __enter__(self, ) -> Any: -//|"""No-op used by Context Managers.""" -//|... +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... +//| // Provided by context manager helper. -//|def __exit__(self, ) -> Any: -//|"""Automatically deinitializes the hardware when exiting a context. See -//|:ref:`lifetime-and-contextmanagers` for more info.""" -//|... +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| STATIC mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_analogio_analogout_deinit(args[0]); @@ -97,12 +102,12 @@ STATIC mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4, analogio_analogout___exit__); -//|value: Any = -//|"""The value on the analog pin between 0 and 65535 inclusive (16-bit). (write-only) +//| value: Any = ... +//| """The value on the analog pin between 0 and 65535 inclusive (16-bit). (write-only) +//| +//| Even if the underlying digital to analog converter (DAC) is lower +//| resolution, the value is 16-bit.""" //| -//|Even if the underlying digital to analog converter (DAC) is lower -//|resolution, the value is 16-bit.""" -//|... STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_analogio_analogout_deinited(self)) { diff --git a/shared-bindings/analogio/__init__.c b/shared-bindings/analogio/__init__.c index b468bcde0..79627f16a 100644 --- a/shared-bindings/analogio/__init__.c +++ b/shared-bindings/analogio/__init__.c @@ -34,7 +34,7 @@ #include "shared-bindings/analogio/AnalogIn.h" #include "shared-bindings/analogio/AnalogOut.h" -//| :mod:`analogio` --- Analog hardware support +//| """:mod:`analogio` --- Analog hardware support //| ================================================= //| //| .. module:: analogio @@ -70,7 +70,7 @@ //| This example will initialize the the device, read //| :py:data:`~analogio.AnalogIn.value` and then //| :py:meth:`~analogio.AnalogIn.deinit` the hardware. The last step is optional -//| because CircuitPython will do it automatically after the program finishes. +//| because CircuitPython will do it automatically after the program finishes.""" //| STATIC const mp_rom_map_elem_t analogio_module_globals_table[] = { diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 765e0a12d..724a65a34 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -35,64 +35,66 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//|class I2SOut: -//|""".. currentmodule:: audiobusio +//| class I2SOut: +//| """.. currentmodule:: audiobusio //| -//|:class:`I2SOut` -- Output an I2S audio signal -//|======================================================== +//| :class:`I2SOut` -- Output an I2S audio signal +//| ======================================================== //| -//|I2S is used to output an audio signal on an I2S bus.""" -//|def __init__(self, bit_clock: microcontroller.Pin, word_select: microcontroller.Pin, data: microcontroller.Pin, *, left_justified: bool): -//|"""Create a I2SOut object associated with the given pins. +//| I2S is used to output an audio signal on an I2S bus.""" //| -//|:param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin -//|:param ~microcontroller.Pin word_select: The word select (or left/right clock) pin -//|:param ~microcontroller.Pin data: The data pin -//|:param bool left_justified: True when data bits are aligned with the word select clock. False -//|when they are shifted by one to match classic I2S protocol. +//| def __init__(self, bit_clock: microcontroller.Pin, word_select: microcontroller.Pin, data: microcontroller.Pin, *, left_justified: bool): +//| """Create a I2SOut object associated with the given pins. //| -//|Simple 8ksps 440 Hz sine wave on `Metro M0 Express <https://www.adafruit.com/product/3505>`_ -//|using `UDA1334 Breakout <https://www.adafruit.com/product/3678>`_:: +//| :param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin +//| :param ~microcontroller.Pin word_select: The word select (or left/right clock) pin +//| :param ~microcontroller.Pin data: The data pin +//| :param bool left_justified: True when data bits are aligned with the word select clock. False +//| when they are shifted by one to match classic I2S protocol. //| -//|import audiobusio -//|import audiocore -//|import board -//|import array -//|import time -//|import math +//| Simple 8ksps 440 Hz sine wave on `Metro M0 Express <https://www.adafruit.com/product/3505>`_ +//| using `UDA1334 Breakout <https://www.adafruit.com/product/3678>`_:: //| -//|# Generate one period of sine wave. -//|length = 8000 // 440 -//|sine_wave = array.array("H", [0] * length) -//|for i in range(length): -//|sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) +//| import audiobusio +//| import audiocore +//| import board +//| import array +//| import time +//| import math //| -//|sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) -//|i2s = audiobusio.I2SOut(board.D1, board.D0, board.D9) -//|i2s.play(sine_wave, loop=True) -//|time.sleep(1) -//|i2s.stop() +//| # Generate one period of sine wave. +//| length = 8000 // 440 +//| sine_wave = array.array("H", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) //| -//|Playing a wave file from flash:: +//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) +//| i2s = audiobusio.I2SOut(board.D1, board.D0, board.D9) +//| i2s.play(sine_wave, loop=True) +//| time.sleep(1) +//| i2s.stop() //| -//|import board -//|import audioio -//|import audiocore -//|import audiobusio -//|import digitalio +//| Playing a wave file from flash:: //| +//| import board +//| import audioio +//| import audiocore +//| import audiobusio +//| import digitalio //| -//|f = open("cplay-5.1-16bit-16khz.wav", "rb") -//|wav = audiocore.WaveFile(f) //| -//|a = audiobusio.I2SOut(board.D1, board.D0, board.D9) +//| f = open("cplay-5.1-16bit-16khz.wav", "rb") +//| wav = audiocore.WaveFile(f) +//| +//| a = audiobusio.I2SOut(board.D1, board.D0, board.D9) +//| +//| print("playing") +//| a.play(wav) +//| while a.playing: +//| pass +//| print("stopped")""" +//| ... //| -//|print("playing") -//|a.play(wav) -//|while a.playing: -//|pass -//|print("stopped")""" -//|... STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_left_justified }; static const mp_arg_t allowed_args[] = { @@ -115,9 +117,10 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a return MP_OBJ_FROM_PTR(self); } -//|def deinit(self, ) -> Any: -//|"""Deinitialises the I2SOut and releases any hardware resources for reuse.""" -//|... +//| def deinit(self, ) -> Any: +//| """Deinitialises the I2SOut and releases any hardware resources for reuse.""" +//| ... +//| STATIC mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiobusio_i2sout_deinit(self); @@ -130,15 +133,17 @@ STATIC void check_for_deinit(audiobusio_i2sout_obj_t *self) { raise_deinited_error(); } } -//|def __enter__(self, ) -> Any: -//|"""No-op used by Context Managers.""" -//|... +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... +//| // Provided by context manager helper. -//|def __exit__(self, ) -> Any: -//|"""Automatically deinitializes the hardware when exiting a context. See -//|:ref:`lifetime-and-contextmanagers` for more info.""" -//|... +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| STATIC mp_obj_t audiobusio_i2sout_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audiobusio_i2sout_deinit(args[0]); @@ -147,14 +152,15 @@ STATIC mp_obj_t audiobusio_i2sout_obj___exit__(size_t n_args, const mp_obj_t *ar STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, audiobusio_i2sout_obj___exit__); -//|def play(self, sample: Any, *, loop: Any = False) -> Any: -//|"""Plays the sample once when loop=False and continuously when loop=True. -//|Does not block. Use `playing` to block. +//| def play(self, sample: Any, *, loop: Any = False) -> Any: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. //| -//|Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. +//| The sample itself should consist of 8 bit or 16 bit samples.""" +//| ... //| -//|The sample itself should consist of 8 bit or 16 bit samples.""" -//|... STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -173,9 +179,10 @@ STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_ar } MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_play); -//|def stop(self, ) -> Any: -//|"""Stops playback.""" -//|... +//| def stop(self, ) -> Any: +//| """Stops playback.""" +//| ... +//| STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -184,9 +191,9 @@ STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop); -//|playing: Any = -//|"""True when the audio sample is being output. (read-only)""" -//|... +//| playing: Any = ... +//| """True when the audio sample is being output. (read-only)""" +//| STATIC mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -201,9 +208,10 @@ const mp_obj_property_t audiobusio_i2sout_playing_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//|def pause(self, ) -> Any: -//|"""Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" -//|... +//| def pause(self, ) -> Any: +//| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" +//| ... +//| STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -216,9 +224,10 @@ STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pause); -//|def resume(self, ) -> Any: -//|"""Resumes sample playback after :py:func:`pause`.""" -//|... +//| def resume(self, ) -> Any: +//| """Resumes sample playback after :py:func:`pause`.""" +//| ... +//| STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -231,9 +240,9 @@ STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_resume_obj, audiobusio_i2sout_obj_resume); -//|paused: Any = -//|"""True when playback is paused. (read-only)""" -//|... +//| paused: Any = ... +//| """True when playback is paused. (read-only)""" +//| STATIC mp_obj_t audiobusio_i2sout_obj_get_paused(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 28ff9a481..6cc834724 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -36,57 +36,58 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//|class PDMIn: -//|""".. currentmodule:: audiobusio -//| -//|:class:`PDMIn` -- Record an input PDM audio stream -//|======================================================== -//| -//|PDMIn can be used to record an input audio signal on a given set of pins.""" -//| -//|def __init__(self, clock_pin: microcontroller.Pin, data_pin: microcontroller.Pin, *, sample_rate: int = 16000, bit_depth: int = 8, mono: bool = True, oversample: int = 64, startup_delay: float = 0.11): -//|"""Create a PDMIn object associated with the given pins. This allows you to -//|record audio signals from the given pins. Individual ports may put further -//|restrictions on the recording parameters. The overall sample rate is -//|determined by `sample_rate` x ``oversample``, and the total must be 1MHz or -//|higher, so `sample_rate` must be a minimum of 16000. -//| -//|:param ~microcontroller.Pin clock_pin: The pin to output the clock to -//|:param ~microcontroller.Pin data_pin: The pin to read the data from -//|:param int sample_rate: Target sample_rate of the resulting samples. Check `sample_rate` for actual value. -//|Minimum sample_rate is about 16000 Hz. -//|:param int bit_depth: Final number of bits per sample. Must be divisible by 8 -//|:param bool mono: True when capturing a single channel of audio, captures two channels otherwise -//|:param int oversample: Number of single bit samples to decimate into a final sample. Must be divisible by 8 -//|:param float startup_delay: seconds to wait after starting microphone clock -//|to allow microphone to turn on. Most require only 0.01s; some require 0.1s. Longer is safer. -//|Must be in range 0.0-1.0 seconds.""" -//|... - -//|Record 8-bit unsigned samples to buffer:: -//| -//|import audiobusio -//|import board -//| -//|# Prep a buffer to record into -//|b = bytearray(200) -//|with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000) as mic: -//|mic.record(b, len(b)) -//| -//|Record 16-bit unsigned samples to buffer:: -//| -//|import audiobusio -//|import board -//| -//|# Prep a buffer to record into. The array interface doesn't allow for -//|# constructing with a set size so we append to it until we have the size -//|# we want. -//|b = array.array("H") -//|for i in range(200): -//|b.append(0) -//|with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16) as mic: -//|mic.record(b, len(b)) -//| +//| class PDMIn: +//| """.. currentmodule:: audiobusio +//| +//| :class:`PDMIn` -- Record an input PDM audio stream +//| ======================================================== +//| +//| PDMIn can be used to record an input audio signal on a given set of pins.""" +//| +//| def __init__(self, clock_pin: microcontroller.Pin, data_pin: microcontroller.Pin, *, sample_rate: int = 16000, bit_depth: int = 8, mono: bool = True, oversample: int = 64, startup_delay: float = 0.11): +//| """Create a PDMIn object associated with the given pins. This allows you to +//| record audio signals from the given pins. Individual ports may put further +//| restrictions on the recording parameters. The overall sample rate is +//| determined by `sample_rate` x ``oversample``, and the total must be 1MHz or +//| higher, so `sample_rate` must be a minimum of 16000. +//| +//| :param ~microcontroller.Pin clock_pin: The pin to output the clock to +//| :param ~microcontroller.Pin data_pin: The pin to read the data from +//| :param int sample_rate: Target sample_rate of the resulting samples. Check `sample_rate` for actual value. +//| Minimum sample_rate is about 16000 Hz. +//| :param int bit_depth: Final number of bits per sample. Must be divisible by 8 +//| :param bool mono: True when capturing a single channel of audio, captures two channels otherwise +//| :param int oversample: Number of single bit samples to decimate into a final sample. Must be divisible by 8 +//| :param float startup_delay: seconds to wait after starting microphone clock +//| to allow microphone to turn on. Most require only 0.01s; some require 0.1s. Longer is safer. +//| Must be in range 0.0-1.0 seconds.""" +//| + +//| """Record 8-bit unsigned samples to buffer:: +//| +//| import audiobusio +//| import board +//| +//| # Prep a buffer to record into +//| b = bytearray(200) +//| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000) as mic: +//| mic.record(b, len(b)) +//| +//| Record 16-bit unsigned samples to buffer:: +//| +//| import audiobusio +//| import board +//| +//| # Prep a buffer to record into. The array interface doesn't allow for +//| # constructing with a set size so we append to it until we have the size +//| # we want. +//| b = array.array("H") +//| for i in range(200): +//| b.append(0) +//| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16) as mic: +//| mic.record(b, len(b))""" +//| ... +//| STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_clock_pin, ARG_data_pin, ARG_sample_rate, ARG_bit_depth, ARG_mono, ARG_oversample, ARG_startup_delay }; static const mp_arg_t allowed_args[] = { @@ -138,9 +139,10 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar return MP_OBJ_FROM_PTR(self); } -//|def deinit(self, ) -> Any: -//|"""Deinitialises the PDMIn and releases any hardware resources for reuse.""" -//|... +//| def deinit(self, ) -> Any: +//| """Deinitialises the PDMIn and releases any hardware resources for reuse.""" +//| ... +//| STATIC mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiobusio_pdmin_deinit(self); @@ -153,14 +155,16 @@ STATIC void check_for_deinit(audiobusio_pdmin_obj_t *self) { raise_deinited_error(); } } -//|def __enter__(self, ) -> Any: -//|"""No-op used by Context Managers.""" -//|... +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... +//| // Provided by context manager helper. -//|def __exit__(self, ) -> Any: -//|"""Automatically deinitializes the hardware when exiting a context.""" -//|... +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context.""" +//| ... +//| STATIC mp_obj_t audiobusio_pdmin_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audiobusio_pdmin_deinit(args[0]); @@ -169,17 +173,18 @@ STATIC mp_obj_t audiobusio_pdmin_obj___exit__(size_t n_args, const mp_obj_t *arg STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, audiobusio_pdmin_obj___exit__); -//|def record(self, destination: Any, destination_length: Any) -> Any: -//|"""Records destination_length bytes of samples to destination. This is -//|blocking. +//| def record(self, destination: Any, destination_length: Any) -> Any: +//| """Records destination_length bytes of samples to destination. This is +//| blocking. //| -//|An IOError may be raised when the destination is too slow to record the -//|audio at the given rate. For internal flash, writing all 1s to the file -//|before recording is recommended to speed up writes. +//| An IOError may be raised when the destination is too slow to record the +//| audio at the given rate. For internal flash, writing all 1s to the file +//| before recording is recommended to speed up writes. +//| +//| :return: The number of samples recorded. If this is less than ``destination_length``, +//| some samples were missed due to processing time.""" +//| ... //| -//|:return: The number of samples recorded. If this is less than ``destination_length``, -//|some samples were missed due to processing time.""" -//|... STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -210,10 +215,10 @@ STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destinat } MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_record); -//|sample_rate: Any = -//|"""The actual sample_rate of the recording. This may not match the constructed -//|sample rate due to internal clock limitations.""" -//|... +//| sample_rate: Any = ... +//| """The actual sample_rate of the recording. This may not match the constructed +//| sample rate due to internal clock limitations.""" +//| STATIC mp_obj_t audiobusio_pdmin_obj_get_sample_rate(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiobusio/__init__.c b/shared-bindings/audiobusio/__init__.c index f7e3a0766..c5c387361 100644 --- a/shared-bindings/audiobusio/__init__.c +++ b/shared-bindings/audiobusio/__init__.c @@ -34,7 +34,7 @@ #include "shared-bindings/audiobusio/I2SOut.h" #include "shared-bindings/audiobusio/PDMIn.h" -//| :mod:`audiobusio` --- Support for audio input and output over digital bus +//| """:mod:`audiobusio` --- Support for audio input and output over digital bus //| ========================================================================= //| //| .. module:: audiobusio @@ -56,7 +56,7 @@ //| //| All libraries change hardware state and should be deinitialized when they //| are no longer needed. To do so, either call :py:meth:`!deinit` or use a -//| context manager. +//| context manager.""" //| STATIC const mp_rom_map_elem_t audiobusio_module_globals_table[] = { diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c index fdedfe959..6091fbfc0 100644 --- a/shared-bindings/audiocore/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -35,45 +35,52 @@ #include "shared-bindings/audiocore/RawSample.h" #include "supervisor/shared/translate.h" -//|class RawSample: -//|""".. currentmodule:: audiocore + + + + + + +//| class RawSample: +//| """.. currentmodule:: audiocore //| -//|:class:`RawSample` -- A raw audio sample buffer -//|======================================================== +//| :class:`RawSample` -- A raw audio sample buffer +//| ======================================================== //| -//|An in-memory sound sample""" +//| An in-memory sound sample""" //| -//|def __init__(self, buffer: array.array, *, channel_count: int = 1, sample_rate: int = 8000): -//|"""Create a RawSample based on the given buffer of signed values. If channel_count is more than -//|1 then each channel's samples should alternate. In other words, for a two channel buffer, the -//|first sample will be for channel 1, the second sample will be for channel two, the third for -//|channel 1 and so on. +//| def __init__(self, buffer: array.array, *, channel_count: int = 1, sample_rate: int = 8000): +//| """Create a RawSample based on the given buffer of signed values. If channel_count is more than +//| 1 then each channel's samples should alternate. In other words, for a two channel buffer, the +//| first sample will be for channel 1, the second sample will be for channel two, the third for +//| channel 1 and so on. //| -//|:param array.array buffer: An `array.array` with samples -//|:param int channel_count: The number of channels in the buffer -//|:param int sample_rate: The desired playback sample rate +//| :param array.array buffer: An `array.array` with samples +//| :param int channel_count: The number of channels in the buffer +//| :param int sample_rate: The desired playback sample rate //| -//|Simple 8ksps 440 Hz sin wave:: +//| Simple 8ksps 440 Hz sin wave:: //| -//|import audiocore -//|import audioio -//|import board -//|import array -//|import time -//|import math +//| import audiocore +//| import audioio +//| import board +//| import array +//| import time +//| import math //| -//|# Generate one period of sine wav. -//|length = 8000 // 440 -//|sine_wave = array.array("h", [0] * length) -//|for i in range(length): -//|sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15)) +//| # Generate one period of sine wav. +//| length = 8000 // 440 +//| sine_wave = array.array("h", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15)) +//| +//| dac = audioio.AudioOut(board.SPEAKER) +//| sine_wave = audiocore.RawSample(sine_wave) +//| dac.play(sine_wave, loop=True) +//| time.sleep(1) +//| dac.stop()""" +//| ... //| -//|dac = audioio.AudioOut(board.SPEAKER) -//|sine_wave = audiocore.RawSample(sine_wave) -//|dac.play(sine_wave, loop=True) -//|time.sleep(1) -//|dac.stop()""" -//|... STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_channel_count, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { @@ -105,9 +112,10 @@ STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a return MP_OBJ_FROM_PTR(self); } -//|def deinit(self, ) -> Any: -//|"""Deinitialises the AudioOut and releases any hardware resources for reuse.""" -//|... +//| def deinit(self, ) -> Any: +//| """Deinitialises the AudioOut and releases any hardware resources for reuse.""" +//| ... +//| STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_rawsample_deinit(self); @@ -121,15 +129,17 @@ STATIC void check_for_deinit(audioio_rawsample_obj_t *self) { } } -//|def __enter__(self, ) -> Any: -//|"""No-op used by Context Managers.""" -//|... +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... +//| // Provided by context manager helper. -//|def __exit__(self, ) -> Any: -//|"""Automatically deinitializes the hardware when exiting a context. See -//|:ref:`lifetime-and-contextmanagers` for more info.""" -//|... +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| STATIC mp_obj_t audioio_rawsample_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audioio_rawsample_deinit(args[0]); @@ -137,12 +147,12 @@ STATIC mp_obj_t audioio_rawsample_obj___exit__(size_t n_args, const mp_obj_t *ar } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4, audioio_rawsample_obj___exit__); -//|sample_rate: Any = -//|"""32 bit value that dictates how quickly samples are played in Hertz (cycles per second). -//|When the sample is looped, this can change the pitch output without changing the underlying -//|sample. This will not change the sample rate of any active playback. Call ``play`` again to -//|change it.""" -//|... +//| sample_rate: Any = ... +//| """32 bit value that dictates how quickly samples are played in Hertz (cycles per second). +//| When the sample is looped, this can change the pitch output without changing the underlying +//| sample. This will not change the sample rate of any active playback. Call ``play`` again to +//| change it.""" +//| STATIC mp_obj_t audioio_rawsample_obj_get_sample_rate(mp_obj_t self_in) { audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index 9116e71f0..65b42fb6c 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -33,43 +33,45 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//|class WaveFile: -//|""".. currentmodule:: audiocore +//| class WaveFile: +//| """.. currentmodule:: audiocore //| -//|:class:`WaveFile` -- Load a wave file for audio playback -//|======================================================== +//| :class:`WaveFile` -- Load a wave file for audio playback +//| ======================================================== //| -//|A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must -//|be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating -//|an internal buffer.""" -//|def __init__(self, file: typing.BinaryIO, buffer: bytearray): -//|"""Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. +//| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must +//| be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating +//| an internal buffer.""" //| -//|:param typing.BinaryIO file: Already opened wave file -//|:param bytearray buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated internally. +//| def __init__(self, file: typing.BinaryIO, buffer: bytearray): +//| """Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| +//| :param typing.BinaryIO file: Already opened wave file +//| :param bytearray buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated internally. //| -//|Playing a wave file from flash:: //| -//|import board -//|import audiocore -//|import audioio -//|import digitalio +//| Playing a wave file from flash:: //| -//|# Required for CircuitPlayground Express -//|speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) -//|speaker_enable.switch_to_output(value=True) +//| import board +//| import audiocore +//| import audioio +//| import digitalio //| -//|data = open("cplay-5.1-16bit-16khz.wav", "rb") -//|wav = audiocore.WaveFile(data) -//|a = audioio.AudioOut(board.A0) +//| # Required for CircuitPlayground Express +//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) +//| speaker_enable.switch_to_output(value=True) +//| +//| data = open("cplay-5.1-16bit-16khz.wav", "rb") +//| wav = audiocore.WaveFile(data) +//| a = audioio.AudioOut(board.A0) +//| +//| print("playing") +//| a.play(wav) +//| while a.playing: +//| pass +//| print("stopped")""" +//| ... //| -//|print("playing") -//|a.play(wav) -//|while a.playing: -//|pass -//|print("stopped")""" -//|... STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_check_num(n_args, kw_args, 1, 2, false); @@ -92,9 +94,9 @@ STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar return MP_OBJ_FROM_PTR(self); } -//|def deinit(self, ) -> Any: -//|"""Deinitialises the WaveFile and releases all memory resources for reuse.""" -//|... +//| def deinit(self, ) -> Any: +//| """Deinitialises the WaveFile and releases all memory resources for reuse.""" +//| ... STATIC mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_wavefile_deinit(self); @@ -108,15 +110,17 @@ STATIC void check_for_deinit(audioio_wavefile_obj_t *self) { } } -//|def __enter__(self, ) -> Any: -//|"""No-op used by Context Managers.""" -//|... +//| def __enter__(self, ) -> Any: +//| """No-op used by Context Managers.""" +//| ... +//| // Provided by context manager helper. -//|def __exit__(self, ) -> Any: -//|"""Automatically deinitializes the hardware when exiting a context. See -//|:ref:`lifetime-and-contextmanagers` for more info.""" -//|... +//| def __exit__(self, ) -> Any: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| STATIC mp_obj_t audioio_wavefile_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audioio_wavefile_deinit(args[0]); @@ -124,11 +128,11 @@ STATIC mp_obj_t audioio_wavefile_obj___exit__(size_t n_args, const mp_obj_t *arg } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4, audioio_wavefile_obj___exit__); -//|sample_rate: Any = -//|"""32 bit value that dictates how quickly samples are loaded into the DAC -//|in Hertz (cycles per second). When the sample is looped, this can change -//|the pitch output without changing the underlying sample.""" -//|... +//| sample_rate: Any = ... +//| """32 bit value that dictates how quickly samples are loaded into the DAC +//| in Hertz (cycles per second). When the sample is looped, this can change +//| the pitch output without changing the underlying sample.""" +//| STATIC mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -151,9 +155,9 @@ const mp_obj_property_t audioio_wavefile_sample_rate_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//|bits_per_sample: Any = -//|"""Bits per sample. (read only)""" -//|... +//| bits_per_sample: Any = ... +//| """Bits per sample. (read only)""" +//| STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -167,10 +171,9 @@ const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = { (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; - -//|channel_count: Any = -//|"""Number of audio channels. (read only)""" -//|... +//| channel_count: Any = ... +//| """Number of audio channels. (read only)""" +//| STATIC mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c index cf05112cb..38f91d8ee 100644 --- a/shared-bindings/audiocore/__init__.c +++ b/shared-bindings/audiocore/__init__.c @@ -35,7 +35,7 @@ #include "shared-bindings/audiocore/WaveFile.h" //#include "shared-bindings/audiomixer/Mixer.h" -//| :mod:`audiocore` --- Support for audio samples and mixer +//| """:mod:`audiocore` --- Support for audio samples and mixer //| ======================================================== //| //| .. module:: audiocore @@ -50,7 +50,7 @@ //| :maxdepth: 3 //| //| RawSample -//| WaveFile +//| WaveFile""" //| STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = { |
