我是一名化学专业的学生,试图在NAudio中使用C#从我的计算机麦克风中收集数据(计划稍后切换到音频端口,以防这与这一问题的答案相关)。我了解源流是什么,以及NAudio如何使用事件处理程序来了解是否开始从所述流读取信息,但在处理从流中读取的数据时,我遇到了困难。据我了解,缓冲区数组是从源流(使用AddSamples命令)以字节或WAV格式填充的。现在,我所要做的就是填充缓冲区并将其内容写入控制台或进行简单的可视化。我似乎无法将我的值从缓冲区中提取出来,而且我已经尝试将其作为WAV和字节数组来处理。有人能帮助我理解NAudio如何从底层开始工作,以及如何从缓冲区中提取数据并以更有用的格式(即双倍格式)存储它吗?下面是我到目前为止处理NAudio的代码及其附带的所有内容:
public NAudio.Wave.BufferedWaveProvider waveBuffer = null; // clears buffer
NAudio.Wave.WaveIn sourceStream = null; // clears source stream
public void startRecording(int samplingFrequency, int deviceNumber, string fileName)
{
sourceStream = new NAudio.Wave.WaveIn(); // initializes incoming audio stream
sourceStream.DeviceNumber = deviceNumber; // specifies microphone device number
sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(samplingFrequency, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels); // specifies sampling frequency, channels
waveBuffer = new NAudio.Wave.BufferedWaveProvider(sourceStream.WaveFormat); // initializes buffer
sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable); // event handler for when incoming audio is available
sourceStream.StartRecording();
PauseForMilliSeconds(500); // delay before recording is stopped
sourceStream.StopRecording(); // terminates recording
sourceStream.Dispose();
sourceStream = null;
}
void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
waveBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded); // populate buffer with audio stream
waveBuffer.DiscardOnBufferOverflow = true;
}发布于 2016-05-11 21:11:06
免责声明:我对NAudio没有那么多的经验。
这在某种程度上取决于你想对音频数据做些什么。
如果您只是想存储或转储数据(无论是文件目标还是控制台),那么您不需要BufferedWaveProvider。只需在事件处理程序sourceStream_DataAvailable()中直接执行您想做的任何事情。但请记住,接收数据是以原始字节的形式接收的,即实际构成单个帧的字节数(即a)。(示例)录制的音频取决于波形格式:
var bytesPerFrame = sourceStream.WaveFormat.BitsPerSample / 8
* sourceStream.WaveFormat.Channels如果您想分析数据(例如,傅立叶分析和快速傅立叶变换),那么我建议使用NAudio的ISampleProvider。这个接口隐藏了所有原始字节、位深度的内容,并允许您以一种简单的方式逐帧访问数据。
首先从您的ISampleProvider中创建一个BufferedWaveProvider,如下所示:
var samples = waveBuffer.ToSampleProvider();然后,您可以使用Read()方法访问示例帧。确保检查BufferedBytes属性对BufferedWaveProvider上的数据是否实际可用
while (true)
{
var bufferedFrames = waveBuffer.BufferedBytes / bytesPerFrame;
if (bufferedFrames < 1)
continue;
var frames = new float[bufferedFrames];
samples.Read(frames, 0, bufferedFrames);
DoSomethingWith(frames);
}因为你想同时做两件事--同时记录和分析音频数据--你应该使用两个不同的线程来完成这个任务。
有一个使用GitHub的小型NAudio项目的DTMF分析记录的音频数据。你可能想看看如何把这一切结合起来。文件DtmfDetector\Program.cs有一个很好的起点。
为了快速启动,这将使您的输出“更连贯”,请尝试如下:
将此字段添加到类中:
ISampleProvider samples;将这一行添加到方法startRecording()中
samples = waveBuffer.ToSampleProvider();像这样扩展sourceStream_DataAvailable():
void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
waveBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded);
waveBuffer.DiscardOnBufferOverflow = true;
var bytesPerFrame = sourceStream.WaveFormat.BitsPerSample / 8
* sourceStream.WaveFormat.Channels
var bufferedFrames = waveBuffer.BufferedBytes / bytesPerFrame;
var frames = new float[bufferedFrames];
samples.Read(frames, 0, bufferedFrames);
foreach (var frame in frames)
Debug.WriteLine(frame);
}https://stackoverflow.com/questions/37148997
复制相似问题