How to get audio output from dac pins on T3.5/3.6?

Status
Not open for further replies.
I found a French YouTube video that shows the DAC and ground going to a powered speaker (with a 10 µF cap between the DAC and the + speaker line in), so I guess I'll try that with this little Sparkfun amp and hope I don't fry something.
 
This Sparkfun amp has two input pins. Connect the + pin to A14/DAC. Connect the - pin to AGND. It will also work if you connect - signal to GND, but best to use AGND.

This amp has DC blocking capacitors built in, so you don't need to add any extra capacitors on the signal lines. That is needed with some amplifiers, but not this one.

Connect the amp's Power - pin to Teensy GND, and its Power + and S pins together, and connect that pair to Teensy VIN.
 
Hi Paul:

Thanks so much for the clarification; I appreciate your help. I hope you can take a few minutes to clear up two more quick questions regarding what I hope to accomplish.

My plan is to transpose the approach/sketch you show in Part_2_03_Samples of your Audio tutorial to my needs. I'd convert my two sound effects (maybe 5 seconds each) to sketch objects (using wav2sketch) to play them from memory through the DAC depending on which button is being triggered (sound plays while button is pressed, stops when released).

Two questions:

1. On the DAC object in the Audio Design Tool I'm seeing:

analogReference(ref);
Configure output voltage range:
INTERNAL selects 1.2 volt peak-to-peak output.
EXTERNAL selects 3.3 volt peak-to-peak output.

Is this something I need to worry about?

2. If I hold down my button for 15 seconds will this Part_2_03_Samples sketch I'm adapting loop my 5-second sound effect as long as the button is pressed, or will I get silence after the effect has played once? I want the sound effect to play and loop for as long as I'm triggering the button.

Best.

Shawn
 
Hi Paul:

Thanks so much for the clarification; I appreciate your help. I hope you can take a few minutes to clear up two more quick questions regarding what I hope to accomplish.

My plan is to transpose the approach/sketch you show in Part_2_03_Samples of your Audio tutorial to my needs. I'd convert my two sound effects (maybe 5 seconds each) to sketch objects (using wav2sketch) to play them from memory through the DAC depending on which button is being triggered (sound plays while button is pressed, stops when released).

Two questions:

1. On the DAC object in the Audio Design Tool I'm seeing:

analogReference(ref);
Configure output voltage range:
INTERNAL selects 1.2 volt peak-to-peak output.
EXTERNAL selects 3.3 volt peak-to-peak output.

Is this something I need to worry about?

2. If I hold down my button for 15 seconds will this Part_2_03_Samples sketch I'm adapting loop my 5-second sound effect as long as the button is pressed, or will I get silence after the effect has played once? I want the sound effect to play and loop for as long as I'm triggering the button.

Best.

Shawn

1) use INTERNAL
2) It plays the sample once. Just try it first this way, with the sketch as it is. You can change this behaviour later (we will help you).
 
Thanks for the help, Frank. I'll work to get the bulk of this all working and check back for info about how to make the SFX loop.

Best.

Shawn
 
Hi there... Is there an example of a really basic way to play a wav file from teensy 3.5 built in sd card reader? Sorry, but I'm a total noob at this and the examples at the library use external spi sd card
 
Look at File > Examples > Audio > WavFilePlayer. The default is using the audio shield, but in the comments you'll find this:

Code:
//   3: Analog DAC - Connect the DAC pin to an amplified speaker
//         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// To configure the output type, first uncomment one of the three
// output objects.  If not using the audio shield, comment out
// the sgtl5000_1 lines in setup(), so it does not wait forever
// trying to configure the SGTL5000 codec chip.

It's really that easy. Just replace the output object which sends to the I2S pins with the one that sends to the analog DAC pin, and delete the unused control object for the audio shield.

The audio library is designed to be extremely flexible. Even though the tutorial shows using the audio shield, if you read the tutorial PDF or watch the video (part 2-1 shows how to use the design tool, and the many parts following show how to do more and more with it), hopefully you'll get the idea that this library has tons of features you can connect together in the design tool. There are several output objects available to be able to send the sound to different types of pins and chips. All you need to do is use this capability. It really does work well.
 
Hi, Thank you for the reply Paul, but I was more referring on how to use the built in SD card reader with Audio Library. Since on the example you mention, it is using SD card with SPI connection. Should I comment all the SPI command in it?
 
