2008年7月22日星期二

转用firefox

为了访问sourceforge,使用gladder“爬墙”,今天开始转向firefox。
firefox+gladder还是无法顺利访问sourceforge,于是注册Linkideo方可。
无语。

2008年7月21日星期一

使用win32 MCI系列接口实现capture midi

使用win32 MCI系列接口实现capture midi基本步骤:
调用midiInGetNumDevs获得接入的midi input 设备数目和id.
调用midiInGetDevCaps轮询manufacture id,product id 和product name,记录下符合条件的 id
使用id 调用midiInOpen获得HMIDIIN gMidiInHandle,设置callback函数MidiInProc
使用gMidiInHandle midiInStart就可以开始记录,当有message

callback函数MidiInProc基本结构:
void CALLBACK MidiInProc(
  HMIDIIN hMidiIn,  
  UINT wMsg,  
  DWORD dwInstance, 
  DWORD dwParam1,  
  DWORD dwParam2  
)
{
  switch(wMsg)
  {
  case MIM_CLOSE:On_Mim_Close(hMidiIn,wMsg,dwInstance,dwParam1,dwParam2);break;
  case MIM_DATA:On_Mim_Data(hMidiIn,dwParam1,dwParam2);break;
  case MIM_ERROR:On_Mim_Error(hMidiIn,wMsg,dwInstance,dwParam1,dwParam2);break;
  case MIM_LONGDATA:On_Mim_LongData(hMidiIn,wMsg,dwInstance,dwParam1,dwParam2);break;
  case MIM_LONGERROR:On_Mim_LongError(hMidiIn,wMsg,dwInstance,dwParam1,dwParam2);break;
  case MIM_MOREDATA:On_Mim_MoreData(hMidiIn,wMsg,dwInstance,dwParam1,dwParam2);break;
  case MIM_OPEN:On_Mim_Open(hMidiIn,wMsg,dwInstance,dwParam1,dwParam2);break;
  default:assert(0&&"Unknown Midi In Msg");break;
  }
}
dwParam1是event内容,dwParam2是timestamp,拨动弦,或按下品格将收到MIM_DATA消息,但奇怪的是释放品格时没有收到这个消息,根据使用directmusic中的经验,估计释放品格也是只发出system exclusive message。
接收system exclusive message步骤,除基本步骤外,还需要:
调用midiInPrepareHeader 创建MIDIHDR gMidiHdr,在将gMidiHdr传给midiInPrepareHeader需要设置好gMidiHdr.dwBufferLength,gMidiHdr.lpData,gMidiHdr.dwFlags,例如:
  gMidiHdr.dwBufferLength = 512;
  gMidiHdr.lpData = (LPSTR)malloc(gMidiHdr.dwBufferLength);
  gMidiHdr.dwFlags = MHDR_PREPARED;
  ret = midiInPrepareHeader(gMidiInHandle,&gMidiHdr,sizeof(gMidiHdr));
调用midiInAddBuffer(gMidiInHandle,&gMidiHdr,sizeof(gMidiHdr));
当收到MIM_LONGDATA,dwParam1是gMidiInHandle的地址,通过gMidiInHandle可以获得buffer中的数据,当做完相关的处理之后,再调用一次midiInAddBuffer(gMidiInHandle,&gMidiHdr,sizeof(gMidiHdr));

问题:
在现在的Demo中解析“system exclusive message”只适合判断品格的状态(按下,释放,按住),若要判断具体某个弦被拨动时按下的品格则必须解析MIM_DATA中内容,不知道这样的处理方法是midi设备通常的情况,还是仅是当前这个设备的情况。