.net core 将用Raspberry pi上的.NetCore C#录制的音频保存到Wav文件
我发现很难找到一种方法来将使用OpenTk.NetStandard捕获的音频存储到NetCore C#中适当的.WAV文件中 我正在寻找的是一个解决方案,它可以在运行Raspberry pi时工作,所以NAudio或任何Windows特定的方法都不能解决我的问题 我找到了一些其他的答案,这些答案显示了如何使用opentk捕获音频,但没有说明如何将其存储在wav文件中 这是一段代码的摘录,应该可以从我从另一个话筒中读取数据。因此,问题是,我看到AudioCapture类可以:.net core 将用Raspberry pi上的.NetCore C#录制的音频保存到Wav文件,.net-core,opentk,audio-capture,.net Core,Opentk,Audio Capture,我发现很难找到一种方法来将使用OpenTk.NetStandard捕获的音频存储到NetCore C#中适当的.WAV文件中 我正在寻找的是一个解决方案,它可以在运行Raspberry pi时工作,所以NAudio或任何Windows特定的方法都不能解决我的问题 我找到了一些其他的答案,这些答案显示了如何使用opentk捕获音频,但没有说明如何将其存储在wav文件中 这是一段代码的摘录,应该可以从我从另一个话筒中读取数据。因此,问题是,我看到AudioCapture类可以: const by
const byte SampleToByte = 2;
short[] _buffer = new short[512];
int _sampling_rate = 16000;
double _buffer_length_ms = 5000;
var _recorders = AudioCapture.AvailableDevices;
int buffer_length_samples = (int)((double)_buffer_length_ms * _sampling_rate * 0.001 / BlittableValueType.StrideOf(_buffer));
using (var audioCapture = new AudioCapture(_recorders.First(), _sampling_rate, ALFormat.Mono16, buffer_length_samples))
{
audioCapture.Start();
int available_samples = audioCapture.AvailableSamples;
_buffer = new short[MathHelper.NextPowerOfTwo((int)(available_samples * SampleToByte / (double)BlittableValueType.StrideOf(_buffer) + 0.5))];
if (available_samples > 0)
{
audioCapture.ReadSamples(_buffer, available_samples);
int buf = AL.GenBuffer();
AL.BufferData(buf, ALFormat.Mono16, buffer, (int)(available_samples * BlittableValueType.StrideOf(_buffer)), audio_capture.SampleFrequency);
AL.SourceQueueBuffer(src, buf);
// TODO: I assume this is where the save to WAV file logic should be placed...
}
}
任何帮助都将不胜感激 这是一个.NET核心控制台程序,它将使用Mono 16位数据编写WAV文件。源代码中有一些链接,您应该通读这些链接,以了解正在编写的值的情况 这将记录10秒的数据,并将其保存到WAV格式的文件中:
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using System;
using System.IO;
using System.Threading;
class Program
{
static void Main(string[] args)
{
var recorders = AudioCapture.AvailableDevices;
for (int i = 0; i < recorders.Count; i++)
{
Console.WriteLine(recorders[i]);
}
Console.WriteLine("-----");
const int samplingRate = 44100; // Samples per second
const ALFormat alFormat = ALFormat.Mono16;
const ushort bitsPerSample = 16; // Mono16 has 16 bits per sample
const ushort numChannels = 1; // Mono16 has 1 channel
using (var f = File.OpenWrite(@"C:\users\andy\desktop\out.wav"))
using (var sw = new BinaryWriter(f))
{
// Read This: http://soundfile.sapp.org/doc/WaveFormat/
sw.Write(new char[] { 'R', 'I', 'F', 'F' });
sw.Write(0); // will fill in later
sw.Write(new char[] { 'W', 'A', 'V', 'E' });
// "fmt " chunk (Google: WAVEFORMATEX structure)
sw.Write(new char[] { 'f', 'm', 't', ' ' });
sw.Write(16); // chunkSize (in bytes)
sw.Write((ushort)1); // wFormatTag (PCM = 1)
sw.Write(numChannels); // wChannels
sw.Write(samplingRate); // dwSamplesPerSec
sw.Write(samplingRate * numChannels * (bitsPerSample / 8)); // dwAvgBytesPerSec
sw.Write((ushort)(numChannels * (bitsPerSample / 8))); // wBlockAlign
sw.Write(bitsPerSample); // wBitsPerSample
// "data" chunk
sw.Write(new char[] { 'd', 'a', 't', 'a' });
sw.Write(0); // will fill in later
// 10 seconds of data. overblown, but it gets the job done
const int bufferLength = samplingRate * 10;
int samplesWrote = 0;
Console.WriteLine($"Recording from: {recorders[0]}");
using (var audioCapture = new AudioCapture(
recorders[0], samplingRate, alFormat, bufferLength))
{
var buffer = new short[bufferLength];
audioCapture.Start();
for (int i = 0; i < 10; ++i)
{
Thread.Sleep(1000); // give it some time to collect samples
var samplesAvailable = audioCapture.AvailableSamples;
audioCapture.ReadSamples(buffer, samplesAvailable);
for (var x = 0; x < samplesAvailable; ++x)
{
sw.Write(buffer[x]);
}
samplesWrote += samplesAvailable;
Console.WriteLine($"Wrote {samplesAvailable}/{samplesWrote} samples...");
}
audioCapture.Stop();
}
sw.Seek(4, SeekOrigin.Begin); // seek to overall size
sw.Write(36 + samplesWrote * (bitsPerSample / 8) * numChannels);
sw.Seek(40, SeekOrigin.Begin); // seek to data size position
sw.Write(samplesWrote * (bitsPerSample / 8) * numChannels);
}
}
}
使用OpenTK.Audio;
使用OpenTK.Audio.OpenAL;
使用制度;
使用System.IO;
使用系统线程;
班级计划
{
静态void Main(字符串[]参数)
{
var记录器=音频捕获。可用设备;
对于(int i=0;i
您必须手动构建WAV标头。你看过WAV文件的结构吗?“我将从这里开始。”安迪谢谢你的评论,我用一些代码改进了这个问题,这些代码应该可以捕获音频样本。知道如何实现实际的save-to-WAV逻辑吗?NAudio会有帮助吗?这是一个开源项目,代码可以复制和使用,生成wav文件的代码不使用windows特定技术。它使用.NET Core中提供的File.IO中的流。这太棒了!谢谢@Andy,我将在接下来的几天内测试它!看看这些规范,我认为这行代码:sw.Write(44+sampleswrite…,应该是:sw.Write(取而代之的是36多个样本。我说的对吗?@bre_dev--是的..把东西算作整数而不是短裤。updated@bre_dev--太棒了!我没有在PI上测试它,所以很高兴听到它能工作。我的下一步是在检测到一定量的静音时停止录制。基于时间的停止并不理想。我可能会提出一个新的so问题。