6
6
This module allows you play sounds with the micro:bit.
7
7
8
8
By default sound output will be via the edge connector on pin 0 and the
9
- :doc: `built-in speaker <speaker >` **V2 **. You can connect wired headphones or
9
+ :doc: `built-in speaker <speaker >` ( **V2 **) . You can connect wired headphones or
10
10
a speaker to pin 0 and GND on the edge connector to hear the sounds.
11
11
12
12
The ``audio `` module can be imported as ``import audio `` or accessed via
13
13
the ``microbit `` module as ``microbit.audio ``.
14
14
15
+ There are three different kinds of audio sources that can be played using the
16
+ :py:meth: `audio.play ` function:
17
+
18
+ 1. `Built in sounds <#built-in-sounds-v2 >`_ (**V2 **),
19
+ e.g. ``audio.play(Sound.HAPPY) ``
20
+ 2. `Sound Effects <#sound-effects-v2 >`_ (**V2 **), a way to create custom sounds
21
+ by configuring its parameters::
22
+
23
+ my_effect = audio.Effect(freq_start=400, freq_end=2500, duration=500)
24
+ audio.play(my_effect)
25
+
26
+ 3. `Audio Frames <##audioframe >`_, an iterable (like a list or a generator)
27
+ of Audio Frames, which are lists of 32 samples with values from 0 to 255::
28
+
29
+ square_wave = audio.AudioFrame()
30
+ for i in range(16):
31
+ square_wave[i] = 0
32
+ square_wave[i + 16] = 255
33
+ audio.play([square_wave] * 64)
34
+
35
+
15
36
Functions
16
37
=========
17
38
18
39
.. py :function :: play(source, wait = True , pin = pin0, return_pin = None )
19
40
20
- Play the source to completion.
41
+ Play the audio source to completion.
21
42
22
- :param source: ``Sound ``: The ``microbit `` module contains a list of
23
- built-in sounds that your can pass to ``audio.play() ``.
43
+ :param source: There are three types of data that can be used as a source:
44
+
45
+ - ``Sound ``: The ``microbit `` module contains a list of
46
+ built-in sounds, e.g. ``audio.play(Sound.TWINKLE) ``. A full list can
47
+ be found in the `Built in sounds <#built-in-sounds-v2 >`_ section.
48
+ - ``Effect ``: A sound effect, or an iterable of sound effects, created
49
+ via the :py:meth: `audio.Effect ` class
50
+ - ``AudioFrame ``: An iterable of ``AudioFrame `` instances as described
51
+ in the `AudioFrame Technical Details <#id2 >`_ section
24
52
25
- ``AudioFrame ``: The source agrument can also be an iterable
26
- of ``AudioFrame `` elements as described below.
27
53
:param wait: If ``wait `` is ``True ``, this function will block until the
28
54
source is exhausted.
55
+
29
56
:param pin: An optional argument to specify the output pin can be used to
30
57
override the default of ``pin0 ``. If we do not want any sound to play
31
58
we can use ``pin=None ``.
59
+
32
60
:param return_pin: specifies a differential edge connector pin to connect
33
61
to an external speaker instead of ground. This is ignored for the **V2 **
34
62
revision.
@@ -41,34 +69,9 @@ Functions
41
69
42
70
Stops all audio playback.
43
71
44
- Classes
45
- =======
46
-
47
- .. py :class ::
48
- AudioFrame
49
-
50
- An ``AudioFrame `` object is a list of 32 samples each of which is an unsigned byte
51
- (whole number between 0 and 255).
52
-
53
- It takes just over 4 ms to play a single frame.
54
-
55
- .. py :function :: copyfrom(other)
56
-
57
- Overwrite the data in this ``AudioFrame `` with the data from another
58
- ``AudioFrame `` instance.
59
-
60
- :param other: ``AudioFrame `` instance from which to copy the data.
61
-
62
-
63
- Using audio
64
- ===========
65
-
66
- You will need a sound source, as input to the ``play `` function. You can use
67
- the built-in sounds **V2 ** from the ``microbit `` module, ``microbit.Sound ``, or
68
- generate your own, like in ``examples/waveforms.py ``.
69
72
70
73
Built-in sounds **V2 **
71
- ----------------------
74
+ ======================
72
75
73
76
The built-in sounds can be called using ``audio.play(Sound.NAME) ``.
74
77
@@ -83,8 +86,213 @@ The built-in sounds can be called using ``audio.play(Sound.NAME)``.
83
86
* ``Sound.TWINKLE ``
84
87
* ``Sound.YAWN ``
85
88
89
+ Sounds Example
90
+ --------------
91
+
92
+ ::
93
+
94
+ from microbit import *
95
+
96
+ while True:
97
+ if button_a.is_pressed() and button_b.is_pressed():
98
+ # When pressing both buttons only play via the edge connector
99
+ audio.play(Sound.HELLO, pin=pin0)
100
+ elif button_a.is_pressed():
101
+ # On button A play a sound and when it's done show an image
102
+ audio.play(Sound.HAPPY)
103
+ display.show(Image.HAPPY)
104
+ elif button_b.is_pressed():
105
+ # On button B play a sound and show an image at the same time
106
+ audio.play(Sound.TWINKLE, wait=False)
107
+ display.show(Image.BUTTERFLY)
108
+
109
+ sleep(500)
110
+ display.clear()
111
+
112
+
113
+ Sound Effects **V2 **
114
+ ====================
115
+
116
+ .. py :class ::
117
+ Effect(preset, freq_start=400, freq_end=200, duration=500, vol_start=100, vol_end=255, wave=WAVE_SQUARE, fx=None, interpolation=INTER_LINEAR)
118
+
119
+ An ``Effect `` instance represents a sound effect, composed by a set of
120
+ parameters configured via the constructor or instance attributes.
121
+
122
+ All the parameters are optional, with default values as shown above, and
123
+ they can all be modified via attributes of the same name. For example, we
124
+ can first create an effect ``my_effect = Effect(duration=1000) ``, and then
125
+ change its attributes ``my_effect.duration = 500 ``.
126
+
127
+ :param preset: Existing Effect instance to use as a base.
128
+ :param freq_start: Start Frequency in Hertz (Hz), eg: ``400 ``
129
+ :param freq_end: End Frequency in Hertz (Hz), eg: ``2000 ``
130
+ :param duration: Duration of the sound (ms), eg: ``500 ``
131
+ :param vol_start: Start volume value, range 0-255, eg: ``120 ``
132
+ :param vol_end: End volume value, range 0-255, eg: ``255 ``
133
+ :param wave: Type of wave shape, one of these values: ``WAVE_SINE ``,
134
+ ``WAVE_SAWTOOTH ``, ``WAVE_TRIANGLE ``, ``WAVE_SQUARE ``,
135
+ ``WAVE_NOISE `` (randomly generated noise).
136
+ :param fx: Effect to add on the sound, one of the following values:
137
+ ``FX_TREMOLO ``, ``FX_VIBRATO ``, ``FX_WARBLE ``, or ``None ``.
138
+ :param interpolation: The type of curve between the start and end
139
+ frequencies, different wave shapes have different rates of change
140
+ in frequency. One of the following values: ``INTER_LINEAR ``,
141
+ ``INTER_CURVE ``, ``INTER_LOG ``.
142
+
143
+ .. py :attribute :: freq_start
144
+
145
+ Start Frequency in Hertz (Hz)
146
+
147
+ .. py :attribute :: freq_end
148
+
149
+ End Frequency in Hertz (Hz)
150
+
151
+ .. py :attribute :: duration
152
+
153
+ Duration of the sound (ms), eg: ``500 ``
154
+
155
+ .. py :attribute :: vol_start
156
+
157
+ Start volume value, range 0-255, eg: ``120 ``
158
+
159
+ .. py :attribute :: vol_end
160
+
161
+ End volume value, range 0-255, eg: ``255 ``
162
+
163
+ .. py :attribute :: wave
164
+
165
+ Type of wave shape, one of these values: ``WAVE_SINE ``,
166
+ ``WAVE_SAWTOOTH ``, ``WAVE_TRIANGLE ``, ``WAVE_SQUARE ``,
167
+ ``WAVE_NOISE `` (randomly generated noise).
168
+
169
+ .. py :attribute :: fx
170
+
171
+ Effect to add on the sound, one of the following values:
172
+ ``FX_TREMOLO ``, ``FX_VIBRATO ``, ``FX_WARBLE ``, or ``None ``.
173
+
174
+ .. py :attribute :: interpolation
175
+
176
+ The type of curve between the start and end
177
+ frequencies, different wave shapes have different rates of change
178
+ in frequency. One of the following values: ``INTER_LINEAR ``,
179
+ ``INTER_CURVE ``, ``INTER_LOG ``.
180
+
181
+ The arguments used to create any Sound Effect, including the built in effects,
182
+ can be inspected by looking at each of the Effect instance attributes, or by
183
+ converting the instance into a string (which can be done via ``str() ``
184
+ function, or by using a function that does the conversion automatically like
185
+ ``print() ``).
186
+
187
+ For example, with the :doc: `REPL </devguide/repl >` you can inspect the built
188
+ in Effects::
189
+
190
+ >>> audio.Effect.CROAK
191
+ Effect(freq_start=..., freq_end=..., duration=..., vol_start=..., vol_end=..., wave=..., fx=..., interpolation=...)
192
+
193
+ The built in Effects are immutable, so they cannot be changed. Trying to modify
194
+ a built in Effect will throw an exception::
195
+
196
+ >>> audio.Effect.CLICK.duration = 1000
197
+ Traceback (most recent call last):
198
+ File "<stdin>", line 1, in <module>
199
+ TypeError: effect cannot be modified
200
+
201
+ But a new one can be created cloning the data::
202
+
203
+ >>> click_clone = Effect(audio.Effect.CLICK)
204
+ >>> click_clone.duration = 1000
205
+ >>>
206
+
207
+ Built in Sound Effects
208
+ ----------------------
209
+
210
+ Some pre-created Sound Effects are already available as examples. These can
211
+ be played directly ``audio.play(audio.Effect.SQUEAK) ``, or used as a base to
212
+ create new effects ``audio.Effect(audio.Effect.SQUEAK, duration=2000) ``.
213
+
214
+ * ``audio.Effect.SQUEAK ``
215
+ * ``audio.Effect.WARBLE ``
216
+ * ``audio.Effect.CHIRP ``
217
+ * ``audio.Effect.CROAK ``
218
+ * ``audio.Effect.CLICK ``
219
+
220
+ Sound Effects Example
221
+ ---------------------
222
+
223
+ ::
224
+
225
+ from microbit import *
226
+
227
+ # Play a built in Sound Effect
228
+ audio.play(audio.Effect.CHIRP)
229
+
230
+ # Create an immediately play a Sound Effect exercising all options
231
+ audio.play(Effect(
232
+ freq_start=400,
233
+ freq_end=2000,
234
+ duration=500,
235
+ vol_start=100,
236
+ vol_end=255,
237
+ wave=audio.WAVE_TRIANGLE,
238
+ fx=audio.FX_VIBRATO,
239
+ interpolation=audio.LOG
240
+ ))
241
+
242
+ # Play a Sound Effect instance, modify an attribute, and play it again
243
+ my_effect = Effect(
244
+ preset=audio.CHIRP
245
+ freq_start=400,
246
+ freq_end=2000,
247
+ )
248
+ audio.play(my_effect)
249
+ my_effect.duration = 1000
250
+ audio.play(my_effect)
251
+
252
+ # You can also create a new effect based on an existing one, and modify
253
+ # any of the options
254
+ audio.play(audio.Effect.WARBLE)
255
+ my_modified_effect = Effect(audio.Effect.WARBLE, duration=1000)
256
+ audio.play(my_modified_effect)
257
+
258
+ # Use sensor data to modify and play the existing Sound Effect instance
259
+ while True:
260
+ my_effect.freq_start=accelerometer.get_x()
261
+ my_effect.freq_end=accelerometer.get_y()
262
+ audio.play(my_effect)
263
+
264
+ if button_a.is_pressed():
265
+ # On button A play an effect and once it's done show an image
266
+ audio.play(audio.Effect.CHIRP)
267
+ display.show(Image.DUCK)
268
+ sleep(500)
269
+ elif button_b.is_pressed():
270
+ # On button B play an effect while showing an image
271
+ audio.play(audio.Effect.CLICK, wait=False)
272
+ display.show(Image.SQUARE)
273
+ sleep(500)
274
+
275
+
276
+ AudioFrame
277
+ ==========
278
+
279
+ .. py :class ::
280
+ AudioFrame
281
+
282
+ An ``AudioFrame `` object is a list of 32 samples each of which is an unsigned byte
283
+ (whole number between 0 and 255).
284
+
285
+ It takes just over 4 ms to play a single frame.
286
+
287
+ .. py :function :: copyfrom(other)
288
+
289
+ Overwrite the data in this ``AudioFrame `` with the data from another
290
+ ``AudioFrame `` instance.
291
+
292
+ :param other: ``AudioFrame `` instance from which to copy the data.
293
+
86
294
Technical Details
87
- =================
295
+ -----------------
88
296
89
297
.. note ::
90
298
You don't need to understand this section to use the ``audio `` module.
@@ -104,11 +312,11 @@ samples. When reading reaches the start or the mid-point of the buffer, it
104
312
triggers a callback to fetch the next ``AudioFrame `` which is then copied into
105
313
the buffer. This means that a sound source has under 4ms to compute the next
106
314
``AudioFrame ``, and for reliable operation needs to take less 2ms (which is
107
- 32000 cycles, so should be plenty).
315
+ 32k cycles in micro:bit V1 or 128k in V2 , so should be plenty).
108
316
109
317
110
- Example
111
- =======
318
+ AudioFrame Example
319
+ ------------------
112
320
113
321
.. include :: ../examples/waveforms.py
114
322
:code: python
0 commit comments