简体   繁体   English

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

[英]How can I make a Pink Noise generator?

((Answer selected - see Edit 5 below.)) (((已选择答案 - 请参阅下面的编辑 5。))

I need to write a simple pink-noise generator in C#.我需要在 C# 中编写一个简单的粉红噪声发生器。 The problem is, I've never done any audio work before, so I don't know how to interact with the sound card, etc. I do know that I want to stay away from using DirectX, mostly because I don't want to download a massive SDK just for this tiny project.问题是,我以前从未做过任何音频工作,所以我不知道如何与声卡等交互。我知道我想远离使用 DirectX,主要是因为我不想为这个小项目下载一个巨大的 SDK。

So I have two problems:所以我有两个问题:

  1. How do I generate Pink Noise?如何产生粉红噪声?
  2. How do I stream it to the sound card?我怎么把stream接到声卡上?

Edit : I really want to make a pink noise generator... I'm aware there are other ways to solve the root problem.编辑:我真的很想制作一个粉红噪声发生器......我知道还有其他方法可以解决根本问题。 =) =)

Edit 2 : Our firewall blocks streaming audio and video - otherwise I'd just go to www.simplynoise.com as suggested in the comments.编辑 2 :我们的防火墙阻止流式传输音频和视频 - 否则我只会 go 到www.simplynoise.com ,如评论中所建议的那样。 :( :(

Edit 3 : I've got the generation of white-noise down, as well as sending output to the sound card - now all I need to know is how to turn the white-noise into pink noise.编辑 3 :我已经降低了白噪声的产生,并将 output 发送到声卡 - 现在我只需要知道如何将白噪声变成粉红噪声。 Oh - and I don't want to loop a wav file because every application I've tried to use for looping ends up with a tiny little break in between loops, which is jarring enough to have prompted me in this direction in the first place...哦 - 我不想循环一个 wav 文件,因为我尝试用于循环的每个应用程序最终都会在循环之间出现一点点中断,这足以让我一开始就朝着这个方向前进...

Edit 4 : ... I'm surprised so many people have jumped in to very explicitly not answer a question.编辑4 :......我很惊讶有这么多人非常明确地回答问题。 I probably would have gotten a better response if I lied about why I need pink noise... This question is more about how to generate and stream data to the sound card than it is about what sort of headphones I should be using.如果我对为什么需要粉红噪声撒谎,我可能会得到更好的回应......这个问题更多的是关于如何向声卡生成和 stream 数据,而不是关于我应该使用哪种耳机。 To that end I've edited out the background details - you can read about it in the edits...为此,我已经编辑了背景细节 - 你可以在编辑中阅读它......

Edit 5 : I've selected Paul's answer below because the link he provided gave me the formula to convert white noise (which is easily generated via the random number generator) into pink noise.编辑 5 :我在下面选择了 Paul 的答案,因为他提供的链接给了我将白噪声(很容易通过随机数生成器生成)转换为粉红噪声的公式。 In addition to this, I used Ianier Munoz's CodeProject entry "Programming Audio Effects in C#" to learn how to generate, modify, and output sound data to the sound card.除此之外,我使用Ianier Munoz 的 CodeProject 条目“Programming Audio Effects in C#”来学习如何生成、修改和 output 声音数据到声卡。 Thank you guys for your help.谢谢你们的帮助。 =) =)

Maybe you can convert the C/C++ code here to C#:也许您可以将此处的 C/C++ 代码转换为 C#:

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

The easiest way to get sound to the sound card is to generate a wav (spit out some hardcoded headers and then sample data).将声音传送到声卡的最简单方法是生成一个 wav(吐出一些硬编码的标头,然后采样数据)。 Then you can play the.wav file.然后就可以播放.wav 文件了。

Pink noise is just white noise put through a -3dB/octave LPF.粉红噪声只是通过 -3dB/倍频程 LPF 的白噪声。 You can generate white noise using rand() (or any function that generates uniformly random numbers).您可以使用 rand() (或任何生成均匀随机数的 function )生成白噪声。

Streaming stuff to the soundcard is reasonably trivial, as long as you have Google handy.只要您有 Google 方便,将内容流式传输到声卡就相当简单。 If you choose to avoid DirectX, consider using PortAudio or ASIO for interfacing with the soundcard... although I think you're gonna have to use C++ or C.如果您选择避免使用 DirectX,请考虑使用 PortAudio 或 ASIO 与声卡连接……尽管我认为您将不得不使用 C++ 或 C。

Other than that, why waste CPU time generating it?除此之外,为什么要浪费 CPU 时间来生成它? Loop a damn WAV file!循环一个该死的 WAV 文件!

bit late to this i realise, but anyone coming across it for answers should know that pink noise is white noise with -3dB/octave, not -6 as stated above, which is actually brown noise.我意识到这一点有点晚了,但是任何遇到它的人都应该知道粉红噪声是-3dB / octave的白噪声,而不是如上所述的-6,实际上是棕色噪声。

Not really an answer to your question, but can't you just listen to some music, ideally with some noise cancelling headphones?不是你的问题的真正答案,但你不能只听一些音乐,最好用一些降噪耳机?

Here's is an example of what the playback thread looks like.这是播放线程的示例。 I'm using DirectSound to create a SecondaryBuffer where the samples are written.我正在使用 DirectSound 创建一个写入样本的 SecondaryBuffer。 As you can see it's pretty straightforward:如您所见,它非常简单:

    /// <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();
    }

