microsoft / pxt-arcade

Arcade game editor based on Microsoft MakeCode
https://arcade.makecode.com
MIT License
477 stars 206 forks source link

music.playInstructions crashes PyGamer? #2423

Closed klausw closed 3 years ago

klausw commented 4 years ago

Describe the bug I've been experimenting with using the low-level sound API, and my test works in the simulator, but apparently crashes on executing music.playInstructions when using an Adafruit PyGamer. (That's the only hardware I currently have available.)

To Reproduce Steps to reproduce the behavior:

  1. Go to https://makecode.com/_DhaECRbah06f
  2. Download onto Adafruit PyGamer
  3. Press A to start
  4. Press A and B to test sounds

As soon as I press A or B to play a sound, the screen sprite stops moving and no sound is heard.

Expected behavior Sounds should play. The screen sprite should keep moving using its (slow) velocity. This works as expected in the simulator.

Desktop (please complete the following information):

Additional context I've also tested other low-level sound API examples, those also don't play any audible sound when downloaded onto the Adafruit PyGamer, for example from https://github.com/microsoft/pxt-arcade/issues/1846 where I tried https://makecode.com/_hLg9f8AK4WUY and @riknoll's https://makecode.com/_4j4hkF95cMjd

Sound works on this hardware for other programs using music.playNote or playMelody.

PyGamer INFO_UF2.TXT :

UF2 Bootloader v3.10.0 SFHWRO
Model: PyGamer
Board-ID: SAMD51J19A-PyGamer-M4

Let me know if there's something I should be able to check using a serial console or other debugging interface.

Here's my test's source for reference:

klausw commented 4 years ago

Here's the source of my test https://makecode.com/_DhaECRbah06f for reference. (The sprite isn't part of the test itself, I just used it to make it more obvious that the update loop seems to have stopped working.(

controller.B.onEvent(ControllerButtonEvent.Pressed, function () {
    const sound2: Buffer = hex`
      0f 00 dc00 0004 0004 0000 7600
      05 00 b801 0004 0008 0000 dc00
    `;
music.playInstructions(0, sound2)
})
controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
    const sound: Buffer = hex`0f 00 7003 0004 0004 0000 7003`;
music.playInstructions(0, sound)
})
namespace music {
    //% shim=music::queuePlayInstructions
    export function playInstructions(timeDelta: number, buf: Buffer) { }
}
scene.setBackgroundColor(6)
game.splash("Press A or B to test sound")
let mySprite = sprites.create(img`
    . . . . . . . . . . . . . . . . 
    . . . . . 2 2 2 2 2 2 . . . . . 
    . . . . . 2 4 4 4 4 2 . . . . . 
    . . . . . 2 4 4 4 4 2 . . . . . 
    . . . . . 2 4 4 4 4 2 . . . . . 
    . 2 2 2 2 2 2 2 2 2 2 2 2 2 2 . 
    . 2 4 4 4 2 4 4 4 4 2 4 4 4 2 . 
    . 2 4 4 4 2 4 5 5 4 2 4 4 4 2 . 
    . 2 4 4 4 2 4 5 5 4 2 4 4 4 2 . 
    . 2 4 4 4 2 4 4 4 4 2 4 4 4 2 . 
    . 2 2 2 2 2 2 2 2 2 2 2 2 2 2 . 
    . . . . . 2 4 4 4 4 2 . . . . . 
    . . . . . 2 4 4 4 4 2 . . . . . 
    . . . . . 2 4 4 4 4 2 . . . . . 
    . . . . . 2 2 2 2 2 2 . . . . . 
    . . . . . . . . . . . . . . . . 
    `, SpriteKind.Player)
mySprite.setPosition(0, 0)
mySprite.setVelocity(2, 2)
mySprite.setFlag(SpriteFlag.StayInScreen, true)
mmoskal commented 3 years ago

playInstructions currently doesn't support read-only buffers. The hex literals are always read-only. (It took me a while to figure it out, as I had to set up my debug environment again)

You can work around it by calling music.playInstructions(0, sound2.slice())

I think I'll fix the code not to require buffers to be writable.

mmoskal commented 3 years ago

Also it will only write the buffers, if some parameters are out of range:

                CLAMP(20, p->frequency, 20000);
                CLAMP(20, p->endFrequency, 20000);
                CLAMP(0, p->startVolume, 1023);
                CLAMP(0, p->endVolume, 1023);
                CLAMP(1, p->duration, 60000);