Audio Library

Status
Not open for further replies.
Using edit feature of Audio Library

To All,

I have started using the Audio System Design tool.

I have tried editing a few items to give them a specific name. I double click the item and then fill in the desired specific name and then hit enter. The name of the items remains as the system generated name such as i2s1 or i2s2.

I will appreciate any help in how to use the design tool to edit an item's name.

Regards,

Charley
 
To All,

I have started using the Audio System Design tool.

I have tried editing a few items to give them a specific name. I double click the item and then fill in the desired specific name and then hit enter. The name of the items remains as the system generated name such as i2s1 or i2s2.

I will appreciate any help in how to use the design tool to edit an item's name.

Regards,

Charley

Yeah there are some bugs in there. I just change them in the generated code later. :)
 
quick question: Is it technically possible for teensy 3.1 equipped with the audio shield and appropriate sd card, to play a .raw file off the card while it records a different raw file to the card? My idea is that I could record to one file while the other file is playing to create continuous playback of samples, though no matter how i write the file juggling code, nothing seems to work. Is this technically possible but my code is wonky or is this technically impossible right now?
 
I would say the answer, if you have a really good SD card, is a very definite "maybe".

The main trouble is writing to the card sometimes takes more than 2.9 ms or 5.8 ms, with some cards. Maybe. The Recorder example (File > Examples > Audio > Recorder) has a couple commented lines to report the time it waited for the card to write a sector. You can uncomment those lines to see how your card is performing.

The audio library updates every 2.9 ms, to process another 128 samples at 44.1 kHz. When playing mono, a 512 byte sector will be read every other update. When playing in stereo, 512 bytes is needed on every update.

So the real question is whether your card will always complete writing before the next read is needed.

Something the audio library does not do, which could really help, is read ahead on the playing objects. Currently, the SD library doesn't have a way to really report the true status of the SD card, which would be needed for such an object to know whether it should attempt to read ahead because the card is idle, or switch to consuming its buffered data because the card is busy. I recently started a complete rewrite of the SD library to add multiple sector caching and a design to support multiple simultaneous access.... but it's still needing quite a lot of work before it can support this sort of usage.

So that's where we're at today. If you have a really good card that can complete all writes in 2.9 ms, or 5.8 ms (and you arrange things so reading happens just before writing on the same update, to give the write the full 5.8 ms) then you could probably get this to work. But if your card takes too long to write, the lack of extra buffering and card status awareness on the reading side will result in choppy playback during those updates where the card is busy writing.
 
I would say the answer, if you have a really good SD card, is a very definite "maybe".

The main trouble is writing to the card sometimes takes more than 2.9 ms or 5.8 ms, with some cards.

My last tests, a cuple of weeks ago showed 2-3ms, but more than 30ms at 8KB intervalls of written data. Perhaps because of wear-leveling ? I don't know. Another reason could have been the library which tried to occupy a new sector or whatever.
 
Last edited:
ahhhh OK. Thanks for explaining that Paul!
though I bet it could be done with 2 teensies and sgt15000_1s (communicating via Wire or Wire2) running in tandem
 
Hi

I have connected the hydrophone to the pre amplifier which is connected to the line in port in the Audio board
My objective is to "RECORD" underwater sound and record as WAV files in the SD card
Pls help me in changing the RECORDER EXAMPLE codes...I intend not to use buttons

