我正在尝试使用Naudio输入音频,然后在它被插件处理后再次输出。为了执行输出步骤,我创建了一个自定义的SampleProvider,但缓冲区的行为与我预期的不同,并且我听不到任何声音。读取音频并尝试再次播放它的代码如下
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();示例提供程序代码如下
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中的那些,我看不出我做错了什么。
任何帮助都将不胜感激。谢谢
发布于 2021-09-13 19:47:15
所以结果是主要的问题是读取输入文件并将音量调低,所以我在玩,但非常安静。
leftSpan[i] = nAudiobuffer[i*2] / int.MaxValue不需要/ int.MaxValue
https://stackoverflow.com/questions/69146706
复制相似问题