Skip to content

Commit 6316624

Browse files
docs: update Recording & Playback on review + tweaks to descriptions.
1 parent d37bfa0 commit 6316624

File tree

3 files changed

+68
-35
lines changed

3 files changed

+68
-35
lines changed

docs/audio.rst

+65-32
Original file line numberDiff line numberDiff line change
@@ -248,30 +248,34 @@ Sound Effects Example
248248
AudioRecording & AudioTrack **V2**
249249
==================================
250250

251-
There are two classes that can contain (or point to) audio data
252-
and an associated sampling rate:
253-
254-
- ``AudioRecording`` contains its own buffer, it's initialised with a size
255-
defined in time, and it's the object type that ``microphone.record()``
256-
returns.
257-
- ``AudioTrack`` does not hold its own buffer and instead points to a buffer
258-
externally created. This buffer could be an ``AudioRecording``, or a basic
259-
type like a ``bytearray``. It's similar to a
251+
To record and play back audio, we need a way to store the audio data and
252+
the sampling rate that has been used to record it and play it back.
253+
254+
Two new classes are introduced in micro:bit V2 for this purpose:
255+
256+
- The ``AudioRecording`` class holds its own audio data and sampling rate.
257+
It is initialised with a size defined in units of time, and it's the object
258+
type that the ``microphone.record()`` function returns.
259+
- The ``AudioTrack`` class contains its sampling rate, but does not hold its
260+
own data. It instead points to a buffer externally created,
261+
like an ``AudioRecording``, or a basic type like a ``bytearray``.
262+
It's similar to a
260263
`memoryview <https://docs.micropython.org/en/v1.9.3/pyboard/reference/speed_python.html#arrays>`_
261-
and it can be used to easily chop a portion of the audio data in the
262-
``AudioRecording`` or to modify its contents.
264+
and it can be used to easily modify the audio data or chop into portions
265+
of different sizes.
263266

264267
AudioRecording
265268
--------------
266269

267270
.. py:class::
268-
AudioRecording(duration, rate=7812)
271+
AudioRecording(duration, rate=11_000)
269272

270273
The ``AudioRecording`` object contains audio data and the sampling rate
271274
associated to it.
272275

273276
The size of the internal buffer will depend on the ``rate``
274277
(number of samples per second) and ``duration`` parameters.
278+
The larger these values are, the more memory that will be used.
275279

276280
:param duration: Indicates how many milliseconds of audio this
277281
instance can store.
@@ -306,32 +310,36 @@ AudioRecording
306310
If the default value of ``-1`` is provided it will end the track
307311
at the end of the AudioRecording.
308312

309-
When an AudioRecording is used to record data from the microphone,
310-
increasing the sampling rate increases the sound quality,
311-
but it also increases the amount of memory used.
313+
When an ``AudioRecording`` is used to record data from the microphone,
314+
a higher sampling rate produces better sound quality,
315+
but it also uses more memory.
312316

313317
During playback, increasing the sampling rate speeds up the sound
314318
and decreasing the sample rate slows it down.
315319

320+
The data inside an ``AudioRecording`` is not easy to modify, so the
321+
``AudioTrack`` class is provided to help access the audio data like a list.
322+
The method ``AudioRecording.track()`` can be used to create an ``AudioTrack``,
323+
and its arguments ``start_ms`` and ``end_ms`` can be used to slice portions
324+
of the data.
325+
316326
AudioTrack
317327
----------
318328

319-
An ``AudioTrack`` can be created from an ``AudioRecording`` or ``bytearray``
320-
and individual bytes can be accessed and modified like elements in a list.
321-
322-
This class is useful to modify the audio data in an ``AudioRecording`` or
323-
to create precisely sized audio data buffers for sending and receiving them
324-
via communication protocols like radio or serial.
325-
326329
.. py:class::
327-
AudioTrack(buffer, rate=7812)
330+
AudioTrack(buffer, rate=None)
328331

329332
The ``AudioTrack`` object points to the data provided by the input buffer,
330-
which can be an ``AudioRecording``, or a buffer-like object like a
331-
``bytearray``.
332-
It also contains its own sampling rate, so multiple ``AudioTrack``
333-
instances pointing to the same buffer can have different rates and won't
334-
affect the rate of the original buffer.
333+
which can be an ``AudioRecording``, another ``AudioTrack``,
334+
or a buffer-like object like a ``bytearray``.
335+
336+
When the input buffer has an associated rate (e.g. an ``AudioRecording``
337+
or ``AudioTrack``), the rate is copied. If the buffer object does not have
338+
a rate, the default value of 11_000 is used.
339+
340+
Changes to an ``AudioTrack`` rate won't affect the original source rate,
341+
so multiple instances pointing to the same buffer can have different
342+
rates and the original buffer rate would stay unmodified.
335343

336344
:param buffer: The buffer containing the audio data.
337345
:param rate: The sampling rate at which data will be stored
@@ -346,19 +354,44 @@ via communication protocols like radio or serial.
346354

347355
.. py:function:: get_rate()
348356
349-
Return the configured sampling rate for this
350-
``AudioTrack`` instance.
357+
Return the configured sampling rate for this ``AudioTrack`` instance.
351358

352359
:return: The configured sample rate.
353360

354361
.. py:function:: copyfrom(other)
355362
356363
Overwrite the data in this ``AudioTrack`` with the data from another
357-
``AudioTrack``, ``AudioRecording`` or buffer-like object like
358-
a ``bytes`` or ``bytearray`` instance.
364+
``AudioTrack``, ``AudioRecording``, or buffer-like object like
365+
a ``bytearray`` instance.
366+
367+
If the input buffer is smaller than the available space in this
368+
instance, the rest of the data is left untouched.
369+
If it is larger, it will stop copying once this instance is filled.
359370

360371
:param other: Buffer-like instance from which to copy the data.
361372

373+
An ``AudioTrack`` can be created from an ``AudioRecording``, another
374+
``AudioTrack``, or a ``bytearray`` and individual bytes can be accessed and
375+
modified like elements in a list::
376+
377+
my_track = AudioTrack(bytearray(100))
378+
# Create a square wave
379+
half_length = len(my_track) // 2
380+
for i in range(half_length):
381+
my_track[i] = 255
382+
for i in range(half_length, len(my_track)):
383+
my_track[i] = 0
384+
385+
386+
Or smaller AudioTracks can be created using slices, useful to send them
387+
via radio or serial::
388+
389+
recording = microphone.record(duration=2000)
390+
track = AudioTrack(recording)
391+
packet_size = 32
392+
for i in range(0, len(track), packet_size):
393+
radio.send_bytes(track[i:i+packet_size])
394+
362395
Example
363396
-------
364397

docs/microbit_micropython_api.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ The Microphone is accessed via the `microphone` object::
109109
# Returns a representation of the sound pressure level in the range 0 to 255.
110110
sound_level()
111111
# Record audio into a new `AudioRecording`
112-
recording = record(duration, rate=7812)
112+
recording = record(duration, rate=11_000)
113113
# Record audio into an existing `AudioRecording`
114-
record_into(recording, rate=7812)
114+
record_into(recording, wait=True)
115115
# Returns `True` if the microphone is currently recording audio
116116
is_recording()
117117
# Stop any active audio recording

docs/microphone.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Functions
141141

142142
:return: A representation of the sound pressure level in the range 0 to 255.
143143

144-
.. py:function:: record(duration, rate=7812)
144+
.. py:function:: record(duration, rate=11000)
145145
146146
Record sound into an ``AudioRecording`` for the amount of time indicated by
147147
``duration`` at the sampling rate indicated by ``rate``.

0 commit comments

Comments
 (0)