| Path: | doc/README_FOR_APP |
| Last Update: | Mon Apr 20 19:46:07 -0400 2009 |
Jazz Toolbox is an online Jazz utility driven by a full object-relational and REST model of concepts in Jazz theory, establishing relationships between chords and scales, and much more. The web interface is a fully Ajaxified Web 2.0 interface towards exploring these relationships and answering questions about the jazz science. The REST interface exposes the underlying data model and relationships to other developers wishing to use Jazz Toolbox as a source for their own web applications.
The core of Jazz Toolbox is a full Ruby object model representing concepts of Jazz theory, distilled to their most basic concepts and architected in a very abstract manner. The system is data-centric and all "rules" (for example, the tones in a C7 chord) in theory are self-contained in the database.
All chord/scale/mode/etc. definitions are stored as a mathematical system (sequences of numbers) which are then used to perform calculations. For example, putting some chord in a different key is a matter of adding a semitone delta and doing modulo 12.
While there are currently many chord calculators in existance, to my knowledge this project is the first one that attempts to fully represent the entirety of Jazz theory as a mathmetical/computational system exposed through an elegant object model.
Currently Jazz Toolbox is only a Ruby object model but will eventually be coupled with a nice front-end at JazzToolbox.com. The object model is built using ActiveRecord (ORM for Rails) and makes extensive use of powerful features in ActiveRecord such as Module mixins on AssociationProxy. Dispite being backed by a database, almost the entire database is cached into memory for fast calculation and performance, as the data representation and calculations are somewhat more complex than what can be afforded using only SQL. A Data Mapper ORM implementation may be in the works, if I can figure out a substitute for ActiveRecord Association Extensions.
Also, the current database consists entirely of my own personal knowledge of Jazz theory. I haven‘t yet scoured through the Jazz theory literature to formalize and expand the current database of chords, scales, and chord-scales.
Chord['maj7'] Chord['Bbmaj7'] # <- With Key Context Chord['Abmaj7#11'] ...
Scale['Major'] Scale['Melodic Minor'] Scale['Diminished'] ...
Scale['Major'].modes['Dorian'] # By Mode Name Scale['Major'].modes[2] # By Mode Index # Or directly index the scale object (same as above): Scale['Major']['Dorian'] Scale['Major'][2]
Chord['maj'].notes # Defaults to C without specified key context
# => ['C', 'E', 'G']
Chord['Ebmaj7'].notes
# => ['Eb', 'G', 'Bb', 'D']
# Or specify key context with chained methods like this...
Chord['maj7'].in_key_of('Eb').notes
Chord['Bmaj7#11'].notes
# => ['B', 'D#', 'F#', 'A#', 'E#']
# Note E# - Correct theoretic value for this chord, not F
Chord['Falt'].notes
Chord['F7b9#9'].notes
# => ['F', 'A', 'Eb', 'Gb', 'G#', 'C#']
Chord['Gbmaj7'].notes
# => ['Gb', 'Bb', 'Db', 'F']
# But...
Chord['F#maj7'].notes
# => ['F#', 'A#', 'C#', 'E#']
Scale['Major'].notes # Defaults to C without specified key context
# => ['C', 'D', 'E', 'F', 'G', 'A', 'B']
Scale['Eb Major'].notes
# => ['Eb', 'F', 'G', 'Ab', 'Bb', 'C', 'D']
# Or specify key context with chained methods like this:
Scale['Major'].in_key_of('Eb').notes
Scale['Whole Tone'].notes
# => ['C', 'D', 'E', 'F#', 'G#', 'Bb']
Scale['Bebop'].notes
# => ['C', 'D', 'E', 'F', 'G', 'A', 'Bb', 'B']
Scale['Major'].in_key_of('Eb').modes['Dorian'].notes
# => ['F', 'G', 'Ab', 'Bb', 'C', 'D', 'Eb']
Scale['Melodic Minor']['Lydian Dominant'].notes
# => ['F', 'G', 'A', 'B', 'C', 'D', 'Eb']
Chord['min7'].modes.names # .names == .map(&:name) # => ['Dorian'] Chord['min7'].modes[0].scale.name # => "Major" Chord['Amin7'].modes.names # => ['A Dorian']
Scale['Major']['Dorian'].chords.symbols
# => ['min7', 'min6']
Scale['Major'][4].chords.symbols
# => ['maj7#11']
Scale['Major'].chords.map {|c| c.name + ': ' + c.notes.join(', ')} * "\n"
# => Major 7: C, E, G, B
Major 6: C, E, G, A
Dominant 6/9: C, E, G, Bb, D, A
These examples should show that with the power of Ruby and the elegant nature of this API, extracting Jazz data from the system is a breeze (even fun!).
The REST API provides a simple XML web service interface to the underlying Jazz object model. Most of the examples are very straightforward since the URLs are simple resources. XML and JSON outputs are supported. For Rails developers, the best way to learn about the REST API is to examine the routes file, which is here:
map.resources :chord_qualities do |chord_qualities|
chord_qualities.resources :chords do |chords|
chords.resources :notes
end
end
map.resources :scales do |scales|
scales.resources :modes do |modes|
modes.resources :chords
end
scales.resources :chords
scales.resources :tones
scales.resources :notes
end
map.resources :chords do |chords|
chords.resources :symbols
chords.resources :voicings
chords.resources :modes
chords.resources :tones
chords.resources :notes
end
map.resources :notes_collection do |notes_collection|
notes_collection.resources :chords
end
GET /chords.xml
# => <chords>
<chord name="Minor 7">
<symbols>
<symbol name="min7" />
<symbol name="m7" />
<symbols>
</chord>
...
</chords>
GET /chords/min7.xml
GET /chords/Bbmin7.xml
GET /chords/Cmin7/notes.xml
# => <notes>
<note name="C" />
<note name="D" />
<note name="Eb" />
...
</notes>
GET /scales.xml
# => <scales>
<scale name="Major">
<modes>
<mode name="Ionian" mode="1" />
<mode name="Dorian" mode="2" />
...
</modes>
</scale>
</scales>
GET /scales/major.xml
GET /scales/major/modes/dorian.xml
GET /scales/major/modes/ionian/notes.xml
# OR:
GET /scales/major/notes.xml # Defaults to 1st Mode
# => <notes>
<note name="C" />
<note name="D" />
<note name="E" />
...
</notes>
GET /scales/major/modes/dorian/chords.xml
# => <chords>
<chord name="Minor 7" />
<chord name="Minor 6" />
...
</chords>
GET /chords/min7/modes.xml
# => <modes>
<mode name="Dorian" mode="2">
<scale name="Major" />
</mode>
...
</modes>
GET /note_list/C,E,G,A/chords.xml
# => <chords>
<chord name="Minor 7" key="A" />
<chord name="Major 6" key="C" />
</chords>