@@ -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,159 @@ 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
+ --------------
266
+
267
+ .. py :class ::
268
+ AudioRecording(duration, rate=7812)
269
+
270
+ The ``AudioRecording `` object contains audio data and the sampling rate
271
+ associated to it.
241
272
242
- On micro:bit V1 the constructor does not take any arguments,
243
- and an AudioFrame instance is always 32 bytes .
273
+ The size of the internal buffer will depend on the `` rate ``
274
+ (number of samples per second) and `` duration `` parameters .
244
275
245
- :param duration: (** V2 **) Indicates how many milliseconds of audio this
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 :: track(start_ms = 0 , end_ms = - 1 )
296
+
297
+ Create an `AudioTrack <#audio.AudioTrack >`_ instance from a portion of
298
+ the data in this ``AudioRecording `` instance.
299
+
300
+ :param start_ms: Where to start of the track in milliseconds.
301
+ :param end_ms: The end of the track in milliseconds.
302
+ If the default value of ``-1 `` is provided it will end the track
303
+ at the end of the AudioRecording.
304
+
305
+ When an AudioRecording is used to record data from the microphone,
306
+ increasing the sampling rate increases the sound quality,
307
+ but it also increases the amount of memory used.
308
+
309
+ During playback, increasing the sampling rate speeds up the sound
310
+ and decreasing the sample rate slows it down.
311
+
312
+ AudioTrack
313
+ ----------
314
+
315
+ An ``AudioTrack `` can be created from an ``AudioRecording `` or ``bytearray ``
316
+ and individual bytes can be accessed and modified like elements in a list.
317
+
318
+ This class is useful to modify the audio data in an ``AudioRecording `` or
319
+ to create precisely sized audio data buffers for sending and receiving them
320
+ via communication protocols like radio or serial.
321
+
322
+ .. py :class ::
323
+ AudioTrack(buffer, rate=7812)
324
+
325
+ The ``AudioTrack `` object points to the data provided by the input buffer,
326
+ which can be an ``AudioRecording ``, or a buffer-like object like a
327
+ ``bytearray ``.
328
+ It also contains its own sampling rate, so multiple ``AudioTrack ``
329
+ instances pointing to the same buffer can have different rates and won't
330
+ affect the rate of the original buffer.
254
331
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.
332
+ :param buffer: The buffer containing the audio data.
333
+ :param rate: The sampling rate at which data will be stored
334
+ via the microphone, or played via the ``audio.play() `` function.
335
+
336
+ .. py :function :: set_rate(sample_rate)
337
+
338
+ Configure the sampling rate associated with the data in the
339
+ ``AudioTrack `` instance.
260
340
261
341
:param sample_rate: The sample rate to set.
262
342
263
343
.. py :function :: get_rate()
264
344
265
- (** V2 only **) Return the configured sampling rate for this
266
- ``AudioFrame `` instance.
345
+ Return the configured sampling rate for this
346
+ ``AudioTrack `` instance.
267
347
268
348
:return: The configured sample rate.
269
349
350
+ .. py :function :: copyfrom(other)
351
+
352
+ Overwrite the data in this ``AudioTrack `` with the data from another
353
+ ``AudioTrack ``, ``AudioRecording `` or buffer-like object like
354
+ a ``bytes `` or ``bytearray `` instance.
355
+
356
+ :param other: Buffer-like instance from which to copy the data.
357
+
358
+ Example
359
+ -------
360
+
361
+ ::
362
+
363
+ from microbit import *
364
+
365
+ # An AudioRecording holds the audio data
366
+ recording = audio.AudioRecording(duration=4000)
367
+
368
+ # AudioTracks point to a portion of the data in the AudioRecording
369
+ # We can obtain the an AudioTrack from the AudioRecording.track() method
370
+ first_half = recording.track(end_ms=2000)
371
+ # Or we can create an AudioTrack from an AudioRecording and slice it
372
+ full_track = audio.AudioTrack(recording)
373
+ second_half = full_track[full_track.length() // 2:]
374
+
375
+ while True:
376
+ if button_a.is_pressed():
377
+ # We can record directly inside the AudioRecording
378
+ microphone.record(recording)
379
+ if button_b.is_pressed():
380
+ audio.play(recording, wait=False)
381
+ # The rate can be changed while playing
382
+ first_half.set_rate(
383
+ scale(accelerometer.get_x(), from_=(-1000, 1000), to=(3_000, 30_000))
384
+ )
385
+ if pin_logo.is_touched():
386
+ # We can also play the AudioTrack pointing to the AudioRecording
387
+ audio.play(first_half)
388
+
389
+
390
+ AudioFrame
391
+ ==========
392
+
393
+ .. py :class ::
394
+ AudioFrame
395
+
396
+ An ``AudioFrame `` object is a list of 32 samples each of which is an unsigned byte
397
+ (whole number between 0 and 255).
398
+
399
+ It takes just over 4 ms to play a single frame.
400
+
270
401
.. py :function :: copyfrom(other)
271
402
272
403
Overwrite the data in this ``AudioFrame `` with the data from another
@@ -281,21 +412,13 @@ Technical Details
281
412
You don't need to understand this section to use the ``audio `` module.
282
413
It is just here in case you wanted to know how it works.
283
414
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
415
+ The ``audio `` module can consumes an iterable (sequence, like list or tuple, or
416
+ generator) of ``AudioFrame `` instances, each 32 samples at 7812.5 Hz,
417
+ which take just over 4 milliseconds to play each frame
295
418
(1/7812.5 * 32 = 0.004096 = 4096 microseconds).
296
419
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
420
+ The function ``play `` fully copies all data from each ``AudioFrame `` before it
421
+ calls ``next() `` for the next frame, so a sound source can use the same
299
422
``AudioFrame `` repeatedly.
300
423
301
424
The ``audio `` module has an internal 64 sample buffer from which it reads
0 commit comments