如何根据我的.NET程序从用户输入和数学函数生成的波形数据播放声音?使用生成的波形数据在.NET中播放声音
所谓“波形数据”我的意思SPL(声压等级)在一个固定的时间间隔时间序列(可能44.1千赫)的值。我认为这需要某种流缓冲区安排。
注意,这必须是现场/实时性,所以只创建一个.wav文件,然后播放这将是不够的。 VB.NET是首选,但C#也可以接受。
只是为了澄清:我所寻找的是一个简单的工作代码示例。
如何根据我的.NET程序从用户输入和数学函数生成的波形数据播放声音?使用生成的波形数据在.NET中播放声音
所谓“波形数据”我的意思SPL(声压等级)在一个固定的时间间隔时间序列(可能44.1千赫)的值。我认为这需要某种流缓冲区安排。
注意,这必须是现场/实时性,所以只创建一个.wav文件,然后播放这将是不够的。 VB.NET是首选,但C#也可以接受。
只是为了澄清:我所寻找的是一个简单的工作代码示例。
您可以使用NAudio来做到这一点。您可以创建一个源自WaveStream的流,并在其覆盖的Read方法中返回您可以即时生成的样本。您可以控制声卡使用的缓冲区大小,从而控制延迟。
我认为你需要使用DirectSound(DirectX API)为。它处理缓冲区,您可以使用生成的数据填充缓冲区。
退房上装载了一个DirectSound缓冲区任意数据和玩它this thread。
每个评论:是的,我知道。您需要将C++转换为C#或VB.NET。但是,这个概念是重要的。您创建一个辅助DirectSound缓冲区,然后使用它将流传输到您的主缓冲区并播放。
那是*不* VB.net或C#。事实上,它看起来不像.Net。 – RBarryYoung 2009-07-06 04:13:58
How to play from an array of doubles
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();
}
我有这样的代码,但是你必须有一些代码在内存中生成的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
我终于开始尝试NAudio解决方案了,它非常出色!比我所担心的要容易得多,容易,我真的应该很久以前尝试过。 – RBarryYoung 2012-12-28 21:01:42
这个问题更具操作性的答案是堆栈溢出问题* [NAudio使用C#播放正弦波x毫秒](http://stackoverflow.com/questions/5485577)*。 – 2015-03-29 16:41:29