To use T3.5/T3.6 microSD slot, try using this for SD.begin()
if (!(SD.begin(BUILTIN_SDCARD))) {
 
Making my sound effects loop?

Following up on my post from 2/22, I was able to convert two 5-second sound effect clips (edited to be loopable, mono 22.1K .wav files) to sketch files using wav2sketch (thanks to Paul's new step-by-step instructions) and incorporate them into the Sample Player example sketch. I used the Audio Design Tool to feed the two sketch clips into a mixer and output that to the DAC. The resulting sketch uses 94% of my Teensy 3.2 flash memory, which is fine for now.

Here's the sketch I'm currently using. I commented out much of the previous code, using it to help me correctly set up the new stuff.

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h>

#include <AudioSamplePke_fast_loop_22k.h>
#include <AudioSamplePke_slow_loop_22k.h>

// WAV files converted to code by wav2sketch
//#include "AudioSampleSnare.h"        // http://www.freesound.org/people/KEVOY/sounds/82583/
//#include "AudioSampleTomtom.h"       // http://www.freesound.org/people/zgump/sounds/86334/
//#include "AudioSampleHihat.h"        // http://www.freesound.org/people/mhc/sounds/102790/
//#include "AudioSampleKick.h"         // http://www.freesound.org/people/DWSD/sounds/171104/
//#include "AudioSampleGong.h"         // http://www.freesound.org/people/juskiddink/sounds/86773/
//#include "AudioSampleCashregister.h" // http://www.freesound.org/people/kiddpark/sounds/201159/

// GUItool: begin automatically generated code
AudioPlayMemory          playMem1;       //xy=349,634
AudioPlayMemory          playMem2;       //xy=349,701
AudioMixer4              mixer1;         //xy=625,691
AudioOutputAnalog        dac1;           //xy=841,722
AudioConnection          patchCord1(playMem1, 0, mixer1, 0);
AudioConnection          patchCord2(playMem2, 0, mixer1, 1);
AudioConnection          patchCord3(mixer1, dac1);
// GUItool: end automatically generated code

// Create the Audio components.  These should be created in the
// order data flows, inputs/sources -> processing -> outputs
//
//AudioPlayMemory    sound0;
//AudioPlayMemory    sound1;  // six memory players, so we can play
//AudioPlayMemory    sound2;  // all six sounds simultaneously
//AudioPlayMemory    sound3;
//AudioPlayMemory    sound4;
//AudioPlayMemory    sound5;
//AudioMixer4        mix1;    // two 4-channel mixers are needed in
//AudioMixer4        mix2;    // tandem to combine 6 audio sources
//AudioOutputI2S     headphones;
//AudioOutputAnalog  dac;     // play to both I2S audio board and on-chip DAC

// Create Audio connections between the components
//
//AudioConnection c1(sound0, 0, mix1, 0);
//AudioConnection c2(sound1, 0, mix1, 1);
//AudioConnection c3(sound2, 0, mix1, 2);
//AudioConnection c4(sound3, 0, mix1, 3);
//AudioConnection c5(mix1, 0, mix2, 0);   // output of mix1 into 1st input on mix2
//AudioConnection c6(sound4, 0, mix2, 1);
//AudioConnection c7(sound5, 0, mix2, 2);
//AudioConnection c8(mix2, 0, headphones, 0);
//AudioConnection c9(mix2, 0, headphones, 1);
//AudioConnection c10(mix2, 0, dac, 0);

// Create an object to control the audio shield.
// 
//AudioControlSGTL5000 audioShield;

// Bounce objects to read six pushbuttons (pins 0-5)
//
Bounce button0 = Bounce(0, 5);
Bounce button1 = Bounce(1, 5);  // 5 ms debounce time
//Bounce button2 = Bounce(2, 5);
//Bounce button3 = Bounce(3, 5);
//Bounce button4 = Bounce(4, 5);
//Bounce button5 = Bounce(5, 5);


void setup() {
  // Configure the pushbutton pins for pullups.
  // Each button should connect from the pin to GND.
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  //pinMode(2, INPUT_PULLUP);
  //pinMode(3, INPUT_PULLUP);
  //pinMode(4, INPUT_PULLUP);
  //pinMode(5, INPUT_PULLUP);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(10);

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

  // by default the Teensy 3.1 DAC uses 3.3Vp-p output
  // if your 3.3V power has noise, switching to the
  // internal 1.2V reference can give you a clean signal
  //dac.analogReference(INTERNAL);

  // reduce the gain on mixer channels, so more than 1
  // sound can play simultaneously without clipping
  mixer1.gain(0, 2);
  mixer1.gain(1, 2);
  //mix1.gain(2, 1);
  //mix1.gain(3, 1);
  //mix2.gain(1, 1);
  //mix2.gain(2, 1);
}

void loop() {
  // Update all the button objects
  button0.update();
  button1.update();
  //button2.update();
  //button3.update();
  //button4.update();
  //button5.update();

  // When the buttons are pressed, just start a sound playing.
  // The audio library will play each sound through the mixers
  // so any combination can play simultaneously.
  //
  if (button0.fallingEdge()) {
    playMem1.play(AudioSamplePke_fast_loop_22k);
  }
  if (button1.fallingEdge()) {
    playMem2.play(AudioSamplePke_slow_loop_22k);
  }
  

}

Everything is working on my prototype, so the next order of business is to design a way to make each sound effect clip loop (or restart) as long as its corresponding button is pressed. Simply put, as long as button 1 is pressed sound effect 1 plays. If button 1 is held down longer than 5 seconds sound effect 1 loops (or restarts once it reaches the end of the clip). If button 1 is released the sound effect stops playing. Same deal for button 2/sound effect 2. There should not be a circumstance where both buttons are pressed at the same time.

Any suggestions on what the best approach would be to accomplish this? I've had success modifying example sketches for my purposes; I don't currently have the skill set to create something totally from scratch. I'm wondering whether subtracting the positionMillis from the lengthMillis would be one way to tell the clip to jump back to the beginning. I'm also seeing a Retrigger sketch in the Bounce2 examples that could be applicable, though I'm having trouble following its logic.

Thanks.

Shawn
 
Last edited:
You could add a variable to remember if the sample was previously playing. Then call the isPlaying() function to check if it's still playing. In the case where it was and now is not, read the button. If the button is still pressed, call the play() function to start it over again. Of course, always update the variable every time loop runs.

The main thing you want to avoid is adding delay() in your loop function. Delays work if you do one simple thing. But for reading 2 or more buttons and managing 2 sounds, structure your code to avoid delays.
 
Thanks for providing some direction. I'll have to study up or look for a sketch that uses a similar concept that I can adapt. Or ask a friend.

I do know NOT to use delays. The sketch I've created for my LED chase does not use delay.

Best.

Shawn
 
Simply put, as long as button 1 is pressed sound effect 1 plays. If button 1 is held down longer than 5 seconds sound effect 1 loops (or restarts once it reaches the end of the clip). If button 1 is released the sound effect stops playing. Same deal for button 2/sound effect 2. There should not be a circumstance where both buttons are pressed at the same time.

Hm, I'm not sure that I understand you correctly, so please excuse my question (and often my English leaves me...)
"As long as button 1 is pressed sound effect 1 plays". Ok, but hat includes the 5 seconds of your second sentence?
"If button 1 is held down longer than 5 seconds sound effect 1 loops". Is that correct ? That would mean, you can omit any timer, because sentence 1 already includes this. And because the sounds stops anyway if btton 1 is released.

Is this correct ? If yes, there are only minor changes to your sketch needed.
Hm, but, really, best would be to learn a bit C :) Copy&Paste does not help you...

Edit: Any chance that you can upload the sounds ?
Or, at best your complete project as zipfile (including the
AudioSamplePke_fast_loop_22k.h and AudioSamplePke_slow_loop_22k.h files)
Would make it easier to help you.

 
Last edited:
Frank:

In its most simplest form, when button 1 is pressed sound 1 plays continuously, no matter whether the button is pressed for 1 second or 30 seconds. When button 1 is released sound 1 stops immediately.

My sound files are 5 seconds long. So if the button is held for longer than 5 seconds I need a way to make the sound restart from the beginning. If the button is held down for less than 5 seconds the sound has to stop before the whole clip plays.

Does that make sense?

I've attached a zipped folder containing the sketches of my sound files.

Thanks for looking into this; I appreciate it.

Shawn
 

Attachments

  • PKELoopSketches.zip
    279.5 KB · Views: 72
Ok, great,
if not somebody else is faster, I'll help you tomorrow evening - it's now 23.15 here, a bit too late :)
And i just found some Barcardi, Coke, & Ice in the fridge...
 
