1 /* 2 * Copyright (c) 2007, 2010, 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 import java.util.ArrayList; 27 28 import javax.sound.sampled.AudioFormat; 29 import javax.sound.sampled.AudioSystem; 30 import javax.sound.sampled.Control; 31 import javax.sound.sampled.DataLine; 32 import javax.sound.sampled.LineListener; 33 import javax.sound.sampled.LineUnavailableException; 34 import javax.sound.sampled.SourceDataLine; 35 import javax.sound.sampled.AudioFormat.Encoding; 36 import javax.sound.sampled.Control.Type; 37 38 import com.sun.media.sound.AudioFloatConverter; 39 40 /** 41 * This is a SourceDataLine simulator used for testing SoftSynthesizer 42 * without using real SourceDataLine / Audio Device. 43 * 44 * @author Karl Helgason 45 */ 46 47 public class DummySourceDataLine implements SourceDataLine { 48 49 private int bufferSize = -1; 50 51 private AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false); 52 53 private DataLine.Info sourceLineInfo; 54 55 private boolean active = false; 56 57 private long framepos = 0; 58 59 private boolean opened = false; 60 61 private int framesize = 0; 62 63 public DummySourceDataLine() 64 { 65 ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>(); 66 for (int channels = 1; channels <= 2; channels++) { 67 formats.add(new AudioFormat(Encoding.PCM_SIGNED, 68 AudioSystem.NOT_SPECIFIED, 8, channels, channels, 69 AudioSystem.NOT_SPECIFIED, false)); 70 formats.add(new AudioFormat(Encoding.PCM_UNSIGNED, 71 AudioSystem.NOT_SPECIFIED, 8, channels, channels, 72 AudioSystem.NOT_SPECIFIED, false)); 73 for (int bits = 16; bits < 32; bits += 8) { 74 formats.add(new AudioFormat(Encoding.PCM_SIGNED, 75 AudioSystem.NOT_SPECIFIED, bits, channels, channels 76 * bits / 8, AudioSystem.NOT_SPECIFIED, false)); 77 formats.add(new AudioFormat(Encoding.PCM_UNSIGNED, 78 AudioSystem.NOT_SPECIFIED, bits, channels, channels 79 * bits / 8, AudioSystem.NOT_SPECIFIED, false)); 80 formats.add(new AudioFormat(Encoding.PCM_SIGNED, 81 AudioSystem.NOT_SPECIFIED, bits, channels, channels 82 * bits / 8, AudioSystem.NOT_SPECIFIED, true)); 83 formats.add(new AudioFormat(Encoding.PCM_UNSIGNED, 84 AudioSystem.NOT_SPECIFIED, bits, channels, channels 85 * bits / 8, AudioSystem.NOT_SPECIFIED, true)); 86 } 87 formats.add(new AudioFormat(Encoding.PCM_FLOAT, 88 AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4, 89 AudioSystem.NOT_SPECIFIED, false)); 90 formats.add(new AudioFormat(Encoding.PCM_FLOAT, 91 AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4, 92 AudioSystem.NOT_SPECIFIED, true)); 93 formats.add(new AudioFormat(Encoding.PCM_FLOAT, 94 AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8, 95 AudioSystem.NOT_SPECIFIED, false)); 96 formats.add(new AudioFormat(Encoding.PCM_FLOAT, 97 AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8, 98 AudioSystem.NOT_SPECIFIED, true)); 99 } 100 AudioFormat[] formats_array = formats.toArray(new AudioFormat[formats 101 .size()]); 102 sourceLineInfo = new DataLine.Info(SourceDataLine.class, 103 formats_array, AudioSystem.NOT_SPECIFIED, 104 AudioSystem.NOT_SPECIFIED); 105 106 } 107 108 public void open() throws LineUnavailableException { 109 open(format); 110 } 111 112 public void open(AudioFormat format) throws LineUnavailableException { 113 if (bufferSize == -1) 114 bufferSize = ((int) (format.getFrameRate() / 2)) 115 * format.getFrameSize(); 116 open(format, bufferSize); 117 } 118 119 public void open(AudioFormat format, int bufferSize) 120 throws LineUnavailableException { 121 this.format = format; 122 this.bufferSize = bufferSize; 123 this.framesize = format.getFrameSize(); 124 opened = true; 125 } 126 127 public boolean isOpen() { 128 return opened; 129 } 130 131 public int write(byte[] b, int off, int len) { 132 if (!isOpen()) 133 return 0; 134 if (len % framesize != 0) 135 throw new IllegalArgumentException( 136 "Number of bytes does not represent an integral number of sample frames."); 137 138 139 int flen = len / framesize; 140 framepos += flen; 141 142 long time = (long) (flen * (1000.0 / (double) getFormat() 143 .getSampleRate())); 144 try { 145 Thread.sleep(time); 146 } catch (InterruptedException e) { 147 e.printStackTrace(); 148 return 0; 149 } 150 151 return len; 152 } 153 154 public int available() { 155 return 0; 156 } 157 158 public void drain() { 159 } 160 161 public void flush() { 162 } 163 164 public int getBufferSize() { 165 return bufferSize; 166 } 167 168 public AudioFormat getFormat() { 169 return format; 170 } 171 172 public int getFramePosition() { 173 return (int) getLongFramePosition(); 174 } 175 176 public float getLevel() { 177 return AudioSystem.NOT_SPECIFIED; 178 } 179 180 public long getLongFramePosition() { 181 return framepos; 182 } 183 184 public long getMicrosecondPosition() { 185 return (long) (getLongFramePosition() * (1000000.0 / (double) getFormat() 186 .getSampleRate())); 187 } 188 189 public boolean isActive() { 190 return active; 191 } 192 193 public boolean isRunning() { 194 return active; 195 } 196 197 public void start() { 198 active = true; 199 } 200 201 public void stop() { 202 active = false; 203 } 204 205 public void close() { 206 stop(); 207 } 208 209 public Control getControl(Type control) { 210 throw new IllegalArgumentException("Unsupported control type : " 211 + control); 212 } 213 214 public Control[] getControls() { 215 return new Control[0]; 216 } 217 218 public javax.sound.sampled.Line.Info getLineInfo() { 219 return sourceLineInfo; 220 } 221 222 public boolean isControlSupported(Type control) { 223 return false; 224 } 225 226 public void addLineListener(LineListener listener) { 227 } 228 229 public void removeLineListener(LineListener listener) { 230 } 231 232 }