Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 17 of 17

Thread: audio record, processing and play with teensy 3.1

  1. #1

    audio record, processing and play with teensy 3.1

    Hello everybody,
    I'm going to start a project soon, and after searching around about the hardware to use (arduino, rpy, etc.), I found out about teensy 3.1. It seems very interesting, but I want to be sure that the board meets the requirements of my project.
    In few words, I will need to use a mic and speaker to record sound and play sound. I found this mic, and I'm looking for something similar (in size/cost) for the speaker. I guess I will also need an amplifier for the audio output.

    Here are a couple of questions:
    1) Can I record and play sound at 44.1KHz sampling rate using the ADC and DAC available in Teensy? I know that the available memory might be a limitation, but I do not need to store the recorded audio, just some DSP with it and discarded.

    2) About the output amplifier, I found this Op Amp, or this audio amp. I know they are two different things, but which one do you think might fit better between the teensy internal DAC and a small speaker?

    Thanks for your time, and I hope you can help me with these questions.

    Enrico

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,675
    Quote Originally Posted by saxen View Post
    Here are a couple of questions:
    1) Can I record and play sound at 44.1KHz sampling rate using the ADC and DAC available in Teensy?
    Play, yes.

    Record, maybe, but no such code exists yet, so it's not even 100% certain whether this is possible. If it is, your choices will involve some combination of waiting for the audio library to develop, or writing the code yourself.

    2) About the output amplifier, I found this Op Amp, or this audio amp. I know they are two different things, but which one do you think might fit better between the teensy internal DAC and a small speaker?
    The 3.7W amp is designed to drive a speaker. That little opamp probably isn't capable of powering a speaker.

  3. #3
    Hi Paul,
    thank you for your answers.
    About recording, maybe this was not the right word to use, sorry. What I meant was getting 44100 samples per second from the ADC (analogRead?) and do some processing with them. Basically, something in this direction but with 44.1k sampling rate. So, is this possible?

    Thanks,
    Enrico
    Last edited by saxen; 02-03-2014 at 06:48 PM.

  4. #4
    It is possbile to get the output what you want easily . Please refer to below calculations:
    You require a sampling rate of 44100 samples per second that means a conversion time of 1/44100 = 22.67 Usec.
    But the conversion rate that teensy3.1 controller offers is much fast almost 11 times faster.
    You Just need to choose the configuration carefuly.
    For details please refer to the datasheet of the teensy3.1 microcontroller.
    I have pasted a screenshot of the same below :
    Click image for larger version. 

