Playing audio files from Teensy on-board memory

Status
Not open for further replies.
Hi there all,
Trying to get my teensy v3.1 to access my .h audio files in the controllers on-board memory.
I want it to playback 3 different sound files.
The first to be played once when a button is pushed in.
The second to then be played in a loop while the button is held down.
The third to be played once when the button is released.
Trouble is the only syntax reference I've seen for doing this isn't compiling in the main arduino program.
Seems it needs something before the AudioPlayMemory command and says the object it's supposed to create hasn't been declared.

Here is my code so far:

int inPin = 14;
int val = 0;

#include <iostream>
#include "mngs1.h";
#include "mngs2.h";
#include "mngs3.h";
AudioPlayMemory gunSound;


void setup()
{
pinMode(inPin, INPUT); //Sets the digital pin as input:
}
void loop()
{
val = digitalRead(inPin); //Read input pin:
if val == 1
gunSound.play (mngs1.h);
else val = digitalRead(inPin); //Read input pin:
while val == 1
{
gunSound.play(mngs2.h);
val = digitalRead(inPin);
}
gunSound.play(mngs3.h);
}
...............................................................................

Any help on what I'm doing wrong would be appreciated.
Please bare in mind all I've had to go on with my coding is that which I've been able to obtain from online examples of syntax so go easy on me.
 
Last edited:
First question are you using the audio card? Have you got the SamplePlayer example to work? I would be tempted to start with SamplePlayer and delete what was not needed.
 
All audio library programs need AudioMemory(), usually in setup(). Your program also lacks any sort of output device, and a connection from the player object to that output device.

I highly recommend trying the SamplePlayer example to get started. Open it with File > Examples > Audio > SamplePlayer.
 
I'm not using the audio card, just the teensy 3.1 micro-controller.
The idea if possible was to upload the main control code and .h audio data files to the cards on-board flash memory.
The output would go to a miniature amplifier which then feeds a miniature speaker.
I am very confused as to which port serves this function on teensy, is this the DAC port?.
 
Again, I recommend starting with File > Examples > Audio > SamplePlayer.

It sends the sounds to both the audio board and DAC (pin A14). It will play without the audio board connected. Just use a 10 uF capacitor to connect between the DAC pin and the input to amplified computer speakers, and of course connect the grounds.

Do yourself a favor and start with the working example. It's there to help you.
 
With much reference to the SamplePlayer example which has been a great help i am now much further along, oh and I never knew the wav2sketch.exe was included in the arduino IDE, wish i'd known that before.
My .cpp and .h files are all properly sorted now.

Here is my main .ino file as of now:


#include <Audio.h>
#include "mngs1.h"
#include "mngs2.h"
#include "mngs3.h"
AudioMemory(2);
AudioPlayMemory gunSound; // creates the Audio memory object
AudioOutputAnalog dac; // play to on-chip DAC
int inPin = 2;
int val = 0;

void setup()
{
pinMode(inPin, INPUT); //Sets the digital pin as input:
};
void loop()
{
val() = digitalRead(inPin); //Read input pin:
if val() == 1
{
gunSound.play(mngs1);
};
val() = digitalRead(inPin); //Read input pin after first file is played once:
while val() == 1
{
gunSound.play(mngs2);
val() = digitalRead(inPin);
};
gunSound.play(mngs3);
};
.......................................................................
However when i come to compile I'm getting a strange error:

In file included from C:\Users\Jo\Desktop\Arduino\arduino-1.0.6\libraries\Audio/Audio.h:85:0,
from minigun.ino:2:
C:\Users\Jo\Desktop\Arduino\arduino-1.0.6\libraries\Audio/play_sd_raw.h:31:16: fatal error: SD.h: No such file or directory
compilation terminated.
..................................................................
I'm not using an SD card...
 
Add #include <SD.h> near the beginning of your program.

Your program must include all the libraries which the Audio library might use, even if you don't actually use any of the features that rely on those libraries. Yes, it's silly, but it's simply how Arduino works.

Future versions of Arduino are likely to fix this someday, but for now with Arduino 1.0.6, you need to have those extra includes. See the SamplePlayer example.
 
Thanks for that, i had already done so by process of elimination along with other libraries but i didn't realise it was necessary regardless of them actually being used or not.
I'm all done now with the compiling, it's all uploaded to my teensy :D.
However i do now have a hardware related issue i need to clear up.
The ports on the teensy 3.1 for power connections, ground and the push button.
I'm a bit confused as to what connections need to be made.
There are 3 power connections and 3 grounds, do i need to connect to all of them if I'm using the dac and digital pin 2 for the push button?
Also do i need to use a resistor with the push button in order to keep it's input as LOW before being pressed and when released?
 
Last edited:
Please, run the example. Connect DAC and the nearby GND pin to the input of an amplified computer speaker.

To trigger the 6 sounds, tap a wire or paperclip between pins 0 to 5 and the nearby GND pin.

The example is there to help. All you have to do is click the Upload button and your Teensy will be running that known-good example. Please, run the example and hear some sounds. I'm sure that'll make everything much clearer.
 
