@@ -24,7 +24,22 @@ There are three different kinds of audio sources that can be played using the
24
24
my_effect = audio.SoundEffect(freq_start=400, freq_end=2500, duration=500)
25
25
audio.play(my_effect)
26
26
27
- 3. `Audio Frames <#audioframe >`_, an instance or an iterable (like a list or
27
+ 3. `Audio Recordings <#audiorecording-audiotrack-v2 >`_, an object that can
28
+ be used to record audio from the microphone::
29
+
30
+ recording = audio.AudioRecording(duration=4000)
31
+ microphone.record_into(recording)
32
+ audio.play(recording)
33
+
34
+ 4. `Audio Tracks <#audiorecording-audiotrack-v2 >`_, a way to point to a portion
35
+ of the data in an ``AudioRecording `` or a ``bytearray `` and/or modify it::
36
+
37
+ recording = audio.AudioRecording(duration=4000)
38
+ microphone.record(recording)
39
+ track = AudioTrack(recording)[1000:3000]
40
+ audio.play(track)
41
+
42
+ 5. `Audio Frames <#audioframe >`_, an instance or an iterable (like a list or
28
43
generator) of Audio Frames, which are lists of samples with values
29
44
from 0 to 255::
30
45
@@ -49,6 +64,10 @@ Functions
49
64
be found in the `Built in sounds <#built-in-sounds-v2 >`_ section.
50
65
- ``SoundEffect ``: A sound effect, or an iterable of sound effects,
51
66
created via the :py:meth: `audio.SoundEffect ` class
67
+ - ``AudioRecording ``: An instance of ``AudioRecording `` as described
68
+ in the `AudioRecording <#audiorecording-audiotrack-v2 >`_ section
69
+ - ``AudioTrack ``: An instance of ``AudioTrack `` as described in the
70
+ `AudioTrack <#audiorecording-audiotrack-v2 >`_ section
52
71
- ``AudioFrame ``: An instance or an iterable of ``AudioFrame ``
53
72
instances as described in the
54
73
`AudioFrame Technical Details <#technical-details >`_ section
@@ -226,47 +245,163 @@ Sound Effects Example
226
245
:code: python
227
246
228
247
229
- AudioFrame
230
- ==========
248
+ AudioRecording & AudioTrack ** V2 **
249
+ ==================================
231
250
232
- .. py : class ::
233
- AudioFrame(duration=-1, rate=7812)
251
+ There are two classes that can contain (or point to) audio data
252
+ and an associated sampling rate:
234
253
235
- An ``AudioFrame `` object is a list of samples, each of which is an unsigned
236
- byte (whole number between 0 and 255).
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
260
+ `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.
237
263
238
- The number of samples in an AudioFrame will depend on the
239
- ``rate `` (number of samples per second) and ``duration `` parameters.
240
- The total number of samples will always be a round up multiple of 32.
264
+ AudioRecording
265
+ --------------
241
266
242
- On micro:bit V1 the constructor does not take any arguments,
243
- and an AudioFrame instance is always 32 bytes.
267
+ .. py :class ::
268
+ AudioRecording(duration, rate=7812)
269
+
270
+ The ``AudioRecording `` object contains audio data and the sampling rate
271
+ associated to it.
244
272
245
- :param duration: (**V2 **) Indicates how many milliseconds of audio this
273
+ The size of the internal buffer will depend on the ``rate ``
274
+ (number of samples per second) and ``duration `` parameters.
275
+
276
+ :param duration: Indicates how many milliseconds of audio this
246
277
instance can store.
247
- :param rate: (** V2 **) The sampling rate at which data will be stored
278
+ :param rate: The sampling rate at which data will be stored
248
279
via the microphone, or played via the ``audio.play() `` function.
249
280
250
281
.. py :function :: set_rate(sample_rate)
251
282
252
- (**V2 only **) Configure the sampling rate associated with the data
253
- in the ``AudioFrame `` instance.
283
+ Configure the sampling rate associated with the data in the
284
+ ``AudioRecording `` instance.
285
+
286
+ :param sample_rate: The sample rate to set.
287
+
288
+ .. py :function :: get_rate()
289
+
290
+ Return the configured sampling rate for this
291
+ ``AudioRecording `` instance.
292
+
293
+ :return: The configured sample rate.
294
+
295
+ .. py :function :: copy()
296
+
297
+ :returns: a copy of the ``AudioRecording ``.
298
+
299
+ .. py :function :: track(start_ms = 0 , end_ms = - 1 )
300
+
301
+ Create an `AudioTrack <#audio.AudioTrack >`_ instance from a portion of
302
+ the data in this ``AudioRecording `` instance.
303
+
304
+ :param start_ms: Where to start of the track in milliseconds.
305
+ :param end_ms: The end of the track in milliseconds.
306
+ If the default value of ``-1 `` is provided it will end the track
307
+ at the end of the AudioRecording.
308
+
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.
312
+
313
+ During playback, increasing the sampling rate speeds up the sound
314
+ and decreasing the sample rate slows it down.
315
+
316
+ AudioTrack
317
+ ----------
318
+
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
+
326
+ .. py :class ::
327
+ AudioTrack(buffer, rate=7812)
328
+
329
+ 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.
335
+
336
+ :param buffer: The buffer containing the audio data.
337
+ :param rate: The sampling rate at which data will be stored
338
+ via the microphone, or played via the ``audio.play() `` function.
254
339
255
- For recording from the microphone, increasing the sampling rate
256
- increases the sound quality, but reduces the length of audio it
257
- can store.
258
- During playback, increasing the sampling rate speeds up the sound
259
- and decreasing it slows it down.
340
+ .. py :function :: set_rate(sample_rate)
341
+
342
+ Configure the sampling rate associated with the data in the
343
+ ``AudioTrack `` instance.
260
344
261
345
:param sample_rate: The sample rate to set.
262
346
263
347
.. py :function :: get_rate()
264
348
265
- (** V2 only **) Return the configured sampling rate for this
266
- ``AudioFrame `` instance.
349
+ Return the configured sampling rate for this
350
+ ``AudioTrack `` instance.
267
351
268
352
:return: The configured sample rate.
269
353
354
+ .. py :function :: copyfrom(other)
355
+
356
+ 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.
359
+
360
+ :param other: Buffer-like instance from which to copy the data.
361
+
362
+ Example
363
+ -------
364
+
365
+ ::
366
+
367
+ from microbit import *
368
+
369
+ # An AudioRecording holds the audio data
370
+ recording = audio.AudioRecording(duration=4000)
371
+
372
+ # AudioTracks point to a portion of the data in the AudioRecording
373
+ # We can obtain the an AudioTrack from the AudioRecording.track() method
374
+ first_half = recording.track(end_ms=2000)
375
+ # Or we can create an AudioTrack from an AudioRecording and slice it
376
+ full_track = audio.AudioTrack(recording)
377
+ second_half = full_track[full_track.length() // 2:]
378
+
379
+ while True:
380
+ if button_a.is_pressed():
381
+ # We can record directly inside the AudioRecording
382
+ microphone.record(recording)
383
+ if button_b.is_pressed():
384
+ audio.play(recording, wait=False)
385
+ # The rate can be changed while playing
386
+ first_half.set_rate(
387
+ scale(accelerometer.get_x(), from_=(-1000, 1000), to=(3_000, 30_000))
388
+ )
389
+ if pin_logo.is_touched():
390
+ # We can also play the AudioTrack pointing to the AudioRecording
391
+ audio.play(first_half)
392
+
393
+
394
+ AudioFrame
395
+ ==========
396
+
397
+ .. py :class ::
398
+ AudioFrame
399
+
400
+ An ``AudioFrame `` object is a list of 32 samples each of which is an unsigned byte
401
+ (whole number between 0 and 255).
402
+
403
+ It takes just over 4 ms to play a single frame.
404
+
270
405
.. py :function :: copyfrom(other)
271
406
272
407
Overwrite the data in this ``AudioFrame `` with the data from another
@@ -281,21 +416,13 @@ Technical Details
281
416
You don't need to understand this section to use the ``audio `` module.
282
417
It is just here in case you wanted to know how it works.
283
418
284
- The ``audio.play() `` function can consume an instance or iterable
285
- (sequence, like list or tuple, or generator) of ``AudioFrame `` instances,
286
- The ``AudioFrame `` default playback rate is 7812 Hz, and can be configured
287
- at any point with the ``AudioFrame.set_rate() `` method.
288
- The ``AudioFrame.set_rate() `` also works while the ``AudioFrame `` is being
289
- played, which will affect the playback speed.
290
-
291
- Each ``AudioFrame `` instance is 32 samples by default, but it can be
292
- configured to a different size via constructor parameters.
293
-
294
- So, for example, playing 32 samples at 7812 Hz takes just over 4 milliseconds
419
+ The ``audio `` module can consumes an iterable (sequence, like list or tuple, or
420
+ generator) of ``AudioFrame `` instances, each 32 samples at 7812.5 Hz,
421
+ which take just over 4 milliseconds to play each frame
295
422
(1/7812.5 * 32 = 0.004096 = 4096 microseconds).
296
423
297
- The function ``play() `` fully copies all data from each ``AudioFrame `` before
298
- it calls ``next() `` for the next frame, so a sound source can use the same
424
+ The function ``play `` fully copies all data from each ``AudioFrame `` before it
425
+ calls ``next() `` for the next frame, so a sound source can use the same
299
426
``AudioFrame `` repeatedly.
300
427
301
428
The ``audio `` module has an internal 64 sample buffer from which it reads
0 commit comments