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.

Reading Chord Sequences
Friday February 6, 2004

C++ strings and STL containers and iterators provide programmers with the functionality of NSString and Foundation Collections, with higher efficiency and better type safety. Another reason to write in C++, instead of Objective C, is portability to other platforms.

A sample program only half a page long will parse and read chord charts such as this one:

| Fmaj7  | Em7b5 A7  | Dm7   G7  | Cm7  F7  |
| Bbmaj7 | Bbm7  Eb7 | Am7   D7  | Abm7 Db7 |
| Gm7    | C7        | Fmaj7 Dm7 | Gm7  C7  |
Compared to NSString and Foundation collections, C++ strings and STL containers are much nicer to use because they’re more “integrated” into the language (like playing well with exceptions, automatic destruction when objects go out of scope, etc.). They’re a little harder to learn. This is probably one of the reasons many Mac programmers prefer Objective C over C++. Then again, I know many people who say they prefer this language and that language over C++, although I don’t think they know C++ very well :-).

Implementing Chords
Thursday February 5, 2004

The representation of chords in MusES, although flexible, isn’t particularly user-friendly. A chord such as C7b5 is printed as [C dim5 7], instead of a more customary chord symbol. This is probably no better than printing a chord as its root and list of intervals.

In my C++ implementation, a chord object contains its root note, (string) type, and list of intervals. A singleton class member contains a STL map from chord types to the corresponding interval lists, for all chords known to the library. A chord is constructed by specifying its root and type. In tonality analysis, it will be necessary to determine the type of a chord. The member functions isMajor() and isMinor() can be used to check whether a chord is a major or minor chord. The member function hasInterval() can be used to check whether a chord contains any given interval. Since interval lists are represented by STL vectors, these member functions are all implemented by a single statement.

Here’re a sample program for chords and its output.


#include <iostream>
#include "JazzTheoryClasses.h"

int main (int argc, char * const argv[]) { Chord Abmaj7(Note(A, Flat), "maj7");

std::cout << Abmaj7 << " [" << Abmaj7.notes() << ']' << std::endl;

std::cout << Abmaj7.isMajor() << std::endl; std::cout << Abmaj7.isMinor() << std::endl; std::cout << Abmaj7.hasInterval(majorSeventh) << std::endl; std::cout << Abmaj7.hasInterval(minorSeventh) << std::endl;

return 0; } Abmaj7 [Ab C Eb G ] 1 0 1 0

Notes and Scales as Classes, not Class Hierarchies
Wednesday February 4, 2004

In MusES, notes are instances of the class NaturalNote, SharpNote, DoubleSharpNote, FlatNote, or DoubleFlatNote. The entire class hierarchy for notes consists of these and two abstract classes. Such complexity is unnecessary. Notes of different classes don’t behave that differently and can be represented adequately by just a single class, if the arithmetic is performed carefully. This is what I have done in my C++ implementation.

Different scales are also represented by different classes in MusES. The only thing that distinguishes the classes is the scales’ interval lists. This is again unnecessary. It’s interesting to note that intervals and chords are represented by single classes in MusES. This is in fact the suitable choice.

A few better questions to ask in the design of scales and chords might be as follows.

  • Should the set of chords and scales that are recognized by the system be expandable? If so, will the code need to be recompiled to add new ones?
  • How should a chord or scale type be specified in the program code? Should it be specified by a variable name/enumerated constant (e.g., as Chord(Note(A), major)) or should an “external” string name be used (e.g., as Chord(Note(A), "major"))?
  • How will scales and chords be used in an application such as tonality analysis?
I have studied these questions today and worked out a design. I’ll try to describe it tomorrow.

Note/Interval Arithmetic and Scales
Tuesday February 3, 2004

I’ve implemented some more of my C++ classes for representing notes and intervals. As in MusES the note resulting from adding or subtracting an interval to or from a note has the correct enharmonic spelling. I then added a class for scales. Here’re another sample program that demonstrates the new functions and its output. The last scale is not valid according to Pachet’s definition but it should be easy to add an additional check. I’ll work on chords tomorrow but it seems that I need to do some design work. The implementation of chords in MusES is highly flexible but I believe a better defined set of chords will make analysis more manageable.


#include <iostream>
#include "JazzTheoryClasses.h"

int main (int argc, char * const argv[]) { std::cout << Note(F, Sharp) - diminishedFifth << std::endl; std::cout << Note(G, Flat) - diminishedFifth << std::endl;

std::cout << Note(F, Sharp) - Note(C) << std::endl; std::cout << Note(G) - Note(C, Sharp) << std::endl;

std::cout << Scale(Note(A, Flat), Major) << std::endl; std::cout << Scale(Note(C), HarmonicMinor) << std::endl; std::cout << Scale(Note(G, Sharp), Major) << std::endl; } B# C augmentedFourth diminishedFifth Ab Major [Ab Bb C Db Eb F G] C HarmonicMinor [C D Eb F G Ab B] G# Major [G# A# B# C# D# E# F##]

C++ Classes for Jazz Theory
Monday February 2, 2004

I read Scott Meyer’s book Effective STL last weekend. It’s a nice book for someone who already knows some STL and wants to gain confidence in using it correctly. For an introduction to STL, try Musser and Saini’s STL Tutorial and Reference Guide: C++ Programming with the Standard Template Library.

I’ve implemented C++ classes to represent notes (pitch classes) and intervals that behave like their Smalltalk counterparts in MusES as described by Pachet. Here’re a sample program that contains some of his examples on notes and intervals and its output.


#include <iostream>
#include "JazzTheoryClasses.h"

int main (int argc, char * const argv[]) { std::cout << Note(C) << std::endl; std::cout << Note(C, Sharp) << std::endl; std::cout << Note(C).sharp().sharp().flat() << std::endl; try { std::cout << Note(C).flat().flat().flat() << std::endl; } catch (std::exception &e) { std::cout << e.what() << std::endl; } std::cout << Note(C, Sharp).pitchEquals(Note(D, Flat)) << std::endl;

std::cout << Note(C) + diminishedFifth << std::endl; std::cout << Note(C) + augmentedFourth << std::endl; std::cout << Note(C) + majorThird + majorThird << std::endl; std::cout << Note(C, Flat) + minorSeventh << std::endl; try { std::cout << Note(C, Flat) + diminishedSeventh << std::endl; } catch (std::exception &e) { std::cout << e.what() << std::endl; } }

C
C#
C#
Cannot flat a double flat
1
Gb
F#
G#
Bbb
Adding interval resulted in illegal note

February 2004
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
Jan  Mar

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