I have now finally run the example successfully so i've know i've gotten the power connections figured out.
However when i came to try my now compiled main program, all I'm getting is a horrible loud popping noise from the speaker as soon as i connect the power.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "mngs1.h"
#include "mngs2.h"
#include "mngs3.h"

AudioPlayMemory gunSound; // creates the Audio memory object
AudioOutputAnalog dac; // play to on-chip DAC
AudioConnection c1(gunSound, 0, dac, 0);
AudioControlSGTL5000 audioShield;

int inPin = 2;
int val = 0;

void setup()
{
pinMode(inPin, INPUT); //Sets the digital pin as input:
AudioMemory(1); //Allocates 1 memory spaces for audio file to be played

// turn on the output
audioShield.enable();
audioShield.volume(0.5);
}
void loop()
{
val = digitalRead(inPin); //Read input pin:
if (val == 1)
{
gunSound.play(mngs1);
}
val = digitalRead(inPin); //Read input pin after first file is played once:
while (val == 1)
{
gunSound.play(mngs2);
val = digitalRead(inPin);
}
gunSound.play(mngs3);
};
 
Use the Bounce library to detect button presses. The Bounce library is well tested. It detects change in pin state very reliably.

You're trying to do the same with only digitalRead(), but you're not storing the previous button state and detecting only the change. You code is repeatedly restarting the sound.

If you will not follow my advice to use the Bounce library, at least add some Serial.print("test") lines various places in your code, and then watch with the Arduino Serial Monitor. That will let you see what your code is actually doing. You'll be able to diagnose problems.

Of course, if you simply use the high quality Bounce library, you won't need to reinvent that wheel. Bounce works extremely well.
 
Ok I'm giving the Bounce library a try, only problem is, the way I've tried using it in the coding doesn't seem to be working properly.
Have i used the correct syntax?


#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Bounce.h>
#include "mngs1.h"
#include "mngs2.h"
#include "mngs3.h"

AudioPlayMemory gunSound; // creates the Audio memory object
AudioOutputAnalog dac; // play to on-chip DAC
AudioConnection c1(gunSound, 0, dac, 0);
AudioControlSGTL5000 audioShield;
Bounce inPin = Bounce(2, 1); // 1 ms debounce time

void setup()
{
pinMode(2, INPUT); //Sets the digital pin as input:
AudioMemory(1); //Allocates 1 memory spaces for audio file to be played

// turn on the output
audioShield.enable();
audioShield.volume(0.5);
}
void loop()
{
inPin.update();
if (inPin.risingEdge())
{
gunSound.play(mngs1);
while (inPin.risingEdge())
{
gunSound.play(mngs2);
}
gunSound.play(mngs3);
}
};
 
You're calling risingEdge() again, without first calling update().

Perhaps you're misunderstanding how the play() function works. It returns to your code immediately. Your code continues running while the audio library actually plays the sound. It does NOT wait for the sound to actually play.
 
Ok, starting to think i may have done something to my teensy...it was going berserk while trying to playing the example file.....it was trying to do it but it seemed to keep going into a nasty loud perpetual scream.
Also there are no leds coming on anymore at anytime, for uploading or just being connected to the usb port.
Wondering if maybe my connections aren't good enough, i have only rapped wire ends through the port holes atm.
I do have some proper breadboard connection cables coming though.
Anyways, I've now updated my main code:


#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "mngs1.h"
#include "mngs2.h"
#include "mngs3.h"

AudioPlayMemory gunSound; // creates the Audio memory object
AudioOutputAnalog dac; // play to on-chip DAC
AudioConnection c1(gunSound, 0, dac, 0);
AudioControlSGTL5000 audioShield;
int inPin = 2;
int val = 0;

void setup()
{
pinMode(2, INPUT); //Sets the digital pin as input:
AudioMemory(1); //Allocates 1 memory spaces for audio file to be played

// turn on the output
audioShield.enable();
audioShield.volume(0.5);
}

void loop()
{
val = (digitalRead(inPin));
if (val == HIGH)
{
gunSound.play(mngs1);
}
if (!gunSound.isPlaying())
{
val = (digitalRead(inPin));
while (val == HIGH)
{
if (gunSound.isPlaying())
{
val = (digitalRead(inPin));
}
gunSound.play(mngs2);
}
}
if (val == LOW)
{
gunSound.play(mngs3);
}
};


It does compile.
Please let me know if you think this should work or if I've made anymore booboos with what I'm trying to achieve.
 
Last edited:
the first 'if' in your loop() will re-trigger file #1 as long as the button is pressed; i suspect that's where the screaming is coming from. ie

Code:
val = (digitalRead(inPin)); 
if (val == HIGH)
{
     gunSound.play(mngs1);
}

you should try to make clear to yourself what needs to happen, when. i haven't tested this, and am not very familiar with the bounce library, but here is some code that might help, and even work (more or less); this assumes your button is normally low, and going high when pushed.



Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Bounce.h>
#include "mngs1.h"
#include "mngs2.h"
#include "mngs3.h"

