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

C#开发音频--WinMM.dll 函数汇总 auxGetDevCaps                  查询指定的辅助输出设备以确定其性能auxGetNumDevs                  检取系统中存在的辅助输出设备的数量auxGetVolume                   返回指定的辅助输出设备的当前卷设备auxOutMessage                  向指定的辅助输出设备发送一条消息auxSetVol 阅读详情

在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

Windows 声音处理编程(基于winmm.dll)(3) 这一篇介绍向声卡发送数据的方法。首先在C#中重写midiOutOpen和midiOutShortMsg方法: //打开指定的MIDI输出设备进行回放 [DllImport("winmm.dll")]         public static extern uint midiOutOpen(out IntPtr lphMidiOut, uint uDeviceID, IntPtr dwC 阅读详情

相关推荐

C#实战:如何用winmm.dll打造毫秒级高精度定时器(附完整代码)

本文详细介绍了在C#中利用winmm.dll实现毫秒级高精度定时器的完整方案。针对.NET内置定时器精度不足的问题,通过调用timeSetEvent等原生API,提供了超越系统时钟中断周期的精准定时能力。文章包含核心原理剖析、完整的封装类代码以及音视频处理、游戏开发等场景下的实战应用与性能调优指南。

ujm5678901的博客 690

C#调用Winmm.dll 的MciSendString无法保存音频文件解决方案

Winmm.dll保存文件失败问题分析与解决方法 最近在调用Winmm.dll的MciSendString save函数保存音频时,发现怎么保存都没有用。 这是保存的相关代码 mciSendString("stop movie", "", 0, 0); int mc_Res= mciSendString("save movie X://x//xxxx//xxxx/xxxx/xxxx.wav...

jinfengdk1995的博客 861

C#实战指南:利用winmm.dll打造毫秒级高精度定时器

本文详细介绍了如何在C#中利用winmm.dll实现毫秒级高精度定时器。通过调用timeSetEvent和timeKillEvent等核心API,解决了System.Timers.Timer精度不足的问题。文章提供了完整的封装类实现、线程安全处理方案,并通过实战测试对比展示了其相较于系统定时器的显著精度优势,适用于音视频处理、数据采集等对时序要求严格的场景。

backprop5master的博客 406

android播放midi api,C#调用Windows Api播放midi音频

导入winmm.dll中的函数mciSendString[DllImport("winmm.dll")]static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);需要注意的是,所有命令需要在同一个线程中,才可以对同一个midi实例进行控...

weixin_33705384的博客 400

C#写的WinForm程序,可实现Midi播放并转化为乐谱

近期对音乐编程感兴趣,然后想做一个midi播放编辑器,无意中从一个小论坛坟贴中找到的这个资源,C#写的WinForm程序,可实现Midi播放并转化为乐谱实时显示,功能十分强大。

unity-midi:使用C#Synth Project在Unity上播放MIDI(SMF)

统一中 在Unity上播放SMF(标准MIDI文件)。 总览 一个纯净的C#MIDI库( )在Unity上进行了少量修改,效果很好。 该存储库包含修改后的库和示例代码,以使用播放SMF。 替代方法 使用本地支持的MIDI API将获得更好的质量。 以下可能是有用的参考。 外部资源和代码的许可 :MIT许可证 :公共领域

Unity游戏开发实战:跨平台MIDI播放与动态音乐生成方案

MIDI(Musical Instrument Digital Interface)作为一种数字音乐指令协议,其核心原理是通过记录音符、力度、时长等乐谱信息而非音频波形,实现了音乐数据的极致压缩与灵活控制。在游戏开发与交互式音频领域,这项技术的价值在于支持运行时动态生成与修改音乐,能够基于游戏逻辑实时驱动音乐演进,极大提升了资源的利用效率与音频的交互性。常见的应用场景包括音乐节奏游戏、RPG动态配乐以及模拟经营类游戏的智能背景音乐适配。本文聚焦于Unity引擎,探讨如何通过集成CSharpSynth合成器库

tyygming的专栏 130

Midi:C#中的Windows MIDI库

