PureEvent pureEvent(eventBlock[eventIndex]); switch(pureEvent.eventType()&0xF0) { case MIDIChannelPressure : {eventString="MIDIChannelPressure(0xD0)";break;} case MIDIProgramChange : {eventString="MIDIProgramChange(0xC0)";break;} case MIDIKeyPressure : {eventString="MIDIKeyPressure(0xA0)";break;} case MIDIParameter : {eventString="MIDIParameter(0xB0)";break;} case MIDIPitchBend : {eventString="MIDIPitchBend(0xE0)";break;} case MIDINoteOff : {eventString="MIDINoteOff(0x80)";break;} case MIDINoteOn : {eventString="MIDINoteOn(0x90)";break;} default : {eventString="UNKNOWN";break;} } ::fprintf(lpFilePointer,"eventType:%3d [% 20s] deltaTime:%5ld playTime:%10ld channel:%2d firstData:%4d secondData:%4d midiTime:%10ld\n", (short)pureEvent.eventType(), (LPSTR)eventString, pureEvent.deltaTime(), pureEvent.playTime(), (short)pureEvent.channel(), (short)pureEvent.firstData(), (short)pureEvent.secondData(), pureEvent.midiTime()); || C | C# | D | D# | E | F | F# | G | G# | A | A# | B ------------------------------------------------------------------------------ 0 || 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 1 || 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 2 || 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 3 || 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 4 || 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 5 || 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 6 || 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 7 || 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 8 || 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 9 || 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 10 || 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | } static int pitchArray[11][12]; int size=sizeof(pitchArray)/sizeof(int); for(int octave=0;octave<11;octave++) { for(int note=0;note<12;note++) { if(10==octave&¬e>127)break; pitchArray[octave][note]=(octave*12)+note; } } || C | C# | D | D# | E | F | F# | G | G# | A | A# | B ------------------------------------------------------------------------------ 0 || 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 1 || 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 2 || 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 3 || 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 4 || 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 5 || 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 6 || 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 7 || 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 8 || 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 9 || 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 10 || 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | */ // ChannelModeMessage channelModeMessage(ChannelModeMessage::Sustain); // mMIDIDevice->midiEvent(channelModeMessage.getEvent(0)); // mMIDIDevice->midiEvent(PureEvent(MIDIChannelPressure,0,0,50,0)); // PureEvent(BYTE eventType,DWORD deltaTime,BYTE channel,BYTE firstData,BYTE secondData); /* 1010nnnn 2 Polyphonic key pressure/after touch 1011nnnn 2 Control change 1100nnnn 1 Program change 1101nnnn 1 Channel pressure/after touch */ inline WORD PureEvent::operator==(const PureEvent &somePureEvent)const { return mPlayTime==somePureEvent.mPlayTime&&eventType()==somePureEvent.eventType(); /* return (mEventType==somePureEvent.mEventType&& mChannel==somePureEvent.mChannel&& mFirstData==somePureEvent.mFirstData&& mSecondData==somePureEvent.mSecondData&& mDeltaTime==somePureEvent.mDeltaTime&& mPlayTime==somePureEvent.mPlayTime&& mMIDITime==somePureEvent.mMIDITime); */ } class PitchBend { public: enum {MinPitch=0x0000,MaxPitch=0x3FFF,CenterPitch=0x2000}; PitchBend(void); PureEvent getEvent(void)const; void setPitch(WORD pitch); WORD getPitch(void)const; void centerWheel(void); private: BYTE getLo(void)const; BYTE getHi(void)const; WORD mPitch; }; inline PitchBend::PitchBend() : mPitch(CenterPitch) { } inline void PitchBend::setPitch(WORD pitch) { if(pitch>MaxPitch)pitch=MaxPitch; mPitch=pitch; } inline WORD PitchBend::getPitch(void)const { return mPitch; } inline void PitchBend::centerWheel(void) { mPitch=CenterPitch; } inline BYTE PitchBend::getLo(void)const { return mPitch&0xFF; } inline BYTE PitchBend::getHi(void)const { return mPitch>>8; } inline PureEvent PitchBend::getEvent(void)const { String strPitch; ::sprintf(strPitch.str(),"lo:0x%04lx hi:0x%04lx\n",getLo(),getHi()); ::OutputDebugString(strPitch.str()); PureEvent pureEvent(MIDIPitchBend,0,0,getHi(),getLo()); return pureEvent; } void testNotes(void) { MIDIOutputDevice midiOut; NoteOn noteOn(PureNote(70,60)); PitchBend pitchBend; pitchBend.setPitch(0x0); pitchBend.setPitch(0x2000+128); // pitchBend.setPitch(0x3FFF); NoteOff noteOff(PureNote(70,60)); if(!midiOut.openDevice())return; midiOut.midiEvent(noteOn.getEvent()); midiOut.midiEvent(pitchBend.getEvent()); pitchBend.setPitch(0x2000); midiOut.midiEvent(pitchBend.getEvent()); midiOut.midiEvent(noteOn.getEvent()); midiOut.midiEvent(noteOff.getEvent()); midiOut.closeDevice(); return; } void testEvent(void) { String musicFileName("D:\\WORK\\SCENE\\MEDIA\\BMP\\E1M2.MID"); int requiredChannel=0; MidiData midiData(musicFileName); midiData.makeRealTime(); ::OutputDebugString(String("MIDI events=")+String().fromInt(midiData.getEventCount())); for(int index=0;index=mMIDIEventVector.size())return closeDevice(); } return (CallbackData::ReturnType)TRUE; } */ #ifndef _MIDISEQ_TIMEBLOCK_HPP_ #define _MIDISEQ_TIMEBLOCK_HPP_ #ifndef _COMMON_WINDOWS_HPP_ #include #endif #ifndef _COMMON_ARRAY_HPP_ #include #endif #ifndef _COMMON_BLOCK_HPP_ #include #endif #ifndef _MIDISEQ_PUREEVENT_HPP_ #include #endif #ifndef _MIDISEQ_EVENTBLOCK_HPP_ #include #endif class MIDIBlock; class TimeBlock { public: TimeBlock(void); virtual ~TimeBlock(); void setStartTime(DWORD startTime); // void setTempo(DWORD tempo); void setDivision(DWORD division); void fixTimeBlock(MIDIBlock &midiEvents,Array &sortedEvents); void printBlock(String pathFileName,Array &eventVector); private: void fixTimeBlock(EventBlock &midiEventBlock); void sortBlocks(MIDIBlock &midiEventBlocks,Array &sortedEvents); void calculateRealTime(Array &eventBlock); void calculateRealTime(MIDIBlock &midiEventBlocks); void dumpTimeVector(Array &eventBlock,String pathFileName); void operator=(const TimeBlock &someTimeBlock); // DWORD mTempo; DWORD mDivision; DWORD mStartTime; }; inline TimeBlock::TimeBlock(void) : mStartTime(0L), mDivision(136L) // , mTempo(5000000L), { } inline TimeBlock::~TimeBlock() { } inline void TimeBlock::setStartTime(DWORD startTime) { mStartTime=startTime; } /* inline void TimeBlock::setTempo(DWORD tempo) { mTempo=tempo; } */ inline void TimeBlock::setDivision(DWORD division) { mDivision=division; } inline void TimeBlock::operator=(const TimeBlock &/*someTimeBlock*/) { return; } #endif // realTime=((((double)midiEvent.tempo()*(double)midiEvent.playTime())/(double)mDivision)/1000.00)+(double)mStartTime; void TimeBlock::calculateRealTime(Array &eventBlock) { DWORD numEvents(eventBlock.size()); double realTime; if(!numEvents)return; for(DWORD eventIndex=0;eventIndex &tracks) { return mMIDIEvents.getTracks(tracks); } */ // DWORD getEventCount(int track); // bool getTracks(Block &tracks); bool MIDIOutputDevice::openDevice(int deviceID) { UINT numDevs; closeDevice(); if(-1==deviceID) { mMIDIDeviceID=MIDIMAPPER; return openDevice(); } if(!(numDevs=::midiOutGetNumDevs()))return false; if(deviceID>=numDevs)return false; // if(::midiOutOpen(&mhMIDIOutput,mMIDIDeviceID,0,0,0))return false; if(::midiOutOpen(&mhMIDIOutput,deviceID,0,0,0))return false; mMIDIDeviceID=deviceID; hasDevice(true); getDeviceCapabilities(); return true; }