|
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.
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.
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.
|
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
|