Mercurial > hg > cmdp
view 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 source
/* 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(); } };;