Go Down

Topic: wav file playback speed issue (Read 1 time) previous topic - next topic

6v6gt

#15
Sep 04, 2018, 11:17 am Last Edit: Sep 04, 2018, 11:40 am by 6v6gt
I can't say much more on the subject. My experience with ADCs is limited to the AVR 8bit architecture and some external SPI controlled ADCs.

However, it looks like you have to address the issue of audio quality of the raw data before looking at getting the headers right. You can, incidentally, import the raw data, that is without headers, directly into Audacity to check it.

Here is a decsription of the SAMD ADC (as in the Arduino Zero) with the native Atmel code.
http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42109-SAM-Analog-to-Digital-Converter-ADC-Driver_ApplicationNote_AT03243.pdf

The Arduino Zero core has presumably built a layer on top of this code base to abstract it.

There is an example of configuring the ADC to collect a number of samples in a buffer (you appear to want 2048), then initiating a callback routine (see 9.2) which could replace what you are doing in the loop. You should look at something like that seriously because, the way you have structured your code, you appear to be losing samples during the time you are writing to the SD card. @Lucario448 has mentioned this also. Your sampling interval at 18750 sps is about 50 microseconds and your code appears to assume that, in between samples, you can write 2048 bytes to the SD card. You probably would need to switch between two (or more) buffers, so the ADC could fill one during the time you are writing the other to the SD card.

However, you'd have to  convert the example to use the Arduino Zero equivalent statements.

Anyway, good luck with it all.

Lucario448

But later in #5 i uploaded files i recorded on mkr zero as i didnt have playback issue but there was constant background buzz noise.
I'm imagining the Zero can operate the SD card at its maximum clock frequency, so I guess it takes less than 22 microseconds to write blocks of 2 KB? Or there you are sampling at lower frequency; I don't know, didn't checked the other files just yet.

The buzzing sound even I find difficult to get rid off. I know that's called a "ground loop"; and the only fix I think is effective, is by passing the AC input of the power supply through a galvanic isolator (it's just a 1 to 1 AC transformer), instead of plugging it directly into the outlet.
Another way is by completely isolating the system from the AC power, that's by powering it with a battery; although you may not have a very long run before you have to use an AC-powered charger anyway (unless the solar energy or a DC generator is used).
It's important to note that if you have to share ground with a device powered by a non-isolated power supply, you'll end up fixing nothing because that connection will bring back the ground loop as well.



You should look at something like that seriously because, the way you have structured your code, you appear to be losing samples during the time you are writing to the SD card. @Lucario448 has mentioned this also. Your sampling interval at 18750 sps is about 50 microseconds and your code appears to assume that, in between samples, you can write 2048 bytes to the SD card. You probably would need to switch between two (or more) buffers, so the ADC could fill one during the time you are writing the other to the SD card.
Indeed that's the problem, and I'm not the only one who agrees.

It appears whatever microcontroller you were using, consumes CPU time to handle SPI transfers (blocking I/O); either due to lack of DMA or bitbanging (software emulation). I'm also thinking the system's clock frequency isn't high enough to operate the SD card at 20 MHz; or it is but can't go that fast due to bitbanging (lack of hardware SPI controller).

Either way, you have a delay problem (caused by the SD card write process).
If you think about it, sampling data is very time-sensitive; if there was a way to do this always in the exact moment and over anything else... Here's where "timed interrupts" come into place.

Interrupts always have higher priority of execution over the main program; this means sampling will occur even if the main program is stuck writting data to the SD card.
You can figure interrupts as "background programs"; although still is not true multitasking, but in practice it's pretty close.

Since interrupts change the code flow in a "unpredictible" manner, they also suffer the typical problems of the concurrence; specially with shared access. In this punctual case, means it's a bad idea that sampling and SD writting operate over the same buffer.
If saving the samples is slower than getting them, for sure you will end up overwritting unsaved data; and thus losing samples anyway.

Since is not a good idea to make those processes operate on the same buffer, you'll need two. This is the so called "double buffer"; where one works in one buffer, and the other in the second one; alternating buffers when needed, but never working on the same one.
I've also mentioned "triple buffer", this is only necessary if the writting process ends up being even slower than anticipated.
You can think the buffers as a way to compensate for the difference in speed of two processes.

Obviously the downside of this technique is RAM usage. If there's not enough available, you'll only have two options:

  • Deal with such distortion.
  • Decrease the data rate (number of channels and/or sample rate) up to the point where sampling is no longer faster than saving (writting to the SD card).

You should investigate about interrupt capabilities on your microcontroller, along with available timers (aka counters since it's a piece of hardware that counts clock cycles) and the amount of RAM; those are some of the ingredients for a more reliable digital audio recorder recipe.

Go Up