Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Jazz Toolbox - An computational model for Jazz theory with a strong object and REST API
branch: master

This branch is 24 commits behind rubiety:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
app
config
db/migrate
doc
lib/tasks
public
script
spec
stories
test
vendor/plugins
.gitignore
CHANGELOG.txt
Capfile
README.rdoc
Rakefile
TODO.txt

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

<tt>

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 </tt>

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>
Something went wrong with that request. Please try again.