[sdiy] MIDI I/O c code..

Randy Dawson rdawson16 at hotmail.com
Fri Mar 20 08:32:59 CET 2020

Hi Dave,
Thats a really good tip to use the I2C decoding feature on the Tek.  I imagine by now its standard feature on the uhhh, clone Rigol scopes.
A look at basic circular buffer interrupt structure may help:
Buffer of length x is assigned;
head and tail pointers to buffer are equal;
Interrupt driven code is input from serial to buffer, moving head buffer and tail pointer +1 and storing new data;
application reads from tail buffer pointer, non interrupt driven,  at its own speed, decrements tail pointer;

Modulo buffer len math on the pointers, these two buffer pointers chase each other as interrupts and application run.


From: Synth-diy <synth-diy-bounces at synth-diy.org> on behalf of Dave Brown <davebr at modularsynthesis.com>
Sent: Thursday, March 19, 2020 11:13 PM
To: synth-diy at synth-diy.org <synth-diy at synth-diy.org>
Subject: Re: [sdiy] MIDI I/O c code..

In 2005 I wrote a MIDI processing program to do minor manipulation such as transposing notes, changing CC messages, etc. I did it in assembly in an 8 MHZ ATTINY2313. Receive and transmit are interrupt driven out of 32 byte buffers each. It handles running status and can filter out some of the real time messages. It will take everything I can throw at it with two hands on the keyboard. It is highly optimized assembly but I suspect your issue is not emptying the buffers fast enough.

I also run this same code on a 16 MHz Basic Stamp which does have I2C D/As which do take some time so care has to be taken. The same code on an Arduino runs about 4.5X faster because the I2C is handled in hardware whereas on the Basic Stamp it is done in software.

I found my Tektronix scope with I2C decoding capability invaluable in seeing where my bottlenecks were in all the communications. Even without that capability I would often use an external pin to create timing signals so I could accurately measure code execution. But I’m a hw guy by nature.



De : dougall [mailto:dougalli at gmail.com<mailto:dougalli at gmail.com>]
Envoyé : 19 mars 2020 21:06
À : eidorian at aladan.net<mailto:eidorian at aladan.net>
Cc : Jean-Pierre Desrochers; Synth-diy at synth-diy.org<mailto:Synth-diy at synth-diy.org>
Objet : Re: [sdiy] MIDI I/O c code..

 Are you handling running status and note off sent as zero velocity note on?


 On Fri, 20 Mar 2020 at 11:55, <eidorian at aladan.net<mailto:eidorian at aladan.net>> wrote:

Sorry, I don't have example code for you, but here is some analysis that I hope might help point you in the right direction:

20MHz / 31,250Hz => ~640 instructions per MIDI data bit, or 6,400 instructions per MIDI data byte.  That's quite a lot of instruction execution time between notes, so I'd be checking the efficiency/optimisation of the code.

How long is it taking to update the analog outputs and do other processing?  If it's updating all 8 CVs via a "slow" protocol like I2C every time it loops then that might be taking a while, and maybe you need a different approach (i.e. only update a CV output when it changes).

How have you implemented the FIFO?  Do you have locking to ensure the interrupt isn't writing to it while the main loop is updating it?

Create a debug version that has checks on the FIFO size in the interrupt, and sets an LED on if it overflows, so you can confirm for certainly whether or not that's the problem.

What I do (with 30+ years of programming experience) is pretend I'm the CPU, and "execute" the code in my head (or on paper if complex) in order to try to work out what unplanned or unexpected things might be happening to cause the problematic behaviour.



On 20-03-2020 11:14, Jean-Pierre Desrochers wrote:

I’m working on a new polyphonic MIDI to CV module (8 voices).

So far I did my tests with an old PIC16F887 @ 20Mhz micro I had on hand.

I use a USART interrupt driven c function to ‘catch’ all the incoming MIDI bytes.

My code is pretty fast, but still, since I only read one MIDI channel (1-16) at the time
when I play very fast chords on an external keyboard

all the notes are read in the incoming queue but sometimes

I get stuck notes or unread ones..

Same thing happens when playing MIDI files on Cakewalk SONAR
feeding my prototype with  a MIDI cable.
The interrupt function grabs each incoming byte and put them

In a receive buffer of 32 bytes and the main () reads and treats them in a FIFO manner

Later in the main loop.

-Would a 32Mhz micro do a difference in the USART interrupt reading speed ?

-And is 32 bytes long enough for the RxBuffer to handle a 6 voices chords ?

-And finaly I checked the web for a ‘decent’ C code examples

  for MIDI reception (MIDI Tx is much easier to implement) with no success..
  ‘Obscure’ Arduino libraries all around with no explainations of its inner code.

Did anybody use good C code available ?


Synth-diy at synth-diy.org<mailto:Synth-diy at synth-diy.org>

Synth-diy mailing list
Synth-diy at synth-diy.org<mailto:Synth-diy at synth-diy.org>

Synth-diy mailing list
Synth-diy at synth-diy.org<mailto:Synth-diy at synth-diy.org>

Synth-diy mailing list
Synth-diy at synth-diy.org<mailto:Synth-diy at synth-diy.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://synth-diy.org/pipermail/synth-diy/attachments/20200320/188984ca/attachment.htm>

More information about the Synth-diy mailing list