/* * Created on Dec 9, 2004 * * Copyright (c) 2005 Peter Johan Salomonsen (http://www.petersalomonsen.com) * * http://www.frinika.com * * This file is part of Frinika. * * Frinika is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Frinika is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Frinika; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.frinika.synth; import com.frinika.synth.envelope.MidiVolume; /** * @author Peter Johan Salomonsen * */ public class PostOscillator extends Oscillator { int overDriveAmount = 0; float echoAmount = 0; int echoLength = 48; float volume = MidiVolume.midiVolumeToAmplitudeRatio(100); float echoBuffer[] = null; int echoBufferPos = 0; Pan pan = new Pan(0.5f); float reverb = MidiVolume.midiVolumeToAmplitudeRatio(0); /** * @param synth */ public PostOscillator(Synth synth) { super(synth); } /* (non-Javadoc) * @see com.petersalomonsen.mystudio.audio.IAudioOutputGenerator#fillBuffer(int, int, float[]) */ public void fillBuffer(int startBufferPos, int endBufferPos, float[] buffer) { // -------------------------- For debugging ------------------------------ // Need to find out whether it is preOscillator or preOscillator.sampleBuffer == null // Ref. bug http://sourceforge.net/tracker/index.php?func=detail&aid=1450319&group_id=131823&atid=722343 if(synth.preOscillator == null) { System.out.println("FATAL: preOscillator is null - please add this line as comment to http://sourceforge.net/tracker/index.php?func=detail&aid=1450319&group_id=131823&atid=722343"); return; } if(synth.preOscillator.sampleBuffer == null) { System.out.println("FATAL: preOscillator.sampleBuffer is null - please add this line as comment to http://sourceforge.net/tracker/index.php?func=detail&aid=1450319&group_id=131823&atid=722343"); return; } // ----------------------------------------------------------------------- for(int n=startBufferPos;n<endBufferPos;n++) { float sample = synth.preOscillator.sampleBuffer[n]; // Overdrive if(overDriveAmount>0) sample = Overdrive.process(synth.preOscillator.sampleBuffer[n],overDriveAmount); // Echo if(echoBuffer!=null) { echoBufferPos %= echoBuffer.length; echoBuffer[echoBufferPos]*=echoAmount; float echoBufferSample = echoBuffer[echoBufferPos]; echoBuffer[echoBufferPos] += sample; sample+=echoBufferSample; echoBufferPos++; } // Gain sample *= volume; // Pan if((n & 0x01) == 0) sample *= pan.getLeftLevel(); else sample *= pan.getRightLevel(); synth.preOscillator.sampleBuffer[n]=sample * reverb; buffer[n] += sample; } if(reverb>0) MasterVoice.getDefaultInstance().addToReverb(startBufferPos, endBufferPos, synth.preOscillator.sampleBuffer); } /** * @param Overdrive amount */ public void setOverDriveAmount(int overDriveAmount) { this.overDriveAmount = overDriveAmount; } /** * @param volume */ public void setVolume(float volume) { this.volume = volume; } public void setReverb(float reverb) { this.reverb = reverb; } /** * @param echoAmount */ public void setEchoAmount(int echoAmount) { if(echoAmount>0) { //TODO: Resolve tempo from midi messages float ticksPerSecond = (synth.getFrinikaSynth().getTempoBPM() / 60f) * 32; if(echoBuffer==null) setEchoLength(echoLength); } else echoBuffer = null; this.echoAmount = echoAmount / 127f; } public void setEchoLength(int echoLength) { this.echoLength = echoLength; float ticksPerSecond = (synth.getFrinikaSynth().getTempoBPM() / 60f) * 32; int echoBufferSize = (int)((echoLength / ticksPerSecond) * sampleRate); if(echoBufferSize>0) echoBuffer = new float[echoBufferSize]; else echoBuffer = null; } /** * Set pan amount * @param position MIDI cc10 value (0-127) */ public void setPan(int position) { pan = new Pan((float)position/127f); } }