QtFM::MidiPlayer Class
The MidiPlayer class plays a MidiFile on an Engine with FM instruments. More…
| Header | #include <QtFM> |
|---|---|
| CMake | target_link_libraries(app PRIVATE Nt::FM) |
| Module | Nt FM C++ Classes |
| Inherits | QObject |
List of all members, including inherited members
Public Functions
| MidiPlayer(Engine *engine, QObject *parent = nullptr) | |
| ~MidiPlayer() | |
| void | setFile(const MidiFile &file) |
| MidiFile | file() const |
| void | setInstruments(const PatchBank &bank) |
| PatchBank | instruments() const |
| void | setLoops(bool loops) |
| bool | loops() const |
| void | setGain(float dB) |
| float | gain() const |
| void | setTranspose(int semitones) |
| int | transpose() const |
| Patch | instrument(int channel, int program, int key) const |
| void | play() |
| void | stop() |
| bool | isPlaying() const |
| double | position() const |
| void | schedule(quint64 untilFrame) |
Signals
| void | finished() |
Detailed Description
The player streams the notes into the engine a fraction of a second ahead of time, placing each on its own sample with Engine::playAt(), so the timing is exact whatever the event loop does. Instruments come from a PatchBank, by default PatchBank::generalMidi(): for a note of program n, the patch named program-n if the bank has one, else the patch of its General MIDI family; on channel 10, drum-k for key k, else the kit's drum for that key.
QString error;
const MidiFile song = MidiFile::fromData(data, &error);
if (!song.isValid()) {
std::fprintf(stderr, "fmplay: %s\n", qPrintable(error));
return 1;
}
EngineConfig config;
config.sampleRate = rate;
config.maxVoices = 64; // one voice per sounding note
if (chip == ChipType::OPL2 || chip == ChipType::OPL3)
config.chips = {ChipType::OPL3}; // eighteen channels, like a Sound Blaster 16
Engine engine(config);
MidiPlayer player(&engine);
player.setInstruments(PatchBank::generalMidi(chip)); // the native bank for ChipType::None
player.setFile(song);
For an engine that is not started, call schedule() before each Engine::render().
Differences from Qt
The native engine plays the notes: there is no OPL rendition of General MIDI yet. Each note uses one voice, so give the engine enough voices (EngineConfig::maxVoices) for the music.
Member Function Documentation
QtFM::MidiPlayer::MidiPlayer(Engine *engine, QObject *parent = nullptr)
Constructs a player for engine, with parent.
QtFM::MidiPlayer::~MidiPlayer()
Destroys the player, releasing its notes.
MidiFile QtFM::MidiPlayer::file() const
Returns the music.
void QtFM::MidiPlayer::finished()
This signal is emitted when music that does not loop has ended.
float QtFM::MidiPlayer::gain() const
Returns the gain of the music in decibels.
Patch QtFM::MidiPlayer::instrument(int channel, int program, int key) const
Returns the patch that plays key key of program program on channel.
PatchBank QtFM::MidiPlayer::instruments() const
Returns the instruments.
bool QtFM::MidiPlayer::isPlaying() const
Returns true while the music plays.
bool QtFM::MidiPlayer::loops() const
Returns true if the music loops.
void QtFM::MidiPlayer::play()
Plays the music from its start.
double QtFM::MidiPlayer::position() const
Returns the position in the music in seconds; for looping music, within the current pass.
void QtFM::MidiPlayer::schedule(quint64 untilFrame)
Starts the notes that begin before the engine's frame untilFrame. A started engine is fed by a timer; for an engine that is pulled with Engine::render(), call it before each render with the frame the render will reach. Emits finished() once the music has ended.
void QtFM::MidiPlayer::setFile(const MidiFile &file)
Sets the music to file, stopping what plays.
void QtFM::MidiPlayer::setGain(float dB)
Sets the gain of the music to dB, for the notes not yet started.
void QtFM::MidiPlayer::setInstruments(const PatchBank &bank)
Sets the instruments to the patches of bank.
void QtFM::MidiPlayer::setLoops(bool loops)
Sets whether the music starts again when it ends to loops.
void QtFM::MidiPlayer::setTranspose(int semitones)
Sets the transposition of every note but the drums to semitones.
void QtFM::MidiPlayer::stop()
Stops the music, releasing its notes.
int QtFM::MidiPlayer::transpose() const
Returns the transposition in semitones.