Skip to content

Commit ed58ade

Browse files
authored
Merge pull request #10635 from relic-se/audio-chaining
Allow for audio chaining by returning `self` object from audio effects and audio mixer
2 parents 2317aec + 7342090 commit ed58ade

File tree

9 files changed

+63
-27
lines changed

9 files changed

+63
-27
lines changed

shared-bindings/audiodelays/Chorus.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_get_playing_obj, audiodelays_chorus
206206
MP_PROPERTY_GETTER(audiodelays_chorus_playing_obj,
207207
(mp_obj_t)&audiodelays_chorus_get_playing_obj);
208208

209-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
209+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Chorus:
210210
//| """Plays the sample once when loop=False and continuously when loop=True.
211211
//| Does not block. Use `playing` to block.
212212
//|
213-
//| The sample must match the encoding settings given in the constructor."""
213+
//| The sample must match the encoding settings given in the constructor.
214+
//|
215+
//| :return: The effect object itself. Can be used for chaining, ie:
216+
//| ``audio.play(effect.play(sample))``.
217+
//| :rtype: Chorus"""
214218
//| ...
215219
//|
216220
static mp_obj_t audiodelays_chorus_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -228,7 +232,7 @@ static mp_obj_t audiodelays_chorus_obj_play(size_t n_args, const mp_obj_t *pos_a
228232
mp_obj_t sample = args[ARG_sample].u_obj;
229233
common_hal_audiodelays_chorus_play(self, sample, args[ARG_loop].u_bool);
230234

231-
return mp_const_none;
235+
return MP_OBJ_FROM_PTR(self);
232236
}
233237
MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_chorus_play_obj, 1, audiodelays_chorus_obj_play);
234238

shared-bindings/audiodelays/Echo.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_playing_obj, audiodelays_echo_obj
230230
MP_PROPERTY_GETTER(audiodelays_echo_playing_obj,
231231
(mp_obj_t)&audiodelays_echo_get_playing_obj);
232232

233-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
233+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Echo:
234234
//| """Plays the sample once when loop=False and continuously when loop=True.
235235
//| Does not block. Use `playing` to block.
236236
//|
237-
//| The sample must match the encoding settings given in the constructor."""
237+
//| The sample must match the encoding settings given in the constructor.
238+
//|
239+
//| :return: The effect object itself. Can be used for chaining, ie:
240+
//| ``audio.play(effect.play(sample))``.
241+
//| :rtype: Echo"""
238242
//| ...
239243
//|
240244
static mp_obj_t audiodelays_echo_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -252,7 +256,7 @@ static mp_obj_t audiodelays_echo_obj_play(size_t n_args, const mp_obj_t *pos_arg
252256
mp_obj_t sample = args[ARG_sample].u_obj;
253257
common_hal_audiodelays_echo_play(self, sample, args[ARG_loop].u_bool);
254258

255-
return mp_const_none;
259+
return MP_OBJ_FROM_PTR(self);
256260
}
257261
MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_echo_play_obj, 1, audiodelays_echo_obj_play);
258262

shared-bindings/audiodelays/MultiTapDelay.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_playing_obj, audiodela
233233
MP_PROPERTY_GETTER(audiodelays_multi_tap_delay_playing_obj,
234234
(mp_obj_t)&audiodelays_multi_tap_delay_get_playing_obj);
235235

236-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
236+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> MultiTapDelay:
237237
//| """Plays the sample once when loop=False and continuously when loop=True.
238238
//| Does not block. Use `playing` to block.
239239
//|
240-
//| The sample must match the encoding settings given in the constructor."""
240+
//| The sample must match the encoding settings given in the constructor.
241+
//|
242+
//| :return: The effect object itself. Can be used for chaining, ie:
243+
//| ``audio.play(effect.play(sample))``.
244+
//| :rtype: MultiTapDelay"""
241245
//| ...
242246
//|
243247
static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -255,7 +259,7 @@ static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj
255259
mp_obj_t sample = args[ARG_sample].u_obj;
256260
common_hal_audiodelays_multi_tap_delay_play(self, sample, args[ARG_loop].u_bool);
257261

