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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy