buffer store

Status
Not open for further replies.

chandrian

Member
Hello all,

I am trying to copy audio inputs from a mic into a buffer that I can use to play the same set of audio over and over. The way I have the code now is to rewrite the audio once it is played back but once I get it working I will write to the buffer only when instructed to.

in addition, If someone could add some insight as to how the timing works to play the audio at the right pace
and why the most efficient size to copy is 256,
and where this code and the "delay" effect stores its recording, id be grateful

I was able to read and play from a small buffer with this technique, but the more I added, the more choppy the output was and then the output and eventually was incomprehensible.
The delay effect is able to play back most of a seconds worth of audio and that is all I will need in the end, so I am wondering where the library differs from my code. I realize it uses a head and tail setup but it seems similar in the sense of writing the same amount of data.


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

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=77,57
AudioRecordQueue         queue2;         //xy=208,57
AudioPlayQueue           queue1;         //xy=327,55
AudioOutputI2S           i2s2;           //xy=459,52
AudioConnection          patchCord1(i2s1, 0, queue2, 0);
AudioConnection          patchCord2(queue1, 0, i2s2, 0);
AudioControlSGTL5000     sgtl5000_1;     //xy=446,103
// GUItool: end automatically generated code

//uint16_t buffer[512];
uint8_t Counter = 0;
uint8_t Counter2 = 0;
uint16_t buff[20000];
  
void setup(){
  
  AudioMemory(64);
  sgtl5000_1.enable();
  sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
  sgtl5000_1.volume(0.7);
  sgtl5000_1.lineInLevel(0);
  sgtl5000_1.lineOutLevel(13);
  queue2.begin();
}

void loop(){
  //delay(1000);
  if(queue2.available() >= 2){ //input buffer

    if(Counter <=78) //read packets into buffer
    {
      memcpy(buff + Counter, queue2.readBuffer(), 256);
      queue2.freeBuffer();
      Counter++;          
    }
    else //copy all packets to output buff
    {
      if(Counter2 <=78)
      {
      memcpy(queue2.readBuffer(), queue2.readBuffer(), 256);
      queue2.freeBuffer();
      
      int16_t *outBuf = queue1.getBuffer();
      memcpy(outBuf, buff + Counter2, 256);
      queue1.playBuffer();
      Counter2++;
      }
      else
      {
        Counter2 = 0;
        Counter = 0;
      }
    }
    
    
}}
 
There are a few errors in your code.
Code:
  if(queue2.available() >= 2){ //input buffer
This does not process the first buffer until the second one has been read. You only process one buffer at a time so it doesn't make sense to delay handling of a buffer. Change this to >= 1



Code:
      memcpy(buff + Counter, queue2.readBuffer(), 256);
This will copy the first buffer starting at buff[0], the second buffer will be written starting at buff[1] and so on. So, you're overwriting most of one buffer with the content of the next one. I think what you need here is
Code:
      memcpy(buff + Counter*256, queue2.readBuffer(), 256);



Code:
      memcpy(queue2.readBuffer(), queue2.readBuffer(), 256);
      queue2.freeBuffer();
I don't understand what this is trying to achieve but I'm pretty sure it is wrong.
It appears to read two buffers, copy the second one into the first, and then free only the second one. This is going to cause buffering problems within the audio library. I think you need to remove the memcpy altogether leaving only the queue2.freeBuffer (which will require that you use "<= 1" in the if statement).



Code:
      memcpy(outBuf, buff + Counter2, 256);
This should be
Code:
      memcpy(outBuf, buff + Counter2*256, 256);

Pete
 
Correction. I've just noticed that you declared buff to be uint16_t. Change it to "uint8_t buff[40000]" so that the addressing (count*256) works out properly.

Pete
 
Thanks for the quick and thorough response Pete. I still have to implement the changes and I did have Counter*256 but I will try it again and report back.
 
Hello,

Your code suggestions were great and it is working as expected now. I have a new problem now that I have run into before but ignored, but it needs to be taken care of.

I am repeating the recorded buffer over and over and each time it restarts i hear a clicking noise; something about the transition. Do you have any insight about this?

Thanks again!
 
Sure - if the last value has - for example a value "200", and the first value is 0, the step is too large and you hear a click.
There is some filtering needed.
 
Thank you for the response. I assumed this were the case but I dont know really how to fix this. Do i take a manual approach like taking the last value of the last buffer and doing an average or use a filter class that Paul has written?
 
Status
Not open for further replies.
Back
Top