void PlaybackTracker::init()
{
	if (!scheduler) {
		TSE3::MidiSchedulerFactory factory;
		try {
			scheduler = factory.createScheduler();
			qDebug() << "MIDI Scheduler created";

			if (!scheduler) {
				qCritical() << "ERROR opening MIDI device / Music can't be played";
//			midiInUse = FALSE;
//			return FALSE;
			}

			metronome = new TSE3::Metronome;
			transport = new TSE3::Transport(metronome, scheduler);
			transport->attachCallback(this);
		} catch (const TSE3::Error &e) {
			qCritical() << "cannot create MIDI Scheduler";
			scheduler = NULL;
		}
	}
}
int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        std::cout << "Useage: recording <filename>\n";
        exit(1);
    }

    /**************************************************************************
     * 1. Create a Transport object to do some recording with
     *************************************************************************/

    TSE3::Metronome             metronome;
    TSE3::MidiSchedulerFactory  msFactory;
    TSE3::MidiScheduler        *scheduler = msFactory.createScheduler();
    TSE3::Transport             transport(&metronome, scheduler);

    /**************************************************************************
     * 2. Record some MIDI events
     *************************************************************************/

    TSE3::Song         song;
    TSE3::PhraseEdit   phraseEdit;
    const TSE3::Clock  stopTime    = TSE3::Clock::PPQN*4*8;

    // Record the events. Display hashes for each input event
    std::cout << "Recording MIDI data now...\n";
    size_t counter = phraseEdit.size();
    transport.record(&song, 0, &phraseEdit, 0);
    while (scheduler->clock() < stopTime)
    {
        transport.poll();

        // Print a hash if something was recieved
        if (phraseEdit.size() != counter)
        {
            std::cout << "#";
            counter = phraseEdit.size();
        }

        // Perhaps sleep here to prevent slaughtering the CPU
    }
    transport.stop();
    std::cout << "\nFinished recording. There were "
              << phraseEdit.size() << " input events.\n";

    // Having finished recording, we have to "tidy" the recorded data
    // See the docs for this function to understand why.
    phraseEdit.tidy();
    std::cout << "This tidies to " << phraseEdit.size() << " events.\n";

    // Now we've recorded a phrase of data, we have to insert it into the Song
    // This means:
    //   i)  Insert it in the PhraseList
    //   ii) Create a Part (in a Track) using it
    TSE3::Phrase *phrase = phraseEdit.createPhrase(song.phraseList());
    TSE3::Part   *part   = new TSE3::Part(0, stopTime);
    part->setPhrase(phrase);
    song[0]->insert(part); // We rely on track 0 existing

    /**************************************************************************
     * 3. Export as a MIDI file
     *************************************************************************/

    // Created with default parameters, so you'll get a type 1 MIDI file
    TSE3::MidiFileExport midiExport;

    midiExport.save(argv[1], &song);

    /**************************************************************************
     * All done
     *************************************************************************/

    delete scheduler;
    return 0;
}