【问题标题】:Visual C++ - MIDI PlayerVisual C++ - MIDI 播放器
【发布时间】:2012-08-14 06:14:23
【问题描述】:

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

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

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

【问题讨论】:

    标签: winforms visual-studio-2010 visual-c++ midi


    【解决方案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;
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2022-11-10
        • 1970-01-01
        • 2014-05-28
        • 2019-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多