使用生成的波形数据在.NET中播放声音

如何根据我的.NET程序从用户输入和数学函数生成的波形数据播放声音?

“波形数据”是指固定间隔时间序列(可能是44.1 kHz)中的SPL(声压级)值。 我认为这需要某种流缓冲区安排。

请注意,这必须是实时/实时的,所以只创建一个.wav文件然后播放它是不够的。 VB.NET是首选,但C#也是可以接受的。

只是为了澄清:我正在寻找的是一个简单的工作代码示例。

你可以使用NAudio来做到这一点 。 您创建一个派生自WaveStream的流,并在其覆盖的Read方法中,返回可以动态生成的样本。 您可以控制声卡使用的缓冲区大小,从而控制延迟。

如何从一系列双打中发挥

PlayerEx pl = new PlayerEx(); private static void PlayArray(PlayerEx pl) { double fs = 8000; // sample freq double freq = 1000; // desired tone short[] mySound = new short[4000]; for (int i = 0; i < 4000; i++) { double t = (double)i / fs; // current time mySound[i] = (short)(Math.Cos(t * freq) * (short.MaxValue)); } IntPtr format = AudioCompressionManager.GetPcmFormat(1, 16, (int)fs); pl.OpenPlayer(format); byte[] mySoundByte = new byte[mySound.Length * 2]; Buffer.BlockCopy(mySound, 0, mySoundByte, 0, mySoundByte.Length); pl.AddData(mySoundByte); pl.StartPlay(); } 

在加载带有任意数据的DirectSound缓冲区并播放它时检查此线程 。

评论:是的,我知道。 您需要将C ++转换为C#或VB.NET。 但是,这个概念很重要。 您创建一个辅助DirectSound缓冲区,然后使用它流式传输到您的主缓冲区并播放。

IrrKlang , BASS.net (在“其他API”下), NAudio , CLAM , G3D以及其他可以做到这一点的人。

我认为你需要使用DirectSound ( DirectX API)。 它可以使用生成的数据来填充缓冲区。

也许这样的事情( 这里是背机)会有所帮助

我有这个代码,但你必须有代码在内存中生成你的wav文件。

 Option Strict Off Option Explicit On Imports Microsoft.DirectX.DirectSound Imports Microsoft.DirectX Imports System.Threading Public Class Form1 Const SRATE As Integer = 44100 Const FREQ As Integer = 440 Const DUR As Integer = 1 Private dsDesc As BufferDescription Private wvFormat As WaveFormat Private DS As Device Dim SecondaryBuffer As Microsoft.DirectX.DirectSound.SecondaryBuffer Dim BufferDescription As Microsoft.DirectX.DirectSound.BufferDescription Dim DXFormat As Microsoft.DirectX.DirectSound.WaveFormat Dim sbuf(DUR * SRATE) As Short Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Show() DS = New Microsoft.DirectX.DirectSound.Device DS.SetCooperativeLevel(Me, CooperativeLevel.Normal) wvFormat.FormatTag = WaveFormatTag.Pcm wvFormat.Channels = 1 wvFormat.SamplesPerSecond = SRATE wvFormat.BitsPerSample = 16 wvFormat.AverageBytesPerSecond = 2 * SRATE wvFormat.BlockAlign = 2 dsDesc = New BufferDescription(wvFormat) dsDesc.BufferBytes = 2 * DUR * SRATE dsDesc.Flags = 0 Dim buff1 = PlayWave(400) Dim buff2 = PlayWave(600) buff1 = PlayWave(400) buff1.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Default) Thread.Sleep(1000) buff1 = PlayWave(600) buff1.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Default) ' End End Sub Function PlayWave(FREQ As Integer) As SecondaryBuffer ' create a buffer Dim dsBuffer As SecondaryBuffer dsBuffer = New SecondaryBuffer(dsDesc, DS) Dim sbuf(DUR * SRATE) As Short ' create tone For i As Integer = 0 To DUR * SRATE sbuf(i) = CShort(10000 * Math.Sin(2 * Math.PI * FREQ * i / SRATE)) Next ' copy to buffer dsBuffer.Write(0, sbuf, LockFlag.EntireBuffer) Return dsBuffer End Function