Audio, SD cards and speakers?


#1

Has anyone been able to play audio using an sd card and amplifier?

I have seen the DF Player used however I want to update the audio files on the sd card without having to plug the sd card into a PC.

Any ideas would be appreciated.


analogWrite (DAC) Examples?
#2

I don’t think the DFPlayer Mini will be the right choice for that.
But there are other options like the Adafruit Music Maker FeatherWing which should be usable with the Particle mesh devices or the Adafruit VS1053 breakout board.
For low/medium quality WAV/PCM files you could also use the Photon/Electron DAC pins.

If you were very adventurous the hypothetical possibility exists to make the DFPlayer accept the Particle devices as an SD/TF Card via SPI Slave Mode, but for that you’d need to find or write an SD/TF Card emulator library for the controllers.
Equally hypothetical would be the option to use the Particle’s USB capabilities to act as USB Mass Storage Device which can be connected to the USB+/USB- pins of the DFPlayer Mini (proving the FW of the player supports it - not all DFPlayer clones do AFAIK).


#3

Thanks for some great suggestions! I believe wav/pcm could be the solution as were only using 0.5w 8ohm speaker. The idea is to play multiple small audio files.


#4

As I was just answering another forum post, here is a library that might be interesting for you too


(also available on Web IDE as speaker)


#5

I’ve used the Talkie Library on the Photon along with an amplifier to get the Photon to talk over the speaker and play low-quality speech and sound files. That all worked.

I also tried an FM Radio tuner that was controlled over I2C via the Photon which also controlled an I2C controllable Amplifier. This worked also.

Never tried playing music from an SD card and amp before.

Tried quite a few amps and liked the 20w Adafruit one the best.

Tried a bunch of micro speakers and some of the 3w speakers were impressive for their size.


#6

Thanks for all your ideas! I have been trying many of them out.

I have figured that the DFPlayer isn’t going to work as there is no upload or interaction possible with the particle. I’m attempting to use an 2.5w amp to DAC pin.

any more suggestions would be appreciated as always!

Thanks


#7

Any ideas on converting a small audio file to play using pwm?


#8

What sort of audio file?
Why use PWM when you can use PCM with the DAC as is?
When it is a .wav it’s already PCM and you just need to get the data from the WAV header to convert the data - if needed -, dump the header and use the rest as input for the DAC.


#9

I’m looking to play a series of tiny 1-2 second audio files. I think what your suggesting is similar to this other thread?


#10

Indeed - and I’ve linked to the same library in this thread as well - just a few posts up, three weeks ago :wink:


#11

Thanks, Just getting my head around all the possible ways to do this, as the requirements for uploading audio was added I have had to remove the DFPlayer. Hopefully, I can get it going asap.


#12

Sparkfun has 3 new audio boards that may or maynot be of interest to you.


#13

These are really nice, however, the project I’m working on will require 1000 of these speaker/amp/particles. for this reason im trying to keep it simple and low cost.


#14

You can always take their open source design and parts and make a custom PCB to keep cost low if their solution does work for you.


#15

the project requires a whole load of other stuff based on the particle which is already built such as neopixels, OSC, accelerometer data, etc. This sound is the final piece in the jigsaw.


#16

After your PM I played a bit with the Speaker library and came up with a minimal sample that plays a ~100KB sound file (mono, 16bit, 22050Hz) from flash memory.
https://go.particle.io/shared_apps/5aef6f695286fce9cb00035e


#17

Wow this is awesome! I will let you know asap how things progress! how did you convert he audio to uint16_t?


#18

I’ve cobbled together some JavaScript that just takes any 16bit raw PCM audio (they usually come signed int16_t) file and spits out the uint16_t array to copy/paste into the sound.h file.

Just take this and copy/paste it into an .html file and open that with the browser of your choice.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>File converter</title>  
</head>
<body>

<div id="main">
  <h1>Raw Signed Int16 PCM to uint16_t array converter</h1>
    <form name="frmConvert" action="">
      <p>
        File: 
        <input type="file" name="fileinput" onchange='openFile(event)' /> 
      </p>
      <p>Options:</p>
        <p>
        Prefix data with variable definition <input id="prefix" value="const uint16_t sound[] = ">		  
        <br>
        Samples prefix <input id="samplePrefix"  type="text" value="0x" maxlength="10" >
        <br>
        Samples suffix <input id="sampleSuffix" type="text" value=", " maxlength="10" >
        <br>
        Insert newlines after every <input id="newline" type="number" value="10" min="0" max="100" style="width: 50px" > samples		  
        </p>
        <p>
          <button type=button name="btnConvert" onclick="Convert()">
            Convert
          </button>
        </p>		  
      </form>
      <p>Output:</p>
      <p>
        <textarea id="ed_output" rows="25" style="width: 100%"></textarea>				
      </p>			    
  </div>
<script type="text/javascript">   
  var samples;
	
  function Convert() {	
    var hexText = document.frmConvert.prefix.value;
    var sPrefix = document.frmConvert.samplePrefix.value;
    var sSuffix = document.frmConvert.sampleSuffix.value;
    var newline = document.frmConvert.newline.value;
    
    hexText += "\r\n{\r\n"
    for (i=0; i<samples.length; i++) {
      var sample = samples[i];
      sample += 32768;  // map int16_t -32768 .. +32767 to uint16 0 .. 65535
      hexText += sPrefix + ("000"+sample.toString(16)).slice(-4) + sSuffix;
      if (newline) {
        if ((i % newline) == newline-1) {
          hexText += "\r\n";
        }
      }
    }
    hexText += "\r\n};"
    document.getElementById("ed_output").value = hexText;		  	
  }

  function readFileAsArray(file) {
    var reader = new FileReader();
    reader.onload = function(){
      var arr = reader.result;
      samples = new Uint16Array(arr);	  
    };
    reader.readAsArrayBuffer(file);    
  }    

  var openFile = function(event) {
    var input = event.target;
    readFileAsArray(input.files[0]);
  };   
</script>

</body>
</html>

#19

Presumably this doesn’t work with the mesh boards because they don’t have a DAC pin ?