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.

More Improvements for Walking Bass Line Generation
Thursday March 18, 2004

I’m still working on fine-tuning the bass line generation algorithm and extending it to handle more general cases, for example, chords that last more than a bar, ones that last three beats, etc. From the input file

Title: I Left My Heart In San Franciso
Meter: 4/4
Key: Bb
Tempo: 100
| Bb | Dm7 C#dim7 | Cm7 | |
| Cm7 | Cm7/F F7#5 | Bb | _ _ Cm7 C#dim7 |
| Bb | Dm7 C#dim7 | Dm7 | _ D7b9 |
| Gm7 | C9 C7b9 | F9 Bdim7 | Cm7 F7 |
| Bb | Dm7 C#dim7 | Cm7 | |
| F9 | _ Eb9 | D7 | |
| G7#5 _ _ G9 | | C _ _ Gm7 | C9 |
| Cm7 | Cm7/F F7b9 | Bb6 _ Ab69 A69 | Bb69 |
The program now generates this bass line (MIDI file):

Better Bass Lines for 4-Beat Chords
Wednesday March 17, 2004

My code for generated bass lines for chords lasting 4 beats now works differently depending on the size of the interval between the first notes of the current and next chords. If it is big, it’ll try to find notes between them. Otherwise it’ll find notes outside the range they define. In the following example, bars 1and 5 fall into the former category while bars 9 and 10 fall into the latter. Here’s the MIDI file for these notes.

A further improvement to the algorithm will be to detect patterns in the chords (ii-V’s, turnarounds, and possibility of play ascending and descending lines, for example) and play “set pieces”. Programmatically this requires quite a different mechanism than what I currently have so some program design work is necessary before I can try to implement this. This is what I’ll work on next.

Bass Lines in MIDI Files
Tuesday March 16, 2004

I adapted some code I wrote earlier to write the bass lines generated by my program to MIDI files. I’ll work on fine-tuning and improving the algorithm next and I find it much easy to listen to the output instead of look at it (here’s an example). Another advantage of having MIDI files is they can be imported into a program like Finale, and the bass line can be viewed in standard notation (here’s an example; the chord names were entered by hand at this time).

MIDI Note Generators
Monday March 15, 2004

Today I designed and implemented a MIDINoteGenerator class, one which encapsulates the information for making random choices of MIDI notes in the course of generating walking bass lines. I also rewrote my program to use it and obtained a much cleaner and shorter program!

MIDI note generators can be created and then combined using operator& and operator|. The member function genNote() can then be called to generate a MIDI note according to the specifications stored in the MIDI note generator. There are a number of different constructors, resulting in different types of MIDI note generators.

  MIDINoteGenerator(const MIDINote& lowerBound, const MIDINote& upperBound,
                    short freq = 1);
  MIDINoteGenerator(const MIDINote& mn, short freq = 1);
  MIDINoteGenerator(const Note& note, short freq = 1);
  MIDINoteGenerator(const Chord& chord, short freq = 1);
  MIDINoteGenerator(const Scale& scale, short freq = 1);
The first constructor will create a MIDI note generator that selects notes within a certain range with equal probability. The second always selects the same MIDI note. The third selects MIDI notes in the same pitch class with equal probability. The fourth and fifth selects MIDI notes from a chord and a scale, respectively, with equal probability. The & operator combines two MIDI note generators and the result generates MIDI notes that satisfy both of them. For example, the MIDI note generator
MIDINoteGenerator(MIDINote(C, 2), MIDINote(G, 3)) &
  MIDINoteGenerator(Chord(C, "Maj7"))
generates chord notes of CMaj7 between C2 and G3, inclusively. The result of the | operator generates MIDI notes that satisfy either of its operands. It also combines the “frequencies” of individual MIDI notes by addition. This determines how likely the MIDI notes are chosen. For example, the MIDI note generator
MIDINoteGenerator(Note(C), 70) |
  MIDINoteGenerator(Note(E), 15) |
  MIDINoteGenerator(Note(G), 15)
generates a MIDI note with pitch classes C, E, and G, with 70%, 15%, and 15% probability, respectively. Note that frequency values are relative and probabilities are computed from them by by dividing by the total of frequencies of all MIDI notes. To illustrate the use of these MIDI note generators, here’s an excerpt from my program where the first notes of the chords are chosen.
...
if (!(thisChord.getBass() == thisChord.getRoot()))
  gen = MIDINoteGenerator(thisChord.getBass());
else
  gen = MIDINoteGenerator(thisChord.getRoot(), RootFrequency) |
        MIDINoteGenerator(ThirdOfChord(thisChord), ThirdFrequency) |
        MIDINoteGenerator(FifthOfChord(thisChord), FifthFrequency);

if (prevDuration.getNumerator() <= 2) gen = gen & MIDINoteGenerator(prevBass - MaxTwoBeatSemiToneLeap, prevBass + MaxTwoBeatSemiToneLeap);

return (gen & standardMNG).genNote();

The first if statement tests whether we’re dealing with a slash chord. If so, use its bass note. Otherwise construct a MIDI note generator that’ll generate the root, third, or fifth of the chord with the appropriate probabilities. The second if statement tests whether the previous chord has short duration. If so, we limit the range of the possible MIDI notes generated to avoid a big upward or downward leap. Finally the MIDI note generator is further constrained to generate MIDI notes in the standard playing range of the bass guitar, respresented by the non-local object standardMNG. This MIDI note generator favors MIDI notes in a certain “normal” range but at the same time allows MIDI notes in an “extended” range to be generated with lower probability.

March 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 30 31
Feb  Apr

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