If you need more details on how it works I'll be glad to help.如果您需要有关其工作原理的更多详细信息,我将很乐意提供帮助。

Here's a very simple way to create pink noise, which just sums lots of waves spaced logarithmically apart, together, It may be too slow for your purposes if you want the sound created in realtime.这是创建粉红噪声的一种非常简单的方法,它只是将大量以对数间隔分开的波加在一起,如果您想要实时创建声音,它可能对您的目的来说太慢了。 but further optimization is surely possible (e:g. a faster cosine function).但肯定可以进一步优化(例如更快的余弦函数)。

The functions outputs a double array with values from -1 to 1. This represents the lowest and highest points in the waveform respectively.这些函数输出一个值从 -1 到 1 的双精度数组。这分别表示波形中的最低点和最高点。

The quality parameter represents the number of waves produced to make the sound. quality参数表示为发出声音而产生的波数。 I find 5000 waves (about 40 intervals per semitone) is just about the threshold where I can't detect any noticeable improvement with higher values, but to be on the safe side, you could (optionally) increase this to about 10,000 waves or higher.我发现 5000 个波(每个半音大约 40 个间隔)大约是我无法检测到更高值的任何明显改进的阈值,但为了安全起见,您可以(可选)将其增加到大约 10,000 个波或更高. Also, according to Wikipedia, 20 hertz is around the lower limit of human perception in terms of what we can hear, but you can change this too if you want.此外,根据 Wikipedia 的说法,就我们能听到的声音而言,20 赫兹大约是人类感知的下限,但如果你愿意,你也可以改变它。

Note the sound gets quieter with a higher quality value due to technical reasons, so you may (optionally) want to adjust the volume via the volumeAdjust parameter.请注意,由于技术原因,声音变得更安静, 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;
}

As a quick and dirty way to do it, how about just looping a pink noise wav in your audio player?作为一种快速而肮脏的方法,在你的音频播放器中循环播放粉红噪声 wav 怎么样? (Yes, I know part of the fun is to make it yourself....) (是的,我知道部分乐趣是自己动手做......)

What about an.mp3 sample of Pink Noise on repeat?重复播放粉红噪声的 .mp3 样本怎么样?

You could use Audacity to generate as much pink noise as you want, and then repeat it.你可以使用Audacity来产生你想要的尽可能多的粉红噪声,然后重复它。

Or you could dig into the source code and see how Audacity does the pink noise generation.或者您可以深入研究源代码,看看 Audacity 如何生成粉红噪声。

If you're on Linux, you can use SOX (you may have it already, try the play command).如果你在 Linux 上,你可以使用 SOX(你可能已经有了,试试play命令)。

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

I can't speak about C#, but you might be better off with some good noise canceling headphones and your favorite mp3's.我不能谈论 C#,但你可能会更好地使用一些好的降噪耳机和你最喜欢的 mp3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM