Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用生成的波形数据在.NET中播放声音_C#_.net_Vb.net_Audio_Waveform - Fatal编程技术网

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

C# 使用生成的波形数据在.NET中播放声音,c#,.net,vb.net,audio,waveform,C#,.net,Vb.net,Audio,Waveform,如何根据.NET程序从用户输入和数学函数生成的波形数据播放声音 所谓“波形数据”,我指的是固定间隔时间序列(可能为44.1 kHz)中的SPL(声压级)值。我认为这需要某种流缓冲区安排 注意,这必须是实时的,所以仅仅创建一个.wav文件然后播放是不够的。VB.NET是首选,但C#也是可以接受的 只是想澄清一下:我想要的是一个简单的工作代码示例。我认为您需要使用(API)来实现这一点。它使用缓冲区,您可以用生成的数据填充缓冲区 也许类似(在way back机器中)的东西可以帮助您在加载带有任意数据

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

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

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


只是想澄清一下:我想要的是一个简单的工作代码示例。

我认为您需要使用(API)来实现这一点。它使用缓冲区,您可以用生成的数据填充缓冲区

也许类似(在way back机器中)的东西可以帮助您在加载带有任意数据的缓冲区并播放它时签出

每个评论:是的,我知道。你需要把C++翻译成C或VB.NET。但是,概念才是最重要的。您可以创建一个辅助DirectSound缓冲区,然后使用它将数据流传输到主缓冲区并播放。

您可以使用。您创建一个从WaveStream派生的流,并在其重写的Read方法中返回您可以动态生成的样本。您可以控制声卡使用的缓冲区大小,从而控制延迟。

,(在“其他API”下),以及其他可以这样做的功能。

PlayerEx pl=new PlayerEx();
专用静态void PlayArray(PlayerEx pl)
{
双fs=8000;//采样频率
双频=1000;//所需音调
short[]mySound=新的short[4000];
对于(int i=0;i<4000;i++)
{
double t=(double)i/fs;//当前时间
mySound[i]=(短)(Math.Cos(t*freq)*(短.MaxValue));
}
IntPtr format=AudioCompressionManager.GetPcmFormat(1,16,(int)fs);
OpenPlayer(格式);
byte[]mySoundByte=新字节[mySound.Length*2];
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

这不是VB.net或C。事实上,它一点也不像.Net。我终于开始尝试NAudio解决方案了,它非常棒!比我担心的要好得多,也容易得多,我真的应该早就尝试了。这个问题的一个更实用的答案是堆栈溢出问题。我终于有机会尝试NAudio,它非常棒。谢谢你的指点。
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