Ok, great,
if not somebody else is faster, I'll help you tomorrow evening - it's now 23.15 here, a bit too late :)
And i just found some Barcardi, Coke, & Ice in the fridge...

No big rush on my end. Enjoy your rum and Coke and get some sleep.

Best.

Shawn
 
FYI, the sounds I'm incorporating into my prop are a sort of electronic static/grinding sound heard with the PKE meter in Ghostbusters. This YouTube video shows my first attempt with the sounds playing from an SD card in the audio shield:

https://youtu.be/Fg0gXjYlqFQ
 
Like this ?
Code:
void loop() {
  // Update all the button objects
  button0.update();
  button1.update();

  if (button0.read() == 0) {                          //Button 0 pressed:
    playMem2.stop();                                  //Stop playing sound 2
    if (!playMem1.isPlaying()) {                      //If not playing sound 1, 
      playMem1.play(AudioSamplePke_fast_loop_22k);    //Start sound 1
    }
  } else {                                            //Button 0 NOT pressed:

    playMem1.stop();                                  //Stop playing sound 1
    if (button1.read() == 0) {                        //Button 1 pressed:
      if (!playMem2.isPlaying()) {                    //if not playing sound 2  
        playMem2.play(AudioSamplePke_slow_loop_22k);  //start sound 2
      }
    } else {
      playMem2.stop();                                //Button 1 not pressed -> stop sound 2
    }
  }
}
 
