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