microbit-foundation / micropython-microbit-v2

Temporary home for MicroPython for micro:bit v2 as we stablise it before pushing upstream
MIT License
41 stars 22 forks source link

audio.play() set a pin mode to `music` instead of `audio` #137

Closed microbit-carlos closed 1 year ago

microbit-carlos commented 1 year ago

To replicate in v2:

>>> frames = [audio.AudioFrame()] * 128
>>> audio.play(frames, pin=pin16, wait=False); pin16.get_mode()
'music'

On V1:

>>> frames = [audio.AudioFrame()] * 128
>>> audio.play(frames, pin=pin16, wait=False); pin16.get_mode()
'audio'
dpgeorge commented 1 year ago

This has been fixed by fd99f400b42857b1094811cea76bd3fb841a8286

dpgeorge commented 1 year ago

Note that there are still some differences between v1 and v2 when it comes to pin modes and music/audio/speech. This is mainly because of https://github.com/microbit-foundation/micropython-microbit-v2/issues/50#issuecomment-865019571

This is a test I used when fixing this issue, that runs on both v1 and v2:

import os
microbit_version = int(os.uname().release[0])

import music
from microbit import pin0, audio

frames = [audio.AudioFrame()] * 128

if microbit_version == 1:
    music.play(music.PYTHON, wait=0)
    assert pin0.get_mode() == "music"
    try:
        audio.play(frames, wait=0)
        assert False
    except Exception as exc:
        assert repr(exc) == "ValueError('Pin 0 in music mode',)"
    assert pin0.get_mode() == "music"
    music.stop()
    assert pin0.get_mode() == "unused"
    audio.play(frames, wait=0)
    assert pin0.get_mode() == "audio", pin0.get_mode()
    audio.stop()
    assert pin0.get_mode() == "unused"
else:
    music.play(music.PYTHON, wait=0)
    assert pin0.get_mode() == "music"
    # allows playing audio while music is playing
    audio.play(frames, wait=0)
    assert pin0.get_mode() == "audio"
    audio.stop()
    # stays in audio mode to prevent clicks
    assert pin0.get_mode() == "audio"

audio.play(frames, wait=0)
assert pin0.get_mode() == "audio"
music.play(music.PYTHON, wait=0)
assert pin0.get_mode() == "music"
music.stop()
if microbit_version == 1:
    assert pin0.get_mode() == "unused"
else:
    # stays in music mode to prevent clicks
    assert pin0.get_mode() == "music"

print("Test passed")

Notice that the test needs very different logic for v1 and v2.