Re: 6502 MIDI file player
Posted: Thu Jan 17, 2019 1:04 pm
Well that took me some effort! First I replaced the SC26C92 with the SC28L92. In order to make use of the 16 bit FIFO, I had to enable it by setting the MR0A[3] bit to ‘1’. This made no difference in playback performance.
Then I implemented a circular 256 byte software buffer together with interrupt based writing to the UART. That was indeed a bit fiddly because of the distinction between the UART and TIMER interrupts. Eventually I got it sort of working. The MIDI file is playing exactly as before, including the lag at those specific areas, but it also misses several MIDI events which of course is even less desirable. I suspect my mistake is that I’m not clearing the interrupt status register bit that indicates the UART interrupt because I don’t know if or how I have to disable it. (I don’t think I have to clear it, because it’s cleared automatically when reading the interrupt status register?)
I’m using the title music of the game Duke Nukem 3D, which is a standard MIDI file from the 90’s, specifically arranged to be played on a Roland Sound Canvas. On a PC, playing that MIDI file over a conventional MIDI interface with a 5-pin MIDI cable, it plays without any lag. It even plays perfectly after setting the tempo to 250 BPM. That should prove that the MIDI file isn’t hogging a physical PC MIDI interface nor the MIDI synthesizer itself.
I’ve analyzed the MIDI file with an event viewer and the moment my player starts to lag is when various MIDI events are to be played at the same time, i.e. when their delta times are 0. After that, when events are streamed with delta times other than 0, it resumes playing at normal speed.
What I will do next is to 1) change the delta times in those areas to 1, eliminating the fact that they have to be send in one interrupt cycle. 2) Replace frequently used subroutines with macros to speed up the code. 3) Perform some code optimizations suggested previously.
Then I implemented a circular 256 byte software buffer together with interrupt based writing to the UART. That was indeed a bit fiddly because of the distinction between the UART and TIMER interrupts. Eventually I got it sort of working. The MIDI file is playing exactly as before, including the lag at those specific areas, but it also misses several MIDI events which of course is even less desirable. I suspect my mistake is that I’m not clearing the interrupt status register bit that indicates the UART interrupt because I don’t know if or how I have to disable it. (I don’t think I have to clear it, because it’s cleared automatically when reading the interrupt status register?)
I’m using the title music of the game Duke Nukem 3D, which is a standard MIDI file from the 90’s, specifically arranged to be played on a Roland Sound Canvas. On a PC, playing that MIDI file over a conventional MIDI interface with a 5-pin MIDI cable, it plays without any lag. It even plays perfectly after setting the tempo to 250 BPM. That should prove that the MIDI file isn’t hogging a physical PC MIDI interface nor the MIDI synthesizer itself.
I’ve analyzed the MIDI file with an event viewer and the moment my player starts to lag is when various MIDI events are to be played at the same time, i.e. when their delta times are 0. After that, when events are streamed with delta times other than 0, it resumes playing at normal speed.
What I will do next is to 1) change the delta times in those areas to 1, eliminating the fact that they have to be send in one interrupt cycle. 2) Replace frequently used subroutines with macros to speed up the code. 3) Perform some code optimizations suggested previously.