32

(((已选择答案 - 请参阅下面的编辑 5。))

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

所以我有两个问题:

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

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

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

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

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

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

4

10 回答 10

15

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

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

将声音传送到声卡的最简单方法是生成一个 wav(吐出一些硬编码的标头,然后采样数据)。然后你就可以播放 .wav 文件了。

于 2009-03-05T22:33:41.927 回答
8

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

只要您有 Google 方便,将内容流式传输到声卡就相当简单。如果您选择避免使用 DirectX,请考虑使用 PortAudio 或 ASIO 来连接声卡……尽管我认为您将不得不使用 C++ 或 C。

除此之外,为什么要浪费 CPU 时间来生成它?循环一个该死的 WAV 文件!

于 2009-03-05T22:31:23.150 回答
7

我意识到这一点有点晚了,但是任何遇到它的人都应该知道粉红噪声是-3dB / octave的白噪声,而不是如上所述的-6,实际上是棕色噪声。

于 2012-08-22T12:26:36.920 回答
4

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

这些函数输出一个值从 -1 到 1 的双精度数组。这分别表示波形中的最低点和最高点。

quality参数表示为发出声音而产生的波数。我发现 5000 个波(每个半音大约 40 个间隔)大约是我无法检测到更高值的任何明显改进的阈值,但为了安全起见,您可以(可选)将其增加到大约 10,000 个波或更高. 此外,根据 Wikipedia 的说法,就我们能听到的声音而言,20 赫兹大约是人类感知的下限,但如果你愿意,你也可以改变它。

请注意,由于技术原因,声音会随着quality值的增加而变得更安静,因此您可能(可选)希望通过volumeAdjust参数调整音量。

public double[] createPinkNoise(double seconds, int quality=5000, double lowestFrequency=20, double highestFrequency = 20000, 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 (long i = 0; i < samples; i++)
        {
            d[i] += Math.Cos(i * Math.PI * 2 / wavelength + offset) / quality * volumeAdjust;
        }
    }
    return d;
}
于 2018-10-14T12:41:49.450 回答
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();
    }

如果您需要有关其工作原理的更多详细信息,我将很乐意提供帮助。

于 2009-03-05T23:35:01.890 回答
2

如果你在 Linux 上,你可以使用 SOX(你可能已经有了,试试这个play命令)。

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

于 2015-09-22T19:42:17.530 回答
0

作为一种快速而肮脏的方法,在你的音频播放器中循环播放粉红噪声 wav 怎么样?(是的,我知道部分乐趣是自己动手做......)

于 2009-03-05T22:28:31.067 回答
0

重复播放粉红噪声的 .mp3 样本怎么样?

于 2009-03-05T22:28:40.207 回答
-1

你可以使用Audacity来产生你想要的尽可能多的粉红噪声,然后重复它。

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

于 2009-03-05T22:31:45.503 回答
-2

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

于 2009-03-05T22:21:21.410 回答