1

我正在创建一个需要播放 MIDI 文件的应用程序。我试过这段代码:

SoundPlayer^ player = gcnew SoundPlayer();
player->SoundLocation = path2+"\\aw.mid";
player->Load();
player->PlaySync();

它告诉我它只能播放波形文件。我可以让它以某种方式播放midi文件吗?或者我可以使用其他代码吗?
E: 现在我有了 NAudio 库,但是我找不到可以播放我的 midi 的代码。

4

2 回答 2

1

据我所知,.net 框架中没有任何东西可以让您播放 MIDI 文件。尝试改用NAudio 库,它是开源的。从他们的主页:

NAudio 是一个开源 .NET 音频和 MIDI 库,包含数十个有用的音频相关类,旨在加速 .NET 中音频相关实用程序的开发。

于 2012-08-17T20:36:49.283 回答
1

NAudio 可能是一个很好的解决方案,但我发现根据我的经验,代码有点像意大利面条,不能很好地解释自己。这是来自 OpenMidiProject 的 midi 播放器的一些代码示例,您需要下载他们的源文件(头文件、库和 dll),但我一直喜欢使用他们的东西。基本上,这个库所做的是它会自动解析和播放 midi 事件。

如果您对使用此代码有任何疑问,请随时提出。它确实可以编译,所以如果你在编译它时遇到任何问题,它必须在你的最后。

#include <stdio.h>
#include <windows.h>
#include "..\\MIDIIO\\MIDIIO.h"
#include "..\\MIDIData\\MIDIData.h"
#include "..\\MIDIClock\\MIDIClock.h"
/* Don't forget to add MIDIIO(d).lib to your project */
/* Don't forget to add MIDIData(d).lib to your project */
/* Don't forget to add MIDIClock(d).lib to your project */

int main () {
  long lTimeMode = 0;
  long lTimeResolution = 0;
  long lTempo = 60000000 / 120; /* [microsec/quarter note] */
  long lEndTime = 0;
  long lOldTime = 0;
  long lCurTime = 0;
  MIDIOut* pMIDIOut = NULL;
  MIDIData* pMIDIData = NULL;
  MIDITrack* pMIDITrack = NULL;
  MIDIEvent* pMIDIEvent = NULL;
  MIDIClock* pMIDIClock = NULL;

  pMIDIOut = MIDIOut_Open ("Microsoft GS Wavetable Synth");
  if (pMIDIOut == NULL) {
    printf ("MIDIOut Open failed.\n");
    return 0;
  }

  pMIDIData = MIDIData_LoadFromSMF ("test.mid");
  if (pMIDIData == NULL) {
    printf ("MIDIData Load failed.\n");
    return 0;
  }

  lTimeMode = MIDIData_GetTimeMode (pMIDIData);
  lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
  lEndTime = MIDIData_GetEndTime (pMIDIData);

  pMIDIClock = MIDIClock_Create (lTimeMode, lTimeResolution, lTempo);
  if (pMIDIClock == NULL) {
    printf ("MIDIClock_Create failed.\n");
    return 0;
  }

  printf ("Now playing...\n");
  MIDIClock_Start (pMIDIClock);

  while (lCurTime <= lEndTime) {
    lCurTime = MIDIClock_GetTickCount (pMIDIClock);
    forEachTrack (pMIDIData, pMIDITrack) {
      forEachEvent (pMIDITrack, pMIDIEvent) {
        long lTime = MIDIEvent_GetTime (pMIDIEvent);
        if (lOldTime <= lTime && lTime < lCurTime) {
          if (MIDIEvent_IsTempo (pMIDIEvent)) {
            long lTempo = MIDIEvent_GetTempo (pMIDIEvent);
            MIDIClock_SetTempo (pMIDIClock, lTempo);
          }
          if (MIDIEvent_IsMIDIEvent (pMIDIEvent) ||
            MIDIEvent_IsSysExEvent (pMIDIEvent)) {
            unsigned char byMessage[256];
            long lLen = MIDIEvent_GetLen (pMIDIEvent);
            MIDIEvent_GetData (pMIDIEvent, byMessage, 256);
            MIDIOut_PutMIDIMessage (pMIDIOut, byMessage, lLen);
          }
        }
      }
    }
    lOldTime = lCurTime;
    Sleep (5);
  }
  MIDIClock_Stop (pMIDIClock);
  printf ("Now end.\n");

  MIDIClock_Delete (pMIDIClock);
  MIDIData_Delete (pMIDIData);
  MIDIOut_Close (pMIDIOut);
  return 1;
}
于 2016-04-04T00:02:51.507 回答