首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NAudio SampleProvider在读取时未按预期更新缓冲区

NAudio SampleProvider在读取时未按预期更新缓冲区
EN

Stack Overflow用户
提问于 2021-09-11 21:04:35
回答 1查看 38关注 0票数 0

我正在尝试使用Naudio输入音频,然后在它被插件处理后再次输出。为了执行输出步骤,我创建了一个自定义的SampleProvider,但缓冲区的行为与我预期的不同,并且我听不到任何声音。读取音频并尝试再次播放它的代码如下

代码语言:javascript
复制
var audioFile = new AudioFileReader(@"C:\Users\alex.clayton\Downloads\Rhythm guitar.mp3");

PluginContext.PluginCommandStub.Commands.MainsChanged(true);
PluginContext.PluginCommandStub.Commands.StartProcess();

var vstSampleProvider = new VstSampleProvider(44100, 2);
var devices = DirectSoundOut.Devices.Last();
var output = new DirectSoundOut(devices.Guid);
output.Init(vstSampleProvider);

int chunckStep = 0;
while (chunckStep < audioFile.Length)
{
    var nAudiobuffer = new float[blockSize * 2];
    audioFile.Read(nAudiobuffer, 0, blockSize * 2);

    var leftSpan = inputMgr.Buffers.ToArray()[0].AsSpan();
    for (int i = 0; i < blockSize; i++)
    {
        leftSpan[i] = nAudiobuffer[i*2] / int.MaxValue;
    }

    var rightSpan = inputMgr.Buffers.ToArray()[0].AsSpan();
    for (int i = 1; i < blockSize; i++)
    {
        rightSpan[i] = nAudiobuffer[i*2 + 1] / int.MaxValue;
    }

    PluginContext.PluginCommandStub.Commands.ProcessReplacing(inputBuffers, outputBuffers);

    vstSampleProvider.LoadBuffer(outputBuffers);

    chunckStep += blockSize;
}
PluginContext.PluginCommandStub.Commands.StopProcess();
PluginContext.PluginCommandStub.Commands.MainsChanged(false);

output.Play();

示例提供程序代码如下

代码语言:javascript
复制
public class VstSampleProvider : ISampleProvider
{
    private readonly int _sampleRate;
    private readonly int _channels;
    private readonly Queue<float> _buffer;

    public VstSampleProvider(int sampleRate, int channels)
    {
        _sampleRate = sampleRate;
        _channels = channels;
        _buffer = new Queue<float>();
    }

    public WaveFormat WaveFormat => WaveFormat.CreateIeeeFloatWaveFormat(_sampleRate, _channels);

    public void LoadBuffer(VstAudioBuffer[] outputBuffers)
    {
        var totalSampleCount = outputBuffers[0].SampleCount * _channels;

        try
        {
            if (_channels == 1)
                for (int i = 0; i < totalSampleCount; i++)
                {
                    _buffer.Enqueue(outputBuffers[0][i]);
                }
            else
            {
                for (int i = 0; i < totalSampleCount; i++)
                {
                    if (i % 2 == 0)
                    {
                        var value = outputBuffers[0][i / 2];
                        _buffer.Enqueue(value);
                    }
                    else
                        _buffer.Enqueue(outputBuffers[1][(i - 1) / 2]);
                }
            }
        }
        catch (Exception ex)
        {
            // Probably should log or something
        }
    }

    public int Read(float[] buffer, int offset, int count)
    {
        if (_buffer.Count < count)
            return 0;

        if (offset > 0)
            throw new NotImplementedException();

        for (int i = 0; i < count; i++)
        {
            var value = _buffer.Dequeue();
            buffer[i] = value;
        }

        if (buffer.Any(f => f > 1))
        {
            return count;
        }

        return count;
    }
}

当我查看正在出列的值时,它们都在-1和1之间,不出所料,但是当我在if (buffer.Any(f => f > 1))之后的行上放置一个断点时,我可以看到缓冲值是大于1或0的整数,并且与我认为添加到缓冲区的出队值没有任何相似之处。

我希望我还没有理解一些关于SampleProvider应该如何工作的东西,通过查看已经在Naudio中的那些,我看不出我做错了什么。

任何帮助都将不胜感激。谢谢

EN

回答 1

Stack Overflow用户

发布于 2021-09-13 19:47:15

所以结果是主要的问题是读取输入文件并将音量调低,所以我在玩,但非常安静。

代码语言:javascript
复制
leftSpan[i] = nAudiobuffer[i*2] / int.MaxValue

不需要/ int.MaxValue

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69146706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档