Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
JJazzLab relies on the Netbeans Platform which provides a modular infrastructure. You'll find below the most important modules of JJazzLab.
ActiveSong Manage the active song. JJazzLab can open several songs in parallel, but only the active one is allowed to send Midi data.
ChordLeadSheet The model for the chord leadsheet: it defines a number of bars and a list of ChordLeadSheetItems : CLI_ChordSymbol (chord symbol at a given position) and CLI_Section (section name and time signatue at a given bar).
CL_Editor The graphical editor for a ChordLeadSheet object.
Harmony All the harmony related base classes, Note, Degree, TimeSignature, ChordSymbol, ChordType, Scale, etc.
Midi General Midi related classes.
MidiMix The model to store a set of instruments and settings (e.g. which Midi bank/program change for the piano voice, which volume, reverb, transposition, etc.). Also contains the MidiMixManager which associates a MidiMix to a song object.
MixConsole The graphical editor for a MidiMix object.
MusicControl Control the music playback (start, pause, etc.), which includes the launch of the backing track generation process.
Rhythm The model for a rhythm (=a style). Also define the RhythmProvider interface which should be implemented by third-party rhythm generation engines.
RhythmDatabase Manage the available rhythms on the system. Upon startup the RhythmDatabase scans the available RhythmProvider implementations which provide the rhythm instances.
RhythmMusicGeneration Utility classes for music generation. Defines the MusicGenerator service provider interface.
Song The model for a song. A song mainly contains a chord leadsheet and a song structure.
SongEditorManager The central place where all song editors are created (from scratch, loaded from file, etc.) and managed.
SongStructure The model for a song structure: a list of SongParts. A SongPart defines a parent CLI_Section (see ChordLeadsheet model), a rhythm, and the value of each of the rhythm parameters.
SptEditor The graphical editor for a SongPart.
SS_Editor The graphical editor for a SongStructure object.
Song
The Song object is the main data model. It is mainly composed of a ChordLeadSheet and a SongStructure.
The ChordLeadSheet
object is the model of the Chord leadsheet editor. It holds the sections and the chord symbols.
The SongStructure
object is the model of the Song structure editor. It holds the SongParts, each one being linked to a parent section, and each one defining a set of RhythmParameter
values.
Combining the SongStructure
and the ChordLeadSheet
will give you the "unrolled" chord lead sheet for which the backing track must be generated.
MidiMix
The MidiMix stores the Midi configuration of a given Song
. It is mainly used by the framework to control the Midi output device. Your MusicGenerator
will use it only to retrieve the Midi channel associated to a Rhythm
track (RhythmVoice
).
Supporting classes used in the Song
: TimeSignature, ChordSymbol, Degree, etc.
Supporting classes useful for your MusicGenerator
:
ContextChordSequence: a helper class to get the "unrolled" chord leadsheet descrive above.
Grid: music phrase manipulation methods
Phrases: music phrase manipulation methods, including methods to adapt a music source phrase (e.g. a bass pattern for C7M) into a different chord (e.g. Ab-6)
etc.
The main APIs you'll be using are found in the Rhythm
and RhythmMusicGeneration
modules:
Give JJazzLab-X access to one or more Rhythm
objects provided by your engine
The main interface which provides descriptive information about the rhythm, with its RhythmVoices
, and hythmParameters
.
MusicGenerator
A Rhythm implementation should also implement the MusicGenerator
interface to be able to generate music
There is one RhythmVoice
for each track generated by your rhythm, e.g. "Drums", "Bass", "Piano"
The parameters to modulate the rhythm, e.g. "Complexity" or "Fill"
You should first create your own Netbeans module, as explained in the Getting started page.
Your engine must be recognized by the JJazzLab framework, so that it can be accessible to the end-user. For this you'll need to start by adding a RhythmProvider
implementation, as explained below.
RhythmProvider
The RhythmProvider
interface is defined in the Rhythm module.
Your implementation must use the @ServiceProvider
annotation so that the RhythmDatabase
instance can automatically find it upon startup. The general Netbeans mechanism used is described here.
When user needs to pick up a rhythm, the rhythm selection dialog asks the RhythmDatabase
to provide the available RhythmProvider
instances (e.g. "Yamaha style based generator") and their list of rhythms (e.g. "jazz", "pop", ...).
The RhythmProvider
implementation is responsible to provide:
An Info
object (name, description, author, version, uniqueId)
The list of built-in Rhythm
objects provided by this implementation
The list of file-based Rhythm
objects provided by this implementation
An optional settings dialog to tune the rhythm generation engine
Example: See RhythmStubProviderImpl.java for a simple RhythmProvider
implementation example.
Rhythm
A Rhythm
interface describes... a rhythm !
name, for example "samba-fast"
description
time signature
preferred tempo
feel : ternary/binary
etc...
It also defines the RhythmVoices
, RhythmParameters
.
The Rhythm implementation must also implement the MusicGenerator
interface to be able to generate music.
Example: See RhythmStub.java for a very simple Rhythm
implementation example.
RhythmVoice
There is one RhythmVoice
for each track generated by this rhythm, e.g. "Drums", "Bass", "Piano". The RhythmVoice
provides the recommended Midi instrument and settings for the track.
The RhythmVoices
information is used for example by the Mix Console to display the relevant tracks.
RhythmParameter
Examples of RhythmParameters
are "Variation", "Fill", or "Complexity".
The RhythmParameters
are the control knobs given to the user so he can modulate the rhythm for each song part. You see them in the Song Structure Editor, for each Song Part.
There are ready-to-use classes to quickly define your RhythmParameters
depending on their type (a boolean value, one value amongst a set of values, etc). When these classes are used the framework will automatically show the relevant UI widget in the Song Structure Editor. You can also define your own UI widgets if you prefer.
MusicGenerator
This is an interface which indicates the capability to generate rhythm music. It has just a single method which takes the music generation context as a parameter, and returns the musical phrases (one per track) that make the backing track.
When user presses the Play button for a given song, JJazzLab-X will:
prepare the MusicGenerationContext (e.g. mainly a Song object which contains a ChordLeadSheet and a SongStructure)
If Rhythm
implements the MusicGenerator
interface, pass it the context data and ask it to generate the backing track
wait until the MusicGenerator
has finished the music generation
convert the received music data into a Midi sequence
play the sequence.
So the MusicGenerator
is really where the heavy stuff will be done by your engine. There is no synchronization constraint since JJazzLab will simply block until music generation is complete.
Note that you can use any technology to perform the generation, including non-Java ones. Only the lightweight API that connects to JJazzLab needs to be in Java.
Example: See DummyGenerator.java for a very simple MusicGenerator
implementation example.
JJazzLab is a Midi-based application dedicated to backing tracks generation.
The ultimate objective is to develop a jam buddy able to quickly generate intelligent and interesting backing tracks: realistic and non-boring backing tracks which you can easily adjust to specific songs.
JJazzLab has a rather well-commented source code: don't hesitate to browse the GitHub repository or the Javadoc API.
Thanks to JJazzLab developers can save a huge amount of work by only focusing on their music generation engine. Out of the box, the JJazzLab framework provides all the infrastructure, all the “plumbing” that, before, every developer had to write themselves.
JJazzLab can host any number of music generation engines as plugins. What happens when you load a song file and press the Play button?
The framework shows the song in the editors
The framework sends Midi messages to initialize the connected Midi sound device
When user press Play, the framework sends the song data to the music generation engine
The music engine uses the song data to generate the Midi data for the backing tracks
The framework retrieves the Midi data and plays it
JJazzLab is based on the Apache Netbeans Platform. It provides a reliable and extensible application architecture.
The Netbeans Platform turns JJazzLab into a pluggable application where plugins can be installed or deactivated at runtime. Plugins can easily add or alter features and the related UI elements such as menu items.
For example suppose that you work on reharmonization algorithms (e.g. replace | A7 | D7M | by | Em7 A7 | D7M). It's easy to add a feature which propose possible reharmonizations when user selects multiple chord symbols. You'll just create a new action class which implements the algorithm on the current chord symbols selection, and "connect" (via annotations, no code required) this action to a new menu item in the Chord Symbol popup menu, as explained in the Getting started page.
!!!! THIS PAGE IS OUTDATED WITH JJAZLAB 4.0 !!!!
JJazzLab is based on the Apache Netbeans Platform (formerly Netbeans RCP for Rich Client Platform). It provides a reliable and extensible architecture for desktop application which manages the application life cycle, the window system, extension points, options, actions, etc.
Each distinct feature in a Netbeans Platform application can be provided by a distinct Netbeans module, which is comparable to a plugin. A Netbeans module is a group of Java classes that provides an application with a specific feature.
So unless you want to fix the JJazzLab code itself, you will probably start by creating your own Netbeans module.
In this example we want to add a new feature which proposes re-harmonized chord progressions. The reharmonization action will operate on the chord symbols selected by the user, and should be accessible via the chord symbol popup menu.
Let's first create a new module to hold our code.
In the Netbeans IDE, select JJazzLab/modules then Add New... in the popup menu.
In the Netbeans IDE, select JJazzLab/modules then Add New... in the popup menu
Enter any name, e.g. "Reharmonize"
Specify any code name base (java package name), e.g. "org.myself.reharmonize"
You new module will appear in the JJazzLab-X modules list. Open it. You should have something like this:
The Important Files folder contain the module configuration files, which usually you don't have to modify manually (this is done automatically by the IDE, typically using the module Properties dialog).
Select the Reharmonize module then **Properties **in the popup menu. The important settings are:
Source level: must be set to 11 (enable Java 11 language features)
**Libraries **: dependencies on other modules (JJazzLab modules or Netbeans application framework modules), plus possibly dependencies on external libraries used by your module
API versioning: this is where you declare the public packages of your module, i.e. the packages visible by other modules when they add your module as a dependency
**Example **: below are the properties of the JJazzLab **Quantizer **module:
As you see below, the Quantizer module has dependencies on 2 JJazzLab modules: ChordLeadSheet and Harmony. The 2 other ones (Base Utilities API and Lookup API) are modules from the Netbeans application framework.
The Quantizer module has only a single API package, which is made public to other modules, via the Public Packages list in the API versioning category.
We want to create a "Reharmonize" action which should be callable from the chord symbol popup menu, and should operate on the user-selected chord symbols.
The best way to start is to look for a similar action and copy the code. Actions classes are mainly found in the following modules:
CL_Editor** **module : Chord Leadsheet editor actions such as insert bar, transpose chord symbols, etc.
SS_Editor module : Song Structure editor actions such as delete song part, change rhythm, etc.
MixConsole module : save default rhythm mix, mute all, etc.
MusicControlActions module: play, stop, etc.
SongEditorManager module: new song, open song, duplicate song, etc.
The chord leadsheet editor action TransposeDown** **is enabled when user has selected one or more chord symbols, so this could be our code basis. Let's refactor-copy the java file in our module :
In the Netbeans IDE:
Open the CL_Editor module, find, select and copy TransposeDown.java.
Open the **Reharmonize **module, select the org.myself.reharmonize package, and choose **Paste **(refactor copy)
A dialog appears, set the new name to Reharmonize.java and press Refactor, the file is created.
Reharmonize.java has many errors: this is due to the missing module dependencies. You could manually update the module properties as explained above, but there is an easier way, directly from the editor, as shown below.
Roll the mouse over the light bulb on the left margin, and click on the popup Seach Module Dependency for org.xxx. This brings the Add Module Dependency with the Filter field initialized with the dependency to be searched. Wait a few seconds and the relevant dependency should appear: select it and press OK.
Repeat the same operation until all dependencies are fixed.
Now you should have only one error in the file:
Netbeans uses annotations to facilitate action declaration:
In the @ActionID declaration, replace the **id **string by a string of your choice, e.g org.myself.reharmonize. This id can be used from any other module to run the action via the Netbeans API Actions.forID().
The action displayName is #CTL_TransposeDown, and the leading # means the string value is searched in the localization Bundle.properties localization file in the same package (so it can be easily internationalized). As we copied only the .java file, the string definition is missing in our Bundle.properties file. Let's fix this:
Change all the CTL_TransposeDown strings to CTL_Reharmonize in Reharmonize.java
Edit Bundle.properties and add a line with CTL_Reharmonize=Reharmonize chord progression
The @ActionReference puts a reference to this action in the Netbeans virtual file system (created at runtime), in the Actions/ChordSymbol directory. When user shows the chord symbol popup menu, JJazzLab-X takes all action references found in this directory and creates the related menu entries, using the **position **value to order them.
In @ActionReference change position value to 415, so our action will appear in the popup menu after the TransposeDown action.
Now the module should be compilable. Select the **Reharmonize **module then **Build **from the popup menu.
Run JJazzLab-X, then in a song select a chord symbol and show the popup menu: our action should be there, as shown below. If you select it it will transpose down the chords symbols, as we have not yet changed the action code itself.
Consult the Netbeans platform online doc for more information about the Netbeans platform API.
The 2 most important methods are:
selectionChange(), which is called each time selection has changed (e.g. user has selected or unselected bars/chord symbols/sections) with a selection context parameter. This is used to enable or disable the action depending on the selection.
actionPerformed(), which performs the action.
The automatic selection change mechanism in the active Chord leadsheet editor is provided by the **CL_ContextActionSupport **helper class. This mechanism is based on the powerful Netbeans global Lookup mechanism, which is a out of scope of this simple tutorial -but you will easily find explanations on the web.
Below is a sketch of a possible Reharmonize action implementation.