1 /* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.media.sound; 27 28 /** 29 * LFO control signal generator. 30 * 31 * @author Karl Helgason 32 */ 33 public final class SoftLowFrequencyOscillator implements SoftProcess { 34 35 private final int max_count = 10; 36 private int used_count = 0; 37 private final double[][] out = new double[max_count][1]; 38 private final double[][] delay = new double[max_count][1]; 39 private final double[][] delay2 = new double[max_count][1]; 40 private final double[][] freq = new double[max_count][1]; 41 private final int[] delay_counter = new int[max_count]; 42 private final double[] sin_phase = new double[max_count]; 43 private final double[] sin_stepfreq = new double[max_count]; 44 private final double[] sin_step = new double[max_count]; 45 private double control_time = 0; 46 private double sin_factor = 0; 47 private static final double PI2 = 2.0 * Math.PI; 48 49 public SoftLowFrequencyOscillator() { 50 // If sin_step is 0 then sin_stepfreq must be -INF 51 for (int i = 0; i < sin_stepfreq.length; i++) { 52 sin_stepfreq[i] = Double.NEGATIVE_INFINITY; 53 } 54 } 55 56 @Override 57 public void reset() { 58 for (int i = 0; i < used_count; i++) { 59 out[i][0] = 0; 60 delay[i][0] = 0; 61 delay2[i][0] = 0; 62 freq[i][0] = 0; 63 delay_counter[i] = 0; 64 sin_phase[i] = 0; 65 // If sin_step is 0 then sin_stepfreq must be -INF 66 sin_stepfreq[i] = Double.NEGATIVE_INFINITY; 67 sin_step[i] = 0; 68 } 69 used_count = 0; 70 } 71 72 @Override 73 public void init(SoftSynthesizer synth) { 74 control_time = 1.0 / synth.getControlRate(); 75 sin_factor = control_time * 2 * Math.PI; 76 for (int i = 0; i < used_count; i++) { 77 delay_counter[i] = (int)(Math.pow(2, 78 this.delay[i][0] / 1200.0) / control_time); 79 delay_counter[i] += (int)(delay2[i][0] / (control_time * 1000)); 80 } 81 processControlLogic(); 82 } 83 84 @Override 85 public void processControlLogic() { 86 for (int i = 0; i < used_count; i++) { 87 if (delay_counter[i] > 0) { 88 delay_counter[i]--; 89 out[i][0] = 0.5; 90 } else { 91 double f = freq[i][0]; 92 93 if (sin_stepfreq[i] != f) { 94 sin_stepfreq[i] = f; 95 double fr = 440.0 * Math.exp( 96 (f - 6900.0) * (Math.log(2) / 1200.0)); 97 sin_step[i] = fr * sin_factor; 98 } 99 /* 100 double fr = 440.0 * Math.pow(2.0, 101 (freq[i][0] - 6900.0) / 1200.0); 102 sin_phase[i] += fr * sin_factor; 103 */ 104 /* 105 sin_phase[i] += sin_step[i]; 106 while (sin_phase[i] > PI2) 107 sin_phase[i] -= PI2; 108 out[i][0] = 0.5 + Math.sin(sin_phase[i]) * 0.5; 109 */ 110 double p = sin_phase[i]; 111 p += sin_step[i]; 112 while (p > PI2) 113 p -= PI2; 114 out[i][0] = 0.5 + Math.sin(p) * 0.5; 115 sin_phase[i] = p; 116 117 } 118 } 119 } 120 121 @Override 122 public double[] get(int instance, String name) { 123 if (instance >= used_count) 124 used_count = instance + 1; 125 if (name == null) 126 return out[instance]; 127 if (name.equals("delay")) 128 return delay[instance]; 129 if (name.equals("delay2")) 130 return delay2[instance]; 131 if (name.equals("freq")) 132 return freq[instance]; 133 return null; 134 } 135 }