midi2 kit clean up: license header, code style

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17860 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2006-06-16 15:38:29 +00:00
parent f8253e50bd
commit 60d1530802
13 changed files with 516 additions and 849 deletions

View File

@ -31,8 +31,8 @@ private:
virtual void _Reserved7(); virtual void _Reserved7();
virtual void _Reserved8(); virtual void _Reserved8();
port_id port; port_id fPort;
bigtime_t latency; bigtime_t fLatency;
uint32 _reserved[2]; uint32 _reserved[2];
}; };
@ -106,10 +106,10 @@ private:
int32 EventThread(); int32 EventThread();
bigtime_t timeout; bigtime_t fTimeout;
void* timeoutData; void* fTimeoutData;
int32 currentProducer; int32 fCurrentProducer;
thread_id thread; thread_id fThread;
uint32 _reserved[1]; uint32 _reserved[1];
}; };

View File

@ -66,14 +66,14 @@ private:
bool LockLooper() const; bool LockLooper() const;
void UnlockLooper() const; void UnlockLooper() const;
int32 id; int32 fId;
BString name; BString fName;
int32 refCount; int32 fRefCount;
BMessage* properties; BMessage* fProperties;
bool isLocal; bool fIsLocal;
bool isConsumer; bool fIsConsumer;
bool isRegistered; bool fIsRegistered;
bool isAlive; bool fIsAlive;
uint32 _reserved[4]; uint32 _reserved[4];
}; };

View File

@ -2,11 +2,10 @@
#ifndef _MIDI_PRODUCER_H #ifndef _MIDI_PRODUCER_H
#define _MIDI_PRODUCER_H #define _MIDI_PRODUCER_H
#include <List.h>
#include <Locker.h> #include <Locker.h>
#include <MidiEndpoint.h> #include <MidiEndpoint.h>
class BList;
namespace BPrivate { class BMidiRosterLooper; } namespace BPrivate { class BMidiRosterLooper; }
class BMidiProducer : public BMidiEndpoint class BMidiProducer : public BMidiEndpoint
@ -46,8 +45,8 @@ private:
bool LockProducer() const; bool LockProducer() const;
void UnlockProducer() const; void UnlockProducer() const;
BList* connections; mutable BLocker fLocker;
BLocker* locker; BList fConnections;
uint32 _reserved[10]; uint32 _reserved[10];
}; };

View File

@ -75,8 +75,8 @@ private:
status_t SendRequest(BMessage*, BMessage*); status_t SendRequest(BMessage*, BMessage*);
BPrivate::BMidiRosterLooper* looper; BPrivate::BMidiRosterLooper* fLooper;
BMessenger* server; BMessenger fServer;
uint32 _reserved[16]; uint32 _reserved[16];
}; };

View File

@ -4,9 +4,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
if $(TARGET_PLATFORM) != haiku { if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FDirName $(HAIKU_TOP) headers os midi2 ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers os midi2 ] : true ;
# We need Errors.h also when not compiling for Haiku.
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
# We need Errors.h also when not compiling for Haiku.
} }
UsePrivateHeaders midi ; UsePrivateHeaders midi ;
@ -22,3 +20,4 @@ SharedLibrary libmidi2.so :
: :
be be
; ;

View File