// 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
//
// Three pushbuttons need to be connected:
// Record Button: pin 0 to GND
// Stop Button: pin 1 to GND
// Play Button: pin 2 to GND
//
// 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
AudioInputI2S i2s2; //xy=105,63
AudioAnalyzePeak peak1; //xy=278,108
AudioRecordQueue queue1; //xy=281,63
AudioPlaySdRaw playRaw1; //xy=302,157
AudioOutputI2S i2s1; //xy=470,120
AudioConnection patchCord1(i2s2, 0, queue1, 0);
AudioConnection patchCord2(i2s2, 0, peak1, 0);
AudioConnection patchCord3(playRaw1, 0, i2s1, 0);
AudioConnection patchCord4(playRaw1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=265,212
// GUItool: end automatically generated code

// Bounce objects to easily and reliably read the buttons
Bounce buttonRecord = Bounce(0, 8);
Bounce buttonStop = Bounce(1, 8); // 8 = 8 ms debounce time
Bounce buttonPlay = Bounce(2, 8);


// which input on the audio shield will be used?
const int myInput = AUDIO_INPUT_LINEIN;
//const int myInput = AUDIO_INPUT_MIC;

// Remember which mode we're doing
int mode = 1; // 0=stopped, 1=recording, 2=playing

// The file where data is recorded
File frec;

void setup() {
// Configure the pushbutton pins
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);

// Audio connections require memory, and the record queue
// uses this memory to buffer incoming audio.
AudioMemory(60);

// Enable the audio shield, select input, and enable output
sgtl5000_1.enable();
sgtl5000_1.inputSelect(myInput);
sgtl5000_1.volume(0.5);

// Initialize the SD card
SPI.setMOSI(7);
SPI.setSCK(14);
if (!(SD.begin(10))) {
// stop here if no SD card, but print a message
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
}


void loop() {
// First, read the buttons
buttonRecord.update();
buttonStop.update();
buttonPlay.update();

// Respond to button presses
if (buttonRecord.fallingEdge()) {
Serial.println("Record Button Press");
if (mode == 2) stopPlaying();
if (mode == 0) startRecording();
}
if (buttonStop.fallingEdge()) {
Serial.println("Stop Button Press");
if (mode == 1) stopRecording();
if (mode == 2) stopPlaying();
}
if (buttonPlay.fallingEdge()) {
Serial.println("Play Button Press");
if (mode == 1) stopRecording();
if (mode == 0) startPlaying();
}

// If we're playing or recording, carry on...
if (mode == 1) {
continueRecording();
}
if (mode == 2) {
continuePlaying();
}

// when using a microphone, continuously adjust gain
if (myInput == AUDIO_INPUT_MIC) adjustMicLevel();
}


void startRecording() {
Serial.println("startRecording");
if (SD.exists("RECORD.RAW")) {
// The SD library writes new data to the end of the
// file, so to start a new recording, the old file
// must be deleted before new data is written.
SD.remove("RECORD.RAW");
}
frec = SD.open("RECORD.RAW", FILE_WRITE);
if (frec) {
queue1.begin();
mode = 1;
}
}

void continueRecording() {
if (queue1.available() >= 2) {
byte buffer[512];
// Fetch 2 blocks from the audio library and copy
// into a 512 byte buffer. The Arduino SD library
// is most efficient when full 512 byte sector size
// writes are used.
memcpy(buffer, queue1.readBuffer(), 256);
queue1.freeBuffer();
memcpy(buffer+256, queue1.readBuffer(), 256);
queue1.freeBuffer();
// write all 512 bytes to the SD card
elapsedMicros usec = 0;
frec.write(buffer, 512);
// Uncomment these lines to see how long SD writes
// are taking. A pair of audio blocks arrives every
// 5802 microseconds, so hopefully most of the writes
// take well under 5802 us. Some will take more, as
// the SD library also must write to the FAT tables
// and the SD card controller manages media erase and
// wear leveling. The queue1 object can buffer
// approximately 301700 us of audio, to allow time
// for occasional high SD card latency, as long as
// the average write time is under 5802 us.
//Serial.print("SD write, us=");
//Serial.println(usec);
}
}

void stopRecording() {
Serial.println("stopRecording");
queue1.end();
if (mode == 1) {
while (queue1.available() > 0) {
frec.write((byte*)queue1.readBuffer(), 256);
queue1.freeBuffer();
}
frec.close();
}
mode = 0;
}


void startPlaying() {
Serial.println("startPlaying");
playRaw1.play("RECORD.RAW");
mode = 2;
}

void continuePlaying() {
if (!playRaw1.isPlaying()) {
playRaw1.stop();
mode = 0;
}
}

void stopPlaying() {
Serial.println("stopPlaying");
if (mode == 2) playRaw1.stop();
mode = 0;
}

void adjustMicLevel() {
// TODO: read the peak1 object and adjust sgtl5000_1.micGain()
// if anyone gets this working, please submit a github pull request :)
}
 
Yes, but the hydrophone setup will be mounted on a quadcopter and will be floating on water

So is there any way of doing it??

I have used only the 'R' and 'G' in the Line In of the Audio board
 
Hi

Recording and storing audio files as WAV files
I do not need the stop, play option
1) Extending this old thread is probably harmless but things like this would benefit more from a thread of their very own, or tacking onto an extremely similar thread; like the last two you have made fairly strongly connected to this.

