My OS X Programming Blog
Mac OS X Cocoa and CoreMIDI Programming
About Andrew Choi


MIDI Programs

MIDI File Player (External Device)

MIDI Destination Pop-Up Button

MIDI File Player (Internal Synth)

MusicSequence Sample Code

MIDI File Writer

MIDI Name Document Parser

NameConfigSetup

Fish Creek MIDI Framework

MidnamUtility

SysExSenderX

Other Programs

FCBlogEditor

FCBlog and Patch

Chinese Checkers Program

jyut6 ping3 Cantonese Input Method

Cocoa Sample Programs

Syntax Coloring Using Flex

NSTextField and Undo

NSToolbar

Implementing File Import

Launch Application and Open URL

Saving Uncommitted Text Field Edits

Algorithms

Jazz Chord Analysis as Optimization

Optimal Line Breaking for Music

Optimal Chord Spacing

   

A blog where I will write mostly about programming in Cocoa and CoreMIDI, and experiences from my ports of Emacs and XEmacs to the Mac OS.

A New SysExSenderX Implementation
Friday September 12, 2003

OK! Here is a new implementation of SysExSenderX using yesterday's design. It turns out to be not too difficult to write, after the design has been worked out like that. The resulting structure of the program is also quite nice.

Again using the C/Core Foundation CoreMIDI API presents a small problem: calling Objective C methods not only from C code, but as callbacks from another pthread is precarious at best. I avoided this by letting the CoreMIDI mechanism do its own thing and using an NSTimer to poll its status and reporting that back to the caller. A more efficient implementation should probably use an NSThread at the higher level to perform the reporting coordinated by some type of Core Foundation synchronization mechanism in the callback. But for now the timer solution is sufficient for my purpose.

What happens if a sysex message is sent to the same device before the previous one finishes? The behavior of SysExSenderX suggests that CoreMIDI queues the requests, in FIFO order. I wonder if there will be future sychronization problems without additional restrictions over how much data is sent concurrently. There's probably no way of knowing except by experiment. Maybe I'll try to read the CoreMIDI mailing list archive.

Design of An “Operation In Progress” Class
Thursday September 11, 2003

We just had quite a hail storm! It must have lasted only 10 minutes but it was a refreshing thing to watch. Cold weather must not be too far ahead. I've just planted some squill and snowdrop bulbs for next spring this morning. Perfect timing!


Let's improve on yesterday's design. What if we need some way for the caller to cancel an on-going sysex data transmission (if the user clicks a “cancel” button)? When we implement receiveSysEx, we'll also need a way to indicate that the synthesizer has finished transmitting all data (when the user clicks a “transmission complete” button). The caller must hold on to some form of handle to send these messages.

Let's take a step back and look at any kind of operation that must be monitored by a progress indicator. What design pattern can be used for this? I didn't find anything useful on the Internet but here's what we can do. Encapsulate the operation in a class, say MyOperation, which responses to start and cancel messages. Once started, a MyOperation instance may create its own NSThread to carry out the operation, or use a asynchronous API as in the case of sysex data transmission. This detail need not be exposed to the caller. As in yesterday's design, the MyOperation instance uses a temporary delegate to report progress and completion. This is passed as an argument in the start message. During the operation, percentCompleted messages may be sent to obtain the percentage of the operation completed.

This design is illustrated by the ProgressIndicatorTest project. Why do I make such a fuss about a simple problem? (1) It's not that simple. (2) I'd rather write code that's pretty.

Design of a Asynchronous Method
Wednesday September 10, 2003

Although yesterday's program works for short, simple sysex messages, it'll probably have synchronization problems with longer ones. MIDISendSysex, the CoreMIDI function it calls, operates asynchronously. Our program didn't do anything special to keep track of invocation and completion of this function. Another shortcoming is that it doesn't show the progress of the sysex data transmission.

Since sysex data is sent through a MIDI end point, the current design provides an instance method

- (void)sendSysEx:(NSData *)sysExData
for the class MyMIDIEndpoint. Since a call to this method returns immediately and proceeds to send the sysex data asynchronously, what if it is called again before the current block of sysex data has been sent? A more complex implementation may queue the data, but our design will simply fail on the second call. If a single progress indicator is used per document, this makes sense because there is only one indicator to display the progress of the current transmission anyway. So to return success or failure, we need:
- (BOOL)sendSysEx:(NSData *)sysExData
Now, how is the caller notified about progress and completion? For multiple observers, we can use notifications. But the caller (a MyDocument instance in the sample code) will most likely be the only observer, delegation is the more suitable design pattern. We will use a temporary delegate relationship, which will exist only for the duration of a transmission. So, we need:
- (BOOL)sendSysEx:(NSData *)sysExData
completionAndProgressDelegate:(id)completionAndProgressDelegate
We chose not to pass selectors for the methods that will be called when transmission is complete or when progress is made. Instead, we assume that the delegate can (optionally) respond to the messages sendSysExComplete and sendSysExProgress:<float>percentage. I'll try to implement this design tomorrow.

Sending MIDI System Exclusive Messages
Tuesday September 9, 2003

I spent a little time reading Apple's CoreMIDI documentation. The API looks simple enough to use, but isn't any improvement over previous MIDI programming libraries such as OMS and FreeMIDI. In fact it exposes (and introduces!) as many low-level details and lacks the management of patch and note names. I found the PYMIDI Framework, which wraps an Objective-C interface around CoreMIDI. It does a lot with MIDI end points but still exposes too much (ugly) details of the underlying API. The code is also released under such a license that I cannot include it in code with the Artistic License.

So I might as well experiment a little and write my own code. Here is the result of my experiments: a program to send MIDI system exclusive (sysex) messages. I tested it by sending sysex messages to my DX-7 II, through my UA-20 interface, which worked fine. Still missing from the program are the display of the progress of data transmission and the ability to receive sysex messages. I should add these soon.

The CoreMIDI API is a C interface that uses CoreFoundation objects (and not an Objective-C interface that uses Foundation objects). So a bit of effort is required to switch between the two within a Cocoa program. The Objective-C PYMIDI Framework is a step in the right direction. But we really need high-level classes such as MIDISourcePopupButton, MIDIDestinationPopupButton, NoteSequence, and so on. Anyway there's a lot of room for improvement. That's not a bad thing. Perhaps I'll take a look at MusicKit next.

Self Printing Programs II
Monday September 8, 2003

Last week I posted a self-printing program which I wrote a long time ago. For completeness, I should note that here's one that most people know about:

main(){char *c="main(){char *c=%c%s%c;printf(c,34,c,34);}";printf(c,34,c,34);}
It's certainly much shorter!

In case you're interested, here are more self-printing programs.

September 2003
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Aug  Oct

xml

Search this blog with


Lists

Less-Known Facts About Emacs

Emacs Rants

Chinese Restaurants in Calgary

Calgary/Banff Tourist Attractions

C++ Reading List

Science Fiction Series

Top-10 Reason I Stopped Working on Emacs

Top-10 Types of Questions I Get About Emacs

10 Defining Moments as Programmer


Misc

Carbon XEmacs

Emacs for Mac OS X


Copyright © 2003, 2004, 2005 Andrew Choi (Contact Information). Created with FCBlog