提供用于处理MIDI文件,序列和设备的完整托管API

作品1:MIDI彩虹钢琴

几年前我对音乐产生了兴趣,想自己做一个钢琴软件。 研究发现windows提供了播放midi的api,而且midi文件是一般播放器都能播放、结构简单、易编辑、体积小的格式。 之后我用C#/WinForm做了个软件。 【MIDI彩虹钢琴】是【键盘钢琴(128+61+N种乐器、可录制)】、【midi播放器(可倒播)】、【midi编辑制作(4种方式)】、【自动作曲】于一身的免费软件。...

weixin_30819085的博客 573

从零构建边缘AI数据管道:K230+ESP8266的物联网实践指南

本文详细介绍了如何利用K230开发板和ESP8266模块构建高可靠性的边缘AI数据管道,特别针对智能农业监测场景。通过完整的系统架构设计、AI模型部署、低功耗通信优化和云端集成方案,为开发者提供了一套可落地的物联网实践指南,重点解决了边缘计算环境下的数据传输稳定性和能效管理问题。

j2k3l4的博客 872

【调试记录】GT ip跑aurora 64b66b协议

如果不用,会出现这种情况:自回环测试,数据收发ok.一旦和对方通信,对方接收的就是一堆乱码,因为GT链路发送数据不能是全1或全0,或者长时间的1或0.否则线路容易受到干扰,毕竟线速率10多G,用了加扰和解扰,就可以提高抗干扰能力。64B66B编码,数据输入是64bit,输出是66bit,所以这之间存在着2bit的带宽差,Gearbox 就是用来解决这种差异的,实现方式是:将66bit数据拿出来2bit先存入Gearbox,然后输出64bit.发送同步码或控制数据时,配置成2.2.4 加扰和解扰!

weixin_41246509的博客 1601

Dev-C++调用Windows MIDI API播放《起风了》实战指南

MIDI(Musical Instrument Digital Interface)是一种标准化的数字音乐通信协议,其核心是通过短消息(Short Message)在设备间传递音符、控制与同步指令。Windows多媒体子系统通过winmm.dll提供MIDI API封装,使C/C++程序可直接操控音频硬件抽象层。技术价值在于绕过高级音频框架,以底层DWORD位域组装实现对音高、力度、通道与时序的精确控制;典型应用场景包括嵌入式音乐教学、轻量级音效引擎开发及Windows平台音频逆向工程实践。本文聚焦Dev-

weixin_34384557的博客 132

保姆级教程:手把手教你从ENSEMBL官网下载GRCh38/GRCh37的GTF注释文件(附网址规律总结)

本文提供从ENSEMBL官网下载GRCh38/GRCh37的GTF注释文件的详细教程,包括路径解析、版本号确定和下载命令示例。特别解析了GRCh37的特殊存储结构,并分享批量下载、文件校验等高级技巧,帮助生物信息学研究者高效获取基因组注释文件。

weixin_29289821的博客 204

C# WinForm使用乐器数字接口

继续,前面已经实现了C#调用Windows API实现了弹出对话框功能。使用了User32.dll文件,主要代码如下:[DllImport("User32.dll")]public static extern int MessageBox(int h, string m, string c, int type);详情请参考:http://hovertree.com/h/bjaf/psjdasa2....

weixin_30287169的博客 125

BPMN-JS :修改节点“Change Type”事件类型

修改路径:node_modules\bpmn-js\lib\features\replace\ReplaceOptions.js。

TaylorY的博客 678

边云协同智能进化:大模型与小模型的动态训练与高效部署策略

本文深入探讨了边云协同架构下大模型与小模型的动态训练与高效部署策略。通过物流分拣、医疗影像等实战案例,展示了如何利用边云协作框架实现AI模型的智能进化,显著提升处理效率与准确性。重点解析了动态任务分配、增量学习和知识蒸馏等关键技术,为分布式训练场景提供优化方案。

work3的博客 191

调用API让声卡发出声音

1.定义一个枚举,乐器类型 #region 乐器定义 public enum MusicNo:uint { /// <summary> /// //大钢琴 /// </summary> AcousticGrandPiano = 0, /// <summary> ///明亮的...

diaohuofu0847的博客 679

华为od统一考试B卷【宜居星球改造计划】Java&Go 实现

XXX年,人类通过对火星的大气进行宜居改造分析,使得火星已在理论上具备人类宜居的条件,由于技术原因,无法一次性将火星大气全部改造,只能通过局部处理形式,假设将火星待改造的区域为row * column的网格每个网格有3个值,宜居区、可改造区、死亡区,使用YES、NO、NA代替,YES表示该网格已经完成大气改造,NO表示该网格未进行改造,后期可进行改造,NA表示死亡区,不作为判断是否改造完成的宜居,无法穿过 初始化下,该区域可能存在多个宜居区,并且每个宜居区能同时在每个太阳日单位向上下左右四个方向的相邻格子进

MISAYAONE的博客 1万+

Windows多媒体API -低阶(三)

1.1      WINMM.DLL winmm.dll是Windows多媒体相关应用程序接口,用于低档的音频和游戏手柄。 函数汇总: auxGetDevCaps 查询指定的辅助输出设备以确定其性能 auxGetNumDevs 检取系统中存在的辅助输出设备的数量 auxGetVolume 返回指定的辅助输出设

nowhaha的专栏 887

ISO13849功能安全从入门到精通(3):安全功能及其对降低风险的贡献4

例如,如果机器必须在有限速度下运行时进行设置,那么在低加速度值下进行设置时,参数P1将是正确的选择:随着危险缓慢出现并给予足够的运动自由,操作员将能够移出危险区域。例如,在无故障的条件下,在操作者的手的方向移动的滚子不能陷住它。在所有其他情况下,F1是正确的选择,前提是危险暴露的持续时间不超过机器总操作时间的1/20。需求来源于必要的风险降低。由于这些考虑而降低的PLr在任何情况下都不得低于通过比较方式考虑的机器的PLr,因为并不能从事故发生率低和严重程度低得出实施的安全功能提供的安全水平高于要求。

wdconan001的博客 834

1、JMP脚本编程全面指南:从基础到高级应用

本博客全面介绍了JMP脚本编程的各个方面,从JMP基础和JSL入门,到数据类型、数据结构、编程方法、数据表操作、图形与三维场景脚本,再到应用程序创建与扩展功能。内容涵盖脚本工具使用、常见任务实现、兼容性说明及未来发展趋势,旨在帮助用户掌握JMP脚本语言的强大功能,提升数据分析的自动化与定制化能力。适合从初学者到高级用户的深入学习与实践参考。

flink9streamer的博客 266

用VB6来实现QBASIC中的Play语句

很久以前写的了,用Midi的API函数来实现以前QBasic中的Play语句,控制符实现可能还不完善,感觉演奏的还是有些问题,懒得弄了,发出来吧。下边是这个bas模块文件的代码,例程代码等下发。用法,Play "ABCDEFGAB"

Bingo 3万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

c# 使用windows自带winmm.dll 播放音频

今天帮同事完成一个C#应用程式,用户需要在点击完成后发出指定声音。我们使用windows 自带的winmm.dll,这样就不用到处找库了,利有系统播放音频功能完成开发。 下面是完整的核心代码: 1 using System.Runtime.InteropServices; //DllImport的命名空间 2 [DllImport("winmm.dll")]privatestatic...

weixin_33847182的博客 721

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C#调用winmm.dll播放声音_中国创造

C#调用winmm.dll播放声音2006-08-12 08:52下面的 C# 代码示例演示如何在 Windows 平台上使用平台调用服务来播放波形声音文件。 示例 此代码示例使用 DllImport 将 winmm.dll 的 PlaySound 方法入口点作为 Form1 PlaySound() 导入。该示例具有一个带有一个按钮的简单 Windows 窗体。单击该按钮可打开标准 Win

qiuqiu173的专栏 2593

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: 使用 BurpSuite,Yakit 进行常规渗透测试
下一篇: g++:在 Win10 上编译 MIDI 音乐程序(三)
belldeep
博客等级 码龄20年 1820粉丝 584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值