如何在周期信号中实现不同的LFO类型

时间:2019-04-26 18:51:50

标签: java android audiotrack modulation

我需要对AudioTrack创建的周期性信号实施不同类型的LFO(低频振荡器)(正弦波,方波,锯齿波,随机...?),我不知道该怎么做。

我从wiki的方程式开始,但是我在数学上并不擅长,而且我不知道如何制作例如锯齿波LFO来调制其他周期信号。

private boolean isRunning;
private double tuneFreqSI;
private double frLFO;
private double ampLFO;
private int sr = 44100;

public void run() {

    super.run();
    isRunning = true;

    int sibuffsize = AudioTrack.getMinBufferSize(sr,
            AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
    AudioTrack siaudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sr, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, sibuffsize,
            AudioTrack.MODE_STREAM);

    short[] samples = new short[sibuffsize];
    int amp = 32767;
    double twopi = 8. * Math.atan(1.);
    double ph = 0.0;
    double ph1 = 0.0;
    double ph2 = 0.0;
    double LFO = 0;

    // start audio
    try {
        siaudioTrack.play();
    } catch (IllegalStateException e) {

        System.out.println("error play " + e);
    }

    // synthesis loop
    while (isRunning) {

        double fr = tuneFreqSI;
        double fLFO = frLFO;

        for (int i = 0; i < sibuffsize; i++) {

            LFO = ampLFO * Math.sin(ph2);

            samples[i] = (short) (amp * Math.sin(ph + LFO));


            ph += twopi * fr / sr;
            ph2 += twopi * fLFO / sr;
        }
        siaudioTrack.write(samples, 0, sibuffsize);

    }


    siaudioTrack.stop();
    siaudioTrack.release();
}

public void setTuneFreq(double tuneFreq, double frLFO, double ampLFO) {

    this.tuneFreqSI = tuneFreq;
    this.frLFO = frLFO;
    this.ampLFO = ampLFO;
}


public void stopTune() {
    isRunning = false;

    try {
        this.join();
        this.interrupt();
    } catch (InterruptedException e) {
        System.out.println("can´t stop thread +" + e);
        e.printStackTrace();
    }
}

这是我生成正弦波的代码。

LFO由2个值控制-频率(1-30Hz)和Amplitude,实际上是混合到主信号的LFO的深度。

我正在使用的方波发生器

samples[i] = (short) (amp * Math.sin(ph+ LFO));

            if (samples[i] > (short) 0.0) {
                samples[i] = (short) amp;
            }

            if (samples[i] < (short) 0.0) {
                samples[i] = (short) -amp;
            }
        ph += twopi * fr / sr;

和锯波发生器类似

samples[i] = (short) (amp * (ph / Math.PI + LFO));

        ph += twopi * fr / sr;

我正在使用的LFO = ampLFO * Math.sin(ph2);这个LFO公式工作正常。 LFO形状为窦形,它可以正确调制我的所有信号。我需要创建Square,Saw或任意形状的LFO波,但我不知道如何。有人可以推我吗?

0 个答案:

没有答案