public
Description: Jazz Toolbox - An computational model for Jazz theory with a strong object and REST API
Homepage: http://www.jazztoolbox.com/
Clone URL: git://github.com/railsgarden/jazztoolbox.git
name age message
file .gitignore Sun Apr 13 23:02:19 -0700 2008 Initial Import from SVN Repo [railsgarden]
file CHANGELOG.txt Sun Aug 24 06:50:03 -0700 2008 Preferential name changes. [railsgarden]
file Capfile Sun Apr 13 23:02:19 -0700 2008 Initial Import from SVN Repo [railsgarden]
file README.rdoc Mon Apr 20 16:16:09 -0700 2009 Fixed minor issue with README. [railsgarden]
file Rakefile Sun Apr 13 23:02:19 -0700 2008 Initial Import from SVN Repo [railsgarden]
file TODO.txt Sun Apr 13 23:02:19 -0700 2008 Initial Import from SVN Repo [railsgarden]
directory app/ Thu Apr 02 20:38:28 -0700 2009 Refactored specs quite a bit with newer rspec f... [railsgarden]
directory config/ Thu Apr 02 18:48:16 -0700 2009 Completed Rails upgrade. [railsgarden]
directory db/ Sun Apr 13 23:02:19 -0700 2008 Initial Import from SVN Repo [railsgarden]
directory doc/ Wed Nov 26 16:12:01 -0800 2008 New documentation. [railsgarden]
directory lib/ Wed Nov 26 16:10:33 -0800 2008 Renamed readme. [railsgarden]
directory public/ Thu Apr 02 18:42:18 -0700 2009 Cleared out older test files and changed to Rai... [railsgarden]
directory script/ Sat May 31 17:33:25 -0700 2008 Froze Rails 2.1 [railsgarden]
directory spec/ Thu Apr 02 20:52:39 -0700 2009 Refactored controller specs to use expanded sho... [railsgarden]
directory vendor/ Thu Apr 02 18:48:16 -0700 2009 Completed Rails upgrade. [railsgarden]
README.rdoc

Jazz Toolbox

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.

Architecture Overview

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.

Current State

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.

Core Features

  • Very Clean API
  • Scale & Mode Enumeration
  • Handles Variety of Notations
  • ChordTone Enumeration
  • Traversing ScaleChord Relationships with Strength Metric
  • Full Understanding of Theoretic Tones (vs. only Pitches)
  • Voicings Associated with Chords

Anticipated Future Features

  • Chord Progression Analysis
  • MIDI Integration
  • User Comments & Contributions (such as Chord-Scale recommendations)
  • Melodic Components & Licks

Ruby API Examples

  • Getting a Chord object:
     Chord['maj7']
     Chord['Bbmaj7']  # <- With Key Context
     Chord['Abmaj7#11']
     ...
    
  • Getting a Scale object:
     Scale['Major']
     Scale['Melodic Minor']
     Scale['Diminished']
     ...
    
  • Getting a particular mode of a scale:
     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]
    
  • Enumerate notes of a Chord:
     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#']
    
  • Enumerate notes of a Scale:
     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']
    
  • Enumerate notes from a Scale Mode:
     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']
    
  • Enumerate scale modes associated with a chord:
     Chord['min7'].modes.names  # .names == .map(&:name)
     # => ['Dorian']
     Chord['min7'].modes[0].scale.name
     # => "Major"
    
     Chord['Amin7'].modes.names
     # => ['A Dorian']
    
  • Enumerate chords associated with a scale mode:
     Scale['Major']['Dorian'].chords.symbols
     # => ['min7', 'min6']
    
     Scale['Major'][4].chords.symbols
           # => ['maj7#11']
    
  • Ruby Example Problem: Find all chords associated with the Major (Ionian) scale and print each on a new line with the chord tones.
     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!).

REST API

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:

Routes File

  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

REST API Examples

  • List all chords:
     GET /chords.xml
     # => <chords>
            <chord name="Minor 7">
              <symbols>
                <symbol name="min7" />
                <symbol name="m7" />
              <symbols>
            </chord>
            ...
          </chords>
    
  • Show Chord (Without Key Context):
     GET /chords/min7.xml
    
  • Show Chord (With Key Context):
     GET /chords/Bbmin7.xml
    
  • Enumerate notes in a given chord:
     GET /chords/Cmin7/notes.xml
     # => <notes>
            <note name="C" />
            <note name="D" />
            <note name="Eb" />
            ...
          </notes>
    
  • List all scales:
     GET /scales.xml
     # => <scales>
            <scale name="Major">
              <modes>
                <mode name="Ionian" mode="1" />
                <mode name="Dorian" mode="2" />
                ...
              </modes>
            </scale>
          </scales>
    
  • Show Scale:
     GET /scales/major.xml
    
  • Show Mode:
     GET /scales/major/modes/dorian.xml
    
  • Enumerate notes in a given scale:
     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>
    
  • Enumerate chords associated with a scale mode:
     GET /scales/major/modes/dorian/chords.xml
     # => <chords>
            <chord name="Minor 7" />
            <chord name="Minor 6" />
            ...
          </chords>
    
  • Enumerate scale modes associated with a chord:
     GET /chords/min7/modes.xml
     # => <modes>
            <mode name="Dorian" mode="2">
              <scale name="Major" />
            </mode>
                                          ...
          </modes>
    
  • Enumerate all potential chords matched from a list of notes:
     GET /note_list/C,E,G,A/chords.xml
     # => <chords>
            <chord name="Minor 7" key="A" />
            <chord name="Major 6" key="C" />
          </chords>