Did audioio, audiomixer, audiomp3

This commit is contained in:
dherrada 2020-04-30 13:06:09 -04:00
parent 7ff9b9bc80
commit d65e851044
No known key found for this signature in database
GPG Key ID: CE2ADBAB8775CE81
7 changed files with 247 additions and 227 deletions

View File

@ -36,64 +36,65 @@
#include "shared-bindings/util.h" #include "shared-bindings/util.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
//|class AudioOut: //| class AudioOut:
//|""".. currentmodule:: audioio //| """.. currentmodule:: audioio
//| //|
//|:class:`AudioOut` -- Output an analog audio signal //| :class:`AudioOut` -- Output an analog audio signal
//|======================================================== //| ========================================================
//| //|
//|AudioOut can be used to output an analog audio signal on a given pin.""" //| AudioOut can be used to output an analog audio signal on a given pin."""
//| //|
//|def __init__(self, left_channel: microcontroller.Pin, *, right_channel: microcontroller.Pin = None, quiescent_value: int = 0x8000): //| def __init__(self, left_channel: microcontroller.Pin, *, right_channel: microcontroller.Pin = None, quiescent_value: int = 0x8000):
//|"""Create a AudioOut object associated with the given pin(s). This allows you to //| """Create a AudioOut object associated with the given pin(s). This allows you to
//|play audio signals out on the given pin(s). //| play audio signals out on the given pin(s).
//| //|
//|:param ~microcontroller.Pin left_channel: The pin to output the left channel to //| :param ~microcontroller.Pin left_channel: The pin to output the left channel to
//|:param ~microcontroller.Pin right_channel: The pin to output the right channel to //| :param ~microcontroller.Pin right_channel: The pin to output the right channel to
//|:param int quiescent_value: The output value when no signal is present. Samples should start //| :param int quiescent_value: The output value when no signal is present. Samples should start
//|and end with this value to prevent audible popping. //| and end with this value to prevent audible popping.
//| //|
//|Simple 8ksps 440 Hz sin wave:: //| Simple 8ksps 440 Hz sin wave::
//| //|
//|import audiocore //| import audiocore
//|import audioio //| import audioio
//|import board //| import board
//|import array //| import array
//|import time //| import time
//|import math //| import math
//| //|
//|# Generate one period of sine wav. //| # Generate one period of sine wav.
//|length = 8000 // 440 //| length = 8000 // 440
//|sine_wave = array.array("H", [0] * length) //| sine_wave = array.array("H", [0] * length)
//|for i in range(length): //| for i in range(length):
//|sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) //| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
//| //|
//|dac = audioio.AudioOut(board.SPEAKER) //| dac = audioio.AudioOut(board.SPEAKER)
//|sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) //| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
//|dac.play(sine_wave, loop=True) //| dac.play(sine_wave, loop=True)
//|time.sleep(1) //| time.sleep(1)
//|dac.stop() //| dac.stop()
//| //|
//|Playing a wave file from flash:: //| Playing a wave file from flash::
//| //|
//|import board //| import board
//|import audioio //| import audioio
//|import digitalio //| import digitalio
//| //|
//|# Required for CircuitPlayground Express //| # Required for CircuitPlayground Express
//|speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) //| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
//|speaker_enable.switch_to_output(value=True) //| speaker_enable.switch_to_output(value=True)
//| //|
//|data = open("cplay-5.1-16bit-16khz.wav", "rb") //| data = open("cplay-5.1-16bit-16khz.wav", "rb")
//|wav = audiocore.WaveFile(data) //| wav = audiocore.WaveFile(data)
//|a = audioio.AudioOut(board.A0) //| 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_audioout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audioio_audioout_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_left_channel, ARG_right_channel, ARG_quiescent_value }; enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -115,9 +116,10 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
//|def deinit(self, ) -> Any: //| def deinit(self, ) -> Any:
//|"""Deinitialises the AudioOut and releases any hardware resources for reuse.""" //| """Deinitialises the AudioOut and releases any hardware resources for reuse."""
//|... //| ...
//|
STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) { STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_audioio_audioout_deinit(self); common_hal_audioio_audioout_deinit(self);
@ -130,15 +132,17 @@ STATIC void check_for_deinit(audioio_audioout_obj_t *self) {
raise_deinited_error(); raise_deinited_error();
} }
} }
//|def __enter__(self, ) -> Any: //| def __enter__(self, ) -> Any:
//|"""No-op used by Context Managers.""" //| """No-op used by Context Managers."""
//|... //| ...
//|
// Provided by context manager helper. // Provided by context manager helper.
//|def __exit__(self, ) -> Any: //| def __exit__(self, ) -> Any:
//|"""Automatically deinitializes the hardware when exiting a context. See //| """Automatically deinitializes the hardware when exiting a context. See
//|:ref:`lifetime-and-contextmanagers` for more info.""" //| :ref:`lifetime-and-contextmanagers` for more info."""
//|... //| ...
//|
STATIC mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args; (void)n_args;
common_hal_audioio_audioout_deinit(args[0]); common_hal_audioio_audioout_deinit(args[0]);
@ -147,16 +151,17 @@ STATIC mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *arg
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, audioio_audioout_obj___exit__); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, audioio_audioout_obj___exit__);
//|def play(self, sample: Any, *, loop: Any = False) -> Any: //| def play(self, sample: Any, *, loop: Any = False) -> Any:
//|"""Plays the sample once when loop=False and continuously when loop=True. //| """Plays the sample once when loop=False and continuously when loop=True.
//|Does not block. Use `playing` to block. //| 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 16 bit samples. Microcontrollers with a lower output
//| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit
//| DAC that ignores the lowest 6 bits when playing 16 bit samples."""
//| ...
//| //|
//|The sample itself should consist of 16 bit samples. Microcontrollers with a lower output
//|resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit
//|DAC that ignores the lowest 6 bits when playing 16 bit samples."""
//|...
STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_sample, ARG_loop }; enum { ARG_sample, ARG_loop };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -175,9 +180,10 @@ STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_arg
} }
MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_play); MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_play);
//|def stop(self, ) -> Any: //| def stop(self, ) -> Any:
//|"""Stops playback and resets to the start of the sample.""" //| """Stops playback and resets to the start of the sample."""
//|... //| ...
//|
STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) { STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -186,9 +192,9 @@ STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) {
} }
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop); MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop);
//|playing: Any = //| playing: Any = ...
//|"""True when an audio sample is being output even if `paused`. (read-only)""" //| """True when an audio sample is being output even if `paused`. (read-only)"""
//|... //|
STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) { STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -203,9 +209,10 @@ const mp_obj_property_t audioio_audioout_playing_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|def pause(self, ) -> Any: //| def pause(self, ) -> Any:
//|"""Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback."""
//|... //| ...
//|
STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) { STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -218,9 +225,10 @@ STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) {
} }
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause); MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause);
//|def resume(self, ) -> Any: //| def resume(self, ) -> Any:
//|"""Resumes sample playback after :py:func:`pause`.""" //| """Resumes sample playback after :py:func:`pause`."""
//|... //| ...
//|
STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) { STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -233,9 +241,9 @@ STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) {
} }
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resume); MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resume);
//|paused: Any = //| paused: Any = ...
//|"""True when playback is paused. (read-only)""" //| """True when playback is paused. (read-only)"""
//|... //|
STATIC mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) { STATIC mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);

