|
Derived from: public BMidi
Declared in: be/midi/MidiStore.h
Library: libmidi.so
more...
The BMidiStore class defines a MIDI recording and playback mechanism. The MIDI messages that a BMidiStore object receives (at its input) are stored as events in an event list, allowing a captured performance to be played back later. The object can also read and write—or import and export—standard MIDI files.
The ability to record a MIDI performance is vested in BMidiStore's MIDI hook functions (NoteOn(), NoteOff(), etc.). When a MIDI hook is invoked, the function fabricates a discrete event based on the data it has received in its arguments, and adds the event to its event list. You don't need to tell a BMidiStore to start recording; it can record from the moment it's constructed.For example, to record a performance from an external MIDI keyboard, you connect a BMidiStore to a BMidiPort object and then tell the BMidiPort to start:
/* Record a keyboard performance. */
BMidiStore MyStore;
BMidiPort MyPort;
MyPort.Open(...);
MyPort.Connect(MyStore);
MyPort.Start();
/* Start playing... */
At the end of the performance, you tell the BMidiPort to stop:
MyPort.Stop();
Events are added to a BMidiStore's event list immediately upon arrival. Each event is given a timestamp as it arrives; the value of the timestamp is the value of the time argument that was passed to the MIDI hook function by the "upstream" object's spray function. There's no guarantee that the time arguments of successive MIDI events will be in chronological order. To ensure that the events are properly ordered, you should call Sort() before you read from the list (note that writing to a MIDI file automatically sorts the list).BMidiStore's input functions don't call SnoozeUntil(): A BMidiStore writes to its event list as soon as it gets a new message, it doesn't wait until the time indicated by the time argument.
You can't. If you make a mistake while you're recording (for example) and want to try again, you can simulate emptying the object by disconnecting the input to the BMidiStore, destroying the object, making a new one, and re-connecting. For example:Editing the events in the event list is less than impossible (were such a state possible). You can't do it, and you can't simulate it, at least not with the default implementation of BMidiStore. If you want to edit MIDI data, you have to provide your own BMidi-derived class.
To "play" a BMidiStore's list of events, you call the object's Start() function. As described in the BMidi class specification, Start() invokes Run(). BMidiStore's Run() reads events in the order that they appear in the event list, and sprays the appropriate messages to the connected objects. You can interrupt a BMidiStore playback by calling Stop(); uninterrupted, the object will stop by itself after it has sprayed the last event in the list.The events' timestamps are used as the time arguments in the spray functions that are called from within Run(). But with a twist: The time argument that's passed in the first spray call (for a given performance) is always B_NOW; subsequent time arguments are re-computed to maintain the correct timing in relation to the first event. In other words, when you tell a BMidiStore to start playing, the first event is performed immediately regardless of the actual value of its timestamp.
You can tell the BMidiStore to begin playing from somewhere in the middle of the list by calling SetCurrentEvent() before starting the playback. The function takes an index into the list.If you want to start playing from a particular time offset into the event list, you first have to figure out which event lies at that time. To do this, you ask for the event that occurs at or after the time offset (in milliseconds) through the EventAtDelta() function. The value that's returned by this function is suitable as the argument to SetCurrentEvent().
Keep in mind that EventAtDelta() returns the index of the first event at or after the desired offset. If you need to know the actual offset of the winning event, you can pass its index to DeltaOfEvent():
long firstEvent = MyStore->EventAtDelta(3000);
long actualDelta = MyStore->DeltaOfEvent(firstEvent);
You add events to a BMidiStore's event list by reading, or importing, a Standard MIDI File through the Import() function. You can import any number of files into the same BMidiStore object. After you import a file, the event list is automatically sorted.One thing you shouldn't do is import a MIDI file into a BMidiStore that contains events that were previously recorded from a BMidiPort (in an attempt to mix the file and the recording). Nor does the reverse work: You can't import a file and then record from a BMidiPort. The file's timestamps are incompatible with those that are generated for events that are received from the BMidiPort; the result certainly won't be satisfactory.
To write the event list as a MIDI file, you call BMidiStore's Export() function:
BMidiStore() , ~BMidiText() |
BMidiStore(void) virtual ~BMidiStore() The constructor creates a new, empty BMidiStore object. The destructor destroys the object and its storage.
BeginTime() |
uint32 BeginTime(void) constReturns the time, in ticks, at which the most recent performance started. This function is only valid if the object has actually performed.
CountEvents() , SortEvents() , DeltaOfEvent() , EventAtDelta() |
uint32 CountEvents(void) const void SortEvents(bool force = false) uint32 DeltaOfEvent(uint32 index) const uint32 EventAtDelta(uint32 delta) const CountEvents() returns the number of events in the object's event list.
SortEvents() time-sorts the events in the event list. The object maintains a (conservative) notion of whether the events are already sorted; if force is false and the object doesn't think the operation is necessary, the sorting isn't performed. If force is true, the operation is always performed, regardless of its necessity.
DeltaOfEvent() returns the "delta time" of the index'th event in the object's list of events. An event's delta time is the time span, in milliseconds, between the first event in the event list and itself.
EventAtDelta() Returns the index of the event that occurs on or after delta milliseconds from the beginning of the event list.
CurrentEvent() see SetCurrentEvent()
|
DeltaOfEvent() see CountEvents()
|
|
ChrisEvert() | |
Export() , Import() |
status_t Export(const entry_ref *to_file, int32 format)
status_t Import(const entry_ref *from_file)Export()ChrisEvert() time-sorts the object's event list, and then writes the list as a standard MIDI file in the designated format; the format argument should be either 0 or 1. The file that to_file refers to must already exist, and is not cleared before it's written.
Import() reads the standard MIDI file from the designated file and adds its events to the object's event list.
RETURN CODES
- B_OK. The file was successfully written or read.
- B_NO_MEMORY (Import() only). Couldn't allocate enough memory to accommodate the file.
- POSIX errors. Some other file error prevented the operation.
SetCurrentEvent() , CurrentEvent() |
void SetCurrentEvent(uint32 index)
uint32 CurrentEvent(void)Sets the object's "current event"—the event that it will perform next—to the event at index in the event list.
Returns the index of the event that will be performed next.
SetTempo() , Tempo() |
void SetTempo(int32 beatsPerMinute) int32 Tempo(void) const Sets and returns the object's tempo—the speed at which it performs events—in beats per minute. The default tempo is 60 bpm.
SortEvents see CountEvents() |
|
Copyright © 2000 Be, Inc. All rights reserved..