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

Thread: buffer store

  1. #1
    Junior Member
    Join Date
    Apr 2018
    Posts
    15

    buffer store

    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;
          }
        }
        
        
    }}

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    970
    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

  3. #3
    Senior Member
    Join Date
    Nov 2012
    Posts
    970
    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

  4. #4
    Junior Member
    Join Date
    Apr 2018
    Posts
    15
    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.

  5. #5
    Junior Member
    Join Date
    Apr 2018
    Posts
    15
    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!

  6. #6
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,774
    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.

  7. #7
    Junior Member
    Join Date
    Apr 2018
    Posts
    15
    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?

Posting Permissions

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