virtual bool Rewind() { for(std::vector<MidiTrack>::iterator i = Tracks.begin(), end = Tracks.end();i != end;i++) { i->Reset(); unsigned long val = i->ReadVarLen(); i->SamplesLeft += val * samplesPerTick; } fluid_synth_program_reset(fluidSynth); UpdateTempo(500000); return true; }
fluidStream(std::istream *_fstream) : alureStream(_fstream), Divisions(100), format(AL_NONE), sampleRate(48000), samplesPerTick(1.), fluidSettings(NULL), fluidSynth(NULL), fontID(FLUID_FAILED), doFontLoad(true) { if(!fsynth_handle) return; ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); if(device) alcGetIntegerv(device, ALC_FREQUENCY, 1, &sampleRate); char hdr[4]; if(!fstream->read(hdr, 4)) return; if(memcmp(hdr, "MThd", 4) == 0) { ALuint len = read_be32(fstream); if(len != 6) return; int type = read_be16(fstream); if(type != 0 && type != 1) return; ALuint numtracks = read_be16(fstream); Divisions = read_be16(fstream); UpdateTempo(500000); Tracks.resize(numtracks); for(std::vector<MidiTrack>::iterator i = Tracks.begin(), end = Tracks.end();i != end;i++) { if(!fstream->read(hdr, 4) || memcmp(hdr, "MTrk", 4) != 0) return; ALint len = read_be32(fstream); i->data.resize(len); if(!fstream->read(reinterpret_cast<char*>(&i->data[0]), len) || fstream->gcount() != len) return; unsigned long val = i->ReadVarLen(); i->SamplesLeft += val * samplesPerTick; } SetupSynth(); } }
afx_msg LRESULT MFCQuaTransportBar::OnQuaCtlChanged(WPARAM wparam, LPARAM lparam) { switch (wparam) { case QCID_TB_TIME: { UpdateGlobalTime(pleitym.time); break; } case QCID_TB_TEMPO: { UpdateTempo(tempeh.value); break; } } return true; }
void ProcessMidi() { ALuint newtempo = 0; // Process more events std::vector<MidiTrack>::iterator i=Tracks.begin(), end=Tracks.end(); while(i != end) { if(i->Offset >= i->data.size() || i->SamplesLeft >= 1.) { i++; continue; } if(i->data.size() - i->Offset < 3) { i->Offset = i->data.size(); i++; continue; } ALubyte event = i->data[i->Offset++]; ALubyte parm1, parm2; if(!(event&0x80)) { event = i->LastEvent; i->Offset--; } if((event&MIDI_EVENT_MASK) != MIDI_SPECIAL) i->LastEvent = event; parm1 = i->data[i->Offset]; parm2 = i->data[i->Offset+1]; int channel = event&MIDI_CHANNEL_MASK; switch(event&MIDI_EVENT_MASK) { case MIDI_NOTEOFF: fluid_synth_noteoff(fluidSynth, channel, parm1); i->Offset += 2; break; case MIDI_NOTEON: fluid_synth_noteon(fluidSynth, channel, parm1, parm2); i->Offset += 2; break; case MIDI_POLYPRESS: i->Offset += 2; break; case MIDI_CTRLCHANGE: fluid_synth_cc(fluidSynth, channel, parm1, parm2); i->Offset += 2; break; case MIDI_PRGMCHANGE: fluid_synth_program_change(fluidSynth, channel, parm1); i->Offset += 1; break; case MIDI_CHANPRESS: fluid_synth_channel_pressure(fluidSynth, channel, parm1); i->Offset += 1; break; case MIDI_PITCHBEND: fluid_synth_pitch_bend(fluidSynth, channel, (parm1&0x7F) | ((parm2&0x7F)<<7)); i->Offset += 2; break; case MIDI_SPECIAL: switch(event) { case MIDI_SYSEX: { unsigned long len = i->ReadVarLen(); if(i->data.size() - i->Offset < len) { i->Offset = i->data.size(); break; } if(i->data[i->Offset+len-1] == MIDI_SYSEXEND) { char *data = reinterpret_cast<char*>(&i->data[i->Offset]); fluid_synth_sysex(fluidSynth, data, len-1, NULL, NULL, NULL, false); } i->Offset += len; break; } case MIDI_SYSEXEND: { unsigned long len = i->ReadVarLen(); if(i->data.size() - i->Offset < len) { i->Offset = i->data.size(); break; } i->Offset += len; break; } case MIDI_SONGPOS: i->Offset += 2; break; case MIDI_SONGSEL: i->Offset += 1; break; case MIDI_META: { ALubyte metatype = i->data[i->Offset++]; unsigned long val = i->ReadVarLen(); if(i->data.size() - i->Offset < val) { i->Offset = i->data.size(); break; } if(metatype == MIDI_META_EOT) { i->Offset = i->data.size(); break; } if(metatype == MIDI_META_TEMPO && val >= 3) { newtempo = (i->data[i->Offset] << 16) | (i->data[i->Offset+1] << 8) | (i->data[i->Offset+2]); } i->Offset += val; break; } default: /* The rest of the special events don't have any * data bytes */ break; } break; default: /* Shouldn't ever get to here */ break; } unsigned long val = i->ReadVarLen(); i->SamplesLeft += val * samplesPerTick; } if(newtempo) UpdateTempo(newtempo); }