The K Desktop Environment

6. The kooBase API - extending functionality

This is under construction

This section shall introduce you into extending kooBase yourself in terms of programming extensions.
For this purpose you have to know a little C++. You don't have to work yourself into the kooBase sources, because I have implemented such a nice API...

6.1 Class KbNote, KbPart & KbTrack

The main classes under consideration are the Class KbNote, KbPart and KbTrack, going from small to large entities, i.e. A part contains notes, and a track may contain several parts.
NOTE: At this point of time, more than one part per track does not really work, or is at least VERY buggy!

6.2 Notes

The properties of a Note are:

  int freq;   // the frequency of the note:           0..127
  int vel;    // the velocity of the note:            0..127
  int len;    // the length (measured in MIDI ticks): 1..
  int pos;    // the (time-) position (MIDI ticks):   0..
  int enh;    // enharmonic shift (bb,b,-,#,x):       -2..2
              // (this only concerns the visual presentation
              // in the score-editor and will be lost when
              // exported to MIDI file format)
  Note* next; // a pointer to the next note in the part
Of course all these are private, so you have to use the following methods to access them:
  // to obtain the properties:
  int gFreq();
  int gVel();
  int gLen();
  int gPos();
  int gEnh();
  Note* gNext();
  // to change the properties
  void sFreq(int);
  void sVel(int);
  void sLen(int);
  void sPos(int);
  void sEnh(int);
  void sNext(Note*);
... where the prefixes g and s of course stand for get and set.
There exist several constructors, usually you want to create a note with all these properties via:
  int freq = 120;
  int vel = 86;  
  int len = 192; // this equals a 1/8 note
  int pos = 0;   // at the beginning of the song
  int enh = 0;   // no enharmonic shift
  Note * n = new Note(freq,vel,len,pos,enh);
Having another note
  Note * n2 = new Note(122,86,192,192,0);
you can connect them to form a (tiny) melody via
  n->sNext(n2);
The notes are arranged in parts. There are certain rules how to connect the notes with each other. Connecting them in the wrong order might have consequences in the presentation and playback!
For you not to worry about having the notes in the right order, kooBase provides convenient methods in the part class...

6.3 Parts

A part consists of notes and further properties these notes share (e.g. MIDI-Program = which instrument to use). To add a note n to a part p, you use the addNote() method:

  p->addNote(n);
or
  p->addNote(new KbNote(freq,vel,len,pos,enh));
This assures that the notes are put in the right order!
You can always get the first note of a part p by calling:
  KbNote * n = p->gFirst();
and the following notes by:
  KbNote * n1 = n->gNext();
If n is the last note, n->gNext() will be zero!

To construct a part for a track tr, just call:
  new KbPart(KbTrack * tr, int leftBar, int rightBar);
where tr is an object of class KbTrack, leftBar and rightBar describe the boundaries in terms of Bars.
If you don't have to worry about the track, just create a new one (see below).

6.4 Tracks

To create a track call (where main is the KbMain-object):

KbTrack * tr = main->addTrack();
With this track, you can create parts and notes like:
KbTrack * tr = main->addTrack();
KbPart  * pt = new KbPart(KbTrack * tr, 0, 4);
pt->addNote(new KbNote(78,86,192,0,0));

6.5 Example

To implement your own algorithm, you might want to copy and modify this example code:

go to the partFunctions directory

     cd kooBase/partFunctions
and define a new class inside a new header- and cpp file. In this example (that comes with the distribution) we want to write an algorithm that stretches a part by a factor of 2: All lengths and positions are multiplied by 2. So the files are called stretch.h and stretch.cpp.
The contents of stretch.h looks like this:
     #include "kbPartExtension.h"

     class KbPart;

     /**
      *  This is a sample extension. It multiplies all notes positions and lengths by two
      */
     class Stretch : public KbPartExtension
     {
      public:

       /// Constructor
       Stretch();

       /// defines the funtionality, (see stretch.cpp)
       virtual void act(KbPart * part);
     };
The contents of stretch.cpp looks like this:
     #include "stretch.h"
     #include "../kbPart.h"
     #include "../kbNote.h"

     /**
      *  This is a sample extension. It multiplies all notes positions and lengths by two
      */

     Stretch::Stretch()
       : KbPartExtension("Stretch")
     {}

     /**
      * This defines the algorithm that shall act on a part.
      */
     void Stretch::act(KbPart * part) {
       if (part!=0 && part->gFirst()!=0) {
         int offset = part->gFirst()->gPos();
         for (KbNote * note=part->gFirst();note!=0;note=note->gNext()) {
           note->sPos(offset+(note->gPos()-offset)*2);
           note->sLen(note->gLen()*2);
         }
       }
     }
Next, you have to inform kooBase about you new algorithm. When you edit the file kbPartExtension.cpp you will find a section like this:
     // *********************************************************************************
     // *********************************************************************************
     //
     // Insert your headers below:
     //

     #include "stretch.h"


     KbExtensionManager::KbExtensionManager()
     : ext(0), cur(0)
     {

       addExtension(new Stretch());

     }


     // Do not touch anything below this line!
     //
     // *********************************************************************************
     // *********************************************************************************
You have to do two things with this file:
1) You have to include every new header file you write.
2) You have to add a method addExtension(...) for every new class you have defined within the cnstructor of KbExtensionManager and with a new instance of your class as a parameter (like ... = new Stretch() in the above example)

To recompile follow the README.TXT instructions which are located in the partFunctions directory!

This is all! Have fun with it ;-)


NEXT PREV CONTENTS