Skip to content

codal_port: Add SoundEffect class. #106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 19, 2022
Merged

codal_port: Add SoundEffect class. #106

merged 2 commits into from
Aug 19, 2022

Conversation

dpgeorge
Copy link
Collaborator

This is an initial implementation of the SoundEffect class, per #103.

As a way to facilitate debugging/experimentation, the SoundEffect constructor can take a 72-length string as the preset value, which is interpreted as a CODAL sound expression string.

The following example will play the GIGGLE sound (string data taken directly from CODAL source):

giggle_str = "010230988019008440044008881023001601003300240000000000000000000000000000,110232570087411440044008880352005901003300010000000000000000010000000000,310232729021105440288908880091006300000000240700020000000000003000000000,310232729010205440288908880091006300000000240700020000000000003000000000,310232729011405440288908880091006300000000240700020000000000003000000000"
giggle = [audio.SoundEffect(s) for s in giggle_str.split(",")]
for g in giggle:
    print(g)
    audio.play(g)

Output:

SoundEffect(freq_start=988, freq_end=440, duration=190, vol_start=255, vol_end=255, wave=WAVE_SINE, fx=FX_VIBRATO, 8)
SoundEffect(freq_start=2570, freq_end=440, duration=874, vol_start=255, vol_end=87, wave=WAVE_SAWTOOTH, fx=FX_VIBRATO, 11)
SoundEffect(freq_start=2729, freq_end=2889, duration=211, vol_start=255, vol_end=22, wave=WAVE_SQUARE, fx=None, 5)
SoundEffect(freq_start=2729, freq_end=2889, duration=102, vol_start=255, vol_end=22, wave=WAVE_SQUARE, fx=None, 5)
SoundEffect(freq_start=2729, freq_end=2889, duration=114, vol_start=255, vol_end=22, wave=WAVE_SQUARE, fx=None, 5)

Limitations:

  • can't play an iterable of SoundEffect objects
  • if a sound effect is playing with wait=False and another one is started then the first one will be stopped immediately

@dpgeorge
Copy link
Collaborator Author

I noticed that after playing a sound expression, the micro:bit consumes about 2x the power at idle REPL.

@microbit-carlos
Copy link
Contributor

microbit-carlos commented Jul 10, 2022

Thanks Damien, this is great to start playing with SoundEffects!

