Fixed warnings.
Applied our coding style a bit, but the class members should be renamed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+166
-262
@@ -33,8 +33,7 @@
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct BMidiEvent
|
struct BMidiEvent {
|
||||||
{
|
|
||||||
BMidiEvent()
|
BMidiEvent()
|
||||||
{
|
{
|
||||||
byte1 = 0;
|
byte1 = 0;
|
||||||
@@ -59,9 +58,9 @@ struct BMidiEvent
|
|||||||
int32 tempo; // beats per minute
|
int32 tempo; // beats per minute
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static int compare_events(const void* event1, const void* event2)
|
static int
|
||||||
|
compare_events(const void* event1, const void* event2)
|
||||||
{
|
{
|
||||||
BMidiEvent* e1 = *((BMidiEvent**) event1);
|
BMidiEvent* e1 = *((BMidiEvent**) event1);
|
||||||
BMidiEvent* e2 = *((BMidiEvent**) event2);
|
BMidiEvent* e2 = *((BMidiEvent**) event2);
|
||||||
@@ -69,7 +68,9 @@ static int compare_events(const void* event1, const void* event2)
|
|||||||
return (e1->time - e2->time);
|
return (e1->time - e2->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
BMidiStore::BMidiStore()
|
BMidiStore::BMidiStore()
|
||||||
{
|
{
|
||||||
@@ -87,22 +88,21 @@ BMidiStore::BMidiStore()
|
|||||||
instruments = new bool[128];
|
instruments = new bool[128];
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BMidiStore::~BMidiStore()
|
BMidiStore::~BMidiStore()
|
||||||
{
|
{
|
||||||
for (int32 t = 0; t < events->CountItems(); ++t)
|
for (int32 t = 0; t < events->CountItems(); ++t) {
|
||||||
{
|
|
||||||
delete EventAt(t);
|
delete EventAt(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete events;
|
delete events;
|
||||||
delete[] instruments;
|
delete[] instruments;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::NoteOff(
|
void
|
||||||
uchar channel, uchar note, uchar velocity, uint32 time)
|
BMidiStore::NoteOff(uchar channel, uchar note, uchar velocity,
|
||||||
|
uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -113,10 +113,10 @@ void BMidiStore::NoteOff(
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::NoteOn(
|
void
|
||||||
uchar channel, uchar note, uchar velocity, uint32 time)
|
BMidiStore::NoteOn(uchar channel, uchar note,
|
||||||
|
uchar velocity, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -127,10 +127,10 @@ void BMidiStore::NoteOn(
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::KeyPressure(
|
void
|
||||||
uchar channel, uchar note, uchar pressure, uint32 time)
|
BMidiStore::KeyPressure(uchar channel, uchar note,
|
||||||
|
uchar pressure, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -141,10 +141,10 @@ void BMidiStore::KeyPressure(
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ControlChange(
|
void
|
||||||
uchar channel, uchar controlNumber, uchar controlValue, uint32 time)
|
BMidiStore::ControlChange(uchar channel, uchar controlNumber,
|
||||||
|
uchar controlValue, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -155,10 +155,10 @@ void BMidiStore::ControlChange(
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ProgramChange(
|
void
|
||||||
uchar channel, uchar programNumber, uint32 time)
|
BMidiStore::ProgramChange(uchar channel, uchar programNumber,
|
||||||
|
uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -168,9 +168,9 @@ void BMidiStore::ProgramChange(
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ChannelPressure(uchar channel, uchar pressure, uint32 time)
|
void
|
||||||
|
BMidiStore::ChannelPressure(uchar channel, uchar pressure, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -180,9 +180,9 @@ void BMidiStore::ChannelPressure(uchar channel, uchar pressure, uint32 time)
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time)
|
void
|
||||||
|
BMidiStore::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -193,9 +193,9 @@ void BMidiStore::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time)
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SystemExclusive(void* data, size_t length, uint32 time)
|
void
|
||||||
|
BMidiStore::SystemExclusive(void* data, size_t length, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -207,10 +207,10 @@ void BMidiStore::SystemExclusive(void* data, size_t length, uint32 time)
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SystemCommon(
|
void
|
||||||
uchar status, uchar data1, uchar data2, uint32 time)
|
BMidiStore::SystemCommon(uchar status, uchar data1,
|
||||||
|
uchar data2, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -221,9 +221,9 @@ void BMidiStore::SystemCommon(
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SystemRealTime(uchar status, uint32 time)
|
void
|
||||||
|
BMidiStore::SystemRealTime(uchar status, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -232,9 +232,9 @@ void BMidiStore::SystemRealTime(uchar status, uint32 time)
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::TempoChange(int32 beatsPerMinute, uint32 time)
|
void
|
||||||
|
BMidiStore::TempoChange(int32 beatsPerMinute, uint32 time)
|
||||||
{
|
{
|
||||||
BMidiEvent* event = new BMidiEvent;
|
BMidiEvent* event = new BMidiEvent;
|
||||||
event->time = time;
|
event->time = time;
|
||||||
@@ -246,49 +246,40 @@ void BMidiStore::TempoChange(int32 beatsPerMinute, uint32 time)
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiStore::Import(const entry_ref* ref)
|
status_t
|
||||||
|
BMidiStore::Import(const entry_ref* ref)
|
||||||
{
|
{
|
||||||
memset(instruments, 0, 128 * sizeof(bool));
|
memset(instruments, 0, 128 * sizeof(bool));
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
file = new BFile(ref, B_READ_ONLY);
|
file = new BFile(ref, B_READ_ONLY);
|
||||||
if (file->InitCheck() != B_OK)
|
if (file->InitCheck() != B_OK)
|
||||||
{
|
|
||||||
throw file->InitCheck();
|
throw file->InitCheck();
|
||||||
}
|
|
||||||
|
|
||||||
char fourcc[4];
|
char fourcc[4];
|
||||||
ReadFourCC(fourcc);
|
ReadFourCC(fourcc);
|
||||||
if (strncmp(fourcc, "MThd", 4) != 0)
|
if (strncmp(fourcc, "MThd", 4) != 0)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
if (Read32Bit() != 6)
|
if (Read32Bit() != 6)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
format = Read16Bit();
|
format = Read16Bit();
|
||||||
numTracks = Read16Bit();
|
numTracks = Read16Bit();
|
||||||
ticksPerBeat = Read16Bit();
|
ticksPerBeat = Read16Bit();
|
||||||
|
|
||||||
if (ticksPerBeat & 0x8000) // we don't support SMPTE
|
if (ticksPerBeat & 0x8000) {
|
||||||
{ // time codes, only ticks
|
// we don't support SMPTE time codes,
|
||||||
ticksPerBeat = 240; // per quarter note
|
// only ticks per quarter note
|
||||||
|
ticksPerBeat = 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
currTrack = 0;
|
currTrack = 0;
|
||||||
while (currTrack < numTracks)
|
while (currTrack < numTracks) {
|
||||||
{
|
|
||||||
ReadChunk();
|
ReadChunk();
|
||||||
}
|
}
|
||||||
}
|
} catch (status_t e) {
|
||||||
catch (status_t e)
|
|
||||||
{
|
|
||||||
delete file;
|
delete file;
|
||||||
file = NULL;
|
file = NULL;
|
||||||
return e;
|
return e;
|
||||||
@@ -301,17 +292,14 @@ status_t BMidiStore::Import(const entry_ref* ref)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiStore::Export(const entry_ref* ref, int32 format)
|
status_t
|
||||||
|
BMidiStore::Export(const entry_ref* ref, int32 format)
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
file = new BFile(ref, B_READ_WRITE);
|
file = new BFile(ref, B_READ_WRITE);
|
||||||
if (file->InitCheck() != B_OK)
|
if (file->InitCheck() != B_OK)
|
||||||
{
|
|
||||||
throw file->InitCheck();
|
throw file->InitCheck();
|
||||||
}
|
|
||||||
|
|
||||||
SortEvents(true);
|
SortEvents(true);
|
||||||
|
|
||||||
@@ -322,9 +310,7 @@ status_t BMidiStore::Export(const entry_ref* ref, int32 format)
|
|||||||
Write16Bit(ticksPerBeat);
|
Write16Bit(ticksPerBeat);
|
||||||
|
|
||||||
WriteTrack();
|
WriteTrack();
|
||||||
}
|
} catch (status_t e) {
|
||||||
catch (status_t e)
|
|
||||||
{
|
|
||||||
delete file;
|
delete file;
|
||||||
file = NULL;
|
file = NULL;
|
||||||
return e;
|
return e;
|
||||||
@@ -335,41 +321,40 @@ status_t BMidiStore::Export(const entry_ref* ref, int32 format)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SortEvents(bool force)
|
void
|
||||||
|
BMidiStore::SortEvents(bool force)
|
||||||
{
|
{
|
||||||
if (force || needsSorting)
|
if (force || needsSorting) {
|
||||||
{
|
|
||||||
events->SortItems(compare_events);
|
events->SortItems(compare_events);
|
||||||
needsSorting = false;
|
needsSorting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::CountEvents() const
|
uint32
|
||||||
|
BMidiStore::CountEvents() const
|
||||||
{
|
{
|
||||||
return events->CountItems();
|
return events->CountItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::CurrentEvent() const
|
uint32
|
||||||
|
BMidiStore::CurrentEvent() const
|
||||||
{
|
{
|
||||||
return currentEvent;
|
return currentEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SetCurrentEvent(uint32 eventNumber)
|
void
|
||||||
|
BMidiStore::SetCurrentEvent(uint32 eventNumber)
|
||||||
{
|
{
|
||||||
currentEvent = eventNumber;
|
currentEvent = eventNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::DeltaOfEvent(uint32 eventNumber) const
|
uint32
|
||||||
|
BMidiStore::DeltaOfEvent(uint32 eventNumber) const
|
||||||
{
|
{
|
||||||
// Even though the BeBook says that the delta is the time span between
|
// Even though the BeBook says that the delta is the time span between
|
||||||
// an event and the first event in the list, this doesn't appear to be
|
// an event and the first event in the list, this doesn't appear to be
|
||||||
@@ -379,42 +364,40 @@ uint32 BMidiStore::DeltaOfEvent(uint32 eventNumber) const
|
|||||||
|
|
||||||
BMidiEvent* event = EventAt(eventNumber);
|
BMidiEvent* event = EventAt(eventNumber);
|
||||||
if (event != NULL)
|
if (event != NULL)
|
||||||
{
|
|
||||||
return GetEventTime(event);
|
return GetEventTime(event);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::EventAtDelta(uint32 time) const
|
uint32
|
||||||
|
BMidiStore::EventAtDelta(uint32 time) const
|
||||||
{
|
{
|
||||||
for (int32 t = 0; t < events->CountItems(); ++t)
|
for (int32 t = 0; t < events->CountItems(); ++t) {
|
||||||
{
|
if (GetEventTime(EventAt(t)) >= time)
|
||||||
if (GetEventTime(EventAt(t)) >= time) { return t; }
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::BeginTime() const
|
uint32
|
||||||
|
BMidiStore::BeginTime() const
|
||||||
{
|
{
|
||||||
return startTime;
|
return startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SetTempo(int32 beatsPerMinute_)
|
void
|
||||||
|
BMidiStore::SetTempo(int32 beatsPerMinute_)
|
||||||
{
|
{
|
||||||
beatsPerMinute = beatsPerMinute_;
|
beatsPerMinute = beatsPerMinute_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int32 BMidiStore::Tempo() const
|
int32
|
||||||
|
BMidiStore::Tempo() const
|
||||||
{
|
{
|
||||||
return beatsPerMinute;
|
return beatsPerMinute;
|
||||||
}
|
}
|
||||||
@@ -427,7 +410,8 @@ void BMidiStore::_ReservedMidiStore3() { }
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void BMidiStore::Run()
|
void
|
||||||
|
BMidiStore::Run()
|
||||||
{
|
{
|
||||||
// This rather compilicated Run() loop is not only used by BMidiStore
|
// This rather compilicated Run() loop is not only used by BMidiStore
|
||||||
// but also by BMidiSynthFile. The "paused", "finished", and "looping"
|
// but also by BMidiSynthFile. The "paused", "finished", and "looping"
|
||||||
@@ -435,57 +419,43 @@ void BMidiStore::Run()
|
|||||||
|
|
||||||
paused = false;
|
paused = false;
|
||||||
finished = false;
|
finished = false;
|
||||||
|
|
||||||
int32 timeAdjust;
|
int32 timeAdjust = 0;
|
||||||
uint32 baseTime;
|
uint32 baseTime = 0;
|
||||||
bool firstEvent = true;
|
bool firstEvent = true;
|
||||||
bool resetTime = false;
|
bool resetTime = false;
|
||||||
|
|
||||||
while (KeepRunning())
|
while (KeepRunning()) {
|
||||||
{
|
if (paused) {
|
||||||
if (paused)
|
|
||||||
{
|
|
||||||
resetTime = true;
|
resetTime = true;
|
||||||
snooze(100000);
|
snooze(100000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMidiEvent* event = EventAt(currentEvent);
|
BMidiEvent* event = EventAt(currentEvent);
|
||||||
|
|
||||||
if (event == NULL) // no more events
|
if (event == NULL) {
|
||||||
{
|
// no more events
|
||||||
if (looping)
|
if (looping) {
|
||||||
{
|
|
||||||
resetTime = true;
|
resetTime = true;
|
||||||
currentEvent = 0;
|
currentEvent = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstEvent)
|
if (firstEvent) {
|
||||||
{
|
|
||||||
startTime = B_NOW;
|
startTime = B_NOW;
|
||||||
baseTime = startTime;
|
baseTime = startTime;
|
||||||
}
|
} else if (resetTime)
|
||||||
else if (resetTime)
|
|
||||||
{
|
|
||||||
baseTime = B_NOW;
|
baseTime = B_NOW;
|
||||||
}
|
|
||||||
|
|
||||||
if (firstEvent || resetTime)
|
if (firstEvent || resetTime) {
|
||||||
{
|
|
||||||
timeAdjust = baseTime - GetEventTime(event);
|
timeAdjust = baseTime - GetEventTime(event);
|
||||||
SprayEvent(event, baseTime);
|
SprayEvent(event, baseTime);
|
||||||
firstEvent = false;
|
firstEvent = false;
|
||||||
resetTime = false;
|
resetTime = false;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
|
||||||
SprayEvent(event, GetEventTime(event) + timeAdjust);
|
SprayEvent(event, GetEventTime(event) + timeAdjust);
|
||||||
}
|
|
||||||
|
|
||||||
++currentEvent;
|
++currentEvent;
|
||||||
}
|
}
|
||||||
@@ -494,29 +464,26 @@ void BMidiStore::Run()
|
|||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
if (hookFunc != NULL)
|
if (hookFunc != NULL)
|
||||||
{
|
|
||||||
(*hookFunc)(hookArg);
|
(*hookFunc)(hookArg);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::AddEvent(BMidiEvent* event)
|
void
|
||||||
|
BMidiStore::AddEvent(BMidiEvent* event)
|
||||||
{
|
{
|
||||||
events->AddItem(event);
|
events->AddItem(event);
|
||||||
needsSorting = true;
|
needsSorting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SprayEvent(const BMidiEvent* event, uint32 time)
|
void
|
||||||
|
BMidiStore::SprayEvent(const BMidiEvent* event, uint32 time)
|
||||||
{
|
{
|
||||||
uchar byte1 = event->byte1;
|
uchar byte1 = event->byte1;
|
||||||
uchar byte2 = event->byte2;
|
uchar byte2 = event->byte2;
|
||||||
uchar byte3 = event->byte3;
|
uchar byte3 = event->byte3;
|
||||||
|
|
||||||
switch (byte1 & 0xF0)
|
switch (byte1 & 0xF0) {
|
||||||
{
|
|
||||||
case B_NOTE_OFF:
|
case B_NOTE_OFF:
|
||||||
SprayNoteOff((byte1 & 0x0F) + 1, byte2, byte3, time);
|
SprayNoteOff((byte1 & 0x0F) + 1, byte2, byte3, time);
|
||||||
return;
|
return;
|
||||||
@@ -546,8 +513,7 @@ void BMidiStore::SprayEvent(const BMidiEvent* event, uint32 time)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case 0xF0:
|
case 0xF0:
|
||||||
switch (byte1)
|
switch (byte1) {
|
||||||
{
|
|
||||||
case B_SYS_EX_START:
|
case B_SYS_EX_START:
|
||||||
SpraySystemExclusive(event->data, event->length, time);
|
SpraySystemExclusive(event->data, event->length, time);
|
||||||
return;
|
return;
|
||||||
@@ -570,93 +536,80 @@ void BMidiStore::SprayEvent(const BMidiEvent* event, uint32 time)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case B_SYSTEM_RESET:
|
case B_SYSTEM_RESET:
|
||||||
if ((byte2 == 0x51) && (byte3 == 0x03))
|
if (byte2 == 0x51 && byte3 == 0x03) {
|
||||||
{
|
|
||||||
SprayTempoChange(event->tempo, time);
|
SprayTempoChange(event->tempo, time);
|
||||||
beatsPerMinute = event->tempo;
|
beatsPerMinute = event->tempo;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
|
||||||
SpraySystemRealTime(byte1, time);
|
SpraySystemRealTime(byte1, time);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BMidiEvent* BMidiStore::EventAt(int32 index) const
|
BMidiEvent*
|
||||||
|
BMidiStore::EventAt(int32 index) const
|
||||||
{
|
{
|
||||||
return (BMidiEvent*) events->ItemAt(index);
|
return (BMidiEvent*)events->ItemAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::GetEventTime(const BMidiEvent* event) const
|
uint32
|
||||||
|
BMidiStore::GetEventTime(const BMidiEvent* event) const
|
||||||
{
|
{
|
||||||
if (event->ticks)
|
if (event->ticks)
|
||||||
{
|
|
||||||
return TicksToMilliseconds(event->time);
|
return TicksToMilliseconds(event->time);
|
||||||
}
|
|
||||||
else
|
return event->time;
|
||||||
{
|
|
||||||
return event->time;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::TicksToMilliseconds(uint32 ticks) const
|
uint32
|
||||||
|
BMidiStore::TicksToMilliseconds(uint32 ticks) const
|
||||||
{
|
{
|
||||||
return ((uint64) ticks * 60000) / (beatsPerMinute * ticksPerBeat);
|
return ((uint64)ticks * 60000) / (beatsPerMinute * ticksPerBeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::MillisecondsToTicks(uint32 ms) const
|
uint32
|
||||||
|
BMidiStore::MillisecondsToTicks(uint32 ms) const
|
||||||
{
|
{
|
||||||
return ((uint64) ms * beatsPerMinute * ticksPerBeat) / 60000;
|
return ((uint64)ms * beatsPerMinute * ticksPerBeat) / 60000;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ReadFourCC(char* fourcc)
|
void
|
||||||
|
BMidiStore::ReadFourCC(char* fourcc)
|
||||||
{
|
{
|
||||||
if (file->Read(fourcc, 4) != 4)
|
if (file->Read(fourcc, 4) != 4)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::WriteFourCC(char a, char b, char c, char d)
|
void
|
||||||
|
BMidiStore::WriteFourCC(char a, char b, char c, char d)
|
||||||
{
|
{
|
||||||
char fourcc[4] = { a, b, c, d };
|
char fourcc[4] = { a, b, c, d };
|
||||||
|
|
||||||
if (file->Write(fourcc, 4) != 4)
|
if (file->Write(fourcc, 4) != 4)
|
||||||
{
|
|
||||||
throw (status_t) B_ERROR;
|
throw (status_t) B_ERROR;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::Read32Bit()
|
uint32
|
||||||
|
BMidiStore::Read32Bit()
|
||||||
{
|
{
|
||||||
uint8 buf[4];
|
uint8 buf[4];
|
||||||
if (file->Read(buf, 4) != 4)
|
if (file->Read(buf, 4) != 4)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
return (buf[0] << 24L) | (buf[1] << 16L) | (buf[2] << 8L) | buf[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::Write32Bit(uint32 val)
|
void
|
||||||
|
BMidiStore::Write32Bit(uint32 val)
|
||||||
{
|
{
|
||||||
uint8 buf[4];
|
uint8 buf[4];
|
||||||
buf[0] = (val >> 24) & 0xFF;
|
buf[0] = (val >> 24) & 0xFF;
|
||||||
@@ -665,128 +618,108 @@ void BMidiStore::Write32Bit(uint32 val)
|
|||||||
buf[3] = val & 0xFF;
|
buf[3] = val & 0xFF;
|
||||||
|
|
||||||
if (file->Write(buf, 4) != 4)
|
if (file->Write(buf, 4) != 4)
|
||||||
{
|
|
||||||
throw (status_t) B_ERROR;
|
throw (status_t) B_ERROR;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint16 BMidiStore::Read16Bit()
|
uint16
|
||||||
|
BMidiStore::Read16Bit()
|
||||||
{
|
{
|
||||||
uint8 buf[2];
|
uint8 buf[2];
|
||||||
if (file->Read(buf, 2) != 2)
|
if (file->Read(buf, 2) != 2)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
return (buf[0] << 8) | buf[1];
|
return (buf[0] << 8) | buf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::Write16Bit(uint16 val)
|
void
|
||||||
|
BMidiStore::Write16Bit(uint16 val)
|
||||||
{
|
{
|
||||||
uint8 buf[2];
|
uint8 buf[2];
|
||||||
buf[0] = (val >> 8) & 0xFF;
|
buf[0] = (val >> 8) & 0xFF;
|
||||||
buf[1] = val & 0xFF;
|
buf[1] = val & 0xFF;
|
||||||
|
|
||||||
if (file->Write(buf, 2) != 2)
|
if (file->Write(buf, 2) != 2)
|
||||||
{
|
|
||||||
throw (status_t) B_ERROR;
|
throw (status_t) B_ERROR;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint8 BMidiStore::PeekByte()
|
uint8
|
||||||
|
BMidiStore::PeekByte()
|
||||||
{
|
{
|
||||||
uint8 buf;
|
uint8 buf;
|
||||||
if (file->Read(&buf, 1) != 1)
|
if (file->Read(&buf, 1) != 1)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->Seek(-1, SEEK_CUR) < 0)
|
if (file->Seek(-1, SEEK_CUR) < 0)
|
||||||
{
|
|
||||||
throw (status_t) B_ERROR;
|
throw (status_t) B_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint8 BMidiStore::NextByte()
|
uint8
|
||||||
|
BMidiStore::NextByte()
|
||||||
{
|
{
|
||||||
uint8 buf;
|
uint8 buf;
|
||||||
if (file->Read(&buf, 1) != 1)
|
if (file->Read(&buf, 1) != 1)
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
--byteCount;
|
--byteCount;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::WriteByte(uint8 val)
|
void
|
||||||
|
BMidiStore::WriteByte(uint8 val)
|
||||||
{
|
{
|
||||||
if (file->Write(&val, 1) != 1)
|
if (file->Write(&val, 1) != 1)
|
||||||
{
|
|
||||||
throw (status_t) B_ERROR;
|
throw (status_t) B_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
++byteCount;
|
++byteCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::SkipBytes(uint32 length)
|
void
|
||||||
|
BMidiStore::SkipBytes(uint32 length)
|
||||||
{
|
{
|
||||||
if (file->Seek(length, SEEK_CUR) < 0)
|
if (file->Seek(length, SEEK_CUR) < 0) {
|
||||||
{
|
|
||||||
throw (status_t) B_BAD_MIDI_DATA;
|
throw (status_t) B_BAD_MIDI_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
byteCount -= length;
|
byteCount -= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint32 BMidiStore::ReadVarLength()
|
uint32
|
||||||
|
BMidiStore::ReadVarLength()
|
||||||
{
|
{
|
||||||
uint32 val;
|
uint32 val;
|
||||||
uint8 byte;
|
uint8 byte;
|
||||||
|
|
||||||
if ((val = NextByte()) & 0x80)
|
if ((val = NextByte()) & 0x80) {
|
||||||
{
|
|
||||||
val &= 0x7F;
|
val &= 0x7F;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
val = (val << 7) + ((byte = NextByte()) & 0x7F);
|
val = (val << 7) + ((byte = NextByte()) & 0x7F);
|
||||||
}
|
} while (byte & 0x80);
|
||||||
while (byte & 0x80);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::WriteVarLength(uint32 val)
|
void
|
||||||
|
BMidiStore::WriteVarLength(uint32 val)
|
||||||
{
|
{
|
||||||
uint32 buffer = val & 0x7F;
|
uint32 buffer = val & 0x7F;
|
||||||
|
|
||||||
while ((val >>= 7))
|
while ((val >>= 7) != 0) {
|
||||||
{
|
|
||||||
buffer <<= 8;
|
buffer <<= 8;
|
||||||
buffer |= ((val & 0x7F) | 0x80);
|
buffer |= ((val & 0x7F) | 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
|
||||||
WriteByte(buffer);
|
WriteByte(buffer);
|
||||||
if (buffer & 0x80)
|
if (buffer & 0x80)
|
||||||
buffer >>= 8;
|
buffer >>= 8;
|
||||||
@@ -795,9 +728,9 @@ void BMidiStore::WriteVarLength(uint32 val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ReadChunk()
|
void
|
||||||
|
BMidiStore::ReadChunk()
|
||||||
{
|
{
|
||||||
char fourcc[4];
|
char fourcc[4];
|
||||||
ReadFourCC(fourcc);
|
ReadFourCC(fourcc);
|
||||||
@@ -805,11 +738,8 @@ void BMidiStore::ReadChunk()
|
|||||||
byteCount = Read32Bit();
|
byteCount = Read32Bit();
|
||||||
|
|
||||||
if (strncmp(fourcc, "MTrk", 4) == 0)
|
if (strncmp(fourcc, "MTrk", 4) == 0)
|
||||||
{
|
|
||||||
ReadTrack();
|
ReadTrack();
|
||||||
}
|
else {
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE(("Skipping '%c%c%c%c' chunk (%lu bytes)",
|
TRACE(("Skipping '%c%c%c%c' chunk (%lu bytes)",
|
||||||
fourcc[0], fourcc[1], fourcc[2], fourcc[3], byteCount))
|
fourcc[0], fourcc[1], fourcc[2], fourcc[3], byteCount))
|
||||||
|
|
||||||
@@ -817,9 +747,9 @@ void BMidiStore::ReadChunk()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ReadTrack()
|
void
|
||||||
|
BMidiStore::ReadTrack()
|
||||||
{
|
{
|
||||||
uint8 status = 0;
|
uint8 status = 0;
|
||||||
uint8 data1;
|
uint8 data1;
|
||||||
@@ -828,18 +758,14 @@ void BMidiStore::ReadTrack()
|
|||||||
|
|
||||||
totalTicks = 0;
|
totalTicks = 0;
|
||||||
|
|
||||||
while (byteCount > 0)
|
while (byteCount > 0) {
|
||||||
{
|
|
||||||
uint32 ticks = ReadVarLength();
|
uint32 ticks = ReadVarLength();
|
||||||
totalTicks += ticks;
|
totalTicks += ticks;
|
||||||
|
|
||||||
if (PeekByte() & 0x80)
|
if (PeekByte() & 0x80)
|
||||||
{
|
|
||||||
status = NextByte();
|
status = NextByte();
|
||||||
}
|
|
||||||
|
|
||||||
switch (status & 0xF0)
|
switch (status & 0xF0) {
|
||||||
{
|
|
||||||
case B_NOTE_OFF:
|
case B_NOTE_OFF:
|
||||||
case B_NOTE_ON:
|
case B_NOTE_ON:
|
||||||
case B_KEY_PRESSURE:
|
case B_KEY_PRESSURE:
|
||||||
@@ -867,14 +793,11 @@ void BMidiStore::ReadTrack()
|
|||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
|
|
||||||
if ((status & 0xF0) == B_PROGRAM_CHANGE)
|
if ((status & 0xF0) == B_PROGRAM_CHANGE)
|
||||||
{
|
|
||||||
instruments[data1] = true;
|
instruments[data1] = true;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xF0:
|
case 0xF0:
|
||||||
switch (status)
|
switch (status) {
|
||||||
{
|
|
||||||
case B_SYS_EX_START:
|
case B_SYS_EX_START:
|
||||||
ReadSystemExclusive();
|
ReadSystemExclusive();
|
||||||
break;
|
break;
|
||||||
@@ -930,26 +853,25 @@ void BMidiStore::ReadTrack()
|
|||||||
++currTrack;
|
++currTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ReadSystemExclusive()
|
void
|
||||||
|
BMidiStore::ReadSystemExclusive()
|
||||||
{
|
{
|
||||||
// We do not import sysex's from MIDI files.
|
// We do not import sysex's from MIDI files.
|
||||||
|
|
||||||
SkipBytes(ReadVarLength());
|
SkipBytes(ReadVarLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::ReadMetaEvent()
|
void
|
||||||
|
BMidiStore::ReadMetaEvent()
|
||||||
{
|
{
|
||||||
// We only import the Tempo Change meta event.
|
// We only import the Tempo Change meta event.
|
||||||
|
|
||||||
uint8 type = NextByte();
|
uint8 type = NextByte();
|
||||||
uint32 length = ReadVarLength();
|
uint32 length = ReadVarLength();
|
||||||
|
|
||||||
if ((type == 0x51) && (length == 3))
|
if (type == 0x51 && length == 3) {
|
||||||
{
|
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
data[0] = NextByte();
|
data[0] = NextByte();
|
||||||
data[1] = NextByte();
|
data[1] = NextByte();
|
||||||
@@ -964,51 +886,38 @@ void BMidiStore::ReadMetaEvent()
|
|||||||
event->byte3 = 0x03;
|
event->byte3 = 0x03;
|
||||||
event->tempo = 60000000 / val;
|
event->tempo = 60000000 / val;
|
||||||
AddEvent(event);
|
AddEvent(event);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
|
||||||
SkipBytes(length);
|
SkipBytes(length);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::WriteTrack()
|
void
|
||||||
|
BMidiStore::WriteTrack()
|
||||||
{
|
{
|
||||||
WriteFourCC('M', 'T', 'r', 'k');
|
WriteFourCC('M', 'T', 'r', 'k');
|
||||||
off_t lengthPos = file->Position();
|
off_t lengthPos = file->Position();
|
||||||
Write32Bit(0);
|
Write32Bit(0);
|
||||||
|
|
||||||
byteCount = 0;
|
byteCount = 0;
|
||||||
uint32 oldTime;
|
uint32 oldTime = 0;
|
||||||
uint32 newTime;
|
uint32 newTime;
|
||||||
|
|
||||||
for (uint32 t = 0; t < CountEvents(); ++t)
|
for (uint32 t = 0; t < CountEvents(); ++t) {
|
||||||
{
|
|
||||||
BMidiEvent* event = EventAt(t);
|
BMidiEvent* event = EventAt(t);
|
||||||
|
|
||||||
if (event->ticks)
|
if (event->ticks)
|
||||||
{
|
|
||||||
newTime = event->time;
|
newTime = event->time;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
newTime = MillisecondsToTicks(event->time);
|
newTime = MillisecondsToTicks(event->time);
|
||||||
}
|
|
||||||
|
|
||||||
if (t == 0)
|
if (t == 0)
|
||||||
{
|
|
||||||
WriteVarLength(0);
|
WriteVarLength(0);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
WriteVarLength(newTime - oldTime);
|
WriteVarLength(newTime - oldTime);
|
||||||
}
|
|
||||||
|
|
||||||
oldTime = newTime;
|
oldTime = newTime;
|
||||||
|
|
||||||
switch (event->byte1 & 0xF0)
|
switch (event->byte1 & 0xF0) {
|
||||||
{
|
|
||||||
case B_NOTE_OFF:
|
case B_NOTE_OFF:
|
||||||
case B_NOTE_ON:
|
case B_NOTE_ON:
|
||||||
case B_KEY_PRESSURE:
|
case B_KEY_PRESSURE:
|
||||||
@@ -1026,8 +935,7 @@ void BMidiStore::WriteTrack()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xF0:
|
case 0xF0:
|
||||||
switch (event->byte1)
|
switch (event->byte1) {
|
||||||
{
|
|
||||||
case B_SYS_EX_START:
|
case B_SYS_EX_START:
|
||||||
// We do not export sysex's.
|
// We do not export sysex's.
|
||||||
break;
|
break;
|
||||||
@@ -1060,7 +968,6 @@ void BMidiStore::WriteTrack()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,14 +981,13 @@ void BMidiStore::WriteTrack()
|
|||||||
file->Seek(0, SEEK_END);
|
file->Seek(0, SEEK_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiStore::WriteMetaEvent(BMidiEvent* event)
|
void
|
||||||
|
BMidiStore::WriteMetaEvent(BMidiEvent* event)
|
||||||
{
|
{
|
||||||
// We only export the Tempo Change meta event.
|
// We only export the Tempo Change meta event.
|
||||||
|
|
||||||
if ((event->byte2 == 0x51) && (event->byte3 == 0x03))
|
if (event->byte2 == 0x51 && event->byte3 == 0x03) {
|
||||||
{
|
|
||||||
uint32 val = 60000000 / event->tempo;
|
uint32 val = 60000000 / event->tempo;
|
||||||
|
|
||||||
WriteByte(0xFF);
|
WriteByte(0xFF);
|
||||||
@@ -1093,5 +999,3 @@ void BMidiStore::WriteMetaEvent(BMidiEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|||||||
+84
-127
@@ -26,9 +26,9 @@
|
|||||||
#include "MidiRosterLooper.h"
|
#include "MidiRosterLooper.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const char* BMidiEndpoint::Name() const
|
const char*
|
||||||
|
BMidiEndpoint::Name() const
|
||||||
{
|
{
|
||||||
const char* str = NULL;
|
const char* str = NULL;
|
||||||
|
|
||||||
@@ -36,8 +36,7 @@ const char* BMidiEndpoint::Name() const
|
|||||||
// BString::String() can change when the string is modified,
|
// BString::String() can change when the string is modified,
|
||||||
// e.g. to allocate more space. That's why we lock here too.
|
// e.g. to allocate more space. That's why we lock here too.
|
||||||
|
|
||||||
if (LockLooper())
|
if (LockLooper()) {
|
||||||
{
|
|
||||||
str = name.String();
|
str = name.String();
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
@@ -45,106 +44,96 @@ const char* BMidiEndpoint::Name() const
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiEndpoint::SetName(const char* name_)
|
void
|
||||||
|
BMidiEndpoint::SetName(const char* newName)
|
||||||
{
|
{
|
||||||
if (name_ == NULL)
|
if (newName == NULL) {
|
||||||
{
|
|
||||||
WARN("SetName() does not accept a NULL name");
|
WARN("SetName() does not accept a NULL name");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (IsRemote())
|
if (IsRemote()) {
|
||||||
{
|
|
||||||
WARN("SetName() is not allowed on remote endpoints");
|
WARN("SetName() is not allowed on remote endpoints");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!IsValid())
|
if (!IsValid())
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
else if (name != name_)
|
|
||||||
{
|
|
||||||
BMessage msg;
|
|
||||||
msg.AddString("midi:name", name_);
|
|
||||||
|
|
||||||
if (SendChangeRequest(&msg) == B_OK)
|
if (name != newName) {
|
||||||
{
|
BMessage msg;
|
||||||
if (LockLooper())
|
msg.AddString("midi:name", newName);
|
||||||
{
|
|
||||||
name.SetTo(name_);
|
if (SendChangeRequest(&msg) == B_OK) {
|
||||||
|
if (LockLooper()) {
|
||||||
|
name.SetTo(newName);
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int32 BMidiEndpoint::ID() const
|
int32
|
||||||
|
BMidiEndpoint::ID() const
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsProducer() const
|
bool
|
||||||
|
BMidiEndpoint::IsProducer() const
|
||||||
{
|
{
|
||||||
return !isConsumer;
|
return !isConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsConsumer() const
|
bool
|
||||||
|
BMidiEndpoint::IsConsumer() const
|
||||||
{
|
{
|
||||||
return isConsumer;
|
return isConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsRemote() const
|
bool
|
||||||
|
BMidiEndpoint::IsRemote() const
|
||||||
{
|
{
|
||||||
return !isLocal;
|
return !isLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsLocal() const
|
bool
|
||||||
|
BMidiEndpoint::IsLocal() const
|
||||||
{
|
{
|
||||||
return isLocal;
|
return isLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsPersistent() const
|
bool
|
||||||
|
BMidiEndpoint::IsPersistent() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsValid() const
|
bool
|
||||||
|
BMidiEndpoint::IsValid() const
|
||||||
{
|
{
|
||||||
if (IsLocal())
|
if (IsLocal())
|
||||||
{
|
|
||||||
return (ID() > 0);
|
return (ID() > 0);
|
||||||
}
|
|
||||||
else // remote endpoint
|
// remote endpoint
|
||||||
{
|
return IsRegistered();
|
||||||
return IsRegistered();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::Release()
|
status_t
|
||||||
|
BMidiEndpoint::Release()
|
||||||
{
|
{
|
||||||
int32 old = atomic_add(&refCount, -1);
|
int32 old = atomic_add(&refCount, -1);
|
||||||
|
|
||||||
TRACE(("BMidiEndpoint::Release refCount is now %ld", old - 1))
|
TRACE(("BMidiEndpoint::Release refCount is now %ld", old - 1))
|
||||||
|
|
||||||
if (old == 1)
|
if (old == 1) {
|
||||||
{
|
|
||||||
// If the reference count of a local endpoint drops to zero,
|
// If the reference count of a local endpoint drops to zero,
|
||||||
// we must delete it. The destructor of BMidiLocalXXX calls
|
// we must delete it. The destructor of BMidiLocalXXX calls
|
||||||
// BMidiRoster::DeleteLocal(), which does all the hard work.
|
// BMidiRoster::DeleteLocal(), which does all the hard work.
|
||||||
@@ -152,57 +141,47 @@ status_t BMidiEndpoint::Release()
|
|||||||
// deleted if that remote endpoint no longer exists.
|
// deleted if that remote endpoint no longer exists.
|
||||||
|
|
||||||
if (IsLocal() || !isAlive)
|
if (IsLocal() || !isAlive)
|
||||||
{
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
} else if (old <= 0) {
|
||||||
}
|
|
||||||
else if (old <= 0)
|
|
||||||
{
|
|
||||||
debugger("too many calls to Release()");
|
debugger("too many calls to Release()");
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::Acquire()
|
status_t
|
||||||
|
BMidiEndpoint::Acquire()
|
||||||
{
|
{
|
||||||
int32 old = atomic_add(&refCount, 1);
|
#ifdef DEBUG
|
||||||
|
int32 old =
|
||||||
|
#endif
|
||||||
|
atomic_add(&refCount, 1);
|
||||||
|
|
||||||
TRACE(("BMidiEndpoint::Acquire refCount is now %ld", old + 1))
|
TRACE(("BMidiEndpoint::Acquire refCount is now %ld", old + 1))
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::SetProperties(const BMessage* properties_)
|
status_t
|
||||||
|
BMidiEndpoint::SetProperties(const BMessage* properties_)
|
||||||
{
|
{
|
||||||
if (properties_ == NULL)
|
if (properties_ == NULL) {
|
||||||
{
|
|
||||||
WARN("SetProperties() does not accept a NULL message")
|
WARN("SetProperties() does not accept a NULL message")
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
} else if (IsRemote()) {
|
||||||
else if (IsRemote())
|
|
||||||
{
|
|
||||||
WARN("SetProperties() is not allowed on remote endpoints");
|
WARN("SetProperties() is not allowed on remote endpoints");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
} else if (!IsValid()) {
|
||||||
else if (!IsValid())
|
|
||||||
{
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
BMessage msg;
|
BMessage msg;
|
||||||
msg.AddMessage("midi:properties", properties_);
|
msg.AddMessage("midi:properties", properties_);
|
||||||
|
|
||||||
status_t err = SendChangeRequest(&msg);
|
status_t err = SendChangeRequest(&msg);
|
||||||
if (err == B_OK)
|
if (err == B_OK) {
|
||||||
{
|
if (LockLooper()) {
|
||||||
if (LockLooper())
|
|
||||||
{
|
|
||||||
*properties = *properties_;
|
*properties = *properties_;
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
@@ -212,83 +191,66 @@ status_t BMidiEndpoint::SetProperties(const BMessage* properties_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::GetProperties(BMessage* properties_) const
|
status_t
|
||||||
|
BMidiEndpoint::GetProperties(BMessage* _properties) const
|
||||||
{
|
{
|
||||||
if (properties_ == NULL)
|
if (_properties == NULL) {
|
||||||
{
|
|
||||||
WARN("GetProperties() does not accept NULL properties")
|
WARN("GetProperties() does not accept NULL properties")
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LockLooper())
|
if (LockLooper()) {
|
||||||
{
|
*_properties = *properties;
|
||||||
*properties_ = *properties;
|
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::Register(void)
|
status_t
|
||||||
|
BMidiEndpoint::Register(void)
|
||||||
{
|
{
|
||||||
if (IsRemote())
|
if (IsRemote()) {
|
||||||
{
|
|
||||||
WARN("You cannot Register() remote endpoints");
|
WARN("You cannot Register() remote endpoints");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
else if (IsRegistered())
|
if (IsRegistered()) {
|
||||||
{
|
|
||||||
WARN("This endpoint is already registered");
|
WARN("This endpoint is already registered");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
else if (!IsValid())
|
if (!IsValid())
|
||||||
{
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
|
||||||
else
|
return SendRegisterRequest(true);
|
||||||
{
|
|
||||||
return SendRegisterRequest(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::Unregister(void)
|
status_t
|
||||||
|
BMidiEndpoint::Unregister(void)
|
||||||
{
|
{
|
||||||
if (IsRemote())
|
if (IsRemote()) {
|
||||||
{
|
|
||||||
WARN("You cannot Unregister() remote endpoints");
|
WARN("You cannot Unregister() remote endpoints");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
else if (!IsRegistered())
|
if (!IsRegistered()) {
|
||||||
{
|
|
||||||
WARN("This endpoint is already unregistered");
|
WARN("This endpoint is already unregistered");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
else if (!IsValid())
|
if (!IsValid())
|
||||||
{
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
|
||||||
else
|
return SendRegisterRequest(false);
|
||||||
{
|
|
||||||
return SendRegisterRequest(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BMidiEndpoint::BMidiEndpoint(const char* name_)
|
BMidiEndpoint::BMidiEndpoint(const char* name_)
|
||||||
{
|
{
|
||||||
TRACE(("BMidiEndpoint::BMidiEndpoint"))
|
TRACE(("BMidiEndpoint::BMidiEndpoint"))
|
||||||
|
|
||||||
if (name_ != NULL)
|
if (name_ != NULL)
|
||||||
{
|
|
||||||
name.SetTo(name_);
|
name.SetTo(name_);
|
||||||
}
|
|
||||||
|
|
||||||
id = 0;
|
id = 0;
|
||||||
refCount = 0;
|
refCount = 0;
|
||||||
@@ -299,14 +261,12 @@ BMidiEndpoint::BMidiEndpoint(const char* name_)
|
|||||||
properties = new BMessage;
|
properties = new BMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BMidiEndpoint::~BMidiEndpoint()
|
BMidiEndpoint::~BMidiEndpoint()
|
||||||
{
|
{
|
||||||
TRACE(("BMidiEndpoint::~BMidiEndpoint (%p)", this))
|
TRACE(("BMidiEndpoint::~BMidiEndpoint (%p)", this))
|
||||||
|
|
||||||
if (refCount > 0)
|
if (refCount > 0) {
|
||||||
{
|
|
||||||
debugger(
|
debugger(
|
||||||
"you should use Release() to dispose of endpoints; "
|
"you should use Release() to dispose of endpoints; "
|
||||||
"do not \"delete\" them or allocate them on the stack!");
|
"do not \"delete\" them or allocate them on the stack!");
|
||||||
@@ -328,16 +288,15 @@ void BMidiEndpoint::_Reserved8() { }
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
status_t BMidiEndpoint::SendRegisterRequest(bool registered)
|
status_t
|
||||||
|
BMidiEndpoint::SendRegisterRequest(bool registered)
|
||||||
{
|
{
|
||||||
BMessage msg;
|
BMessage msg;
|
||||||
msg.AddBool("midi:registered", registered);
|
msg.AddBool("midi:registered", registered);
|
||||||
|
|
||||||
status_t err = SendChangeRequest(&msg);
|
status_t err = SendChangeRequest(&msg);
|
||||||
if (err == B_OK)
|
if (err == B_OK) {
|
||||||
{
|
if (LockLooper()) {
|
||||||
if (LockLooper())
|
|
||||||
{
|
|
||||||
isRegistered = registered;
|
isRegistered = registered;
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
@@ -346,9 +305,9 @@ status_t BMidiEndpoint::SendRegisterRequest(bool registered)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
status_t BMidiEndpoint::SendChangeRequest(BMessage* msg)
|
status_t
|
||||||
|
BMidiEndpoint::SendChangeRequest(BMessage* msg)
|
||||||
{
|
{
|
||||||
ASSERT(msg != NULL)
|
ASSERT(msg != NULL)
|
||||||
|
|
||||||
@@ -357,20 +316,19 @@ status_t BMidiEndpoint::SendChangeRequest(BMessage* msg)
|
|||||||
|
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
status_t err = BMidiRoster::MidiRoster()->SendRequest(msg, &reply);
|
status_t err = BMidiRoster::MidiRoster()->SendRequest(msg, &reply);
|
||||||
if (err != B_OK) { return err; }
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
status_t res;
|
status_t res;
|
||||||
if (reply.FindInt32("midi:result", &res) == B_OK)
|
if (reply.FindInt32("midi:result", &res) == B_OK)
|
||||||
{
|
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::IsRegistered() const
|
bool
|
||||||
|
BMidiEndpoint::IsRegistered() const
|
||||||
{
|
{
|
||||||
// No need to protect this with a lock, because reading
|
// No need to protect this with a lock, because reading
|
||||||
// and writing a bool is always an atomic operation.
|
// and writing a bool is always an atomic operation.
|
||||||
@@ -378,18 +336,17 @@ bool BMidiEndpoint::IsRegistered() const
|
|||||||
return isRegistered;
|
return isRegistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool BMidiEndpoint::LockLooper() const
|
bool
|
||||||
|
BMidiEndpoint::LockLooper() const
|
||||||
{
|
{
|
||||||
return BMidiRoster::MidiRoster()->looper->Lock();
|
return BMidiRoster::MidiRoster()->looper->Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiEndpoint::UnlockLooper() const
|
void
|
||||||
|
BMidiEndpoint::UnlockLooper() const
|
||||||
{
|
{
|
||||||
BMidiRoster::MidiRoster()->looper->Unlock();
|
BMidiRoster::MidiRoster()->looper->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include "MidiRoster.h"
|
#include "MidiRoster.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BMidiLocalProducer::BMidiLocalProducer(const char* name)
|
BMidiLocalProducer::BMidiLocalProducer(const char* name)
|
||||||
: BMidiProducer(name)
|
: BMidiProducer(name)
|
||||||
@@ -41,7 +40,6 @@ BMidiLocalProducer::BMidiLocalProducer(const char* name)
|
|||||||
BMidiRoster::MidiRoster()->CreateLocal(this);
|
BMidiRoster::MidiRoster()->CreateLocal(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
BMidiLocalProducer::~BMidiLocalProducer()
|
BMidiLocalProducer::~BMidiLocalProducer()
|
||||||
{
|
{
|
||||||
@@ -50,9 +48,9 @@ BMidiLocalProducer::~BMidiLocalProducer()
|
|||||||
BMidiRoster::MidiRoster()->DeleteLocal(this);
|
BMidiRoster::MidiRoster()->DeleteLocal(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::Connected(BMidiConsumer* cons)
|
void
|
||||||
|
BMidiLocalProducer::Connected(BMidiConsumer* cons)
|
||||||
{
|
{
|
||||||
ASSERT(cons != NULL)
|
ASSERT(cons != NULL)
|
||||||
TRACE(("Connected() %ld to %ld", ID(), cons->ID()))
|
TRACE(("Connected() %ld to %ld", ID(), cons->ID()))
|
||||||
@@ -60,9 +58,9 @@ void BMidiLocalProducer::Connected(BMidiConsumer* cons)
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::Disconnected(BMidiConsumer* cons)
|
void
|
||||||
|
BMidiLocalProducer::Disconnected(BMidiConsumer* cons)
|
||||||
{
|
{
|
||||||
ASSERT(cons != NULL)
|
ASSERT(cons != NULL)
|
||||||
TRACE(("Disconnected() %ld from %ld", ID(), cons->ID()))
|
TRACE(("Disconnected() %ld from %ld", ID(), cons->ID()))
|
||||||
@@ -70,165 +68,143 @@ void BMidiLocalProducer::Disconnected(BMidiConsumer* cons)
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayData(
|
void
|
||||||
void* data, size_t length, bool atomic, bigtime_t time) const
|
BMidiLocalProducer::SprayData(void* data, size_t length,
|
||||||
|
bool atomic, bigtime_t time) const
|
||||||
{
|
{
|
||||||
SprayEvent(data, length, atomic, time);
|
SprayEvent(data, length, atomic, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayNoteOff(
|
void
|
||||||
uchar channel, uchar note, uchar velocity, bigtime_t time) const
|
BMidiLocalProducer::SprayNoteOff(uchar channel, uchar note,
|
||||||
|
uchar velocity, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
data[0] = B_NOTE_OFF + channel;
|
data[0] = B_NOTE_OFF + channel;
|
||||||
data[1] = note;
|
data[1] = note;
|
||||||
data[2] = velocity;
|
data[2] = velocity;
|
||||||
|
|
||||||
SprayEvent(&data, 3, true, time);
|
SprayEvent(&data, 3, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayNoteOn(
|
void
|
||||||
uchar channel, uchar note, uchar velocity, bigtime_t time) const
|
BMidiLocalProducer::SprayNoteOn(uchar channel, uchar note,
|
||||||
|
uchar velocity, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
data[0] = B_NOTE_ON + channel;
|
data[0] = B_NOTE_ON + channel;
|
||||||
data[1] = note;
|
data[1] = note;
|
||||||
data[2] = velocity;
|
data[2] = velocity;
|
||||||
|
|
||||||
SprayEvent(&data, 3, true, time);
|
SprayEvent(&data, 3, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayKeyPressure(
|
void
|
||||||
uchar channel, uchar note, uchar pressure, bigtime_t time) const
|
BMidiLocalProducer::SprayKeyPressure(uchar channel, uchar note,
|
||||||
|
uchar pressure, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
data[0] = B_KEY_PRESSURE + channel;
|
data[0] = B_KEY_PRESSURE + channel;
|
||||||
data[1] = note;
|
data[1] = note;
|
||||||
data[2] = pressure;
|
data[2] = pressure;
|
||||||
|
|
||||||
SprayEvent(&data, 3, true, time);
|
SprayEvent(&data, 3, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayControlChange(
|
void
|
||||||
uchar channel, uchar controlNumber, uchar controlValue,
|
BMidiLocalProducer::SprayControlChange(uchar channel,
|
||||||
bigtime_t time) const
|
uchar controlNumber, uchar controlValue, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
data[0] = B_CONTROL_CHANGE + channel;
|
data[0] = B_CONTROL_CHANGE + channel;
|
||||||
data[1] = controlNumber;
|
data[1] = controlNumber;
|
||||||
data[2] = controlValue;
|
data[2] = controlValue;
|
||||||
|
|
||||||
SprayEvent(&data, 3, true, time);
|
SprayEvent(&data, 3, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayProgramChange(
|
void
|
||||||
uchar channel, uchar programNumber, bigtime_t time) const
|
BMidiLocalProducer::SprayProgramChange(uchar channel,
|
||||||
|
uchar programNumber, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[2];
|
uchar data[2];
|
||||||
data[0] = B_PROGRAM_CHANGE + channel;
|
data[0] = B_PROGRAM_CHANGE + channel;
|
||||||
data[1] = programNumber;
|
data[1] = programNumber;
|
||||||
|
|
||||||
SprayEvent(&data, 2, true, time);
|
SprayEvent(&data, 2, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayChannelPressure(
|
void
|
||||||
uchar channel, uchar pressure, bigtime_t time) const
|
BMidiLocalProducer::SprayChannelPressure(uchar channel,
|
||||||
|
uchar pressure, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[2];
|
uchar data[2];
|
||||||
data[0] = B_CHANNEL_PRESSURE + channel;
|
data[0] = B_CHANNEL_PRESSURE + channel;
|
||||||
data[1] = pressure;
|
data[1] = pressure;
|
||||||
|
|
||||||
SprayEvent(&data, 2, true, time);
|
SprayEvent(&data, 2, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayPitchBend(
|
void
|
||||||
uchar channel, uchar lsb, uchar msb, bigtime_t time) const
|
BMidiLocalProducer::SprayPitchBend(uchar channel,
|
||||||
|
uchar lsb, uchar msb, bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (channel < 16)
|
if (channel < 16) {
|
||||||
{
|
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
data[0] = B_PITCH_BEND + channel;
|
data[0] = B_PITCH_BEND + channel;
|
||||||
data[1] = lsb;
|
data[1] = lsb;
|
||||||
data[2] = msb;
|
data[2] = msb;
|
||||||
|
|
||||||
SprayEvent(&data, 3, true, time);
|
SprayEvent(&data, 3, true, time);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
debugger("invalid MIDI channel");
|
debugger("invalid MIDI channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SpraySystemExclusive(
|
void
|
||||||
void* data, size_t length, bigtime_t time) const
|
BMidiLocalProducer::SpraySystemExclusive(void* data,
|
||||||
|
size_t length, bigtime_t time) const
|
||||||
{
|
{
|
||||||
SprayEvent(data, length, true, time, true);
|
SprayEvent(data, length, true, time, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SpraySystemCommon(
|
void
|
||||||
uchar status, uchar data1, uchar data2, bigtime_t time) const
|
BMidiLocalProducer::SpraySystemCommon(uchar status, uchar data1,
|
||||||
|
uchar data2, bigtime_t time) const
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
uchar data[3];
|
uchar data[3];
|
||||||
@@ -236,46 +212,45 @@ void BMidiLocalProducer::SpraySystemCommon(
|
|||||||
data[1] = data1;
|
data[1] = data1;
|
||||||
data[2] = data2;
|
data[2] = data2;
|
||||||
|
|
||||||
switch (status)
|
switch (status) {
|
||||||
{
|
|
||||||
case B_TUNE_REQUEST:
|
case B_TUNE_REQUEST:
|
||||||
case B_SYS_EX_END:
|
case B_SYS_EX_END:
|
||||||
len = 1; break;
|
len = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case B_CABLE_MESSAGE:
|
case B_CABLE_MESSAGE:
|
||||||
case B_MIDI_TIME_CODE:
|
case B_MIDI_TIME_CODE:
|
||||||
case B_SONG_SELECT:
|
case B_SONG_SELECT:
|
||||||
len = 2; break;
|
len = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
case B_SONG_POSITION:
|
case B_SONG_POSITION:
|
||||||
len = 3; break;
|
len = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
debugger("invalid system common status");
|
debugger("invalid system common status");
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SprayEvent(&data, len, true, time);
|
SprayEvent(&data, len, true, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SpraySystemRealTime(
|
void
|
||||||
uchar status, bigtime_t time) const
|
BMidiLocalProducer::SpraySystemRealTime(uchar status,
|
||||||
|
bigtime_t time) const
|
||||||
{
|
{
|
||||||
if (status >= B_TIMING_CLOCK)
|
if (status >= B_TIMING_CLOCK)
|
||||||
{
|
|
||||||
SprayEvent(&status, 1, true, time);
|
SprayEvent(&status, 1, true, time);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
debugger("invalid real time status");
|
debugger("invalid real time status");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayTempoChange(
|
void
|
||||||
int32 beatsPerMinute, bigtime_t time) const
|
BMidiLocalProducer::SprayTempoChange(int32 beatsPerMinute,
|
||||||
|
bigtime_t time) const
|
||||||
{
|
{
|
||||||
int32 tempo = 60000000 / beatsPerMinute;
|
int32 tempo = 60000000 / beatsPerMinute;
|
||||||
|
|
||||||
@@ -303,14 +278,12 @@ void BMidiLocalProducer::_Reserved8() { }
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void BMidiLocalProducer::SprayEvent(
|
void
|
||||||
const void* data, size_t length, bool atomic, bigtime_t time,
|
BMidiLocalProducer::SprayEvent(const void* data, size_t length,
|
||||||
bool sysex) const
|
bool atomic, bigtime_t time, bool sysex) const
|
||||||
{
|
{
|
||||||
if (LockProducer())
|
if (LockProducer()) {
|
||||||
{
|
if (CountConsumers() > 0) {
|
||||||
if (CountConsumers() > 0)
|
|
||||||
{
|
|
||||||
// We don't just send the MIDI event data to all connected
|
// We don't just send the MIDI event data to all connected
|
||||||
// consumers, we also send a header. The header contains our
|
// consumers, we also send a header. The header contains our
|
||||||
// ID (4 bytes), the consumer's ID (4 bytes), the performance
|
// ID (4 bytes), the consumer's ID (4 bytes), the performance
|
||||||
@@ -318,32 +291,29 @@ void BMidiLocalProducer::SprayEvent(
|
|||||||
// padding (3 bytes). The MIDI event data follows the header.
|
// padding (3 bytes). The MIDI event data follows the header.
|
||||||
|
|
||||||
size_t buf_size = 20 + length;
|
size_t buf_size = 20 + length;
|
||||||
if (sysex) { buf_size += 2; } // add 0xF0 and 0xF7 markers
|
if (sysex) {
|
||||||
|
// add 0xF0 and 0xF7 markers
|
||||||
|
buf_size += 2;
|
||||||
|
}
|
||||||
|
|
||||||
uint8* buffer = (uint8*) malloc(buf_size);
|
uint8* buffer = (uint8*)malloc(buf_size);
|
||||||
if (buffer != NULL)
|
if (buffer != NULL) {
|
||||||
{
|
|
||||||
*((uint32*) (buffer + 0)) = id;
|
*((uint32*) (buffer + 0)) = id;
|
||||||
*((bigtime_t*) (buffer + 8)) = time;
|
*((bigtime_t*) (buffer + 8)) = time;
|
||||||
*((uint32*) (buffer + 16)) = 0;
|
*((uint32*) (buffer + 16)) = 0;
|
||||||
*((bool*) (buffer + 16)) = atomic;
|
*((bool*) (buffer + 16)) = atomic;
|
||||||
|
|
||||||
if (sysex)
|
if (sysex) {
|
||||||
{
|
|
||||||
*((uint8*) (buffer + 20)) = B_SYS_EX_START;
|
*((uint8*) (buffer + 20)) = B_SYS_EX_START;
|
||||||
if (data != NULL)
|
if (data != NULL)
|
||||||
{
|
|
||||||
memcpy(buffer + 21, data, length);
|
memcpy(buffer + 21, data, length);
|
||||||
}
|
|
||||||
*((uint8*) (buffer + buf_size - 1)) = B_SYS_EX_END;
|
*((uint8*) (buffer + buf_size - 1)) = B_SYS_EX_END;
|
||||||
}
|
} else if (data != NULL) {
|
||||||
else if (data != NULL)
|
|
||||||
{
|
|
||||||
memcpy(buffer + 20, data, length);
|
memcpy(buffer + 20, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 t = 0; t < CountConsumers(); ++t)
|
for (int32 t = 0; t < CountConsumers(); ++t) {
|
||||||
{
|
|
||||||
BMidiConsumer* cons = ConsumerAt(t);
|
BMidiConsumer* cons = ConsumerAt(t);
|
||||||
*((uint32*) (buffer + 4)) = cons->id;
|
*((uint32*) (buffer + 4)) = cons->id;
|
||||||
|
|
||||||
@@ -367,4 +337,3 @@ void BMidiLocalProducer::SprayEvent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|||||||
Reference in New Issue
Block a user