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