403 lines
9.9 KiB
Plaintext
403 lines
9.9 KiB
Plaintext
|
|
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<midiData.getEventCount();index++)
|
|
{
|
|
PureEvent &pureEvent=midiData.getEventAt(index);
|
|
if(144==pureEvent.eventType()&&requiredChannel==pureEvent.channel())
|
|
{
|
|
::OutputDebugString(pureEvent.toString()+String("\n"));
|
|
}
|
|
// ::OutputDebugString(pureEvent.toString()+String("\n"));
|
|
|
|
// eventType:144 [ MIDINoteOn] deltaTime: 31 playTime: 2323643 channel: 0 byteOne: 74 byteTwo: 62 midiTime: 0
|
|
// midiChannelMessage(PureEvent(mEventType,mDeltaTime,channel,mNoteOn.pitch(),mNoteOn.velocity()));
|
|
// PureEvent(BYTE eventType,DWORD deltaTime,BYTE channel,BYTE firstData,BYTE secondData);
|
|
// pureEvent.playTime();
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
CallbackData::ReturnType MidiData::timerEvent(CallbackData &someCallbackData)
|
|
{
|
|
DWORD currTime(getSystemTime());
|
|
|
|
if(!mMIDIOutDevice.hasDevice()||!mMIDIEventVector.size())return closeDevice();
|
|
while(mMIDIEventVector[mPlayIndex].playTime()<=currTime)
|
|
{
|
|
if(!mMIDIOutDevice.midiEvent(mMIDIEventVector[mPlayIndex]))return closeDevice();
|
|
if(++mPlayIndex>=mMIDIEventVector.size())return closeDevice();
|
|
}
|
|
return (CallbackData::ReturnType)TRUE;
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _MIDISEQ_TIMEBLOCK_HPP_
|
|
#define _MIDISEQ_TIMEBLOCK_HPP_
|
|
#ifndef _COMMON_WINDOWS_HPP_
|
|
#include <common/windows.hpp>
|
|
#endif
|
|
|
|
#ifndef _COMMON_ARRAY_HPP_
|
|
#include <common/array.hpp>
|
|
#endif
|
|
|
|
#ifndef _COMMON_BLOCK_HPP_
|
|
#include <common/block.hpp>
|
|
#endif
|
|
#ifndef _MIDISEQ_PUREEVENT_HPP_
|
|
#include <midiseq/pureevnt.hpp>
|
|
#endif
|
|
#ifndef _MIDISEQ_EVENTBLOCK_HPP_
|
|
#include <midiseq/evntblck.hpp>
|
|
#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<PureEvent> &sortedEvents);
|
|
void printBlock(String pathFileName,Array<PureEvent> &eventVector);
|
|
private:
|
|
void fixTimeBlock(EventBlock &midiEventBlock);
|
|
void sortBlocks(MIDIBlock &midiEventBlocks,Array<PureEvent> &sortedEvents);
|
|
void calculateRealTime(Array<PureEvent> &eventBlock);
|
|
void calculateRealTime(MIDIBlock &midiEventBlocks);
|
|
|
|
void dumpTimeVector(Array<PureEvent> &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<PureEvent> &eventBlock)
|
|
{
|
|
DWORD numEvents(eventBlock.size());
|
|
double realTime;
|
|
|
|
if(!numEvents)return;
|
|
for(DWORD eventIndex=0;eventIndex<numEvents;eventIndex++)
|
|
{
|
|
PureEvent &pureEvent=eventBlock[eventIndex];
|
|
realTime=((((double)pureEvent.tempo()*(double)pureEvent.playTime())/(double)mDivision)/1000.00)+(double)mStartTime;
|
|
pureEvent.playTime(realTime);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
inline
|
|
DWORD MidiData::getEventCount(int track)
|
|
{
|
|
return mMIDIEvents[track].size();
|
|
}
|
|
|
|
|
|
inline
|
|
bool MidiData::getTracks(Block<PureWORD> &tracks)
|
|
{
|
|
return mMIDIEvents.getTracks(tracks);
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
// DWORD getEventCount(int track);
|
|
// bool getTracks(Block<PureWORD> &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;
|
|
}
|