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

Thread: Direct audio samples into Audio Library objects

  1. #1
    Senior Member
    Join Date
    Apr 2014
    Posts
    347

    Direct audio samples into Audio Library objects

    I can use the audio library to play sounds, waveforms etc and all works very well, but is there a way to directly input the samples from a sound array or waveform and play continuous at various speeds or data rates.
    I can do similar using and interval timer to analogwrite(A14, data) each data sample and I hear the sound as a complete sound waveform all samples. but have no other functions from the library.??
    When using the audio library, it uses DSP, phase accum. etc so all samples for the complete wave are not read for all frequencies of playing. eg to get 2x speed out half of the samples are read and values interpolated.
    I was wondering how I could read the data in as input and the use the rest of the library functions, filters, mixer etc on the data once inputted.

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,691
    The AudioPlayQueue object is used to "play" 128 samples at a time.

    Pete

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Posts
    347
    Thanks for reply, I had looked at this, but basically I don't know how or cannot get the "getBuffer()" to look at the data, It compiles outputs just random noise.???
    attached is my basic code after reading through the VideoSDcard example.

    Code:
    include <Audio.h>
    //#include <Wire.h>
    //#include <SPI.h>
    //#include <SD.h>
    //#include <SerialFlash.h>
    
    //#include <OctoWS2811.h>
    
    // GUItool: begin automatically generated code
    AudioPlayQueue           audio;         //xy=270,355
    AudioOutputAnalog        dac1;           //xy=645,351
    AudioConnection          patchCord1(audio, dac1);
    // GUItool: end automatically generated code
    
    
    int16_t  samples[128] = {
    0,
    1'
    2,
    3'
    up to
    127.....(this is array of 128 values range -30000. 0. +30000)
    };
    
    
    void setup() {
    
       AudioMemory(40);
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
              int16_t *p = audio.getBuffer();
             
              audio.playBuffer();
        
    }

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,691
    getBuffer returns NULL if a buffer isn't available. Try this:
    Code:
              int16_t *p = audio.getBuffer();
             
              if(p)audio.playBuffer();
    EDIT. AND you need to copy the samples into the buffer:

    Code:
              int16_t *p = audio.getBuffer();
              
              if(p) {
                for(int i = 0;i < 128;i++) {
                  *p++ = samples[i];
                }
                audio.playBuffer();
              }
    Pete

  5. #5
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,691
    I posted a (fairly) simple example of using readBuffer/freeBuffer and getBuffer/Playbuffer here which might help you. It simply reads the stereo input (MIC or LINEIN) and plays it back to the headphone output. If a button is pushed it switches the left and right channels.

    Pete

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Posts
    347
    Thanks for your fast response, I am replying to your post #4....That is magic it works perfectly...thats the basics, will need to play with it to get different rates of playing sorted etc and controlled by timers etc so as rate not affected by what else the processor is doing. I will take a look at your #5 post tomorrow. is there any good bedtime reading on this stuff.??? Thanks

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Posts
    347
    Looked at your sketch for recording and playing queues. I think I understand what it does recording mic or linein in a queue for each channel and allowing it to be switched and played etc.
    As I see it instead of recording I want to play an already recorded array at various rates to give me different frequency as the rate is changed. Does playBuffer always play at same rate 44100 as audio library or can it be changed on demand.?? I get the "for next loop" working OK and it plays the 128 sample wave perfect no glitches......
    Last edited by Teenfor3; 07-11-2020 at 12:48 PM. Reason: removed this bit < 128 is OK........I notice it needs 0 to128 and not 0 to 127..?? why.? If I use 0 to 127 I get a glitch.

  8. #8
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,691
    The default sample rate is 44100Hz. You can change that rate at startup but I don't think you can change it on the fly and AFAIK you can only change it to a small range of frequencies (e.g. 8kHz, 11025Hz, 48kHz).
    I think what you're trying to do is pitch shifting which is a non-trivial problem.

    Pete

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Posts
    347
    Yes, it is probably pitch shifting. playing wave array at various freqs and mixing and filtering.
    Code:
    const int16_t tone1[256] = {
    0,
    628,
    1256,
    
    256 element array
    
    -1884,
    -1256,
    -629
    };
    
    
    
    
    
    const int16_t tone2[256] = {
    0,
    20872,
    25928,
    
    256 element array
    
    25583,
    -25929,
    -20872
    };
    
    
    
        
    // Create IntervalTimer objects 
    IntervalTimer myTimer;
    IntervalTimer myTimer2;
    IntervalTimer myTimer3;
    
    
    int16_t dat1 = 0;
    int16_t dat2 = 0;
    int16_t cpdat = 0;
    int samp = 0;
    int samp2 = 0;
    int onoff = 0;
    int freq = 3;
    int freq2 = 3;
    
    void setup() {
      
     analogWriteResolution(12);
     analogReference(INTERNAL);
    
    }
    
    void play1(){
      dat1 = ((tone1[samp]+30000)/20);  // stream 1st wave repeating
      samp = samp + 1;
      if (samp > 255) {
        samp = 0;
      }
      return;
    }
    
    void play2(){
      dat2 = ((tone2[samp2]+30000)/20);  // stream 2nd wave repeating
      samp2 = samp2 + 1;
      if (samp2 > 255) {
        samp2 = 0;
      }
      return;
    }
    
    void playout(){
      cpdat = ((dat1 + dat2)/2);  // mix both streamed samples
       analogWrite(A14, cpdat); //play out to DAC
      return;
    }
    
     void Controlonoff() {
          
        if (onoff == 0 && freq >= 15)
           {
          myTimer.end();     // turn timers off 
          myTimer2.end();
          myTimer3.end();
           }
        
            delay(100);
            
        if (onoff == 1)
        {
          freq = freq + 1;       //start timers at new freq
          freq2 = freq2 + 1;
                    
          myTimer.begin(play1, freq);  
          myTimer2.begin(play2, freq2);  
          myTimer3.begin(playout, 22.6756);  // output at 44100
       
     delay(200);
        
          freq = freq + 1;
          freq2 = freq2 + 1;             // timer period update to change freq
            myTimer.update(freq);
            myTimer2.update(freq2);
        if (freq >= 20) freq = 2;
        if (freq2 >= 20) freq2 = 5;
        }
    
     }
    
    
       void loop() {    // start of loop xxxxxxxxxxxxxxxxxxxxxx
               onoff = !onoff;
        delay(200);
        Controlonoff();
        }            // end of loop ........   xxxxxxxxxxxxxxxx
    This is outline of what I had been trying. It plays the audio arrays and mixes them and ends up with playing out to DAC. I could probably send the output cpdat instead via a queue to the audio library....???... will maybe try that next few days...

Posting Permissions

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