Recent

Author Topic: HELP OSx Midiroutines causing BAD EXEC error  (Read 2892 times)

Josh

  • Hero Member
  • *****
  • Posts: 1425
HELP OSx Midiroutines causing BAD EXEC error
« on: October 06, 2015, 11:11:28 am »
Hi
I have been trying to use coremidi to receive sysex and midi cc commands for a while now, and I have now got to a stage where i think I have progressed, but I am getting BAD EXEC errors, and I cannot run in debugger mode as I get error run error 202. Using Laz 1.4.2 fpc 2.6.4.

The application runs, but as soon as it receives sysex data I then get the errors.

Below is the code I am using for the midiinput call back routine.

I suspect it is something to do with pointers/de-referencing etc, but I cannot find it.

Hoping someone can help.
Code: [Select]
procedure MyMIDIReadProcInput(const list:MIDIPacketListPtr;
                   procRef:UnivPtr;
                   srcRef:UniVPtr); mwpascal;


Var continueSysEx :boolean= false;
    nbytes:Integer=0;
    sysExLength:integer=0;
    lengthToCopy:integer=0;
    MPacket:MIDIPacket;
    pPacket:MIDIPacketPtr;
    iByte:Integer=0;
    size:integer=0;
    status:byte;
    lengthLeftInMessage:Integer=0;
    messageType:Byte;
    messagechannel:byte;
    i,c:integer;
    s:string='';

function moveintoarray(start,howmany:integer):boolean;
var c:integer;
begin
  for c:=0 to howmany do
  begin
    sysexmessage[start+c]:=mpacket.data[c];
  end;
  moveintoarray:=true;
end;

begin
  MPacket:= &list.packet[0];
  s:='';  // temp to create string
  for i := 0 to list.numPackets do
  begin
    nBytes := Mpacket.length;
        // Check if this is the end of a continued SysEx message
    if (continueSysEx) then
    begin
      LengthToCopy := MIN (nBytes, MAX_SYSEX_LENGTH - sysExLength);
      // Copy the message into our SysEx message buffer,
      // making sure not to overrun the buffer
      moveintoarray(sysExLength,lengthToCopy);
      sysExLength := sysExLength+lengthToCopy;
      // Check if the last byte is SysEx End.
      continueSysEx := (mpacket.data[nBytes - 1] = $F7);
      if (( not continueSysEx) or (sysExLength = MAX_SYSEX_LENGTH)) then
      begin
        // process the SysEx message here
        // temp dump to memo
        s:='';
        for c:=0 to sysexlength do s:=s+inttohex(sysexmessage[c],2)+' ';
        form1.Memo2.Lines.add(s);
        sysExLength := 0;
      end;
    end
    else
    begin
      iByte := 0;
      while (iByte < nBytes) do
      begin
        size := 0;
        // First byte should be status
        status := mpacket.data[iByte];
        if (status < $C0) then
        begin
          size := 3;
        end
        else
        if (status < $E0) then
        begin
          size := 2;
        end
        else
        if (status < $F0) then
        begin
          size := 3;
        end
        else
        if (status = $F0) then
        begin
          // MIDI SysEx then we copy the rest of the message into the SysEx message buffer
          lengthLeftInMessage := nBytes - iByte;
          lengthToCopy := MIN (lengthLeftInMessage,MAX_SYSEX_LENGTH);
          moveintoarray(sysExLength,lengthToCopy);
          sysExLength:=lengthToCopy;
          size := 0;
          iByte := nBytes;
          // Check whether the message at the end is the end of the SysEx
          continueSysEx := (mpacket.data[nBytes - 1] <> $F7);
        end
        else
        if (status < $F3) then
        begin
          size := 3;
        end
        else
        if (status = $F3) then
        begin
          size := 2;
        end
        else
        begin
          size := 1;
        end;
        messageType := status and $F0;
        messageChannel := status and $F;
        case (status and $F0) of

          $80:begin
                 //Note off
               end;
          $90:begin
                 // note on
               end;
          $A0:begin
                 //after touch
               end;
          $B0:begin
                // cc
              end;
          $C0:begin
                // pc
              end;
          $D0:begin
                 // change aftertouch
               end;
          $E0:begin
                 // pitchwheel
               end;
          else begin
                 // something else;
                end;
        end;
        iByte:= size;
        ppacket:=midipacketnext(ppacket);
        mpacket:=pPacket^;
        nbytes:=mpacket.length;
      end;
    end;
  end;
end;             
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

 

TinyPortal © 2005-2018