About Andrew Choi
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
Fish Creek MIDI Framework
FCBlog and Patch
Chinese Checkers Program
jyut6 ping3 Cantonese Input Method
Cocoa Sample Programs
Syntax Coloring Using Flex
NSTextField and Undo
Implementing File Import
Launch Application and Open URL
Saving Uncommitted Text Field Edits
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.
Friday September 17, 2004
Less-Known Facts About Emacs, and Rants :-)
I think Ill just take a day off from MIDI programming and go walk about. So I give you some less-known facts about Emacs, and my rants. Or are they all rants :-)? You decide.
Top 10 less-known facts about Emacs:
- The primary person responsible for bringing Emacs 21 into existence is Gerd Moellmann.
- A number of people (including myself) contributed texts to the Emacs manual. However the title page shows only the name Richard Stallman.
- The Emacs people hate it when someone calls Emacs FSF Emacs. If you dont believe me, try doing so on one of the Emacs mailing lists :-). Its like when you call Linux Linux (instead of GNU/Linux).
- Mac OS is a non-free platform and supporting it is not, and will never be, a primary goal of the Emacs project.
- Although I did both, the Mac OS classic port is a much bigger accomplishment than the Mac OS X port.
- I actually did two ports for Mac OS classic, one for Emacs 20.x and one for Emacs 21.x. The display code in those two versions is significantly different.
- There is no bazaar, as in The Cathedral and the Bazaar. I did the Mac ports all on my own. There have only been minor code contributions after I released my code. People using the Mac ports are generally not programmers.
Unexpected roles that came with being Mac maintainer:
- hand-hold people who couldnt build/use Emacs (and cant read manuals),
- as free software advocate,
- as secretary/apprentice (check/install other peoples patches, adding comments, doing CVS stuffs, I hated that),
- as secretary/apprentice (obtaining copyright assignments for FSF, hated that even more).
- I was never asked nor had I ever promised to be Mac maintainer for Emacs. One day someone put my name in the
MAINTAINER file without asking me and that was it. I only noticed that quite a bit later.
- Ive never asked for my code to be included in the main distribution. I was invited.
My top 10 Emacs/free software pet peeves:
- Most people use Emacs because it makes them sound cool, not because they really need Emacs.
- When developing a program such as Emacs by CVS, it only takes a few bad programmers among people with write access to greatly lower the quality of the code.
- Most people use free software because it is gratis, not because it is libre.
- Make no mistake about it: the primary goal of FSF is software freedom. Producing good software is secondary.
- During the course of my working on Emacs, I got quite a few requests from people to be included into the developer team, or even to be nominated as maintainer. Well, you dont become a developer by asking; you become one by contributing a lot of high-quality and useful code! As for maintainership, I believe you just have to be invited.
- My theory on binaries for software in CVS. If you dont offer them, someone will anyway. But guess who gets the questions for old builds. Arrrrgh!!
- If you cant figure out how to build and install a free software package on your own, you probably have no business using it.
- I ported Emacs for the love of programming, certainly not because Im a free software advocate (I am not).
- My Emacs ports have probably affected more people than those affected by all the research papers I have written combined. Quite sad, actually.
- Emacs is, afterall, just a text editor :-). There, I said it. Emacs is just a text editor!
It has been almost a year since I stopped working on Emacs. Im glad I did. As I said, I did the ports because it was fun. And I dont regret working on them. I wasnt quite prepared for all the unpleasantness that followed.
Thursday September 16, 2004
Heres the design of the portion of a GUI for selecting a patch by name for a channel of a MIDI device. At any given time the device is in a certain device mode (e.g., performance mode). This device mode and the MIDI channel determine the name set that is available (e.g., channel 10 in performance mode can use rhythm banks). The selected bank then determines which patches are available on the patch name list.
The code for filling the pop-up buttons in this test program actually already works, and it makes use of the
kMIDIPropertyNameConfiguration property of the external device. It also takes into account patch banks that may be overridden by another MIDI name document.
Unfortunately, Aqua does not really have any GUI element suitable for selecting an item from a large number of choices. The list of a pop-up button extends beyond the top and bottom of the screen and a lot of scrolling is required to locate the desired selection. A better GUI should probably use something like the Cocoa font or color panel. OMS, on the other hand, has this two-dimensional custom control:
Wednesday September 15, 2004
Using MusicPlayer to Play Sequences to MIDI Devices
I received a request this morning to show some sample code for sending MIDI messages to external MIDI devices. If one is using functions in
CoreMIDI/MIDIServices.h, the list of out-going MIDI packets need to be built and sent by calling
MIDISend. Doing the same thing using the
MusicSequence type in the
AudioToolbox framework is a lot easier. Ive written a small sample application to illustrate this.
The application basically combines two projects I posted earlier: one for playing MIDI files (to the DLS music device, i.e., the internal sample-based synthesizer) and one for selecting destination MIDI devices. After a document is opened, the user can choose the destination for the MIDI sequence with a popup button. The modifications to the code that plays the sequence is minimal since we simply need to call
MusicSequenceSetMIDIEndpoint before the sequence is played. To send tracks selectively to different MIDI devices, one can use the function
MusicTrackSetDestMIDIEndpoint instead. Ive verified that this works fine in my automatic accompaniment program (so the bass, piano, and drum tracks can all go to different MIDI devices!). But that code will be left as an exercise for the reader.
Oh, I should mention that you can also learn how to use the function
MusicSequenceSetMIDIEndpoint by reading Apples sample program in
Tuesday September 14, 2004
Herere the steps I took to get my application, which has been developed on 10.3, to also run on 10.2. Again, if Ive thought of this earlier, Id have avoided using more of the 10.3-only Cocoa features. The changes to CoreMIDI between OS X 10.2 and 10.3 also presented a few additional problems.
For the application to run on 10.2, the availability macro values must be set so that weak linking is used when necessary. This is specified by changing the Mac OS X Deployment Target setting in the Project Info panel to Mac OS X 10.2. Then, to help identify 10.3 features used in the application, change Cross-Develop Using Target SDK: in the Project Info to MacOSX10.2.8 and rebuild the application. The compiler should warn against methods and data types absent in 10.2. For me, these included the class
NSAlert and the method
NSView. So I rewrote these by using equivalent or similar features in 10.2.
If the application uses frameworks outside the 10.2.8 SDK, such as CoreMIDI, one should ideally find the versions of those frameworks that come with the deployment target and link against them. Alternatively as I have done, I identified the differences manually and rewrote the code to behave in a reasonable way under both versions of CoreMIDI. For example,
MusicPlayerSetPlayRateScalar is available in the Panther version of CoreMIDI but not the Jaguar version, and calling
MusicTrackGetProperty with a property ID of
kSequenceTrackProperty_TrackLength always returns an error in Jaguar.
When all the modifications to the code have been made, change Cross-Develop Using Target SDK: in the Project Info back to Current Mac OS and build the final application bundle, which will now run on both 10.2 and 10.3.
Monday September 13, 2004
Backward Binary Compatibility
Id like my automatic accompaniment program to run on Jaguar as well as Panther. Since one generally has to pay full price to upgrade to Panther, I suspect therell be a few people running Jaguar for a while. Releasing a single binary application bundle that runs on both Jaguar and Panther is not as easy as it sounds, especially for a program that uses a lot of Cocoa features. I wish I had thought of this earlier and stick to only Jaguar features. Even then, CoreMIDI and AudioToolbox have changed between Jaguar and Panther and handling backward compatibility there also requires a bit of work.
To understand some of the issues involved, read Apples technical note 2064. Then read the Panther Cocoa Application Framework Release Notes for difference between the Panther and earlier versions of Cocoa classes. Also read about availability macros and cross development.
I have installed Jaguar (10.2.8) on my PowerPC 8500 for testing purposes. That machine is quite old and not supported by Apple to run OS X. Of course XPostFacto allows Jaguar to be installed it and so far everything seems to work fine except for sound.
Search this blog with
Less-Known Facts About Emacs
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
Mac OS X