Bandpass Filter to SD card

Hello there,

I’m working w/ some other folks here (jcooper, shaneL) on the ASA project. I’m really struggling writing to the SD card after passing audio through a band pass filter I modeled based on the example.

The filter passes audio through to the audio output, but writing to SD card causes errors. Raw audio to SD card works fine.

Here are the patch cords (yes the input is single channel):

AudioConnection_F32       patchCord1(i2s_in, 0, audioEffectBandpassFD, 0);   //connect the Left input to our algorithm
AudioConnection_F32       patchCord2(audioEffectBandpassFD, 0, i2s_out, 0);  //connect the algorithm to the left output
AudioConnection_F32       patchCord3(audioEffectBandpassFD, 0, i2s_out, 1);  //connect the algorithm to the right output
AudioConnection_F32       patchCord4(audioEffectBandpassFD, 0, audioSDWriter, 0); //connect audio to left channel of SD writer
AudioConnection_F32       patchCord5(audioEffectBandpassFD, 0, audioSDWriter, 1); //connect audio to right channel of SD writer

Here’s the error it spits out:

AudioControlAIC3206: Received Error During goToPage(): Error = 4
AudioControlAIC3206: Received Error During writeRegister(): Error = 4
AudioControlAIC3206: Received Error During writeRegister(): Error = 4
AudioControlAIC3206: Received Error During writeRegister(): Error = 4
AudioControlAIC3206: Received Error During writeRegister(): Error = 4
AudioControlAIC3206: Received Error During goToPage(): Error = 4

When I try to activate SD recording it says stuff like this over and over (presumably, each time it services the SD card in a loop):

AudioSDWriter: chan 0, data skip? This ID = 0, Previous ID = 13570355
AudioSDWriter: chan 1, data skip? This ID = 0, Previous ID = 13570355

Any idea what I might be doing wrong?

Thanks.

Oo! Sorry about the trouble! The error messages that you posted makes it look like your problems have nothing to do with filtering or with the SD card. It looks more like a basic problem with the main processor not really being able to talk with the audio chip. Weird. Bummer. I wonder why?

Is there any way that you can share your whole program? Like posting it here? Or sharing a GitHub link?

I wanna help!

Chip

Hi Chip,

I got rid of all my custom mods and only used the lowpass filter in the examples and the provided SD card writer, in case it was my error (still might be!). I get the same error messages.

How’s a pastebin?
Lowpass + SDwrite - Pastebin.com

Note that I commented out the PRINT_OVERRUN_WARNING section for debugging purposes… doesn’t seem to matter either way.

Sorry for the delayed reply…I was on the road. I’m on this now!

I’ve grabbed your code. It references another file “AudioEffectLowpass_FD_F32.h”, which I’m assuming is the same as from the Tympan Library’s example “LowpassFilter_FD”. Is that true? Or did you modify it in some way?

Chip

I’ve recreated your error messages! That means that I can maybe fix it!

OK, I think that I’ve found your problem. In your code, in setup(), you correctly have the line:

myTympan.enable(); // activate AIC

Unfortunately, I think that it comes a bit later than it should. When I move the line earlier, like before your myTympan.inputSelect() lines, the error messages went away:

 //Enable the Tympan to start the audio flowing!
  myTympan.enable(); // activate AIC

  //Choose the desired audio input on the Typman...this will be overridden by the serviceMicDetect() in loop()
  //myTympan.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on-board microphones
  //myTympan.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
  myTympan.inputSelect(TYMPAN_INPUT_JACK_AS_LINEIN); // use the microphone jack - defaults to mic bias OFF

Does that make it work for you?


As an unrelated issue, I see that you’re asking for an FFT size of 512. At the same time, I also see that your audio block size is at 32. I know that this might sound weird, but these two settings do have some interaction. For example, I’ve only ever run the system when the FFT size is 2x or 4x the block size. So, for a block size of 32, I’ve only ever used an FFT size of 64 or 128. It’s possible that 512 will work with a block size of 32, I’m just letting you know that I’ve never tried it myself. You’ll find out!

If you do have trouble, try increasing your block size up to 128. Since 512 / 128 is 4, that means that it is a 4x case, which means that it’ll be more akin to what I myself have used.

Either way, let me know…we want to help it work for you!


I listened to the code using your N=512 along with the audio_block_length being 32. To my ears, it ran fine despite the FFT being 16x the block size. Fantastic! You just did something new!

What I did hear, however, is that the processed audio had a short, but noticeable, delay relative to the original sound. It felt like a slight echo. This kind of latency is one downside of using a long FFT (N=512) with a slow sample rate (16 kHz). At minimum, latency is the FFT length divided by the sampling rate, which in this case is 512/16000 = 32 msec. In reality, the latency will be more than that…possibly up to twice that value.

If you want to reduce the latency, you might consider running at a faster sample rate (24 kHz? 32 kHz? 44.1 kHz?), or using a shorter FFT, or both.

Hi Chip,

Thanks for taking a look. This indeed took care of the first error. Did you try starting the SD recording? After changing the order of the commands still produces a ton of errors like this when you activate the SD recording:

