Мне нужно реализовать различные типы LFO [низкочастотного генератора] (синус, квадрат, пила, случайный ...?) Для периодического сигнала, создаваемого AudioTrack
, и я не знаю как.
Я начинаю с уравнения из вики , но я не очень хорош в математике, и я не знаю, как, например, сделать пилообразную волну 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-30 Гц) и 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, которую я использую LFO = ampLFO * Math.sin(ph2);
, работает очень хорошо,Форма LFO синусовая, и он точно модулирует весь мой сигнал.Мне нужно создать волну НЛО квадратной, пильной или произвольной формы, и я не знаю как.Кто-нибудь может подтолкнуть меня?