(NAudio)如何使用缓冲区播放C#中变化的音频波的单个样本?

时间:2019-04-25 07:26:19

标签: c# audio stream naudio

我正在编写一个程序,该程序应模仿“ DCF77”信号来更改无线电时钟的时间。 为此,我必须使用不断变化的声音(不断变化的音量)连续播放声音(没有破裂声音;无缝播放)。

有人告诉我使用NAudio和一个缓冲区,该缓冲区存储样本/ 1个样本,将它们/发送到声卡,并根据需要请求更多样本。

但是我该如何实现呢?

我当前的代码有一个包含60个元素的数组,这些元素称为位,用于确定声音每秒的变化。 每分钟一次重新计算该数组。

如果您不知道,DCF77信号将对二进制信息进行如下编码: 0表示每秒的前0.1秒约为正常音量的15%。 1表示相同,但​​持续0.2秒。

现在,我有一个SineWaveProvider32类:

class SineWaveProvider32 : WaveProvider32
{
    int sample;

    public SineWaveProvider32()
    {
        Frequency = 1000;
        Amplitude = 0.25f;
    }

    public float Frequency { get; set; }
    public float Amplitude { get; set; }

    public override int Read(float[] buffer, int offset, int sampleCount)
    {
        int sampleRate = WaveFormat.SampleRate;

        for(int i = 0; i < sampleCount; i++)
        {
            buffer[i + offset] = (float)(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));
            sample++;
            if(sample >= sampleRate)
            {
                sample = 0;
            }
        }

        return sampleCount;
    }
}

以及WaveOut对象

WaveOut waveOut;

并且主要代码具有此方法:

void StartStopSineWave()
{
    if (waveOut == null)
    {
        var sineWaveProvider = new SineWaveProvider32();
        sineWaveProvider.SetWaveFormat(192000, 1);
        sineWaveProvider.Frequency = 1000;
        sineWaveProvider.Amplitude = 0.25f;
        waveOut = new WaveOut();
        waveOut.Init(sineWaveProvider);
        waveOut.Play();
    }
    else
    {
        waveOut.Stop();
        waveOut.Dispose();
        waveOut = null;
    }
}

请注意,我是C#的新手,很抱歉,如果这是一个重复的问题,但是我找不到任何有用的信息,或者至少不了解它。

编辑:对于可能遇到相同问题的任何人,我通过输出恒定的正弦波并使用

实时更改音量来解决了该问题。
waveOut.Volume

我知道这不是完美的方法,但是它可以满足我的工作要求。

0 个答案:

没有答案