如何制作粉红噪声发生器?

问题描述 投票:27回答:11

((选择答案 - 见下面的编辑5)。)

我需要在C#中编写一个简单的粉红噪声发生器。问题是,我以前从未做过任何音频工作,所以我不知道如何与声卡等进行交互。我知道我想远离使用DirectX,主要是因为我不想要为这个小项目下载一个大规模的SDK。

所以我有两个问题:

  1. 如何生成粉红噪音?
  2. 如何将其流式传输到声卡?

编辑:我真的想制作粉红噪声发生器...我知道还有其他方法可以解决根问题。 =)

编辑2:我们的防火墙阻止流音频和视频 - 否则我只是按照评论中的建议去www.simplynoise.com。 :(

编辑3:我已经产生了白噪声,并将输出发送到声卡 - 现在我需要知道的是如何将白噪声变成粉红噪声。哦 - 而且我不想循环一个wav文件,因为我尝试用于循环的每个应用程序最终都会在循环之间出现一点点中断,这足以让我在这个方向上提示我...

编辑4:......我很惊讶很多人都非常明确地没有回答问题。如果我说谎为什么我需要粉红噪声,我可能会得到更好的响应......这个问题更多的是关于如何生成和流式传输数据到声卡而不是我应该使用什么类型的耳机。为此,我已经删除了背景细节 - 您可以在编辑中阅读它...

编辑5:我在下面选择了Paul的答案,因为他提供的链接给了我一个公式,可以将白噪声(很容易通过随机数生成器生成)转换为粉红噪声。除此之外,我还使用Ianier Munoz's CodeProject entry "Programming Audio Effects in C#"来学习如何生成,修改和输出声卡的声音数据。谢谢你们的帮助。 =)

c# .net audio noise
11个回答
15
投票

也许您可以将C / C ++代码转换为C#:

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

获取声卡的最简单方法是生成一个wav(吐出一些硬编码头然后采样数据)。然后你可以播放.wav文件。


0
投票

我不能谈论C#,但你可能会用一些好的降噪耳机和你最喜欢的mp3来改善。


0
投票

如果你在Linux上,你可以使用SOX(你可能已经拥有它,尝试使用play命令)。

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


9
投票

粉红噪声只是白噪声通过-3dB /倍频程LPF。您可以使用rand()(或生成均匀随机数的任何函数)生成白噪声。

只要你有谷歌方便,流媒体到声卡的东西是相当微不足道的。如果您选择避免使用DirectX,请考虑使用PortAudio或ASIO与声卡接口......虽然我认为您将不得不使用C ++或C.

除此之外,为什么浪费CPU时间产生呢?循环该死的WAV文件!


6
投票

有点迟到这个我意识到,但任何遇到答案的人都应该知道粉红噪声是-3dB /倍频程的白噪声,而不是如上所述的-6,实际上是棕色噪声。


3
投票

不是你的问题的答案,但你不能只听一些音乐,理想情况下用一些降噪耳机吗?


2
投票

这是播放线程的样子。我正在使用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
投票

作为一种快速而肮脏的方式,如何在音频播放器中循环粉红噪声wav? (是的,我知道有趣的一部分就是亲自制作....)


1
投票

重复粉红噪音的.mp3样本怎么样?


1
投票

您可以使用Audacity生成尽可能多的粉红噪声,然后重复它。

或者你可以深入研究源代码,看看Audacity如何产生粉红噪声。


1
投票

这是一种非常简单的方法来创建粉红噪声,它只是将大量间隔为对数的波浪加在一起!如果你想要实时创建的声音,它可能太慢了你的目的,但肯定可以进一步优化(例如:更快的余弦函数)。

这些函数输出一个双数组,其值为-1到1.这分别代表波形中的最低点和最高点。

quality参数表示产生声音的波数。我发现5000波(每个半音大约40个区间)只是我无法通过更高的值检测到任何显着改善的阈值,但为了安全起见,你可以(可选地)将此增加到大约10,000波或更高。此外,根据维基百科的说法,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;
}
© www.soinside.com 2019 - 2024. All rights reserved.