File: Midi2XmlExample.cxx

package info (click to toggle)
clam 1.4.0-6
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 17,836 kB
  • ctags: 20,981
  • sloc: cpp: 92,504; python: 9,721; ansic: 1,602; xml: 444; sh: 239; makefile: 153; perl: 54; asm: 15
file content (182 lines) | stat: -rw-r--r-- 5,384 bytes parent folder | download | duplicates (2)
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;
}