我需要对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波,但我不知道如何。有人可以推我吗?