Go Down

Topic: Timers for audio (Read 1 time) previous topic - next topic

Hi,
I'll try to explain my problem the best I can.

I'm doing an audio sampler with Arduino Due.
I made a loop with a timer interrupt running 44000 times per second to generate my sound.
I load a buffer with an other timer. When I'm doing short computations, it's ok. But when I do long computations, like reading an SD card, the first timer is lacking. As if it is waiting the second timer to end its operation.
When I load the buffer in the main loop(), it seems to work, but I don't want to do it here.

I tried different timers on different TC (there are 9), but it's always the same problem.
So, I guess that timers are not independant, unlike the loop() function, which is decorrelated to other timers (computations made in one timer slow other timers) ? Or can it be an other problem ? Is there an option to put in the declaration of the timers which can make them independant from the others ?

I coded the timers like it was discussed in this topic :
http://arduino.cc/forum/index.php?topic=130423.0

Thanks in avance,

GaƩtan
Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

fungus

The Arduino only has 16 million CPU cycles in a second.

44000 interrupts per second, plus reading an SD card...it's probably asking too much. Interrupts have a lot of CPU overhead.
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Yes, I'm asking a lot to the arduino, but what i don't understand it's that it works with the main loop function, but not with timers. I tooth that the main loop was a timer interrupt like others...
Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

billroy

The loop() function is not called on a timer interrupt; it's called from a C loop in the invisible main() function.

Because loop() can be interrupted, it loses time.  Be aware you will probably find there are jitter artifacts on your data sampled in loop().

-br

Ok thanks, it explains why the comportment is not the same between loop() and timers.
So about I want to do :

1. Using loop()

loop()
{
  read SD card
  fill the buffer
}

timer1_handler (44100 Hz)
{
  read the buffer
}

2. Using timer

timer2_handler() (45 Hz)
{
  read SD card (1024 samples at a time)
  fill the buffer
}

timer1_handler(44000 Hz)
{
  read the buffer
}

Using loop() in solution 1 is too unstable because I can't determine the loop frequency.
Using timer2 in solution 2 can't be done because the time used to read SD card cause lacking in the timer 1.

Is there an other solution ? It must be, because I know it's possible to read mp3 on SD cards with some shields. I didn't manage  to analyse the codes to find the solution. I use SDFatLib, but didn't find the solution inside.
If someone already did audio stream, let me know !
Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

fungus


Using loop() in solution 1 is too unstable because I can't determine the loop frequency.
Using timer2 in solution 2 can't be done because the time used to read SD card cause lacking in the timer 1.


It may be that interrupts are automatically when the chip goes to timer2_handler()

Try adding "sei();" inside timer2_handler()


Is there an other solution ? It must be, because I know it's possible to read mp3 on SD cards with some shields.


mp3 data is a lot smaller than uncompressed 44kHz audio.
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Thanks for the answer. I tried using sei() function, but my Due doesn't recognize it (function unknown). Maybe this function is just for Uno or Mega ?
I will have to find an equivalence.

About the mp3, indeed there is 10 times less information per second than wave, but it must be uncompressed, and it's a costly operation.
When I look at some projects about streaming audio data, it seems that it's always buffered in the loop() section. Maybe I will have to do this, because, as Billroy said, it's a C loop, not an interrupted loop.

If someone already made audio streaming, and already thought about this, I will be thankful if he shares his knowledge...
Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

DuaneB

for cli and sei you should use nointerrupts and interrupts instead, these globally disable or enable interrupts and are available on all Arduino platforms

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

fungus


Thanks for the answer. I tried using sei() function, but my Due doesn't recognize it (function unknown). Maybe this function is just for Uno or Mega ?


Maybe it's Arduino IDE 1.0 only.

Try "interrupts();" instead.


About the mp3, indeed there is 10 times less information per second than wave, but it must be uncompressed, and it's a costly operation.


Yes, but the Arduino isn't decompressing it, the special chip on the mp3 shield is. All the Arduino does is transport the compressed data to the shield.
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Ok, thanks guys. That is what I was looking for, but it doesn't work for buffering. In fact, I think buffering has to be in the main loop. So I cleaned the code (I had some delay instructions), and now it works very well. I can read at least 4 different samples from sd card in the same time.

@duane : that's who wrote a lot of messages in your blog. My project of groovebox is nearly finished.

Thanks.
Build a groove box with Arduino Due :
http://groovuino.blogspot.com/

Go Up