View File

@ -42,7 +42,7 @@
#include "shared-bindings/audiomixer/Mixer.h" #include "shared-bindings/audiomixer/Mixer.h"
#endif #endif
//| :mod:`audioio` --- Support for audio input and output //| """:mod:`audioio` --- Support for audio input and output
//| ====================================================== //| ======================================================
//| //|
//| .. module:: audioio //| .. module:: audioio
@ -68,7 +68,7 @@
//| //|
//| For compatibility with CircuitPython 4.x, some builds allow the items in //| For compatibility with CircuitPython 4.x, some builds allow the items in
//| `audiocore` to be imported from `audioio`. This will be removed for all //| `audiocore` to be imported from `audioio`. This will be removed for all
//| boards in a future build of CircuitPython. //| boards in a future build of CircuitPython."""
//| //|
STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = { STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = {

View File

@ -38,50 +38,51 @@
#include "shared-bindings/util.h" #include "shared-bindings/util.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
//|class Mixer: //| class Mixer:
//|""".. currentmodule:: audiomixer //| """.. currentmodule:: audiomixer
//| //|
//|:class:`Mixer` -- Mixes one or more audio samples together //| :class:`Mixer` -- Mixes one or more audio samples together
//|=========================================================== //| ===========================================================
//| //|
//|Mixer mixes multiple samples into one sample.""" //| Mixer mixes multiple samples into one sample."""
//| //|
//|def __init__(self, voice_count: int = 2, buffer_size: int = 1024, channel_count: int = 2, bits_per_sample: int = 16, samples_signed: bool = True, sample_rate: int = 8000): //| def __init__(self, voice_count: int = 2, buffer_size: int = 1024, channel_count: int = 2, bits_per_sample: int = 16, samples_signed: bool = True, sample_rate: int = 8000):
//|"""Create a Mixer object that can mix multiple channels with the same sample rate. //| """Create a Mixer object that can mix multiple channels with the same sample rate.
//|Samples are accessed and controlled with the mixer's `audiomixer.MixerVoice` objects. //| Samples are accessed and controlled with the mixer's `audiomixer.MixerVoice` objects.
//| //|
//|:param int voice_count: The maximum number of voices to mix //| :param int voice_count: The maximum number of voices to mix
//|:param int buffer_size: The total size in bytes of the buffers to mix into //| :param int buffer_size: The total size in bytes of the buffers to mix into
//|:param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. //| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo.
//|:param int bits_per_sample: The bits per sample of the samples being played //| :param int bits_per_sample: The bits per sample of the samples being played
//|:param bool samples_signed: Samples are signed (True) or unsigned (False) //| :param bool samples_signed: Samples are signed (True) or unsigned (False)
//|:param int sample_rate: The sample rate to be used for all samples //| :param int sample_rate: The sample rate to be used for all samples
//| //|
//|Playing a wave file from flash:: //| Playing a wave file from flash::
//| //|
//|import board //| import board
//|import audioio //| import audioio
//|import audiocore //| import audiocore
//|import audiomixer //| import audiomixer
//|import digitalio //| import digitalio
//| //|
//|a = audioio.AudioOut(board.A0) //| a = audioio.AudioOut(board.A0)
//|music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb")) //| music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb"))
//|drum = audiocore.WaveFile(open("drum.wav", "rb")) //| drum = audiocore.WaveFile(open("drum.wav", "rb"))
//|mixer = audiomixer.Mixer(voice_count=2, sample_rate=16000, channel_count=1, //| mixer = audiomixer.Mixer(voice_count=2, sample_rate=16000, channel_count=1,
//|bits_per_sample=16, samples_signed=True) //| bits_per_sample=16, samples_signed=True)
//|
//| print("playing")
//| # Have AudioOut play our Mixer source
//| a.play(mixer)
//| # Play the first sample voice
//| mixer.voice[0].play(music)
//| while mixer.playing:
//| # Play the second sample voice
//| mixer.voice[1].play(drum)
//| time.sleep(1)
//| print("stopped")"""
//| ...
//| //|
//|print("playing")
//|# Have AudioOut play our Mixer source
//|a.play(mixer)
//|# Play the first sample voice
//|mixer.voice[0].play(music)
//|while mixer.playing:
//|# Play the second sample voice
//|mixer.voice[1].play(drum)
//|time.sleep(1)
//|print("stopped")"""
//|...
STATIC mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audiomixer_mixer_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_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -125,9 +126,10 @@ STATIC mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_ar
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
//|def deinit(self, ) -> Any: //| def deinit(self, ) -> Any:
//|"""Deinitialises the Mixer and releases any hardware resources for reuse.""" //| """Deinitialises the Mixer and releases any hardware resources for reuse."""
//|... //| ...
//|
STATIC mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) { STATIC mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) {
audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_audiomixer_mixer_deinit(self); common_hal_audiomixer_mixer_deinit(self);
@ -141,15 +143,17 @@ STATIC void check_for_deinit(audiomixer_mixer_obj_t *self) {
} }
} }
//|def __enter__(self, ) -> Any: //| def __enter__(self, ) -> Any:
//|"""No-op used by Context Managers.""" //| """No-op used by Context Managers."""
//|... //| ...
//|
// Provided by context manager helper. // Provided by context manager helper.
//|def __exit__(self, ) -> Any: //| def __exit__(self, ) -> Any:
//|"""Automatically deinitializes the hardware when exiting a context. See //| """Automatically deinitializes the hardware when exiting a context. See
//|:ref:`lifetime-and-contextmanagers` for more info.""" //| :ref:`lifetime-and-contextmanagers` for more info."""
//|... //| ...
//|
STATIC mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args; (void)n_args;
common_hal_audiomixer_mixer_deinit(args[0]); common_hal_audiomixer_mixer_deinit(args[0]);
@ -157,9 +161,9 @@ STATIC mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *arg
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomixer_mixer___exit___obj, 4, 4, audiomixer_mixer_obj___exit__); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomixer_mixer___exit___obj, 4, 4, audiomixer_mixer_obj___exit__);
//|playing: Any = //| playing: Any = ...
//|"""True when any voice is being output. (read-only)""" //| """True when any voice is being output. (read-only)"""
//|... //|
STATIC mp_obj_t audiomixer_mixer_obj_get_playing(mp_obj_t self_in) { STATIC mp_obj_t audiomixer_mixer_obj_get_playing(mp_obj_t self_in) {
audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -174,9 +178,9 @@ const mp_obj_property_t audiomixer_mixer_playing_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|sample_rate: Any = //| sample_rate: Any = ...
//|"""32 bit value that dictates how quickly samples are played in Hertz (cycles per second).""" //| """32 bit value that dictates how quickly samples are played in Hertz (cycles per second)."""
//|... //|
STATIC mp_obj_t audiomixer_mixer_obj_get_sample_rate(mp_obj_t self_in) { STATIC mp_obj_t audiomixer_mixer_obj_get_sample_rate(mp_obj_t self_in) {
audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -191,14 +195,13 @@ const mp_obj_property_t audiomixer_mixer_sample_rate_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|voice: Any = //| voice: Any = ...
//|"""A tuple of the mixer's `audiomixer.MixerVoice` object(s). //| """A tuple of the mixer's `audiomixer.MixerVoice` object(s).
//| //|
//|.. code-block:: python //| .. code-block:: python
//| //|
//|>>> mixer.voice //| >>> mixer.voice
//|(<MixerVoice>,)""" //| (<MixerVoice>,)"""
//|...
STATIC mp_obj_t audiomixer_mixer_obj_get_voice(mp_obj_t self_in) { STATIC mp_obj_t audiomixer_mixer_obj_get_voice(mp_obj_t self_in) {
audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -213,14 +216,15 @@ const mp_obj_property_t audiomixer_mixer_voice_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|def play(self, sample: Any, *, voice: Any = 0, loop: Any = False) -> Any: //| def play(self, sample: Any, *, voice: Any = 0, loop: Any = False) -> Any:
//|"""Plays the sample once when loop=False and continuously when loop=True. //| """Plays the sample once when loop=False and continuously when loop=True.
//|Does not block. Use `playing` to block. //| 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 must match the Mixer's encoding settings given in the constructor."""
//| ...
//| //|
//|The sample must match the Mixer's encoding settings given in the constructor."""
//|...
STATIC mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_sample, ARG_voice, ARG_loop }; enum { ARG_sample, ARG_voice, ARG_loop };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -245,9 +249,10 @@ STATIC mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_arg
} }
MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play); MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play);
//|def stop_voice(self, voice: Any = 0) -> Any: //| def stop_voice(self, voice: Any = 0) -> Any:
//|"""Stops playback of the sample on the given voice.""" //| """Stops playback of the sample on the given voice."""
//|... //| ...
//|
STATIC mp_obj_t audiomixer_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audiomixer_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_voice }; enum { ARG_voice };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {

View File

@ -37,18 +37,18 @@
#include "shared-bindings/util.h" #include "shared-bindings/util.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
//|class MixerVoice: //| class MixerVoice:
//|""".. currentmodule:: audiomixer //| """.. currentmodule:: audiomixer
//| //|
//|:class:`MixerVoice` -- Voice objects used with Mixer //| :class:`MixerVoice` -- Voice objects used with Mixer
//|===================================================== //| =====================================================
//| //|
//|Used to access and control samples with `audiomixer.Mixer`.""" //| Used to access and control samples with `audiomixer.Mixer`."""
//| //|
//|def __init__(self, ): //| def __init__(self, ):
//| """MixerVoice instance object(s) created by `audiomixer.Mixer`."""
//| ...
//| //|
//|"""MixerVoice instance object(s) created by `audiomixer.Mixer`."""
//|...
// TODO: support mono or stereo voices // TODO: support mono or stereo voices
STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
audiomixer_mixervoice_obj_t *self = m_new_obj(audiomixer_mixervoice_obj_t); audiomixer_mixervoice_obj_t *self = m_new_obj(audiomixer_mixervoice_obj_t);
@ -59,14 +59,15 @@ STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
//|def play(self, sample: Any, *, loop: Any = False) -> Any: //| def play(self, sample: Any, *, loop: Any = False) -> Any:
//|"""Plays the sample once when ``loop=False``, and continuously when ``loop=True``. //| """Plays the sample once when ``loop=False``, and continuously when ``loop=True``.
//|Does not block. Use `playing` to block. //| Does not block. Use `playing` to block.
//| //|
//|Sample must be an `audiocore.WaveFile`, `audiomixer.Mixer` or `audiocore.RawSample`. //| Sample must be an `audiocore.WaveFile`, `audiomixer.Mixer` or `audiocore.RawSample`.
//|
//| The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor."""
//| ...
//| //|
//|The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor."""
//|...
STATIC mp_obj_t audiomixer_mixervoice_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audiomixer_mixervoice_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_sample, ARG_loop }; enum { ARG_sample, ARG_loop };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -83,9 +84,10 @@ STATIC mp_obj_t audiomixer_mixervoice_obj_play(size_t n_args, const mp_obj_t *po
} }
MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_play_obj, 1, audiomixer_mixervoice_obj_play); MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_play_obj, 1, audiomixer_mixervoice_obj_play);
//|def stop(self, ) -> Any: //| def stop(self, ) -> Any:
//|"""Stops playback of the sample on this voice.""" //| """Stops playback of the sample on this voice."""
//|... //| ...
//|
STATIC mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_voice }; enum { ARG_voice };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -101,9 +103,9 @@ STATIC mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *po
} }
MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop); MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop);
//|level(): Any = //| level: Any = ...
//|"""The volume level of a voice, as a floating point number between 0 and 1.""" //| """The volume level of a voice, as a floating point number between 0 and 1."""
//|... //|
STATIC mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { STATIC mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) {
return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in)); return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in));
} }
@ -137,9 +139,9 @@ const mp_obj_property_t audiomixer_mixervoice_level_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|playing: Any = //| playing: Any = ...
//|"""True when this voice is being output. (read-only)""" //| """True when this voice is being output. (read-only)"""
//|... //|
STATIC mp_obj_t audiomixer_mixervoice_obj_get_playing(mp_obj_t self_in) { STATIC mp_obj_t audiomixer_mixervoice_obj_get_playing(mp_obj_t self_in) {
audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in);

View File

@ -32,7 +32,7 @@
#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/audiomixer/Mixer.h" #include "shared-bindings/audiomixer/Mixer.h"
//| :mod:`audiomixer` --- Support for audio mixer //| """:mod:`audiomixer` --- Support for audio mixer
//| ======================================================== //| ========================================================
//| //|
//| .. module:: audiomixer //| .. module:: audiomixer
@ -46,7 +46,7 @@
//| :maxdepth: 3 //| :maxdepth: 3
//| //|
//| Mixer //| Mixer
//| MixerVoice //| MixerVoice"""
//| //|
STATIC const mp_rom_map_elem_t audiomixer_module_globals_table[] = { STATIC const mp_rom_map_elem_t audiomixer_module_globals_table[] = {

View File

@ -34,42 +34,44 @@
#include "shared-bindings/util.h" #include "shared-bindings/util.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
//|class MP3: //| class MP3:
//|""".. currentmodule:: audiomp3 //| """.. currentmodule:: audiomp3
//| //|
//|:class:`MP3Decoder` -- Load a mp3 file for audio playback //| :class:`MP3Decoder` -- Load a mp3 file for audio playback
//|========================================================= //| =========================================================
//| //|
//|An object that decodes MP3 files for playback on an audio device.""" //| An object that decodes MP3 files for playback on an audio device."""
//| //|
//|def __init__(self, file: typing.BinaryIO, buffer: bytearray): //| def __init__(self, file: typing.BinaryIO, buffer: bytearray):
//|"""Load a .mp3 file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`.
//| //|
//|:param typing.BinaryIO file: Already opened mp3 file //| """Load a .mp3 file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`.
//|: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 buffers are allocated internally. The specific buffer size required depends on the mp3 file. //|
//| :param typing.BinaryIO file: Already opened mp3 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 buffers are allocated internally. The specific buffer size required depends on the mp3 file.
//| //|
//| //|
//|Playing a mp3 file from flash:: //| Playing a mp3 file from flash::
//| //|
//|import board //| import board
//|import audiomp3 //| import audiomp3
//|import audioio //| import audioio
//|import digitalio //| import digitalio
//| //|
//|# Required for CircuitPlayground Express //| # Required for CircuitPlayground Express
//|speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) //| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
//|speaker_enable.switch_to_output(value=True) //| speaker_enable.switch_to_output(value=True)
//| //|
//|data = open("cplay-16bit-16khz-64kbps.mp3", "rb") //| data = open("cplay-16bit-16khz-64kbps.mp3", "rb")
//|mp3 = audiomp3.MP3Decoder(data) //| mp3 = audiomp3.MP3Decoder(data)
//|a = audioio.AudioOut(board.A0) //| a = audioio.AudioOut(board.A0)
//|
//| print("playing")
//| a.play(mp3)
//| while a.playing:
//| pass
//| print("stopped")"""
//| ...
//| //|
//|print("playing")
//|a.play(mp3)
//|while a.playing:
//|pass
//|print("stopped")"""
//|...
STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { STATIC mp_obj_t audiomp3_mp3file_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); mp_arg_check_num(n_args, kw_args, 1, 2, false);
@ -92,9 +94,10 @@ STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
//|def deinit(self, ) -> Any: //| def deinit(self, ) -> Any:
//|"""Deinitialises the MP3 and releases all memory resources for reuse.""" //| """Deinitialises the MP3 and releases all memory resources for reuse."""
//|... //| ...
//|
STATIC mp_obj_t audiomp3_mp3file_deinit(mp_obj_t self_in) { STATIC mp_obj_t audiomp3_mp3file_deinit(mp_obj_t self_in) {
audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_audiomp3_mp3file_deinit(self); common_hal_audiomp3_mp3file_deinit(self);
@ -108,15 +111,17 @@ STATIC void check_for_deinit(audiomp3_mp3file_obj_t *self) {
} }
} }
//|def __enter__(self, ) -> Any: //| def __enter__(self, ) -> Any:
//|"""No-op used by Context Managers.""" //| """No-op used by Context Managers."""
//|... //| ...
//|
// Provided by context manager helper. // Provided by context manager helper.
//|def __exit__(self, ) -> Any: //| def __exit__(self, ) -> Any:
//|"""Automatically deinitializes the hardware when exiting a context. See //| """Automatically deinitializes the hardware when exiting a context. See
//|:ref:`lifetime-and-contextmanagers` for more info.""" //| :ref:`lifetime-and-contextmanagers` for more info."""
//|... //| ...
//|
STATIC mp_obj_t audiomp3_mp3file_obj___exit__(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t audiomp3_mp3file_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args; (void)n_args;
common_hal_audiomp3_mp3file_deinit(args[0]); common_hal_audiomp3_mp3file_deinit(args[0]);
@ -124,9 +129,9 @@ STATIC mp_obj_t audiomp3_mp3file_obj___exit__(size_t n_args, const mp_obj_t *arg
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomp3_mp3file___exit___obj, 4, 4, audiomp3_mp3file_obj___exit__); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomp3_mp3file___exit___obj, 4, 4, audiomp3_mp3file_obj___exit__);
//|file: Any = //| file: Any = ...
//|"""File to play back.""" //| """File to play back."""
//|... //|
STATIC mp_obj_t audiomp3_mp3file_obj_get_file(mp_obj_t self_in) { STATIC mp_obj_t audiomp3_mp3file_obj_get_file(mp_obj_t self_in) {
audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -154,11 +159,11 @@ const mp_obj_property_t audiomp3_mp3file_file_obj = {
//|sample_rate: Any = //| sample_rate: Any = ...
//|"""32 bit value that dictates how quickly samples are loaded into the DAC //| """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 //| in Hertz (cycles per second). When the sample is looped, this can change
//|the pitch output without changing the underlying sample.""" //| the pitch output without changing the underlying sample."""
//|... //|
STATIC mp_obj_t audiomp3_mp3file_obj_get_sample_rate(mp_obj_t self_in) { STATIC mp_obj_t audiomp3_mp3file_obj_get_sample_rate(mp_obj_t self_in) {
audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -181,9 +186,9 @@ const mp_obj_property_t audiomp3_mp3file_sample_rate_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|bits_per_sample: Any = //| bits_per_sample: Any = ...
//|"""Bits per sample. (read only)""" //| """Bits per sample. (read only)"""
//|... //|
STATIC mp_obj_t audiomp3_mp3file_obj_get_bits_per_sample(mp_obj_t self_in) { STATIC mp_obj_t audiomp3_mp3file_obj_get_bits_per_sample(mp_obj_t self_in) {
audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -198,9 +203,9 @@ const mp_obj_property_t audiomp3_mp3file_bits_per_sample_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|channel_count: Any = //| channel_count: Any = ...
//|"""Number of audio channels. (read only)""" //| """Number of audio channels. (read only)"""
//|... //|
STATIC mp_obj_t audiomp3_mp3file_obj_get_channel_count(mp_obj_t self_in) { STATIC mp_obj_t audiomp3_mp3file_obj_get_channel_count(mp_obj_t self_in) {
audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);
@ -215,9 +220,9 @@ const mp_obj_property_t audiomp3_mp3file_channel_count_obj = {
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
//|rms_level: Any = //| rms_level: Any = ...
//|"""The RMS audio level of a recently played moment of audio. (read only)""" //| """The RMS audio level of a recently played moment of audio. (read only)"""
//|... //|
STATIC mp_obj_t audiomp3_mp3file_obj_get_rms_level(mp_obj_t self_in) { STATIC mp_obj_t audiomp3_mp3file_obj_get_rms_level(mp_obj_t self_in) {
audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self); check_for_deinit(self);

View File

@ -31,7 +31,7 @@
#include "shared-bindings/audiomp3/MP3Decoder.h" #include "shared-bindings/audiomp3/MP3Decoder.h"
//| :mod:`audiomp3` --- Support for MP3-compressed audio files //| """:mod:`audiomp3` --- Support for MP3-compressed audio files
//| ========================================================== //| ==========================================================
//| //|
//| .. module:: audiomp3 //| .. module:: audiomp3
@ -44,7 +44,7 @@
//| .. toctree:: //| .. toctree::
//| :maxdepth: 3 //| :maxdepth: 3
//| //|
//| MP3Decoder //| MP3Decoder"""
//| //|
STATIC const mp_rom_map_elem_t audiomp3_module_globals_table[] = { STATIC const mp_rom_map_elem_t audiomp3_module_globals_table[] = {