Recent

Author Topic: OSX and midi  (Read 1934 times)

corpusgemini

  • New Member
  • *
  • Posts: 19
OSX and midi
« on: August 01, 2020, 12:33:49 pm »
Hello,

Has anyone successfully implemented MIDI in a project for OSX?

If so, can they share the code used for it, because I find lots of posts of people having the same issue, but up till now no working solution.

Thanks a lot,
Tony

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: macOS and midi
« Reply #1 on: August 01, 2020, 12:52:51 pm »
I wrote example code for a minimal MIDI player for the macOS MIDI article on the Wiki.

corpusgemini

  • New Member
  • *
  • Posts: 19
Re: OSX and midi
« Reply #2 on: August 01, 2020, 01:02:35 pm »
Thanks trev.

However I am looking for a way to send and receive MIDI commands from devices. It should make use of CoreMIDI apparently.

Best regards,
Tony

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: OSX and midi
« Reply #3 on: August 01, 2020, 01:08:58 pm »
Be aware that Apple is extending the CoreMIDI API for the forthcoming release of Big Sur (macOS 11.0). See: https://developer.apple.com/documentation/coremidi/

(I don't have a MIDI musical instrument, so haven't seriously looked at the CoreMIDI API).

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: OSX and midi
« Reply #4 on: April 24, 2023, 07:41:57 am »
Hello Trev,
i have succeeded to compile  c++ rtmidi library under windows (with visual studio) and linux (ubuntu) to use with Lazarus. I have a project demo to read the midi in and out opened in a O.S and monitor midi events using callback.
Rtmidi on Mac use COREMIDI :
Quote
A set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI) and Windows (Multimedia)
Do you know is it possible to compile this library under OS X ?
to generate midi events you can use a virtual midi keyboard like midikeys on Mac OS X.
Friendly, J.P
« Last Edit: April 24, 2023, 07:49:51 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: OSX and midi
« Reply #5 on: April 25, 2023, 10:39:13 am »
Hello,
Ultimately the rtmidi library also works under Mac Os X, with CoreMidi or with Jack library.
Attachment shows a lazarus project listening for midi events generated by virtual midi keyboard midikeys on Mac OS X Catalina 10.15.
Friendly, J.P
« Last Edit: April 25, 2023, 03:28:58 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Key-Real

  • Full Member
  • ***
  • Posts: 201
Re: OSX and midi
« Reply #6 on: May 23, 2023, 09:28:06 am »
Code: Pascal  [Select][+][-]
  1. {$linkframework AudioToolbox}
  2. {$linkframework CoreMIDI}
  3. {$MODE OBJFPC}
  4. uses MacOSAll,CocoaAll;
  5.  
  6.  
  7. procedure checkError(error: OSStatus; msg: string);
  8. begin
  9.     if (error <> noErr) then begin
  10.         writeln('Error: ', error, ' ', msg);
  11.         halt;
  12.     end;
  13. end;
  14.  
  15.  
  16. type
  17.                 myMIDIPlayer = record
  18.                 end;
  19.  
  20.  
  21.  
  22. procedure myMIDINotifyProc(message: MIDINotificationPTR; refCon: pointer); MWPascal;
  23. begin
  24.         writeln('MIDI Notify ',message^.messageID);
  25. end;
  26.  
  27. procedure myMIDIReadProc(pktlist: MIDIPacketListPTR; refCon: pointer; connRefCon: pointer); MWPascal;
  28. var packet : MIDIPacketPTR;
  29.         i : longint;
  30.         midiStatus : byte;
  31.         midiCommand : byte;
  32.         note : byte;
  33.         velocity : byte;
  34. begin
  35.         packet:= @pktlist^.packet[0];
  36.  
  37.         for i:=0 to pktlist^.numPackets-1 do begin
  38.  
  39.                 midiStatus:= packet^.data[0];
  40.                 midiCommand:= midiStatus shr 4;
  41.  
  42. //              writeln(packet^.length, ' ', midiStatus);    // if midiStatus returns 0 and packet^.length an random value than your FPC is broken :(
  43.  
  44.                 if (midiCommand = $09) then begin
  45.                         note:= packet^.data[1] and $7F;
  46.                         velocity:= packet^.data[2] and $7F;
  47.                         writeln('note ', note, ' stroke at ', velocity);
  48.                 end;
  49.  
  50.                 if (midiCommand = $08) then begin
  51.                         note:= packet^.data[1] and $7F;
  52.                         writeln('note ', note, ' releaced');
  53.                 end;
  54.  
  55.  
  56.                 packet:= MIDIPacketNext(packet);
  57.  
  58.         end;
  59.  
  60. end;
  61.  
  62.  
  63. var
  64.         client : MIDIClientRef;
  65.         inPort : MIDIPortRef;
  66.         src : MIDIEndpointRef;
  67.  
  68.         sourceCount : dword;
  69.         endpointName : CFStringRef;
  70.  
  71.         status : OSStatus;
  72.  
  73.         strC : array [0..255] of char;
  74.  
  75.         player : myMIDIPlayer;
  76.  
  77.         i : longint;
  78. begin
  79.  
  80.         status:= MIDIClientCreate(CFSTR('Core MIDI Demo'), @myMIDINotifyProc, @player, client);
  81.         checkError(status, 'Coundn''t create MIDI client');
  82.  
  83.  
  84.         status:= MIDIInputPortCreate(client,CFSTR('Input Port'), @myMIDIReadProc, @player, inPort);
  85.         checkError(status, 'Coundn''t create MIDI input port');
  86.  
  87.  
  88.         sourceCount:= MIDIGetNumberOfSources;
  89.         writeln(sourceCount, ' Sources found');
  90.  
  91.         if sourceCount = 0 then halt;
  92.  
  93.  
  94.         for i:=0 to sourceCount - 1 do begin
  95.  
  96.                 src:= MIDIGetSource(i);
  97.  
  98.                 status:= MIDIObjectGetStringProperty(src, kMIDIPropertyName, endpointName);
  99.                 checkError(status, 'Coundn''t get endpoint name');
  100.  
  101.                 CFStringGetCString(endpointName, strC, 255, kCFStringEncodingUTF8);
  102.                 writeln('- source ', i, ' ', strC);
  103.                
  104.                 status:= MIDIPortConnectSource(inPort, src, nil);
  105.                 checkError(status, 'Coundn''t connect MIDI port');
  106.  
  107.         end;
  108.  
  109.  
  110.  
  111.         readln;
  112.  
  113.  
  114. end.





BUT!!!!

you have to patch your FPC Trunk manually:

https://gitlab.com/freepascal.org/fpc/source/-/issues/35750

 

TinyPortal © 2005-2018