首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 音訊播放控制:WinMM API 低延遲播放與記憶體 WAV 資源嵌入技巧

     編輯:關於C語言

避免控制項延遲:直接呼叫 WinMM API

標準元件(如 `SoundPlayer`、`MediaPlayer`)初始化緩衝會造成明顯延遲。對遊戲音效、即時提示等低延遲場景,直接 P/Invoke `winmm.dll` 是最佳選擇。

方案一:MCI 命令播放檔案(支援 MP3/WAV/MP4 等)


using System.Runtime.InteropServices;

public class AudioPlayer {
    [DllImport("winmm.dll")]
    private static extern long mciSendString(string command, StringBuilder returnString, int returnLength, IntPtr callback);

    private string _alias = "MediaFile";

    public void Play(string filePath) {
        _alias = "\"" + filePath + "\"";
        mciSendString($"close {_alias}", null, 0, IntPtr.Zero);
        mciSendString($"open {_alias} type mpegvideo alias MediaFile", null, 0, IntPtr.Zero);
        mciSendString("play MediaFile", null, 0, IntPtr.Zero);
    }

    public void Stop() {
        mciSendString("close MediaFile", null, 0, IntPtr.Zero);
    }
}

關鍵點:路徑含空白需雙引號包裹;`type mpegvideo` 讓 MCI 自動選擇解碼器;`alias` 避免重複開啟衝突。

方案二:sndPlaySound 播放記憶體 WAV(零磁碟 I/O,極低延遲)


public class MemoryWavPlayer {
    private const int SND_ASYNC = 0x0001;
    private const int SND_MEMORY = 0x0004;

    [DllImport("winmm.dll", EntryPoint = "sndPlaySoundA")]
    private static extern int sndPlaySound(byte[] sound, int flags);

    private byte[] _wavBuffer;

    public MemoryWavPlayer(string embeddedResourceName) {
        var asm = Assembly.GetExecutingAssembly();
        using (var stream = asm.GetManifestResourceStream(embeddedResourceName)) {
            _wavBuffer = new byte[stream.Length];
            stream.Read(_wavBuffer, 0, _wavBuffer.Length);
        }
    }

    public void Play() {
        sndPlaySound(_wavBuffer, SND_ASYNC | SND_MEMORY);
    }
}

嵌入 WAV 為資源步驟

  1. 專案右鍵 → Properties → Resources → Add Existing File 選取 `.wav`
  2. 或手動:專案項目設定 `Build Action = Embedded Resource`
  3. 資源名稱格式:`命名空間.檔案名`(如 `MyGame.Sounds.click.wav`)

進階:非同步播放多音效重疊

MCI / sndPlaySound 單一別名/緩衝不支援疊加。需求多聲道混音請改用:

  • NAudio:.NET 專業音訊庫,支援 WASAPI/ASIO、混音、效果器。
  • FMOD / Wwise:工業級遊戲音訊引擎,有 C# Wrapper。
  • XAudio2 (SharpDX):Windows 底層音訊引擎,適合高效能遊戲。

常見坑點與解決

問題原因解決
播放無聲檔案路徑錯誤、別名衝突、格式不支援檢查 `mciSendString` 回傳碼(非 0 為失敗),用 `mciGetErrorString` 取得錯誤訊息
中文路徑亂碼MCI 命令字串編碼確保命令字串為 ANSI(`Encoding.Default`)或使用短路徑 `GetShortPathName`
記憶體 WAV 播放失敗資源名稱錯誤、非標準 PCM WAV驗證 `GetManifestResourceStream` 不為 null;WAV 必須為 PCM 格式
重複播放卡頓MCI 單實例限制每次播放用唯一 alias(Guid),播放完 close 釋放

總結

簡單提示音:嵌入 WAV + sndPlaySound(SND_MEMORY) 最輕量、延遲最低。
背景音樂/長音訊:MCI 命令 免安裝解碼器。
專業音訊應用:請直接引入 NAudio 或遊戲音訊中介軟體。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved