java - 你如何创建一个音调生成器,其音调可以在 "live"或在 java 中即时操作?

标签 java signal-processing audio

我想用 Java 制作一个可以实时操作的基本音调发生器(刚开始时只是调音)。

我想从简单的开始,然后添加更复杂的音调生成和效果,最终得到某种基本的合成器。

我找到了 a helpful post on this site在小程序 Beeper.java 中包含一些示例代码。

它生成了一个音调并将其保存到一个剪辑中。然后在需要时循环播放该剪辑。相关音调生成位:

/** Generates a tone, and assigns it to the Clip. */
public void generateTone()
    throws LineUnavailableException {
    if ( clip!=null ) {
        clip.stop();
        clip.close();
    } else {
        clip = AudioSystem.getClip();
    }
    boolean addHarmonic = harmonic.isSelected();

    int intSR = ((Integer)sampleRate.getSelectedItem()).intValue();
    int intFPW = framesPerWavelength.getValue();

    float sampleRate = (float)intSR;

    // oddly, the sound does not loop well for less than
    // around 5 or so, wavelengths
    int wavelengths = 20;
    byte[] buf = new byte[2*intFPW*wavelengths];
    AudioFormat af = new AudioFormat(
        sampleRate,
        8,  // sample size in bits
        2,  // channels
        true,  // signed
        false  // bigendian
        );

    int maxVol = 127;
    for(int i=0; i<intFPW*wavelengths; i++){
        double angle = ((float)(i*2)/((float)intFPW))*(Math.PI);
        buf[i*2]=getByteValue(angle);
        if(addHarmonic) {
            buf[(i*2)+1]=getByteValue(2*angle);
        } else {
            buf[(i*2)+1] = buf[i*2];
        }
    }

    try {
        byte[] b = buf;
        AudioInputStream ais = new AudioInputStream(
            new ByteArrayInputStream(b),
            af,
            buf.length/2 );

        clip.open( ais );
    } catch(Exception e) {
        e.printStackTrace();
    }
}

循环位:

/** Loops the current Clip until a commence false is passed. */
public void loopSound(boolean commence) {
    if ( commence ) {
        clip.setFramePosition(0);
        clip.loop( Clip.LOOP_CONTINUOUSLY );
    } else {
        clip.stop();
    }
}

我试图解决这个问题,以便在背景中创建另一个剪辑,并在我想改变音调时快速将一个剪辑换成另一个剪辑,但当然,当一个剪辑开始而另一个剪辑停止时,会发出明显的咔嗒声。

所以我猜我需要某种巧妙的缓冲来做到这一点,使一波的结束与另一波无缝匹配?

或者预生成的剪辑是不可能的?如果是这样,我应该怎么做?

顺便说一句,软件合成器是如何工作的?它们是连续生成所有声音和效果,还是像 Beeper.java 一样预生成“剪辑”和循环?

谢谢!

最佳答案

听起来你想实现一个 numerically controlled oscillator (NCO) ,用 Java 中的相位累加器实现。

基本上,您需要计算出所需频率的增量相位,然后继续将其以 2pi 为模添加到累加器。累加器的值用作 sin() 的值以生成样本值。

当你想改变频率时,你更新增量相位。这确保了样本的连续性(波浪中没有突然中断)。我怀疑这是导致您点击的原因。如果你想要更好的改变,那么你需要在一堆样本上逐渐改变 delta-phase。

关于java - 你如何创建一个音调生成器,其音调可以在 "live"或在 java 中即时操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10357861/

相关文章:

java - 在android中使用新的SQLite数据库恢复和删除旧的SQLite数据库

c++ - 从 flv 视频(或任何其他视频)中提取音频的算法。怎么办?

javascript - 音频元素不会在 Firefox 的 iframe 中显示/播放

java - 如何在 libgdx 中调整纹理大小

java - 用动态值替换字符串中标签的动态数量 - Java

matlab - MATLAB 上的低通巴特沃斯滤波

python - 如何获取信号的相位 fft &--我可以获取时域相位吗?

java - 视频中的声音充满静电

java - Android:数据库字段未通过循环填充

android - 从乐器中提取音频以找到音符