2 * Copyright 2005-2006, Haiku.
4 * Copyright (c) 2002-2004 Matthijs Hollemans
5 * Copyright (c) 2002 Jerome Leveque
6 * Copyright (c) 2002 Paul Stadler
7 * Distributed under the terms of the MIT License.
18 #include <MidiStore.h>
40 uint32 time
; // either ticks or milliseconds
41 bool ticks
; // event is from MIDI file
45 void* data
; // sysex data
46 size_t length
; // sysex data size
47 int32 tempo
; // beats per minute
52 compare_events(const void* event1
, const void* event2
)
54 BMidiEvent
* e1
= *((BMidiEvent
**) event1
);
55 BMidiEvent
* e2
= *((BMidiEvent
**) event2
);
57 return (e1
->time
- e2
->time
);
64 BMidiStore::BMidiStore()
69 fNeedsSorting
= false;
77 fInstruments
= new bool[128];
81 BMidiStore::~BMidiStore()
83 for (int32 t
= 0; t
< fEvents
->CountItems(); ++t
) {
88 delete[] fInstruments
;
93 BMidiStore::NoteOff(uchar channel
, uchar note
, uchar velocity
,
96 BMidiEvent
* event
= new BMidiEvent
;
99 event
->byte1
= B_NOTE_OFF
| (channel
- 1);
101 event
->byte3
= velocity
;
107 BMidiStore::NoteOn(uchar channel
, uchar note
,
108 uchar velocity
, uint32 time
)
110 BMidiEvent
* event
= new BMidiEvent
;
112 event
->ticks
= false;
113 event
->byte1
= B_NOTE_ON
| (channel
- 1);
115 event
->byte3
= velocity
;
121 BMidiStore::KeyPressure(uchar channel
, uchar note
,
122 uchar pressure
, uint32 time
)
124 BMidiEvent
* event
= new BMidiEvent
;
126 event
->ticks
= false;
127 event
->byte1
= B_KEY_PRESSURE
| (channel
- 1);
129 event
->byte3
= pressure
;
135 BMidiStore::ControlChange(uchar channel
, uchar controlNumber
,
136 uchar controlValue
, uint32 time
)
138 BMidiEvent
* event
= new BMidiEvent
;
140 event
->ticks
= false;
141 event
->byte1
= B_CONTROL_CHANGE
| (channel
- 1);
142 event
->byte2
= controlNumber
;
143 event
->byte3
= controlValue
;
149 BMidiStore::ProgramChange(uchar channel
, uchar programNumber
,
152 BMidiEvent
* event
= new BMidiEvent
;
154 event
->ticks
= false;
155 event
->byte1
= B_PROGRAM_CHANGE
| (channel
- 1);
156 event
->byte2
= programNumber
;
162 BMidiStore::ChannelPressure(uchar channel
, uchar pressure
, uint32 time
)
164 BMidiEvent
* event
= new BMidiEvent
;
166 event
->ticks
= false;
167 event
->byte1
= B_CHANNEL_PRESSURE
| (channel
- 1);
168 event
->byte2
= pressure
;
174 BMidiStore::PitchBend(uchar channel
, uchar lsb
, uchar msb
, uint32 time
)
176 BMidiEvent
* event
= new BMidiEvent
;
178 event
->ticks
= false;
179 event
->byte1
= B_PITCH_BEND
| (channel
- 1);
187 BMidiStore::SystemExclusive(void* data
, size_t length
, uint32 time
)
189 BMidiEvent
* event
= new BMidiEvent
;
191 event
->ticks
= false;
192 event
->byte1
= B_SYS_EX_START
;
193 event
->data
= malloc(length
);
194 event
->length
= length
;
195 memcpy(event
->data
, data
, length
);
201 BMidiStore::SystemCommon(uchar status
, uchar data1
,
202 uchar data2
, uint32 time
)
204 BMidiEvent
* event
= new BMidiEvent
;
206 event
->ticks
= false;
207 event
->byte1
= status
;
208 event
->byte2
= data1
;
209 event
->byte3
= data2
;
215 BMidiStore::SystemRealTime(uchar status
, uint32 time
)
217 BMidiEvent
* event
= new BMidiEvent
;
219 event
->ticks
= false;
220 event
->byte1
= status
;
226 BMidiStore::TempoChange(int32 beatsPerMinute
, uint32 time
)
228 BMidiEvent
* event
= new BMidiEvent
;
230 event
->ticks
= false;
234 event
->tempo
= beatsPerMinute
;
240 BMidiStore::Import(const entry_ref
* ref
)
242 memset(fInstruments
, 0, 128 * sizeof(bool));
245 fFile
= new BFile(ref
, B_READ_ONLY
);
246 if (fFile
->InitCheck() != B_OK
)
247 throw fFile
->InitCheck();
251 if (strncmp(fourcc
, "MThd", 4) != 0)
252 throw (status_t
) B_BAD_MIDI_DATA
;
254 if (Read32Bit() != 6)
255 throw (status_t
) B_BAD_MIDI_DATA
;
257 fFormat
= Read16Bit();
258 fNumTracks
= Read16Bit();
259 fTicksPerBeat
= Read16Bit();
261 if (fTicksPerBeat
& 0x8000) {
262 // we don't support SMPTE time codes,
263 // only ticks per quarter note
268 while (fCurrTrack
< fNumTracks
) {
271 } catch (status_t e
) {
286 BMidiStore::Export(const entry_ref
* ref
, int32 format
)
289 fFile
= new BFile(ref
, B_READ_WRITE
);
290 if (fFile
->InitCheck() != B_OK
)
291 throw fFile
->InitCheck();
295 WriteFourCC('M', 'T', 'h', 'd');
297 Write16Bit(0); // we do only format 0
299 Write16Bit(fTicksPerBeat
);
302 } catch (status_t e
) {
315 BMidiStore::SortEvents(bool force
)
317 if (force
|| fNeedsSorting
) {
318 fEvents
->SortItems(compare_events
);
319 fNeedsSorting
= false;
325 BMidiStore::CountEvents() const
327 return fEvents
->CountItems();
332 BMidiStore::CurrentEvent() const
334 return fCurrentEvent
;
339 BMidiStore::SetCurrentEvent(uint32 eventNumber
)
341 fCurrentEvent
= eventNumber
;
346 BMidiStore::DeltaOfEvent(uint32 eventNumber
) const
348 // Even though the BeBook says that the delta is the time span between
349 // an event and the first event in the list, this doesn't appear to be
350 // true for events that were captured from other BMidi objects such as
351 // BMidiPort. For those events, we return the absolute timestamp. The
352 // BeBook is correct for events from MIDI files, though.
354 BMidiEvent
* event
= EventAt(eventNumber
);
356 return GetEventTime(event
);
363 BMidiStore::EventAtDelta(uint32 time
) const
365 for (int32 t
= 0; t
< fEvents
->CountItems(); ++t
) {
366 if (GetEventTime(EventAt(t
)) >= time
)
375 BMidiStore::BeginTime() const
382 BMidiStore::SetTempo(int32 beatsPerMinute_
)
384 fBeatsPerMinute
= beatsPerMinute_
;
389 BMidiStore::Tempo() const
391 return fBeatsPerMinute
;
395 void BMidiStore::_ReservedMidiStore1() { }
396 void BMidiStore::_ReservedMidiStore2() { }
397 void BMidiStore::_ReservedMidiStore3() { }
403 // This rather compilicated Run() loop is not only used by BMidiStore
404 // but also by BMidiSynthFile. The "paused", "finished", and "looping"
405 // flags, and the "stop hook" are especially provided for the latter.
410 int32 timeAdjust
= 0;
412 bool firstEvent
= true;
413 bool resetTime
= false;
415 while (KeepRunning()) {
422 BMidiEvent
* event
= EventAt(fCurrentEvent
);
436 baseTime
= fStartTime
;
437 } else if (resetTime
)
440 if (firstEvent
|| resetTime
) {
441 timeAdjust
= baseTime
- GetEventTime(event
);
442 SprayEvent(event
, baseTime
);
446 SprayEvent(event
, GetEventTime(event
) + timeAdjust
);
454 if (fHookFunc
!= NULL
)
455 (*fHookFunc
)(fHookArg
);
460 BMidiStore::AddEvent(BMidiEvent
* event
)
462 fEvents
->AddItem(event
);
463 fNeedsSorting
= true;
468 BMidiStore::SprayEvent(const BMidiEvent
* event
, uint32 time
)
470 uchar byte1
= event
->byte1
;
471 uchar byte2
= event
->byte2
;
472 uchar byte3
= event
->byte3
;
474 switch (byte1
& 0xF0) {
476 SprayNoteOff((byte1
& 0x0F) + 1, byte2
, byte3
, time
);
480 SprayNoteOn((byte1
& 0x0F) + 1, byte2
, byte3
, time
);
484 SprayKeyPressure((byte1
& 0x0F) + 1, byte2
, byte3
, time
);
487 case B_CONTROL_CHANGE
:
488 SprayControlChange((byte1
& 0x0F) + 1, byte2
, byte3
, time
);
491 case B_PROGRAM_CHANGE
:
492 SprayProgramChange((byte1
& 0x0F) + 1, byte2
, time
);
495 case B_CHANNEL_PRESSURE
:
496 SprayChannelPressure((byte1
& 0x0F) + 1, byte2
, time
);
500 SprayPitchBend((byte1
& 0x0F) + 1, byte2
, byte3
, time
);
506 SpraySystemExclusive(event
->data
, event
->length
, time
);
509 case B_MIDI_TIME_CODE
:
510 case B_SONG_POSITION
:
512 case B_CABLE_MESSAGE
:
515 SpraySystemCommon(byte1
, byte2
, byte3
, time
);
522 case B_ACTIVE_SENSING
:
523 SpraySystemRealTime(byte1
, time
);
527 if (byte2
== 0x51 && byte3
== 0x03) {
528 SprayTempoChange(event
->tempo
, time
);
529 fBeatsPerMinute
= event
->tempo
;
531 SpraySystemRealTime(byte1
, time
);
540 BMidiStore::EventAt(int32 index
) const
542 return (BMidiEvent
*)fEvents
->ItemAt(index
);
547 BMidiStore::GetEventTime(const BMidiEvent
* event
) const
550 return TicksToMilliseconds(event
->time
);
557 BMidiStore::TicksToMilliseconds(uint32 ticks
) const
559 return ((uint64
)ticks
* 60000) / (fBeatsPerMinute
* fTicksPerBeat
);
564 BMidiStore::MillisecondsToTicks(uint32 ms
) const
566 return ((uint64
)ms
* fBeatsPerMinute
* fTicksPerBeat
) / 60000;
571 BMidiStore::ReadFourCC(char* fourcc
)
573 if (fFile
->Read(fourcc
, 4) != 4)
574 throw (status_t
) B_BAD_MIDI_DATA
;
579 BMidiStore::WriteFourCC(char a
, char b
, char c
, char d
)
581 char fourcc
[4] = { a
, b
, c
, d
};
583 if (fFile
->Write(fourcc
, 4) != 4)
584 throw (status_t
) B_ERROR
;
589 BMidiStore::Read32Bit()
592 if (fFile
->Read(buf
, 4) != 4)
593 throw (status_t
) B_BAD_MIDI_DATA
;
595 return (buf
[0] << 24L) | (buf
[1] << 16L) | (buf
[2] << 8L) | buf
[3];
600 BMidiStore::Write32Bit(uint32 val
)
603 buf
[0] = (val
>> 24) & 0xFF;
604 buf
[1] = (val
>> 16) & 0xFF;
605 buf
[2] = (val
>> 8) & 0xFF;
608 if (fFile
->Write(buf
, 4) != 4)
609 throw (status_t
) B_ERROR
;
614 BMidiStore::Read16Bit()
617 if (fFile
->Read(buf
, 2) != 2)
618 throw (status_t
) B_BAD_MIDI_DATA
;
620 return (buf
[0] << 8) | buf
[1];
625 BMidiStore::Write16Bit(uint16 val
)
628 buf
[0] = (val
>> 8) & 0xFF;
631 if (fFile
->Write(buf
, 2) != 2)
632 throw (status_t
) B_ERROR
;
637 BMidiStore::PeekByte()
640 if (fFile
->Read(&buf
, 1) != 1)
641 throw (status_t
) B_BAD_MIDI_DATA
;
643 if (fFile
->Seek(-1, SEEK_CUR
) < 0)
644 throw (status_t
) B_ERROR
;
651 BMidiStore::NextByte()
654 if (fFile
->Read(&buf
, 1) != 1)
655 throw (status_t
) B_BAD_MIDI_DATA
;
663 BMidiStore::WriteByte(uint8 val
)
665 if (fFile
->Write(&val
, 1) != 1)
666 throw (status_t
) B_ERROR
;
673 BMidiStore::SkipBytes(uint32 length
)
675 if (fFile
->Seek(length
, SEEK_CUR
) < 0) {
676 throw (status_t
) B_BAD_MIDI_DATA
;
679 fByteCount
-= length
;
684 BMidiStore::ReadVarLength()
689 if ((val
= NextByte()) & 0x80) {
692 val
= (val
<< 7) + ((byte
= NextByte()) & 0x7F);
693 } while (byte
& 0x80);
701 BMidiStore::WriteVarLength(uint32 val
)
703 uint32 buffer
= val
& 0x7F;
705 while ((val
>>= 7) != 0) {
707 buffer
|= ((val
& 0x7F) | 0x80);
721 BMidiStore::ReadChunk()
726 fByteCount
= Read32Bit();
728 if (strncmp(fourcc
, "MTrk", 4) == 0)
731 TRACE(("Skipping '%c%c%c%c' chunk (%" B_PRIu32
" bytes)",
732 fourcc
[0], fourcc
[1], fourcc
[2], fourcc
[3], fByteCount
))
734 SkipBytes(fByteCount
);
740 BMidiStore::ReadTrack()
749 while (fByteCount
> 0) {
750 uint32 ticks
= ReadVarLength();
751 fTotalTicks
+= ticks
;
753 if (PeekByte() & 0x80)
756 switch (status
& 0xF0) {
760 case B_CONTROL_CHANGE
:
764 event
= new BMidiEvent
;
765 event
->time
= fTotalTicks
;
767 event
->byte1
= status
;
768 event
->byte2
= data1
;
769 event
->byte3
= data2
;
773 case B_PROGRAM_CHANGE
:
774 case B_CHANNEL_PRESSURE
:
776 event
= new BMidiEvent
;
777 event
->time
= fTotalTicks
;
779 event
->byte1
= status
;
780 event
->byte2
= data1
;
783 if ((status
& 0xF0) == B_PROGRAM_CHANGE
)
784 fInstruments
[data1
] = true;
790 ReadSystemExclusive();
799 case B_ACTIVE_SENSING
:
800 event
= new BMidiEvent
;
801 event
->time
= fTotalTicks
;
803 event
->byte1
= status
;
807 case B_MIDI_TIME_CODE
:
809 case B_CABLE_MESSAGE
:
811 event
= new BMidiEvent
;
812 event
->time
= fTotalTicks
;
814 event
->byte1
= status
;
815 event
->byte2
= data1
;
819 case B_SONG_POSITION
:
822 event
= new BMidiEvent
;
823 event
->time
= fTotalTicks
;
825 event
->byte1
= status
;
826 event
->byte2
= data1
;
827 event
->byte3
= data2
;
846 BMidiStore::ReadSystemExclusive()
848 // We do not import sysex's from MIDI files.
850 SkipBytes(ReadVarLength());
855 BMidiStore::ReadMetaEvent()
857 // We only import the Tempo Change meta event.
859 uint8 type
= NextByte();
860 uint32 length
= ReadVarLength();
862 if (type
== 0x51 && length
== 3) {
864 data
[0] = NextByte();
865 data
[1] = NextByte();
866 data
[2] = NextByte();
867 uint32 val
= (data
[0] << 16) | (data
[1] << 8) | data
[2];
869 BMidiEvent
* event
= new BMidiEvent
;
870 event
->time
= fTotalTicks
;
875 event
->tempo
= 60000000 / val
;
883 BMidiStore::WriteTrack()
885 WriteFourCC('M', 'T', 'r', 'k');
886 off_t lengthPos
= fFile
->Position();
893 for (uint32 t
= 0; t
< CountEvents(); ++t
) {
894 BMidiEvent
* event
= EventAt(t
);
897 newTime
= event
->time
;
899 newTime
= MillisecondsToTicks(event
->time
);
904 WriteVarLength(newTime
- oldTime
);
908 switch (event
->byte1
& 0xF0) {
912 case B_CONTROL_CHANGE
:
914 WriteByte(event
->byte1
);
915 WriteByte(event
->byte2
);
916 WriteByte(event
->byte3
);
919 case B_PROGRAM_CHANGE
:
920 case B_CHANNEL_PRESSURE
:
921 WriteByte(event
->byte1
);
922 WriteByte(event
->byte2
);
926 switch (event
->byte1
) {
928 // We do not export sysex's.
937 case B_ACTIVE_SENSING
:
938 WriteByte(event
->byte1
);
941 case B_MIDI_TIME_CODE
:
943 case B_CABLE_MESSAGE
:
944 WriteByte(event
->byte1
);
945 WriteByte(event
->byte2
);
948 case B_SONG_POSITION
:
949 WriteByte(event
->byte1
);
950 WriteByte(event
->byte2
);
951 WriteByte(event
->byte3
);
955 WriteMetaEvent(event
);
963 WriteByte(0xFF); // the end-of-track
964 WriteByte(0x2F); // marker is required
967 fFile
->Seek(lengthPos
, SEEK_SET
);
968 Write32Bit(fByteCount
);
969 fFile
->Seek(0, SEEK_END
);
974 BMidiStore::WriteMetaEvent(BMidiEvent
* event
)
976 // We only export the Tempo Change meta event.
978 if (event
->byte2
== 0x51 && event
->byte3
== 0x03) {
979 uint32 val
= 60000000 / event
->tempo
;
984 WriteByte(val
>> 16);