1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
/*
* Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
* UNIVERSITAT POMPEU FABRA
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU GeMidi2XmlExampleneral Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "MIDI2Melody.hxx"
#include "MIDIManager.hxx"
#include "MIDIInControl.hxx"
#include "MIDIClocker.hxx"
#include "MIDIMelody.hxx"
#include "TraverseDirectory.hxx"
#include "XMLStorage.hxx"
#include "OutControl.hxx"
#include "InPort.hxx"
#include <iostream>
using CLAM::MIDIMelody;
using CLAM::MIDIManager;
using CLAM::MIDIIOConfig;
using CLAM::MIDIIn;
using CLAM::MIDIClockerConfig;
using CLAM::MIDIClocker;
using CLAM::MIDI2Melody;
using CLAM::TTime;
using CLAM::MIDIInControl;
using CLAM::XMLStorage;
/** Declaration of the concrete Traverse directory class to apply to all files*/
class ConvertAllMidiFiles:public TraverseDirectory
{
public:
void OnFile(const std::string& filename);
private:
std::string ChangeExtension(const std::string& filename,const std::string& newExtension);
};
//Auxiliary function to change the .mid extension to .xml in a given filename
std::string ConvertAllMidiFiles::ChangeExtension(const std::string& filename,const std::string& newExtension)
{
std::string result=filename.substr(0,filename.rfind('.')+1);
result.append(newExtension);
return result;
}
//Function where the process related to every file is actually implemented
void ConvertAllMidiFiles::OnFile(const std::string& filename)
{
std::string mid("mid");
//First we ensure that it is a MIDI file looking at the extension
if(GetExtension(filename)!=mid)
return;
std::cout<<"\n"<<"Processing file: "<<filename<<"\n";
//We configure MIDIManager and controls
std::string midiDeviceStr="file:"+filename;
MIDIManager manager;
// Controls for handling MIDI notes
MIDIIOConfig inNoteOnCfg;
inNoteOnCfg.SetDevice(midiDeviceStr);
inNoteOnCfg.SetMessage(CLAM::MIDI::eNoteOn);
MIDIInControl inNoteOn(inNoteOnCfg);
// Controls for handling MIDI notes
MIDIIOConfig inNoteOffCfg;
inNoteOffCfg.SetDevice(midiDeviceStr);
inNoteOffCfg.SetMessage(CLAM::MIDI::eNoteOff);
MIDIInControl inNoteOff(inNoteOffCfg);
//control for stoping at eof
MIDIIOConfig inStopCfg;
inStopCfg.SetDevice(midiDeviceStr);
inStopCfg.SetChannel(CLAM::MIDI::eStop); //it is a sys message that uses channel byte for actual data
inStopCfg.SetMessage(CLAM::MIDI::eSystem);
MIDIInControl inStop(inStopCfg);
//MIDI clocker to keep track of timing
MIDIClockerConfig clockerCfg;
clockerCfg.SetDevice(midiDeviceStr);
MIDIClocker clocker(clockerCfg);
//We instantiate our MIDI2Melody converter and link MIDi controls to its input controls
MIDI2Melody converter;
/** Key for Note Off*/
CLAM::ConnectControls(inNoteOff, 1, converter, 2);
/** Velocity for Note Off */
CLAM::ConnectControls(inNoteOff, 1, converter, 3);
/** Key for Note On */
CLAM::ConnectControls(inNoteOn, 1, converter, 4);
/** Velocity for Note On */
CLAM::ConnectControls(inNoteOn, 2, converter, 5);
CLAM::ConnectControls(inStop, 0, converter, 0);
//We start the MIDI manager and initialize loop variables
manager.Start();
TTime curTimeInc=10;
TTime curTime=0;
//We attach our melody object to the output of the converter
CLAM::InPort<MIDIMelody> outputMelodyWrapper;
converter.mOutput.ConnectToIn( outputMelodyWrapper );
do{//Converter loop
//we send a timing control to the MIDI clocker
SendFloatToInControl(clocker,0,curTime);
//we increment the time counter
curTime += curTimeInc;
//we check for new events in the MIDI manager
manager.Check();
//we send the timing control to converter
converter.mTime.DoControl(curTime);
}while (converter.Do());//we call the converter
converter.mOutput.Produce();
MIDIMelody & outputMelody = outputMelodyWrapper.GetData();
//we change the extension of the filename to .xml
std::string outputFilename=ChangeExtension(filename,"xml");
//we store the output melody
XMLStorage::Dump(outputMelody,"MidiMelody",outputFilename);
std::cout<<"Wrote succesfully "<<outputFilename<<"\n";
}
//Main program
int main(int argc,char** argv)
{
ConvertAllMidiFiles fileConverter;
std::string dir;
if (argc>1)//if program is called with a list of directories to look in...
{
for (int i=1;i<argc;i++)
{
//we recursively look on every file on the folder applying the OnFileFunc to each file
fileConverter.Traverse(argv[i]);
}
}else{
std::cout<<"Please enter path to directory where midi files are located (all subdirectories will also be scaned recursively)"<<"\n";
std::cin>>dir;
//we recursively look on every file on the folder applying the OnFileFunc to each file
fileConverter.Traverse(dir);
}
return 0;
}
|