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];
}