2015年6月24日 星期三

Visual Studio 2013 C++ / Midi output (windows)

最近,花了三週研究 midi 的library, 但是很多的Library都是非常舊的文章,大概嘗試過幾個,都不太成功,也有些library是基於 linux 系統的(unistd.h),因此貼上一個修正版本的midi程式。
嘗試過的library:


midi io library

mmsystem.h

midifile

以下是透過 visual c++ 2013 改造過的 midi 程式碼:

#include "stdafx.h"
#include <conio.h>   
#include <stdio.h>  
#include <iostream>
#include <windows.h>   
#include <mmsystem.h>  

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
 int ckey;
 int notestate = 0;
 int velocity = 100;
 int midiport;
 int flag;
 HMIDIOUT device;
 union { unsigned long word; unsigned char data[4]; } message;

 message.data[0] = 0x90;
 message.data[1] = 60;
 message.data[2] = 100;
 message.data[3] = 0;

 midiport = 0;
 flag = midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL);
 if (flag != MMSYSERR_NOERROR) {
  printf("MIDI錯誤 \n");
  return 1;
 }


 printf("Press \"q\" to quit.\n");
 while (1) {
  if (_kbhit()) {
   ckey = getchar();
   if (notestate == 0) {
    message.data[2] = velocity;
    notestate = 1;
    printf("Note turned ON.\n");
   }
   else {
    message.data[2] = 0;
    notestate = 0;
    printf("Note turned OFF.\n");
   }
   flag = midiOutShortMsg(device, message.word);
   if (flag != MMSYSERR_NOERROR) {
    printf("Warning: MIDI Output is not open.\n");
   }
   if (ckey == 'q') break;
  }
 }

 midiOutReset(device);

 midiOutClose(device);

 return 0;
}

最後,記得在 Linker 中加入一個 winmm.lib 這個library 編譯才會通過

參考文件:
http://www.ccarh.org/courses/253/lab/midiprog/keymidi/keymidi.c
http://improv.sapp.org/doc/howto/basicoutput/
https://code.msdn.microsoft.com/windowsapps/MIDI-Windows-Runtime-sample-4fd6dcbc
http://nauful.com/pages/midiprogramming.html
https://social.msdn.microsoft.com/Forums/vstudio/en-US/7f023e53-a917-458b-af72-783d42f506bb/lphmidiout-hmidiout-and-midioutopen-problem-in-vs2005?forum=vclanguage
http://www.43577.com/show/857284.shtml

沒有留言:

張貼留言

© ERIC RILEY , 自由無須告知轉貼
Background Japanese Sayagata by Olga Libby