The Midi Kit Table of Contents | The Midi Kit Index |
Derived from: public BMidiSynth
Declared in: be/midi/MidiSynthFile.h
Library: libmidi.so
The BMidiSynthFile class reads a standard MIDI file and plays it on the General MIDI synthesizer. Each BMidiSynthFile object can read (and play) only one file at a time. To use a BMidiSynthFile, you create the object, load a MIDI file, and tell the object to Start():
/* Create and initialize a BMidiSynthFile. */ BMidiSynthFile midiSynthFile; entry_ref midiRef; get_ref_for_path("/boot/optional/midi/QuickBrownFox.mid", &midiRef); midiSynthFile.LoadFile(&midiRef); /* Play the file. */ midiSynthFile.Start();
You should create a different BMidiSynthFile object for each MIDI file that you want to mix together into a single performance.
|
When you call LoadFile(), the BMidiSynthFile object automatically calls...
EnableInput(true, false)
It then loads the file's MIDI data into the synthesizer, which loads all the instruments that are needed by the file. If the file uses a lot of different instruments, loading the file can take some time.
When the file is finished playing (either because it's reached the end, or because you called Stop()) the instruments are not unloaded. This cuts the overhead if you play the file a second time.
BMidiSynthFile is different from other Start()-able BMidi objects in that it doesn't have a run loop. The MIDI data is parsed and realized in the synthesizer's subscriber thread (the thread that dumps data into the DAC stream). The lack of a run loop shouldn't affect the way you write your code, but you should be aware that the thread isn't there so you won't go looking for it while you're developing your app
Furthermore, BMidiSynthFile doesn't implement the Run() function. Starting and stopping the object's performance (activities that are normally handled in the Run() function) are handled by the synthesizer in its subscriber thread. If you create a BMidiSynthFile subclass, don't try to resurrect the Run() function—leave it as a no-op.
As with the BMidiSynth class, the BMidiSynthFile MIDI hook implementations don't call the spray functions. This means that you can't, for example, connect a BMidiSynthFile to a BMidiPort. If you want to play a MIDI file out a MIDI port, use BMidiStore to represent and play the file.
|
Creates a new, empty BMidiSynthFile object. Also constructs a BSynth object and assigns the object to the app-wide be_synth variable (if the object doesn't already exist). To load a MIDI file into the BMidiSynthFile object, you must call LoadFile() after construction. Unlike plain BMidiSynth instances, however, you don't have to call EnableInput() (LoadFile() calls it for you).
|
Disconnects the object from the synthesizer, unloads the object's file (and all its instruments) and destroys the object.
|
Duration() returns the length of the object's loaded data, measured in 64ths of a MIDI tick.
Position() sets the object's current position within the data.
Seek() returns the object's current position.
If you want to reposition the "song pointer", you should do it as a percentage of the Duration() measurement.
|
RETURN CODES
Currently Position() always returns B_OK.
|
Returns an array of the instruments numbers that are needed by the loaded MIDI file. The instruments array should be 128 elements long (to be on the safe side), and must be allocated before it's passed in. Upon return, function sets count to the number of instrument numbers that it placed in the array. For example:
int16 insts[128]; int16 count; midiSynthFile.GetPatches(insts, &count); for (int n = 0; n < count; n++) printf("The file uses instrument #%dn", insts[n]);
|
LoadFile() tells the object to load, into the synthesizer, the MIDI data from the midiFileRef. The synthesizer caches the data for subsequent playback (which you initiate through Start()). All instruments that are needed to play the file are loaded into the synthesizer, if they're aren't loaded already.
UnloadFile() stops playback of the data that was loaded through this object (if it's playing), and flushes the data (removes it from the synthesizer).
|
RETURN CODES
B_OK. The file was found and loaded.
|
|
These functions control the object's performance.
Start() tells the synthesizer to start playing the object's loaded MIDI data beginning at the beginning. Note that Start() does not halt a performance in progress; in other words, if the object is already playing its data, you'll get a second, performance while the first continues.
Stop() immediately halts the currently playing data. Fade() also stops playback, but is a bit more graceful: It fades out the sound before killing it.
|
Pause() and Resume() do as they say. Note that when you resume playback, "old" notes are not regenerated, but exact timing is respected. For example, lets say you have a MIDI file that contains two notes, one that starts at time 1.0 (seconds) and lasts for 10.0 seconds, and the other starts at time 9.0. You start the file, then Pause() at time 3.0; as expected, the first note stops. After awhile, you Resume(); there's a six second silence and then the second note plays.
IsFinished() returns false if the object is currently playing (or paused during play). Note that the function returns false before you load a file, and returns true after you've loaded a file but before you begin playing it.
EnableLooping(true) tells the object to replay the file when it reaches the end of the data. If the argument is false, the file isn't replayed. Stop() always shuts up playback, even if looping is enabled.
SetFileHook() registers a function that's called when the object is finished playing (either because it ran out of data or Stop() was called. arg is passed to the hook function as its sole argument. Note that the hook function is called when the object is completely finished—it isn't called at the end of each pass through the data while looping is enabled.
RETURN CODES
Start() returns...
|
Tempo() returns the tempo of the data, as read from the MIDI file (or as set by the other functions), in beats-per-minute. The other two functions set the tempo: SetTempo() sets it absolutely in beats-per-minute, and ScaleTempoBy() scales the current tempo by the argument (scalar == 2.0 means the data is played twice as fast, scalar == .5 is twice as slow, and so on).
The Midi Kit Table of Contents | The Midi Kit Index |
Copyright © 2000 Be, Inc. All rights reserved..