bill Posted March 31, 2006 Report Posted March 31, 2006 Hello, i have no problem, but i wrote my first C function :) and i'm happy with it,so i like to share it with you as i think it can be usefull ( at least for a c newbie like me ::) )The function take the midi note number to display the note in a human readable form. const char note_name[12][3] = { "C-","C#","D-","D#","E-","F-","F#","G-","G#","A-","A#","B-", }; void GET_NCHR(unsigned char note) { unsigned char n=0; //8bit is enough unsigned char oct=0;//octave number do{ oct++; n=oct*12; } while(n<=note); oct--; MIOS_LCD_CursorSet(0x00); MIOS_LCD_PrintCString(note_name[note-12*oct]);// MIOS_LCD_PrintBCD1(oct); return ; } Quote
stryd_one Posted March 31, 2006 Report Posted March 31, 2006 Way to make code dude! Thanks for sharing! Quote
johnh Posted April 3, 2006 Report Posted April 3, 2006 Hi,I have a similiar function in a program I'm working on. In my version I used DIV and MOD which eliminates the need for the loop that you have. But looking at the assembly code generated by SDCC I see that the DIV and MOD operators are handled by function calls to routines that are themselves written in C. So, a simple operation turns out to be not so simple when you look 'under the hood'. I took a look at your code, simplified it a little bit, and am now using it instead of what I had in my program. Here's my modified version of your function:void GET_NCHR(unsigned char note) { unsigned char oct=0;//octave number while ( note > 11) { note=note-12; oct++; } MIOS_LCD_CursorSet(0x00); MIOS_LCD_PrintCString(note_name[note]); MIOS_LCD_PrintBCD1(oct); return ; } I believe they are equivalent. Thanks for getting me to dig a little deeper and look at this problem in a different way. Quote
stryd_one Posted April 3, 2006 Report Posted April 3, 2006 I'd be interested to see the performance comparison between the looped statements you guys have written, the divide operation (which can be done in pure ASM by the way) and a table lookup...Obviously the loop/while way of doing this will vary depending on which note is being calculated... Higher notes will have to be subtracted from less times, meaning less loops.I was also thinking of ways of optimising the function like subtracting in 2 or 3-octave steps, but i imagine that in a range of only 127 that would be overkill and would introduce more overhead than it would save.... Quote
johnh Posted April 3, 2006 Report Posted April 3, 2006 I was surprised the compiler used a C subroutine to handle the division in my original version of the function. If we wanted to be really efficient we could write the whole thing in ASM ;) ... I'd really rather just stick to C and use as many techniques as possible to keep the code/data reasonable small and efficient. The DIV and MOD experience is now tucked away so it's something to think about next time I need something like that.Higher notes will have to be subtracted from less times, meaning less loops.Actually the loop will run fewer times for low notes. In fact, for C-0 though B-0 the loop won't run at all! Quote
stryd_one Posted April 3, 2006 Report Posted April 3, 2006 Derrrrr!That's oct++, not oct-- ,etc... Helps if I read it properly ;) heheheheGeez I sometimes wonder if I should try learning more C to write my seq or just stick with ASM. I don't know... I just find ASM more easy simple and straightforward... Am I weird? Does anyone else prefer ASM over C? (For reasons other than code size and execution speed) Quote
TK. Posted April 3, 2006 Report Posted April 3, 2006 I just find ASM more easy simple and straightforward... Am I weird?just compare the C code above with the assembly version within the MIDIbox SEQ package (midi_evnt.inc, MIDI_EVNT_PrintNote)There are two versions, one iterative, one table based (which is disabled). The iterative version works fast enough. The loop which determines the octave takes ca. 13 uS in worst case (highest octave), thats appr. the same time it takes to print a character on LCD, and this is the point:The LCD always needs some time to print a character. MIOS polls for the busy flag before (and not after) a new character is transfered to the display. This has the advantage, that the CPU can do something else during the busy state without loosing performance.Best Regards, Thorsten. Quote
stryd_one Posted April 3, 2006 Report Posted April 3, 2006 Thanks TK :) I always love reading your comments on the inner workings of MIOS. It really is an impressive work of art :) Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.