@ -1,62 +1,44 @@
/* /*
* Copyright (c) 2002-2003 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include "debug.h" #include "debug.h"
#include "MidiConsumer.h" #include <MidiConsumer.h>
#include "protocol.h" #include "protocol.h"
//------------------------------------------------------------------------------
bigtime_t BMidiConsumer::Latency() const bigtime_t
BMidiConsumer::Latency() const
{ {
bigtime_t res = 0LL; bigtime_t res = 0LL;
if (LockLooper()) if (LockLooper()) {
{ res = fLatency;
res = latency;
UnlockLooper(); UnlockLooper();
} }
return res; return res;
} }
//------------------------------------------------------------------------------
BMidiConsumer::BMidiConsumer(const char* name) BMidiConsumer::BMidiConsumer(const char* name)
: BMidiEndpoint(name) : BMidiEndpoint(name)
{ {
isConsumer = true; fIsConsumer = true;
latency = 0LL; fLatency = 0LL;
port = 0; fPort = 0;
} }
//------------------------------------------------------------------------------
BMidiConsumer::~BMidiConsumer() BMidiConsumer::~BMidiConsumer()
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiConsumer::_Reserved1() { } void BMidiConsumer::_Reserved1() { }
void BMidiConsumer::_Reserved2() { } void BMidiConsumer::_Reserved2() { }
@ -67,4 +49,3 @@ void BMidiConsumer::_Reserved6() { }
void BMidiConsumer::_Reserved7() { } void BMidiConsumer::_Reserved7() { }
void BMidiConsumer::_Reserved8() { } void BMidiConsumer::_Reserved8() { }
//------------------------------------------------------------------------------

View File

@ -1,28 +1,14 @@
/* /*
* Copyright (c) 2002-2003 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include "debug.h" #include "debug.h"
#include "MidiEndpoint.h" #include <MidiEndpoint.h>
#include "MidiRoster.h" #include <MidiRoster.h>
#include "MidiRosterLooper.h" #include "MidiRosterLooper.h"
#include "protocol.h" #include "protocol.h"
@ -37,7 +23,7 @@ BMidiEndpoint::Name() const
// 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 = fName.String();
UnlockLooper(); UnlockLooper();
} }
@ -59,13 +45,13 @@ BMidiEndpoint::SetName(const char* newName)
if (!IsValid()) if (!IsValid())
return; return;
if (name != newName) { if (fName != newName) {
BMessage msg; BMessage msg;
msg.AddString("midi:name", newName); msg.AddString("midi:name", newName);
if (SendChangeRequest(&msg) == B_OK) { if (SendChangeRequest(&msg) == B_OK) {
if (LockLooper()) { if (LockLooper()) {
name.SetTo(newName); fName.SetTo(newName);
UnlockLooper(); UnlockLooper();
} }
} }
@ -76,35 +62,35 @@ BMidiEndpoint::SetName(const char* newName)
int32 int32
BMidiEndpoint::ID() const BMidiEndpoint::ID() const
{ {
return id; return fId;
} }
bool bool
BMidiEndpoint::IsProducer() const BMidiEndpoint::IsProducer() const
{ {
return !isConsumer; return !fIsConsumer;
} }
bool bool
BMidiEndpoint::IsConsumer() const BMidiEndpoint::IsConsumer() const
{ {
return isConsumer; return fIsConsumer;
} }
bool bool
BMidiEndpoint::IsRemote() const BMidiEndpoint::IsRemote() const
{ {
return !isLocal; return !fIsLocal;
} }
bool bool
BMidiEndpoint::IsLocal() const BMidiEndpoint::IsLocal() const
{ {
return isLocal; return fIsLocal;
} }
@ -129,7 +115,7 @@ BMidiEndpoint::IsValid() const
status_t status_t
BMidiEndpoint::Release() BMidiEndpoint::Release()
{ {
int32 old = atomic_add(&refCount, -1); int32 old = atomic_add(&fRefCount, -1);
TRACE(("BMidiEndpoint::Release refCount is now %ld", old - 1)) TRACE(("BMidiEndpoint::Release refCount is now %ld", old - 1))
@ -140,7 +126,7 @@ BMidiEndpoint::Release()
// If we are a proxy for a remote endpoint, we must only be // If we are a proxy for a remote endpoint, we must only be
// deleted if that remote endpoint no longer exists. // deleted if that remote endpoint no longer exists.
if (IsLocal() || !isAlive) if (IsLocal() || !fIsAlive)
delete this; delete this;
} else if (old <= 0) { } else if (old <= 0) {
debugger("too many calls to Release()"); debugger("too many calls to Release()");
@ -156,7 +142,7 @@ BMidiEndpoint::Acquire()
#ifdef DEBUG #ifdef DEBUG
int32 old = int32 old =
#endif #endif
atomic_add(&refCount, 1); atomic_add(&fRefCount, 1);
TRACE(("BMidiEndpoint::Acquire refCount is now %ld", old + 1)) TRACE(("BMidiEndpoint::Acquire refCount is now %ld", old + 1))
@ -182,7 +168,7 @@ BMidiEndpoint::SetProperties(const BMessage* 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_; *fProperties = *properties_;
UnlockLooper(); UnlockLooper();
} }
} }
@ -201,7 +187,7 @@ BMidiEndpoint::GetProperties(BMessage* _properties) const
} }
if (LockLooper()) { if (LockLooper()) {
*_properties = *properties; *_properties = *fProperties;
UnlockLooper(); UnlockLooper();
} }
@ -250,15 +236,15 @@ BMidiEndpoint::BMidiEndpoint(const char* name_)
TRACE(("BMidiEndpoint::BMidiEndpoint")) TRACE(("BMidiEndpoint::BMidiEndpoint"))
if (name_ != NULL) if (name_ != NULL)
name.SetTo(name_); fName.SetTo(name_);
id = 0; fId = 0;
refCount = 0; fRefCount = 0;
isLocal = false; fIsLocal = false;
isRegistered = false; fIsRegistered = false;
isAlive = true; fIsAlive = true;
properties = new BMessage; fProperties = new BMessage;
} }
@ -266,13 +252,13 @@ BMidiEndpoint::~BMidiEndpoint()
{ {
TRACE(("BMidiEndpoint::~BMidiEndpoint (%p)", this)) TRACE(("BMidiEndpoint::~BMidiEndpoint (%p)", this))
if (refCount > 0) { if (fRefCount > 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!");
} }
delete properties; delete fProperties;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -297,7 +283,7 @@ BMidiEndpoint::SendRegisterRequest(bool 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; fIsRegistered = registered;
UnlockLooper(); UnlockLooper();
} }
} }
@ -333,20 +319,20 @@ 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.
return isRegistered; return fIsRegistered;
} }
bool bool
BMidiEndpoint::LockLooper() const BMidiEndpoint::LockLooper() const
{ {
return BMidiRoster::MidiRoster()->looper->Lock(); return BMidiRoster::MidiRoster()->fLooper->Lock();
} }
void void
BMidiEndpoint::UnlockLooper() const BMidiEndpoint::UnlockLooper() const
{ {
BMidiRoster::MidiRoster()->looper->Unlock(); BMidiRoster::MidiRoster()->fLooper->Unlock();
} }

View File

@ -1,60 +1,44 @@
/* /*
* Copyright (c) 2002-2003 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "debug.h" #include "debug.h"
#include "MidiConsumer.h" #include <MidiConsumer.h>
#include "MidiRoster.h" #include <MidiRoster.h>
#include "protocol.h" #include "protocol.h"
//------------------------------------------------------------------------------
int32 _midi_event_thread(void* data) int32
_midi_event_thread(void* data)
{ {
return ((BMidiLocalConsumer*) data)->EventThread(); return ((BMidiLocalConsumer*) data)->EventThread();
} }
//------------------------------------------------------------------------------
BMidiLocalConsumer::BMidiLocalConsumer(const char* name) BMidiLocalConsumer::BMidiLocalConsumer(const char* name)
: BMidiConsumer(name) : BMidiConsumer(name)
{ {
TRACE(("BMidiLocalConsumer::BMidiLocalConsumer")) TRACE(("BMidiLocalConsumer::BMidiLocalConsumer"))
isLocal = true; fIsLocal = true;
refCount = 1; fRefCount = 1;
timeout = (bigtime_t) -1; fTimeout = (bigtime_t) -1;
timeoutData = NULL; fTimeoutData = NULL;
port = create_port(1, "MidiEventPort"); fPort = create_port(1, "MidiEventPort");
thread = spawn_thread( fThread = spawn_thread(
_midi_event_thread, "MidiEventThread", B_REAL_TIME_PRIORITY, this); _midi_event_thread, "MidiEventThread", B_REAL_TIME_PRIORITY, this);
resume_thread(thread); resume_thread(fThread);
BMidiRoster::MidiRoster()->CreateLocal(this); BMidiRoster::MidiRoster()->CreateLocal(this);
} }
//------------------------------------------------------------------------------
BMidiLocalConsumer::~BMidiLocalConsumer() BMidiLocalConsumer::~BMidiLocalConsumer()
{ {
@ -62,147 +46,119 @@ BMidiLocalConsumer::~BMidiLocalConsumer()
BMidiRoster::MidiRoster()->DeleteLocal(this); BMidiRoster::MidiRoster()->DeleteLocal(this);
delete_port(port); delete_port(fPort);
status_t result; status_t result;
wait_for_thread(thread, &result); wait_for_thread(fThread, &result);
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::SetLatency(bigtime_t latency_) void
BMidiLocalConsumer::SetLatency(bigtime_t latency_)
{ {
if (latency_ < 0) if (latency_ < 0) {
{
WARN("SetLatency() does not accept negative values"); WARN("SetLatency() does not accept negative values");
return; return;
} } else if (!IsValid()) {
else if (!IsValid())
{
return; return;
} } else if (fLatency != latency_) {
else if (latency != latency_)
{
BMessage msg; BMessage msg;
msg.AddInt64("midi:latency", latency_); msg.AddInt64("midi:latency", latency_);
if (SendChangeRequest(&msg) == B_OK) if (SendChangeRequest(&msg) == B_OK) {
{ if (LockLooper()) {
if (LockLooper()) fLatency = latency_;
{
latency = latency_;
UnlockLooper(); UnlockLooper();
} }
} }
} }
} }
//------------------------------------------------------------------------------
int32 BMidiLocalConsumer::GetProducerID(void) int32
BMidiLocalConsumer::GetProducerID(void)
{ {
return currentProducer; return fCurrentProducer;
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::SetTimeout(bigtime_t when, void* data) void
BMidiLocalConsumer::SetTimeout(bigtime_t when, void* data)
{ {
timeout = when; fTimeout = when;
timeoutData = data; fTimeoutData = data;
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::Timeout(void* data) void
BMidiLocalConsumer::Timeout(void* data)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::Data( void
uchar* data, size_t length, bool atomic, bigtime_t time) BMidiLocalConsumer::Data(uchar* data, size_t length, bool atomic, bigtime_t time)
{ {
if (atomic) if (atomic) {
{ switch (data[0] & 0xF0) {
switch (data[0] & 0xF0)
{
case B_NOTE_OFF: case B_NOTE_OFF:
{ {
if (length == 3) if (length == 3)
{
NoteOff(data[0] & 0x0F, data[1], data[2], time); NoteOff(data[0] & 0x0F, data[1], data[2], time);
}
break; break;
} }
case B_NOTE_ON: case B_NOTE_ON:
{ {
if (length == 3) if (length == 3)
{
NoteOn(data[0] & 0x0F, data[1], data[2], time); NoteOn(data[0] & 0x0F, data[1], data[2], time);
}
break; break;
} }
case B_KEY_PRESSURE: case B_KEY_PRESSURE:
{ {
if (length == 3) if (length == 3)
{
KeyPressure(data[0] & 0x0F, data[1], data[2], time); KeyPressure(data[0] & 0x0F, data[1], data[2], time);
}
break; break;
} }
case B_CONTROL_CHANGE: case B_CONTROL_CHANGE:
{ {
if (length == 3) if (length == 3)
{
ControlChange(data[0] & 0x0F, data[1], data[2], time); ControlChange(data[0] & 0x0F, data[1], data[2], time);
}
break; break;
} }
case B_PROGRAM_CHANGE: case B_PROGRAM_CHANGE:
{ {
if (length == 2) if (length == 2)
{
ProgramChange(data[0] & 0x0F, data[1], time); ProgramChange(data[0] & 0x0F, data[1], time);
}
break; break;
} }
case B_CHANNEL_PRESSURE: case B_CHANNEL_PRESSURE:
{ {
if (length == 2) if (length == 2)
{
ChannelPressure(data[0] & 0x0F, data[1], time); ChannelPressure(data[0] & 0x0F, data[1], time);
}
break; break;
} }
case B_PITCH_BEND: case B_PITCH_BEND:
{ {
if (length == 3) if (length == 3)
{
PitchBend(data[0] & 0x0F, data[1], data[2], time); PitchBend(data[0] & 0x0F, data[1], data[2], time);
}
break; break;
} }
case 0xF0: case 0xF0:
{ {
switch (data[0]) switch (data[0]) {
{
case B_SYS_EX_START: case B_SYS_EX_START:
{ {
if (data[length - 1] == B_SYS_EX_END) if (data[length - 1] == B_SYS_EX_END) {
{
SystemExclusive(data + 1, length - 2, time); SystemExclusive(data + 1, length - 2, time);
} } else { // sysex-end is not required
else // sysex-end is not required
{
SystemExclusive(data + 1, length - 1, time); SystemExclusive(data + 1, length - 1, time);
} }
break; break;
@ -211,8 +167,7 @@ void BMidiLocalConsumer::Data(
case B_TUNE_REQUEST: case B_TUNE_REQUEST:
case B_SYS_EX_END: case B_SYS_EX_END:
{ {
if (length == 1) if (length == 1) {
{
SystemCommon(data[0], 0, 0, time); SystemCommon(data[0], 0, 0, time);
} }
break; break;
@ -222,8 +177,7 @@ void BMidiLocalConsumer::Data(
case B_MIDI_TIME_CODE: case B_MIDI_TIME_CODE:
case B_SONG_SELECT: case B_SONG_SELECT:
{ {
if (length == 2) if (length == 2) {
{
SystemCommon(data[0], data[1], 0, time); SystemCommon(data[0], data[1], 0, time);
} }
break; break;
@ -231,8 +185,7 @@ void BMidiLocalConsumer::Data(
case B_SONG_POSITION: case B_SONG_POSITION:
{ {
if (length == 3) if (length == 3) {
{
SystemCommon(data[0], data[1], data[2], time); SystemCommon(data[0], data[1], data[2], time);
} }
break; break;
@ -244,8 +197,7 @@ void BMidiLocalConsumer::Data(
case B_STOP: case B_STOP:
case B_ACTIVE_SENSING: case B_ACTIVE_SENSING:
{ {
if (length == 1) if (length == 1) {
{
SystemRealTime(data[0], time); SystemRealTime(data[0], time);
} }
break; break;
@ -253,13 +205,10 @@ void BMidiLocalConsumer::Data(
case B_SYSTEM_RESET: case B_SYSTEM_RESET:
{ {
if (length == 1) if (length == 1) {
{
SystemRealTime(data[0], time); SystemRealTime(data[0], time);
} } else if ((length == 6) && (data[1] == 0x51)
else if ((length == 6) && (data[1] == 0x51) && (data[2] == 0x03)) {
&& (data[2] == 0x03))
{
int32 tempo = int32 tempo =
(data[3] << 16) | (data[4] << 8) | data[5]; (data[3] << 16) | (data[4] << 8) | data[5];
@ -273,100 +222,91 @@ void BMidiLocalConsumer::Data(
} }
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::NoteOff( void
uchar channel, uchar note, uchar velocity, bigtime_t time) BMidiLocalConsumer::NoteOff(uchar channel, uchar note, uchar velocity, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::NoteOn( void
uchar channel, uchar note, uchar velocity, bigtime_t time) BMidiLocalConsumer::NoteOn(uchar channel, uchar note, uchar velocity, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::KeyPressure( void
uchar channel, uchar note, uchar pressure, bigtime_t time) BMidiLocalConsumer::KeyPressure(uchar channel, uchar note, uchar pressure, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::ControlChange( void
uchar channel, uchar controlNumber, uchar controlValue, bigtime_t time) BMidiLocalConsumer::ControlChange(uchar channel, uchar controlNumber, uchar controlValue, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::ProgramChange( void
uchar channel, uchar programNumber, bigtime_t time) BMidiLocalConsumer::ProgramChange(uchar channel, uchar programNumber, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::ChannelPressure( void BMidiLocalConsumer::ChannelPressure(uchar channel, uchar pressure, bigtime_t time)
uchar channel, uchar pressure, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::PitchBend( void
uchar channel, uchar lsb, uchar msb, bigtime_t time) BMidiLocalConsumer::PitchBend(uchar channel, uchar lsb, uchar msb, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::SystemExclusive( void
BMidiLocalConsumer::SystemExclusive(
void* data, size_t length, bigtime_t time) void* data, size_t length, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::SystemCommon( void
BMidiLocalConsumer::SystemCommon(
uchar statusByte, uchar data1, uchar data2, bigtime_t time) uchar statusByte, uchar data1, uchar data2, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::SystemRealTime(uchar statusByte, bigtime_t time) void
BMidiLocalConsumer::SystemRealTime(uchar statusByte, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::TempoChange(int32 beatsPerMinute, bigtime_t time) void
BMidiLocalConsumer::TempoChange(int32 beatsPerMinute, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::AllNotesOff(bool justChannel, bigtime_t time) void
BMidiLocalConsumer::AllNotesOff(bool justChannel, bigtime_t time)
{ {
// Do nothing. // Do nothing.
} }
//------------------------------------------------------------------------------
void BMidiLocalConsumer::_Reserved1() { } void BMidiLocalConsumer::_Reserved1() { }
void BMidiLocalConsumer::_Reserved2() { } void BMidiLocalConsumer::_Reserved2() { }
@ -377,61 +317,53 @@ void BMidiLocalConsumer::_Reserved6() { }
void BMidiLocalConsumer::_Reserved7() { } void BMidiLocalConsumer::_Reserved7() { }
void BMidiLocalConsumer::_Reserved8() { } void BMidiLocalConsumer::_Reserved8() { }
//------------------------------------------------------------------------------
int32 BMidiLocalConsumer::EventThread() int32
BMidiLocalConsumer::EventThread()
{ {
int32 msg_code; int32 msg_code;
ssize_t msg_size; ssize_t msg_size;
ssize_t buf_size = 100; ssize_t buf_size = 100;
uint8* buffer = (uint8*) malloc(buf_size); uint8* buffer = (uint8*) malloc(buf_size);
while (true) while (true) {
{ if (fTimeout == (bigtime_t) -1) {
if (timeout == (bigtime_t) -1) msg_size = port_buffer_size(fPort);
{ } else { // have timeout
msg_size = port_buffer_size(port); msg_size = port_buffer_size_etc(fPort, B_ABSOLUTE_TIMEOUT, fTimeout);
} if (msg_size == B_TIMED_OUT) {
else // have timeout Timeout(fTimeoutData);
{ fTimeout = (bigtime_t) -1;
msg_size = port_buffer_size_etc(port, B_ABSOLUTE_TIMEOUT, timeout); fTimeoutData = NULL;
if (msg_size == B_TIMED_OUT)
{
Timeout(timeoutData);
timeout = (bigtime_t) -1;
timeoutData = NULL;
continue; continue;
} }
} }
if (msg_size < 0) { break; } // error reading port if (msg_size < 0)
break; // error reading port
if (msg_size > buf_size) if (msg_size > buf_size) {
{
buffer = (uint8*) realloc(buffer, msg_size); buffer = (uint8*) realloc(buffer, msg_size);
buf_size = msg_size; buf_size = msg_size;
} }
read_port(port, &msg_code, buffer, msg_size); read_port(fPort, &msg_code, buffer, msg_size);
if (msg_size > 20) // minimum valid size if (msg_size > 20) { // minimum valid size
{
#ifdef DEBUG #ifdef DEBUG
printf("*** received: "); printf("*** received: ");
for (int32 t = 0; t < msg_size; ++t) for (int32 t = 0; t < msg_size; ++t) {
{
printf("%02X, ", ((uint8*) buffer)[t]); printf("%02X, ", ((uint8*) buffer)[t]);
} }
printf("\n"); printf("\n");
#endif #endif
currentProducer = *((uint32*) (buffer + 0)); fCurrentProducer = *((uint32*) (buffer + 0));
int32 targetId = *((uint32*) (buffer + 4)); int32 targetId = *((uint32*) (buffer + 4));
bigtime_t time = *((bigtime_t*) (buffer + 8)); bigtime_t time = *((bigtime_t*) (buffer + 8));
bool atomic = *((bool*) (buffer + 16)); bool atomic = *((bool*) (buffer + 16));
if (targetId == id) // only if we are the destination if (targetId == fId) { // only if we are the destination
{
Data((uchar*) (buffer + 20), msg_size - 20, atomic, time); Data((uchar*) (buffer + 20), msg_size - 20, atomic, time);
} }
} }
@ -441,4 +373,3 @@ int32 BMidiLocalConsumer::EventThread()
return 0; return 0;
} }
//------------------------------------------------------------------------------

View File

@ -1,31 +1,17 @@
/* /*
* Copyright (c) 2002-2004 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "debug.h" #include "debug.h"
#include "MidiConsumer.h" #include <MidiConsumer.h>
#include "MidiProducer.h" #include <MidiProducer.h>
#include "MidiRoster.h" #include <MidiRoster.h>
#include "protocol.h" #include "protocol.h"
@ -34,8 +20,8 @@ BMidiLocalProducer::BMidiLocalProducer(const char* name)
{ {
TRACE(("BMidiLocalProducer::BMidiLocalProducer")) TRACE(("BMidiLocalProducer::BMidiLocalProducer"))
isLocal = true; fIsLocal = true;
refCount = 1; fRefCount = 1;
BMidiRoster::MidiRoster()->CreateLocal(this); BMidiRoster::MidiRoster()->CreateLocal(this);
} }
@ -298,7 +284,7 @@ BMidiLocalProducer::SprayEvent(const void* data, size_t length,
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)) = fId;
*((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;
@ -315,7 +301,7 @@ BMidiLocalProducer::SprayEvent(const void* data, size_t 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->fId;
#ifdef DEBUG #ifdef DEBUG
printf("*** spraying: "); printf("*** spraying: ");
@ -326,7 +312,7 @@ BMidiLocalProducer::SprayEvent(const void* data, size_t length,
printf("\n"); printf("\n");
#endif #endif
write_port(cons->port, 0, buffer, buf_size); write_port(cons->fPort, 0, buffer, buf_size);
} }
free(buffer); free(buffer);

View File

@ -1,81 +1,55 @@
/* /*
* Copyright (c) 2002-2003 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include "debug.h" #include "debug.h"
#include "MidiConsumer.h" #include <MidiConsumer.h>
#include "MidiProducer.h" #include <MidiProducer.h>
#include "MidiRoster.h" #include <MidiRoster.h>
#include "MidiRosterLooper.h" #include "MidiRosterLooper.h"
#include "protocol.h" #include "protocol.h"
//------------------------------------------------------------------------------
status_t BMidiProducer::Connect(BMidiConsumer* cons) status_t
BMidiProducer::Connect(BMidiConsumer* cons)
{ {
if (cons == NULL) if (cons == NULL) {
{
WARN("Connect() does not accept a NULL consumer") WARN("Connect() does not accept a NULL consumer")
return B_BAD_VALUE; return B_BAD_VALUE;
} }
else if (!IsValid() || !cons->IsValid()) if (!IsValid() || !cons->IsValid()) {
{
return B_ERROR; return B_ERROR;
} }
else return SendConnectRequest(cons, true);
{
return SendConnectRequest(cons, true);
}
} }
//------------------------------------------------------------------------------
status_t BMidiProducer::Disconnect(BMidiConsumer* cons) status_t
BMidiProducer::Disconnect(BMidiConsumer* cons)
{ {
if (cons == NULL) if (cons == NULL) {
{
WARN("Disconnect() does not accept a NULL consumer") WARN("Disconnect() does not accept a NULL consumer")
return B_BAD_VALUE; return B_BAD_VALUE;
} }
else if (!IsValid() || !cons->IsValid()) if (!IsValid() || !cons->IsValid()) {
{
return B_ERROR; return B_ERROR;
} }
else return SendConnectRequest(cons, false);
{
return SendConnectRequest(cons, false);
}
} }
//------------------------------------------------------------------------------
bool BMidiProducer::IsConnected(BMidiConsumer* cons) const bool
BMidiProducer::IsConnected(BMidiConsumer* cons) const
{ {
bool isConnected = false; bool isConnected = false;
if (cons != NULL) if (cons != NULL) {
{ if (LockProducer()) {
if (LockProducer()) isConnected = fConnections.HasItem(cons);
{
isConnected = connections->HasItem(cons);
UnlockProducer(); UnlockProducer();
} }
} }
@ -83,16 +57,14 @@ bool BMidiProducer::IsConnected(BMidiConsumer* cons) const
return isConnected; return isConnected;
} }
//------------------------------------------------------------------------------
BList* BMidiProducer::Connections() const BList*
BMidiProducer::Connections() const
{ {
BList* list = new BList(); BList* list = new BList();
if (LockProducer()) if (LockProducer()) {
{ for (int32 t = 0; t < CountConsumers(); ++t) {
for (int32 t = 0; t < CountConsumers(); ++t)
{
BMidiConsumer* cons = ConsumerAt(t); BMidiConsumer* cons = ConsumerAt(t);
cons->Acquire(); cons->Acquire();
list->AddItem(cons); list->AddItem(cons);
@ -104,25 +76,20 @@ BList* BMidiProducer::Connections() const
return list; return list;
} }
//------------------------------------------------------------------------------
BMidiProducer::BMidiProducer(const char* name) BMidiProducer::BMidiProducer(const char* name)
: BMidiEndpoint(name) : BMidiEndpoint(name),
fLocker("MidiProducerLock"),
fConnections()
{ {
isConsumer = false; fIsConsumer = false;
connections = new BList;
locker = new BLocker("MidiProducerLock");
} }
//------------------------------------------------------------------------------
BMidiProducer::~BMidiProducer() BMidiProducer::~BMidiProducer()
{ {
delete connections;
delete locker;
} }
//------------------------------------------------------------------------------
void BMidiProducer::_Reserved1() { } void BMidiProducer::_Reserved1() { }
void BMidiProducer::_Reserved2() { } void BMidiProducer::_Reserved2() { }
@ -133,21 +100,18 @@ void BMidiProducer::_Reserved6() { }
void BMidiProducer::_Reserved7() { } void BMidiProducer::_Reserved7() { }
void BMidiProducer::_Reserved8() { } void BMidiProducer::_Reserved8() { }
//------------------------------------------------------------------------------
status_t BMidiProducer::SendConnectRequest( status_t
BMidiProducer::SendConnectRequest(
BMidiConsumer* cons, bool mustConnect) BMidiConsumer* cons, bool mustConnect)
{ {
ASSERT(cons != NULL) ASSERT(cons != NULL)
BMessage msg, reply; BMessage msg, reply;
if (mustConnect) if (mustConnect) {
{
msg.what = MSG_CONNECT_ENDPOINTS; msg.what = MSG_CONNECT_ENDPOINTS;
} } else {
else
{
msg.what = MSG_DISCONNECT_ENDPOINTS; msg.what = MSG_DISCONNECT_ENDPOINTS;
} }
@ -155,24 +119,20 @@ status_t BMidiProducer::SendConnectRequest(
msg.AddInt32("midi:consumer", cons->ID()); msg.AddInt32("midi:consumer", cons->ID());
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) {
{ if (res == B_OK) {
if (res == B_OK) if (mustConnect) {
{
if (mustConnect)
{
ConnectionMade(cons); ConnectionMade(cons);
} } else {
else
{
ConnectionBroken(cons); ConnectionBroken(cons);
} }
#ifdef DEBUG #ifdef DEBUG
BMidiRoster::MidiRoster()->looper->DumpEndpoints(); BMidiRoster::MidiRoster()->fLooper->DumpEndpoints();
#endif #endif
} }
@ -182,77 +142,71 @@ status_t BMidiProducer::SendConnectRequest(
return B_ERROR; return B_ERROR;
} }
//------------------------------------------------------------------------------
void BMidiProducer::ConnectionMade(BMidiConsumer* cons) void
BMidiProducer::ConnectionMade(BMidiConsumer* consumer)
{ {
ASSERT(cons != NULL) ASSERT(consumer != NULL)
if (LockProducer()) if (LockProducer()) {
{ ASSERT(!fConnections.HasItem(consumer))
ASSERT(!connections->HasItem(cons))
connections->AddItem(cons); fConnections.AddItem(consumer);
UnlockProducer(); UnlockProducer();
} }
if (IsLocal()) if (IsLocal()) {
{ ((BMidiLocalProducer*) this)->Connected(consumer);
((BMidiLocalProducer*) this)->Connected(cons);
} }
} }
//------------------------------------------------------------------------------
bool BMidiProducer::ConnectionBroken(BMidiConsumer* cons) bool
BMidiProducer::ConnectionBroken(BMidiConsumer* consumer)
{ {
ASSERT(cons != NULL) ASSERT(consumer != NULL)
bool wasConnected = false; bool wasConnected = false;
if (LockProducer()) if (LockProducer()) {
{ wasConnected = fConnections.RemoveItem(consumer);
wasConnected = connections->RemoveItem(cons);
UnlockProducer(); UnlockProducer();
} }
if (wasConnected && IsLocal()) if (wasConnected && IsLocal()) {
{ ((BMidiLocalProducer*) this)->Disconnected(consumer);
((BMidiLocalProducer*) this)->Disconnected(cons);
} }
return wasConnected; return wasConnected;
} }
//------------------------------------------------------------------------------
int32 BMidiProducer::CountConsumers() const int32
BMidiProducer::CountConsumers() const
{ {
return connections->CountItems(); return fConnections.CountItems();
} }
//------------------------------------------------------------------------------
BMidiConsumer* BMidiProducer::ConsumerAt(int32 index) const BMidiConsumer*
BMidiProducer::ConsumerAt(int32 index) const
{ {
ASSERT(connections != NULL)
ASSERT(index >= 0 && index < CountConsumers()) ASSERT(index >= 0 && index < CountConsumers())
return (BMidiConsumer*) connections->ItemAt(index); return (BMidiConsumer*) fConnections.ItemAt(index);
} }
//------------------------------------------------------------------------------
bool BMidiProducer::LockProducer() const bool
BMidiProducer::LockProducer() const
{ {
return locker->Lock(); return fLocker.Lock();
} }
//------------------------------------------------------------------------------
void BMidiProducer::UnlockProducer() const void
BMidiProducer::UnlockProducer() const
{ {
locker->Unlock(); fLocker.Unlock();
} }
//------------------------------------------------------------------------------

View File

@ -1,28 +1,14 @@
/* /*
* Copyright (c) 2002-2004 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include "debug.h" #include "debug.h"
#include "MidiConsumer.h" #include <MidiConsumer.h>
#include "MidiRoster.h" #include <MidiRoster.h>
#include "MidiRosterLooper.h" #include "MidiRosterLooper.h"
#include "protocol.h" #include "protocol.h"
@ -60,20 +46,17 @@ namespace BPrivate
midi_roster_killer; midi_roster_killer;
} }
//------------------------------------------------------------------------------
BMidiEndpoint* BMidiRoster::NextEndpoint(int32* id) BMidiEndpoint*
BMidiRoster::NextEndpoint(int32* id)
{ {
BMidiEndpoint* endp = NULL; BMidiEndpoint* endp = NULL;
if (id != NULL) if (id != NULL) {
{ BMidiRosterLooper* looper = MidiRoster()->fLooper;
BMidiRosterLooper* looper = MidiRoster()->looper; if (looper->Lock()) {
if (looper->Lock())
{
endp = looper->NextEndpoint(id); endp = looper->NextEndpoint(id);
if (endp != NULL) if (endp != NULL) {
{
endp->Acquire(); endp->Acquire();
} }
looper->Unlock(); looper->Unlock();
@ -83,69 +66,55 @@ BMidiEndpoint* BMidiRoster::NextEndpoint(int32* id)
return endp; return endp;
} }
//------------------------------------------------------------------------------
BMidiProducer* BMidiRoster::NextProducer(int32* id) BMidiProducer*
BMidiRoster::NextProducer(int32* id)
{ {
BMidiEndpoint* endp; BMidiEndpoint* endp;
while ((endp = NextEndpoint(id)) != NULL) while ((endp = NextEndpoint(id)) != NULL) {
{ if (endp->IsProducer()) {
if (endp->IsProducer())
{
return (BMidiProducer*) endp; return (BMidiProducer*) endp;
} }
else endp->Release();
{
endp->Release();
}
} }
return NULL; return NULL;
} }
//------------------------------------------------------------------------------
BMidiConsumer* BMidiRoster::NextConsumer(int32* id) BMidiConsumer*
BMidiRoster::NextConsumer(int32* id)
{ {
BMidiEndpoint* endp; BMidiEndpoint* endp;
while ((endp = NextEndpoint(id)) != NULL) while ((endp = NextEndpoint(id)) != NULL) {
{ if (endp->IsConsumer()) {
if (endp->IsConsumer())
{
return (BMidiConsumer*) endp; return (BMidiConsumer*) endp;
} }
else endp->Release();
{
endp->Release();
}
} }
return NULL; return NULL;
} }
//------------------------------------------------------------------------------
BMidiEndpoint* BMidiRoster::FindEndpoint(int32 id, bool localOnly) BMidiEndpoint*
BMidiRoster::FindEndpoint(int32 id, bool localOnly)
{ {
BMidiEndpoint* endp = NULL; BMidiEndpoint* endp = NULL;
BMidiRosterLooper* looper = MidiRoster()->looper; BMidiRosterLooper* looper = MidiRoster()->fLooper;
if (looper->Lock()) if (looper->Lock()) {
{
endp = looper->FindEndpoint(id); endp = looper->FindEndpoint(id);
if ((endp != NULL) && endp->IsRemote()) if ((endp != NULL) && endp->IsRemote()) {
{ if (localOnly || !endp->IsRegistered()) {
if (localOnly || !endp->IsRegistered())
{
endp = NULL; endp = NULL;
} }
} }
if (endp != NULL) if (endp != NULL) {
{
endp->Acquire(); endp->Acquire();
} }
@ -155,14 +124,13 @@ BMidiEndpoint* BMidiRoster::FindEndpoint(int32 id, bool localOnly)
return endp; return endp;
} }
//------------------------------------------------------------------------------
BMidiProducer* BMidiRoster::FindProducer(int32 id, bool localOnly) BMidiProducer*
BMidiRoster::FindProducer(int32 id, bool localOnly)
{ {
BMidiEndpoint* endp = FindEndpoint(id, localOnly); BMidiEndpoint* endp = FindEndpoint(id, localOnly);
if ((endp != NULL) && !endp->IsProducer()) if ((endp != NULL) && !endp->IsProducer()) {
{
endp->Release(); endp->Release();
endp = NULL; endp = NULL;
} }
@ -170,14 +138,13 @@ BMidiProducer* BMidiRoster::FindProducer(int32 id, bool localOnly)
return (BMidiProducer*) endp; return (BMidiProducer*) endp;
} }
//------------------------------------------------------------------------------
BMidiConsumer* BMidiRoster::FindConsumer(int32 id, bool localOnly) BMidiConsumer*
BMidiRoster::FindConsumer(int32 id, bool localOnly)
{ {
BMidiEndpoint* endp = FindEndpoint(id, localOnly); BMidiEndpoint* endp = FindEndpoint(id, localOnly);
if ((endp != NULL) && !endp->IsConsumer()) if ((endp != NULL) && !endp->IsConsumer()) {
{
endp->Release(); endp->Release();
endp = NULL; endp = NULL;
} }
@ -185,76 +152,68 @@ BMidiConsumer* BMidiRoster::FindConsumer(int32 id, bool localOnly)
return (BMidiConsumer*) endp; return (BMidiConsumer*) endp;
} }
//------------------------------------------------------------------------------
void BMidiRoster::StartWatching(const BMessenger* msngr) void
BMidiRoster::StartWatching(const BMessenger* msngr)
{ {
if (msngr == NULL) if (msngr == NULL) {
{
WARN("StartWatching does not accept a NULL messenger") WARN("StartWatching does not accept a NULL messenger")
} } else {
else BMidiRosterLooper* looper = MidiRoster()->fLooper;
{ if (looper->Lock()) {
BMidiRosterLooper* looper = MidiRoster()->looper;
if (looper->Lock())
{
looper->StartWatching(msngr); looper->StartWatching(msngr);
looper->Unlock(); looper->Unlock();
} }
} }
} }
//------------------------------------------------------------------------------
void BMidiRoster::StopWatching() void
BMidiRoster::StopWatching()
{ {
BMidiRosterLooper* looper = MidiRoster()->looper; BMidiRosterLooper* looper = MidiRoster()->fLooper;
if (looper->Lock()) if (looper->Lock()) {
{
looper->StopWatching(); looper->StopWatching();
looper->Unlock(); looper->Unlock();
} }
} }
//------------------------------------------------------------------------------
status_t BMidiRoster::Register(BMidiEndpoint* endp) status_t
BMidiRoster::Register(BMidiEndpoint* endp)
{ {
if (endp != NULL) if (endp != NULL) {
{
return endp->Register(); return endp->Register();
} }
return B_BAD_VALUE; return B_BAD_VALUE;
} }
//------------------------------------------------------------------------------
status_t BMidiRoster::Unregister(BMidiEndpoint* endp) status_t
BMidiRoster::Unregister(BMidiEndpoint* endp)
{ {
if (endp != NULL) if (endp != NULL) {
{
return endp->Unregister(); return endp->Unregister();
} }
return B_BAD_VALUE; return B_BAD_VALUE;
} }
//------------------------------------------------------------------------------
BMidiRoster* BMidiRoster::MidiRoster() BMidiRoster*
BMidiRoster::MidiRoster()
{ {
if (roster == NULL) if (roster == NULL) {
{
new BMidiRoster(); new BMidiRoster();
} }
return roster; return roster;
} }
//------------------------------------------------------------------------------
BMidiRoster::BMidiRoster() BMidiRoster::BMidiRoster()
: fServer(MIDI_SERVER_SIGNATURE)
{ {
TRACE(("BMidiRoster::BMidiRoster")) TRACE(("BMidiRoster::BMidiRoster"))
@ -265,17 +224,16 @@ BMidiRoster::BMidiRoster()
roster = this; roster = this;
server = new BMessenger(MIDI_SERVER_SIGNATURE); fLooper = new BMidiRosterLooper();
looper = new BMidiRosterLooper();
if (!looper->Init(this)) { return; } if (!fLooper->Init(this))
return;
BMessage msg; BMessage msg;
msg.what = MSG_REGISTER_APP; msg.what = MSG_REGISTER_APP;
msg.AddMessenger("midi:messenger", BMessenger(looper)); msg.AddMessenger("midi:messenger", BMessenger(fLooper));
if (server->SendMessage(&msg, looper, TIMEOUT) != B_OK) if (fServer.SendMessage(&msg, fLooper, TIMEOUT) != B_OK) {
{
WARN("Cannot send request to midi_server"); WARN("Cannot send request to midi_server");
return; return;
} }
@ -286,25 +244,20 @@ BMidiRoster::BMidiRoster()
// will bump the semaphore count, and our acquire_sem() // will bump the semaphore count, and our acquire_sem()
// can grab the semaphore safely (without blocking). // can grab the semaphore safely (without blocking).
acquire_sem(looper->initLock); acquire_sem(fLooper->fInitLock);
} }
//------------------------------------------------------------------------------
BMidiRoster::~BMidiRoster() BMidiRoster::~BMidiRoster()
{ {
TRACE(("BMidiRoster::~BMidiRoster")) TRACE(("BMidiRoster::~BMidiRoster"))
if (looper != NULL) if (fLooper != NULL) {
{ fLooper->Lock();
looper->Lock(); fLooper->Quit();
looper->Quit();
} }
delete server;
} }
//------------------------------------------------------------------------------
void BMidiRoster::_Reserved1() { } void BMidiRoster::_Reserved1() { }
void BMidiRoster::_Reserved2() { } void BMidiRoster::_Reserved2() { }
@ -315,9 +268,9 @@ void BMidiRoster::_Reserved6() { }
void BMidiRoster::_Reserved7() { } void BMidiRoster::_Reserved7() { }
void BMidiRoster::_Reserved8() { } void BMidiRoster::_Reserved8() { }
//------------------------------------------------------------------------------
void BMidiRoster::CreateLocal(BMidiEndpoint* endp) void
BMidiRoster::CreateLocal(BMidiEndpoint* endp)
{ {
ASSERT(endp != NULL) ASSERT(endp != NULL)
@ -328,35 +281,29 @@ void BMidiRoster::CreateLocal(BMidiEndpoint* endp)
BMessage msg; BMessage msg;
msg.what = MSG_CREATE_ENDPOINT; msg.what = MSG_CREATE_ENDPOINT;
msg.AddBool("midi:consumer", endp->isConsumer); msg.AddBool("midi:consumer", endp->fIsConsumer);
msg.AddBool("midi:registered", endp->isRegistered); msg.AddBool("midi:registered", endp->fIsRegistered);
msg.AddString("midi:name", endp->Name()); msg.AddString("midi:name", endp->Name());
msg.AddMessage("midi:properties", endp->properties); msg.AddMessage("midi:properties", endp->fProperties);
if (endp->IsConsumer()) if (endp->IsConsumer()) {
{
BMidiConsumer* consumer = (BMidiConsumer*) endp; BMidiConsumer* consumer = (BMidiConsumer*) endp;
msg.AddInt32("midi:port", consumer->port); msg.AddInt32("midi:port", consumer->fPort);
msg.AddInt64("midi:latency", consumer->latency); msg.AddInt64("midi:latency", consumer->fLatency);
} }
BMessage reply; BMessage reply;
if (SendRequest(&msg, &reply) == B_OK) if (SendRequest(&msg, &reply) == B_OK) {
{
status_t res; status_t res;
if (reply.FindInt32("midi:result", &res) == B_OK) if (reply.FindInt32("midi:result", &res) == B_OK) {
{ if (res == B_OK) {
if (res == B_OK)
{
int32 id; int32 id;
if (reply.FindInt32("midi:id", &id) == B_OK) if (reply.FindInt32("midi:id", &id) == B_OK) {
{ endp->fId = id;
endp->id = id;
if (looper->Lock()) if (fLooper->Lock()) {
{ fLooper->AddEndpoint(endp);
looper->AddEndpoint(endp); fLooper->Unlock();
looper->Unlock();
} }
} }
} }
@ -374,9 +321,9 @@ void BMidiRoster::CreateLocal(BMidiEndpoint* endp)
// trip an assertion, so you can't delete these endpoints.) // trip an assertion, so you can't delete these endpoints.)
} }
//------------------------------------------------------------------------------
void BMidiRoster::DeleteLocal(BMidiEndpoint* endp) void
BMidiRoster::DeleteLocal(BMidiEndpoint* endp)
{ {
ASSERT(endp != NULL) ASSERT(endp != NULL)
@ -389,40 +336,36 @@ void BMidiRoster::DeleteLocal(BMidiEndpoint* endp)
// a reply from the server. If something went wrong, the // a reply from the server. If something went wrong, the
// object will be destroyed regardless. // object will be destroyed regardless.
server->SendMessage(&msg, (BHandler*) NULL, TIMEOUT); fServer.SendMessage(&msg, (BHandler*) NULL, TIMEOUT);
// If the endpoint was successfully created, we must remove // If the endpoint was successfully created, we must remove
// it from the list of endpoints. If creation failed, then // it from the list of endpoints. If creation failed, then
// we didn't put the endpoint on that list. If the endpoint // we didn't put the endpoint on that list. If the endpoint
// was connected to anything, we must also disconnect it. // was connected to anything, we must also disconnect it.
if (endp->ID() > 0) if (endp->ID() > 0) {
{ if (fLooper->Lock()) {
if (looper->Lock()) fLooper->RemoveEndpoint(endp);
{ fLooper->Unlock();
looper->RemoveEndpoint(endp);
looper->Unlock();
} }
} }
} }
//------------------------------------------------------------------------------
status_t BMidiRoster::SendRequest(BMessage* msg, BMessage* reply) status_t
BMidiRoster::SendRequest(BMessage* msg, BMessage* reply)
{ {
ASSERT(msg != NULL) ASSERT(msg != NULL)
ASSERT(reply != NULL) ASSERT(reply != NULL)
status_t err = server->SendMessage(msg, reply, TIMEOUT, TIMEOUT); status_t err = fServer.SendMessage(msg, reply, TIMEOUT, TIMEOUT);
if (err != B_OK) if (err != B_OK) {
{
WARN("Cannot send request to midi_server"); WARN("Cannot send request to midi_server");
} }
#ifdef DEBUG #ifdef DEBUG
if (err == B_OK) if (err == B_OK) {
{
printf("REPLY "); reply->PrintToStream(); printf("REPLY "); reply->PrintToStream();
} }
#endif #endif
@ -430,4 +373,3 @@ status_t BMidiRoster::SendRequest(BMessage* msg, BMessage* reply)
return err; return err;
} }
//------------------------------------------------------------------------------

View File

@ -1,53 +1,36 @@
/* /*
* Copyright (c) 2002-2004 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#include "debug.h" #include "debug.h"
#include "MidiConsumer.h" #include <MidiConsumer.h>
#include "MidiProducer.h" #include <MidiProducer.h>
#include "MidiRoster.h" #include <MidiRoster.h>
#include "MidiRosterLooper.h" #include "MidiRosterLooper.h"
#include "protocol.h" #include "protocol.h"
using namespace BPrivate; using namespace BPrivate;
//------------------------------------------------------------------------------
BMidiRosterLooper::BMidiRosterLooper() BMidiRosterLooper::BMidiRosterLooper()
: BLooper("MidiRosterLooper") : BLooper("MidiRosterLooper")
{ {
initLock = -1; fInitLock = -1;
roster = NULL; fRoster = NULL;
watcher = NULL; fWatcher = NULL;
} }
//------------------------------------------------------------------------------
BMidiRosterLooper::~BMidiRosterLooper() BMidiRosterLooper::~BMidiRosterLooper()
{ {
StopWatching(); StopWatching();
if (initLock >= B_OK) if (fInitLock >= B_OK) {
{ delete_sem(fInitLock);
delete_sem(initLock);
} }
// At this point, our list may still contain endpoints with a // At this point, our list may still contain endpoints with a
@ -58,30 +41,26 @@ BMidiRosterLooper::~BMidiRosterLooper()
// It would have been better to jump into the debugger, but I // It would have been better to jump into the debugger, but I
// did not want to risk breaking any (misbehaving) old apps. // did not want to risk breaking any (misbehaving) old apps.
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
if (endp->refCount > 0) if (endp->fRefCount > 0) {
{
fprintf( fprintf(
stderr, "[midi] WARNING: Endpoint %ld (%p) has " stderr, "[midi] WARNING: Endpoint %ld (%p) has "
"not been Release()d properly (refcount = %ld)\n", "not been Release()d properly (refcount = %ld)\n",
endp->ID(), endp, endp->refCount); endp->ID(), endp, endp->fRefCount);
} } else {
else
{
delete endp; delete endp;
} }
} }
} }
//------------------------------------------------------------------------------
bool BMidiRosterLooper::Init(BMidiRoster* roster_) bool
BMidiRosterLooper::Init(BMidiRoster* roster_)
{ {
ASSERT(roster_ != NULL) ASSERT(roster_ != NULL)
roster = roster_; fRoster = roster_;
// We create a semaphore with a zero count. BMidiRoster's // We create a semaphore with a zero count. BMidiRoster's
// MidiRoster() method will try to acquire this semaphore, // MidiRoster() method will try to acquire this semaphore,
@ -89,18 +68,16 @@ bool BMidiRosterLooper::Init(BMidiRoster* roster_)
// "app registered" message in our MessageReceived() hook, // "app registered" message in our MessageReceived() hook,
// we release the semaphore and MidiRoster() will unblock. // we release the semaphore and MidiRoster() will unblock.
initLock = create_sem(0, "InitLock"); fInitLock = create_sem(0, "InitLock");
if (initLock < B_OK) if (fInitLock < B_OK) {
{
WARN("Could not create semaphore") WARN("Could not create semaphore")
return false; return false;
} }
thread_id threadId = Run(); thread_id threadId = Run();
if (threadId < B_OK) if (threadId < B_OK) {
{
WARN("Could not start looper thread") WARN("Could not start looper thread")
return false; return false;
} }
@ -108,19 +85,16 @@ bool BMidiRosterLooper::Init(BMidiRoster* roster_)
return true; return true;
} }
//------------------------------------------------------------------------------
BMidiEndpoint* BMidiRosterLooper::NextEndpoint(int32* id) BMidiEndpoint*
BMidiRosterLooper::NextEndpoint(int32* id)
{ {
ASSERT(id != NULL) ASSERT(id != NULL)
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
if (endp->ID() > *id) if (endp->ID() > *id) {
{ if (endp->IsRemote() && endp->IsRegistered()) {
if (endp->IsRemote() && endp->IsRegistered())
{
*id = endp->ID(); *id = endp->ID();
return endp; return endp;
} }
@ -130,15 +104,13 @@ BMidiEndpoint* BMidiRosterLooper::NextEndpoint(int32* id)
return NULL; return NULL;
} }
//------------------------------------------------------------------------------
BMidiEndpoint* BMidiRosterLooper::FindEndpoint(int32 id) BMidiEndpoint*
BMidiRosterLooper::FindEndpoint(int32 id)
{ {
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
if (endp->ID() == id) if (endp->ID() == id) {
{
return endp; return endp;
} }
} }
@ -146,12 +118,12 @@ BMidiEndpoint* BMidiRosterLooper::FindEndpoint(int32 id)
return NULL; return NULL;
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::AddEndpoint(BMidiEndpoint* endp) void
BMidiRosterLooper::AddEndpoint(BMidiEndpoint* endp)
{ {
ASSERT(endp != NULL) ASSERT(endp != NULL)
ASSERT(!endpoints.HasItem(endp)) ASSERT(!fEndpoints.HasItem(endp))
// We store the endpoints sorted by ID, because that // We store the endpoints sorted by ID, because that
// simplifies the implementation of NextEndpoint(). // simplifies the implementation of NextEndpoint().
@ -160,36 +132,31 @@ void BMidiRosterLooper::AddEndpoint(BMidiEndpoint* endp)
// are delivered in this order (mostly they will be). // are delivered in this order (mostly they will be).
int32 t; int32 t;
for (t = CountEndpoints(); t > 0; --t) for (t = CountEndpoints(); t > 0; --t) {
{
BMidiEndpoint* other = EndpointAt(t - 1); BMidiEndpoint* other = EndpointAt(t - 1);
if (endp->ID() > other->ID()) if (endp->ID() > other->ID()) {
{
break; break;
} }
} }
endpoints.AddItem(endp, t); fEndpoints.AddItem(endp, t);
#ifdef DEBUG #ifdef DEBUG
DumpEndpoints(); DumpEndpoints();
#endif #endif
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::RemoveEndpoint(BMidiEndpoint* endp) void
BMidiRosterLooper::RemoveEndpoint(BMidiEndpoint* endp)
{ {
ASSERT(endp != NULL) ASSERT(endp != NULL)
ASSERT(endpoints.HasItem(endp)) ASSERT(fEndpoints.HasItem(endp))
endpoints.RemoveItem(endp); fEndpoints.RemoveItem(endp);
if (endp->IsConsumer()) if (endp->IsConsumer()) {
{
DisconnectDeadConsumer((BMidiConsumer*) endp); DisconnectDeadConsumer((BMidiConsumer*) endp);
} } else {
else
{
DisconnectDeadProducer((BMidiProducer*) endp); DisconnectDeadProducer((BMidiProducer*) endp);
} }
@ -198,37 +165,36 @@ void BMidiRosterLooper::RemoveEndpoint(BMidiEndpoint* endp)
#endif #endif
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::StartWatching(const BMessenger* watcher_) void
BMidiRosterLooper::StartWatching(const BMessenger* watcher_)
{ {
ASSERT(watcher_ != NULL) ASSERT(watcher_ != NULL)
StopWatching(); StopWatching();
watcher = new BMessenger(*watcher_); fWatcher = new BMessenger(*watcher_);
AllEndpoints(); AllEndpoints();
AllConnections(); AllConnections();
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::StopWatching() void
BMidiRosterLooper::StopWatching()
{ {
delete watcher; delete fWatcher;
watcher = NULL; fWatcher = NULL;
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::MessageReceived(BMessage* msg) void
BMidiRosterLooper::MessageReceived(BMessage* msg)
{ {
#ifdef DEBUG #ifdef DEBUG
printf("IN "); msg->PrintToStream(); printf("IN "); msg->PrintToStream();
#endif #endif
switch (msg->what) switch (msg->what) {
{
case MSG_APP_REGISTERED: OnAppRegistered(msg); break; case MSG_APP_REGISTERED: OnAppRegistered(msg); break;
case MSG_ENDPOINT_CREATED: OnEndpointCreated(msg); break; case MSG_ENDPOINT_CREATED: OnEndpointCreated(msg); break;
case MSG_ENDPOINT_DELETED: OnEndpointDeleted(msg); break; case MSG_ENDPOINT_DELETED: OnEndpointDeleted(msg); break;
@ -240,16 +206,16 @@ void BMidiRosterLooper::MessageReceived(BMessage* msg)
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::OnAppRegistered(BMessage* msg) void
BMidiRosterLooper::OnAppRegistered(BMessage* msg)
{ {
release_sem(initLock); release_sem(fInitLock);
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::OnEndpointCreated(BMessage* msg) void
BMidiRosterLooper::OnEndpointCreated(BMessage* msg)
{ {
int32 id; int32 id;
bool isRegistered; bool isRegistered;
@ -258,37 +224,32 @@ void BMidiRosterLooper::OnEndpointCreated(BMessage* msg)
bool isConsumer; bool isConsumer;
if ((msg->FindInt32("midi:id", &id) == B_OK) if ((msg->FindInt32("midi:id", &id) == B_OK)
&& (msg->FindBool("midi:registered", &isRegistered) == B_OK) && (msg->FindBool("midi:registered", &isRegistered) == B_OK)
&& (msg->FindString("midi:name", &name) == B_OK) && (msg->FindString("midi:name", &name) == B_OK)
&& (msg->FindMessage("midi:properties", &properties) == B_OK) && (msg->FindMessage("midi:properties", &properties) == B_OK)
&& (msg->FindBool("midi:consumer", &isConsumer) == B_OK)) && (msg->FindBool("midi:consumer", &isConsumer) == B_OK)) {
{ if (isConsumer) {
if (isConsumer)
{
int32 port; int32 port;
bigtime_t latency; bigtime_t latency;
if ((msg->FindInt32("midi:port", &port) == B_OK) if ((msg->FindInt32("midi:port", &port) == B_OK)
&& (msg->FindInt64("midi:latency", &latency) == B_OK)) && (msg->FindInt64("midi:latency", &latency) == B_OK)) {
{
BMidiConsumer* cons = new BMidiConsumer(); BMidiConsumer* cons = new BMidiConsumer();
cons->name = name; cons->fName = name;
cons->id = id; cons->fId = id;
cons->isRegistered = isRegistered; cons->fIsRegistered = isRegistered;
cons->port = port; cons->fPort = port;
cons->latency = latency; cons->fLatency = latency;
*(cons->properties) = properties; *(cons->fProperties) = properties;
AddEndpoint(cons); AddEndpoint(cons);
return; return;
} }
} } else { // producer
else // producer
{
BMidiProducer* prod = new BMidiProducer(); BMidiProducer* prod = new BMidiProducer();
prod->name = name; prod->fName = name;
prod->id = id; prod->fId = id;
prod->isRegistered = isRegistered; prod->fIsRegistered = isRegistered;
*(prod->properties) = properties; *(prod->fProperties) = properties;
AddEndpoint(prod); AddEndpoint(prod);
return; return;
} }
@ -297,26 +258,22 @@ void BMidiRosterLooper::OnEndpointCreated(BMessage* msg)
WARN("Could not create proxy for remote endpoint") WARN("Could not create proxy for remote endpoint")
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::OnEndpointDeleted(BMessage* msg) void
BMidiRosterLooper::OnEndpointDeleted(BMessage* msg)
{ {
int32 id; int32 id;
if (msg->FindInt32("midi:id", &id) == B_OK) if (msg->FindInt32("midi:id", &id) == B_OK) {
{
BMidiEndpoint* endp = FindEndpoint(id); BMidiEndpoint* endp = FindEndpoint(id);
if (endp != NULL) if (endp != NULL) {
{
RemoveEndpoint(endp); RemoveEndpoint(endp);
// If the client is watching, and the endpoint is // If the client is watching, and the endpoint is
// registered remote, we need to let it know that // registered remote, we need to let it know that
// the endpoint is now unregistered. // the endpoint is now unregistered.
if (endp->IsRemote() && endp->IsRegistered()) if (endp->IsRemote() && endp->IsRegistered()) {
{ if (fWatcher != NULL) {
if (watcher != NULL)
{
BMessage notify; BMessage notify;
notify.AddInt32("be:op", B_MIDI_UNREGISTERED); notify.AddInt32("be:op", B_MIDI_UNREGISTERED);
ChangeEvent(&notify, endp); ChangeEvent(&notify, endp);
@ -330,14 +287,11 @@ void BMidiRosterLooper::OnEndpointDeleted(BMessage* msg)
// object. We clear the "isRegistered" flag to // object. We clear the "isRegistered" flag to
// let the client know the object is now invalid. // let the client know the object is now invalid.
if (endp->refCount == 0) if (endp->fRefCount == 0) {
{
delete endp; delete endp;
} } else { // still being used
else // still being used endp->fIsRegistered = false;
{ endp->fIsAlive = false;
endp->isRegistered = false;
endp->isAlive = false;
} }
return; return;
@ -347,16 +301,14 @@ void BMidiRosterLooper::OnEndpointDeleted(BMessage* msg)
WARN("Could not delete proxy for remote endpoint") WARN("Could not delete proxy for remote endpoint")
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::OnEndpointChanged(BMessage* msg) void
BMidiRosterLooper::OnEndpointChanged(BMessage* msg)
{ {
int32 id; int32 id;
if (msg->FindInt32("midi:id", &id) == B_OK) if (msg->FindInt32("midi:id", &id) == B_OK) {
{
BMidiEndpoint* endp = FindEndpoint(id); BMidiEndpoint* endp = FindEndpoint(id);
if ((endp != NULL) && endp->IsRemote()) if ((endp != NULL) && endp->IsRemote()) {
{
ChangeRegistered(msg, endp); ChangeRegistered(msg, endp);
ChangeName(msg, endp); ChangeName(msg, endp);
ChangeProperties(msg, endp); ChangeProperties(msg, endp);
@ -373,37 +325,30 @@ void BMidiRosterLooper::OnEndpointChanged(BMessage* msg)
WARN("Could not change endpoint attributes") WARN("Could not change endpoint attributes")
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::OnConnectedDisconnected(BMessage* msg) void
BMidiRosterLooper::OnConnectedDisconnected(BMessage* msg)
{ {
int32 prodId, consId; int32 prodId, consId;
if ((msg->FindInt32("midi:producer", &prodId) == B_OK) if ((msg->FindInt32("midi:producer", &prodId) == B_OK)
&& (msg->FindInt32("midi:consumer", &consId) == B_OK)) && (msg->FindInt32("midi:consumer", &consId) == B_OK)) {
{
BMidiEndpoint* endp1 = FindEndpoint(prodId); BMidiEndpoint* endp1 = FindEndpoint(prodId);
BMidiEndpoint* endp2 = FindEndpoint(consId); BMidiEndpoint* endp2 = FindEndpoint(consId);
if ((endp1 != NULL) && endp1->IsProducer()) if ((endp1 != NULL) && endp1->IsProducer()) {
{ if ((endp2 != NULL) && endp2->IsConsumer()) {
if ((endp2 != NULL) && endp2->IsConsumer())
{
BMidiProducer* prod = (BMidiProducer*) endp1; BMidiProducer* prod = (BMidiProducer*) endp1;
BMidiConsumer* cons = (BMidiConsumer*) endp2; BMidiConsumer* cons = (BMidiConsumer*) endp2;
bool mustConnect = (msg->what == MSG_ENDPOINTS_CONNECTED); bool mustConnect = (msg->what == MSG_ENDPOINTS_CONNECTED);
if (mustConnect) if (mustConnect) {
{
prod->ConnectionMade(cons); prod->ConnectionMade(cons);
} } else {
else
{
prod->ConnectionBroken(cons); prod->ConnectionBroken(cons);
} }
if (watcher != NULL) if (fWatcher != NULL) {
{
ConnectionEvent(prod, cons, mustConnect); ConnectionEvent(prod, cons, mustConnect);
} }
@ -419,29 +364,23 @@ void BMidiRosterLooper::OnConnectedDisconnected(BMessage* msg)
WARN("Could not connect/disconnect endpoints") WARN("Could not connect/disconnect endpoints")
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::ChangeRegistered(BMessage* msg, BMidiEndpoint* endp) void
BMidiRosterLooper::ChangeRegistered(BMessage* msg, BMidiEndpoint* endp)
{ {
ASSERT(msg != NULL) ASSERT(msg != NULL)
ASSERT(endp != NULL) ASSERT(endp != NULL)
bool isRegistered; bool isRegistered;
if (msg->FindBool("midi:registered", &isRegistered) == B_OK) if (msg->FindBool("midi:registered", &isRegistered) == B_OK) {
{ if (endp->fIsRegistered != isRegistered) {
if (endp->isRegistered != isRegistered) endp->fIsRegistered = isRegistered;
{
endp->isRegistered = isRegistered;
if (watcher != NULL) if (fWatcher != NULL) {
{
BMessage notify; BMessage notify;
if (isRegistered) if (isRegistered) {
{
notify.AddInt32("be:op", B_MIDI_REGISTERED); notify.AddInt32("be:op", B_MIDI_REGISTERED);
} } else {
else
{
notify.AddInt32("be:op", B_MIDI_UNREGISTERED); notify.AddInt32("be:op", B_MIDI_UNREGISTERED);
} }
ChangeEvent(&notify, endp); ChangeEvent(&notify, endp);
@ -450,22 +389,19 @@ void BMidiRosterLooper::ChangeRegistered(BMessage* msg, BMidiEndpoint* endp)
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::ChangeName(BMessage* msg, BMidiEndpoint* endp) void
BMidiRosterLooper::ChangeName(BMessage* msg, BMidiEndpoint* endp)
{ {
ASSERT(msg != NULL) ASSERT(msg != NULL)
ASSERT(endp != NULL) ASSERT(endp != NULL)
BString name; BString name;
if (msg->FindString("midi:name", &name) == B_OK) if (msg->FindString("midi:name", &name) == B_OK) {
{ if (endp->fName != name) {
if (endp->name != name) endp->fName = name;
{
endp->name = name;
if ((watcher != NULL) && endp->IsRegistered()) if ((fWatcher != NULL) && endp->IsRegistered()) {
{
BMessage notify; BMessage notify;
notify.AddInt32("be:op", B_MIDI_CHANGED_NAME); notify.AddInt32("be:op", B_MIDI_CHANGED_NAME);
notify.AddString("be:name", name); notify.AddString("be:name", name);
@ -475,20 +411,18 @@ void BMidiRosterLooper::ChangeName(BMessage* msg, BMidiEndpoint* endp)
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::ChangeProperties(BMessage* msg, BMidiEndpoint* endp) void
BMidiRosterLooper::ChangeProperties(BMessage* msg, BMidiEndpoint* endp)
{ {
ASSERT(msg != NULL) ASSERT(msg != NULL)
ASSERT(endp != NULL) ASSERT(endp != NULL)
BMessage properties; BMessage properties;
if (msg->FindMessage("midi:properties", &properties) == B_OK) if (msg->FindMessage("midi:properties", &properties) == B_OK) {
{ *(endp->fProperties) = properties;
*(endp->properties) = properties;
if ((watcher != NULL) && endp->IsRegistered()) if ((fWatcher != NULL) && endp->IsRegistered()) {
{
BMessage notify; BMessage notify;
notify.AddInt32("be:op", B_MIDI_CHANGED_PROPERTIES); notify.AddInt32("be:op", B_MIDI_CHANGED_PROPERTIES);
notify.AddMessage("be:properties", &properties); notify.AddMessage("be:properties", &properties);
@ -497,25 +431,21 @@ void BMidiRosterLooper::ChangeProperties(BMessage* msg, BMidiEndpoint* endp)
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::ChangeLatency(BMessage* msg, BMidiEndpoint* endp) void
BMidiRosterLooper::ChangeLatency(BMessage* msg, BMidiEndpoint* endp)
{ {
ASSERT(msg != NULL) ASSERT(msg != NULL)
ASSERT(endp != NULL) ASSERT(endp != NULL)
bigtime_t latency; bigtime_t latency;
if (msg->FindInt64("midi:latency", &latency) == B_OK) if (msg->FindInt64("midi:latency", &latency) == B_OK) {
{ if (endp->IsConsumer()) {
if (endp->IsConsumer())
{
BMidiConsumer* cons = (BMidiConsumer*) endp; BMidiConsumer* cons = (BMidiConsumer*) endp;
if (cons->latency != latency) if (cons->fLatency != latency) {
{ cons->fLatency = latency;
cons->latency = latency;
if ((watcher != NULL) && cons->IsRegistered()) if ((fWatcher != NULL) && cons->IsRegistered()) {
{
BMessage notify; BMessage notify;
notify.AddInt32("be:op", B_MIDI_CHANGED_LATENCY); notify.AddInt32("be:op", B_MIDI_CHANGED_LATENCY);
notify.AddInt64("be:latency", latency); notify.AddInt64("be:latency", latency);
@ -526,16 +456,14 @@ void BMidiRosterLooper::ChangeLatency(BMessage* msg, BMidiEndpoint* endp)
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::AllEndpoints() void
BMidiRosterLooper::AllEndpoints()
{ {
BMessage notify; BMessage notify;
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
if (endp->IsRemote() && endp->IsRegistered()) if (endp->IsRemote() && endp->IsRegistered()) {
{
notify.MakeEmpty(); notify.MakeEmpty();
notify.AddInt32("be:op", B_MIDI_REGISTERED); notify.AddInt32("be:op", B_MIDI_REGISTERED);
ChangeEvent(&notify, endp); ChangeEvent(&notify, endp);
@ -543,22 +471,17 @@ void BMidiRosterLooper::AllEndpoints()
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::AllConnections() void
BMidiRosterLooper::AllConnections()
{ {
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
if (endp->IsRemote() && endp->IsRegistered()) if (endp->IsRemote() && endp->IsRegistered()) {
{ if (endp->IsProducer()) {
if (endp->IsProducer())
{
BMidiProducer* prod = (BMidiProducer*) endp; BMidiProducer* prod = (BMidiProducer*) endp;
if (prod->LockProducer()) if (prod->LockProducer()) {
{ for (int32 k = 0; k < prod->CountConsumers(); ++k) {
for (int32 k = 0; k < prod->CountConsumers(); ++k)
{
ConnectionEvent(prod, prod->ConsumerAt(k), true); ConnectionEvent(prod, prod->ConsumerAt(k), true);
} }
prod->UnlockProducer(); prod->UnlockProducer();
@ -568,35 +491,32 @@ void BMidiRosterLooper::AllConnections()
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::ChangeEvent(BMessage* msg, BMidiEndpoint* endp) void
BMidiRosterLooper::ChangeEvent(BMessage* msg, BMidiEndpoint* endp)
{ {
ASSERT(watcher != NULL) ASSERT(fWatcher != NULL)
ASSERT(msg != NULL) ASSERT(msg != NULL)
ASSERT(endp != NULL) ASSERT(endp != NULL)
msg->what = B_MIDI_EVENT; msg->what = B_MIDI_EVENT;
msg->AddInt32("be:id", endp->ID()); msg->AddInt32("be:id", endp->ID());
if (endp->IsConsumer()) if (endp->IsConsumer()) {
{
msg->AddString("be:type", "consumer"); msg->AddString("be:type", "consumer");
} } else {
else
{
msg->AddString("be:type", "producer"); msg->AddString("be:type", "producer");
} }
watcher->SendMessage(msg); fWatcher->SendMessage(msg);
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::ConnectionEvent( void
BMidiRosterLooper::ConnectionEvent(
BMidiProducer* prod, BMidiConsumer* cons, bool mustConnect) BMidiProducer* prod, BMidiConsumer* cons, bool mustConnect)
{ {
ASSERT(watcher != NULL) ASSERT(fWatcher != NULL)
ASSERT(prod != NULL) ASSERT(prod != NULL)
ASSERT(cons != NULL) ASSERT(cons != NULL)
@ -605,21 +525,18 @@ void BMidiRosterLooper::ConnectionEvent(
notify.AddInt32("be:producer", prod->ID()); notify.AddInt32("be:producer", prod->ID());
notify.AddInt32("be:consumer", cons->ID()); notify.AddInt32("be:consumer", cons->ID());
if (mustConnect) if (mustConnect) {
{
notify.AddInt32("be:op", B_MIDI_CONNECTED); notify.AddInt32("be:op", B_MIDI_CONNECTED);
} } else {
else
{
notify.AddInt32("be:op", B_MIDI_DISCONNECTED); notify.AddInt32("be:op", B_MIDI_DISCONNECTED);
} }
watcher->SendMessage(&notify); fWatcher->SendMessage(&notify);
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::DisconnectDeadConsumer(BMidiConsumer* cons) void
BMidiRosterLooper::DisconnectDeadConsumer(BMidiConsumer* cons)
{ {
ASSERT(cons != NULL) ASSERT(cons != NULL)
@ -627,16 +544,12 @@ void BMidiRosterLooper::DisconnectDeadConsumer(BMidiConsumer* cons)
// of connected consumers, we let ConnectionBroken() tell // of connected consumers, we let ConnectionBroken() tell
// us whether the consumer really was connected. // us whether the consumer really was connected.
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
if (endp->IsProducer()) if (endp->IsProducer()) {
{
BMidiProducer* prod = (BMidiProducer*) endp; BMidiProducer* prod = (BMidiProducer*) endp;
if (prod->ConnectionBroken(cons)) if (prod->ConnectionBroken(cons)) {
{ if (cons->IsRemote() && (fWatcher != NULL)) {
if (cons->IsRemote() && (watcher != NULL))
{
ConnectionEvent(prod, cons, false); ConnectionEvent(prod, cons, false);
} }
} }
@ -644,9 +557,9 @@ void BMidiRosterLooper::DisconnectDeadConsumer(BMidiConsumer* cons)
} }
} }
//------------------------------------------------------------------------------
void BMidiRosterLooper::DisconnectDeadProducer(BMidiProducer* prod) void
BMidiRosterLooper::DisconnectDeadProducer(BMidiProducer* prod)
{ {
ASSERT(prod != NULL) ASSERT(prod != NULL)
@ -654,42 +567,38 @@ void BMidiRosterLooper::DisconnectDeadProducer(BMidiProducer* prod)
// the producer's list of connections, because when this // the producer's list of connections, because when this
// function is called, we're destroying the object. // function is called, we're destroying the object.
if (prod->IsRemote() && (watcher != NULL)) if (prod->IsRemote() && (fWatcher != NULL)) {
{ for (int32 t = 0; t < prod->CountConsumers(); ++t) {
for (int32 t = 0; t < prod->CountConsumers(); ++t)
{
ConnectionEvent(prod, prod->ConsumerAt(t), false); ConnectionEvent(prod, prod->ConsumerAt(t), false);
} }
} }
} }
//------------------------------------------------------------------------------
int32 BMidiRosterLooper::CountEndpoints() int32
BMidiRosterLooper::CountEndpoints()
{ {
return endpoints.CountItems(); return fEndpoints.CountItems();
} }
//------------------------------------------------------------------------------
BMidiEndpoint* BMidiRosterLooper::EndpointAt(int32 index) BMidiEndpoint*
BMidiRosterLooper::EndpointAt(int32 index)
{ {
ASSERT(index >= 0 && index < CountEndpoints()) ASSERT(index >= 0 && index < CountEndpoints())
return (BMidiEndpoint*) endpoints.ItemAt(index); return (BMidiEndpoint*) fEndpoints.ItemAt(index);
} }
//------------------------------------------------------------------------------
#ifdef DEBUG #ifdef DEBUG
void BMidiRosterLooper::DumpEndpoints() void
BMidiRosterLooper::DumpEndpoints()
{ {
if (Lock()) if (Lock()) {
{
printf("*** START DumpEndpoints\n"); printf("*** START DumpEndpoints\n");
for (int32 t = 0; t < CountEndpoints(); ++t) for (int32 t = 0; t < CountEndpoints(); ++t) {
{
BMidiEndpoint* endp = EndpointAt(t); BMidiEndpoint* endp = EndpointAt(t);
printf("\tendpoint %ld (%p):\n", t, endp); printf("\tendpoint %ld (%p):\n", t, endp);
@ -700,25 +609,20 @@ void BMidiRosterLooper::DumpEndpoints()
endp->IsConsumer() ? "consumer" : "producer", endp->IsConsumer() ? "consumer" : "producer",
endp->IsRegistered() ? "registered" : "unregistered", endp->IsRegistered() ? "registered" : "unregistered",
endp->IsLocal() ? "local" : "remote", endp->IsLocal() ? "local" : "remote",
endp->IsValid() ? "valid" : "invalid", endp->refCount); endp->IsValid() ? "valid" : "invalid", endp->fRefCount);
printf("\t\tproperties: "); printf("\t\tproperties: ");
endp->properties->PrintToStream(); endp->fProperties->PrintToStream();
if (endp->IsConsumer()) if (endp->IsConsumer()) {
{
BMidiConsumer* cons = (BMidiConsumer*) endp; BMidiConsumer* cons = (BMidiConsumer*) endp;
printf("\t\tport %ld, latency %Ld\n", printf("\t\tport %ld, latency %Ld\n",
cons->port, cons->latency); cons->fPort, cons->fLatency);
} } else {
else
{
BMidiProducer* prod = (BMidiProducer*) endp; BMidiProducer* prod = (BMidiProducer*) endp;
if (prod->LockProducer()) if (prod->LockProducer()) {
{
printf("\t\tconnections:\n"); printf("\t\tconnections:\n");
for (int32 k = 0; k < prod->CountConsumers(); ++k) for (int32 k = 0; k < prod->CountConsumers(); ++k) {
{
BMidiConsumer* cons = prod->ConsumerAt(k); BMidiConsumer* cons = prod->ConsumerAt(k);
printf("\t\t\tid %ld (%p)\n", cons->ID(), cons); printf("\t\t\tid %ld (%p)\n", cons->ID(), cons);
} }
@ -733,4 +637,3 @@ void BMidiRosterLooper::DumpEndpoints()
} }
#endif #endif
//------------------------------------------------------------------------------

View File

@ -1,23 +1,9 @@
/* /*
* Copyright (c) 2002-2004 Matthijs Hollemans * Copyright 2002-2006, Haiku.
* * Distributed under the terms of the MIT License.
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), * Authors:
* to deal in the Software without restriction, including without limitation * Matthijs Hollemans
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/ */
#ifndef MIDI_ROSTER_LOOPER_H #ifndef MIDI_ROSTER_LOOPER_H
@ -122,17 +108,17 @@ private:
int32 CountEndpoints(); int32 CountEndpoints();
BMidiEndpoint* EndpointAt(int32 index); BMidiEndpoint* EndpointAt(int32 index);
BMidiRoster* roster; BMidiRoster* fRoster;
// Makes sure BMidiRoster::MidiRoster() does not return // Makes sure BMidiRoster::MidiRoster() does not return
// until confirmation from the midi_server is received. // until confirmation from the midi_server is received.
sem_id initLock; sem_id fInitLock;
// The object we send B_MIDI_EVENT notifications to. // The object we send B_MIDI_EVENT notifications to.
BMessenger* watcher; BMessenger* fWatcher;
// All the endpoints in the system, local and remote. // All the endpoints in the system, local and remote.
BList endpoints; BList fEndpoints;
#ifdef DEBUG #ifdef DEBUG
void DumpEndpoints(); void DumpEndpoints();