MIDI Programs

Other Programs

Cocoa Sample Programs

Algorithms

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

Carbon XEmacs Beta 4

Saturday October 29, 2005

Not a lot to report. I’ve just put together a new diff file for the Carbon XEmacs port for their xemacs-21.5.23 release. As long as their changes are minor, like the last few times, this has not been hard to do. My first priority is now TOE though, and my upcoming vacation :-).

TOE Discussion Forum

Thursday October 27, 2005

The guest book for this blog and the TOE discussion forum are now on line. You can leave a message on my guest book without registration. You will need to register with the forum if you want to participate in the TOE discussion forum. The forums are managed by YaBB 2.0 running on an old Pentium II PC running Linux.

At the end of a blog entry for which I want to invite discussion, I’ll add a link with the label “[DISCUSS THIS ENTRY]”. See yesterday’s entry for example.

You’re still welcome to write back on topics unrelated to blog entries so marked by posting messages to the guest book. Again I welcome thoughtful comments on programming and program design (especially ones related to TOE, MIDI programming, and jazz improvisation). I can’t promise I will always respond to posts on other topics.

TOE Source Code!

Wednesday October 26, 2005

Here’s a snapshot of my latest TOE Xcode project. TOE is a MIDI programming library that aims to show that good design and implementation decisions make it simple to write MIDI applications.

TOE is built using SWIG. This makes it possible to call it from a variety of languages such as Python, Scheme, Ocaml, Java, Perl, and Tcl/Tk. Currently Python and Scheme (the Chicken implementation) are supported. Support for other languages can be added reasonably easily. (See my blog entries on Sep. 26, Sep. 27, Sep. 29, and Sep. 30).

The SWIG typemaps for Python and Chicken support Objective-C style exception handling (Oct. 24) and Unicode (Oct. 3 and Oct. 4). Since only Objective-C code and CFPropertyListRef objects are used at the API, TOE is also readily accessible from Cocoa/Objective C applications.

TOE introduces the notion of device descriptions and device name resolution which handle addressing of and provide persistent handles to MIDI devices in an intuitive manner (Oct. 7, Oct. 10, and Oct. 14).

TOE provides the function Devices, which returns the device descriptions of the source, destination, or sysex devices in the MIDI setup (Oct. 10).

TOE provides the class Sysex and the class methods Send, NumOfBytesSent, CancelSend, Receive, and NumOfBytesReceived for data transfer to and from sysex devices (Oct. 13).

TOE provides the class Destination to represent MIDI devices that can receive MIDI data. The class method Send can be used to send MIDI data to a destination (Oct. 17). The class methods Banks and Programs return a list of symbolic names of banks and programs (i.e., patches) of a destination, respectively (Oct. 21). The class methods BankSelect and ProgramChange converts symbolic bank and program names to the MIDI data that can to be send to a destination to select the bank and program, respectively (Oct. 24 and Oct. 25).

The SWIG interface definition file TOE.i in the Xcode project summarizes the current definition of the TOE API.

Since the project uses SWIG, you must have it installed to build TOE. Chicken must also be installed if you want to build the “Chicken Extension” target. The latest versions, SWIG 1.3.27 and Chicken 2.2, are used.

TOE requires OS X 10.4 and Xcode 2.1.

The association of MIDI name documents (or .midnam files) to a MIDI device is recorded in OS X in its name configuration property. The name configuration properties of MIDI devices in a MIDI setup can be edited using NameConfigSetup utilities I have written (this one or an older one).

TOE is released under the “four-clause” BSD license (Oct. 18).

TOE is an ongoing project.

[DISCUSS THIS ENTRY]

Bank Select

Tuesday October 25, 2005

Today’s program is brought to you by the function BankSelect(d, ch, b). It returns a CFDataRef that points to an object containing the MIDI bytes needed to select bank b for MIDI channel ch on (destination) device d.

When d refers to a E-mu Morpheus, for instance, the call (BankSelect d 1 "HyperPresets") returns the byte-vector 0xb0 0x00 0x00 0xb0 0x20 0x02, which is a MIDI bank select 0 followed by a MIDI bank select 32. This information is extracted from the master name document associated with the device. Here’s the relevant portion of that document:
  <PatchBank Name="HyperPresets" >
    <MIDICommands>
      <ControlChange Control="0" Value="0" />
      <ControlChange Control="32" Value="2" />
    </MIDICommands>
    ...
  </PatchBank>
