一种制作假视听器的算法

时间:2018-05-16 01:28:59

标签: audio random soundcloud spectrum visualizer

是否有人知道制作随机数字序列的算法(如100个java-byte(> = -127&< = 127)),当绘制为条形图时,将类似于常规数字音频频谱,就像SoundCloud那样?

我试图写一个,它有多个随机和鼻窦计算,但结果非常难看,它是在窦波和旧牙刷之间的东西。如果你把我的代码指向一个具有美学意义的那个

,我将非常感激

带有解释(和/或图片)的算法很好。伪代码对你很好。实际的JAVA代码是奖金。 :d

修改

这是我现在正在使用的代码。它很复杂,但我基本上是随机偏差给随机幅度的正弦波增加(我不确定这是不是一个好主意)。

private static final int FREQ = 7;
private static final double DEG_TO_RAD = Math.PI / 180;
private static final int MAX_AMPLITUDE = 127;
private static final float DEVIATION = 0.1f; // 10 percent is maximum deviation

private void makeSinusoidRandomBytes() {
    byte[] bytes = new byte[AUDIO_VISUALIZER_DENSITY];
    for (int i = 0; i < AUDIO_VISUALIZER_DENSITY; i++) {

        int amplitude = random.nextInt(MAX_AMPLITUDE) - MAX_AMPLITUDE/2;
        byte dev = (byte) (random.nextInt((int) Math.max(Math.abs(2 * DEVIATION * amplitude), 1))
                - Math.abs(DEVIATION * amplitude));
        bytes[i] = (byte) (Math.sin(i * FREQ * DEG_TO_RAD) * amplitude - dev);
    }
    this.bytes = bytes;
}

2 个答案:

答案 0 :(得分:1)

真实的声波实际上是不同频率和幅度加在一起的正弦波的组合,而不是与正弦波的随机偏差。困难的部分是选择波幅和频率的组合,产生你会主观喜欢的输出!然而,大多数声波具有基频,然后是许多适合于&#34;该波长 - 例如它可能在基频的3/2 *处具有泛音,并且在基频的2/3幅度处具有泛音。通过组合这些泛音并将得到的波形缩放到-127 - +127范围,您将获得实际的声波。

以下代码是C#,但与Java足够接近,可以给您一个想法。它来自一个游戏,我需要将许多正弦波组合在一起,以创造各种类型的振荡效果:

     /// <summary>
    /// Return a value between 0 and 1 based on a sine-wave oscillating with a given combination of periods at a given point in time  
    /// </summary>
    /// <param name="time">time to get wave value at</param>
    /// <param name="periods">lengths of waves</param>
    /// <returns>height of wave</returns>
    public static float MultiPulse(float time, params float[] periods)
    {
        float c = 0;
        foreach (float p in periods)
        {
            float cp = (MathHelper.Pi / p) * time;
            float s = ((float)Math.Sin(cp) + 1) / 2;
            c += s / periods.Length;
        }
        return c;
    }

您可能希望对其进行修改,以便指定不同的幅度以及要合并的波的周期。

通过结合许多不同的振幅和周期(频率),您应该通过反复试验来获得令人信服的信息。

答案 1 :(得分:0)

根据这个想法,看到更清晰的给了我,这是我现在正在使用的代码:

int mainAmp = random.nextInt(MAX_AMPLITUDE) - MAX_AMPLITUDE / 2;
int overtoneAmp = random.nextInt(MAX_AMPLITUDE * 2 / 3) - MAX_AMPLITUDE / 3;
int overtone2Amp = random.nextInt(MAX_AMPLITUDE * 4 / 7) - MAX_AMPLITUDE / 2 * 7;

int mainFreq = random.nextInt(7) + 7;
int overtoneFreq = mainFreq * 3 / 2;
int overtone2Freq = mainFreq * 7 / 4;

byte[] bytes = new byte[AUDIO_VISUALIZER_DENSITY];
for (int i = 0; i < AUDIO_VISUALIZER_DENSITY; i++) {

    bytes[i] = (byte) (Math.sin(i * mainFreq * DEG_TO_RAD) * mainAmp
            + Math.sin(i * overtoneFreq * DEG_TO_RAD) * overtoneAmp
            + Math.sin(i * overtone2Freq * DEG_TO_RAD) * overtone2Amp);
}

我的应用的主频率在8到15之间。你可以玩那些。我正在使用的另外两个泛音是(2 - 1/2)x&amp; (2 - 1/4)x主频率。您可以添加更多像(2 - 1/8)x等。或使用另一系列频率。我也随机化幅度以获得每次独特的波。

这些是我正在使用此代码绘制的一些波形:

wave 1

wave 2

wave 3