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

Thread: Recording audio to buffer

  1. #1

    Recording audio to buffer

    I am having trouble with recording an analog microphones output to a byte buffer. Right now I am not using the audio adapter board, but trying to use pin 14 (A0) as an analog input. This is a modified version of the audio board recorder example.

    Code:
    #include "Bounce.h"
    #include "Audio.h"
    #include "Wire.h"
    #include "SPI.h"
    #include "SD.h"
    
    // GUItool: begin automatically generated code
    AudioInputAnalog         analogPinInput(14);
    AudioRecordQueue         queue1;
    AudioConnection          patchCord1(analogPinInput, queue1);
    
    const int nbyte = 128;
    
    const int naudiomem = 12;
    
    float y[4411];
    
    void setup() {
    
      // Audio connections require memory, and the record queue
      // uses this memory to buffer incoming audio.
      AudioMemory(naudiomem);
    
      Serial.begin(9600);
      
      delay(1000);
      
      Serial.println("STARTING");
    }
    
    
    void loop() {
      
      queue1.begin();
      elapsedMicros timerec;
      
      while (timerec < 100000) {
        
      }
      queue1.end();
      Serial.print("Elapsed usec: ");
      Serial.println(timerec);
      
      int npac = queue1.available();
      
      Serial.print("Available Packets in Queue: ");
      Serial.println(npac);
      Serial.println(npac*nbyte);
      
      byte buffer[npac*nbyte];
    
      for (int k1=0; k1<naudiomem; k1++) {
        memcpy(buffer + k1*nbyte, queue1.readBuffer(), nbyte);
        queue1.freeBuffer();
      }
      queue1.clear();
      
      Serial.print("Buffer contents: ");
      for (int k1=0; k1<50; k1++) {
        Serial.print(buffer[k1]);
        Serial.print(" ");
      }
      Serial.println();
        
      delay(5000);
      
    }
    An example of the output is:
    Elapsed usec: 100004
    Available Packets in Queue: 34
    4352
    Buffer contents: 223 46 223 46 223 46 223 46 223 46 223 46 223 46 223 46 223

    I am not sure what the buffer contents mean, if anything. The buffer contents do change with voltage, but always have a repeating pattern as such.
    1. Is the audio board required to acheive 44100 Hz sampling?
    2. Am I going about storing the samples in a queue and then reading them post sampling in the right manner?

  2. #2
    Senior Member
    Join Date
    Nov 2013
    Posts
    720
    1). No. But sample rate is closer to 44117 either way with this library.
    2). Sort of close but at least a little off...


    I think you will be better off using the Library's default input pin by invoking AudioInputAnalog without specifying a pin; use the default input pin: A2/16

    Your nbyte figure is wrong, it needs to be 256 bytes to cover 128 samples of 16 bits each. Your memcpy line may look better to me if nbyte is doubled as needed.

    You cannot see the actual values because you are reading data that is 16 bit signed integer as if it is 8 bit unsigned integer. I cannot think right now if it is big endian or little endian but "223 46 223 46 223 46 223 46 ...." suggests to me that you had a steady (pretty much DC) voltage going to the pin you were reading; it is either (int16_t)((223*256)+46) or (int16_t((46*256)+223) pretty much constantly and either way it indicates a DC bias on the pin which is undesirable.


    If this wasn't helpful please just say so

  3. #3
    Thanks robsoles, that is helpful. I changed the byte size to 256.

    I could not find if the 16 bit of the audio is unsigned or signed. From your response it seems to be signed. With this I changed my code and the output makes much more sense now.

    Code:
    // Record sound as raw data to a SD card, and play it back.
    //
    // Requires the audio shield:
    //   http://www.pjrc.com/store/teensy3_audio.html
    //
    // This example code is in the public domain.
    
    #include "Bounce.h"
    #include "Audio.h"
    #include "Wire.h"
    #include "SPI.h"
    #include "SD.h"
    
    // GUItool: begin automatically generated code
    AudioInputAnalog         adc1;
    AudioRecordQueue         queue1;
    AudioConnection          patchCord1(adc1, queue1);
    
    float y[4411];
    
    const int nbyte = 256;
    
    void setup() {
    
      // Audio connections require memory, and the record queue
      // uses this memory to buffer incoming audio.
      AudioMemory(60);
    
      Serial.begin(9600);
      
      delay(1000);
      
      Serial.println("STARTING");
    }
    
    
    void loop() {
      
      Serial.println("\nNEW RECORDING CYCLE");
      
      queue1.begin();
      elapsedMicros rectime;
      
      while (rectime < 100000) {
        
      }
      queue1.end();
      Serial.println(rectime);
      
      int npac = queue1.available();  
      Serial.println(npac);
        
      if (queue1.available() >= 2) {
        byte buffer[512];
        memcpy(buffer, queue1.readBuffer(), 256);
        queue1.freeBuffer();
        memcpy(buffer+256, queue1.readBuffer(), 256);
        queue1.freeBuffer();
        
        //Serial.println();
        for (int k1=0; k1<16-1; k1+=2) {
          Serial.print(buffer[k1]);
          Serial.print(" ");
          Serial.print(buffer[k1+1]);
          Serial.print(" | ");
          //Serial.print(buffer[k1+1]);
        }
        Serial.println();
        
        Serial.println("BIG ENDIAN: ");
        Serial.print("16 bit int: ");
        for (int k1=0; k1<512-1; k1+=2) {
          Serial.print(256*buffer[k1] + buffer[k1+1]);
          Serial.print(" | ");
        }
        Serial.println();
        
        Serial.print("2s complement: ");
        for (int k1=0; k1<512-1; k1+=2) {
          long val = 256*buffer[k1] + buffer[k1+1]; 
          if (val > 32767) {
            val = - (65536 - val);
          }
          Serial.print(val);
          Serial.print(" | ");
        }
        Serial.println();
      
        Serial.println("LITTLE ENDIAN: ");
        Serial.print("16 bit int: ");
        for (int k1=0; k1<512-1; k1+=2) {
          Serial.print(256*buffer[k1+1] + buffer[k1]);
          Serial.print(" | ");
        }
        Serial.println();
          
        Serial.print("2s complement: ");
        for (int k1=0; k1<512-1; k1+=2) {
          long val = 256*buffer[k1+1] + buffer[k1]; 
          if (val > 32767) {
            val = - (65536 - val);
          }
          Serial.print(val);
          Serial.print(" | ");
        }
        Serial.println();
        
        queue1.clear();
      }
        
      delay(15*1000);
      
    }
    The output is now as such with the input connected to AGND, and the little endian numbers make sense to me

    NEW RECORDING CYCLE
    100000
    35
    3 0 | 6 0 | 251 255 | 4 0 | 16 0 | 4 0 | 13 0 | 0 0 |
    BIG ENDIAN:
    16 bit int: 768 | 1536 | 64511 | 1024 | 4096 | 1024 | 3328 | 0 |
    2s complement: 768 | 1536 | -1025 | 1024 | 4096 | 1024 | 3328 | 0 |
    LITTLE ENDIAN:
    16 bit int: 3 | 6 | 65531 | 4 | 16 | 4 | 13 | 0 |
    2s complement: 3 | 6 | -5 | 4 | 16 | 4 | 13 | 0 |

Posting Permissions

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