Name:	conversion time.PNG 
Views:	671 
Size:	131.6 KB 
ID:	1377

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,675
    Quote Originally Posted by saxen View Post
    What I meant was getting 44100 samples per second from the ADC (analogRead?) and do some processing with them.
    Yes. In fact, the audio library already has an object for the ADC input. So far, it's a little light on the "do some processing" part. There's a FFT object that sort-of works. You can certainly feed the audio through the mixer with other sources and output it. Eventually the library will get many more objects that do analysis on the sound.

  6. #6
    Junior Member
    Join Date
    Mar 2014
    Posts
    5

    audio record, processing and play with teensy 3.1

    Quote Originally Posted by PaulStoffregen View Post
    So far, it's a little light on the "do some processing" part. There's a FFT object that sort-of works. You can certainly feed the audio through the mixer with other sources and output it. Eventually the library will get many more objects that do analysis on the sound.
    Until here, I thought I understood everything. :-)

    I want to build a guitar effects pedal with the Teensy (something like the pedalshield http://www.electrosmash.com/pedalshield or the stompshield http://www.openmusiclabs.com/projects/stomp-shield/). And my assumption was/is that I could use their arduino sketches already because the teensy is fully compatible. Can you point me to the error in my theory? Thanks a lot!

  7. #7
    Hi Eggsperde,
    Stomppedal code for the arduino wont work straightaway on Teensy3.0/3.1.. it is not the same kind of chip, and many registers are hard coded to get stuff like freerunning adc's and more going on the small AVR chips
    .. But my guess is, that the Teensy3.1 will quickly be adapted by the stompbox freaks.. you dont even need the audioshield for fullspeed 12-bit playback! Just use a timer to get a stable samplefrequency, read 1 or more adc's (you can use standard calls to start with, they are fast enough on Teensy 3.
    I've measured standard analogRead() performance yesterday, and calculated performance for it, I switchd resolution easily with analogReadRes();
    Conversion times with analogRead()
    16bit 11.8 uS
    10bit 8,6 us
    8bit 4.2 uS

    So if you were to sample with 60khz ( which could also be 2 channels of 30 khz ofcourse..)
    16bit: 60k*11,8us= 708mS -> ~30% free for processing
    10bit: 60k*8,6us= 516mS -> ~50% free for processing
    8bit: 60k*4,2= 258mS -> ~75% free for processing

    So, actually it is a piece of cake to make a (multichannel in, mono out) stompbox with 10 or 8 bit with pure a teensy3.1, for real 16 stereo bit i'd advise to go for the audioshield plus audio library. nobody has build a stompbox with it sofar as far as I know, but hey.. maybe you are the first..




    Quote Originally Posted by eggsperde View Post
    Until here, I thought I understood everything. :-)

    I want to build a guitar effects pedal with the Teensy (something like the pedalshield http://www.electrosmash.com/pedalshield or the stompshield http://www.openmusiclabs.com/projects/stomp-shield/). And my assumption was/is that I could use their arduino sketches already because the teensy is fully compatible. Can you point me to the error in my theory? Thanks a lot!

  8. #8
    Junior Member
    Join Date
    Mar 2014
    Posts
    5

    audio record, processing and play with teensy 3.1

    Hi Paul,

    I read very positive things about the Teensy project in general and your communication in special. Great to see you live and in action! :-)

    Since I am a rather new citizen in the microcontroller world, I will just order a Teensy for playing around with buttons and LEDs and wait for the
    stompbox freaks
    to make the
    piece of cake
    slightly easier to digest. You calculations definitely give hope to well-sounding results. Thank you very much for your reply; I will come back in due time.

    All the best!!!

  9. #9
    Eggsperde, don't mix the great Paul Stoffregen up with humble me! I'm PaulD, and I will post a working stompbox code this weekend for Teensy3.1, it is testproject for me, so it is no extra work.
    Wishing you also the best, nevertheless! ")

  10. #10
    Junior Member
    Join Date
    Mar 2014
    Posts
    5
    Oh no, how embarrassing... and on the internet.... forever... .plus being officially guilty of thread-hijacking. Sorry for the confusion, Paul!

    Do you plan publishing your efforts with the Guitar-Teensy? I am absolutely interested in seeing your ideas materialize in the very first implementation.

    Cheers,
    Frank

  11. #11
    haha Eggsperde,
    I've got the code running, with synchronized background adc function, using Pedvides adc library: https://github.com/pedvide/ADC
    You can choose resolution and sampleRate you want, lowering sampleRate will give you more cpu time, ofcourse..
    I havent tested it with actual guitar yet, but hey, it runs, gives vital information about performance over serial, so you can tweak it fast.
    Have fun!
    -You'll have to connect your guitar to A0 via C and dividernetwork. protective Diodes strongly recommended!
    -output A14 via C

    Code:
    /*
    ---------------------------------------------------------------
     C r u d e   S t o m p b o x   w i t h   T e e n s y   3 . 1 
    ---------------------------------------------------------------
    Version 0.1  "Fuzzzzyy.."
    Paul Driessen - 27 March 2014
    ADC library used https://github.com/pedvide/ADC
    
    This code represents the shortes way a sample can travel through a Teensy 3.1.
    It uses Pedvide's ADC lib, for the benefit of adc usage in the background, the standard Arduino calls dont support that ( why not? )
    Once setup correctly, the audiolatency of this code is 2 samples.
    
    Features:
    -low latency 2 sample latency throughput, output 12 bits via internal ADC
    -A serial performance indicator will show you how much CPU you have left for coding cool stuff.
    -An example fuzz routine with simple LP filter
    
    Connections needed:
    Input circuitry:
    [TODO] ** OWN RISK **
    
    Output circuitry:
    -A condensator on pin A14
    
    */
    
    #include <ADC.h>
    
    ADC adc; // adc object
    
    int rawAudioIn; 
    int dcAudio;
    int audioIn;
    int audioOut;
    int sampleRate;
    int microsPerSample;
    elapsedMicros microCount;
    elapsedMillis updateDisplay;
    int accu=0;
    
    void setup()
    {                
      Serial.begin(38400);
      delay(1000);
      adc.setAveraging(1);                   // where not into astrophysics here, no averaging required
      adc.setResolution(16);                 // valid resolutions for singelended adc like this are 8, 10, 12 or 16 bit.
                                             // each resolution comes with it own max speed.  
                                             // Note: 16 bit will distort the output easy, I've added no conversion between bit depth buildin ( but it's easy: code it yourself!)
      sampleRate=50000 ;                    // requested samplerate, will result however in 1 uS steppable frequencies!
      microsPerSample= 1000000/sampleRate;   // thats how we keep pace
      
      analogWriteResolution(12);             // max resolution on the output
      
      for(int t=0; t<40000; t++)
      {
        accu  += adc.analogRead(A0);          // get the dc level.. 
      }
      dcAudio = accu / 40000;
      
      adc.enableInterrupts();
      adc.startSingleRead(A0);                //get the systems started,
      //adc.startContinuous (A0);
      while(!adc.isComplete()) {};   //gets the first rawAudio..
      microCount=0;
    }
    
    volatile byte readySample=0;
    int adcUsage=0;
    int originalAudio;
    void loop()                     
    {
      audioIn += (rawAudioIn - dcAudio);             // get rid of DC values the easiest way.. 
      readySample=0; //reset flag
      adc.startSingleRead(A0);                       // prepare the sample for next 
      originalAudio=audioIn;
      //rawAudioIn= adc.analogReadContinuous (); 
      analogWrite(A14, (audioOut+2048));             // 1uS: write the value from previous calculation
      //
      //  
      // S T A R T   O F  C O D I N G   A R E A  ( you'll have about 80% power at your dispo @ 44,1k )
      //
      // Let's try a fuzz to start with..
      int posTreshold=50;      //higher than this will be set to Outlevel
      int negTreshold=-50;     //lower  than this will be set to -1* Outlevel
      int outLevel=1000;       // 
      int IR_filter=8;         // LP: the higher the number, the more the squarewave becomes smooth
      if(audioIn>posTreshold)
      { 
          audioIn=outLevel;    
      }else{
         if(audioIn<negTreshold)
          { 
              audioIn=-1*outLevel; 
          }else{
              audioIn=0; // dead silence below treshold, typicall for fuzz..
          }  
      }  
      // now apply a simple IR filter, to smooth the edges (LP)
      audioIn = audioOut + ( (audioIn - (audioOut)) / IR_filter );
     // Output is ready, copy it to the output.
      audioOut =  audioIn; // 
      
      //  
      // E N D   O F  C O D I N G   A R E A  
      //
      
      // Display Performance in %
      int MC= microCount;
      int Performance= (MC*100)/(microsPerSample);
      int actFramerate =(1000000/microsPerSample);
      if(updateDisplay>1000)
      {
        Serial.println("");
        Serial.print("Time between samples:");
        Serial.println(microsPerSample);
        Serial.print("Real samplerate:");
        Serial.print(actFramerate);    
        Serial.println(" uS"); 
        Serial.print("CPU usage:");
        Serial.print(Performance);
        Serial.println("%"); 
        Serial.print("ADC usage:");
        Serial.print((adcUsage*100)/(microsPerSample));
        Serial.println("% "); 
        Serial.print("originalAudio:");
        Serial.println(originalAudio);
         Serial.print("audioOut:");
        Serial.println(audioOut);
        updateDisplay=0;
      }  
      while(microCount<microsPerSample){}     // fill our timing budget
    
      microCount-=microsPerSample;            // keep pace 
    }
    
    void adc0_isr(void) {
        // Low-level code
        rawAudioIn=ADC0_RA;
        //GPIOC_PTOR = 1<<5; */
        readySample=1;
        adcUsage=microCount;
    }

  12. #12
    Junior Member
    Join Date
    Mar 2014
    Posts
    5
    Hi Paul, now thats a lot of awesomeness for one post! :-)

    Thanks a lot for the code and the additional hints! With them the list of ingredients for this project is complete... your support is highly appreciated!

    Have a good one,
    Frank

  13. #13
    thanks Frank,
    today I will test the simplest bufferamp for it, with the least amount of components, it would be nice if the buffer ran on 3volts, that would automatically protect the input, and no divider needed that way if you use the a special trick a friend showed me. I'll keep you posted!

    For the trick read this:
    https://wiki.analog.com/university/c...tronics-lab-20
    Last edited by PaulD; 03-30-2014 at 11:45 AM.

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,675
    You certainly can build your own sampling code, but the audio library already has this implemented with very efficient DMA transfers. The DMA engine automatically moves the samples 44100 times per second, so only a single interrupt is generated when a buffer fills. That leaves far more CPU time available for implementing your effects.

    The audio library is still very beta status, but the inputs and outputs work quite well. El Supremo contributed a few effect objects, like chorus and flanging, which could be really useful for a guitar peddle.

    Of course, you can write your own effect objects. Here's a page with details.

    http://www.pjrc.com/teensy/td_libs_AudioNewObjects.html

    Basically, you just copy the template and write your own update() function that processes each block of 128 audio samples. Use those functions documented on that page and your effect object will integrate nicely with the rest of the audio library.

    The beauty of using the audio library, aside from the already-working efficient input/output, is your effect object will be able to receive input and send output to any other objects. So your effect could run together with chorus and flange, with all 3 running simultaneously, and them perhaps feed those 3 to a mixer object, which then drives the output object.

    If you later decide you also need to add a filter before or after your effect, it's extremely easy. Just create another object in your sketch, and different connection objects to route the audio between them. The library lets you very easily build complex audio processing systems, because everything is interoperable with the connection objects to hook the audio streams together between them in any way you need.

    The audio library takes care of everything in the background. Your object would also do all its work in the background, every time the library calls its update() function to process another 128 samples.

    With all the audio processing happening in the background, your Arduino sketch can do things like adjust your object's parameters or the mixer gains (for more/less chorus, more/less flange, more/less of whatever your custom effect does, etc).

    Even though the audio library is still considered beta, and APIs might change before 1.0 release, it already has a lot of excellent infrastructure and interchangeable input and output objects (very easy to upgrade from built-in 12 bit DAC to 16 bit I2S for a higher quality audio DAC) that can really help for a guitar peddle project.
    Last edited by PaulStoffregen; 03-31-2014 at 07:57 PM.

  15. #15
    Your right! But I just wanted to present a simular "crude" approach as some AVR guitar peddles, I know audiolibrary is better for sound and versatility. The only thing my example does better is latency, and the freedom to choose any samplerate/bitdepth you want, on the fly.. and yes: having no buffer makes it extremely inefficient to make calls to routines, I know..

  16. #16
    Junior Member
    Join Date
    Mar 2014
    Posts
    5
    Hi PaulD, the link to the Analog Devices wiki is great - I "wasted" 2h there already today. :-)

    It throws me a bit back again on the other hand, because now I am not sure which op amp to take. Originally I wanted to buy this amp http://fredsamplifiers.com.au/index....products_id=83 and use one output for the link to the Teensy and one for headphones (clean sound and no delay). The battery is a bit of a turn-off on the other hand and your suggestion looks somewhat simpler... Guess I have to keep reading. Not the worst thing to do. ;-)

  17. #17
    Senior Member
    Join Date
    Feb 2013
    Posts
    178
    Not to hijack, and I have no plans for an audio effects device, but I know MaxMSP can export it's "Gen" level code to a C++ file. I wonder how difficult it would be to prototype effects in MaxMSP->Gen, and then take that code and implement it on a Teensy 3.1. If it could be made relatively painless, it would be a HUGE boon to the Max community.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •