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; }
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; }