#include MidiData::MidiData(const String &midiPathFileName) : mTimerCallback(this,&MidiData::timerEvent), mMidiFile(midiPathFileName,FileIO::BigEndian), MidiTrack(mMidiFile) { insertHandler(&mTimerCallback); if(!readHeader(mMidiFile))return; ::OutputDebugString(String("[MidiData::MidiData]MIDI header=")+String(MidiHeader::toString()+String("\n")).str()); setMethod(timingMethod()); mStartOfTracks=mMidiFile.tell(); } MidiData::~MidiData() { stopTimer(); mMIDIOutDevice.closeDevice(); } bool MidiData::play(WORD blocking) { if(!makeRealTime())return false; startTimer(TimerDelay); if(blocking)waitEvent(); return true; } bool MidiData::makeRealTime(void) { TimeBlock timeBlock; if(!tracks())return false; mCurrentTrack=0; mMidiFile.seek(mStartOfTracks,FileIO::SeekBeginning); while(readTrack())mCurrentTrack++; timeBlock.setDivision(method()); timeBlock.setStartTime(getSystemTime()+TwoSecs); timeBlock.fixTimeBlock(mMIDIEvents); mMIDISequencer.setData(mMIDIEvents); return true; } CallbackData::ReturnType MidiData::timerEvent(CallbackData &/*someCallbackData*/) { if(!mMIDISequencer.sequence(mMIDIOutDevice))return closeDevice(); return true; } CallbackData::ReturnType MidiData::closeDevice(void) { mMIDIOutDevice.closeDevice(); return (CallbackData::ReturnType)FALSE; } // virtual overloads void MidiData::midiChannelMessage(PureEvent &midiEvent) { midiEvent.tempo(mCurrentTempo.microsecsPerQtrNote()); mMIDIEvents[mCurrentTrack].insert(&midiEvent); return; } void MidiData::setTempo(DWORD microsecsPerQtrNote) { mCurrentTempo.microsecsPerQtrNote(microsecsPerQtrNote); return; } void MidiData::smpteFormat(const SMPTEFormat &someSMPTEFormat) { mSMPTEFormat=someSMPTEFormat; return; } void MidiData::timeSignature(const TimeInfo &/*someTimeInfo*/) { return; }