|
About Andrew Choi
MIDI Programs
MIDI File Player (External Device)
MIDI Destination Pop-Up Button
Other Programs Cocoa Sample Programs Syntax Coloring Using Flex Algorithms Jazz Chord Analysis as Optimization
|
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.
Im 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):
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, itll try to find notes between them. Otherwise itll 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. Heres the MIDI file for these notes.
I adapted some code I wrote earlier to write the bass lines generated by my program to MIDI files. Ill 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 (heres 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 (heres an example; the chord names were entered by hand at this time).
Today I designed and implemented a
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, heres 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);
The first if statement tests whether were dealing with a slash chord. If so, use its bass note. Otherwise construct a MIDI note generator thatll 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.
|
Lists
Less-Known Facts About Emacs
Chinese Restaurants in Calgary
Calgary/Banff Tourist Attractions
Top-10 Reason I Stopped Working on Emacs
Misc
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Copyright © 2003, 2004, 2005 Andrew Choi (Contact Information). | Created with FCBlog |