AudioPlayMemory gunSound; // creates the Audio memory object
AudioOutputAnalog dac; // play to on-chip DAC
AudioConnection c1(gunSound, 0, dac, 0);
AudioControlSGTL5000 audioShield;
int inPin = 2;

Bounce Button = Bounce(inPin, 20);

uint8_t STATE;    // variable that tells us where we are in the sequence

// the sequence of states (another way of writing {0, 1, 2, 3} ):

enum Sequence {

   DO_NOTHING,
   SOUND1,
   SOUND2,
   SOUND3 
};



void setup()
{
pinMode(inPin, INPUT); //Sets the digital pin as input:
AudioMemory(10); //Allocates memory for audio file to be played

// turn on the output
audioShield.enable();
audioShield.volume(0.5);

// initial state :

STATE = DO_NOTHING;
}



void loop() {
  
    Button.update();                 // check button
    
    if (Button.risingEdge())  STATE = SOUND1;     // did someone push it? if so, start playing.
        
    if (STATE) playgun();       // do we play? 
}; 



void playgun() {
 
  // which stage are we at?   
  switch (STATE) {
        
       case SOUND1: {
           // play file #1 once and move on to stage 2: 
           gunSound.play(mngs1.h);
           STATE = SOUND2;
           delay(25); // give isPlaying() some time.
           break;
         
       }  
       
       case SOUND2: {
           // button still held down?
           if (digitalRead(inPin)) {
           // if so, (re)play sound 2, but only if nothing is being played already:        
               if (!gunSound.isPlaying()) gunSound.play(mngs2.h);
           }
           // if button was released, move on:
           else STATE = SOUND3;  
           break;
      }
      
      case SOUND3: {
            // play sound # 3 
            gunSound.play(mngs3.h);
            // and reset state:
            STATE = DO_NOTHING;
            break; 
      }  
  }
}
 
Last edited:
Are you ever going to try my advice to add some Serial.println("something") lines into your code, and view the "something" messages in the Arduino Serial Monitor?
 
As I said in the other thread, I tried using the serial monitor without success.
Hmmm interesting it works for you, I'm very glad that the code DOES work as intended at last.
One possibly bad thing that has occurred to me from a hardware standpoint.
Couple of days ago i had no clue about the proper power in connection for using the 3v coin cell battery (i was confused and thought the 3v meant it was for using the 3v battery).
Would this have damaged anything?
The strange thing is, this is how i managed to play the sampleplayer example to begin with.
I'm now using the proper Vin port for the battery.
Really hope i haven't done my Teensy a damage....
 
I now have a nice new none defective Teensy 3.1 purchased from Hobbytronics!
My program now works properly on the serial monitor!
However there is something i just don't understand.

The "if" line for my 2nd sound loop, i don't get what it's supposed to be doing.
It just says:

if (digitalRead(inPin))

yeah but if (inPin) is what?
it doesn't give anything to compare it to.....
but it is working, i just want to understand exactly what this line is doing!?


#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Bounce.h>
#include "mngs1.h"
#include "mngs2.h"
#include "mngs3.h"

AudioPlayMemory gunSound; // creates the Audio memory object
AudioOutputAnalog dac; // play to on-chip DAC
AudioConnection c1(gunSound, 0, dac, 0);
AudioControlSGTL5000 audioShield;
int inPin = 2;



Bounce Button = Bounce(inPin, 20);

uint8_t STATE; // variable that tells us where we are in the sequence
uint8_t playnow; // variable that tells us whether we are playing

// the sequence of states (another way of writing {0,1,2}):

enum Sequence
{
SOUND1,
SOUND2,
SOUND3
};

void setup()
{
Serial.begin(9600);
pinMode(inPin, INPUT); //Sets the digital pin as input:
AudioMemory(10); //Allocates memory space for audio file to be played

// turn on the output
audioShield.enable();
audioShield.volume(0.5);

// initial state:

STATE = SOUND1;
playnow = false;
}

void loop()
{
Button.update(); // check button
if (Button.risingEdge()) playnow = true; // did someone push it? if so start playing.
if (playnow) playgun(); // do we play?
};

void playgun()
{
// which stage are we at?
switch (STATE)
{

case SOUND1:
{
Serial.println("1st Sound");
// play file #1 once and move on to stage 2:
gunSound.play(mngs1);
delay(662);
STATE = SOUND2;
break;
}

case SOUND2:
{
Serial.println("2nd Sound");
// button still held down?
if (digitalRead(inPin))
{
// if so, (re)play sound 2, but only if nothing is being played already:
if (!gunSound.isPlaying()) gunSound.play(mngs2);
delay(58);
}
// if button was released, move on:
else STATE = SOUND3;
break;
}

case SOUND3:
{
Serial.println("3rd Sound");
// play sound # 3
gunSound.play(mngs3);
// and reset state:
STATE = SOUND1;
playnow = false;
break;
}

}
};
 
If the condition in an if statement evaluates to non-zero it is the same as "true". If it evaluates to zero it is equivalent to "false".
So the statement "if (digitalRead(inPin))" reads the value of inPin and if it is HIGH (non-zero) the condition is true.

Pete
 
Status
Not open for further replies.
Back
Top