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;
}
Exemple #2
0
int main()
{
    /**************************************************************************
     * 1. Create a Song containing a scale
     *************************************************************************/

    // First, we create a scale in a PhraseEdit

    TSE3::PhraseEdit phraseEdit;
    int              note = rootNote;
    TSE3::Clock      time = 0;
    for (int n = 0; n < 8; n++)
    {
        const int delta[]  = {2, 2, 1, 2, 2, 2, 1, 0};
        const int velocity = 0x60;
        const int channel  = 0;
        const int port     = 0;

        phraseEdit.insert
            (TSE3::MidiEvent(TSE3::MidiCommand(TSE3::MidiCommand_NoteOn,
                                               channel, port, note, velocity),
             time, velocity, time+duration));

        note += delta[n];
        time += duration;
    }

    // Now assemble the Song
    TSE3::Song    song(1);
    TSE3::Phrase *phrase = phraseEdit.createPhrase(song.phraseList());
    TSE3::Part   *part   = new TSE3::Part(0, phraseEdit.lastClock());
    part->setPhrase(phrase);
    song[0]->insert(part);

    /**************************************************************************
     * 2. Play the Song
     *************************************************************************/

    // Create transport objects
    // (You really want to create a MidiScheduler for your platform, perhaps
    // you'll use the UnixMidiSchedulerFactory)
    TSE3::Metronome                 metronome;
    TSE3::Util::StreamMidiScheduler scheduler;
    TSE3::Transport                 transport(&metronome, &scheduler);

    // Play and wait for the end
    transport.play(&song, 0);
    while (transport.status() != TSE3::Transport::Resting)
    {
        transport.poll();
        // perhaps sleep here to prevent slaughtering the CPU
    }

    /**************************************************************************
     * 3. Save the Song as a standard MIDI file
     *************************************************************************/

    TSE3::MidiFileExport mfe;
    mfe.save("export.midi", &song);

    /**************************************************************************
     * All done - note that there is no memory leak - when the Song is deleted
     * (it is on the stack, so this will happen automatically) all the other
     * components will be deleted by the Song's destructor.
     *************************************************************************/

    return 0;
}