• I try to play with sounds on my MDBT42Q module. It seems that w.startOutput is not doing anything. Any hint? Furthermore, event 'finish' is never emitted.

    My code is below:
    (sound.raw is in internal storage and has been generated following the procedure explained here)

    BZ=D28;
    LS=D29;
    var w;
    function play() {
        var wave = require("Storage").read("sound.raw");
        w = new Waveform(wave.length);
        w.buffer.set(wave);
        analogWrite(BZ, 0.5,{freq:40000} );
        w.startOutput(BZ, 4000);
        w.on("finish", function(buf) {
          BZ.reset();
          console.log("done!");
        });
    }
    
    var inited=false;
    function onInit(){
      if(!inited)
      {
        inited=true;
        analogWrite(BZ, 0.0,{freq:4000} );
        pinMode(LS,'input_pullup');
        setWatch("play();", LS, {repeat:true,edge:'rising',debounce:50})­;
      }
    }
    onInit();
    
  • Just a guess - I'd put line 10 with the w.on setup above the w.startOutput(BZ, 4000); so the event handler is registered before it is started.

  • As for the playback, the example looks STM32 based and loads data from sd card into RAM. With nrf52 internal storage the require("Storage").read("sound.raw") actually does not read anything into RAM, it gives direct pointer to flash memory and I am not sure it can play audio directly from that (nrf52 DMA cannot read from flash, only RAM?). So I'd suggest to copy data to new array in RAM to see if it makes difference.

  • ... , it gives direct pointer to flash memory

    This is true, but w.buffer.set(wave); should then just copy that into the RAM buffer so the waveform should work.

    I just tried here and something odd does seem to be going on.

    If you do repeat:true then it does work. For instance this 'pulses' the LED:

    var w = new Waveform(256);
    for (var i=0;i<256;i++) w.buffer[i] = 128+Math.sin(i*Math.PI/128)*127;
    analogWrite(LED1, 0.5);
    w.on("finish", function(buf) {
      console.log("Done");
    });
    w.startOutput(LED1, 100, {repeat:true});
    

    But there's some odd flickering going on right at the start which makes me think maybe the start time is set wrong. I'll see if I can figure out what's up and get back to you

  • Ok, just fixed it I think. Try the latest cutting edge build.

    What was happening was since 2v13 the start time was set wrong (at time=0). After I'd made the timer improvements in 2v13 I did test waveform, but I basically booted the device up so getTime()==0 and checked the waveform almost right away with repeat=true - and in that case it worked.

    But otherwise it would have failed. I'm pretty surprised this was never found as the Micro:bit 2 build has a 'play' function that would have been affected by this too!

    ... and @fanoush is right re: on("finish" position too - if it was set earlier you'd have seen it being called. It just would have been called almost immediately (when it shouldn't have)

  • Thanks very much @fanoush and @Gordon, I followed your advices and it works like a charm!
    I confirm that there is no need to explicitely load the raw file in RAM. I tested with cutting edge build 2v17.39.

    So much fun with Espruino!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

waveform.startOutput on MDBT42Q seems not to start, any experience out there?

Posted by Avatar for Jean-Philippe_Rey @Jean-Philippe_Rey

Actions