Naudio-播放双阵列
Naudio- Play double array
我对 c# 很陌生,我一直在尝试编写一个程序来录制声音、显示它的波形、修改它并实时播放它。绘图效果很好,因为我使用了互联网上的一些示例,但我无法正确播放。我一直在尝试将 "WaveOut" 与转换为字节的双数组一起使用,但它给了我一些可怕的噪音,但我想我可以从我的输入中听到一些东西。提前致谢!
以下是代码中最重要的部分:
(Ys2 是带有样本的双精度数组)
static byte[] GetBytesAlt(double[] values)
{
var result = new byte[values.Length * sizeof(double)];
Buffer.BlockCopy(values, 0, result, 0, result.Length);
return result;
}
public void UpdateAudioGraph()
{
[.....]
WaveOut wo = new WaveOut();
byte[] Ys3 = GetBytesAlt(Ys2);
IWaveProvider provider = new RawSourceWaveStream(
new MemoryStream(Ys3), new WaveFormat());
wo.Init(provider);
wo.Play();
[.....]
}
private void timer1_Tick(object sender, EventArgs e)
{
UpdateAudioGraph();
}
*编辑
我设法做到了。仍然有一些回声,但效果很好。结果如下:
public partial class Form1 : Form
{
static WaveFormat waveFormat;
static int bufferMilliseconds;
static int x = 0;
public WaveIn wi;
public BufferedWaveProvider bwp;
public BufferedWaveProvider provider;
public Int32 envelopeMax;
public IWavePlayer wo;
double cutoff = 10000;
private int RATE = 44100; // sample rate of the sound card
private int BUFFERSIZE = (int)Math.Pow(2, 16); // must be a multiple of 2
//private int BUFFERSIZE = 44100;
public byte[] frames;
public Form1()
{
InitializeComponent();
// see what audio devices are available
int devcount = WaveIn.DeviceCount;
Console.Out.WriteLine("Device Count: {0}.", devcount);
//waveFormat = new NAudio.Wave.WaveFormat.(RATE, 1);
waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(RATE, 1);
bufferMilliseconds = (int)((double)BUFFERSIZE / (double)RATE * 1000.0);
// get the WaveIn class started
WaveIn wi = new WaveIn();
wi.DeviceNumber = 0;
wi.WaveFormat = waveFormat;
wi.BufferMilliseconds = bufferMilliseconds;
// create a wave buffer and start the recording
wo = new DirectSoundOut();
wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
bwp = new BufferedWaveProvider(waveFormat);
bwp.BufferLength = BUFFERSIZE * 8;
bwp.DiscardOnBufferOverflow = true;
wi.StartRecording();
wo.Init(bwp);
wo.Play();
}
// adds data to the audio recording buffer
void wi_DataAvailable(object sender, WaveInEventArgs e)
{
int size = e.BytesRecorded;
label3.Text = size.ToString();
frames = new byte[size];
e.Buffer.CopyTo(frames, 0);
float[] values = new float[size / 4];
for (int i = 0; i < values.Length; i++)
{
values[i] = BitConverter.ToSingle(frames, i * 4);
}
double[] doubleArray = Array.ConvertAll(values, x => (double)x);
doubleArray = Butterworth(doubleArray,cutoff);
values = Array.ConvertAll(doubleArray, y => (float)y);
frames = values.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
x++;
label2.Text = x.ToString();
label1.Text = timer2.Interval.ToString();
bwp.AddSamples(frames, 0, size);
}
您提供的是双声道音频(大概是单声道),但播放代码需要 16 位立体声音频。如果您可以将音频作为 float
提供,那么您可以在构造函数中使用 WaveFormat.CreateIeeeFloatWaveFormat(44100,1)
(具有正确的音频采样率和通道数)到 RawSourceWaveStream
我对 c# 很陌生,我一直在尝试编写一个程序来录制声音、显示它的波形、修改它并实时播放它。绘图效果很好,因为我使用了互联网上的一些示例,但我无法正确播放。我一直在尝试将 "WaveOut" 与转换为字节的双数组一起使用,但它给了我一些可怕的噪音,但我想我可以从我的输入中听到一些东西。提前致谢!
以下是代码中最重要的部分:
(Ys2 是带有样本的双精度数组)
static byte[] GetBytesAlt(double[] values)
{
var result = new byte[values.Length * sizeof(double)];
Buffer.BlockCopy(values, 0, result, 0, result.Length);
return result;
}
public void UpdateAudioGraph()
{
[.....]
WaveOut wo = new WaveOut();
byte[] Ys3 = GetBytesAlt(Ys2);
IWaveProvider provider = new RawSourceWaveStream(
new MemoryStream(Ys3), new WaveFormat());
wo.Init(provider);
wo.Play();
[.....]
}
private void timer1_Tick(object sender, EventArgs e)
{
UpdateAudioGraph();
}
*编辑
我设法做到了。仍然有一些回声,但效果很好。结果如下:
public partial class Form1 : Form
{
static WaveFormat waveFormat;
static int bufferMilliseconds;
static int x = 0;
public WaveIn wi;
public BufferedWaveProvider bwp;
public BufferedWaveProvider provider;
public Int32 envelopeMax;
public IWavePlayer wo;
double cutoff = 10000;
private int RATE = 44100; // sample rate of the sound card
private int BUFFERSIZE = (int)Math.Pow(2, 16); // must be a multiple of 2
//private int BUFFERSIZE = 44100;
public byte[] frames;
public Form1()
{
InitializeComponent();
// see what audio devices are available
int devcount = WaveIn.DeviceCount;
Console.Out.WriteLine("Device Count: {0}.", devcount);
//waveFormat = new NAudio.Wave.WaveFormat.(RATE, 1);
waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(RATE, 1);
bufferMilliseconds = (int)((double)BUFFERSIZE / (double)RATE * 1000.0);
// get the WaveIn class started
WaveIn wi = new WaveIn();
wi.DeviceNumber = 0;
wi.WaveFormat = waveFormat;
wi.BufferMilliseconds = bufferMilliseconds;
// create a wave buffer and start the recording
wo = new DirectSoundOut();
wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
bwp = new BufferedWaveProvider(waveFormat);
bwp.BufferLength = BUFFERSIZE * 8;
bwp.DiscardOnBufferOverflow = true;
wi.StartRecording();
wo.Init(bwp);
wo.Play();
}
// adds data to the audio recording buffer
void wi_DataAvailable(object sender, WaveInEventArgs e)
{
int size = e.BytesRecorded;
label3.Text = size.ToString();
frames = new byte[size];
e.Buffer.CopyTo(frames, 0);
float[] values = new float[size / 4];
for (int i = 0; i < values.Length; i++)
{
values[i] = BitConverter.ToSingle(frames, i * 4);
}
double[] doubleArray = Array.ConvertAll(values, x => (double)x);
doubleArray = Butterworth(doubleArray,cutoff);
values = Array.ConvertAll(doubleArray, y => (float)y);
frames = values.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
x++;
label2.Text = x.ToString();
label1.Text = timer2.Interval.ToString();
bwp.AddSamples(frames, 0, size);
}
您提供的是双声道音频(大概是单声道),但播放代码需要 16 位立体声音频。如果您可以将音频作为 float
提供,那么您可以在构造函数中使用 WaveFormat.CreateIeeeFloatWaveFormat(44100,1)
(具有正确的音频采样率和通道数)到 RawSourceWaveStream