C# 调用 winmm.dll 播放 midi 文件

在C#中调用 winmm.dll(Windows Multimedia Library)来播放 MIDI 文件通常涉及使用mciSendString 函数,该函数是 winmm.dll 中提供的一个函数,用于发送 MCI(Media Control Interface)命令给MCI设备。

但是,需要注意的是,直接通过 mciSendString 播放 MIDI 文件可能需要一些特定的设置和配置,因为MIDI通常是通过MIDI输出设备(如声卡上的MIDI端口或MIDI合成器)来播放的,而不是通过默认的音频输出设备。

编写一个简单的示例 play_mid.cs,说明如何在C#中使用 P/Invoke 调用 mciSendString 函数来尝试播放 MIDI 文件:

using System;
using System.IO;
using System.Text;
using System.Threading; 
using System.Runtime.InteropServices;  
  
class MidiPlayer  
{  
    // 导入 mciSendString 函数  
    [DllImport("winmm.dll")]  
    private static extern int mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback);  
  
    // 播放MIDI文件的函数  
    public static void PlayMidi(string midiFileName)  
    {  
        const int bufferSize = 128;  
        StringBuilder returnBuffer = new StringBuilder(bufferSize);  
  
        // 构建MCI命令来打开并播放MIDI文件  
        string command = "open \"" + midiFileName + "\" type sequencer alias myMidi";  
        if (mciSendString(command, returnBuffer, bufferSize, IntPtr.Zero) != 0)  
        {  
            Console.WriteLine("Error open MIDI file: " + returnBuffer.ToString());  
            return;  
        }  
  
        // 构建MCI命令来播放MIDI文件  
        command = "play myMidi";  
        if (mciSendString(command, returnBuffer, bufferSize, IntPtr.Zero) != 0)  
        {  
            Console.WriteLine("Error play MIDI file: " + returnBuffer.ToString());  
            return;  
        }  
  
    }  
  
    static void Main(string[] args)  
    {  
        if (args.Length <1){
            Console.WriteLine(" usage: play_mid.exe file1.mid ");
            return;
        }  
        string filename = args[0];
        if (!File.Exists(filename)){
            Console.WriteLine(filename +" is not exists");
            return;
        }
        string ext = Path.GetExtension(filename).ToLower();
        if (!string.Equals(ext, ".mid")) {
            Console.WriteLine(filename +" extension is not .mid ");
            return;
        }
        Console.WriteLine("play: " + filename);
        PlayMidi(filename);
        
        StringBuilder status = new StringBuilder(255);
        // 循环,每秒查询一次状态
        while (true)
        {
            // 获取状态
            mciSendString("status myMidi mode", status, status.Capacity, IntPtr.Zero); 
            // 判断状态
            if (string.Compare("playing", status.ToString()) !=0) break; 
            // 暂停一秒
            Thread.Sleep(1000);
        }
 
        // 关闭媒体文件
        mciSendString("close myMidi", null, 0, IntPtr.Zero);
        //Console.ReadKey();
    }  
}

where csc
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe

编译  csc play_mid.cs

运行 play_mid.exe  test1.mid

C# 直接调用 OpenFileDialog,打开文件夹,选择*.mid文件,并播放。

编写  open_mid.cs  如下

// open a midi file
using System;
using System.Diagnostics;
using System.Windows.Forms;
 
public class OpenMidFile
{
    [STAThread]
    public static void Main()
    {
        OpenFileDialog ofd = new OpenFileDialog();
 
        // 设置对话框属性
        ofd.Title = "请选择.mid文件";
        // 设置初始目录
        ofd.InitialDirectory = "D:\\Music";
        // 设置文件过滤器
        ofd.Filter = "mid files (*.mid)|*.mid";
        ofd.FilterIndex = 1; // 设置默认的文件过滤器索引
        ofd.RestoreDirectory = true; // 设置在关闭对话框前还原目录
 
        if (ofd.ShowDialog() == DialogResult.OK) // 显示对话框
        {
            // 获取选中的文件路径
            string filePath = ofd.FileName;
            ProcessStartInfo startInfo = new ProcessStartInfo("play_mid.exe");
            startInfo.Arguments = " " +filePath;
            startInfo.UseShellExecute = false;
        
            Process process = Process.Start(startInfo);
            process.WaitForExit();
        } else {
            Console.WriteLine("Select null");
        }
    }
}

编译  csc /r:System.Windows.Forms.dll /target:winexe open_mid.cs

运行  open_mid.exe

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值