aros-development-team / AROS

Main AROS repository for active development. Contains the main Operating System components and Build System.

Home Page:http://www.aros.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Proper USB MIDI Driver & four bugs in camdusbmidi.class.c & miditodriver.c to fix

hitchhikr opened this issue · comments

The driver together with the source code are here:

https://hitchhikr.net/usbmidi.lha

Two bugs in the class are located in the nParseMidiOut() function :

                    case 0xe:
                        if(len < 3)
                        {
                            len = 0;
                            break;
                        }
                        len -= 3;
                        *out++ = cmd|chan;
                        *out++ = cmd;
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = buf[ca->ca_TXReadPos];
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = buf[ca->ca_TXReadPos];
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        goodpkt++;
                        break;

should be:

                    case 0xe:
                        if(len < 3)
                        {
                            len = 0;
                            break;
                        }
                        len -= 3;
                        *out++ = (cmd >> 4) | chan;
                        *out++ = cmd;
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = buf[ca->ca_TXReadPos];
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = buf[ca->ca_TXReadPos];
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        goodpkt++;
                        break;

and:

                    case 0xc:
                    case 0xd:
                        if(len < 2)
                        {
                            len = 0;
                            break;
                        }
                        len -= 2;
                        *out++ = cmd|chan;
                        *out++ = cmd;
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = buf[ca->ca_TXReadPos];
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = 0;
                        goodpkt++;
                        break;

should be:

                    case 0xc:
                    case 0xd:
                        if(len < 2)
                        {
                            len = 0;
                            break;
                        }
                        len -= 2;
                        *out++ = (cmd >> 4) | chan;
                        *out++ = cmd;
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = buf[ca->ca_TXReadPos];
                        ca->ca_TXReadPos = (ca->ca_TXReadPos+1) & mask;
                        *out++ = 0;
                        goodpkt++;
                        break;

Also another bug in the SysEx messages sending part (same function):

                if(ca->ca_SysExMode)
                {
                    ca->ca_SysExData <<= 8;
                    ca->ca_SysExData |= cmd;
                    ca->ca_SysExNum++;
                    if(ca->ca_SysExNum == 3)
                    {
                        KPRINTF(1, ("Cont 3B SysEx %06lx\n", ca->ca_SysExData));
                        *((ULONG *) out) = ((0x4|chan)<<24)|ca->ca_SysExData;
                        goodpkt++;
                        ca->ca_SysExData = 0;
                        ca->ca_SysExNum = 0;
                    }
                }

should be:

                if(ca->ca_SysExMode)
                {
                    ca->ca_SysExData <<= 8;
                    ca->ca_SysExData |= cmd;
                    ca->ca_SysExNum++;
                    if(ca->ca_SysExNum == 3)
                    {
                        KPRINTF(1, ("Cont 3B SysEx %06lx\n", ca->ca_SysExData));
                        *out++ = 0x4|chan;
                        *out++ = (ca->ca_SysExData >> 16) & 0xff;
                        *out++ = (ca->ca_SysExData >> 8) & 0xff;
                        *out++ = ca->ca_SysExData & 0xff;
                        goodpkt++;
                        ca->ca_SysExData = 0;
                        ca->ca_SysExNum = 0;
                    }
                }

also in the camd.library in the file miditodriver.c in the function Transmit_Status() this part should be removed (or reworked) as it forbids to send several notes in the same transfer (like chords):

	if(driverdata->status==ret){
		if(len>1){
			driverdata->transmitfunc=Transmit_Datas;
			driverdata->sendpos=2;
		}else{
		  IncBuffer(driverdata,&driverdata->buffercurrsend);
		  driverdata->unsent--;
		}
		return buf[BUF1];
	}