Как я могу сделать генератор розового шума? - PullRequest
27 голосов
/ 06 марта 2009

((Ответ выбран - см. Редактирование 5 ниже.))

Мне нужно написать простой генератор розового шума на C #. Проблема в том, что я никогда раньше не работал со звуком, поэтому я не знаю, как взаимодействовать со звуковой картой и т. Д. Я знаю, что хочу избежать использования DirectX, главным образом потому, что не хочу скачать массивный SDK только для этого крошечного проекта.

Итак, у меня две проблемы:

  1. Как генерировать розовый шум?
  2. Как мне передать его на звуковую карту?

Редактировать : Я действительно хочу сделать генератор розового шума ... Я знаю, что есть другие способы решения корневой проблемы. =)

Редактировать 2 : Наш брандмауэр блокирует потоковую передачу аудио и видео - в противном случае я просто зайду на www.simplynoise.com , как предлагается в комментариях. (

Редактировать 3 : у меня отключено генерация белого шума, а также отправка вывода на звуковую карту - теперь все, что мне нужно знать, это как превратить белый шум в розовый шум. О-о, и я не хочу зацикливать файл wav, потому что каждое приложение, которое я пытался использовать для зацикливания, заканчивается небольшим перерывом между циклами, что достаточно неожиданно, чтобы сначала подтолкнуть меня в этом направлении. ...

Редактировать 4 : ... Я удивлен, что так много людей вскочили, чтобы очень явно не ответить на вопрос. Я, вероятно, получил бы лучший ответ, если бы соврал о том, почему мне нужен розовый шум ... Этот вопрос больше о том, как генерировать и передавать данные на звуковую карту, чем о том, какие наушники мне следует использовать. С этой целью я отредактировал детали фона - вы можете прочитать об этом в редактировании ...

Редактировать 5 : Я выбрал ответ Пола ниже, потому что ссылка, которую он предоставил, дала мне формулу для преобразования белого шума (который легко генерируется с помощью генератора случайных чисел) в розовый шум. В дополнение к этому я использовал запись Ianier Munoz CodeProject «Программирование звуковых эффектов в C #» , чтобы научиться генерировать, изменять и выводить звуковые данные на звуковую карту. Спасибо, ребята, за вашу помощь. =) * * Тысяча тридцать-девять

Ответы [ 11 ]

15 голосов
/ 06 марта 2009

Может быть, вы можете преобразовать код C / C ++ здесь в C #:

http://www.firstpr.com.au/dsp/pink-noise/

Самый простой способ получить звук на звуковую карту - это сгенерировать wav (выложить несколько жестко закодированных заголовков и затем сэмплировать данные). Затем вы можете воспроизвести файл .wav.

9 голосов
/ 06 марта 2009

Розовый шум - это просто белый шум, подаваемый через LPF -3 дБ / октаву. Вы можете генерировать белый шум, используя rand () (или любую функцию, которая генерирует равномерно случайные числа).

Потоковое вещание на звуковую карту достаточно тривиально, если у вас есть Google. Если вы решите избегать DirectX, рассмотрите возможность использования PortAudio или ASIO для взаимодействия со звуковой картой ... хотя я думаю, что вам придется использовать C ++ или C.

Кроме того, зачем тратить время процессора на его создание? Зациклить чертов WAV-файл!

6 голосов
/ 22 августа 2012

немного поздно, я понимаю, но любой, кто сталкивается с этим для ответов, должен знать, что розовый шум - это белый шум с -3 дБ / октава, а не -6, как указано выше, что на самом деле является коричневым шумом.

3 голосов
/ 06 марта 2009

Не совсем ответ на ваш вопрос, но вы не можете просто послушать музыку, в идеале, с наушниками с шумоподавлением?

2 голосов
/ 06 марта 2009

Вот пример того, как выглядит поток воспроизведения. Я использую DirectSound для создания SecondaryBuffer, где записаны примеры. Как видите, все довольно просто:

    /// <summary>
    /// Thread in charge of feeding the playback buffer.
    /// </summary>
    private void playbackThreadFn()
    {
        // Begin playing the sound buffer.
        m_playbackBuffer.Play( 0, BufferPlayFlags.Looping );

        // Change playing state.
        IsPlaying = true;

        // Playback loop.
        while( IsPlaying )
        {
            // Suspend thread until the playback cursor steps into a trap...
            m_trapEvent.WaitOne();

            // ...read audio from the input stream... (In this case from your pink noise buffer)
            Input.Collect( m_target, m_target.Length );

            // ...calculate the next writing position...
            var writePosition = m_traps[ ((1 & m_pullCounter++) != 0) ? 0 : 1 ].Offset;

            // ...and copy audio to the device buffer.
            m_playbackBuffer.Write( writePosition, m_deviceBuffer, LockFlag.None );
        }

        // Stop playback.
        m_playbackBuffer.Stop();
    }

Если вам нужно больше подробностей о том, как это работает, я буду рад помочь.

1 голос
/ 14 октября 2018

Вот очень простой способ создания розового шума, который просто суммирует множество волн, логарифмически разнесенных друг от друга, вместе! Это может быть слишком медленно для ваших целей, если вы хотите, чтобы звук создавался в реальном времени, но дальнейшая оптимизация, безусловно, возможна (например, более быстрая функция косинуса).

Функции выводят двойной массив со значениями от -1 до 1. Это представляет самую низкую и самую высокую точки в форме волны соответственно.

Параметр quality представляет количество волн, создаваемых для создания звука. Я нахожу, что 5000 волн (около 40 интервалов на полутон) - это почти порог, когда я не могу обнаружить заметного улучшения с более высокими значениями, но чтобы быть в безопасности, вы могли бы (опционально) увеличить это примерно до 10000 волн или выше , Кроме того, согласно Википедии, 20 герц - это нижний предел человеческого восприятия с точки зрения того, что мы можем слышать, но вы также можете изменить это, если хотите.

Обратите внимание, что звук становится тише с более высоким значением quality по техническим причинам, поэтому вы можете (необязательно) настроить громкость с помощью параметра volumeAdjust.

public double[] createPinkNoise(double seconds, int quality=5000, double lowestFrequency=20, double highestFrequency = 44100, double volumeAdjust=1.0)
{
    long samples = (long)(44100 * seconds);
    double[] d = new double[samples];
    double[] offsets = new double[samples];
    double lowestWavelength = highestFrequency / lowestFrequency;
    Random r = new Random();
    for (int j = 0; j < quality; j++)
    {
        double wavelength = Math.Pow(lowestWavelength, (j * 1.0) / quality)  * 44100 / highestFrequency;
        double offset = r.NextDouble() * Math.PI*2;     // Important offset is needed, as otherwise all the waves will be almost in phase, and this will ruin the effect!
        for (int i = 0; i < samples; i++)
        {
            d[i] += Math.Cos(i * Math.PI * 2 / wavelength + offset) / quality * volumeAdjust;
        }
    }
    return d;
}
1 голос
/ 06 марта 2009

Вы можете использовать Audacity , чтобы генерировать столько розового шума, сколько хотите, а затем повторить его.

Или вы можете покопаться в исходном коде и посмотреть, как Audacity генерирует розовый шум.

1 голос
/ 06 марта 2009

Как насчет .mp3 образца Pink Noise при повторении?

1 голос
/ 06 марта 2009

Как быстрый и грязный способ сделать это, как насчет петли розового шума WAV в вашем аудиоплеере? (Да, я знаю, что самое интересное в том, чтобы сделать это самостоятельно ....)

0 голосов
/ 22 сентября 2015

Если вы работаете в Linux, вы можете использовать SOX (возможно, он уже есть, попробуйте команду play).

play -t sl - synth 3 pinknoise band -n 1200 200 tremolo .1 40 < /dev/zero

...