2) If you do not wish to use buttons that is fine but if you do not know how to use what you wish to use instead then you will have to tell us what you want to use; there are logical choices as to what to use but iterating through them all and trying to present decent help for each one would be a lot of work where you could just cut us to the chase...


How do you wish to control the recording? Do you want it to just start recording when powered up and continue till record medium is full? Do you want to signal it via serial? Are you going to control it wirelessly?
 
Has anyone experience with the audio board from the teensy and how to use the auto gain control of the sgtl5000? I used audiopreprocessorenable() and autovolumecontrol() and autovolumeenable() in setup with hopefully correct parameters, but I can't recognize any difference when I adjust the volume of my audio source. Any suggestions? Or examples? Thanks
 
The auto levelling control has a unique response.

I found it a little buggy, and only certain settings would work properly and not in the same way you would expect equivalent gain controls from other solutions to work. It was also possible to crash the gain controller with certain settings.

Look in the bitcrusher example for more info and example working code.

https://github.com/Pensive/Audio/blob/master/examples/Effects/Bitcrusher/Bitcrusher.ino

Code:
/ Initialise the AutoVolumeLeveller
  audioShield.autoVolumeControl(1, 1, 0, -6, 40, 20); // **BUG** with a max gain of 0, turning the AVC off leaves a hung AVC problem where the attack seems to hang in a loop. with it set 1 or 2, this does not occur.
  audioShield.autoVolumeDisable(); //or Enable, if you want to turn it on :)
  audioShield.audioPostProcessorEnable();
 
Last edited:
Thanks Pensive for your fast answer. I hope that I have understand it, so the agc only controls the output of the audio board and holds the volume on the same level!? But I want to do this with the Input. Is there any chance to do that? In my project I have a line Input which has different volume levels, but I want to make a FFT which should bring nearly everytime the same output. Any suggestions how to do that? Thanks
 
A soft compressor is currently not available but is certainly on my list of essential addons the library needs.

I'm sure it's simple enough to implement but I can't help on how to do that right now, much as it has piqued my interest.

The same module could be used in an advanced mixer block to balance input levels to reference RMS before applying output gain, which is another function on the massive list of nice-to-haves.

But I don't know how you can achieve that today, sorry.
 
Sorry I've confused you.

The mixer won't do it out of the box but perhaps you could use fft to monitor the input signal and fill a buffer of X sample volume levels.

Take an average every Y milliseconds and use it to adjust mixer gain?

You would need to apply some smoothing too but it is achievable.

Edit: come to think of it, you could probably skip the fft and just work on full range samples, or put it through a filter instead.
 
Last edited:
sd_T3 LIBRARY
/* Why reinvent the SD library wheel...
* 1: Allow reading files from within interrupts
* 2: Cache more than one sector for improved performance
* 3: General optimization for 32 bit ARM on Teensy 3.x &

I have been using the above library for a while now in our product in development. On rare occasion, we lose audio, but the main code will continue to run. It is a difficult bug to replicate, but typically it occurs when there are many sounds playing at a time, while opening and closing very quickly. I suspect it is an SD card error. I imagine there is an easy way to re-initialize the SD card while running the main code, without a full reboot. Does anyone know how to do this? It won't solve the problem, but is a good band-aid for now.
 
I actually just last night started looking into a cache management bug in that code. Yesterday I found a test case that reliably reproduces the bug, so I'll probably have a fix soonish...

Very difficult to say if that bug is responsible for the problems you're seeing.
 
Status
Not open for further replies.
Back
Top