AudioSDWriter: chan 0, data skip? This ID = 0, Previous ID = 13570355 AudioSDWriter: chan 1, data skip? This ID = 0, Previous ID = 13570355 AudioSDWriter: chan 0, data skip? This ID = 0, Previous ID = 13570355 AudioSDWriter: chan 1, data skip? This ID = 0, Previous ID = 13570355

Just for giggles I changed the block size to 128 and I got something slightly different. It repeats this error over and over again with the exact same numbers.

AudioSDWriter: chan 0, data skip? This ID = 9835, Previous ID = 9510
AudioSDWriter: chan 1, data skip? This ID = 9835, Previous ID = 9510
AudioSDWriter: chan 0, data skip? This ID = 9526, Previous ID = 9835
AudioSDWriter: chan 1, data skip? This ID = 9526, Previous ID = 9835
AudioSDWriter: chan 0, data skip? This ID = 9761, Previous ID = 9526
AudioSDWriter: chan 1, data skip? This ID = 9761, Previous ID = 9526
AudioSDWriter: chan 0, data skip? This ID = 9510, Previous ID = 9761
AudioSDWriter: chan 1, data skip? This ID = 9510, Previous ID = 9761

I updated the pastebin… got rid of a couple superfluous things.

I opened up the .wav file and it seems to be mostly okay despite the errors? Maybe a popping noise or two? I haven’t experimented with it too much. So really the worst thing that’s happening is dumping tons of error messages to the serial port. Is there an easy way to suppress those? (short of just commenting it out in the library)?

If you don’t mind I have a couple more questions.

  1. What is the block size (e.g. 128 instead of 32) doing in the library and why would you pick a smaller/larger value? (I was simply fiddling with the knobs, not doing anything intelligent.)

  2. Do you have any good rules of thumb for the AudioMemory setting? When I was fiddling I had to use larger numbers for larger FFTs, but I was wondering if there was any more intelligent way to think about it.

Thanks again!

I do NOT understand why I don’t get email notifications of activity. So annoying! And it leaves you hanging with hot and exciting questions! Sorry!

Regarding the “errors” during SD writing…

  • I wouldn’t characterize them as actual errors, but as opportunities when there might have been an error. It’s actually quite difficult to tell if the SD card itself has hiccupped and caused some audio to be dropped. [If you’re not aware, an SD card is itself a tiny little computer, which can take a non-deterministic amount of time to actually respond to a request for a write. That’s why it’s important to get a good card.] In trying to figure out if audio blocks might be dropped, I kludged together a pretty amateur approach. Clearly, when the “This ID” is stuck at zero, something is amiss with my amateur approach.

  • The second set of errors look somewhat more troubling as those numbers are actually close enough to maybe reflect that audio blocks have been dropped. With the second set of errors, how many errors are you getting (per minute? per 10 minutes?)? Just a handful, or lots and lots and lots? If it’s lots and lots, it’s clearly not capturing dropped audio…I’ll see if I can figure out how to suppress the errors.

  • Regarding the quality of your SD card, did you provide your own SD card, or did we provide you with one? For example, is it a SanDisk Ultra (or SanDisk Extreme) or something else?

As for rules-of-thumb regarding the AudioMemory setting, you need enough so that your algorithm blocks don’t run out. That’s not terribly enlightening, so here are more thoughts:

  • Usually, if I’ve forgotten to allocate enough memroy blocks, the audio sounds horrible (glitchy with breaks and drop outs). If it sounds fine, you’re probably fine.

  • If you want to get quantitative, many of the example Tympan programs have CPU and Memory reporting that show how many of AudioMemory blocks are being used (as well as how much free RAM is available after the audio memory has been allocated). If it reports that you’re using fewer audio memroy blocks than you’ve allocated, you’re good! There’s no need to have more than a handful more than the max that you’re actually using.

  • As an aside, the SDWriter has it’s own buffer of memory to help smooth over the non-deterministic write time. That buffer is separate from the AudioMemory pool (though it should be reflected in making your FreeRAM smaller), so that shouldn’t come into the calculus of what value to use for AudioMemory.

  • If the audio processing blocks were all perfect in their ability to manage and release memroy, and if you weren’t doing FFT processing, you should always be able to get away with less than 10 blocks of AudioMemroy. If you are doing FFT processing, you’ll need more…you’ll need enough AudioMemory to handle the buffering that happens as part of the FFT overlapping. For example, for 50% overlap, you need 2 blocks per left/right channel for buffering. For 75% overlap, you need 4 blocks per channel. For 87.5% overlap you need 8 blocks per channel, etc.

I don’t think that I’ve ever actually needed more than 40 blocks. But, the Teensy 4.1 that is at the heart of your Tympan RevE has so much RAM, that you could easily allocate 150 blocks of AudioMemory and not pinch your RAM usage for other tasks. So, for an embedded processing device (ie, not Matlab on your PC) you have plenty for most anything that you want to do.

Did I address what you asked?

Thanks for sticking with it!

Chip