Like this ?
Code:
void loop() {
  // Update all the button objects
  button0.update();
  button1.update();

  if (button0.read() == 0) {                          //Button 0 pressed:
    playMem2.stop();                                  //Stop playing sound 2
    if (!playMem1.isPlaying()) {                      //If not playing sound 1, 
      playMem1.play(AudioSamplePke_fast_loop_22k);    //Start sound 1
    }
  } else {                                            //Button 0 NOT pressed:

    playMem1.stop();                                  //Stop playing sound 1
    if (button1.read() == 0) {                        //Button 1 pressed:
      if (!playMem2.isPlaying()) {                    //if not playing sound 2  
        playMem2.play(AudioSamplePke_slow_loop_22k);  //start sound 2
      }
    } else {
      playMem2.stop();                                //Button 1 not pressed -> stop sound 2
    }
  }
}

Thanks so much for taking the time to write this out; I greatly appreciate it. I think this makes sense, but I'm still pretty inexperienced with the coding language and syntax, so I'm going to have to spend some time breaking it down to understand what it's doing. I have a few friends nearby who know the C language very well, so they could probably talk me through the aspects I don't understand. I'd rather not just copy and paste the code into my sketch and leave it at that; I'd like to understand what it's doing to some extent.

Cheers.

Shawn
 
It was fun :)
I hope it does what you want.

Frank.

Just curious, how long did it take you to work this out? I see that you're a senior member here, so I assume you have years of experience doing this.

I do computer animation as a profession and have been doing that for around 20 years, with 15 years of television production experience before that. I rely on software created by others to do my work.

I took a Fortran class at the University of Arizona around 1980; it didn't stick. I still remember taking my punchcards to the big computer lab and loading them into those giant, very noisy card readers.

Best.

Shawn
 
Hi Shawn,
some minutes, maybe ten incl. a short test?
Wow, computer animation is very interesting, but I do not know much about it. I'm only playing with the displays on the Teensy. And in the 90's I wrote some "graphic demos" for the C64. My first computer was a ZX81 - I got it from my parents to my 13th birthday.
images
Later, I had the chance work with one of these little thingies: https://en.wikipedia.org/wiki/CDC_Cyber and i learned some other programming languages. Today my main job are databases and web..
 
Hi Shawn,
some minutes, maybe ten incl. a short test?
Wow, computer animation is very interesting, but I do not know much about it. I'm only playing with the displays on the Teensy. And in the 90's I wrote some "graphic demos" for the C64. My first computer was a ZX81 - I got it from my parents to my 13th birthday.
images
Later, I had the chance work with one of these little thingies: https://en.wikipedia.org/wiki/CDC_Cyber and i learned some other programming languages. Today my main job are databases and web..

Very nice. I never really got into the nuts and bolts of programming. My grandfather gave me a subscription to Byte magazine in the late 70s and early 80s, and I never knew what to make of it. I ended up majoring in Radio and Television with a Bachelor's degree in Fine Arts. My first real computer was a Mac IIci which my wife and I bought in the early 90s. After working in local TV for around 20 years we started our own small animation business in 2000. I use off-the-shelf software: Cinema 4D (from Maxon, based in Germany) for 3D animation, Adobe After Effects for motion graphics and compositing. I'll occasionally have to cobble up some scripting to automate certain tasks in these programs, though I often rely on the help of others to point me in the right direction. I'd love to educate myself more in regards to electronics and programming, but running our business and keeping up-to-date with new software tools takes up almost all of my available brain capacity.

Here's a short reel of our work:

http://marshall-arts.net

It's mostly corporate and commercial stuff. It's not super-compelling, but it's a lot better than working at a TV station and cranking out Murder maps. We get a cool, fun project like a documentary now and then.

I have a client call in 8 minutes.

Thanks again. I'll try out this sketch later today. I'm excited that I might be in the home stretch of finishing this prop I've been working on for over 20 years.

Shawn
 
I came in here with a very similar question.

I'll be joining a Teensy-based project soon. I'm an electronics noob, but I'll be doing the software/DSP development. To already get started I'd like to create a most minimal setup that would allow me to do some testing...

Is the following layout a correct interpretation of the above posts?

teensy layout.png
 
Status
Not open for further replies.
Back
Top