그래서 저는 midiOutShortMsg()를 사용하여 C#에서 단일 음표를 연주하려고합니다. 문제는 사운드가 재생되지 않는다는 것입니다. 내가 노트를 연주하는 것으로 알아 낸 한 가지 방법은 i = 0에서 10000까지의 for 루프에 midiOutShortMsg()를 삽입하는 것입니다.하지만 API가 작동하는 방법은 그렇게 생각하지 않습니다.C# midioutshortmsg no sound
나중에 프로젝트에서 MIDI를 Kinect 프로젝트에 구현하고 for 루프를 사용하여 Kinect의 실시간 피드백을 지연시킵니다. 그래서 for 루프 메서드는 no-go이다.
다음은 메모를 재생할 때 사용하는 코드입니다. for 루프를 주석 처리하면 소리가 재생되지 않습니다. 어떤 도움을 주시면 감사하겠습니다.
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace MIDITest
{
[StructLayout(LayoutKind.Sequential)]
public struct MidiOutCaps
{
public UInt16 wMid;
public UInt16 wPid;
public UInt32 vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst = 32)]
public String szPname;
public UInt16 wTechnology;
public UInt16 wVoices;
public UInt16 wNotes;
public UInt16 wChannelMask;
public UInt32 dwSupport;
}
class Program
{
// MCI INterface
[DllImport("winmm.dll")]
private static extern long mciSendString(string command,
StringBuilder returnValue, int returnLength,
IntPtr winHandle);
// Midi API
[DllImport("winmm.dll")]
private static extern int midiOutGetNumDevs();
[DllImport("winmm.dll")]
private static extern int midiOutGetDevCaps(Int32 uDeviceID,
ref MidiOutCaps lpMidiOutCaps, UInt32 cbMidiOutCaps);
[DllImport("winmm.dll")]
private static extern int midiOutOpen(ref int handle,
int deviceID, MidiCallBack proc, int instance, int flags);
[DllImport("winmm.dll")]
private static extern int midiOutShortMsg(int handle,
int message);
[DllImport("winmm.dll")]
private static extern int midiOutClose(int handle);
private delegate void MidiCallBack(int handle, int msg,
int instance, int param1, int param2);
static void Main()
{
int handle = 0;
var numDevs = midiOutGetNumDevs();
Console.WriteLine("You have {0} midi output devices", numDevs);
MidiOutCaps myCaps = new MidiOutCaps();
var res = midiOutGetDevCaps(0, ref myCaps,
(UInt32)Marshal.SizeOf(myCaps));
res = midiOutOpen(ref handle, 0, null, 0, 0);
byte[] data = new byte[4];
data[0] = 0x90;
data[1] = 50;
data[2] = 111;
uint msg = BitConverter.ToUInt32(data, 0);
for (int i = 0; i < 10000; i++)
{
// both hard coding the message and creating it with byte doesn't work
//res = midiOutShortMsg(handle, 0x007F4A90);
res = midiOutShortMsg(handle, (int)msg);
}
res = midiOutClose(handle);
Console.ReadLine();
}
}
}
이 방법이 잘못되었다고 생각합니다. 이를 위해 기존의 MIDI 라이브러리를 사용하십시오. 나는 [naudio] (https://github.com/naudio/NAudio)를 존경합니다. 이미 잘 테스트되어야하는 MIDI IO 용 관리 랩퍼가 포함되어 있습니다. 왜 당신은 바이트 순서에 대해 걱정하고, 미디 래퍼 작성에 엄청난 시간을 낭비하지 않고 그것을 사용하지 않습니까? 그것은 당신에게 시간을 절약하고 상자에서 보편적 인 응용 프로그램을 지원합니다. 너는 너의 프로젝트에 그것을 (nuget 할 수있다) (https://www.nuget.org/packages/NAudio/) 쉽게. – spender
안녕하세요, 귀하의 회신을 보내 주셔서 감사합니다! 저는 하루 종일 naudio에서 일해 왔지만, 하나의 노트를 연주 할 때도 System.Threading.Thread.Sleep()을 사용해야한다는 것을 알게되었습니다. 그리고 단일 음표를 연주하면 전체 프로그램이 중단되고 소리가 들리지 않는 동일한 문제가 발생합니다. 어떤 대안을 알게됩니까? – Shinsuke