• I'm just trying here with an example raw file I know, and it does seems that I'm not getting any output on the DAC...

    However, output via PWM does work for me, so:

    analogWrite(A0, 0.5, {freq:20000});
    w.startOutput(A0,4000,{repeat:true});
    

    Should actually produce something for you...

  • not working mate. Whatever pin I use, whatever code I try, nothing but odd sounds :(

    Really wanted this to work as playing sounds directly from the card would be perfect for my project.

    The raw file was saved as unsigned too (ignore aff filename in screen shot).

    If you lived closer I would drop it by!!! ;)


    1 Attachment

    • Untitled-1.jpg
  • Have you tried something longer, and a bit easier to listen to - like music? The sound sample you had was quite short and not very easy to hear.

    Actually looking at it, the sample is around 0.5 sec long? So at 4kHz you'd expect it to be ~2000 samples = 2k bytes.

    However it's ~17k? and in the bottom left of your image you can see 'project rate' is still 48kHz.

    It could be it is playing, but it's basically 10x slower than you're expecting so it sounds totally wrong?

    Also - if it was only a few k, you could load it into a string as you were doing before and play it that way, since it's a lot smaller.

  • I'm thinking it might be best to just use this the WTV020-SD-16P module (http://www.ebay.co.uk/itm/262483803386) and try to interface with that. I'll be needing to store and play some rather large files (+5mb) and I don't thing streaming them off the on board sdcard will work too well? I would be very happy to be corrected :)

    Now I need to work out how to get the module wired up and communicating with the Espruino. Would you have any advice for this dude? I know I'm asking a lot of questions but can't afford to go buggering things up by getting it wrong!

    Thanks for all your help thus far.

  • I wouldn't give up just yet.

    Have you tried once you got the sample rate correct? To test I used Audacity to export a 5 minute long song to a 4kHz RAW file and it worked great, without any problems at all.

  • really??? hmmmm.......

    Do you have the code block you used and perhaps that actual raw file so I can replicate and have some kind of datum to start from?

  • Sure, I just tried it and the following works great for me:

    var f = E.openFile("music.raw","r");
    var w = new Waveform(2048, {doubleBuffer:true});
    // load first bits of sound file
    w.buffer.set(f.read(w.buffer.length));
    w.buffer2.set(f.read(w.buffer.length));
    var fileBuf = f.read(w.buffer.length);
    // when one buffer finishes playing, load the next one
    w.on("buffer", function(buf) {
      buf.set(fileBuf);
      fileBuf = f.read(buf.length);
      if (fileBuf===undefined) w.stop(); // end of file
    });
    // start output
    analogWrite(A4, 0.5);
    w.startOutput(A4,4000,{repeat:true});
    

    just copy the file to the root of the SD card as music.raw


    1 Attachment

  • The sound quality is much better with an 8kHz file and playback. Definitely seems to be a sweet spot for it

    ... and the DAC does work fine, it's just not very powerful so you need to put it into something that'll amplify it

  • PROGRESS!! It's working, whoop! ... Still a few glitches to iron out but the way it sounds actually works better for my project (will share when done).

    Main issue, a large raw file (+9mb) plays ok, but when I stop and restart it I get out of memory error. Can I free the memory taken by the file?

    Example block:

    var AUDIOUT = A1;
    
    function TRamp_playSoundFile(file)
    {
      var f = E.openFile("/audio/" + file,"r");
      w = undefined;
      w = new Waveform(2048, {doubleBuffer:true});
      // load first bits of sound file
      w.buffer.set(f.read(w.buffer.length));
      w.buffer2.set(f.read(w.buffer.length));
      var fileBuf = f.read(w.buffer.length);
      // when one buffer finishes playing, load the next one
      w.on("buffer", function(buf) {
        buf.set(fileBuf);
        fileBuf = f.read(buf.length);
        if (fileBuf===undefined)
        {
          w.stop(); // end of file
          f.close();
          TRamp_stopSoundFile();
        }
      });
      // start output
      analogWrite(AUDIOUT, 0.5, {freq:20000});
      w.startOutput(AUDIOUT,4000,{repeat:true}­);
    }
    
    function TRamp_stopSoundFile()
    {
      AUDIOUT.write(0);
      w = undefined;
    }
    
  • Yes, do w.stop() to stop playback, and f.close() (I think), and you'll be sorted.

    As I said above though, it turns out the DAC on A4/A5 does work nicely, it just needs amplifying.

  • YAY< working!! Pin A1 gives the best results, got nothing with A4, even when amplified. Go figure... anyhow, onto the next little issue, you know there will be one ... ;)

    Cheers G

  • Is it possible to shed any light on this mate?

    I constantly get the ERROR: Prompt not detected issue, and also it's now telling me that (I'm guessing) the code is too big to save? It's 460 lines long and around 10k (marginally more with the setting file file but that's only a few lines).

    Also, it seems like the stop() and close() aren't working so well as playing different sounds results in memory errors :(

    So close though!


    1 Attachment

    • ide.jpg
  • Looks like you've put save() at the end of the code on the right hand side? I'd take that out and do it manually.

    Would you have started playing code immediately on upload? That could have made the code seem larger than it is?

    Could you post up the code you use for stop/play? Do you always let the file play through to the end, or do you sometimes stop it halfway?

  • OK I can do that. I thought I read somewhere in the forums that to make the code run on power up it would be best to have save at the end?

    There is a start up sound but it's triggered from within onInit().

    Sounds do get stopped/started partway through when needed. This is the stop/play code:

    var AUDIOUT = A1;
    
    function _playSoundFile(file)
    {
      LED3.write(1);
      var filename = "/audio/" + file;
      f = E.openFile(filename,"r");
      w = undefined;
      w = new Waveform(2048, {doubleBuffer:true});
      w.buffers = [ w.buffer, w.buffer2 ];
      w.buffer.set(f.read(w.buffer.length));
      w.buffer2.set(f.read(w.buffer.length));
      var fileBuf = f.read(w.buffer.length);
      w.on("buffer", function(buf) {
        buf.set(fileBuf);
        fileBuf = f.read(buf.length);
        if (fileBuf===undefined)
        {
          f.close();
          _stopSoundFile();
        }
      });
      analogWrite(AUDIOUT, 0.5, {freq:20000});
      w.startOutput(AUDIOUT,8000,{repeat:true}­);
    }
    
    function _stopSoundFile()
    {
      LED3.write(0);
      if (w && w.running) w.stop();
      AUDIOUT.write(0);
      w = undefined;
    }
    
    

    I would love to share details and full code with you dude as well as an overview of requirements, images and videos of performance, but this is an actively developing product and as such I have to protect the IP (it's a small but competitive arena that this will sit into when done). That said, I would be happier to send full details to your email if possible?

    I feel this is really close to fully working and once done would be the best of it's kind within it's field, so would welcome your assistance in completing it, and could look at re-reimbursement for your time spent.

  • It looks like you missed out the f.close I'd suggested, so the file will be left open which will use memory?

    Try:

    function _playSoundFile(file)
    {
      LED3.write(1);
      var filename = "/audio/" + file;
      f = E.openFile(filename,"r");
      w = undefined;
      w = new Waveform(2048, {doubleBuffer:true});
      w.buffers = [ w.buffer, w.buffer2 ];
      w.buffer.set(f.read(w.buffer.length));
      w.buffer2.set(f.read(w.buffer.length));
      var fileBuf = f.read(w.buffer.length);
      w.on("buffer", function(buf) {
        buf.set(fileBuf);
        fileBuf = f.read(buf.length);
        if (fileBuf===undefined)
        {
          _stopSoundFile();
        }
      });
      analogWrite(AUDIOUT, 0.5, {freq:20000});
      w.startOutput(AUDIOUT,8000,{repeat:true}­);
    }
    function _stopSoundFile()
    {
      LED3.write(0);
      if (w && w.running) w.stop();
      AUDIOUT.write(0);
      w = undefined;
      if (f) f.close();
      f = undefined;
    }
    

    Another option is just to leave the w object defined... Something like below should work:

    var w = new Waveform(2048, {doubleBuffer:true});
    var fileBuf, f;
    w.buffers = [ w.buffer, w.buffer2 ];
    w.on("buffer", function(buf) {
        buf.set(fileBuf);
        fileBuf = f.read(buf.length);
        if (fileBuf===undefined)
        {
          _stopSoundFile();
        }
    });
    
    function _playSoundFile(file)
    {
      LED3.write(1);
      var filename = "/audio/" + file;
      f = E.openFile(filename,"r");  
      w.buffer.set(f.read(w.buffer.length));
      w.buffer2.set(f.read(w.buffer.length));
      fileBuf = f.read(w.buffer.length); 
      analogWrite(AUDIOUT, 0.5, {freq:20000});
      w.startOutput(AUDIOUT,8000,{repeat:true}­);
    }
    function _stopSoundFile()
    {
      LED3.write(0);
      if (w.running) w.stop();
      AUDIOUT.write(0);
      if (f) f.close();
      f = undefined;
    }
    
  • hmmm, f.close(); was in the _playSoundFile function before the _stopSoundFile call, so I assumed that would work there.

    I'll give those a try and see what happens. Thanks G

  • _stopSoundFile only gets called when the file has finished playing - so if you called it yourself to stop the sound then it wouldn't have closed the file.

  • _stopSoundFile was also called from another function elsewhere

  • I give up! It was so close to working, was able to select and play files off the card, but now for apparently no reason as I've not added anything, it constantly runs out of memory and falls over playing a file.

    I see my only options now as either hooking up a dedicated mp3 player breakout (with sdcard), but I have zero idea of where to start with this (want to be able to control and select the file being played but can't find any info in the forums or main pages that I can make sense of) or drop Espruino and try to learn Ardiono as it seems to be more suited for this sort of thing (really don't want to do this).

    As a wise man once said, it's only easy when you know how.

    I'm open to any and all advice at this point!

  • Does it fail even with the second section of code I posted above?

    Perhaps you could strip your code down to a bare minimum that still exhibits the problem and that you can post up here? Then we can run it and see what's wrong.

    It may not even be related to playback - it might be the rest of your code that's allocating memory somewhere.

  • Just to add, you can run something like E.getSizeOf(global,1) every once in a while, and see if some particular variable keeps going up in size.

  • Was using the code from above, and it was working for a bit but now falls over with some larger files. All the other code is running as expected and presents no memory error. I'll give your above suggestion a try and see if I get any information.

    Was also looking at hooking up the VS1053 break out mp3 player, but no having much luck with that either. I'm assuming it's down to having an sdcard already on the Espruino 1.4, as I get a NOT_READY response from it when I hook up the VS module to SPI2 (LCD is on SPI1) and try to connect to it with E.connectSDCard. I'm assuming it's due to the require('fs') only reading teh onboard sdcard so tried separating them and assigning as unique, but no dice.

    
    var fs, mp3, temp;
    // LCD
    var LCDGND = B1,
    LCDLIGHT = B0,
    LCDVCC = A7,
    LCDSCK = A6,
    LCDMOSI = A5,
    LCDSPI12SCK = A4,
    LCDSPI2MISO = A3,
    LCDSPI2MOSI = A2;
    
    
    function onInit() 
    {
      clearInterval();
      fs = require('fs');
      _loadSettings();
      // set up temp sensor
      temp = require("DS18B20").connect(ow);
      // Setup SPI
      var SPI1 = new SPI();
      SPI1.setup({ sck:LCDSCK, mosi:LCDMOSI });
      // Initialise the LCD
      g = require("PCD8544").connect(SPI1,LCDSPI12­SCK,LCDSPI2MISO,LCDSPI2MOSI, function() 
      {
        LCDLIGHT.write(1); // Turn on the backlight
        // When it's initialised, start...
        _Start();
      });
      
      _setupMP3player();
    }
    
    function _setupMP3player()
    {
      mp3 = require('fs');
      var SPI2 = new SPI();
      SPI2.setup({mosi:B5, miso:B4, sck:B3});
      E.connectSDCard(SPI2, B6 /*CS*/); // .... gives ERROR: UNable to mount SD card : NOT_READY
      // see what's on the device
      //print(mp3.readdirSync());
    }
    
    
    
  • I've spent hours so far helping you get your code working. I've posted code above (at the end of last post) that I just tested, and that is working perfectly, without any loss of memory. In fact you could use the code below, which allows you to just call _playSoundFile without worrying about calling _stopSoundFile first:

    var AUDIOUT = A0;
    var w = new Waveform(2048, {doubleBuffer:true});
    var fileBuf, f;
    w.buffers = [ w.buffer, w.buffer2 ];
    w.on("buffer", function(buf) {
      buf.set(fileBuf);
      fileBuf = f.read(buf.length);
      if (fileBuf===undefined)
        _stopSoundFile();
    });
    function _playSoundFile(file) {
      _stopSoundFile();
      LED3.write(1);
      var filename = file;
      f = E.openFile(filename,"r");  
      w.buffer.set(f.read(w.buffer.length));
      w.buffer2.set(f.read(w.buffer.length));
      fileBuf = f.read(w.buffer.length); 
      analogWrite(AUDIOUT, 0.5, {freq:20000});
      w.startOutput(AUDIOUT,8000,{repeat:true}­);
    }
    function _stopSoundFile() {
      LED3.write(0);
      if (w.running) w.stop();
      AUDIOUT.write(0);
      if (f) f.close();
      f = undefined;
      fileBuf = undefined;
    }
    

    I'm afraid I just don't have time to help you throw everything away and start again from scratch, especially when I offered to fix your code and you can't be bothered to strip it down enough that you can post it up for me.

  • Dude, I didn't mean to piss you off.

    I have to be careful with the code I post so I can protect the IP of the product being developed. I have tried to implement your suggestions and have fed back results.

    I very much appreciate all your help Gordon, and have expressed that. I understand how busy you must be and how annoying constant questions are from a "newbie" who doesn't have as much knowledge of the subject matter as yourself, I get that in what I do, so I'm trying to structure help requests and feedback on implementing your suggestions as well as I can.

    In a previous post I did ask if I could send you the entire code "as is" to your email (for security reasons) rather than listing it all here, so that you could see the full structure as opposed to snippets but had no response from that so have had to keep posting piecemeal bites of code. I apologise if this approach has angered you.

    I don't recall an offer to fix my code if I'm honest but maybe I missed that or misread a post, and neither did I ask you help me start again from scratch. I have stripped down what I believed to be the relevant parts and posted them for you, so to hear you say I couldn't be bothered is a little unsavoury. I did also say I was open to suggestions and if that is "go away and don't bother me again" than so be it.

    Thank you for your time thus far.

  • Sorry for the misunderstanding - it just seemed from the previous post that you were starting off on the VS1053 player when you were so close to getting the existing one working.

    Sure, if you email the code to gw@pur3.co.uk that's fine, and I'll take a look and see if I can figure out what's using up the memory.

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

Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4

Posted by Avatar for davenelson @davenelson

Actions