(NAudio) Как использовать буфер для воспроизведения отдельных сэмплов меняющихся звуковых волн в C #? - PullRequest
1 голос
/ 25 апреля 2019

Я пишу программу, которая должна имитировать сигнал «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

Я знаю, что это не идеально, но это работает для того, что я делаю.

...