从 WasapiLoopbackCapture 捕获音频,并转换为 muLaw
Capture audio from WasapiLoopbackCapture, and convert to muLaw
我正在使用 WasapiLoopbackCapture 捕捉音频
- format = IeeeFloat
- SampleRate = 48000
- BitsPerSample = 32
我需要将其转换为 muLaw(8Khz、8 位、单声道)- 最终它将通过 SIP 中继发送到 phone。我已经尝试了 100 多个示例(其中大部分使用 NAudio)和解决方案,但仍然不知道如何执行此操作...
NAudio 中的 Mu-Law 工具有限,因此您可能需要自己动手。
您需要设置一系列 IWaveProvider
过滤器以转换为单声道、更改比特率和更改位深度。
waveBuffer = new BufferedWaveProvider(waveIn.WaveFormat);
waveBuffer.DiscardOnBufferOverflow = true;
waveBuffer.ReadFully = false; // leave a buffer?
sampleStream = new WaveToSampleProvider(waveBuffer);
// Stereo to mono
monoStream = new StereoToMonoSampleProvider(sampleStream)
{
LeftVolume = 1f,
RightVolume = 1f
};
// Downsample to 8000
resamplingProvider = new WdlResamplingSampleProvider(monoStream, 8000);
// Convert to 16-bit in order to use ACM or MuLaw tools.
ieeeToPcm = new SampleToWaveProvider16(resamplingProvider);
然后为下一步创建自定义 IWaveProvider。
// In MuLawConversionProvider
public int Read(byte[] destinationBuffer, int offset, int readingCount)
{
// Source buffer has twice as many items as the output array.
var sizeOfPcmBuffer = readingCount * 2;
_sourceBuffer = BufferHelpers.Ensure(_sourceBuffer, sizeOfPcmBuffer);
var sourceBytesRead = _sourceProvider.Read(_sourceBuffer, offset * 2, sizeOfPcmBuffer);
var samplesRead = sourceBytesRead / 2;
var outIndex = 0;
for (var n = 0; n < sizeOfPcmBuffer; n += 2)
{
destinationBuffer[outIndex++] = MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(_sourceBuffer, offset + n));
}
return samplesRead * 2;
}
新提供者可以直接发送到WaveOut
outputStream = new MuLawConversionProvider(ieeeToPcm);
waveOut.Init(outputStream);
waveOut.Play();
这些过滤器与 BufferedWaveProvider 保持原位,如 "root"。每当您调用 BufferedWaveProvider.AddSamples()
时,数据将通过所有这些过滤器。
我正在使用 WasapiLoopbackCapture 捕捉音频
- format = IeeeFloat - SampleRate = 48000 - BitsPerSample = 32
我需要将其转换为 muLaw(8Khz、8 位、单声道)- 最终它将通过 SIP 中继发送到 phone。我已经尝试了 100 多个示例(其中大部分使用 NAudio)和解决方案,但仍然不知道如何执行此操作...
NAudio 中的 Mu-Law 工具有限,因此您可能需要自己动手。
您需要设置一系列 IWaveProvider
过滤器以转换为单声道、更改比特率和更改位深度。
waveBuffer = new BufferedWaveProvider(waveIn.WaveFormat);
waveBuffer.DiscardOnBufferOverflow = true;
waveBuffer.ReadFully = false; // leave a buffer?
sampleStream = new WaveToSampleProvider(waveBuffer);
// Stereo to mono
monoStream = new StereoToMonoSampleProvider(sampleStream)
{
LeftVolume = 1f,
RightVolume = 1f
};
// Downsample to 8000
resamplingProvider = new WdlResamplingSampleProvider(monoStream, 8000);
// Convert to 16-bit in order to use ACM or MuLaw tools.
ieeeToPcm = new SampleToWaveProvider16(resamplingProvider);
然后为下一步创建自定义 IWaveProvider。
// In MuLawConversionProvider
public int Read(byte[] destinationBuffer, int offset, int readingCount)
{
// Source buffer has twice as many items as the output array.
var sizeOfPcmBuffer = readingCount * 2;
_sourceBuffer = BufferHelpers.Ensure(_sourceBuffer, sizeOfPcmBuffer);
var sourceBytesRead = _sourceProvider.Read(_sourceBuffer, offset * 2, sizeOfPcmBuffer);
var samplesRead = sourceBytesRead / 2;
var outIndex = 0;
for (var n = 0; n < sizeOfPcmBuffer; n += 2)
{
destinationBuffer[outIndex++] = MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(_sourceBuffer, offset + n));
}
return samplesRead * 2;
}
新提供者可以直接发送到WaveOut
outputStream = new MuLawConversionProvider(ieeeToPcm);
waveOut.Init(outputStream);
waveOut.Play();
这些过滤器与 BufferedWaveProvider 保持原位,如 "root"。每当您调用 BufferedWaveProvider.AddSamples()
时,数据将通过所有这些过滤器。