The following Chicken interaction shows the use of this function. Two calls to the Send method are used to send a bank select followed by a program change to the Destination. The combined effect is of course to select a patch in a bank on a channel of a destination device.
~/Documents/TOE/TOE/build/chicken/Debug$ csi -q
#;1> (load-library 'TOE "TOE.dylib")
#t
#;2> (Initialize)
#;3> (define d (make <Destination> "Morpheus"))
#;4> (Banks d 1)
#("RAM Presets" "ROM Presets" "HyperPresets" "Card Presets" "Card HyperPresets")
#;5> (Patches d 1 "HyperPresets")
#("Hyp:HootTube" "Hyp:BassPno " "Hyp:VelElPno" "Hyp:MoodTxtr" "Hyp:MostBass" "Hyp:GtrAura "
"Hyp:MeanLead" "Hyp:Ah Yeah " "Hyp:JazzSplt" "Hyp:WeirdDrm" "Hyp:MorphMe " "Hyp:Mill Set"
"Hyp:DblPluck" "Hyp:MidiHorn" "Hyp:TmptSax " "Hyp:AlivePno" "Hyp:DayMajik" "Hyp:Stringed"
[...]
"Hyp:Default ")
#;6> (use lolevel)
#;7> (define number->hex-string (lambda (x) (number->string x 16)))
#;8> (map number->hex-string
  (byte-vector->list (ProgramChange d 1 "HyperPresets" "Hyp:MostBass")))
("c0" "4")
#;9> (map number->hex-string (byte-vector->list (BankSelect d 1 "HyperPresets")))
("b0" "0" "0" "b0" "20" "2")
#;10> (Send d (BankSelect d 1 "HyperPresets"))
#;11> (Send d (ProgramChange d 1 "HyperPresets" "Hyp:MostBass"))
#;12> ^D
~/Documents/TOE/TOE/build/chicken/Debug$ 

Program Change

Monday October 24, 2005

Now that we can use TOE to query destination devices for banks and patches, we can add two functions to translate symbolic names into MIDI program changes and bank selects. The function ProgramChange(d, ch, b, p) returns a CFDataRef (i.e., a string in Python and a byte-vector in Chicken) that contains a MIDI program change command for changing channel ch on device d to patch p, assuming bank b is already selected. I’ll write another function BankSelect(d, ch, b) to perform the latter operation tomorrow. Of course the CFDataRef returned can be sent to the destination device using the Destination method Send, written last week.

The following Python interaction shows the use of this new function. Note that the call to ProgramChange return the two bytes 0xC0 (program change for channel 1) and 0x02 (patch number 2).
~/Documents/TOE/TOE/build/python$ python
Python 2.3.5 (#1, Mar 20 2005, 20:38:20) 
[GCC 3.3 20030304 (Apple Computer, Inc. build 1809)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import TOE
>>> TOE.Initialize()
>>> TOE.Devices(TOE.kDeviceTypeDestinations)
[{u'DisplayName': u'IAC Driver Bus 1'}, {u'DisplayName': u'Morpheus', u'Devices':
 [{u'Model': u'Morpheus', u'DisplayName': u'Morpheus', u'Manufacturer': u'E-mu Systems'}]}]
>>> d = TOE.Destination('Morpheus') 
>>> TOE.Banks(d, 1)
[u'RAM Presets', u'ROM Presets', u'HyperPresets', u'Card Presets', u'Card HyperPresets']
>>> TOE.Patches(d, 1, u'RAM Presets')
[u'Mph:Z-Synth ', u'Real:PnoVibe', u'Cmp:ElecPno ', u'Pad:Strings ', u'Bass:UpRight',
u'Gtr:Trippy  ', u'Ld:Grunge   ', u'Atm:RaveGruv', u'Voc:Why?    ', u'Drum:Sweep  ',
u'Mph:KlavKlip', u'Mph:FluteToo', u'Mph:AirStrg ', u'Mph:Voices  ', u'Mph:Whisper ',
u'Mph:RhyOfLfe', u'Mph:MetalMlt', u'Mph:Phazbraz', u'Mph:RezzSlth', u'Mph:SteinChl',
[...]
u'Tek:RzrSlce ', u'Tek:RaviaMaj', u'Tek:BellEpic', u'Tek:KrazyRom', u'-defPreset- ']
>>> TOE.ProgramChange(d, 1, u'RAM Presets', u'Cmp:ElecPno ')
'\xc0\x02'
>>> d.Send(TOE.ProgramChange(d, 1, u'RAM Presets', u'Cmp:ElecPno '))
>>> ^D
~/Documents/TOE/TOE/build/python$ 
The parsing of XML files in MIDI name document (or .midnam) format is done using the Foundation NSXML API. This makes specifying the parser easier but integration with current code harder due to the mixing of Foundation and CoreFoundation code (object ownership conventions are different, Foundation objects use auto-release pools, etc.). The use of NSXML also requires OS X 10.4. If I ever need to back port it to 10.3 and earlier, I do have some code I wrote a while back that uses the CFXMLParser.

Since we’re now linking with the Foundation framework, I’ve also converted all code in TOE to use Objective C style exceptions instead of the C longjump/setjump exception macros I was using last week. The SWIG typemaps were also changed accordingly. This will allows TOE to integrate better when called from Cocoa code in the future.

October 2005
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 31
Sep  Nov

xml

Forums

Lists

Misc