xref: /haiku/src/kits/midi/MidiStore.cpp (revision eac71506d6d8d7671fc858cf9d04a53151aebdd7)
16ba60405Smahlzeit #include "MidiStore.h"
2*eac71506Sjerl1 #include "MidiEvent.h"
352a38012Sejakowatz 
4*eac71506Sjerl1 #include <File.h>
5*eac71506Sjerl1 #include <string.h> //For strcmp(...)
6*eac71506Sjerl1 #include <stdio.h> //For printf(...)
7*eac71506Sjerl1 #include <Debug.h>
8*eac71506Sjerl1 #include <List.h>
9*eac71506Sjerl1 
10*eac71506Sjerl1 //-----------------------------------------------
11*eac71506Sjerl1 //#define DEBUG
12*eac71506Sjerl1 //-----------------------------------------------
13*eac71506Sjerl1 
14*eac71506Sjerl1 //-----------------------------------------------
15*eac71506Sjerl1 //-----------------------------------------------
16*eac71506Sjerl1 //-----------------------------------------------
17*eac71506Sjerl1 
18*eac71506Sjerl1 int CompareEvents(const void* event1, const void* event2)
19*eac71506Sjerl1 {
20*eac71506Sjerl1 	return ((BMidiEvent*)event1)->time - ((BMidiEvent*)event2)->time;
21*eac71506Sjerl1 }
22*eac71506Sjerl1 
23*eac71506Sjerl1 //-----------------------------------------------
2452a38012Sejakowatz 
256ba60405Smahlzeit BMidiStore::BMidiStore()
266ba60405Smahlzeit {
276ba60405Smahlzeit 	events = new BList();
28*eac71506Sjerl1 	fFile = NULL;
29*eac71506Sjerl1 	fFileBuffer = NULL;
30*eac71506Sjerl1 	fFileBufferMax = 0;
31*eac71506Sjerl1 	fNeedsSorting = false;
32*eac71506Sjerl1 	fDivision = 480;
33*eac71506Sjerl1 	fNumTracks = 1;
34*eac71506Sjerl1 	fStartTime = 0;
35*eac71506Sjerl1 	fCurrEvent = 0;
3652a38012Sejakowatz }
3752a38012Sejakowatz 
38*eac71506Sjerl1 //-----------------------------------------------
396ba60405Smahlzeit 
406ba60405Smahlzeit BMidiStore::~BMidiStore()
416ba60405Smahlzeit {
426ba60405Smahlzeit 	int32 count = events->CountItems();
436ba60405Smahlzeit 	for (int i = count - 1; i >= 0; i--)
446ba60405Smahlzeit 	{
456ba60405Smahlzeit 		delete (BMidiEvent*) events->RemoveItem(i);
4652a38012Sejakowatz 	}
476ba60405Smahlzeit 	delete events;
4852a38012Sejakowatz }
4952a38012Sejakowatz 
50*eac71506Sjerl1 //-----------------------------------------------
5152a38012Sejakowatz 
52*eac71506Sjerl1 void BMidiStore::NoteOff(uchar chan, uchar note, uchar vel, uint32 time)
536ba60405Smahlzeit {
54*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_NOTE_OFF, chan, note, vel);
556ba60405Smahlzeit }
566ba60405Smahlzeit 
57*eac71506Sjerl1 //-----------------------------------------------
586ba60405Smahlzeit 
59*eac71506Sjerl1 void BMidiStore::NoteOn(uchar chan, uchar note, uchar vel, uint32 time)
606ba60405Smahlzeit {
61*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_NOTE_ON, chan, note, vel);
626ba60405Smahlzeit }
636ba60405Smahlzeit 
64*eac71506Sjerl1 //-----------------------------------------------
656ba60405Smahlzeit 
66*eac71506Sjerl1 void BMidiStore::KeyPressure(uchar chan, uchar note, uchar pres, uint32 time)
676ba60405Smahlzeit {
68*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_KEY_PRESSURE, chan, note, pres);
696ba60405Smahlzeit }
706ba60405Smahlzeit 
71*eac71506Sjerl1 //-----------------------------------------------
726ba60405Smahlzeit 
73*eac71506Sjerl1 void BMidiStore::ControlChange(uchar chan, uchar ctrl_num, uchar ctrl_val, uint32 time)
746ba60405Smahlzeit {
75*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_CONTROL_CHANGE, chan, ctrl_num, ctrl_val);
766ba60405Smahlzeit }
776ba60405Smahlzeit 
78*eac71506Sjerl1 //-----------------------------------------------
796ba60405Smahlzeit 
80*eac71506Sjerl1 void BMidiStore::ProgramChange(uchar chan, uchar prog_num, uint32 time)
816ba60405Smahlzeit {
82*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_PROGRAM_CHANGE, chan, prog_num);
836ba60405Smahlzeit }
846ba60405Smahlzeit 
85*eac71506Sjerl1 //-----------------------------------------------
866ba60405Smahlzeit 
87*eac71506Sjerl1 void BMidiStore::ChannelPressure(uchar chan, uchar pres, uint32 time)
886ba60405Smahlzeit {
89*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_CHANNEL_PRESSURE, chan, pres);
906ba60405Smahlzeit }
916ba60405Smahlzeit 
92*eac71506Sjerl1 //-----------------------------------------------
936ba60405Smahlzeit 
94*eac71506Sjerl1 void BMidiStore::PitchBend(uchar chan, uchar lsb, uchar msb, uint32 time)
956ba60405Smahlzeit {
96*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_PITCH_BEND, chan, lsb, msb);
97*eac71506Sjerl1 }
98*eac71506Sjerl1 //-----------------------------------------------
99*eac71506Sjerl1 
100*eac71506Sjerl1 void BMidiStore::SystemExclusive(void *data, size_t data_len, uint32 time)
101*eac71506Sjerl1 {
102*eac71506Sjerl1 	BMidiEvent *e = new BMidiEvent;
103*eac71506Sjerl1 	e->opcode = BMidiEvent::OP_SYSTEM_EXCLUSIVE;
104*eac71506Sjerl1 	e->time = time;
105*eac71506Sjerl1 	e->systemExclusive.data = new uint8[data_len];
106*eac71506Sjerl1 	memcpy(e->systemExclusive.data, data, data_len);
107*eac71506Sjerl1 	e->systemExclusive.dataLength = data_len;
108*eac71506Sjerl1 	AddSystemExclusive(e, sizeof(BMidiEvent));
10952a38012Sejakowatz }
11052a38012Sejakowatz 
111*eac71506Sjerl1 //-----------------------------------------------
1126ba60405Smahlzeit 
113*eac71506Sjerl1 void BMidiStore::SystemCommon(uchar stat_byte, uchar data1, uchar data2, uint32 time)
1146ba60405Smahlzeit {
115*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_SYSTEM_COMMON, stat_byte, data1, data2);
11652a38012Sejakowatz }
11752a38012Sejakowatz 
118*eac71506Sjerl1 //-----------------------------------------------
1196ba60405Smahlzeit 
120*eac71506Sjerl1 void BMidiStore::SystemRealTime(uchar stat_byte, uint32 time)
1216ba60405Smahlzeit {
122*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_SYSTEM_REAL_TIME, stat_byte);
12352a38012Sejakowatz }
12452a38012Sejakowatz 
125*eac71506Sjerl1 //-----------------------------------------------
12652a38012Sejakowatz 
127*eac71506Sjerl1 void BMidiStore::TempoChange(int32 bpm, uint32 time)
1286ba60405Smahlzeit {
129*eac71506Sjerl1 	AddEvent(time, true, BMidiEvent::OP_TEMPO_CHANGE, bpm);
13052a38012Sejakowatz }
13152a38012Sejakowatz 
132*eac71506Sjerl1 //-----------------------------------------------
1336ba60405Smahlzeit 
1346ba60405Smahlzeit status_t BMidiStore::Import(const entry_ref *ref)
135*eac71506Sjerl1 {//ToTest
136*eac71506Sjerl1 status_t status = B_NO_ERROR;
137*eac71506Sjerl1 
138*eac71506Sjerl1 	fFile = new BFile(ref, B_READ_ONLY);
139*eac71506Sjerl1 
140*eac71506Sjerl1 	status = fFile->InitCheck();
141*eac71506Sjerl1 	if (status != B_OK)
1426ba60405Smahlzeit 	{
143*eac71506Sjerl1 		delete fFile;
14425767509Smahlzeit 		return status;
14525767509Smahlzeit 	}
14625767509Smahlzeit 
147*eac71506Sjerl1 	status = ReadHeader();
148*eac71506Sjerl1 	if (status != B_OK)
149*eac71506Sjerl1 	{
150*eac71506Sjerl1 		delete fFile;
151*eac71506Sjerl1 		return status;
152*eac71506Sjerl1 	}
15325767509Smahlzeit 
154*eac71506Sjerl1 	Read16Bit(); //Format of the MidiFile
155*eac71506Sjerl1 	fNumTracks = Read16Bit();
156*eac71506Sjerl1 	fDivision = Read16Bit();
157*eac71506Sjerl1 	fDivisionFactor = 1 / fDivision;
158*eac71506Sjerl1 
159*eac71506Sjerl1 	status = B_OK;
160*eac71506Sjerl1 	for(fCurrTrack = 0; fCurrTrack < fNumTracks; fCurrTrack++)
161*eac71506Sjerl1 	{
162*eac71506Sjerl1 	char mtrk[4];
163*eac71506Sjerl1 		if (ReadMT(mtrk) == false)
164*eac71506Sjerl1 		{
165*eac71506Sjerl1 			PRINT("Error while reading MTrk\n");
166*eac71506Sjerl1 			status = B_BAD_MIDI_DATA;
167*eac71506Sjerl1 			break;
168*eac71506Sjerl1 		}
169*eac71506Sjerl1 		PRINT(("Printing Track %ld\n", fCurrTrack));
170*eac71506Sjerl1 
171*eac71506Sjerl1 		fFileBufferSize = Read32Bit();
172*eac71506Sjerl1 		if (fFileBufferSize > fFileBufferMax)
173*eac71506Sjerl1 		{
174*eac71506Sjerl1 			fFileBufferMax = fFileBufferSize;
175*eac71506Sjerl1 			delete fFileBuffer;
176*eac71506Sjerl1 			fFileBuffer = new uchar[fFileBufferSize];
177*eac71506Sjerl1 		}
178*eac71506Sjerl1 		if (ReadTrack() == false)
179*eac71506Sjerl1 		{
180*eac71506Sjerl1 			PRINT(("Error while reading Trak %ld\n", fCurrTrack));
181*eac71506Sjerl1 			status = B_BAD_MIDI_DATA;
182*eac71506Sjerl1 			break;
183*eac71506Sjerl1 		}
184*eac71506Sjerl1 	}
185*eac71506Sjerl1 
186*eac71506Sjerl1 	delete fFile;
187*eac71506Sjerl1 	delete fFileBuffer;
188*eac71506Sjerl1 	fFileBuffer = NULL;
189*eac71506Sjerl1 	SortEvents(true);
190*eac71506Sjerl1 return status;
191*eac71506Sjerl1 }
192*eac71506Sjerl1 
193*eac71506Sjerl1 //-----------------------------------------------
1946ba60405Smahlzeit 
1956ba60405Smahlzeit status_t BMidiStore::Export(const entry_ref *ref, int32 format)
196*eac71506Sjerl1 {//ToDo
197*eac71506Sjerl1 	fFile = new BFile(ref, B_READ_WRITE);
198*eac71506Sjerl1 	status_t status = fFile->InitCheck();
199*eac71506Sjerl1 	if (status != B_OK)
2006ba60405Smahlzeit 	{
201*eac71506Sjerl1 		delete fFile;
202*eac71506Sjerl1 		return status;
203*eac71506Sjerl1 	}
204*eac71506Sjerl1 
205*eac71506Sjerl1 	SortEvents(true);
206*eac71506Sjerl1 	WriteHeaderChunk(format);
207*eac71506Sjerl1 
208*eac71506Sjerl1 off_t position_of_length = 0;
209*eac71506Sjerl1 
210*eac71506Sjerl1 	if (format == 0)
211*eac71506Sjerl1 	{//Format is 0 just one track
212*eac71506Sjerl1 		position_of_length = fFile->Position() + 4;
213*eac71506Sjerl1 		WriteTrack(-1);
214*eac71506Sjerl1 		fFile->Seek(position_of_length, SEEK_SET);
215*eac71506Sjerl1 		Write32Bit(fNumBytesWritten);
216*eac71506Sjerl1 		fFile->Seek(0, SEEK_END);
217*eac71506Sjerl1 	}
218*eac71506Sjerl1 
219*eac71506Sjerl1 	if (format == 1)
220*eac71506Sjerl1 	{//Format is 1, number of track is fNumTracks initialized when import file
221*eac71506Sjerl1 		for (int32 i = 0; i < fNumTracks; i++)
222*eac71506Sjerl1 		{
223*eac71506Sjerl1 			position_of_length = fFile->Position() + 4;
224*eac71506Sjerl1 			WriteTrack(i);
225*eac71506Sjerl1 			fFile->Seek(position_of_length, SEEK_SET);
226*eac71506Sjerl1 			Write32Bit(fNumBytesWritten);
227*eac71506Sjerl1 			fFile->Seek(0, SEEK_END);
228*eac71506Sjerl1 		}
229*eac71506Sjerl1 	}
230*eac71506Sjerl1 
2316ba60405Smahlzeit return B_OK;
2326ba60405Smahlzeit }
2336ba60405Smahlzeit 
234*eac71506Sjerl1 //-----------------------------------------------
2356ba60405Smahlzeit 
2366ba60405Smahlzeit void BMidiStore::SortEvents(bool force)
2376ba60405Smahlzeit {
2386ba60405Smahlzeit 	events->SortItems(CompareEvents);
2396ba60405Smahlzeit }
2406ba60405Smahlzeit 
241*eac71506Sjerl1 //-----------------------------------------------
2426ba60405Smahlzeit 
2436ba60405Smahlzeit uint32 BMidiStore::CountEvents() const
244*eac71506Sjerl1 {//ToTest
2456ba60405Smahlzeit return events->CountItems();
2466ba60405Smahlzeit }
2476ba60405Smahlzeit 
248*eac71506Sjerl1 //-----------------------------------------------
2496ba60405Smahlzeit 
2506ba60405Smahlzeit uint32 BMidiStore::CurrentEvent() const
251*eac71506Sjerl1 {//ToTest
252*eac71506Sjerl1 	return fCurrEvent;
2536ba60405Smahlzeit }
2546ba60405Smahlzeit 
255*eac71506Sjerl1 //-----------------------------------------------
2566ba60405Smahlzeit 
257*eac71506Sjerl1 void BMidiStore::SetCurrentEvent(uint32 event_num)
258*eac71506Sjerl1 {//ToTest
259*eac71506Sjerl1 	fCurrEvent = event_num;
2606ba60405Smahlzeit }
2616ba60405Smahlzeit 
262*eac71506Sjerl1 //-----------------------------------------------
2636ba60405Smahlzeit 
264*eac71506Sjerl1 uint32 BMidiStore::DeltaOfEvent(uint32 event_num) const
265*eac71506Sjerl1 {//ToDo
2666ba60405Smahlzeit return 0;
2676ba60405Smahlzeit }
2686ba60405Smahlzeit 
269*eac71506Sjerl1 //-----------------------------------------------
270*eac71506Sjerl1 
271*eac71506Sjerl1 uint32 BMidiStore::EventAtDelta(uint32 time) const
272*eac71506Sjerl1 {//ToDo
273*eac71506Sjerl1 return 0;
274*eac71506Sjerl1 }
275*eac71506Sjerl1 
276*eac71506Sjerl1 //-----------------------------------------------
2776ba60405Smahlzeit 
2786ba60405Smahlzeit uint32 BMidiStore::BeginTime() const
279*eac71506Sjerl1 {//ToTest
280*eac71506Sjerl1 		return fStartTime;
2816ba60405Smahlzeit }
2826ba60405Smahlzeit 
283*eac71506Sjerl1 //-----------------------------------------------
2846ba60405Smahlzeit 
285*eac71506Sjerl1 void BMidiStore::SetTempo(int32 bpm)
286*eac71506Sjerl1 {//ToTest
287*eac71506Sjerl1 	fTempo = bpm;
2886ba60405Smahlzeit }
2896ba60405Smahlzeit 
290*eac71506Sjerl1 //-----------------------------------------------
2916ba60405Smahlzeit 
2926ba60405Smahlzeit int32 BMidiStore::Tempo() const
293*eac71506Sjerl1 {//ToTest
294*eac71506Sjerl1 	return fTempo;
2956ba60405Smahlzeit }
2966ba60405Smahlzeit 
297*eac71506Sjerl1 //-----------------------------------------------
298*eac71506Sjerl1 //-----------------------------------------------
299*eac71506Sjerl1 //-----------------------------------------------
300*eac71506Sjerl1 //-----------------------------------------------
3016ba60405Smahlzeit 
3026ba60405Smahlzeit void BMidiStore::Run()
3036ba60405Smahlzeit {
304*eac71506Sjerl1 	fStartTime = B_NOW;
305*eac71506Sjerl1 	SortEvents(true);
3066ba60405Smahlzeit 	while (KeepRunning())
3076ba60405Smahlzeit 	{
308*eac71506Sjerl1 		BMidiEvent* event = (BMidiEvent*)events->ItemAt(fCurrEvent);
3096ba60405Smahlzeit 
310*eac71506Sjerl1 		if (event == NULL) return;
3116ba60405Smahlzeit 
312*eac71506Sjerl1 		printf("Curr Event : %ld, Time : %ld\n", fCurrEvent, event->time);
3136ba60405Smahlzeit 
314*eac71506Sjerl1 		fCurrTime = event->time;
315*eac71506Sjerl1 		event->time += fStartTime;
316*eac71506Sjerl1 //		SprayMidiEvent(event);
317*eac71506Sjerl1 		event->time = fCurrTime;
318*eac71506Sjerl1 
319*eac71506Sjerl1 		fCurrEvent++;
3206ba60405Smahlzeit 	}
3216ba60405Smahlzeit }
3226ba60405Smahlzeit 
323*eac71506Sjerl1 //-----------------------------------------------
3246ba60405Smahlzeit 
325*eac71506Sjerl1 void BMidiStore::AddEvent(uint32 time, bool inMS, uchar type, uchar data1 = 0, uchar data2 = 0, uchar data3 = 0, uchar data4 = 0)
326*eac71506Sjerl1 {//ToTest
327*eac71506Sjerl1 	if (!inMS)
3286ba60405Smahlzeit 	{
329*eac71506Sjerl1 		time = TicksToMilliseconds(time);
330*eac71506Sjerl1 	}
331*eac71506Sjerl1 	BMidiEvent *e = new BMidiEvent();
332*eac71506Sjerl1 	e->time = time;
333*eac71506Sjerl1 	switch (type)
334*eac71506Sjerl1 	{
335*eac71506Sjerl1 		case BMidiEvent::OP_NOTE_OFF :
336*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_NOTE_OFF;
337*eac71506Sjerl1 					e->noteOff.channel = data1;
338*eac71506Sjerl1 					e->noteOff.note = data2;
339*eac71506Sjerl1 					e->noteOff.velocity = data3;
340*eac71506Sjerl1 					break;
341*eac71506Sjerl1 		case BMidiEvent::OP_NOTE_ON :
342*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_NOTE_ON;
343*eac71506Sjerl1 					e->noteOn.channel = data1;
344*eac71506Sjerl1 					e->noteOn.note = data2;
345*eac71506Sjerl1 					e->noteOn.velocity = data3;
346*eac71506Sjerl1 					break;
347*eac71506Sjerl1 		case BMidiEvent::OP_KEY_PRESSURE :
348*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_KEY_PRESSURE;
349*eac71506Sjerl1 					e->keyPressure.channel = data1;
350*eac71506Sjerl1 					e->keyPressure.note = data2;
351*eac71506Sjerl1 					e->keyPressure.pressure = data3;
352*eac71506Sjerl1 					break;
353*eac71506Sjerl1 		case BMidiEvent::OP_CONTROL_CHANGE :
354*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_CONTROL_CHANGE;
355*eac71506Sjerl1 					e->controlChange.channel = data1;
356*eac71506Sjerl1 					e->controlChange.controlNumber = data2;
357*eac71506Sjerl1 					e->controlChange.controlValue = data3;
358*eac71506Sjerl1 					break;
359*eac71506Sjerl1 		case BMidiEvent::OP_PROGRAM_CHANGE :
360*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_PROGRAM_CHANGE;
361*eac71506Sjerl1 					e->programChange.channel = data1;
362*eac71506Sjerl1 					e->programChange.programNumber = data2;
363*eac71506Sjerl1 					break;
364*eac71506Sjerl1 		case BMidiEvent::OP_CHANNEL_PRESSURE :
365*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_CHANNEL_PRESSURE;
366*eac71506Sjerl1 					e->channelPressure.channel = data1;
367*eac71506Sjerl1 					e->channelPressure.pressure = data2;
368*eac71506Sjerl1 					break;
369*eac71506Sjerl1 		case BMidiEvent::OP_PITCH_BEND :
370*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_PITCH_BEND;
371*eac71506Sjerl1 					e->pitchBend.channel = data1;
372*eac71506Sjerl1 					e->pitchBend.lsb = data2;
373*eac71506Sjerl1 					e->pitchBend.msb = data3;
374*eac71506Sjerl1 					break;
375*eac71506Sjerl1 		case BMidiEvent::OP_SYSTEM_COMMON :
376*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_SYSTEM_COMMON;
377*eac71506Sjerl1 					e->systemCommon.status = data1;
378*eac71506Sjerl1 					e->systemCommon.data1 = data2;
379*eac71506Sjerl1 					e->systemCommon.data2 = data3;
380*eac71506Sjerl1 					break;
381*eac71506Sjerl1 		case BMidiEvent::OP_SYSTEM_REAL_TIME :
382*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_SYSTEM_REAL_TIME;
383*eac71506Sjerl1 					e->systemRealTime.status = data1;
384*eac71506Sjerl1 					break;
385*eac71506Sjerl1 		case BMidiEvent::OP_TEMPO_CHANGE :
386*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_TEMPO_CHANGE;
387*eac71506Sjerl1 					e->tempoChange.beatsPerMinute = data1;
388*eac71506Sjerl1 					break;
389*eac71506Sjerl1 		case BMidiEvent::OP_ALL_NOTES_OFF :
390*eac71506Sjerl1 					e->opcode = BMidiEvent::OP_ALL_NOTES_OFF;
391*eac71506Sjerl1 					e->allNotesOff.justChannel = data1;
392*eac71506Sjerl1 					break;
393*eac71506Sjerl1 		default :
394*eac71506Sjerl1 			delete e;
395*eac71506Sjerl1 			return;
396*eac71506Sjerl1 	}
397*eac71506Sjerl1 	events->AddItem(e);
3986ba60405Smahlzeit }
3996ba60405Smahlzeit 
400*eac71506Sjerl1 //-----------------------------------------------
4016ba60405Smahlzeit 
402*eac71506Sjerl1 void BMidiStore::AddSystemExclusive(void* data, size_t dataLength)
403*eac71506Sjerl1 {//ToTest
404*eac71506Sjerl1 //	BMidiEvent *e = new BMidiEvent();
405*eac71506Sjerl1 //	e->time = 0;
406*eac71506Sjerl1 //	e->systemExclusive.data = (uint8*)data;
407*eac71506Sjerl1 //	e->systemExclusive.dataLength = dataLength;
408*eac71506Sjerl1 	events->AddItem(data);
4096ba60405Smahlzeit }
4106ba60405Smahlzeit 
411*eac71506Sjerl1 //-----------------------------------------------
4126ba60405Smahlzeit 
413*eac71506Sjerl1 status_t BMidiStore::ReadHeader()
414*eac71506Sjerl1 {//ToTest
415*eac71506Sjerl1 char mthd[4];
416*eac71506Sjerl1 	if (ReadMT(mthd) == false)
417*eac71506Sjerl1 		return B_ERROR;
418*eac71506Sjerl1 	if(strncmp(mthd, "MThd", 4) != 0)
41925767509Smahlzeit 	{
420*eac71506Sjerl1 		return B_BAD_MIDI_DATA;
42125767509Smahlzeit 	}
42225767509Smahlzeit 
42325767509Smahlzeit int32 length = Read32Bit();
424*eac71506Sjerl1 	if (length != 6)
42525767509Smahlzeit 	{
426*eac71506Sjerl1 		return B_BAD_MIDI_DATA;
427*eac71506Sjerl1 	}
428*eac71506Sjerl1 return B_OK;
42925767509Smahlzeit }
43025767509Smahlzeit 
431*eac71506Sjerl1 //-----------------------------------------------
43225767509Smahlzeit 
433*eac71506Sjerl1 bool BMidiStore::ReadMT(char *data)
434*eac71506Sjerl1 {//ToTest
435*eac71506Sjerl1 	return fFile->Read(data, 4) == 4;
43625767509Smahlzeit }
43725767509Smahlzeit 
438*eac71506Sjerl1 //-----------------------------------------------
43925767509Smahlzeit 
44025767509Smahlzeit int32 BMidiStore::Read32Bit()
441*eac71506Sjerl1 {//ToTest
442*eac71506Sjerl1 uchar char32bit[4];
443*eac71506Sjerl1 	fFile->Read(char32bit, 4);
444*eac71506Sjerl1 return To32Bit(char32bit[0], char32bit[1], char32bit[2], char32bit[3]);
44525767509Smahlzeit }
44625767509Smahlzeit 
447*eac71506Sjerl1 //-----------------------------------------------
44825767509Smahlzeit 
449*eac71506Sjerl1 int32 BMidiStore::EGetC()
450*eac71506Sjerl1 {//ToDo
451*eac71506Sjerl1 return 0;
45225767509Smahlzeit }
45325767509Smahlzeit 
454*eac71506Sjerl1 //-----------------------------------------------
45525767509Smahlzeit 
456*eac71506Sjerl1 int32 BMidiStore::To32Bit(int32 data1, int32 data2, int32 data3, int32 data4)
457*eac71506Sjerl1 {//ToTest
458*eac71506Sjerl1 	return data1 << 24 | data2 << 16 | data3 << 8 | data4;
459*eac71506Sjerl1 }
46025767509Smahlzeit 
461*eac71506Sjerl1 //-----------------------------------------------
462*eac71506Sjerl1 
463*eac71506Sjerl1 int32 BMidiStore::Read16Bit()
464*eac71506Sjerl1 {//ToTest
465*eac71506Sjerl1 uchar char16bit[2];
466*eac71506Sjerl1 	fFile->Read(char16bit, 2);
467*eac71506Sjerl1 return To16Bit(char16bit[0], char16bit[1]);
468*eac71506Sjerl1 }
469*eac71506Sjerl1 
470*eac71506Sjerl1 //-----------------------------------------------
471*eac71506Sjerl1 
472*eac71506Sjerl1 int32 BMidiStore::To16Bit(int32 data1, int32 data2)
473*eac71506Sjerl1 {//ToTest
474*eac71506Sjerl1 	return (uint32)data1 << 8 | (uint32)data2;
475*eac71506Sjerl1 }
476*eac71506Sjerl1 
477*eac71506Sjerl1 //-----------------------------------------------
478*eac71506Sjerl1 
479*eac71506Sjerl1 bool BMidiStore::ReadTrack()
480*eac71506Sjerl1 {//ToTest
481*eac71506Sjerl1 	if (fFile->Read(fFileBuffer, fFileBufferSize) != fFileBufferSize)
482*eac71506Sjerl1 		return false;
483*eac71506Sjerl1 fNeedsSorting = true;
484*eac71506Sjerl1 fFileBufferIndex = 0;
485*eac71506Sjerl1 uint32 ticks = 0;
486*eac71506Sjerl1 uint32 time = 0; //in ms
487*eac71506Sjerl1 uchar data = 0;
488*eac71506Sjerl1 uint32 ForTempo = 0;
489*eac71506Sjerl1 //fStartTime = 0;
490*eac71506Sjerl1 	while (fFileBufferIndex < (fFileBufferSize - 3))
49125767509Smahlzeit 	{
492*eac71506Sjerl1 		ticks += ReadVariNum();
493*eac71506Sjerl1 		time = /*fStartTime + */TicksToMilliseconds(ticks);
494*eac71506Sjerl1 		uchar temp = fFileBuffer[fFileBufferIndex];
495*eac71506Sjerl1 		if (temp > 0x7F)
496*eac71506Sjerl1 		{
497*eac71506Sjerl1 			data = temp;
498*eac71506Sjerl1 			fFileBufferIndex++;
499*eac71506Sjerl1 		}
500*eac71506Sjerl1 		if (data < 0x80)
501*eac71506Sjerl1 		{
502*eac71506Sjerl1 			PRINT(("Big Problem, data : %d, Index : %ld\n", data, fFileBufferIndex));
503*eac71506Sjerl1 			return false;
504*eac71506Sjerl1 		}
505*eac71506Sjerl1 		switch (data & 0xF0)
506*eac71506Sjerl1 		{
507*eac71506Sjerl1 			case B_NOTE_OFF :
508*eac71506Sjerl1 				NoteOff(data & 0x0F, fFileBuffer[fFileBufferIndex],
509*eac71506Sjerl1 							fFileBuffer[fFileBufferIndex + 1], time);
510*eac71506Sjerl1 				fFileBufferIndex += 2;
511*eac71506Sjerl1 				break;
512*eac71506Sjerl1 			case B_NOTE_ON :
513*eac71506Sjerl1 				NoteOn(data & 0x0F, fFileBuffer[fFileBufferIndex],
514*eac71506Sjerl1 							fFileBuffer[fFileBufferIndex + 1], time);
515*eac71506Sjerl1 				fFileBufferIndex += 2;
516*eac71506Sjerl1 				break;
517*eac71506Sjerl1 			case B_KEY_PRESSURE :
518*eac71506Sjerl1 				KeyPressure(data & 0x0F, fFileBuffer[fFileBufferIndex],
519*eac71506Sjerl1 							fFileBuffer[fFileBufferIndex + 1], time);
520*eac71506Sjerl1 				fFileBufferIndex += 2;
521*eac71506Sjerl1 				break;
522*eac71506Sjerl1 			case B_CONTROL_CHANGE :
523*eac71506Sjerl1 				ControlChange(data & 0x0F, fFileBuffer[fFileBufferIndex],
524*eac71506Sjerl1 							fFileBuffer[fFileBufferIndex + 1], time);
525*eac71506Sjerl1 				fFileBufferIndex += 2;
526*eac71506Sjerl1 				break;
527*eac71506Sjerl1 			case B_PITCH_BEND :
528*eac71506Sjerl1 				PitchBend(data & 0x0F, fFileBuffer[fFileBufferIndex],
529*eac71506Sjerl1 							fFileBuffer[fFileBufferIndex + 1], time);
530*eac71506Sjerl1 				fFileBufferIndex += 2;
531*eac71506Sjerl1 				break;
532*eac71506Sjerl1 			case B_PROGRAM_CHANGE :
533*eac71506Sjerl1 				ProgramChange(data & 0x0F, fFileBuffer[fFileBufferIndex], time);
534*eac71506Sjerl1 				fFileBufferIndex += 2;
535*eac71506Sjerl1 				break;
536*eac71506Sjerl1 			case B_CHANNEL_PRESSURE :
537*eac71506Sjerl1 				ChannelPressure(data & 0x0F, fFileBuffer[fFileBufferIndex], time);
538*eac71506Sjerl1 				fFileBufferIndex += 1;
539*eac71506Sjerl1 				break;
540*eac71506Sjerl1 		}
541*eac71506Sjerl1 		switch (data)
542*eac71506Sjerl1 		{
543*eac71506Sjerl1 			case B_SYS_EX_START :
544*eac71506Sjerl1 				temp = MsgLength();
545*eac71506Sjerl1 				SystemExclusive(&fFileBuffer[fFileBufferIndex - 1], temp + 2, time);
546*eac71506Sjerl1 				fFileBufferIndex += temp;
547*eac71506Sjerl1 				break;
548*eac71506Sjerl1 			case B_SONG_POSITION :
549*eac71506Sjerl1 				SystemCommon(data, fFileBuffer[fFileBufferIndex], fFileBuffer[fFileBufferIndex + 1], time);
550*eac71506Sjerl1 				fFileBufferIndex += 2;
551*eac71506Sjerl1 				break;
552*eac71506Sjerl1 			case B_MIDI_TIME_CODE :
553*eac71506Sjerl1 			case B_SONG_SELECT :
554*eac71506Sjerl1 				SystemCommon(data, fFileBuffer[fFileBufferIndex], 0, time);
555*eac71506Sjerl1 				fFileBufferIndex += 1;
556*eac71506Sjerl1 				break;
557*eac71506Sjerl1 			case B_TUNE_REQUEST :
558*eac71506Sjerl1 			case B_TIMING_CLOCK :
559*eac71506Sjerl1 				SystemCommon(data, 0, 0, time);
560*eac71506Sjerl1 				break;
561*eac71506Sjerl1 			case B_START :
562*eac71506Sjerl1 			case B_CONTINUE :
563*eac71506Sjerl1 			case B_STOP :
564*eac71506Sjerl1 			case B_ACTIVE_SENSING :
565*eac71506Sjerl1 				SystemRealTime(data, time);
566*eac71506Sjerl1 				break;
567*eac71506Sjerl1 			case B_SYSTEM_RESET :
568*eac71506Sjerl1 				temp = fFileBuffer[fFileBufferIndex];
569*eac71506Sjerl1 				if (temp == 0x2F)
570*eac71506Sjerl1 					return true;
571*eac71506Sjerl1 				if (temp == 0x51)
572*eac71506Sjerl1 				{//Calcul of the tempo is wrong
573*eac71506Sjerl1 					fFileBufferIndex +=2;
574*eac71506Sjerl1 					ForTempo = fFileBuffer[fFileBufferIndex++] << 8;
575*eac71506Sjerl1 					ForTempo |= fFileBuffer[fFileBufferIndex++];
576*eac71506Sjerl1 					ForTempo = (ForTempo << 8) | fFileBuffer[fFileBufferIndex++];
577*eac71506Sjerl1 //					ForTempo /= 2500;
578*eac71506Sjerl1 					TempoChange(ForTempo, time);
579*eac71506Sjerl1 				}
580*eac71506Sjerl1 				else
581*eac71506Sjerl1 				{
582*eac71506Sjerl1 					temp = fFileBuffer[fFileBufferIndex + 1] + 3;
583*eac71506Sjerl1 					SystemExclusive(&fFileBuffer[fFileBufferIndex - 1], temp, time);
584*eac71506Sjerl1 					fFileBufferIndex += temp - 1;
585*eac71506Sjerl1 				}
586*eac71506Sjerl1 				break;
587*eac71506Sjerl1 			default :
588*eac71506Sjerl1 				if (data >= 0xF0)
589*eac71506Sjerl1 					printf("Midi Data not Defined\n");
590*eac71506Sjerl1 		}
591*eac71506Sjerl1 	}
592*eac71506Sjerl1 return true;
593*eac71506Sjerl1 }
594*eac71506Sjerl1 
595*eac71506Sjerl1 //-----------------------------------------------
596*eac71506Sjerl1 
597*eac71506Sjerl1 int32 BMidiStore::ReadVariNum()
598*eac71506Sjerl1 {//ToTest
599*eac71506Sjerl1 int32 result = 0;
600*eac71506Sjerl1 uchar tempo = 0;
601*eac71506Sjerl1 	while (fFileBufferIndex < fFileBufferSize)
602*eac71506Sjerl1 	{
603*eac71506Sjerl1 		tempo = fFileBuffer[fFileBufferIndex++];
604*eac71506Sjerl1 		result |= tempo & 0x7F;
605*eac71506Sjerl1 		if ((tempo & 0x80) == 0)
606*eac71506Sjerl1 			return result;
607*eac71506Sjerl1 		result <<= 7;
608*eac71506Sjerl1 	}
609*eac71506Sjerl1 return B_ERROR;
610*eac71506Sjerl1 }
611*eac71506Sjerl1 
612*eac71506Sjerl1 //-----------------------------------------------
613*eac71506Sjerl1 
614*eac71506Sjerl1 void BMidiStore::ChannelMessage(int32, int32, int32)
615*eac71506Sjerl1 {//ToDo
616*eac71506Sjerl1 
617*eac71506Sjerl1 }
618*eac71506Sjerl1 
619*eac71506Sjerl1 //-----------------------------------------------
620*eac71506Sjerl1 
621*eac71506Sjerl1 void BMidiStore::MsgInit()
622*eac71506Sjerl1 {//ToDo
623*eac71506Sjerl1 
624*eac71506Sjerl1 }
625*eac71506Sjerl1 
626*eac71506Sjerl1 //-----------------------------------------------
627*eac71506Sjerl1 
628*eac71506Sjerl1 void BMidiStore::MsgAdd(int32)
629*eac71506Sjerl1 {//ToDo
630*eac71506Sjerl1 
631*eac71506Sjerl1 }
632*eac71506Sjerl1 
633*eac71506Sjerl1 //-----------------------------------------------
634*eac71506Sjerl1 
635*eac71506Sjerl1 void BMidiStore::BiggerMsg()
636*eac71506Sjerl1 {//ToDo
637*eac71506Sjerl1 
638*eac71506Sjerl1 }
639*eac71506Sjerl1 
640*eac71506Sjerl1 //-----------------------------------------------
641*eac71506Sjerl1 
642*eac71506Sjerl1 void BMidiStore::MetaEvent(int32)
643*eac71506Sjerl1 {//ToDo
644*eac71506Sjerl1 
645*eac71506Sjerl1 }
646*eac71506Sjerl1 
647*eac71506Sjerl1 //-----------------------------------------------
648*eac71506Sjerl1 
649*eac71506Sjerl1 int32 BMidiStore::MsgLength()
650*eac71506Sjerl1 {//ToTest
651*eac71506Sjerl1 int32 t = 0;
652*eac71506Sjerl1 	while (fFileBuffer[fFileBufferIndex + t] != 0xF7)
653*eac71506Sjerl1 	{
654*eac71506Sjerl1 		if (fFileBufferIndex + t > fFileBufferSize - 3)
655*eac71506Sjerl1 			return -1;
656*eac71506Sjerl1 		else
657*eac71506Sjerl1 			t++;
658*eac71506Sjerl1 	}
659*eac71506Sjerl1 return t;
660*eac71506Sjerl1 }
661*eac71506Sjerl1 
662*eac71506Sjerl1 //-----------------------------------------------
663*eac71506Sjerl1 
664*eac71506Sjerl1 uchar *BMidiStore::Msg()
665*eac71506Sjerl1 {//ToDo
666*eac71506Sjerl1 return 0;
667*eac71506Sjerl1 }
668*eac71506Sjerl1 
669*eac71506Sjerl1 //-----------------------------------------------
670*eac71506Sjerl1 
671*eac71506Sjerl1 void BMidiStore::BadByte(int32)
672*eac71506Sjerl1 {//ToDo
673*eac71506Sjerl1 
674*eac71506Sjerl1 }
675*eac71506Sjerl1 
676*eac71506Sjerl1 //-----------------------------------------------
677*eac71506Sjerl1 
678*eac71506Sjerl1 
679*eac71506Sjerl1 int32 BMidiStore::PutC(int32 c)
680*eac71506Sjerl1 {//ToDo
681*eac71506Sjerl1 return 0;
682*eac71506Sjerl1 }
683*eac71506Sjerl1 
684*eac71506Sjerl1 //-----------------------------------------------
685*eac71506Sjerl1 
686*eac71506Sjerl1 bool BMidiStore::WriteTrack(int32 track)
687*eac71506Sjerl1 {//ToTest
688*eac71506Sjerl1 uchar temp[4] = {0x00, 0x00, 0x00, 0x00};
689*eac71506Sjerl1 	WriteTrackChunk(track);
690*eac71506Sjerl1 	fNumBytesWritten = 0;
691*eac71506Sjerl1 uint32 ticks = 0;
692*eac71506Sjerl1 int32 i = 0;
693*eac71506Sjerl1 // If track == -1 write all events
694*eac71506Sjerl1 BMidiEvent *event = (BMidiEvent*)events->ItemAt(i++);
695*eac71506Sjerl1 	if (event != NULL)
696*eac71506Sjerl1 		fCurrTime = event->time;
697*eac71506Sjerl1 	while (event != NULL)
698*eac71506Sjerl1 	{
699*eac71506Sjerl1 		ticks = MillisecondsToTicks(event->time - fCurrTime);
700*eac71506Sjerl1 		switch(event->opcode)
701*eac71506Sjerl1 		{
702*eac71506Sjerl1 			case BMidiEvent::OP_NOTE_OFF :
703*eac71506Sjerl1 					if ((track == -1) || (track == event->noteOff.channel))
704*eac71506Sjerl1 					{
705*eac71506Sjerl1 						temp[0] = event->noteOff.note;
706*eac71506Sjerl1 						temp[1] = event->noteOff.velocity;
707*eac71506Sjerl1 						WriteMidiEvent(ticks, B_NOTE_OFF, event->noteOff.channel, temp, 2);
708*eac71506Sjerl1 					}
709*eac71506Sjerl1 					break;
710*eac71506Sjerl1 			case BMidiEvent::OP_NOTE_ON :
711*eac71506Sjerl1 					if ((track == -1) || (track == event->noteOn.channel))
712*eac71506Sjerl1 					{
713*eac71506Sjerl1 						temp[0] = event->noteOn.note;
714*eac71506Sjerl1 						temp[1] = event->noteOn.velocity;
715*eac71506Sjerl1 						WriteMidiEvent(ticks, B_NOTE_ON, event->noteOn.channel, temp, 2);
716*eac71506Sjerl1 					}
717*eac71506Sjerl1 					break;
718*eac71506Sjerl1 			case BMidiEvent::OP_KEY_PRESSURE :
719*eac71506Sjerl1 					if ((track == -1) || (track == event->keyPressure.channel))
720*eac71506Sjerl1 					{
721*eac71506Sjerl1 						temp[0] = event->keyPressure.note;
722*eac71506Sjerl1 						temp[1] = event->keyPressure.pressure;
723*eac71506Sjerl1 						WriteMidiEvent(ticks, B_KEY_PRESSURE, event->keyPressure.channel, temp, 2);
724*eac71506Sjerl1 					}
725*eac71506Sjerl1 					break;
726*eac71506Sjerl1 			case BMidiEvent::OP_CONTROL_CHANGE :
727*eac71506Sjerl1 					if ((track == -1) || (track == event->controlChange.channel))
728*eac71506Sjerl1 					{
729*eac71506Sjerl1 						temp[0] = event->controlChange.controlNumber;
730*eac71506Sjerl1 						temp[1] = event->controlChange.controlValue;
731*eac71506Sjerl1 						WriteMidiEvent(ticks, B_CONTROL_CHANGE, event->controlChange.channel, temp, 2);
732*eac71506Sjerl1 					}
733*eac71506Sjerl1 					break;
734*eac71506Sjerl1 			case BMidiEvent::OP_PROGRAM_CHANGE :
735*eac71506Sjerl1 					if ((track == -1) || (track == event->programChange.channel))
736*eac71506Sjerl1 					{
737*eac71506Sjerl1 						temp[0] = event->programChange.programNumber;
738*eac71506Sjerl1 						WriteMidiEvent(ticks, B_PROGRAM_CHANGE, event->programChange.channel, temp, 1);
739*eac71506Sjerl1 					}
740*eac71506Sjerl1 					break;
741*eac71506Sjerl1 			case BMidiEvent::OP_CHANNEL_PRESSURE :
742*eac71506Sjerl1 					if ((track == -1) || (track == event->channelPressure.channel))
743*eac71506Sjerl1 					{
744*eac71506Sjerl1 						temp[0] = event->channelPressure.pressure;
745*eac71506Sjerl1 						WriteMidiEvent(ticks, B_CHANNEL_PRESSURE, event->channelPressure.channel, temp, 1);
746*eac71506Sjerl1 					}
747*eac71506Sjerl1 					break;
748*eac71506Sjerl1 			case BMidiEvent::OP_PITCH_BEND :
749*eac71506Sjerl1 					if ((track == -1) || (track == event->pitchBend.channel))
750*eac71506Sjerl1 					{
751*eac71506Sjerl1 						temp[0] = event->pitchBend.lsb;
752*eac71506Sjerl1 						temp[1] = event->pitchBend.msb;
753*eac71506Sjerl1 						WriteMidiEvent(ticks, B_PITCH_BEND, event->pitchBend.channel, temp, 2);
754*eac71506Sjerl1 					}
755*eac71506Sjerl1 					break;
756*eac71506Sjerl1 			case BMidiEvent::OP_SYSTEM_COMMON :
757*eac71506Sjerl1 					if ((track == -1) || (track == 0))
758*eac71506Sjerl1 					{
759*eac71506Sjerl1 						temp[0] = event->systemCommon.data1;
760*eac71506Sjerl1 						temp[1] = event->systemCommon.data2;
761*eac71506Sjerl1 						WriteMetaEvent(ticks, event->systemCommon.status, temp, 2);
762*eac71506Sjerl1 					}
763*eac71506Sjerl1 					break;
764*eac71506Sjerl1 			case BMidiEvent::OP_SYSTEM_REAL_TIME :
765*eac71506Sjerl1 					if ((track == -1) || (track == 0))
766*eac71506Sjerl1 					{
767*eac71506Sjerl1 						WriteMetaEvent(ticks, event->systemRealTime.status, temp, 0);
768*eac71506Sjerl1 					}
769*eac71506Sjerl1 					break;
770*eac71506Sjerl1 			case BMidiEvent::OP_SYSTEM_EXCLUSIVE :
771*eac71506Sjerl1 					if ((track == -1) || (track == 0))
772*eac71506Sjerl1 					{
773*eac71506Sjerl1 						WriteSystemExclusiveEvent(ticks, event->systemExclusive.data, event->systemExclusive.dataLength);
774*eac71506Sjerl1 					}
775*eac71506Sjerl1 					break;
776*eac71506Sjerl1 			case BMidiEvent::OP_TEMPO_CHANGE :
777*eac71506Sjerl1 					if ((track == -1) || (track == 0))
778*eac71506Sjerl1 					{
779*eac71506Sjerl1 						WriteTempo(ticks, event->tempoChange.beatsPerMinute);
780*eac71506Sjerl1 					}
781*eac71506Sjerl1 					break;
782*eac71506Sjerl1 //Not used
783*eac71506Sjerl1 			case BMidiEvent::OP_NONE :
784*eac71506Sjerl1 			case BMidiEvent::OP_ALL_NOTES_OFF :
785*eac71506Sjerl1 			case BMidiEvent::OP_TRACK_END :
786*eac71506Sjerl1 					break;
787*eac71506Sjerl1 		}
788*eac71506Sjerl1 //		}
789*eac71506Sjerl1 		fCurrTime = event->time;
790*eac71506Sjerl1 		event = (BMidiEvent*)events->ItemAt(i++);
791*eac71506Sjerl1 	}
792*eac71506Sjerl1 
793*eac71506Sjerl1 	Write16Bit(0xFF2F);
794*eac71506Sjerl1 	EPutC(0);
795*eac71506Sjerl1 return true;
796*eac71506Sjerl1 }
797*eac71506Sjerl1 
798*eac71506Sjerl1 //-----------------------------------------------
799*eac71506Sjerl1 
800*eac71506Sjerl1 void BMidiStore::WriteTempoTrack()
801*eac71506Sjerl1 {//ToDo
802*eac71506Sjerl1 }
803*eac71506Sjerl1 
804*eac71506Sjerl1 //-----------------------------------------------
805*eac71506Sjerl1 
806*eac71506Sjerl1 bool BMidiStore::WriteTrackChunk(int32 whichTrack)
807*eac71506Sjerl1 {//ToTest
808*eac71506Sjerl1 	Write32Bit('MTrk');
809*eac71506Sjerl1 	Write32Bit(6);
810*eac71506Sjerl1 return true;
811*eac71506Sjerl1 }
812*eac71506Sjerl1 
813*eac71506Sjerl1 //-----------------------------------------------
814*eac71506Sjerl1 
815*eac71506Sjerl1 void BMidiStore::WriteHeaderChunk(int32 format)
816*eac71506Sjerl1 {//ToTest
817*eac71506Sjerl1 	Write32Bit('MThd');
818*eac71506Sjerl1 	Write32Bit(6);
819*eac71506Sjerl1 	Write16Bit(format);
820*eac71506Sjerl1 	if (format == 0)
821*eac71506Sjerl1 		fNumTracks = 1;
822*eac71506Sjerl1 	Write16Bit(fNumTracks);
823*eac71506Sjerl1 	Write16Bit(fDivision);
824*eac71506Sjerl1 }
825*eac71506Sjerl1 
826*eac71506Sjerl1 //-----------------------------------------------
827*eac71506Sjerl1 
828*eac71506Sjerl1 bool BMidiStore::WriteMidiEvent(uint32 deltaTime, uint32 type, uint32 channel, uchar* data, uint32 size)
829*eac71506Sjerl1 {//ToTest
830*eac71506Sjerl1 	WriteVarLen(deltaTime);
831*eac71506Sjerl1 	if (EPutC(type | channel) != 1)
832*eac71506Sjerl1 		return false;
833*eac71506Sjerl1 	while (size > 0)
834*eac71506Sjerl1 	{
835*eac71506Sjerl1 		if (EPutC(*data) != 1)
836*eac71506Sjerl1 			return false;
837*eac71506Sjerl1 		data++;
838*eac71506Sjerl1 		size--;
839*eac71506Sjerl1 	}
840*eac71506Sjerl1 return true;
841*eac71506Sjerl1 }
842*eac71506Sjerl1 
843*eac71506Sjerl1 //-----------------------------------------------
844*eac71506Sjerl1 
845*eac71506Sjerl1 bool BMidiStore::WriteMetaEvent(uint32 deltaTime, uint32 type, uchar* data, uint32 size)
846*eac71506Sjerl1 {//ToTest
847*eac71506Sjerl1 	WriteVarLen(deltaTime);
848*eac71506Sjerl1 	if (EPutC(type) != 1)
849*eac71506Sjerl1 		return false;
850*eac71506Sjerl1 	while (size > 0)
851*eac71506Sjerl1 	{
852*eac71506Sjerl1 		if (EPutC(*data) != 1)
853*eac71506Sjerl1 			return false;
854*eac71506Sjerl1 		data++;
855*eac71506Sjerl1 		size--;
856*eac71506Sjerl1 	}
857*eac71506Sjerl1 return true;
858*eac71506Sjerl1 }
859*eac71506Sjerl1 
860*eac71506Sjerl1 //-----------------------------------------------
861*eac71506Sjerl1 
862*eac71506Sjerl1 bool BMidiStore::WriteSystemExclusiveEvent(uint32 deltaTime, uchar* data, uint32 size)
863*eac71506Sjerl1 {//ToTest
864*eac71506Sjerl1 	WriteVarLen(deltaTime);
865*eac71506Sjerl1 	while (size > 0)
866*eac71506Sjerl1 	{
867*eac71506Sjerl1 		if (EPutC(*data) != 1)
868*eac71506Sjerl1 			return false;
869*eac71506Sjerl1 		data++;
870*eac71506Sjerl1 		size--;
871*eac71506Sjerl1 	}
872*eac71506Sjerl1 return true;
873*eac71506Sjerl1 }
874*eac71506Sjerl1 
875*eac71506Sjerl1 //-----------------------------------------------
876*eac71506Sjerl1 
877*eac71506Sjerl1 void BMidiStore::WriteTempo(uint32 deltaTime, int32 tempo)
878*eac71506Sjerl1 {//ToTest
879*eac71506Sjerl1 	WriteVarLen(deltaTime);
880*eac71506Sjerl1 	Write16Bit(0xFF51);
881*eac71506Sjerl1 	EPutC(3);
882*eac71506Sjerl1 	EPutC((tempo >> 16) & 0xFF);
883*eac71506Sjerl1 	EPutC((tempo >> 8) & 0xFF);
884*eac71506Sjerl1 	EPutC(tempo & 0xFF);
885*eac71506Sjerl1 }
886*eac71506Sjerl1 
887*eac71506Sjerl1 //-----------------------------------------------
888*eac71506Sjerl1 
889*eac71506Sjerl1 void BMidiStore::WriteVarLen(uint32 value)
890*eac71506Sjerl1 {//ToTest
891*eac71506Sjerl1 uint32 buffer = value & 0x7F;
892*eac71506Sjerl1 	while ( (value >>= 7) )
893*eac71506Sjerl1 	{
894*eac71506Sjerl1 		buffer <<= 8;
895*eac71506Sjerl1 		buffer |= ((value & 0x7F) | 0x80);
896*eac71506Sjerl1 	}
897*eac71506Sjerl1 	while (true)
898*eac71506Sjerl1 	{
899*eac71506Sjerl1 		EPutC(buffer);
900*eac71506Sjerl1 		if (buffer & 0x80)
901*eac71506Sjerl1 			buffer >>= 8;
902*eac71506Sjerl1 		else
903*eac71506Sjerl1 			break;
90425767509Smahlzeit 	}
90525767509Smahlzeit }
90625767509Smahlzeit 
907*eac71506Sjerl1 //-----------------------------------------------
90825767509Smahlzeit 
909*eac71506Sjerl1 void BMidiStore::Write32Bit(uint32 data)
910*eac71506Sjerl1 {//ToTest
911*eac71506Sjerl1 	EPutC((data >> 24) & 0xFF);
912*eac71506Sjerl1 	EPutC((data >> 16) & 0xFF);
913*eac71506Sjerl1 	EPutC((data >> 8) & 0xFF);
914*eac71506Sjerl1 	EPutC(data & 0xFF);
915*eac71506Sjerl1 }
916*eac71506Sjerl1 
917*eac71506Sjerl1 //-----------------------------------------------
918*eac71506Sjerl1 
919*eac71506Sjerl1 void BMidiStore::Write16Bit(ushort data)
920*eac71506Sjerl1 {//ToTest
921*eac71506Sjerl1 	EPutC((data >> 8) & 0xFF);
922*eac71506Sjerl1 	EPutC(data & 0xFF);
923*eac71506Sjerl1 }
924*eac71506Sjerl1 
925*eac71506Sjerl1 //-----------------------------------------------
926*eac71506Sjerl1 
927*eac71506Sjerl1 int32 BMidiStore::EPutC(uchar c)
928*eac71506Sjerl1 {//ToTest
929*eac71506Sjerl1 	fNumBytesWritten++;
930*eac71506Sjerl1 return fFile->Write(&c, 1);
931*eac71506Sjerl1 }
932*eac71506Sjerl1 
933*eac71506Sjerl1 //-----------------------------------------------
934*eac71506Sjerl1 
935*eac71506Sjerl1 
936*eac71506Sjerl1 uint32 BMidiStore::TicksToMilliseconds(uint32 ticks) const
937*eac71506Sjerl1 {//ToTest
938*eac71506Sjerl1 	return ((uint64)ticks * 1000) / fDivision;
939*eac71506Sjerl1 }
940*eac71506Sjerl1 
941*eac71506Sjerl1 //-----------------------------------------------
942*eac71506Sjerl1 
943*eac71506Sjerl1 uint32 BMidiStore::MillisecondsToTicks(uint32 ms) const
944*eac71506Sjerl1 {//ToTest
945*eac71506Sjerl1 	return ((uint64)ms * fDivision) / 1000;
946*eac71506Sjerl1 }
947*eac71506Sjerl1 
948*eac71506Sjerl1 //-----------------------------------------------
949*eac71506Sjerl1 
950*eac71506Sjerl1 void BMidiStore::_ReservedMidiStore1()
951*eac71506Sjerl1 {
952*eac71506Sjerl1 }
953*eac71506Sjerl1 
954*eac71506Sjerl1 //-----------------------------------------------
955*eac71506Sjerl1 
956*eac71506Sjerl1 void BMidiStore::_ReservedMidiStore2()
957*eac71506Sjerl1 {
958*eac71506Sjerl1 }
959*eac71506Sjerl1 
960*eac71506Sjerl1 //-----------------------------------------------
961*eac71506Sjerl1 
962*eac71506Sjerl1 void BMidiStore::_ReservedMidiStore3()
963*eac71506Sjerl1 {
964*eac71506Sjerl1 }
965*eac71506Sjerl1 
966*eac71506Sjerl1 //-----------------------------------------------
967*eac71506Sjerl1 //-----------------------------------------------
968*eac71506Sjerl1 //-----------------------------------------------
969*eac71506Sjerl1 //-----------------------------------------------
970*eac71506Sjerl1 //-----------------------------------------------
971*eac71506Sjerl1 //-----------------------------------------------
972*eac71506Sjerl1 //-----------------------------------------------
973*eac71506Sjerl1 //-----------------------------------------------
974*eac71506Sjerl1 //-----------------------------------------------
975*eac71506Sjerl1 //-----------------------------------------------
976