Можно ли генерировать постоянный звук в C # при настройке его частоты? - PullRequest
8 голосов
/ 01 октября 2011

Можно ли генерировать постоянный звук в C # и манипулировать его частотой по ходу?

Я пробовал что-то вроде этого:

for (int i = 500; i < 15000; i += 1)
{
    Console.Beep(i, 500));
}

Но, будучи синхронным, цикл ожидаеткаждый звуковой сигнал, чтобы закончить.Итак, я попробовал это:

for (int i = 500; i < 15000; i += 1)
{
    new Thread(x => Console.Beep(i, 500)).Start();
}

Я бы подумал, что это будет началом создания постоянного звука, частота которого постоянно увеличивается.Однако, это все еще заикается, поскольку это идет.Есть ли способ сделать это, но более гладко?

Ответы [ 2 ]

7 голосов
/ 01 октября 2011

Если вы хотите сделать это в режиме реального времени (т.е. динамически изменять частоту в ответ на ввод пользователя), это будет невероятно сложно и повлечет за собой написание программного синтезатора.В этом случае вы можете попробовать использовать такую ​​библиотеку, как NAudio (хотя я не уверен на 100%, что NAudio выполняет синтез в реальном времени).

С другой стороны, если вы просто хотитепредварительно сгенерировать WAV-файл с непрерывно восходящим тоном и затем воспроизвести его, это невероятно просто.

Редактировать: Третий вариант - воспроизвести звук MIDI и отправлять сообщения об изменении управления на MIDI-устройство, чтобы постепенно применить portmanteau к воспроизводимой ноте.Это также легко, но имеет тот недостаток, что вы не можете быть точно уверены, как он будет звучать на чужом компьютере.

2 голосов
/ 03 февраля 2014

Код ниже генерирует синусоидальную волну . Вы можете изменить частоту и другие параметры

    private void TestSine()
    {
        IntPtr format;
        byte[] data;
        GetSineWave(1000, 100, 44100, -1, out format, out data);
        WaveWriter ww = new WaveWriter(File.Create(@"d:\work\sine.wav"),
            AudioCompressionManager.FormatBytes(format));
        ww.WriteData(data);
        ww.Close();
    }

    private void GetSineWave(double freq, int durationMs, int sampleRate, short decibel, out IntPtr format, out byte[] data)
    {
        short max = dB2Short(decibel);//short.MaxValue
        double fs = sampleRate; // sample freq
        int len = sampleRate * durationMs / 1000;
        short[] data16Bit = new short[len];
        for (int i = 0; i < len; i++)
        {
            double t = (double)i / fs; // current time
            data16Bit[i] = (short)(Math.Sin(2 * Math.PI * t * freq) * max);
        }
        IntPtr format1 = AudioCompressionManager.GetPcmFormat(1, 16, (int)fs);
        byte[] data1 = new byte[data16Bit.Length * 2];
        Buffer.BlockCopy(data16Bit, 0, data1, 0, data1.Length);
        format = format1;
        data = data1;
    }

    private static short dB2Short(double dB)
    {
        double times = Math.Pow(10, dB / 10);
        return (short)(short.MaxValue * times);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...