Mercurial > hg > cmdp
diff src/uk/ac/qmul/eecs/depic/daw/referencesound/BeadsWaveTableSequenceMapping.java @ 0:3074a84ef81e
first import
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Wed, 26 Aug 2015 16:16:53 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/uk/ac/qmul/eecs/depic/daw/referencesound/BeadsWaveTableSequenceMapping.java Wed Aug 26 16:16:53 2015 +0100 @@ -0,0 +1,199 @@ +/* + Cross-Modal DAW Prototype - Prototype of a simple Cross-Modal Digital Audio Workstation. + + Copyright (C) 2015 Queen Mary University of London (http://depic.eecs.qmul.ac.uk/) + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +*/ +package uk.ac.qmul.eecs.depic.daw.referencesound; + +import net.beadsproject.beads.core.AudioContext; +import net.beadsproject.beads.core.Bead; +import net.beadsproject.beads.core.UGen; +import net.beadsproject.beads.data.Buffer; +import net.beadsproject.beads.ugens.Envelope; +import net.beadsproject.beads.ugens.Gain; +import net.beadsproject.beads.ugens.WavePlayer; +import uk.ac.qmul.eecs.depic.patterns.Range; +import uk.ac.qmul.eecs.depic.patterns.Sequence; + +/** + * Implements a sequence mapping using beads engine and simple wave tables ugens + * + * + */ +class BeadsWaveTableSequenceMapping extends BeadsSequenceMapping { + private Range<Float> renderCurvePitchSpan; + private Range<Float> renderValuePitchSpan; + private static final float ATTACK_TIME_MS = 5.0f; + + static { + /* loads the buffer for the PeakLevelPitchedUgen and stores it into staticBuffs */ + int bufferLen = 4096; + Buffer pulse = new Buffer(bufferLen); + int pulseWidth = bufferLen/10; + + for(int i=0; i<pulseWidth;i++){ + pulse.buf[i] = 1.0f; + } + + for(int i=pulseWidth; i<bufferLen; i++){ + pulse.buf[i] = -1.0f; + } + + Buffer.staticBufs.put("Pulse", pulse); + } + + public BeadsWaveTableSequenceMapping(AudioContext ac, Range<Float> curvePitchSpan, Range<Float> valuePitchSpan){ + super(ac); + renderCurvePitchSpan = curvePitchSpan; + renderValuePitchSpan = valuePitchSpan; + } + + @Override + protected PitchedUGen createRenderValueUGen(){ + return new BufferPitchedUGen(ac, renderValuePitchSpan, Buffer.SINE); + } + + @Override + protected PitchedUGen createRenderCurveUGen(){ + return new BufferPitchedUGen(ac, renderCurvePitchSpan, Buffer.SINE); + } + + + @Override + protected Range<Float> getRenderValuePitchSpan() { + return renderValuePitchSpan; + } + + @Override + protected Range<Float> getRenderCurvePitchSpan() { + return renderCurvePitchSpan; + } + + private class BufferPitchedUGen extends PitchedUGen { + private Gain gain; + private WavePlayer player; + private float maxFreq; + private float minFreq; + private Envelope env; + + /** + * + * Pulse TriangularBuffer Square Saw Noise Sine + * + * @param ac + * @param pitchSpan + * @param buffer + */ + public BufferPitchedUGen(AudioContext ac, Range<Float> pitchSpan, Buffer buffer) { + super(ac); + if(maxFreq < minFreq){ + throw new IllegalArgumentException("minFreq must be lower than maxFreq. minFreq: "+minFreq+" maxFreq:"+maxFreq ); + } + + this.minFreq = pitchSpan.getStart(); + this.maxFreq = pitchSpan.getEnd(); + gain = new Gain(ac, 1, 0.5f); + player = new WavePlayer(ac,minFreq,buffer); + + gain.addInput(player); + + addToChainOutput(gain); + } + + @Override + public void setPitch(float pitch){ + /* set the frequency for both the actual curve sound and the threshold sound */ + player.setFrequency(pitch); + + } + + @Override + public void setPitch(UGen pitch) { + player.setFrequency(pitch); + } + + public float getFrequency(float freq){ + return player.getFrequency(); + } + + @Override + public void start(){ + player.start(); + } + + + @Override + public void setLen(float sustainValue, float decayTime){ + /* if decayTime is long enough, smooth out the attack to avoid glitchy sound */ + if(Float.compare(decayTime,ATTACK_TIME_MS) > 0){ + env = new Envelope(context,0.0f); // starts from 0 + env.addSegment(sustainValue,ATTACK_TIME_MS,2); // attack + env.addSegment(0.0f,decayTime-ATTACK_TIME_MS, this); // decay + }else{ + env = new Envelope(context,sustainValue); + env.addSegment(0.0f, decayTime, this); // decay + } + gain.setGain(env); + } + + @Override + public void addLen(float sustainValue, float duration, final Bead bead){ + if(env == null){ + if(Float.compare(duration,ATTACK_TIME_MS) > 0){ + env = new Envelope(context,0.0f); // starts from 0 + env.addSegment(sustainValue,ATTACK_TIME_MS,2); // attack + env.addSegment(sustainValue,duration-ATTACK_TIME_MS, bead); // decay + }else{ + env = new Envelope(context,sustainValue); + env.addSegment(0.0f, duration, bead); // decay + } + gain.setGain(env); + }else{ + env.addSegment(sustainValue,duration, bead); + } + + } + + @Override + public void addLen(float sustainValue, float duration ){ + if(env == null){ + if(Float.compare(duration,ATTACK_TIME_MS) > 0){ + env = new Envelope(context,0.0f); // starts from 0 + env.addSegment(sustainValue,ATTACK_TIME_MS,2); // attack + env.addSegment(sustainValue,duration-ATTACK_TIME_MS, this); // decay + }else{ + env = new Envelope(context,sustainValue); + env.addSegment(sustainValue, duration, this); // decay + } + gain.setGain(env); + }else{ + env.addSegment(0.0f,duration, this); + } + + } + + @Override + public void messageReceived(Bead b){ + kill(); + } + + } + + @Override + public void renderCurve(Sequence m, float startTime) { + throw new UnsupportedOperationException(); + } +};; \ No newline at end of file