I take it the WAVE_, FX_, and INTER_ are not get set as audio globals yet?
(Edit: I've just saw the comments on the docs PR, so we can discuss that there 👍 )

Also, playing the default SoundEffect() doesn't produce any sound and seems to crash or freeze:

>>> effect = audio.SoundEffect()
>>> audio.play(effect)

But changing the interpolation to a value other than log works

>>> effect = audio.SoundEffect()
>>> effect.interpolation = 1
>>> audio.play(effect)
>>> 

So it might be related to this:

We might need to update CODAL to ensure we've got the latest fixes.

I noticed that after playing a sound expression, the micro:bit consumes about 2x the power at idle REPL.

@JohnVidler any ideas about the larger power consumption?

@dpgeorge
Copy link
Collaborator Author

Also, playing the default SoundEffect() doesn't produce any sound and seems to crash or freeze:

I've now updated CODAL to v0.2.40 and this default works correctly.

@dpgeorge
Copy link
Collaborator Author

I've now updated CODAL to v0.2.40

But I just noticed that the microphone LED is permanently on now and the micro:bit draws 17mA extra compared to CODAL v0.2.35.

And after playing a sound the micro:bit draws 54mA total at an idle REPL (it used to be 20mA at the REPL).

@microbit-carlos
Copy link
Contributor

microbit-carlos commented Jul 11, 2022

I think maybe using setSilenceLevel() to setting the "silence level" to zero might have an effect in power consumption.
https://github.com/lancaster-university/codal-microbit-v2/blob/13a651754e668464855fc40a81dd7dcb796b58c9/source/Mixer2.cpp#L370
@JohnVidler do you have any suggestions or insight about the additional power consumption in the latest CODAL releases?

@JohnVidler
Copy link

Not had any cycles to investigate the power consumption yet, but my best guess would be that the audio pipline is being turned on, and left running after the initial playback, perhaps? Or that the speaker pin is being pulled strongly high/low at the end of playback rather than going back to floating when no data is present.

In either case, consider this on my radar.

@dpgeorge
Copy link
Collaborator Author

dpgeorge commented Aug 8, 2022

TODO:

  • remove preset arg to constructor
  • make constructor args position with defaults (being the default sound effect)
  • add copy method
  • make provided sound effects immutable
  • add _from_string class/static method for testing

@microbit-carlos
Copy link
Contributor

I think I'd also add that we'd like __repr__ to contain positional arguments to keep the string short, and it'd be useful to have __str__ with the keyword arguments, so that users can read the values:

>>> se = SoundEffect()
>>> se
SoundEffect(500, 2500, 500, 255, 0, 3, 0, 18)
>>> print(se)
SoundEffect(freq_start=500, freq_end=2500, duration=500, vol_start=255, vol_end=0, wave=WAVE_SQUARE, fx=None, interpolation=INTER_LOG)

@microbit-carlos
Copy link
Contributor

Quick thing I've found, setting the volume to a value n results in n-1 being set:

>>> se = audio.SoundEffect(vol_start=150)
>>> se.vol_start
149
>>> se.vol_start = 200
>>> se.vol_start
199
>>> 

@dpgeorge
Copy link
Collaborator Author

Do we want to rename interpolation to shape?

@microbit-carlos
Copy link
Contributor

Yes, let's rename interpolation to shape 👍

@dpgeorge
Copy link
Collaborator Author

Need to also think about the default settings for the following parameters which are not exposed by the API here:

  • steps
  • fx param
  • fx steps

The value of steps makes a difference for the default sound.

@dpgeorge dpgeorge force-pushed the audio-sound-effect branch from 381972b to ab084f4 Compare August 15, 2022 09:58
@dpgeorge
Copy link
Collaborator Author

Quick thing I've found, setting the volume to a value n results in n-1 being set:

This was a rounding error converting between a range of 255 and 1023. Now fixed.

@dpgeorge dpgeorge force-pushed the audio-sound-effect branch from ab084f4 to 5aa03ad Compare August 15, 2022 13:06
dpgeorge added a commit that referenced this pull request Aug 19, 2022
As per issue #103 and PR #106.

Current limitations:
- can't play an iterable of SoundEffect objects
- if a sound effect is playing with wait=False and another one is started
  then the first one will be stopped immediately

Signed-off-by: Damien George <[email protected]>
@dpgeorge dpgeorge force-pushed the audio-sound-effect branch from 5aa03ad to 854658d Compare August 19, 2022 07:36
As per issue #103 and PR #106.

Current limitations:
- can't play an iterable of SoundEffect objects
- if a sound effect is playing with wait=False and another one is started
  then the first one will be stopped immediately

Signed-off-by: Damien George <[email protected]>
@dpgeorge dpgeorge force-pushed the audio-sound-effect branch from 854658d to a54e8a0 Compare August 19, 2022 13:07
@dpgeorge
Copy link
Collaborator Author

Implemented support for playing a tuple/list of SoundEffect instances.

For simplicity of implementation, this just concatenates the tuple/list of
SoundEffect's into a big string to be passed directly to CODAL.

Signed-off-by: Damien George <[email protected]>
@dpgeorge dpgeorge force-pushed the audio-sound-effect branch from a54e8a0 to 822b3c9 Compare August 19, 2022 13:24
@dpgeorge dpgeorge merged commit 822b3c9 into master Aug 19, 2022
@dpgeorge dpgeorge deleted the audio-sound-effect branch August 19, 2022 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants