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.

MusicKit
Friday September 26, 2003

I spent a little time today playing with MusicKit. Unfortunately, after the lengthy installation process, only a few applications and examples built successfully, and among these, fewer worked correctly. Those that seemed to work were EnvelopeEd, PatchCord, MidiFilePlayback, MidiLoop, and MidiRecord.

CoreMIDI, OMS, and FreeMIDI just aren't very good API's for writing MIDI programs. I'm studying the MusicKit API to see if it is perhaps a bit nicer.

[Later that evening...] I played with PyObjC. Looks like quite an amazing piece of software! It takes frameworks and makes them available to Python programs. Now there seem to be three ways to call the MIDI library I'll write from Python:

  • write it in C or C++ and generate the interface using SWIG,
  • write it in Objective C, package it as a framework, and use the PyObjC bridge, or
  • write it in C, C++, or Objective C and also write a wrapper for it (in C) using the Python/C API.
Each method has its advantages and disadvantages. Presently I'm more inclined to use the last one since I won't have to rely on another piece of software. There's also flexibility in the implementation language. As long as I don't change the API a lot, writing the wrapper by hand shouldn't be that bad.

SWIG and Python Distutils
Thursday September 25, 2003

Today I learned to use the Python distutils to build dynamically loaded modules. A module is written in C and its attributes are described in a file setup.py. Distutils then takes care of building it. It'll even package the module for distribution in various forms.

Then I played with SWIG a little. It takes a C header file (basically) and generates wrappers for functions in it so that they can be called from different languages. The documentation doesn't explain how Python modules should be generated on Mac OS X. Running the distutils build command with the --dry-run option shows what the compiler and linker options look like.

Afterwards I found out that distutils is clever enough to call SWIG if source files have the .i suffix. So the setup.py file below will correctly build a Python module from the files example.i and example.c. Quite painless.

import distutils
from distutils.core import setup, Extension

setup(name = "Example in SWIG tutorial",
      version = "1.0",
      ext_modules = [Extension("_example", ["example.i","example.c"])])

Finally, I have this new version of yesterday's turtle graphics program with embedded Python. This time, the graphics routines are written with ordinary C calling conventions. SWIG is used in a PB “shell script build phase” to generate a wrapper to make these routines available in Python. Note that SWIG adds an underscore before the module name, making it _Tortoise.

Turtle Graphics with Embedded Python
Wednesday September 24, 2003

I embedded Python instead of Guile in the turtle graphics toy, resulting in this PB project. To build it you need to first build and install Python 2.3 as a framework as described in Python-2.3/Mac/OSX/README. The tortoise (static) module exports the functions reset, pendown, penup, move, and turn. To play with it, type Python statements into the text view and click “Evaluate”. Try this:

import tortoise

def move_and_turn(angle):
    tortoise.move(100)
    tortoise.turn(angle)

for i in range(9):
    move_and_turn(80)

Indentations are made by tabs, not spaces. You may need to enter each statement separately.

Python Spam Cleaner Script
Monday September 22, 2003

OK, this spam thing is getting out of hand. So here is a Python script for fetching message headers from a POP3 server and offering to delete them if they satisfy certain criteria. Only headers are fetch so this is faster than checking mail using a regular mail client. Since the worm permutates buzzwords in the subject line, currently only multipart/mixed and multipart/alternative messages in certain size ranges are offered for deletion. This seems to catch over 80% of the spam messages.

Meanwhile I should finish reading the Python tutorial today and start looking at embedding Python in a Cocoa program.

Damned E-mail Worm
Sunday September 21, 2003

Thanks to the worm, I now realize how many people have my address on their computers :-). What baffles me is how careless my friends can be in preventing their computers from being attack. Mind you, some of them are people knowledgeable in computer science, like CS professors!

If this thing continues, it'll be quite easy to write a tool to automatically screen the messages at my POP account before fetching them. In the mean time, I'm using a modified version of this little Python script to do that manually.

To edit the script in Emacs, I used this Python mode.

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