258-
return mp_const_none;
262+
return MP_OBJ_FROM_PTR(self);
259263
}
260264
MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_multi_tap_delay_play_obj, 1, audiodelays_multi_tap_delay_obj_play);
261265

shared-bindings/audiodelays/PitchShift.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,15 @@ MP_PROPERTY_GETTER(audiodelays_pitch_shift_playing_obj,
190190
(mp_obj_t)&audiodelays_pitch_shift_get_playing_obj);
191191

192192

193-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
193+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> PitchShift:
194194
//| """Plays the sample once when loop=False and continuously when loop=True.
195195
//| Does not block. Use `playing` to block.
196196
//|
197-
//| The sample must match the encoding settings given in the constructor."""
197+
//| The sample must match the encoding settings given in the constructor.
198+
//|
199+
//| :return: The effect object itself. Can be used for chaining, ie:
200+
//| ``audio.play(effect.play(sample))``.
201+
//| :rtype: PitchShift"""
198202
//| ...
199203
//|
200204
static mp_obj_t audiodelays_pitch_shift_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -211,7 +215,7 @@ static mp_obj_t audiodelays_pitch_shift_obj_play(size_t n_args, const mp_obj_t *
211215
mp_obj_t sample = args[ARG_sample].u_obj;
212216
common_hal_audiodelays_pitch_shift_play(self, sample, args[ARG_loop].u_bool);
213217

214-
return mp_const_none;
218+
return MP_OBJ_FROM_PTR(self);
215219
}
216220
MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_pitch_shift_play_obj, 1, audiodelays_pitch_shift_obj_play);
217221

shared-bindings/audiofilters/Distortion.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_playing_obj, audiofilters_
309309
MP_PROPERTY_GETTER(audiofilters_distortion_playing_obj,
310310
(mp_obj_t)&audiofilters_distortion_get_playing_obj);
311311

312-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
312+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Distortion:
313313
//| """Plays the sample once when loop=False and continuously when loop=True.
314314
//| Does not block. Use `playing` to block.
315315
//|
316-
//| The sample must match the encoding settings given in the constructor."""
316+
//| The sample must match the encoding settings given in the constructor.
317+
//|
318+
//| :return: The effect object itself. Can be used for chaining, ie:
319+
//| ``audio.play(effect.play(sample))``.
320+
//| :rtype: Distortion"""
317321
//| ...
318322
//|
319323
static mp_obj_t audiofilters_distortion_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -331,7 +335,7 @@ static mp_obj_t audiofilters_distortion_obj_play(size_t n_args, const mp_obj_t *
331335
mp_obj_t sample = args[ARG_sample].u_obj;
332336
common_hal_audiofilters_distortion_play(self, sample, args[ARG_loop].u_bool);
333337

334-
return mp_const_none;
338+
return MP_OBJ_FROM_PTR(self);
335339
}
336340
MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_distortion_play_obj, 1, audiofilters_distortion_obj_play);
337341

shared-bindings/audiofilters/Filter.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_get_playing_obj, audiofilters_filt
179179
MP_PROPERTY_GETTER(audiofilters_filter_playing_obj,
180180
(mp_obj_t)&audiofilters_filter_get_playing_obj);
181181

182-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
182+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Filter:
183183
//| """Plays the sample once when loop=False and continuously when loop=True.
184184
//| Does not block. Use `playing` to block.
185185
//|
186-
//| The sample must match the encoding settings given in the constructor."""
186+
//| The sample must match the encoding settings given in the constructor.
187+
//|
188+
//| :return: The effect object itself. Can be used for chaining, ie:
189+
//| ``audio.play(effect.play(sample))``.
190+
//| :rtype: Filter"""
187191
//| ...
188192
//|
189193
static mp_obj_t audiofilters_filter_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -201,7 +205,7 @@ static mp_obj_t audiofilters_filter_obj_play(size_t n_args, const mp_obj_t *pos_
201205
mp_obj_t sample = args[ARG_sample].u_obj;
202206
common_hal_audiofilters_filter_play(self, sample, args[ARG_loop].u_bool);
203207

204-
return mp_const_none;
208+
return MP_OBJ_FROM_PTR(self);
205209
}
206210
MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_filter_play_obj, 1, audiofilters_filter_obj_play);
207211

