关于c#:Random.Next()没有选择随机值的问题

Issue with Random.Next() not choosing random values

据我所知,random.next()使用系统时间来获取种子,但是当非常快地遍历循环时,系统时间没有更改或几乎没有更改,给了我相同的"随机"数字。我正试图随机选择开始位置,开始在音乐文件中输入静态字节大约2秒,选择30个不同的位置,但它们几乎是相同的。我从一开始就几乎一直处于静态状态,在它恢复正常播放30秒左右的音乐之前,我中断了大约3次,仅几秒钟;这不是我想要的,我需要它在整个剪辑中展开。""int pos"是个问题,它不是随机的,每个起始位置几乎都是相同的,所以我有一个长期的静态量,而不是静态随机分布在整个音乐中。我的随机数也是静态的。

1
2
3
4
5
6
7
8
9
10
11
12
FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
for (int i = 0; i < 20; i++)
{
    int pos = rand2.Next(75000, 4000000 /*I've been too lazy to get the file length, so I'm using 4000000*/ );
    for (int x = 0; x < 500000/*500000 is a little over 2 seconds of static*/; x++)
    {
        byte number = array[rand.Next(array.Length)];
        stream.Position = pos;
        pos++;
        stream.WriteByte(number);
    }
}

我假设每写一次(在我的慢CPU上)需要5秒左右的时间,这足够让下一个随机事件给我一个与前一个位置不相同或非常接近的位置。现在看来,每次我的初始位置大约是90000(音乐的前几秒);接下来的所有位置都在20秒内。所以我的问题是,为了达到我想要的结果,我需要做哪些不同的修改/操作?我想要在整个剪辑中分散几秒钟的静态效果,而不是聚集在一起。

我有一个字节数组,它存储我的十六进制数字,这些数字是随机选择的,看起来工作得很好,只是书写位置的随机性根本不是随机的,它们都非常接近。

1
byte[] array = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };

谢谢。

另外,我知道应该为文件流设置using块,我会在访问时添加它。


当你写作时:int pos=rand2.下一个(75000,4000000)如果您的文件是立体声16位48kHz,则4000000/(2*2*48000)=20秒声音的使用文件大小,很容易。你不应该懒惰。但是,如果您"添加"噪声,则不应替换文件值,而应添加到它是一个随机值。为什么噪声振幅只有16/字节?固定?使用数字=rand.next(振幅)计算附加噪声似乎很好。还要注意,您正在创建两个白噪声,每个通道一个。


如果500000字节是2秒的音频,而您的开始时间介于75000到4000000之间,那么您将在歌曲的开始时间介于0.15到8秒之间。这就解释了为什么在进入歌曲大约10秒后你没有听到任何静电。尝试使用实际文件大小(减去500000)作为rand的上界。next调用用于填充pos


第一个是随机数。下一个不是使用系统时钟生成随机数。随机数是根据提供的种子生成的,默认的构造函数(无参数)使用系统时钟作为种子,但它只将系统时钟设置为种子。如果我错了,请纠正我,但看起来你得到的是随机数,但这些数字非常接近,可以产生几乎相同的声音,你希望你的数字分散在很大的空白处(连续随机数之间的差异)。为了实现这一点,我建议您使用最小阈值。如果连续数之间的差小于阈值,请尝试生成下一个值或调整该值以满足阈值。代码可以更好地解释我想说的话。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int RandomNumber(Random rand,int? lastRandomNumber, int min, int max, int threshold)
        {
            var number = rand.Next(min, max);
            if (lastRandomNumber.HasValue && Math.Abs(lastRandomNumber.Value - number) < threshold)
            {
                Console.WriteLine("Actual:{0}", number);
                if (lastRandomNumber.Value < number)
                {
                    number += threshold;
                    if (number > max)
                        number = max;
                }
                else
                {
                    number -= threshold;
                    if (number < min)
                        number = min;

                }
            }
            return number;
        }

我在生成随机数时也遇到了同样的问题。它产生了相同的值。下面的简单代码解决了我的问题。

1
2
3
4
5
6
7
8
9
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public int RandomNumber(int min, int max)
{
   lock (syncLock)
   { // synchronize
       return random.Next(min, max);
   }
}

您将使用如下所示:

1
int rn = RandomNumber(0, 10); //for example