【问题标题】:Capture audio from WasapiLoopbackCapture, and convert to muLaw从 WasapiLoopbackCapture 捕获音频,并转换为 muLaw
【发布时间】:2018-01-12 19:47:43
【问题描述】:

我正在使用 WasapiLoopbackCapture 捕获音频

- 格式 = ieeeFloat - 采样率 = 48000 - BitsPerSample = 32

我需要将其转换为 muLaw(8Khz,8 位,单声道) - 最终它将通过 SIP 中继发送到电话。我已经尝试了 100 多个样本(其中大部分使用 NAudio)和解决方案,但仍然不知道如何做到这一点......

【问题讨论】:

    标签: c# naudio pcm wasapi mu-law


    【解决方案1】:

    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 作为“根”的位置。每当您拨打BufferedWaveProvider.AddSamples() 时,数据都会经过所有这些过滤器。

    【讨论】:

    猜你喜欢
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2019-01-19
    相关资源
    最近更新 更多