shared-bindings/audiofilters/Phaser.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_playing_obj, audiofilters_phas
214214
MP_PROPERTY_GETTER(audiofilters_phaser_playing_obj,
215215
(mp_obj_t)&audiofilters_phaser_get_playing_obj);
216216

217-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
217+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Phaser:
218218
//| """Plays the sample once when loop=False and continuously when loop=True.
219219
//| Does not block. Use `playing` to block.
220220
//|
221-
//| The sample must match the encoding settings given in the constructor."""
221+
//| The sample must match the encoding settings given in the constructor.
222+
//|
223+
//| :return: The effect object itself. Can be used for chaining, ie:
224+
//| ``audio.play(effect.play(sample))``.
225+
//| :rtype: Phaser"""
222226
//| ...
223227
//|
224228
static mp_obj_t audiofilters_phaser_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -236,7 +240,7 @@ static mp_obj_t audiofilters_phaser_obj_play(size_t n_args, const mp_obj_t *pos_
236240
mp_obj_t sample = args[ARG_sample].u_obj;
237241
common_hal_audiofilters_phaser_play(self, sample, args[ARG_loop].u_bool);
238242

239-
return mp_const_none;
243+
return MP_OBJ_FROM_PTR(self);
240244
}
241245
MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_phaser_play_obj, 1, audiofilters_phaser_obj_play);
242246

shared-bindings/audiofreeverb/Freeverb.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_playing_obj, audiofreeverb_
196196
MP_PROPERTY_GETTER(audiofreeverb_freeverb_playing_obj,
197197
(mp_obj_t)&audiofreeverb_freeverb_get_playing_obj);
198198

199-
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
199+
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Freeverb:
200200
//| """Plays the sample once when loop=False and continuously when loop=True.
201201
//| Does not block. Use `playing` to block.
202202
//|
203-
//| The sample must match the encoding settings given in the constructor."""
203+
//| The sample must match the encoding settings given in the constructor.
204+
//|
205+
//| :return: The effect object itself. Can be used for chaining, ie:
206+
//| ``audio.play(effect.play(sample))``.
207+
//| :rtype: Freeverb"""
204208
//| ...
205209
//|
206210
static mp_obj_t audiofreeverb_freeverb_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -218,7 +222,7 @@ static mp_obj_t audiofreeverb_freeverb_obj_play(size_t n_args, const mp_obj_t *p
218222
mp_obj_t sample = args[ARG_sample].u_obj;
219223
common_hal_audiofreeverb_freeverb_play(self, sample, args[ARG_loop].u_bool);
220224

221-
return mp_const_none;
225+
return MP_OBJ_FROM_PTR(self);
222226
}
223227
MP_DEFINE_CONST_FUN_OBJ_KW(audiofreeverb_freeverb_play_obj, 1, audiofreeverb_freeverb_obj_play);
224228

shared-bindings/audiomixer/Mixer.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,17 @@ MP_PROPERTY_GETTER(audiomixer_mixer_voice_obj,
160160

161161
//| def play(
162162
//| self, sample: circuitpython_typing.AudioSample, *, voice: int = 0, loop: bool = False
163-
//| ) -> None:
163+
//| ) -> Mixer:
164164
//| """Plays the sample once when loop=False and continuously when loop=True.
165165
//| Does not block. Use `playing` to block.
166166
//|
167167
//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer` or `audiomp3.MP3Decoder`.
168168
//|
169-
//| The sample must match the Mixer's encoding settings given in the constructor."""
169+
//| The sample must match the Mixer's encoding settings given in the constructor.
170+
//|
171+
//| :return: The mixer object itself. Can be used for chaining, ie:
172+
//| ``audio.play(mixer.play(sample))``.
173+
//| :rtype: Chorus"""
170174
//| ...
171175
//|
172176
static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -189,7 +193,7 @@ static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_arg
189193
mp_obj_t sample = args[ARG_sample].u_obj;
190194
common_hal_audiomixer_mixervoice_play(voice, sample, args[ARG_loop].u_bool);
191195

192-
return mp_const_none;
196+
return MP_OBJ_FROM_PTR(self);
193197
}
194198
MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play);
195199

0 commit comments

Comments
 (0)