I2S example code

Post your cool example code here.
madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: I2S example code

Post by madias » Tue Sep 08, 2015 2:52 pm

I've done a little benchmark with different buffer sizes (with low level pin manipulation):
On a buffer 256 I have
2459us IDLE time
214,8us IRQ
= 8.034% CPU time

On a buffer 16:
153,6 IDLE
13,5us IRQ
= 8.079% CPU time

So the match winner is: Buffer 16 with better audio quality :)
So in this calculation it's not important how the CPU time for pin manipulation is, because it's about the relationship between the results. So the main CPU time is calculating the real time audio itself.
Strange thing: (I suspect it, must check it again): On a PIC32MX250 @68MHZ nearly the same code (but without DMA for I2s!) is faster.

So in my final code I suspect to need 10-12% CPU cycle time for each oscillator, so all in all about 40-50% of CPU time, but I need TFT, encoders-knobs-buttons, (USB) MIDI, and more permanent calculations (not on a high frequency as the osc code) like 8x ADSR's , 8-12x LFO's and DAC's (12x) outs to control the external filter board....

victor_pv
Posts: 1681
Joined: Mon Apr 27, 2015 12:12 pm

Re: I2S example code

Post by victor_pv » Tue Sep 08, 2015 5:03 pm

madias wrote:I've done a little benchmark with different buffer sizes (with low level pin manipulation):
On a buffer 256 I have
2459us IDLE time
214,8us IRQ
= 8.034% CPU time

On a buffer 16:
153,6 IDLE
13,5us IRQ
= 8.079% CPU time

So the match winner is: Buffer 16 with better audio quality :)
So in this calculation it's not important how the CPU time for pin manipulation is, because it's about the relationship between the results. So the main CPU time is calculating the real time audio itself.
Strange thing: (I suspect it, must check it again): On a PIC32MX250 @68MHZ nearly the same code (but without DMA for I2s!) is faster.

So in my final code I suspect to need 10-12% CPU cycle time for each oscillator, so all in all about 40-50% of CPU time, but I need TFT, encoders-knobs-buttons, (USB) MIDI, and more permanent calculations (not on a high frequency as the osc code) like 8x ADSR's , 8-12x LFO's and DAC's (12x) outs to control the external filter board....
Are those times with all the processing still in the ISR?

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: I2S example code

Post by madias » Tue Sep 08, 2015 5:49 pm

Yes, the LED pin is on on the IRQ start and off on the IRQ end

victor_pv
Posts: 1681
Joined: Mon Apr 27, 2015 12:12 pm

Re: I2S example code

Post by victor_pv » Tue Sep 08, 2015 7:22 pm

madias wrote:Yes, the LED pin is on on the IRQ start and off on the IRQ end
OK, I was trying to figure out why the ISR would take 13uS in one case and over 200uS in the other, but if the processing is done inside the ISR, that explains it.

With the number of tasks you want to do, I think you would greatly benefit from an RTOS and giving each task a different priority, so you know that for example redrawing the screen is not going to slow down generating a certain wave, etc.

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: I2S example code

Post by madias » Tue Sep 08, 2015 7:49 pm

freeRTOS could really my friend with this project, I'll consider the included examples
Is there something to observe with RTOS (ok, away from using it's own functions like delay)?
Is RTOS using a specific hardware timer for the tasks?
I'll read all the functions on http://www.freertos.org/a00019.html

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: I2S example code

Post by madias » Tue Sep 08, 2015 8:13 pm

Ok, answer to my hw timer question
FreeRTOS uses systick with 1khz

victor_pv
Posts: 1681
Joined: Mon Apr 27, 2015 12:12 pm

Re: I2S example code

Post by victor_pv » Wed Sep 09, 2015 3:59 am

madias wrote:Ok, answer to my hw timer question
FreeRTOS uses systick with 1khz
Correct ;)
try to keep isrs small, so they dont mess up with the task scheduling, and use semaphores and queues to signal when a buffer is free, etc.

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: I2S example code

Post by madias » Wed Sep 09, 2015 1:40 pm

Ok, I was reading the RTOS reference and looked at some examples.
In the library folder there are two RTOS libs: FreeRTOS and FreeRTOS821. I think the 821 is the newer one that I should use? (Sadly I didn't found a hint in the forum)
Howto DMA and RTOS-tasks (my consideration):
In the DMA IRQ, which triggers when buffer is empty (I deleted the half empty option) I should set a handler/trigger to an RTOS-task (call it: RTOS_audioengine)
So the RTOS_audinoengine fires up fill up and fill up the buffer?

Should I do that within the DMA IRQ with:
xQueueSendFromISR
xQueueReceiveFromISR ?
edit or
xSemaphoreGiveFromISR
xSemaphoreTake
So the RTOS_audioengine is first priority.
The rest of the tasks should be: TFT (low priority), MIDI (middle-high), human-interface (middle-low), modulations ADSR, LFO's (middle)....

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: I2S example code

Post by madias » Wed Sep 09, 2015 7:52 pm

Next question answered to myself:
In the current STM32F1 folder there are two libraries:
"FreeRTOS" this is the old V7.0.1 and
"FreeRTOS821" this is the newest version 8.21

Victor: I found your wav player example at https://github.com/victorpv/Arduino_STM ... odule2.ino
In this example you use coos instead of RTOS - why?
edit: Ok, on the first look I feel Coos has the better user manual and looks easier to understand than RTOS

victor_pv
Posts: 1681
Joined: Mon Apr 27, 2015 12:12 pm

Re: I2S example code

Post by victor_pv » Thu Sep 10, 2015 12:03 am

madias wrote:Next question answered to myself:
In the current STM32F1 folder there are two libraries:
"FreeRTOS" this is the old V7.0.1 and
"FreeRTOS821" this is the newest version 8.21

Victor: I found your wav player example at https://github.com/victorpv/Arduino_STM ... odule2.ino
In this example you use coos instead of RTOS - why?
edit: Ok, on the first look I feel Coos has the better user manual and looks easier to understand than RTOS
CoOS and freeRTOS offer pretty much the same features. CoOS is ARM specific while FreeRTOS is not. If you plan on porting your code to something else than ARM, may be better to start with FreeRTOS, but as far as I can tell, they share so many features that changing one for the other would be as simple as changing some "keywords" for others. That is pretty much how I wrote the rotating cubes examples, just wrote it in one (I believe FreeRTOS first), then changed the declaration of the tasks, and the part in loop where it starts each task setting their stack space etc, and run.

Both add a very thin layer to the sketch. I remember I posted in some thread the amount of Ram and flash consumed by each for a very basic sketch.

CoOS documentation is not very detailed though, you learn more by looking at examples. My wav player may be a start since it has a few tasks running at the same time, including reading from SDcard and reading a button and timing how long it is pressed to act differently.

I haven't finished it yet, haven't had much time to seat and work on the sketch or the tmrpcm library, I need to clean it up a lot...

I would use the latest version of either one, whichever one you feel comfortable with.

On CoOS there is one setting to set the maximum number of tasks. Be careful, I dont remember what was the default, but when writting the wav player I went over the limit, and wont give any error, but simply the last few tasks to get started would just not start, without any crash. Took me a while to figure out that I was using more tasks than the limit set at that time.

So remember to check and rise the limit as needed. It is somewhere in the config header file.

Besides that, I love how easy it is to run several concurrent tasks at different priorities without having to use a bunch of interrupts.
I am a complete novice to any RTOS, and still found them easy enough to use.

Post Reply