annotate 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
rev   line source
f@0 1 /*
f@0 2 Cross-Modal DAW Prototype - Prototype of a simple Cross-Modal Digital Audio Workstation.
f@0 3
f@0 4 Copyright (C) 2015 Queen Mary University of London (http://depic.eecs.qmul.ac.uk/)
f@0 5
f@0 6 This program is free software: you can redistribute it and/or modify
f@0 7 it under the terms of the GNU General Public License as published by
f@0 8 the Free Software Foundation, either version 3 of the License, or
f@0 9 (at your option) any later version.
f@0 10
f@0 11 This program is distributed in the hope that it will be useful,
f@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
f@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f@0 14 GNU General Public License for more details.
f@0 15
f@0 16 You should have received a copy of the GNU General Public License
f@0 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
f@0 18 */
f@0 19 package uk.ac.qmul.eecs.depic.daw.referencesound;
f@0 20
f@0 21 import net.beadsproject.beads.core.AudioContext;
f@0 22 import net.beadsproject.beads.core.Bead;
f@0 23 import net.beadsproject.beads.core.UGen;
f@0 24 import net.beadsproject.beads.data.Buffer;
f@0 25 import net.beadsproject.beads.ugens.Envelope;
f@0 26 import net.beadsproject.beads.ugens.Gain;
f@0 27 import net.beadsproject.beads.ugens.WavePlayer;
f@0 28 import uk.ac.qmul.eecs.depic.patterns.Range;
f@0 29 import uk.ac.qmul.eecs.depic.patterns.Sequence;
f@0 30
f@0 31 /**
f@0 32 * Implements a sequence mapping using beads engine and simple wave tables ugens
f@0 33 *
f@0 34 *
f@0 35 */
f@0 36 class BeadsWaveTableSequenceMapping extends BeadsSequenceMapping {
f@0 37 private Range<Float> renderCurvePitchSpan;
f@0 38 private Range<Float> renderValuePitchSpan;
f@0 39 private static final float ATTACK_TIME_MS = 5.0f;
f@0 40
f@0 41 static {
f@0 42 /* loads the buffer for the PeakLevelPitchedUgen and stores it into staticBuffs */
f@0 43 int bufferLen = 4096;
f@0 44 Buffer pulse = new Buffer(bufferLen);
f@0 45 int pulseWidth = bufferLen/10;
f@0 46
f@0 47 for(int i=0; i<pulseWidth;i++){
f@0 48 pulse.buf[i] = 1.0f;
f@0 49 }
f@0 50
f@0 51 for(int i=pulseWidth; i<bufferLen; i++){
f@0 52 pulse.buf[i] = -1.0f;
f@0 53 }
f@0 54
f@0 55 Buffer.staticBufs.put("Pulse", pulse);
f@0 56 }
f@0 57
f@0 58 public BeadsWaveTableSequenceMapping(AudioContext ac, Range<Float> curvePitchSpan, Range<Float> valuePitchSpan){
f@0 59 super(ac);
f@0 60 renderCurvePitchSpan = curvePitchSpan;
f@0 61 renderValuePitchSpan = valuePitchSpan;
f@0 62 }
f@0 63
f@0 64 @Override
f@0 65 protected PitchedUGen createRenderValueUGen(){
f@0 66 return new BufferPitchedUGen(ac, renderValuePitchSpan, Buffer.SINE);
f@0 67 }
f@0 68
f@0 69 @Override
f@0 70 protected PitchedUGen createRenderCurveUGen(){
f@0 71 return new BufferPitchedUGen(ac, renderCurvePitchSpan, Buffer.SINE);
f@0 72 }
f@0 73
f@0 74
f@0 75 @Override
f@0 76 protected Range<Float> getRenderValuePitchSpan() {
f@0 77 return renderValuePitchSpan;
f@0 78 }
f@0 79
f@0 80 @Override
f@0 81 protected Range<Float> getRenderCurvePitchSpan() {
f@0 82 return renderCurvePitchSpan;
f@0 83 }
f@0 84
f@0 85 private class BufferPitchedUGen extends PitchedUGen {
f@0 86 private Gain gain;
f@0 87 private WavePlayer player;
f@0 88 private float maxFreq;
f@0 89 private float minFreq;
f@0 90 private Envelope env;
f@0 91
f@0 92 /**
f@0 93 *
f@0 94 * Pulse TriangularBuffer Square Saw Noise Sine
f@0 95 *
f@0 96 * @param ac
f@0 97 * @param pitchSpan
f@0 98 * @param buffer
f@0 99 */
f@0 100 public BufferPitchedUGen(AudioContext ac, Range<Float> pitchSpan, Buffer buffer) {
f@0 101 super(ac);
f@0 102 if(maxFreq < minFreq){
f@0 103 throw new IllegalArgumentException("minFreq must be lower than maxFreq. minFreq: "+minFreq+" maxFreq:"+maxFreq );
f@0 104 }
f@0 105
f@0 106 this.minFreq = pitchSpan.getStart();
f@0 107 this.maxFreq = pitchSpan.getEnd();
f@0 108 gain = new Gain(ac, 1, 0.5f);
f@0 109 player = new WavePlayer(ac,minFreq,buffer);
f@0 110
f@0 111 gain.addInput(player);
f@0 112
f@0 113 addToChainOutput(gain);
f@0 114 }
f@0 115
f@0 116 @Override
f@0 117 public void setPitch(float pitch){
f@0 118 /* set the frequency for both the actual curve sound and the threshold sound */
f@0 119 player.setFrequency(pitch);
f@0 120
f@0 121 }
f@0 122
f@0 123 @Override
f@0 124 public void setPitch(UGen pitch) {
f@0 125 player.setFrequency(pitch);
f@0 126 }
f@0 127
f@0 128 public float getFrequency(float freq){
f@0 129 return player.getFrequency();
f@0 130 }
f@0 131
f@0 132 @Override
f@0 133 public void start(){
f@0 134 player.start();
f@0 135 }
f@0 136
f@0 137
f@0 138 @Override
f@0 139 public void setLen(float sustainValue, float decayTime){
f@0 140 /* if decayTime is long enough, smooth out the attack to avoid glitchy sound */
f@0 141 if(Float.compare(decayTime,ATTACK_TIME_MS) > 0){
f@0 142 env = new Envelope(context,0.0f); // starts from 0
f@0 143 env.addSegment(sustainValue,ATTACK_TIME_MS,2); // attack
f@0 144 env.addSegment(0.0f,decayTime-ATTACK_TIME_MS, this); // decay
f@0 145 }else{
f@0 146 env = new Envelope(context,sustainValue);
f@0 147 env.addSegment(0.0f, decayTime, this); // decay
f@0 148 }
f@0 149 gain.setGain(env);
f@0 150 }
f@0 151
f@0 152 @Override
f@0 153 public void addLen(float sustainValue, float duration, final Bead bead){
f@0 154 if(env == null){
f@0 155 if(Float.compare(duration,ATTACK_TIME_MS) > 0){
f@0 156 env = new Envelope(context,0.0f); // starts from 0
f@0 157 env.addSegment(sustainValue,ATTACK_TIME_MS,2); // attack
f@0 158 env.addSegment(sustainValue,duration-ATTACK_TIME_MS, bead); // decay
f@0 159 }else{
f@0 160 env = new Envelope(context,sustainValue);
f@0 161 env.addSegment(0.0f, duration, bead); // decay
f@0 162 }
f@0 163 gain.setGain(env);
f@0 164 }else{
f@0 165 env.addSegment(sustainValue,duration, bead);
f@0 166 }
f@0 167
f@0 168 }
f@0 169
f@0 170 @Override
f@0 171 public void addLen(float sustainValue, float duration ){
f@0 172 if(env == null){
f@0 173 if(Float.compare(duration,ATTACK_TIME_MS) > 0){
f@0 174 env = new Envelope(context,0.0f); // starts from 0
f@0 175 env.addSegment(sustainValue,ATTACK_TIME_MS,2); // attack
f@0 176 env.addSegment(sustainValue,duration-ATTACK_TIME_MS, this); // decay
f@0 177 }else{
f@0 178 env = new Envelope(context,sustainValue);
f@0 179 env.addSegment(sustainValue, duration, this); // decay
f@0 180 }
f@0 181 gain.setGain(env);
f@0 182 }else{
f@0 183 env.addSegment(0.0f,duration, this);
f@0 184 }
f@0 185
f@0 186 }
f@0 187
f@0 188 @Override
f@0 189 public void messageReceived(Bead b){
f@0 190 kill();
f@0 191 }
f@0 192
f@0 193 }
f@0 194
f@0 195 @Override
f@0 196 public void renderCurve(Sequence m, float startTime) {
f@0 197 throw new UnsupportedOperationException();
f@0 198 }
f@0 199 };;