Big docs cleanup.
* Fixed headers including: - All rights reserved not All Rights Reserved. - name, [email protected] not name <[email protected]> - tabs and spaces - Authors: not Documented by: * Renamed string.dox to String.dox * Renamed midixxx.dox files to MidiXxx.dox * Moved images into images subdirectories and updated Doxfile. * Re-format all files with tabs instead of spaces. * Fix many spelling mistakes. * Added all files, classes, structs, and enums to libbe group.
This commit is contained in:
+309
-245
@@ -1,280 +1,344 @@
|
||||
/*!
|
||||
\file Midi2Defs.h
|
||||
\brief Some definitions to define raw MIDI events.
|
||||
\ingroup midi2
|
||||
\file Midi2Defs.h
|
||||
\ingroup midi2
|
||||
\ingroup libbe
|
||||
\brief Some definitions to define raw MIDI events.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\name Channel Message Masks
|
||||
\brief Some definitions to define the raw MIDI events.
|
||||
\name Channel Message Masks
|
||||
\brief Some definitions to define the raw MIDI events.
|
||||
|
||||
The default implementation of BMidiLocalConsumer::Data() uses these constants
|
||||
to determine which event has been passed on. If you override that method, you
|
||||
may use the constants yourself.
|
||||
The default implementation of BMidiLocalConsumer::Data() uses these
|
||||
constants to determine which event has been passed on. If you override
|
||||
that method, you may use the constants yourself.
|
||||
*/
|
||||
|
||||
//! @{
|
||||
|
||||
/*!
|
||||
\var B_NOTE_OFF
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_NOTE_ON
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_KEY_PRESSURE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_CONTROL_CHANGE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_PROGRAM_CHANGE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_CHANNEL_PRESSURE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_PITCH_BEND
|
||||
*/
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
/*!
|
||||
\name System Messages
|
||||
\brief Some definitions to define the raw MIDI system messages.
|
||||
|
||||
The default implementation of BMidiLocalConsumer::Data() uses these constants
|
||||
to determine which event system message has been passed on. See
|
||||
BMidiLocalProducer::SpraySystemCommon() and BMidiLocalProducer::SpraySystemRealTime()
|
||||
for more details on how and when to use these messages.
|
||||
*/
|
||||
|
||||
//! @{
|
||||
|
||||
/*!
|
||||
\var B_SYS_EX_START
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_MIDI_TIME_CODE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SONG_POSITION
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SONG_SELECT
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_CABLE_MESSAGE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_TUNE_REQUEST
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SYS_EX_END
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_TIMING_CLOCK
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_START
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_CONTINUE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_STOP
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_ACTIVE_SENSING
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SYSTEM_RESET
|
||||
*/
|
||||
|
||||
//! @}
|
||||
|
||||
/*!
|
||||
\name Controller Numbers
|
||||
\brief Constants that represent specific controller messages.
|
||||
|
||||
These constants can be used in BMidiLocalProducer::SprayControlChange()
|
||||
and BMidiLocalConsumer::ControlChange(). These constants represent the
|
||||
MIDI specification.
|
||||
*/
|
||||
|
||||
//! @{
|
||||
|
||||
|
||||
/*!
|
||||
\var B_NOTE_OFF
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MODULATION
|
||||
\var B_NOTE_ON
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_BREATH_CONTROLLER
|
||||
\var B_KEY_PRESSURE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_FOOT_CONTROLLER
|
||||
\var B_CONTROL_CHANGE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_PORTAMENTO_TIME
|
||||
\var B_PROGRAM_CHANGE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_DATA_ENTRY
|
||||
\var B_CHANNEL_PRESSURE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MAIN_VOLUME
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_MIDI_BALANCE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_PAN
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_EXPRESSION_CTRL
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_1
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_3
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_4
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SUSTAIN_PEDAL
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_PORTAMENTO
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SOSTENUTO
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_SOFT_PEDAL
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_HOLD_2
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_5
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_6
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_TEMPO_CHANGE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_7
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_8
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_EFFECTS_DEPTH
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_TREMOLO_DEPTH
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_CHORUS_DEPTH
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_CELESTE_DEPTH
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_PHASER_DEPTH
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_DATA_INCREMENT
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_DATA_DECREMENT
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_RESET_ALL_CONTROLLERS
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_LOCAL_CONTROL
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_ALL_NOTES_OFF
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_OMNI_MODE_OFF
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_OMNI_MODE_ON
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_MONO_MODE_ON
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var B_POLY_MODE_ON
|
||||
\var B_PITCH_BEND
|
||||
*/
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
/*!
|
||||
\name System Messages
|
||||
\brief Some definitions to define the raw MIDI system messages.
|
||||
|
||||
The default implementation of BMidiLocalConsumer::Data() uses these
|
||||
constants to determine which event system message has been passed on.
|
||||
See BMidiLocalProducer::SpraySystemCommon() and
|
||||
BMidiLocalProducer::SpraySystemRealTime() for more details on how and
|
||||
when to use these messages.
|
||||
*/
|
||||
|
||||
|
||||
//! @{
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SYS_EX_START
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MIDI_TIME_CODE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SONG_POSITION
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SONG_SELECT
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_CABLE_MESSAGE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_TUNE_REQUEST
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SYS_EX_END
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_TIMING_CLOCK
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_START
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_CONTINUE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_STOP
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_ACTIVE_SENSING
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SYSTEM_RESET
|
||||
*/
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
/*!
|
||||
\name Controller Numbers
|
||||
\brief Constants that represent specific controller messages.
|
||||
|
||||
These constants can be used in BMidiLocalProducer::SprayControlChange()
|
||||
and BMidiLocalConsumer::ControlChange(). These constants represent the
|
||||
MIDI specification.
|
||||
*/
|
||||
|
||||
|
||||
//! @{
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MODULATION
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_BREATH_CONTROLLER
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_FOOT_CONTROLLER
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_PORTAMENTO_TIME
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_DATA_ENTRY
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MAIN_VOLUME
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MIDI_BALANCE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_PAN
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_EXPRESSION_CTRL
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_1
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_2
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_3
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_4
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SUSTAIN_PEDAL
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_PORTAMENTO
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SOSTENUTO
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_SOFT_PEDAL
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_HOLD_2
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_5
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_6
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_TEMPO_CHANGE
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_7
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_GENERAL_CTRL_8
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_EFFECTS_DEPTH
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_TREMOLO_DEPTH
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_CHORUS_DEPTH
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_CELESTE_DEPTH
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_PHASER_DEPTH
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_DATA_INCREMENT
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_DATA_DECREMENT
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_RESET_ALL_CONTROLLERS
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_LOCAL_CONTROL
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_ALL_NOTES_OFF
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_OMNI_MODE_OFF
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_OMNI_MODE_ON
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MONO_MODE_ON
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_POLY_MODE_ON
|
||||
*/
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/*!
|
||||
\file MidiConsumer.h
|
||||
\ingroup midi2
|
||||
\ingroup libbe
|
||||
\brief Defines consumer classes for the MIDI Kit.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\class BMidiConsumer MidiConsumer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\ingroup libbe
|
||||
\brief Receives MIDI events from a producer
|
||||
|
||||
A consumer is an object that knows how to deal with incoming MIDI events. A
|
||||
consumer can be connected to multiple producers at the same time. There is no
|
||||
way to find out which producers are connected to this consumer just by looking
|
||||
at the BMidiConsumer object; you will have to consult BMidiRoster for that.
|
||||
|
||||
A BMidiConsumer either represents a local consumer, i.e. a class extending from
|
||||
BMidiLocalConsumer, or is a proxy for a remote object published by another app.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bigtime_t BMidiConsumer::Latency() const
|
||||
\brief Returns the latency of this consumer
|
||||
|
||||
The latency is measured in microseconds. Producers should attempt to get MIDI
|
||||
events to this consumer by <I>(when - latency)</I>. You do this by subtracting
|
||||
the latency from the performance time when you spray the events (provided that
|
||||
you spray these events ahead of time, of course).
|
||||
|
||||
You cannot <I>set</I> the latency on a BMidiConsumer, only on a
|
||||
BMidiLocalConsumer.
|
||||
|
||||
The latency issue gets slightly more complicated when multiple endpoints are
|
||||
chained together, as in the following picture:
|
||||
|
||||
\verbatim
|
||||
+-------+ +-------------+ +-------+
|
||||
| | | | | |
|
||||
| prodA |---->| consB prodB |---->| consC |
|
||||
| | | | | |
|
||||
+-------+ +-------------+ +-------+
|
||||
appA appB (filter) appC
|
||||
\endverbatim
|
||||
|
||||
Suppose consC has 200ms latency, and consB has 100ms latency. If consB simply
|
||||
reports 100ms, then prodA will schedule its events for (t - 100), which is
|
||||
really 200ms too late. (Of course, producers send out their events as soon as
|
||||
possible, so depending on the load of the system, everything may work out just
|
||||
fine.)
|
||||
|
||||
ConsB should report the latency of the consumer that is hooked up to its
|
||||
output, consC, in addition to its own latency. In other words, the full
|
||||
downstream latency. So, the reported latency in this case would be 300ms. This
|
||||
also means that appB should change the latency of consB when prodB makes or
|
||||
breaks a connection, and when consC reports a latency change. (If multiple
|
||||
consumers are connected to prodB, you should take the slowest one.)
|
||||
Unfortunately, the Midi Kit provides no easy mechanism for doing any of this,
|
||||
so you are on your own here.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class BMidiLocalConsumer MidiConsumer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\ingroup libbe
|
||||
\brief A consumer endpoint that is created by your own application.
|
||||
|
||||
If you want to create a consumer that reacts to MIDI events, you should
|
||||
subclass BMidiLocalConsumer.
|
||||
|
||||
Each local consumer has its own thread that receives and dispatches the MIDI
|
||||
events. Whenever MIDI data arrives, the Data() hook passes the MIDI event on to
|
||||
a more specific hook function: NoteOn(), NoteOff(), SystemExclusive(), and so
|
||||
on. Calls to these hook functions are serialized -- they will never have to be
|
||||
re-entrant. They also should not be called from outside the thread that is
|
||||
invoking them.
|
||||
|
||||
Your subclass can override any of the MIDI event hooks. BMidiLocalConsumer
|
||||
doesn't provide default implementations for them, so you don't have to call a
|
||||
hook's default implementation if you override it. For complete control, you can
|
||||
also override Data().
|
||||
|
||||
Most hook functions take a channel argument. Even though MIDI channels are
|
||||
really numbered 1 through 16, the hook functions work with channels 0 through
|
||||
15. The performance time for the event is specified in microseconds relative to
|
||||
the system time base. A performance time that is 0 (or really any time in the
|
||||
past) means "play as soon as possible". See the \ref midi2time "introduction"
|
||||
for more information about timing and consumers.
|
||||
|
||||
The thread driving the consumer's events is a very high priority real time
|
||||
thread. Events should be handled as quickly as possible (not counting
|
||||
snoozing). If non-time-critical computation is needed it may be wise to queue
|
||||
events up for a lower priority thread to handle them external to the main event
|
||||
thread.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiLocalConsumer::BMidiLocalConsumer(const char *name = NULL)
|
||||
\brief Creates a new local consumer endpoint
|
||||
|
||||
The new endpoint is not visible to other applications until you Register() it.
|
||||
|
||||
You can tell the constructor what the name of the new consumer will be. If you
|
||||
pass NULL (or use the default argument), then the consumer's name will be an
|
||||
empty string. It won't be NULL, since endpoint names cannot be NULL.
|
||||
|
||||
There is no guarantee that the endpoint will be successfully created. For
|
||||
example, the Midi Server may not be running. Therefore, you should always call
|
||||
IsValid() after creating a new endpoint to make sure that everything went okay.
|
||||
If not, Release() the object to reclaim memory and abort gracefully.
|
||||
|
||||
\code
|
||||
MyConsumer* cons = new MyConsumer(...);
|
||||
if (!cons->IsValid())
|
||||
{
|
||||
cons->Release();
|
||||
...exit gracefully...
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SetLatency(bigtime_t latency)
|
||||
\brief Changes the published latency of the consumer.
|
||||
|
||||
\sa Latency()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn int32 BMidiLocalConsumer::GetProducerID()
|
||||
\brief Returns the ID of the producer that most recently sent a MIDI event to
|
||||
this consumer.
|
||||
|
||||
You can call this from one of the hooks to determine which producer the event
|
||||
came from.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SetTimeout(bigtime_t when, void* data)
|
||||
\brief Requests that the Timeout() hook will be called at some point.
|
||||
|
||||
This method asks the consumer thread to call the Timeout() hook as soon as
|
||||
possible after the timeout expires. For every call to SetTimeout(), the
|
||||
Timeout() hook is only called once. Note: the term "timeout" may be a little
|
||||
misleading; the hook will <I>always</I> be called, even if events are received
|
||||
in the mean time. Apparently, this facility is handy for dealing with early
|
||||
events.
|
||||
|
||||
Note that the event thread blocks on the consumer's port as long as no events
|
||||
arrive. By default no timeout is set, and as a result the thread blocks
|
||||
forever. Your call to SetTimeout() doesn't change this. The new timeout value
|
||||
will go into effect the next time the thread tries to read from the port, i.e.
|
||||
after the first event has been received. If no event ever comes in, the
|
||||
Timeout() hook will never be called. This also means that you cannot cancel a
|
||||
timeout once you have set it. To repeat, calling SetTimeout() only takes effect
|
||||
after at least one new event has been received.
|
||||
|
||||
\param when An absolute time that's measured against the system clock.
|
||||
|
||||
\param data A pointer to a "cookie" that you can pass along to Timeout(). The
|
||||
data is not copied, so you must ensure that the pointer remains valid until
|
||||
Timeout() is called. You typically delete the data inside Timeout().
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::Timeout(void* data)
|
||||
\brief Hook function that is called per your own request.
|
||||
|
||||
\sa SetTimeout()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::Data(uchar* data, size_t length, bool atomic,
|
||||
bigtime_t time)
|
||||
\brief Invoked when raw MIDI is received.
|
||||
|
||||
What the default implementation of Data() does depends on the value of atomic.
|
||||
If atomic is true, the data received comprises a single MIDI event; i.e. one
|
||||
status byte followed by the appropriate number of data bytes and nothing else.
|
||||
In this case, Data() calls the event-specific hook function that corresponds to
|
||||
that status byte. This optimization is used by the Midi Kit to allow faster
|
||||
dispatch of events generated by the specific Spray functions from
|
||||
BMidiLocalProducer.
|
||||
|
||||
If atomic is false, Data() ignores the MIDI event. If you want a consumer to
|
||||
handle non-atomic events, you have to override Data() and program this
|
||||
yourself. In that case, you probably also want to call the default
|
||||
implementation to handle the "normal" MIDI events.
|
||||
|
||||
Data() is rarely overridden, but you can override it if you want to. If you do,
|
||||
remember that the data buffer is owned by the Midi Kit. Do not attempt to
|
||||
modify or free it, lest you wish to be laughed at by other developers.
|
||||
|
||||
\param data the MIDI event data
|
||||
\param length byte size of the data buffer
|
||||
\param atomic whether the data buffer contains a single complete MIDI event
|
||||
\param time the requested performance time of the event
|
||||
|
||||
\sa BMidiLocalProducer::SprayData()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::NoteOff(uchar channel, uchar note,
|
||||
uchar velocity, bigtime_t time)
|
||||
\brief Invoked when a Note Off event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayNoteOff()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::NoteOn(uchar channel, uchar note,
|
||||
uchar velocity, bigtime_t time)
|
||||
\brief Invoked when a Note On event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayNoteOn()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::KeyPressure(uchar channel, uchar note,
|
||||
uchar pressure, bigtime_t time)
|
||||
\brief Invoked when a Polyphonic Pressure (Aftertouch) event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayKeyPressure()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::ControlChange(uchar channel,
|
||||
uchar controlNumber, uchar controlValue, bigtime_t time)
|
||||
\brief Invoked when a Controller Change event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayControlChange()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::ProgramChange(uchar channel,
|
||||
uchar programNumber, bigtime_t time)
|
||||
\brief Invoked when a Program Change event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayProgramChange()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::ChannelPressure(uchar channel,
|
||||
uchar pressure, bigtime_t time)
|
||||
\brief Invoked when a Channel Pressure event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayChannelPressure()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::PitchBend(uchar channel, uchar lsb,
|
||||
uchar msb, bigtime_t time)
|
||||
\brief Invoked when a Pitch Bend event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SprayPitchBend()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SystemExclusive(void* data, size_t length,
|
||||
bigtime_t time)
|
||||
\brief Invoked when a System Exclusive event is received.
|
||||
|
||||
The data does not include the sysex start and end control bytes
|
||||
(0xF0 and 0xF7), only the payload of the sysex message.
|
||||
|
||||
The data belongs to the Midi Kit and is only valid for the duration of
|
||||
this event. You may not modify or free it.
|
||||
|
||||
\sa BMidiLocalProducer::SpraySystemExclusive()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SystemCommon(uchar status, uchar data1,
|
||||
uchar data2, bigtime_t time)
|
||||
\brief Invoked when a System Common event is received.
|
||||
|
||||
Not all data bytes are used for all common events. Unused bytes are
|
||||
set to 0.
|
||||
|
||||
\sa BMidiLocalProducer::SpraySystemCommon()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SystemRealTime(uchar status, bigtime_t time)
|
||||
\brief Invoked when a Real Time event is received.
|
||||
|
||||
\sa BMidiLocalProducer::SpraySystemRealTime()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::TempoChange(int32 beatsPerMinute, bigtime_t time)
|
||||
|
||||
\brief Invoked when a Tempo Change event is received
|
||||
\sa BMidiLocalProducer::SprayTempoChange()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::AllNotesOff(bool justChannel, bigtime_t time)
|
||||
\brief Not used.
|
||||
*/
|
||||
@@ -0,0 +1,322 @@
|
||||
/*!
|
||||
\file MidiEndpoint.h
|
||||
\ingroup midi2
|
||||
\ingroup libbe
|
||||
\brief Defines the Baseclass of all MIDI consumers and producers.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\class BMidiEndpoint
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\ingroup libbe
|
||||
\brief Base class for all MIDI endpoints.
|
||||
|
||||
BMidiEndpoint is the abstract base class that represents either a
|
||||
producer or consumer endpoint. It may be used to obtain the state, name,
|
||||
properties, or system-wide ID of the object. BMidiEndpoint also provides
|
||||
the ability to change the name and properties of endpoints that were
|
||||
created locally.
|
||||
|
||||
Remember, you cannot call the destructor of BMidiEndpoint and its
|
||||
subclasses directly. Endpoint objects are destructed automatically when
|
||||
their reference count drops to zero. If necessary, the destructor of a
|
||||
local endpoint first breaks off any connections and Unregister()'s the
|
||||
endpoint before it is deleted. However, for good style and bonus points
|
||||
you should really \link BMidiProducer::Disconnect() Disconnect() \endlink
|
||||
and Unregister() the object yourself and not rely on the destructor to
|
||||
do this.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const char* BMidiEndpoint::Name() const
|
||||
\brief Returns the name of the endpoint.
|
||||
|
||||
The function never returns NULL. If you created a local endpoint by
|
||||
passing a \c NULL name into its constructor (or passing no name,
|
||||
which is the same thing), then Name() will return an empty string,
|
||||
not \c NULL.
|
||||
|
||||
\sa SetName()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiEndpoint::SetName(const char* name)
|
||||
\brief Changes the name of the endpoint.
|
||||
|
||||
Names don't have to be unique, but it is recommended that you give any
|
||||
endpoints you publish meaningful and unique names, so users can easily
|
||||
recognize what each endpoint does. There is no limit to the size of
|
||||
endpoint names.
|
||||
|
||||
Even though you can call this function on both remote and local objects,
|
||||
you are only allowed to change the names of local endpoints; SetName()
|
||||
calls on remote endpoints are ignored.
|
||||
|
||||
\param name The new name. If you pass \c NULL the name won't be changed.
|
||||
|
||||
\sa Name()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int32 BMidiEndpoint::ID() const
|
||||
\brief Returns the ID of the endpoint
|
||||
|
||||
An ID uniquely identifies an endpoint in the system. The ID is a signed
|
||||
32-bit number that is assigned by the Midi Server when the endpoint is
|
||||
created. (So even if a local endpoint is not published, it still has a
|
||||
unique ID.) Valid IDs range from 1 to 0x7FFFFFFF, the largest value an
|
||||
int32 can have. 0 and negative values are <b>not</b> valid IDs.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsProducer() const
|
||||
\brief Determines whether this endpoint is a BMidiProducer
|
||||
|
||||
If it is, you can use a dynamic_cast to convert this object into a
|
||||
producer:
|
||||
|
||||
\code
|
||||
if (endp->IsProducer())
|
||||
{
|
||||
BMidiProducer* prod = dynamic_cast<BMidiProducer*>(endp);
|
||||
|
||||
....
|
||||
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsConsumer() const
|
||||
\brief Determines whether this endpoint is a BMidiConsumer
|
||||
|
||||
If it is, you can use a dynamic_cast to convert this object into a consumer:
|
||||
|
||||
\code
|
||||
if (endp->IsConsumer())
|
||||
{
|
||||
BMidiConsumer* cons = dynamic_cast<BMidiConsumer*>(endp);
|
||||
|
||||
....
|
||||
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsRemote() const
|
||||
\brief Determines whether this endpoint is a proxy for a remote object.
|
||||
|
||||
An endpoint is "remote" when it is created by another application.
|
||||
Obviously, the remote object is Register()'ed as well, otherwise you would
|
||||
not be able to see it.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsLocal() const
|
||||
\brief Determines whether this endpoint represents a local object
|
||||
|
||||
An endpoint is "local" when it is created by this application; in other
|
||||
words, a BMidiLocalConsumer or BMidiLocalProducer.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsPersistent() const
|
||||
\brief Not used.
|
||||
|
||||
The purpose of this function is unclear, and as a result it doesn't do
|
||||
anything in the Haiku Midi Kit implementation.
|
||||
|
||||
\return \c false always.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsValid() const
|
||||
\brief Determines whether the endpoint still exists.
|
||||
|
||||
Suppose you obtained a proxy object for a remote endpoint by querying the
|
||||
BMidiRoster. What if the application that published this endpoint quits,
|
||||
or less drastically, Unregister()'s that endpoint? Even though you still
|
||||
have a BMidiEndpoint proxy object, the real endpoint no longer exists.
|
||||
You can use IsValid() to check for this.
|
||||
|
||||
Don't worry, operations on invalid objects, such as GetProperties(), will
|
||||
return an error code (typically B_ERROR), but not cause a crash. Local
|
||||
objects are always are considered to be valid, even if you did not
|
||||
Register() them. (The only time a local endpoint is not valid is when there
|
||||
was a problem constructing it.)
|
||||
|
||||
If the application that created the remote endpoint crashes, then there is
|
||||
no guarantee that the Midi Server immediately recognizes this. In that
|
||||
case, IsValid() may still return true. Eventually, the stale endpoint will
|
||||
be removed from the roster, though. From then on, IsValid() correctly
|
||||
returns \c false.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Acquire()
|
||||
\brief Increments the endpoint's reference count
|
||||
|
||||
Each BMidiEndpoint has a reference count associated with it, so that
|
||||
BMidiRoster can do proper bookkeeping. Acquire() increments this reference
|
||||
count, and Release() decrements it. Once the count reaches zero, the
|
||||
endpoint is deleted.
|
||||
|
||||
When you are done with the endpoint, whether local or remote, you should
|
||||
always Release() it!
|
||||
|
||||
Upon construction, local endpoints start with a reference count of 1. Any
|
||||
objects you obtain from BMidiRoster using the NextXXX() or FindXXX()
|
||||
functions have their reference counts incremented in the process. If you
|
||||
forget to call Release(), the objects won't be properly cleaned up and
|
||||
you'll make a fool out of yourself.
|
||||
|
||||
After you Release() an object, you are advised not to use it any further.
|
||||
If you do, your app will probably crash. That also happens if you Release()
|
||||
an object too many times.
|
||||
|
||||
Typically, you don't need to call Acquire(), unless you have two disparate
|
||||
parts of your application working with the same endpoint, and you don't
|
||||
want to have to keep track of who needs to Release() the endpoint. Now you
|
||||
simply have both of them release it.
|
||||
|
||||
\return Always returns B_OK
|
||||
|
||||
\sa Release()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Release()
|
||||
\brief Decrements the endpoint's reference count.
|
||||
|
||||
\return Always returns B_OK
|
||||
|
||||
\sa Acquire()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Register()
|
||||
\brief Publishes the endpoint on the roster
|
||||
|
||||
MIDI objects created by an application are invisible to other applications
|
||||
until they are published. To publish an object use the Register() method.
|
||||
The corresponding Unregister() method will cause an object to once again
|
||||
become invisible to remote applications.
|
||||
|
||||
BMidiRoster also has Register() and Unregister() methods. You may also use
|
||||
those methods to publish or hide your endpoints; both do the same thing.
|
||||
|
||||
Although it is considered bad style, calling Register() on local endpoints
|
||||
that are already registered won't mess things up. The Midi Server will
|
||||
simply ignore your request. Likewise for Unregister()'ing more than once.
|
||||
Attempts to Register() or Unregister() remote endpoints will fail, of
|
||||
course.
|
||||
|
||||
If you are \link BMidiRoster::StartWatching() watching \endlink, you will
|
||||
<b>not</b> receive notifications for any local endpoints you register or
|
||||
unregister. Of course, other applications <I>will</I> be notified about
|
||||
your endpoints.
|
||||
|
||||
Existing connections will not be broken when an object is unregistered,
|
||||
but future remote connections will be denied. When objects are destroyed,
|
||||
they automatically become unregistered.
|
||||
|
||||
\returns B_OK on success, or an error code (typically \c B_ERROR) if
|
||||
something went wrong.
|
||||
|
||||
\sa Unregister()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Unregister()
|
||||
\brief Hides the endpoint from the roster/
|
||||
|
||||
\sa Register()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::SetProperties(const BMessage* props)
|
||||
\brief Changes the properties of the endpoint
|
||||
|
||||
Endpoints can have properties, which is any kind of information that
|
||||
might be useful to associate with a MIDI object. The properties are
|
||||
stored in a BMessage.
|
||||
|
||||
Usage example:
|
||||
|
||||
\code
|
||||
BMessage props;
|
||||
if (endpoint->GetProperties(&props) == B_OK)
|
||||
{
|
||||
...add data to the message...
|
||||
endpoint->SetProperties(&props);
|
||||
}
|
||||
\endcode
|
||||
|
||||
You are only allowed to call SetProperties() on a local object.
|
||||
|
||||
Properties should follow a protocol, so different applications will know
|
||||
how to read each other's properties. The current protocol is very limited
|
||||
-- it only allows you to associate icons with your endpoints. Be planned
|
||||
to publish a more complete protocol that included additional information,
|
||||
such as vendor/model names, copyright/version info, category, etc., but
|
||||
they never got around to it.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>property</TD><TD>Vector icon (raw data)</TD></TR>
|
||||
<TR><TD>field name</TD><TD>"icon"</TD></TR>
|
||||
<TR><TD>field type</TD><TD>'VICN'</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
This vector icon is available under Haiku only, and comes as raw data,
|
||||
not a BBitmap. Before being able to display it, you first must render
|
||||
the vector icon in the size of your choice.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>property</TD><TD>Large (32x32) icon</TD></TR>
|
||||
<TR><TD>field name</TD><TD>"be:large_icon"</TD></TR>
|
||||
<TR><TD>field type</TD><TD>'ICON'</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>property</TD><TD>Small (16x16) icon</TD></TR>
|
||||
<TR><TD>field name</TD><TD>"be:mini_icon"</TD></TR>
|
||||
<TR><TD>field type</TD><TD>'MICN'</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
The MidiUtil package (downloadable from the OpenBeOS website) contains a
|
||||
number of convenient functions to associate icons with endpoints, so you
|
||||
don't have to write that code all over again.
|
||||
|
||||
\sa GetProperties()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::GetProperties(BMessage* props) const
|
||||
\brief Reads the properties of the endpoint
|
||||
|
||||
Usage example:
|
||||
|
||||
\code
|
||||
BMessage props;
|
||||
if (endpoint->GetProperties(&props) == B_OK)
|
||||
{
|
||||
...examine the contents of the message...
|
||||
}
|
||||
\endcode
|
||||
|
||||
Note that GetProperties() overwrites the contents of your BMessage.
|
||||
|
||||
\sa SetProperties()
|
||||
*/
|
||||
@@ -0,0 +1,359 @@
|
||||
/*!
|
||||
\file MidiProducer.h
|
||||
\ingroup midi2
|
||||
\ingroup libbe
|
||||
\brief Defines producer classes for the MIDI Kit.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\class BMidiProducer MidiProducer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\ingroup libbe
|
||||
\brief Streams MIDI events to connected consumers.
|
||||
|
||||
A producer is an object that generate a stream of MIDI events. Each
|
||||
producer has a list of BMidiConsumer objects to which it is connected,
|
||||
and may be asked to connect to or disconnect from a BMidiConsumer. A
|
||||
producer can spray its events to multiple consumers at the same time.
|
||||
A BMidiProducer either represents a local producer, i.e. a class extending
|
||||
from BMidiLocalProducer, or is a proxy for a remote object published by
|
||||
another app.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiProducer::Connect(BMidiConsumer* cons)
|
||||
\brief Connects a consumer to this producer.
|
||||
|
||||
Establishes a connection between this producer and the specified consumer
|
||||
endpoint. From now on, any events that this producer sprays will be sent
|
||||
to that consumer. You may connect multiple consumers to a producer.
|
||||
|
||||
\return B_OK on success, or an error code when the connection could not be
|
||||
established. If the consumer is a proxy for a remote object and that
|
||||
object no longer exists, Connect() returns B_ERROR. It also returns
|
||||
\c B_ERROR if you try to connect the same producer and consumer more
|
||||
than once.
|
||||
|
||||
\sa Disconnect()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiProducer::Disconnect(BMidiConsumer* cons)
|
||||
\brief Disconnects a consumer from this producer.
|
||||
|
||||
Terminates the connection between this producer and the specified consumer
|
||||
endpoint. From now on, any events that this producer sprays no longer go
|
||||
to that consumer.
|
||||
|
||||
\return B_OK on success, or an error code if there was no connection to break
|
||||
\sa Connect()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn bool BMidiProducer::IsConnected(BMidiConsumer* cons) const
|
||||
\brief Determines whether a consumer is connected to this producer.
|
||||
|
||||
\sa Connect()
|
||||
\sa Disconnect()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BList* BMidiProducer::Connections() const
|
||||
\brief Returns a list with all connected consumers.
|
||||
|
||||
Returns a BList with pointers to BMidiEndpoint objects for all consumers
|
||||
that are connected to this producer. You can examine the contents of the
|
||||
list as follows:
|
||||
\code
|
||||
BList* list = prod->Connections();
|
||||
for (int32 t = 0; t < list->CountItems(); ++t)
|
||||
{
|
||||
BMidiEndpoint* endp = (BMidiEndpoint*) list->ItemAt(t);
|
||||
...do stuff...
|
||||
endp->Release(); // yes, here too!
|
||||
}
|
||||
delete list;
|
||||
\endcode
|
||||
Every time you call this function, a new BList is allocated. The caller
|
||||
(that is you) is responsible for freeing this list. The BMidiEndpoint
|
||||
objects in the list have their reference counts bumped, so you need to
|
||||
Release() them before you delete the list or they will go all leaky on
|
||||
you.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\class BMidiLocalProducer MidiProducer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\ingroup libbe
|
||||
\brief A producer endpoint that is created by your own application.
|
||||
|
||||
You create a BMidiLocalProducer if you want your application to send MIDI
|
||||
events. You use the various spray functions to send events to all connected
|
||||
consumers. If no consumers are connected to the producer, any calls to the
|
||||
spray functions are ignored.
|
||||
|
||||
Most spray functions accept a channel argument. Even though MIDI channels are
|
||||
really numbered 1 through 16, the spray functions work with channels 0 through
|
||||
15. You can also specify the performance time for the event using the time
|
||||
argument. Specify 0 (or any time in the past) to perform the event "now", i.e.
|
||||
as soon as possible. You can also schedule events to be performed in the
|
||||
future, by passing a time such as system_time() + 5000000, which means 5
|
||||
seconds from now.
|
||||
|
||||
Unlike BMidiLocalConsumer, which should be subclassed almost always, you hardly
|
||||
ever need to derive a class from BMidiLocalProducer. The only reason for
|
||||
subclassing is when you need to know when the producer gets connected or
|
||||
disconnected.
|
||||
|
||||
Also unlike consumers, local producers have no thread of control directly
|
||||
associated with them. If you want to send out the MIDI events from a different
|
||||
thread, you will have to create one yourself.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiLocalProducer::BMidiLocalProducer(const char *name = NULL)
|
||||
\brief Creates a new local producer endpoint.
|
||||
|
||||
The new endpoint is not visible to other applications until you Register() it.
|
||||
You can tell the constructor what the name of the new producer will be. If you
|
||||
pass NULL (or use the default argument), then the producer's name will be an
|
||||
empty string. It won't be NULL, since endpoint names cannot be NULL.
|
||||
There is no guarantee that the endpoint will be successfully created. For
|
||||
example, the Midi Server may not be running. Therefore, you should always call
|
||||
IsValid() after creating a new endpoint to make sure that everything went okay.
|
||||
If not, Release() the object to reclaim memory and abort gracefully.
|
||||
\code
|
||||
BMidiLocalProducer* prod = new BMidiLocalProducer(...);
|
||||
if (!prod->IsValid())
|
||||
{
|
||||
prod->Release();
|
||||
...exit gracefully...
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::Connected(BMidiConsumer* cons)
|
||||
\brief Invoked when a new consumer is connected to this producer
|
||||
|
||||
Although typical notifications (i.e. from BMidiRoster's "watching" facility)
|
||||
are only sent if it is some other app that is performing the operation,
|
||||
Connected() is also called if you are making the connection yourself.
|
||||
If you override this hook, you don't have to call the default implementation,
|
||||
because that does nothing.
|
||||
|
||||
\param cons The newly connected consumer. The reference count of the
|
||||
consumer object is not increased, so you should not Release() it.
|
||||
However, if you want to keep track of the consumer beyond this
|
||||
function, you should first Acquire() it, and Release() it when you
|
||||
are done.
|
||||
|
||||
\sa Disconnected()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::Disconnected(BMidiConsumer* cons)
|
||||
\brief Invoked when a consumer is disconnected from this producer.
|
||||
|
||||
\sa Connected()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayData(void* data, size_t length,
|
||||
bool atomic = false, bigtime_t time = 0) const
|
||||
\brief Sends raw MIDI data downstream to all connected consumers.
|
||||
|
||||
Typically you won't have to call SprayData(); the other spray functions
|
||||
will do just fine. If you do call it, remember that you retain ownership
|
||||
of the data and that you are responsible for freeing it at some point.
|
||||
(Even though data is not declared const, the function does not change it.)
|
||||
With atomic set to false, you can send a MIDI message in segments (perhaps
|
||||
for a large sysex dump). However, when you do this, you are on your own.
|
||||
The Midi Kit only tags the data as being non-atomic, but offers no]
|
||||
additional support.
|
||||
|
||||
The default implementation of BMidiLocalConsumer completely ignores such
|
||||
events. To handle non-atomic MIDI data, you should override the
|
||||
BMidiLocalConsumer::Data() hook and process the MIDI event yourself. All of
|
||||
BMidiLocalProducer's other spray functions always send atomic data.
|
||||
|
||||
\param data the MIDI event data.
|
||||
\param length byte size of the data buffer.
|
||||
\param atomic whether the data buffer contains a single complete
|
||||
MIDI event.
|
||||
\param time the required performance time of the event.
|
||||
|
||||
\sa BMidiLocalConsumer::Data()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayNoteOff(uchar channel, uchar note,
|
||||
uchar velocity, bigtime_t time = 0) const
|
||||
\brief Sends a Note Off event to all connected consumers.
|
||||
|
||||
\sa BMidiLocalConsumer::NoteOff()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayNoteOn(uchar channel, uchar note,
|
||||
uchar velocity, bigtime_t time = 0) const
|
||||
\brief Sends a Note On event to all connected consumers.
|
||||
|
||||
\sa BMidiLocalConsumer::NoteOn()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayKeyPressure(uchar channel, uchar note,
|
||||
uchar pressure, bigtime_t time = 0) const
|
||||
\brief Sends a Polyphonic Pressure (Aftertouch) event to all connected
|
||||
consumers.
|
||||
|
||||
\sa BMidiLocalConsumer::KeyPressure()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayControlChange(uchar channel,
|
||||
uchar controlNumber, uchar controlValue, bigtime_t time = 0) const
|
||||
\brief Sends a Controller Change event to all connected consumers.
|
||||
|
||||
\sa Midi2Defs.h
|
||||
\sa BMidiLocalConsumer::ControlChange()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayProgramChange(uchar channel,
|
||||
uchar programNumber, bigtime_t time = 0) const
|
||||
\brief Sends a Program Change event to all connected consumers.
|
||||
|
||||
\sa BMidiLocalConsumer::ProgramChange()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayChannelPressure(uchar channel,
|
||||
uchar pressure, bigtime_t time = 0) const
|
||||
\brief Sends a Channel Pressure event to all connected consumers.
|
||||
|
||||
\sa BMidiLocalConsumer::ChannelPressure()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayPitchBend(uchar channel, uchar lsb,
|
||||
uchar msb, bigtime_t time = 0) const
|
||||
\brief Sends a Pitch Bend event to all connected consumers.
|
||||
|
||||
\sa BMidiLocalConsumer::PitchBend()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SpraySystemExclusive(void* data,
|
||||
size_t length, bigtime_t time = 0) const
|
||||
\brief Sends a System Exclusive event to all connected consumers.
|
||||
|
||||
You retain ownership of the data and are responsible for freeing it. Even
|
||||
though data is not declared const, the function does not change it. Even
|
||||
though the amount of data may be quite large, this function always sends
|
||||
sysex messages as an atomic block of data.
|
||||
|
||||
\sa BMidiLocalConsumer::SystemExclusive()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SpraySystemCommon(uchar status,\
|
||||
uchar data1, uchar data2, bigtime_t time = 0) const
|
||||
\brief Sends a System Common event to the connected consumers.
|
||||
|
||||
The status byte must be one of the following:
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>0xF1</td>
|
||||
<td>\c B_MIDI_TIME_CODE</td>
|
||||
<td>data1 only</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0xF2</td>
|
||||
<td>\c B_SONG_POSITION</td>
|
||||
<td>data1 and data2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0xF3</td>
|
||||
<td>\c B_SONG_SELECT</td>
|
||||
<td>data1 only</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0xF5</td>
|
||||
<td>\c B_CABLE_MESSAGE</td>
|
||||
<td>data1 only</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0xF6</td>
|
||||
<td>\c B_TUNE_REQUEST</td>
|
||||
<td>no data</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0xF7</td>
|
||||
<td>\c B_SYS_EX_END</td>
|
||||
<td>no data</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
\sa BMidiLocalConsumer::SystemCommon()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SpraySystemRealTime(uchar status,
|
||||
bigtime_t time = 0) const
|
||||
\brief Sends a Real Time event to the connected consumers.
|
||||
|
||||
The status byte must be one of the following:
|
||||
<table border="1">
|
||||
<tr><td>0xf8</td><td>\c B_TIMING_CLOCK</td></tr>
|
||||
<tr><td>0xfa</td><td>\c B_START</td></tr>
|
||||
<tr><td>0xfb</td><td>\c B_CONTINUE</td></tr>
|
||||
<tr><td>0xfc</td><td>\c B_STOP</td></tr>
|
||||
<tr><td>0xfe</td><td>\c B_ACTIVE_SENSING</td></tr>
|
||||
<tr><td>0xff</td><td>\c B_SYSTEM_RESET</td></tr>
|
||||
</table>
|
||||
|
||||
Because of their high priority, the MIDI specification allows real time
|
||||
messages to "interleave" with other MIDI messages. A large sysex dump, for
|
||||
example, may be interrupted by a real time event. The Midi Kit, however,
|
||||
doesn't care. If you (or another producer) have just sent a big system
|
||||
exclusive to a consumer, any following real time message will simply have
|
||||
to wait until the consumer has dealt with the sysex.
|
||||
|
||||
\sa BMidiLocalConsumer::SystemRealTime()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayTempoChange(int32 bpm,
|
||||
bigtime_t time = 0) const
|
||||
\brief Sends a Tempo Change event to the connected consumers.
|
||||
|
||||
This kind of Tempo Change event is not really part of the MIDI spec,
|
||||
rather it is an extension from the SMF (Standard MIDI File) format.
|
||||
|
||||
\sa BMidiLocalConsumer::TempoChange()
|
||||
*/
|
||||
@@ -0,0 +1,418 @@
|
||||
/*!
|
||||
\file MidiRoster.h
|
||||
\ingroup midi2
|
||||
\ingroup libbe
|
||||
\brief Defines the heart of the MIDI Kit: the MIDI Roster.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\enum BMidiOp
|
||||
\ingroup midi2
|
||||
\ingroup libbe
|
||||
\brief Defines the status codes for MIDI Server notification messages.
|
||||
|
||||
These codes are used when you request notification as in
|
||||
BMidiRoster::StartWatching(). Check against these codes to determine what
|
||||
is happening. See the StartWatching() method for a more complete
|
||||
description of the codes and their meaning.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\var B_MIDI_EVENT
|
||||
\brief BMessage identifier of MIDI messages.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\class BMidiRoster MidiRoster.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\ingroup libbe
|
||||
\brief Interface to the system-wide Midi Roster.
|
||||
|
||||
BMidiRoster allows you to find available MIDI consumer and producer
|
||||
objects. You can locate these objects using the iterative NextEndpoint(),
|
||||
NextProducer(), and NextConsumer() methods or by requesting notification
|
||||
messages to be sent with StartWatching(). Notification messages may
|
||||
contain object IDs which can be resolved using the FindEndpoint(),
|
||||
FindProducer(), and FindConsumer() methods.
|
||||
|
||||
The constructor and destructor of BMidiRoster are private, which means
|
||||
that you cannot create or delete your own BMidiRoster objects. Every
|
||||
application can have only one instance of BMidiRoster, which is
|
||||
automatically created the very first time you use a Midi Kit function.
|
||||
You can call BMidiRoster's functions like this:
|
||||
\code
|
||||
producer = BMidiRoster::FindProducer(someID);
|
||||
\endcode
|
||||
Or using the slightly more annoying:
|
||||
\code
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (roster != NULL)
|
||||
{
|
||||
producer = roster->FindProducer(someID);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiEndpoint* BMidiRoster::NextEndpoint(int32* id)
|
||||
\brief Returns the next endpoint from the roster
|
||||
|
||||
The "next endpoint" means: the endpoint with the ID that follows \a id.
|
||||
So if you set id to 3, the first possible endpoint it returns is
|
||||
endpoint 4. No endpoint can have ID 0, so passing 0 gives you the first
|
||||
endpoint. If you pass \c NULL instead of an ID, NextEndpoint() always
|
||||
returns \c NULL. When the function returns, it sets \a id to the ID of the
|
||||
endpoint that was found. If no more endpoints exist, NextEndpoint()
|
||||
returns \c NULL and id is not changed. NextEndpoint() does <b>not</b>
|
||||
return locally created endpoints, even if they are Register()'ed.
|
||||
|
||||
Usage example:
|
||||
\code
|
||||
int32 id = 0;
|
||||
BMidiEndpoint* endp;
|
||||
while ((endp = BMidiRoster::NextEndpoint(&id)) != NULL)
|
||||
{
|
||||
... do something with endpoint ...
|
||||
endp->Release(); // don't forget!
|
||||
}
|
||||
\endcode
|
||||
Remember that NextEndpoint() bumps the endpoint's reference count, so you
|
||||
should always \link BMidiEndpoint::Release() Release() \endlink it when
|
||||
you are done.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiProducer* BMidiRoster::NextProducer(int32* id)
|
||||
\brief Returns the next producer from the roster.
|
||||
|
||||
Like NextEndpoint(), but only returns producer endpoints.
|
||||
|
||||
\sa NextConsumer
|
||||
\sa NextEndpoint
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiConsumer* BMidiRoster::NextConsumer(int32* id)
|
||||
\brief Returns the next consumer from the roster.
|
||||
|
||||
Like NextEndpoint(), but only returns consumer endpoints.
|
||||
|
||||
\sa NextProducer
|
||||
\sa NextEndpoint
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiEndpoint* BMidiRoster::FindEndpoint(int32 id,
|
||||
bool localOnly = false)
|
||||
\brief Returns the endpoint with the specified \a id.
|
||||
|
||||
FindEndpoint() will always find <b>any</b> local endpoints created by this
|
||||
application; they do not have to be published with Register() first. If
|
||||
localOnly is false, FindEndpoint() also looks at remote endpoints,
|
||||
otherwise only local endpoints will be resolved. Returns NULL if no such
|
||||
endpoint could be found.
|
||||
|
||||
You should use a dynamic_cast to convert the BMidiEndpoint into a producer
|
||||
or consumer:
|
||||
\code
|
||||
BMidiEndpoint* endp = ...;
|
||||
BMidiProducer* prod = NULL;
|
||||
BMidiConsumer* cons = NULL;
|
||||
if (endp->IsProducer())
|
||||
{
|
||||
prod = dynamic_cast<BMidiProducer*>(endp);
|
||||
}
|
||||
else if (endp->IsConsumer())
|
||||
{
|
||||
cons = dynamic_cast<BMidiConsumer*>(endp);
|
||||
}
|
||||
\endcode
|
||||
|
||||
Remember that FindEndpoint() increments the endpoint's reference count,
|
||||
so you should always \link BMidiEndpoint::Release() Release() \endlink
|
||||
an endpoint when you are done with it:
|
||||
\code
|
||||
BMidiEndpoint* endp = BMidiRoster::FindEndpoint(someID);
|
||||
if (endp != NULL)
|
||||
{
|
||||
...do stuff with the endpoint...
|
||||
endp->Release();
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiProducer* BMidiRoster::FindProducer(int32 id,
|
||||
bool localOnly = false)
|
||||
\brief Finds the producer with the specified \a id.
|
||||
|
||||
Like FindEndpoint(), but only looks for producer endpoints. Returns
|
||||
\c NULL if no endpoint with that ID exists, or if that endpoint is not
|
||||
a producer.
|
||||
|
||||
\sa FindConsumer
|
||||
\sa FindEndpoint
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiConsumer* BMidiRoster::FindConsumer(int32 id,
|
||||
bool localOnly = false)
|
||||
\brief Finds the consumer with the specified \a id.
|
||||
|
||||
Like FindEndpoint(), but only looks for consumer endpoints. Returns
|
||||
\c NULL if no endpoint with that ID exists, or if that endpoint is not
|
||||
a consumer.
|
||||
|
||||
\sa FindProducer
|
||||
\sa FindEndpoint
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiRoster::StartWatching(const BMessenger* msngr)
|
||||
\brief Start receiving notifications from the Midi Roster
|
||||
|
||||
When you start watching, BMidiRoster sends you notifications for all
|
||||
currently \b published \c remote endpoints, and all the current
|
||||
connections between them. (At this point, BMidiRoster does not let you
|
||||
know about connections between unpublished endpoints, nor does it tell
|
||||
you anything about your local endpoints, even though they may be
|
||||
published.)
|
||||
|
||||
Thereafter, you'll receive notifications any time something important
|
||||
happens to an object. The application that performs these operations is
|
||||
itself not notified. The assumption here is that you already know about
|
||||
these changes, because you are the one that is performing them.
|
||||
|
||||
The notifications are BMessages with code B_MIDI_EVENT. You specify the
|
||||
BMessenger that will be used to send these messages. Each message contains
|
||||
a field called be:op that describes the type of notification.
|
||||
|
||||
The "registered" and "unregistered" notifications are sent when a remote
|
||||
endpoint Register()'s or Unregister()'s, respectively. You don't receive
|
||||
these notifications when you register or unregister your local endpoints,
|
||||
but the other apps will.
|
||||
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>int32</td>
|
||||
<td>\c B_MIDI_REGISTERED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:id</td>
|
||||
<td>int32</td>
|
||||
<td>id of the endpoint</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:type</td>
|
||||
<td>string</td>
|
||||
<td>"producer" or "consumer"</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>int32</td>
|
||||
<td>\c B_MIDI_UNREGISTERED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:id</td>
|
||||
<td>int32</td>
|
||||
<td>id of the endpoint</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:type</td>
|
||||
<td>string</td>
|
||||
<td>"producer" or "consumer"</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The "connected" and "disconnected" notifications are sent when a consumer
|
||||
\link BMidiProducer::Connect() Connect()\endlink's to a producer, or when
|
||||
they \link BMidiProducer::Disconnect() Disconnect() \endlink. You will
|
||||
receive these notifications when \b any two endpoints connect or
|
||||
disconnect, even if they are not published. (The purpose of which is
|
||||
debatable.) You won't receive the notifications if you are the one making
|
||||
the connection, even if both endpoints are remote. You \b will be notified
|
||||
when another app connects one of your published endpoints.
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>\c int32</td>
|
||||
<td>\c B_MIDI_CONNECTED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:producer</td>
|
||||
<td>\c int32</td>
|
||||
<td>id of the connector</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:consumer</td>
|
||||
<td>\c int32</td>
|
||||
<td>id of the connectee</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>\c int32</td>
|
||||
<td>\c B_MIDI_DISCONNECTED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:producer</td>
|
||||
<td>\c int32</td>
|
||||
<td>id of the connector</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:consumer</td>
|
||||
<td>int32</td>
|
||||
<td>id of the connectee</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
the following notifications are sent when an endpoint's attributes are
|
||||
changed. you receive these notifications only if another application is
|
||||
changing one of its published endpoints.
|
||||
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>\c int32</td>
|
||||
<td>\c B_MIDI_CHANGED_NAME</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:id</td>
|
||||
<td>\c int32</td>
|
||||
<td>id of the endpoint</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:type</td>
|
||||
<td>string</td>
|
||||
<td>"producer" or "consumer"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:name</td>
|
||||
<td>string</td>
|
||||
<td>the endpoint's new name</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>\c int32</td>
|
||||
<td>\c B_MIDI_CHANGED_LATENCY</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:id</td>
|
||||
<td>\c int32</td>
|
||||
<td>id of the endpoint</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:type</td>
|
||||
<td>string</td>
|
||||
<td>"producer" or "consumer"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:latency</td>
|
||||
<td>int64</td>
|
||||
<td>the new latency (microseconds)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>be:op</td>
|
||||
<td>int32</td>
|
||||
<td>\c B_MIDI_CHANGED_PROPERTIES</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:id</td>
|
||||
<td>\c int32</td>
|
||||
<td>id of the endpoint</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:type</td>
|
||||
<td>string</td>
|
||||
<td>"producer" or "consumer"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>be:properties</td>
|
||||
<td>bmessage</td>
|
||||
<td>the new properties</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Typical usage example:
|
||||
|
||||
\code
|
||||
void MyView::AttachedToWindow()
|
||||
{
|
||||
BMessenger msgr(this);
|
||||
BMidiRoster::StartWatching(&msgr);
|
||||
}
|
||||
void MyView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case B_MIDI_EVENT:
|
||||
HandleMidiEvent(msg);
|
||||
break;
|
||||
default:
|
||||
super::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
For the possible midi options, see #BMidiOp
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void BMidiRoster::StopWatching()
|
||||
\brief Stop receiving notifications from the Midi Roster.
|
||||
|
||||
\sa StartWatching()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiRoster::Register(BMidiEndpoint* object)
|
||||
\brief Publishes an endpoint to other applications.
|
||||
|
||||
Calls BMidiEndpoint's \link BMidiEndpoint::Register() Register() \endlink
|
||||
method to publish an endpoint, which makes it visible to other
|
||||
applications.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiRoster::Unregister(BMidiEndpoint* object)
|
||||
\brief Hides an endpoint from other applications.
|
||||
|
||||
Calls BMidiEndpoint's
|
||||
\link BMidiEndpoint::Unregister() Unregister() \endlink method to hide
|
||||
a previously published endpoint from other applications.
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn BMidiRoster* BMidiRoster::MidiRoster()
|
||||
\brief Returns a pointer to the only instance of BMidiRoster.
|
||||
|
||||
There is no real reason use this function, since all BMidiRoster's public
|
||||
function are static.
|
||||
*/
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
@@ -1,291 +0,0 @@
|
||||
/*!
|
||||
\class BMidiConsumer MidiConsumer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\brief Receives MIDI events from a producer
|
||||
|
||||
A consumer is an object that knows how to deal with incoming MIDI events. A
|
||||
consumer can be connected to multiple producers at the same time. There is no
|
||||
way to find out which producers are connected to this consumer just by looking
|
||||
at the BMidiConsumer object; you will have to consult BMidiRoster for that.
|
||||
|
||||
A BMidiConsumer either represents a local consumer, i.e. a class extending from
|
||||
BMidiLocalConsumer, or is a proxy for a remote object published by another app.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bigtime_t BMidiConsumer::Latency() const
|
||||
\brief Returns the latency of this consumer
|
||||
|
||||
The latency is measured in microseconds. Producers should attempt to get MIDI
|
||||
events to this consumer by <I>(when - latency)</I>. You do this by subtracting
|
||||
the latency from the performance time when you spray the events (provided that
|
||||
you spray these events ahead of time, of course).
|
||||
|
||||
You cannot <I>set</I> the latency on a BMidiConsumer, only on a
|
||||
BMidiLocalConsumer.
|
||||
|
||||
The latency issue gets slightly more complicated when multiple endpoints are
|
||||
chained together, as in the following picture:
|
||||
|
||||
\verbatim
|
||||
+-------+ +-------------+ +-------+
|
||||
| | | | | |
|
||||
| prodA |---->| consB prodB |---->| consC |
|
||||
| | | | | |
|
||||
+-------+ +-------------+ +-------+
|
||||
appA appB (filter) appC
|
||||
\endverbatim
|
||||
|
||||
Suppose consC has 200ms latency, and consB has 100ms latency. If consB simply
|
||||
reports 100ms, then prodA will schedule its events for (t - 100), which is
|
||||
really 200ms too late. (Of course, producers send out their events as soon as
|
||||
possible, so depending on the load of the system, everything may work out just
|
||||
fine.)
|
||||
|
||||
ConsB should report the latency of the consumer that is hooked up to its
|
||||
output, consC, in addition to its own latency. In other words, the full
|
||||
downstream latency. So, the reported latency in this case would be 300ms. This
|
||||
also means that appB should change the latency of consB when prodB makes or
|
||||
breaks a connection, and when consC reports a latency change. (If multiple
|
||||
consumers are connected to prodB, you should take the slowest one.)
|
||||
Unfortunately, the Midi Kit provides no easy mechanism for doing any of this,
|
||||
so you are on your own here.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class BMidiLocalConsumer MidiConsumer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\brief A consumer endpoint that is created by your own application
|
||||
|
||||
If you want to create a consumer that reacts to MIDI events, you should
|
||||
subclass BMidiLocalConsumer.
|
||||
|
||||
Each local consumer has its own thread that receives and dispatches the MIDI
|
||||
events. Whenever MIDI data arrives, the Data() hook passes the MIDI event on to
|
||||
a more specific hook function: NoteOn(), NoteOff(), SystemExclusive(), and so
|
||||
on. Calls to these hook functions are serialized -- they will never have to be
|
||||
re-entrant. They also should not be called from outside the thread that is
|
||||
invoking them.
|
||||
|
||||
Your subclass can override any of the MIDI event hooks. BMidiLocalConsumer
|
||||
doesn't provide default implementations for them, so you don't have to call a
|
||||
hook's default implementation if you override it. For complete control, you can
|
||||
also override Data().
|
||||
|
||||
Most hook functions take a channel argument. Even though MIDI channels are
|
||||
really numbered 1 through 16, the hook functions work with channels 0 through
|
||||
15. The performance time for the event is specified in microseconds relative to
|
||||
the system time base. A performance time that is 0 (or really any time in the
|
||||
past) means "play as soon as possible". See the \ref midi2time "introduction"
|
||||
for more information about timing and consumers.
|
||||
|
||||
The thread driving the consumer's events is a very high priority real time
|
||||
thread. Events should be handled as quickly as possible (not counting
|
||||
snoozing). If non-time-critical computation is needed it may be wise to queue
|
||||
events up for a lower priority thread to handle them external to the main event
|
||||
thread.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiLocalConsumer::BMidiLocalConsumer(const char *name = NULL)
|
||||
\brief Creates a new local consumer endpoint
|
||||
|
||||
The new endpoint is not visible to other applications until you Register() it.
|
||||
|
||||
You can tell the constructor what the name of the new consumer will be. If you
|
||||
pass NULL (or use the default argument), then the consumer's name will be an
|
||||
empty string. It won't be NULL, since endpoint names cannot be NULL.
|
||||
|
||||
There is no guarantee that the endpoint will be successfully created. For
|
||||
example, the Midi Server may not be running. Therefore, you should always call
|
||||
IsValid() after creating a new endpoint to make sure that everything went okay.
|
||||
If not, Release() the object to reclaim memory and abort gracefully.
|
||||
|
||||
\code
|
||||
MyConsumer* cons = new MyConsumer(...);
|
||||
if (!cons->IsValid())
|
||||
{
|
||||
cons->Release();
|
||||
...exit gracefully...
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SetLatency(bigtime_t latency)
|
||||
\brief Changes the published latency of the consumer
|
||||
\sa Latency()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int32 BMidiLocalConsumer::GetProducerID()
|
||||
\brief Returns the ID of the producer that most recently sent a MIDI event to
|
||||
this consumer
|
||||
|
||||
You can call this from one of the hooks to determine which producer the event
|
||||
came from.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SetTimeout(bigtime_t when, void* data)
|
||||
\brief Requests that the Timeout() hook will be called at some point
|
||||
|
||||
This method asks the consumer thread to call the Timeout() hook as soon as
|
||||
possible after the timeout expires. For every call to SetTimeout(), the
|
||||
Timeout() hook is only called once. Note: the term "timeout" may be a little
|
||||
misleading; the hook will <I>always</I> be called, even if events are received
|
||||
in the mean time. Apparently, this facility is handy for dealing with early
|
||||
events.
|
||||
|
||||
Note that the event thread blocks on the consumer's port as long as no events
|
||||
arrive. By default no timeout is set, and as a result the thread blocks
|
||||
forever. Your call to SetTimeout() doesn't change this. The new timeout value
|
||||
will go into effect the next time the thread tries to read from the port, i.e.
|
||||
after the first event has been received. If no event ever comes in, the
|
||||
Timeout() hook will never be called. This also means that you cannot cancel a
|
||||
timeout once you have set it. To repeat, calling SetTimeout() only takes effect
|
||||
after at least one new event has been received.
|
||||
|
||||
\param when An absolute time that's measured against the system clock.
|
||||
|
||||
\param data A pointer to a "cookie" that you can pass along to Timeout(). The
|
||||
data is not copied, so you must ensure that the pointer remains valid until
|
||||
Timeout() is called. You typically delete the data inside Timeout().
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::Timeout(void* data)
|
||||
\brief Hook function that is called per your own request
|
||||
\sa SetTimeout()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::Data(
|
||||
uchar* data, size_t length, bool atomic, bigtime_t time)
|
||||
\brief Invoked when raw MIDI is received
|
||||
|
||||
What the default implementation of Data() does depends on the value of atomic.
|
||||
If atomic is true, the data received comprises a single MIDI event; i.e. one
|
||||
status byte followed by the appropriate number of data bytes and nothing else.
|
||||
In this case, Data() calls the event-specific hook function that corresponds to
|
||||
that status byte. This optimization is used by the Midi Kit to allow faster
|
||||
dispatch of events generated by the specific Spray functions from
|
||||
BMidiLocalProducer.
|
||||
|
||||
If atomic is false, Data() ignores the MIDI event. If you want a consumer to
|
||||
handle non-atomic events, you have to override Data() and program this
|
||||
yourself. In that case, you probably also want to call the default
|
||||
implementation to handle the "normal" MIDI events.
|
||||
|
||||
Data() is rarely overridden, but you can override it if you want to. If you do,
|
||||
remember that the data buffer is owned by the Midi Kit. Do not attempt to
|
||||
modify or free it, lest you wish to be laughed at by other developers.
|
||||
|
||||
\param data the MIDI event data
|
||||
\param length byte size of the data buffer
|
||||
\param atomic whether the data buffer contains a single complete MIDI event
|
||||
\param time the requested performance time of the event
|
||||
|
||||
\sa BMidiLocalProducer::SprayData()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::NoteOff(
|
||||
uchar channel, uchar note, uchar velocity, bigtime_t time)
|
||||
\brief Invoked when a Note Off event is received
|
||||
\sa BMidiLocalProducer::SprayNoteOff()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::NoteOn(
|
||||
uchar channel, uchar note, uchar velocity, bigtime_t time)
|
||||
\brief Invoked when a Note On event is received
|
||||
\sa BMidiLocalProducer::SprayNoteOn()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::KeyPressure(
|
||||
uchar channel, uchar note, uchar pressure, bigtime_t time)
|
||||
\brief Invoked when a Polyphonic Pressure (Aftertouch) event is received
|
||||
\sa BMidiLocalProducer::SprayKeyPressure()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::ControlChange(
|
||||
uchar channel, uchar controlNumber, uchar controlValue, bigtime_t time)
|
||||
\brief Invoked when a Controller Change event is received
|
||||
\sa BMidiLocalProducer::SprayControlChange()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::ProgramChange(
|
||||
uchar channel, uchar programNumber, bigtime_t time)
|
||||
\brief Invoked when a Program Change event is received
|
||||
\sa BMidiLocalProducer::SprayProgramChange()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::ChannelPressure(
|
||||
uchar channel, uchar pressure, bigtime_t time)
|
||||
\brief Invoked when a Channel Pressure event is received
|
||||
\sa BMidiLocalProducer::SprayChannelPressure()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::PitchBend(
|
||||
uchar channel, uchar lsb, uchar msb, bigtime_t time)
|
||||
\brief Invoked when a Pitch Bend event is received
|
||||
\sa BMidiLocalProducer::SprayPitchBend()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SystemExclusive(
|
||||
void* data, size_t length, bigtime_t time)
|
||||
\brief Invoked when a System Exclusive event is received
|
||||
|
||||
The data does not include the sysex start and end control bytes (0xF0 and 0xF7),
|
||||
only the payload of the sysex message.
|
||||
|
||||
The data belongs to the Midi Kit and is only valid for the duration of this
|
||||
event. You may not modify or free it.
|
||||
|
||||
\sa BMidiLocalProducer::SpraySystemExclusive()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SystemCommon(
|
||||
uchar status, uchar data1, uchar data2, bigtime_t time)
|
||||
\brief Invoked when a System Common event is received
|
||||
|
||||
Not all data bytes are used for all common events. Unused bytes are set to 0.
|
||||
|
||||
\sa BMidiLocalProducer::SpraySystemCommon()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::SystemRealTime(
|
||||
uchar status, bigtime_t time)
|
||||
\brief Invoked when a Real Time event is received
|
||||
\sa BMidiLocalProducer::SpraySystemRealTime()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::TempoChange(int32 beatsPerMinute, bigtime_t time)
|
||||
\brief Invoked when a Tempo Change event is received
|
||||
\sa BMidiLocalProducer::SprayTempoChange()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalConsumer::AllNotesOff(bool justChannel, bigtime_t time)
|
||||
\brief Not used
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,296 +0,0 @@
|
||||
/*!
|
||||
\class BMidiEndpoint
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\brief Base class for all MIDI endpoints
|
||||
|
||||
BMidiEndpoint is the abstract base class that represents either a producer or
|
||||
consumer endpoint. It may be used to obtain the state, name, properties, or
|
||||
system-wide ID of the object. BMidiEndpoint also provides the ability to change
|
||||
the name and properties of endpoints that were created locally.
|
||||
|
||||
Remember, you cannot call the destructor of BMidiEndpoint and its subclasses
|
||||
directly. Endpoint objects are destructed automatically when their reference
|
||||
count drops to zero. If necessary, the destructor of a local endpoint first
|
||||
breaks off any connections and Unregister()'s the endpoint before it is
|
||||
deleted. However, for good style and bonus points you should really \link
|
||||
BMidiProducer::Disconnect() Disconnect() \endlink and Unregister() the object
|
||||
yourself and not rely on the destructor to do this.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const char* BMidiEndpoint::Name() const
|
||||
\brief Returns the name of the endpoint
|
||||
|
||||
The function never returns NULL. If you created a local endpoint by passing a
|
||||
NULL name into its constructor (or passing no name, which is the same thing),
|
||||
then Name() will return an empty string, not NULL.
|
||||
|
||||
\sa SetName()
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiEndpoint::SetName(const char* name)
|
||||
\brief Changes the name of the endpoint.
|
||||
|
||||
Names don't have to be unique, but it is recommended that you give any
|
||||
endpoints you publish meaningful and unique names, so users can easily
|
||||
recognize what each endpoint does. There is no limit to the size of endpoint
|
||||
names.
|
||||
|
||||
Even though you can call this function on both remote and local objects, you
|
||||
are only allowed to change the names of local endpoints; SetName() calls on
|
||||
remote endpoints are ignored.
|
||||
|
||||
\param name The new name. If you pass NULL, the name simply won't be changed.
|
||||
|
||||
\sa Name()
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int32 BMidiEndpoint::ID() const
|
||||
\brief Returns the ID of the endpoint
|
||||
|
||||
An ID uniquely identifies an endpoint in the system. The ID is a signed 32-bit
|
||||
number that is assigned by the Midi Server when the endpoint is created. (So
|
||||
even if a local endpoint is not published, it still has a unique ID.) Valid IDs
|
||||
range from 1 to 0x7FFFFFFF, the largest value an int32 can have. 0 and negative
|
||||
values are <I>not</I> valid IDs.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsProducer() const
|
||||
\brief Determines whether this endpoint is a BMidiProducer
|
||||
|
||||
If it is, you can use a dynamic_cast to convert this object into a producer:
|
||||
|
||||
\code
|
||||
if (endp->IsProducer())
|
||||
{
|
||||
BMidiProducer* prod = dynamic_cast<BMidiProducer*>(endp);
|
||||
....
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsConsumer() const
|
||||
\brief Determines whether this endpoint is a BMidiConsumer
|
||||
|
||||
If it is, you can use a dynamic_cast to convert this object into a consumer:
|
||||
|
||||
\code
|
||||
if (endp->IsConsumer())
|
||||
{
|
||||
BMidiConsumer* cons = dynamic_cast<BMidiConsumer*>(endp);
|
||||
....
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsRemote() const
|
||||
\brief Determines whether this endpoint is a proxy for a remote object
|
||||
|
||||
An endpoint is "remote" when it is created by another application. Obviously,
|
||||
the remote object is Register()'ed as well, otherwise you would not be able to
|
||||
see it.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsLocal() const
|
||||
\brief Determines whether this endpoint represents a local object
|
||||
|
||||
An endpoint is "local" when it is created by this application; in other words,
|
||||
a BMidiLocalConsumer or BMidiLocalProducer.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsPersistent() const
|
||||
\brief Not used
|
||||
|
||||
The purpose of this function is unclear, and as a result it doesn't do anything
|
||||
in the OpenBeOS implementation of the Midi Kit.
|
||||
|
||||
\return Always returns false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiEndpoint::IsValid() const
|
||||
\brief Determines whether the endpoint still exists
|
||||
|
||||
Suppose you obtained a proxy object for a remote endpoint by querying the
|
||||
BMidiRoster. What if the application that published this endpoint quits, or
|
||||
less drastically, Unregister()'s that endpoint? Even though you still have a
|
||||
BMidiEndpoint proxy object, the real endpoint no longer exists. You can use
|
||||
IsValid() to check for this.
|
||||
|
||||
Don't worry, operations on invalid objects, such as GetProperties(), will
|
||||
return an error code (typically B_ERROR), but not cause a crash. Local objects
|
||||
are always are considered to be valid, even if you did not Register() them.
|
||||
(The only time a local endpoint is not valid is when there was a problem
|
||||
constructing it.)
|
||||
|
||||
If the application that created the remote endpoint crashes, then there is no
|
||||
guarantee that the Midi Server immediately recognizes this. In that case,
|
||||
IsValid() may still return true. Eventually, the stale endpoint will be removed
|
||||
from the roster, though. From then on, IsValid() correctly returns false.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Acquire()
|
||||
\brief Increments the endpoint's reference count
|
||||
|
||||
Each BMidiEndpoint has a reference count associated with it, so that
|
||||
BMidiRoster can do proper bookkeeping. Acquire() increments this reference
|
||||
count, and Release() decrements it. Once the count reaches zero, the endpoint
|
||||
is deleted.
|
||||
|
||||
When you are done with the endpoint, whether local or remote, you should
|
||||
<I>always</I> Release() it!
|
||||
|
||||
Upon construction, local endpoints start with a reference count of 1. Any
|
||||
objects you obtain from BMidiRoster using the NextXXX() or FindXXX() functions
|
||||
have their reference counts incremented in the process. If you forget to call
|
||||
Release(), the objects won't be properly cleaned up and you'll make a fool out
|
||||
of yourself.
|
||||
|
||||
After you Release() an object, you are advised not to use it any further. If
|
||||
you do, your app will probably crash. That also happens if you Release() an
|
||||
object too many times.
|
||||
|
||||
Typically, you don't need to call Acquire(), unless you have two disparate
|
||||
parts of your application working with the same endpoint, and you don't want to
|
||||
have to keep track of who needs to Release() the endpoint. Now you simply have
|
||||
both of them release it.
|
||||
|
||||
\return Always returns B_OK
|
||||
\sa Release()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Release()
|
||||
\brief Decrements the endpoint's reference count
|
||||
\return Always returns B_OK
|
||||
\sa Acquire()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Register()
|
||||
\brief Publishes the endpoint on the roster
|
||||
|
||||
MIDI objects created by an application are invisible to other applications
|
||||
until they are published. To publish an object use the Register() method. The
|
||||
corresponding Unregister() method will cause an object to once again become
|
||||
invisible to remote applications.
|
||||
|
||||
BMidiRoster also has Register() and Unregister() methods. You may also use
|
||||
those methods to publish or hide your endpoints; both do the same thing.
|
||||
|
||||
Although it is considered bad style, calling Register() on local endpoints that
|
||||
are already registered won't mess things up. The Midi Server will simply ignore
|
||||
your request. Likewise for Unregister()'ing more than once. Attempts to
|
||||
Register() or Unregister() remote endpoints will fail, of course.
|
||||
|
||||
If you are \link BMidiRoster::StartWatching() watching \endlink, you will
|
||||
<I>not</I> receive notifications for any local endpoints you register or
|
||||
unregister. Of course, other applications <I>will</I> be notified about your
|
||||
endpoints.
|
||||
|
||||
Existing connections will not be broken when an object is unregistered, but
|
||||
future remote connections will be denied. When objects are destroyed, they
|
||||
automatically become unregistered.
|
||||
|
||||
\return B_OK on success, or a negative error code (typically B_ERROR) if
|
||||
something went wrong.
|
||||
|
||||
\sa Unregister()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::Unregister()
|
||||
\brief Hides the endpoint from the roster
|
||||
\sa Register()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::SetProperties(const BMessage* props)
|
||||
\brief Changes the properties of the endpoint
|
||||
|
||||
Endpoints can have properties, which is any kind of information that might be
|
||||
useful to associate with a MIDI object. The properties are stored in a
|
||||
BMessage.
|
||||
|
||||
Usage example:
|
||||
|
||||
\code
|
||||
BMessage props;
|
||||
if (endpoint->GetProperties(&props) == B_OK)
|
||||
{
|
||||
...add data to the message...
|
||||
endpoint->SetProperties(&props);
|
||||
}
|
||||
\endcode
|
||||
|
||||
You are only allowed to call SetProperties() on a local object.
|
||||
|
||||
Properties should follow a protocol, so different applications will know how to
|
||||
read each other's properties. The current protocol is very limited -- it only
|
||||
allows you to associate icons with your endpoints. Be planned to publish a more
|
||||
complete protocol that included additional information, such as vendor/model
|
||||
names, copyright/version info, category, etc., but they never got around to it.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>property</TD><TD>Vector icon (raw data)</TD></TR>
|
||||
<TR><TD>field name</TD><TD>"icon"</TD></TR>
|
||||
<TR><TD>field type</TD><TD>'VICN'</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
This vector icon is available under Haiku only, and comes as raw data, not a BBitmap.
|
||||
Before being able to display it, you first must render the vector icon in the size of
|
||||
your choice.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>property</TD><TD>Large (32x32) icon</TD></TR>
|
||||
<TR><TD>field name</TD><TD>"be:large_icon"</TD></TR>
|
||||
<TR><TD>field type</TD><TD>'ICON'</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>property</TD><TD>Small (16x16) icon</TD></TR>
|
||||
<TR><TD>field name</TD><TD>"be:mini_icon"</TD></TR>
|
||||
<TR><TD>field type</TD><TD>'MICN'</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
The MidiUtil package (downloadable from the OpenBeOS website) contains a number
|
||||
of convenient functions to associate icons with endpoints, so you don't have to
|
||||
write that code all over again.
|
||||
|
||||
\sa GetProperties()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiEndpoint::GetProperties(BMessage* props) const
|
||||
\brief Reads the properties of the endpoint
|
||||
|
||||
Usage example:
|
||||
|
||||
\code
|
||||
BMessage props;
|
||||
if (endpoint->GetProperties(&props) == B_OK)
|
||||
{
|
||||
...examine the contents of the message...
|
||||
}
|
||||
\endcode
|
||||
|
||||
Note that GetProperties() overwrites the contents of your BMessage.
|
||||
|
||||
\sa SetProperties()
|
||||
*/
|
||||
@@ -1,31 +0,0 @@
|
||||
*!
|
||||
\file Midi2Defs.h
|
||||
\ingroup midi2
|
||||
\brief General Defines for the MIDI2 kit
|
||||
|
||||
Please see \ref midi2defs for more information.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file MidiConsumer.h
|
||||
\ingroup midi2
|
||||
\brief Defines consumer classes for the MIDI Kit
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file MidiProducer.h
|
||||
\ingroup midi2
|
||||
\brief Defines producer classes for the MIDI Kit
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file MidiEndpoint.h
|
||||
\ingroup midi2
|
||||
\brief Defines the Baseclass of all MIDI consumers and producers
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file MidiRoster.h
|
||||
\ingroup midi2
|
||||
\brief Defines the heart of the MIDI Kit: the MIDI Roster
|
||||
*/
|
||||
@@ -1,308 +0,0 @@
|
||||
/*!
|
||||
\class BMidiProducer MidiProducer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\brief Streams MIDI events to connected consumers
|
||||
|
||||
A producer is an object that generate a stream of MIDI events. Each producer
|
||||
has a list of BMidiConsumer objects to which it is connected, and may be asked
|
||||
to connect to or disconnect from a BMidiConsumer. A producer can spray its
|
||||
events to multiple consumers at the same time.
|
||||
|
||||
A BMidiProducer either represents a local producer, i.e. a class extending from
|
||||
BMidiLocalProducer, or is a proxy for a remote object published by another app.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiProducer::Connect(BMidiConsumer* cons)
|
||||
\brief Connects a consumer to this producer
|
||||
|
||||
Establishes a connection between this producer and the specified consumer
|
||||
endpoint. From now on, any events that this producer sprays will be sent to
|
||||
that consumer. You may connect multiple consumers to a producer.
|
||||
|
||||
\return B_OK on success, or an error code when the connection could not be
|
||||
established. If the consumer is a proxy for a remote object and that object no
|
||||
longer exists, Connect() returns B_ERROR. It also returns B_ERROR if you try to
|
||||
connect the same producer and consumer more than once.
|
||||
|
||||
\sa Disconnect()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiProducer::Disconnect(BMidiConsumer* cons)
|
||||
\brief Disconnects a consumer from this producer
|
||||
|
||||
Terminates the connection between this producer and the specified consumer
|
||||
endpoint. From now on, any events that this producer sprays no longer go to
|
||||
that consumer.
|
||||
|
||||
\return B_OK on success, or an error code if there was no connection to break
|
||||
|
||||
\sa Connect()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool BMidiProducer::IsConnected(BMidiConsumer* cons) const
|
||||
\brief Determines whether a consumer is connected to this producer
|
||||
\sa Connect()
|
||||
\sa Disconnect()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BList* BMidiProducer::Connections() const
|
||||
\brief Returns a list with all connected consumers
|
||||
|
||||
Returns a BList with pointers to BMidiEndpoint objects for all consumers that
|
||||
are connected to this producer. You can examine the contents of the list as
|
||||
follows:
|
||||
|
||||
\code
|
||||
BList* list = prod->Connections();
|
||||
for (int32 t = 0; t < list->CountItems(); ++t)
|
||||
{
|
||||
BMidiEndpoint* endp = (BMidiEndpoint*) list->ItemAt(t);
|
||||
...do stuff...
|
||||
endp->Release(); // yes, here too!
|
||||
}
|
||||
delete list;
|
||||
\endcode
|
||||
|
||||
Every time you call this function, a new BList is allocated. The caller (that
|
||||
is you) is responsible for freeing this list. The BMidiEndpoint objects in the
|
||||
list have their reference counts bumped, so you need to Release() them before
|
||||
you delete the list or they will go all leaky on you.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class BMidiLocalProducer MidiProducer.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\brief A producer endpoint that is created by your own application
|
||||
|
||||
You create a BMidiLocalProducer if you want your application to send MIDI
|
||||
events. You use the various spray functions to send events to all connected
|
||||
consumers. If no consumers are connected to the producer, any calls to the
|
||||
spray functions are ignored.
|
||||
|
||||
Most spray functions accept a channel argument. Even though MIDI channels are
|
||||
really numbered 1 through 16, the spray functions work with channels 0 through
|
||||
15. You can also specify the performance time for the event using the time
|
||||
argument. Specify 0 (or any time in the past) to perform the event "now", i.e.
|
||||
as soon as possible. You can also schedule events to be performed in the
|
||||
future, by passing a time such as system_time() + 5000000, which means 5
|
||||
seconds from now.
|
||||
|
||||
Unlike BMidiLocalConsumer, which should be subclassed almost always, you hardly
|
||||
ever need to derive a class from BMidiLocalProducer. The only reason for
|
||||
subclassing is when you need to know when the producer gets connected or
|
||||
disconnected.
|
||||
|
||||
Also unlike consumers, local producers have no thread of control directly
|
||||
associated with them. If you want to send out the MIDI events from a different
|
||||
thread, you will have to create one yourself.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiLocalProducer::BMidiLocalProducer(const char *name = NULL)
|
||||
\brief Creates a new local producer endpoint
|
||||
|
||||
The new endpoint is not visible to other applications until you Register() it.
|
||||
|
||||
You can tell the constructor what the name of the new producer will be. If you
|
||||
pass NULL (or use the default argument), then the producer's name will be an
|
||||
empty string. It won't be NULL, since endpoint names cannot be NULL.
|
||||
|
||||
There is no guarantee that the endpoint will be successfully created. For
|
||||
example, the Midi Server may not be running. Therefore, you should always call
|
||||
IsValid() after creating a new endpoint to make sure that everything went okay.
|
||||
If not, Release() the object to reclaim memory and abort gracefully.
|
||||
|
||||
\code
|
||||
BMidiLocalProducer* prod = new BMidiLocalProducer(...);
|
||||
if (!prod->IsValid())
|
||||
{
|
||||
prod->Release();
|
||||
...exit gracefully...
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::Connected(BMidiConsumer* cons)
|
||||
\brief Invoked when a new consumer is connected to this producer
|
||||
|
||||
Although typical notifications (i.e. from BMidiRoster's "watching" facility)
|
||||
are only sent if it is some other app that is performing the operation,
|
||||
Connected() is also called if you are making the connection yourself.
|
||||
|
||||
If you override this hook, you don't have to call the default implementation,
|
||||
because that does nothing.
|
||||
|
||||
\param cons The newly connected consumer. The reference count of the consumer
|
||||
object is not increased, so you should not Release() it. However, if you want
|
||||
to keep track of the consumer beyond this function, you should first Acquire()
|
||||
it, and Release() it when you are done.
|
||||
|
||||
\sa Disconnected()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::Disconnected(BMidiConsumer* cons)
|
||||
\brief Invoked when a consumer is disconnected from this producer
|
||||
\sa Connected()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayData(
|
||||
void* data, size_t length, bool atomic = false, bigtime_t time = 0) const
|
||||
\brief Sends raw MIDI data downstream to all connected consumers
|
||||
|
||||
Typically you won't have to call SprayData(); the other spray functions will do
|
||||
just fine. If you do call it, remember that you retain ownership of the data
|
||||
and that you are responsible for freeing it at some point. (Even though data is
|
||||
not declared const, the function does not change it.)
|
||||
|
||||
With atomic set to false, you can send a MIDI message in segments (perhaps for
|
||||
a large sysex dump). However, when you do this, you are on your own. The Midi
|
||||
Kit only tags the data as being non-atomic, but offers no additional support.
|
||||
The default implementation of BMidiLocalConsumer completely ignores such
|
||||
events. To handle non-atomic MIDI data, you should override the
|
||||
BMidiLocalConsumer::Data() hook and process the MIDI event yourself. All of
|
||||
BMidiLocalProducer's other spray functions always send atomic data.
|
||||
|
||||
\param data the MIDI event data
|
||||
\param length byte size of the data buffer
|
||||
\param atomic whether the data buffer contains a single complete MIDI event
|
||||
\param time the required performance time of the event
|
||||
|
||||
\sa BMidiLocalConsumer::Data()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayNoteOff(
|
||||
uchar channel, uchar note, uchar velocity, bigtime_t time = 0) const
|
||||
\brief Sends a Note Off event to all connected consumers
|
||||
\sa BMidiLocalConsumer::NoteOff()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayNoteOn(
|
||||
uchar channel, uchar note, uchar velocity, bigtime_t time = 0) const
|
||||
\brief Sends a Note On event to all connected consumers
|
||||
\sa BMidiLocalConsumer::NoteOn()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayKeyPressure(
|
||||
uchar channel, uchar note, uchar pressure, bigtime_t time = 0) const
|
||||
\brief Sends a Polyphonic Pressure (Aftertouch) event to all connected
|
||||
consumers
|
||||
\sa BMidiLocalConsumer::KeyPressure()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayControlChange(
|
||||
uchar channel, uchar controlNumber, uchar controlValue,
|
||||
bigtime_t time = 0) const
|
||||
\brief Sends a Controller Change event to all connected consumers
|
||||
|
||||
\sa Midi2Defs.h
|
||||
\sa BMidiLocalConsumer::ControlChange()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayProgramChange(
|
||||
uchar channel, uchar programNumber, bigtime_t time = 0) const
|
||||
\brief Sends a Program Change event to all connected consumers
|
||||
\sa BMidiLocalConsumer::ProgramChange()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayChannelPressure(
|
||||
uchar channel, uchar pressure, bigtime_t time = 0) const
|
||||
\brief Sends a Channel Pressure event to all connected consumers
|
||||
\sa BMidiLocalConsumer::ChannelPressure()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayPitchBend(
|
||||
uchar channel, uchar lsb, uchar msb, bigtime_t time = 0) const
|
||||
\brief Sends a Pitch Bend event to all connected consumers
|
||||
\sa BMidiLocalConsumer::PitchBend()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SpraySystemExclusive(
|
||||
void* data, size_t length, bigtime_t time = 0) const
|
||||
\brief Sends a System Exclusive event to all connected consumers
|
||||
|
||||
You retain ownership of the data and are responsible for freeing it. Even
|
||||
though data is not declared const, the function does not change it. Even though
|
||||
the amount of data may be quite large, this function always sends sysex
|
||||
messages as an atomic block of data.
|
||||
|
||||
\sa BMidiLocalConsumer::SystemExclusive()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SpraySystemCommon(
|
||||
uchar status, uchar data1, uchar data2, bigtime_t time = 0) const
|
||||
\brief Sends a System Common event to the connected consumers
|
||||
|
||||
The status byte must be one of the following:
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>0xF1</TD><TD>B_MIDI_TIME_CODE</TD><TD>data1 only</TD></TR>
|
||||
<TR><TD>0xF2</TD><TD>B_SONG_POSITION</TD><TD>data1 and data2</TD></TR>
|
||||
<TR><TD>0xF3</TD><TD>B_SONG_SELECT</TD><TD>data1 only</TD></TR>
|
||||
<TR><TD>0xF5</TD><TD>B_CABLE_MESSAGE</TD><TD>data1 only</TD></TR>
|
||||
<TR><TD>0xF6</TD><TD>B_TUNE_REQUEST</TD><TD>no data</TD></TR>
|
||||
<TR><TD>0xF7</TD><TD>B_SYS_EX_END</TD><TD>no data</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
\sa BMidiLocalConsumer::SystemCommon()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SpraySystemRealTime(
|
||||
uchar status, bigtime_t time = 0) const
|
||||
\brief Sends a Real Time event to the connected consumers
|
||||
|
||||
The status byte must be one of the following:
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>0xF8</TD><TD>B_TIMING_CLOCK</TD></TR>
|
||||
<TR><TD>0xFA</TD><TD>B_START</TD></TR>
|
||||
<TR><TD>0xFB</TD><TD>B_CONTINUE</TD></TR>
|
||||
<TR><TD>0xFC</TD><TD>B_STOP</TD></TR>
|
||||
<TR><TD>0xFE</TD><TD>B_ACTIVE_SENSING</TD></TR>
|
||||
<TR><TD>0xFF</TD><TD>B_SYSTEM_RESET</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
Because of their high priority, the MIDI specification allows real time
|
||||
messages to "interleave" with other MIDI messages. A large sysex dump, for
|
||||
example, may be interrupted by a real time event. The Midi Kit, however,
|
||||
doesn't care. If you (or another producer) have just sent a big system
|
||||
exclusive to a consumer, any following real time message will simply have to
|
||||
wait until the consumer has dealt with the sysex.
|
||||
|
||||
\sa BMidiLocalConsumer::SystemRealTime()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiLocalProducer::SprayTempoChange(
|
||||
int32 bpm, bigtime_t time = 0) const
|
||||
\brief Sends a Tempo Change event to the connected consumers.
|
||||
|
||||
This kind of Tempo Change event is not really part of the MIDI spec, rather
|
||||
it is an extension from the SMF (Standard MIDI File) format.
|
||||
|
||||
\sa BMidiLocalConsumer::TempoChange()
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
/*!
|
||||
\var B_MIDI_EVENT
|
||||
\ingroup midi2
|
||||
\brief BMessage identifier of MIDI messages.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class BMidiRoster MidiRoster.h
|
||||
\ingroup midi2
|
||||
\ingroup libmidi2
|
||||
\brief Interface to the system-wide Midi Roster
|
||||
|
||||
BMidiRoster allows you to find available MIDI consumer and producer objects.
|
||||
You can locate these objects using the iterative NextEndpoint(),
|
||||
NextProducer(), and NextConsumer() methods or by requesting notification
|
||||
messages to be sent with StartWatching(). Notification messages may contain
|
||||
object IDs which can be resolved using the FindEndpoint(), FindProducer(), and
|
||||
FindConsumer() methods.
|
||||
|
||||
The constructor and destructor of BMidiRoster are private, which means that you
|
||||
cannot create or delete your own BMidiRoster objects. Every application can
|
||||
have only one instance of BMidiRoster, which is automatically created the very
|
||||
first time you use a Midi Kit function.
|
||||
|
||||
You can call BMidiRoster's functions like this:
|
||||
|
||||
\code
|
||||
producer = BMidiRoster::FindProducer(someID);
|
||||
\endcode
|
||||
|
||||
Or using the slightly more annoying:
|
||||
|
||||
\code
|
||||
BMidiRoster* roster = BMidiRoster::MidiRoster();
|
||||
if (roster != NULL)
|
||||
{
|
||||
producer = roster->FindProducer(someID);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiEndpoint* BMidiRoster::NextEndpoint(int32* id)
|
||||
\brief Returns the next endpoint from the roster
|
||||
|
||||
The "next endpoint" means: the endpoint with the ID that follows id. So if you
|
||||
set id to 3, the first possible endpoint it returns is endpoint 4. No endpoint
|
||||
can have ID 0, so passing 0 gives you the first endpoint. If you pass NULL
|
||||
instead of an ID, NextEndpoint() always returns NULL. When the function
|
||||
returns, it sets id to the ID of the endpoint that was found. If no more
|
||||
endpoints exist, NextEndpoint() returns NULL and id is not changed.
|
||||
NextEndpoint() does <I>not</I> return locally created endpoints, even if they
|
||||
are Register()'ed.
|
||||
|
||||
Usage example:
|
||||
|
||||
\code
|
||||
int32 id = 0;
|
||||
BMidiEndpoint* endp;
|
||||
while ((endp = BMidiRoster::NextEndpoint(&id)) != NULL)
|
||||
{
|
||||
...do something with endpoint ...
|
||||
endp->Release(); // don't forget!
|
||||
}
|
||||
\endcode
|
||||
|
||||
Remember that NextEndpoint() bumps the endpoint's reference count, so you
|
||||
should always \link BMidiEndpoint::Release() Release() \endlink it when you are
|
||||
done.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiProducer* BMidiRoster::NextProducer(int32* id)
|
||||
\brief Returns the next producer from the roster
|
||||
|
||||
Like NextEndpoint(), but only returns producer endpoints.
|
||||
|
||||
\sa NextConsumer
|
||||
\sa NextEndpoint
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiConsumer* BMidiRoster::NextConsumer(int32* id)
|
||||
\brief Returns the next consumer from the roster
|
||||
|
||||
Like NextEndpoint(), but only returns consumer endpoints.
|
||||
|
||||
\sa NextProducer
|
||||
\sa NextEndpoint
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiEndpoint* BMidiRoster::FindEndpoint(
|
||||
int32 id, bool localOnly = false)
|
||||
\brief Returns the endpoint with the specified ID
|
||||
|
||||
FindEndpoint() will always find <I>any</I> local endpoints created by this
|
||||
application; they do not have to be published with Register() first. If
|
||||
localOnly is false, FindEndpoint() also looks at remote endpoints, otherwise
|
||||
only local endpoints will be resolved. Returns NULL if no such endpoint could
|
||||
be found.
|
||||
|
||||
You should use a dynamic_cast to convert the BMidiEndpoint into a producer or
|
||||
consumer:
|
||||
|
||||
\code
|
||||
BMidiEndpoint* endp = ...;
|
||||
BMidiProducer* prod = NULL;
|
||||
BMidiConsumer* cons = NULL;
|
||||
|
||||
if (endp->IsProducer())
|
||||
{
|
||||
prod = dynamic_cast<BMidiProducer*>(endp);
|
||||
}
|
||||
else if (endp->IsConsumer())
|
||||
{
|
||||
cons = dynamic_cast<BMidiConsumer*>(endp);
|
||||
}
|
||||
\endcode
|
||||
|
||||
Remember that FindEndpoint() increments the endpoint's reference count, so you
|
||||
should always \link BMidiEndpoint::Release() Release() \endlink an endpoint
|
||||
when you are done with it:
|
||||
|
||||
\code
|
||||
BMidiEndpoint* endp = BMidiRoster::FindEndpoint(someID);
|
||||
if (endp != NULL)
|
||||
{
|
||||
...do stuff with the endpoint...
|
||||
endp->Release();
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiProducer* BMidiRoster::FindProducer(
|
||||
int32 id, bool localOnly = false)
|
||||
\brief Finds the producer with the specified ID
|
||||
|
||||
Like FindEndpoint(), but only looks for producer endpoints. Returns NULL if no
|
||||
endpoint with that ID exists, or if that endpoint is not a producer.
|
||||
|
||||
\sa FindConsumer
|
||||
\sa FindEndpoint
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiConsumer* BMidiRoster::FindConsumer(
|
||||
int32 id, bool localOnly = false)
|
||||
\brief Finds the consumer with the specified ID
|
||||
|
||||
Like FindEndpoint(), but only looks for consumer endpoints. Returns NULL if no
|
||||
endpoint with that ID exists, or if that endpoint is not a consumer.
|
||||
|
||||
\sa FindProducer
|
||||
\sa FindEndpoint
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiRoster::StartWatching(const BMessenger* msngr)
|
||||
\brief Start receiving notifications from the Midi Roster
|
||||
|
||||
When you start watching, BMidiRoster sends you notifications for all currently
|
||||
<I>published</I> <I>remote</I> endpoints, and all the current connections
|
||||
between them. (At this point, BMidiRoster does not let you know about
|
||||
connections between unpublished endpoints, nor does it tell you anything about
|
||||
your local endpoints, even though they may be published.)
|
||||
|
||||
Thereafter, you'll receive notifications any time something important happens
|
||||
to an object. The application that performs these operations is itself not
|
||||
notified. The assumption here is that you already know about these changes,
|
||||
because you are the one that is performing them.
|
||||
|
||||
The notifications are BMessages with code B_MIDI_EVENT. You specify the
|
||||
BMessenger that will be used to send these messages. Each message contains a
|
||||
field called be:op that describes the type of notification.
|
||||
|
||||
The "registered" and "unregistered" notifications are sent when a remote
|
||||
endpoint Register()'s or Unregister()'s, respectively. You don't receive these
|
||||
notifications when you register or unregister your local endpoints, but the
|
||||
other apps will.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_REGISTERED</TD></TR>
|
||||
<TR><TD>be:id</TD><TD>int32</TD><TD>ID of the endpoint</TD></TR>
|
||||
<TR><TD>be:type</TD><TD>string</TD><TD>"producer" or "consumer"</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_UNREGISTERED</TD></TR>
|
||||
<TR><TD>be:id</TD><TD>int32</TD><TD>ID of the endpoint</TD></TR>
|
||||
<TR><TD>be:type</TD><TD>string</TD><TD>"producer" or "consumer"</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
The "connected" and "disconnected" notifications are sent when a consumer \link
|
||||
BMidiProducer::Connect() Connect()\endlink's to a producer, or when they \link
|
||||
BMidiProducer::Disconnect() Disconnect() \endlink. You will receive these
|
||||
notifications when <I>any</I> two endpoints connect or disconnect, even if they
|
||||
are not published. (The purpose of which is debatable.) You won't receive the
|
||||
notifications if you are the one making the connection, even if both endpoints
|
||||
are remote. You <I>will</I> be notified when another app connects one of your
|
||||
published endpoints.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_CONNECTED</TD></TR>
|
||||
<TR><TD>be:producer</TD><TD>int32</TD><TD>ID of the connector</TD></TR>
|
||||
<TR><TD>be:consumer</TD><TD>int32</TD><TD>ID of the connectee</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_DISCONNECTED</TD></TR>
|
||||
<TR><TD>be:producer</TD><TD>int32</TD><TD>ID of the connector</TD></TR>
|
||||
<TR><TD>be:consumer</TD><TD>int32</TD><TD>ID of the connectee</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
The following notifications are sent when an endpoint's attributes are changed.
|
||||
You receive these notifications only if another application is changing one of
|
||||
its published endpoints.
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_CHANGED_NAME</TD></TR>
|
||||
<TR><TD>be:id</TD><TD>int32</TD><TD>ID of the endpoint</TD></TR>
|
||||
<TR><TD>be:type</TD><TD>string</TD><TD>"producer" or "consumer"</TD></TR>
|
||||
<TR><TD>be:name</TD><TD>string</TD><TD>the endpoint's new name</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_CHANGED_LATENCY</TD></TR>
|
||||
<TR><TD>be:id</TD><TD>int32</TD><TD>ID of the endpoint</TD></TR>
|
||||
<TR><TD>be:type</TD><TD>string</TD><TD>"producer" or "consumer"</TD></TR>
|
||||
<TR><TD>be:latency</TD><TD>int64</TD><TD>the new latency (microseconds)</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
<TABLE BORDER="1">
|
||||
<TR><TD>be:op</TD><TD>int32</TD><TD>B_MIDI_CHANGED_PROPERTIES</TD></TR>
|
||||
<TR><TD>be:id</TD><TD>int32</TD><TD>ID of the endpoint</TD></TR>
|
||||
<TR><TD>be:type</TD><TD>string</TD><TD>"producer" or "consumer"</TD></TR>
|
||||
<TR><TD>be:properties</TD><TD>BMessage</TD><TD>the new properties</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
Typical usage example:
|
||||
|
||||
\code
|
||||
void MyView::AttachedToWindow()
|
||||
{
|
||||
BMessenger msgr(this);
|
||||
BMidiRoster::StartWatching(&msgr);
|
||||
}
|
||||
|
||||
void MyView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case B_MIDI_EVENT:
|
||||
HandleMidiEvent(msg);
|
||||
break;
|
||||
default:
|
||||
super::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
For the possible midi options, see #BMidiOp
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void BMidiRoster::StopWatching()
|
||||
\brief Stop receiving notifications from the Midi Roster
|
||||
\sa StartWatching()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiRoster::Register(BMidiEndpoint* object)
|
||||
\brief Publishes an endpoint to other applications
|
||||
|
||||
Calls BMidiEndpoint's \link BMidiEndpoint::Register() Register() \endlink
|
||||
method to publish an endpoint, which makes it visible to other applications.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn status_t BMidiRoster::Unregister(BMidiEndpoint* object)
|
||||
\brief Hides an endpoint from other applications
|
||||
|
||||
Calls BMidiEndpoint's \link BMidiEndpoint::Unregister() Unregister() \endlink
|
||||
method to hide a previously published endpoint from other applications.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn BMidiRoster* BMidiRoster::MidiRoster()
|
||||
\brief Returns a pointer to the only instance of BMidiRoster
|
||||
|
||||
There is no real reason use this function, since all BMidiRoster's public
|
||||
function are static.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum BMidiOp
|
||||
\brief Defines the status codes for MIDI Server notification messages.
|
||||
|
||||
These codes are used when you request notification as in BMidiRoster::StartWatching().
|
||||
Check against these codes to determine what is happening. See the StartWatching() method
|
||||
for a more complete description of the codes and their meaning.
|
||||
*/
|
||||
Reference in New Issue
Block a user