1717//| """A raw audio sample buffer in memory"""
1818//|
1919//| def __init__(
20- //| self, buffer: ReadableBuffer, *, channel_count: int = 1, sample_rate: int = 8000
20+ //| self,
21+ //| buffer: ReadableBuffer,
22+ //| *,
23+ //| channel_count: int = 1,
24+ //| sample_rate: int = 8000,
25+ //| single_buffer: bool = True
2126//| ) -> None:
2227//| """Create a RawSample based on the given buffer of values. If channel_count is more than
2328//| 1 then each channel's samples should alternate. In other words, for a two channel buffer, the
2732//| :param ~circuitpython_typing.ReadableBuffer buffer: A buffer with samples
2833//| :param int channel_count: The number of channels in the buffer
2934//| :param int sample_rate: The desired playback sample rate
35+ //| :param bool single_buffer: Selects single buffered or double buffered transfer mode. This affects
36+ //| what happens if the sample buffer is changed while the sample is playing.
37+ //| In single buffered transfers, a change in buffer contents will not affect active playback.
38+ //| In double buffered transfers, changed buffer contents will
39+ //| be played back when the transfer reaches the next half-buffer point.
3040//|
31- //| Simple 8ksps 440 Hz sin wave ::
41+ //| Playing 8ksps 440 Hz and 880 Hz sine waves ::
3242//|
43+ //| import analogbufio
44+ //| import array
3345//| import audiocore
34- //| import audioio
46+ //| import audiopwmio
3547//| import board
36- //| import array
37- //| import time
3848//| import math
49+ //| import time
3950//|
40- //| # Generate one period of sine wav .
51+ //| # Generate one period of sine wave .
4152//| length = 8000 // 440
4253//| sine_wave = array.array("h", [0] * length)
4354//| for i in range(length):
4455//| sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15))
56+ //| pwm = audiopwmio.PWMAudioOut(left_channel=board.D12, right_channel=board.D13)
4557//|
46- //| dac = audioio.AudioOut(board.SPEAKER)
47- //| sine_wave = audiocore.RawSample(sine_wave)
48- //| dac.play(sine_wave, loop=True)
58+ //| # Play single-buffered
59+ //| sample = audiocore.RawSample(sine_wave)
60+ //| pwm.play(sample, loop=True)
61+ //| time.sleep(3)
62+ //| # changing the wave has no effect
63+ //| for i in range(length):
64+ //| sine_wave[i] = int(math.sin(math.pi * 4 * i / length) * (2 ** 15))
65+ //| time.sleep(3)
66+ //| pwm.stop()
4967//| time.sleep(1)
50- //| dac.stop()"""
68+ //|
69+ //| # Play double-buffered
70+ //| sample = audiocore.RawSample(sine_wave, single_buffer=False)
71+ //| pwm.play(sample, loop=True)
72+ //| time.sleep(3)
73+ //| # changing the wave takes effect almost immediately
74+ //| for i in range(length):
75+ //| sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15))
76+ //| time.sleep(3)
77+ //| pwm.stop()
78+ //| pwm.deinit()"""
5179//| ...
5280static mp_obj_t audioio_rawsample_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * all_args ) {
53- enum { ARG_buffer , ARG_channel_count , ARG_sample_rate };
81+ enum { ARG_buffer , ARG_channel_count , ARG_sample_rate , ARG_single_buffer };
5482 static const mp_arg_t allowed_args [] = {
5583 { MP_QSTR_buffer , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
5684 { MP_QSTR_channel_count , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 1 } },
5785 { MP_QSTR_sample_rate , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 8000 } },
86+ { MP_QSTR_single_buffer , MP_ARG_BOOL | MP_ARG_KW_ONLY , {.u_bool = true} },
5887 };
5988 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
6089 mp_arg_parse_all_kw_array (n_args , n_kw , all_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
@@ -69,9 +98,12 @@ static mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a
6998 } else if (bufinfo .typecode != 'b' && bufinfo .typecode != 'B' && bufinfo .typecode != BYTEARRAY_TYPECODE ) {
7099 mp_raise_ValueError_varg (MP_ERROR_TEXT ("%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" ), MP_QSTR_buffer );
71100 }
101+ if (!args [ARG_single_buffer ].u_bool && bufinfo .len % (bytes_per_sample * args [ARG_channel_count ].u_int * 2 ) != 0 ) {
102+ mp_raise_ValueError_varg (MP_ERROR_TEXT ("Length of %q must be an even multiple of channel_count * type_size" ), MP_QSTR_buffer );
103+ }
72104 common_hal_audioio_rawsample_construct (self , ((uint8_t * )bufinfo .buf ), bufinfo .len ,
73105 bytes_per_sample , signed_samples , args [ARG_channel_count ].u_int ,
74- args [ARG_sample_rate ].u_int );
106+ args [ARG_sample_rate ].u_int , args [ ARG_single_buffer ]. u_bool );
75107
76108 return MP_OBJ_FROM_PTR (self );
77109}
0 commit comments