Is there a way to increase the audio lib buffer?

Status
Not open for further replies.

alrj

Well-known member
I would really love to be able to add some buffer in the audio library to prevent pops and clicks. if i have a couple of wavs playing then i get pops and clicks when i open envelopes. its fine with just one wav playing. is there a way to do this? I realise it would be at the expense of latency.

I have had a look at AudioPlayMemory and AudioRecordMemory but presumably the library has its own buffer, is it possible to adjust this?

regards,
Al.
 
it makes more memory available but doesn't fill it with buffer which is what i would like to do : )
 
@alrj can you post some sample code that reproduces your problem, it makes it a lot easier to help that way, cheer Paul
 
So this code shows part of the problem. triggering the sample that is already playing should result in a click but there is a bit of distortion in there as well that you can "tune" by adjusting the AUDIO_BLOCK_SAMPLES. the smaller number the higher pitched the artifact. this makes it impossible to trigger a wav that is already playing from the start, i have similar issues triggering a wav straight after one has just finished.
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlaySdWav           playSdWav1;     //xy=314,214
AudioOutputI2S           i2s1;           //xy=587,192
AudioConnection          patchCord1(playSdWav1, 0, i2s1, 0);
AudioConnection          patchCord2(playSdWav1, 1, i2s1, 1);
// GUItool: end automatically generated code



// Use these with the Teensy Audio Shield
//#define SDCARD_CS_PIN    10
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14

// Use these with the Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13
int inByte = 0;
byte  newDATAin = 1;


void setup() {
  Serial.begin(115200);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(100);


  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }   
}

void loop() {
   
  
   
switch (Serial.read()) {

            
      
   case 's': {
    Serial.println("s");
   // envelope1.noteOff();
   // envelope2.noteOff();
   playSdWav1.stop();
   //playSdWav2.stop();
   //playSdWav3.stop();
   //playSdWav4.stop();
//   playSdWav5.stop();
  // playSdWav6.stop();
 //  playSdWav7.stop();
 //  playSdWav8.stop();

 
   
 }
 break;

 case 't': {

  playSdWav1.play("10BAB1.WAV");

 delay(5);

 // playSdWav2.play("10BAB2.WAV");
  
  //playSdWav3.play("10BAB3.WAV");
  //playSdWav4.play("10BAB4.WAV"); 

 }
 break;

   
}
}

Here are the wav files for the test...
http://donjohnstonmusic.co.uk/tr/sinewavs.zip

Here is what the click should sound like without the artefact..
https://soundcloud.com/donjohnston/sinecut/s-S49FSTnUxvs

I get similar artefacts trying to launch several wavs at the same time, or actuating an envelope on a wav with more than 2 other wavs playing.

Regards,
Al.
 
Last edited:
I think I just need a way to buffer the audio but as wavs only play at realtime I am not sure how to go about it. I was hoping to increase AUDIO_BLOCK_SAMPLES to make the lib more robust to clicks as the latency is super low anyway i would happily swap some latency to get rid of these artefacts.
 
Last edited:
No issues with SD read speed...

Code:
SD Card Test
------------
SD card is connected :-)
Card type is SDHC
File system space is 63848.94 Mbytes.
SD library is able to access the filesystem
Unable to find SDTEST1.WAV on this card
[Disconnected]
[Connected]
SD Card Test
------------
SD card is connected :-)
Card type is SDHC
File system space is 63848.94 Mbytes.
SD library is able to access the filesystem

Reading SDTEST1.WAV:
  Overall speed = 1.73 Mbyte/sec
  Worst block time = 0.55 ms
    18.85% of audio frame time

Reading SDTEST1.WAV & SDTEST2.WAV:
  Overall speed = 1.85 Mbyte/sec
  Worst block time = 0.59 ms
    20.34% of audio frame time

Reading SDTEST1.WAV & SDTEST2.WAV staggered:
  Overall speed = 1.85 Mbyte/sec
  Worst block time = 0.59 ms
    20.30% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV:
  Overall speed = 1.89 Mbyte/sec
  Worst block time = 0.85 ms
    29.19% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV staggered:
  Overall speed = 1.89 Mbyte/sec
  Worst block time = 0.85 ms
    29.23% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV, SDTEST4.WAV:
  Overall speed = 1.91 Mbyte/sec
  Worst block time = 1.60 ms
    55.32% of audio frame time

Reading SDTEST1.WAV, SDTEST2.WAV, SDTEST3.WAV, SDTEST4.WAV staggered:
  Overall speed = 1.91 Mbyte/sec
  Worst block time = 1.36 ms
    46.81% of audio frame time
 
This demonstrates the issue even more clearly. 4 WAVs launched at the same time creates the drop out i am talking about if you trigger it a couple of times..

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

// GUItool: begin automatically generated code
AudioPlaySdWav           playSdWav2;     //xy=411,434
AudioPlaySdWav           playSdWav3;     //xy=428,498
AudioPlaySdWav           playSdWav1;     //xy=439,351
AudioPlaySdWav           playSdWav4;     //xy=460,575
AudioOutputI2S           i2s1;           //xy=712,329
AudioConnection          patchCord1(playSdWav1, 0, i2s1, 0);
AudioConnection          patchCord2(playSdWav1, 1, i2s1, 1);
// GUItool: end automatically generated code



// Use these with the Teensy Audio Shield
//#define SDCARD_CS_PIN    10
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14

// Use these with the Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13
int inByte = 0;
byte  newDATAin = 1;


void setup() {
  Serial.begin(115200);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(100);


  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }   
}

void loop() {
   
  
   
switch (Serial.read()) {

            
      
   case 's': {
    Serial.println("s");
   // envelope1.noteOff();
   // envelope2.noteOff();tttttttttttt
   playSdWav1.stop();
   playSdWav2.stop();
   playSdWav3.stop();
   playSdWav4.stop();
   //playSdWav5.stop();
   //playSdWav6.stop();
   //playSdWav7.stop();
   //playSdWav8.stop();

 
   
 }
 break;

 case 't': {

  playSdWav1.play("10BAB1.WAV");

 delay(5);

  playSdWav2.play("10BAB2.WAV");
  
  playSdWav3.play("10BAB3.WAV");
  playSdWav4.play("10BAB4.WAV"); 

 }
 break;

   
}
}
 
The problem is with the SDCard FAT library. It is quite inefficient in how it reads blocks, and how it scans directories for files.
If you can add a multi-threaded runtime into the Teensy runtime, and let it run at a lower priority than the main Teensy loop, then you could do this without more buffering.
Another option would be to copy the code for the SDCard FAT reader, and write your own, that's either more efficient, or splits the work into multiple iterations using a state machine approach.
 
That is great info thank you. I have been working through this with a friend who is a much better programmer than me and he said a similar thing about having a multi-threaded runtime. I wouldn't be able to implement that but he can for sure.

I managed to get the teensy to compile with the Bill's SDfat.h and using that all the pops and clicks were gone but every time audio was triggered the system would hang and you would loose control for up to 4 seconds. I might go back down this route and post in the SDfat thread to see if anyone has a solution.
 
Status
Not open for further replies.
Back
Top