/Users/lyon/j4p/src/sound/audioDigitizer/StreamingPlaybackThread.java
|
1 package sound.audioDigitizer;
2
3 import gui.ClosableJFrame;
4 import gui.run.RunSlider;
5 import sound.OscopePanel;
6 import sound.UlawCodec;
7 import sound.Utils;
8
9 import javax.sound.sampled.AudioFileFormat;
10 import javax.sound.sampled.AudioFormat;
11 import javax.sound.sampled.AudioInputStream;
12 import javax.sound.sampled.AudioSystem;
13 import javax.sound.sampled.DataLine;
14 import javax.sound.sampled.LineUnavailableException;
15 import javax.sound.sampled.SourceDataLine;
16 import javax.swing.BoxLayout;
17 import javax.swing.JPanel;
18 import java.awt.BorderLayout;
19 import java.awt.Container;
20 import java.awt.Dimension;
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23
24 /**
25 * DocJava, Inc.
26 * http://www.docjava.com
27 * Programmer: dlyon
28 * Date: Dec 6, 2004
29 * Time: 2:37:32 PM
30 */
31 public class StreamingPlaybackThread
32 extends Thread implements Runnable {
33 SourceDataLine line;
34 String errStr = null;
35 AudioInputStream ais = null;
36 private final int bufSize = 16384;
37 CapturePlayBackPanel.FormatControls formatControls = null;
38
39 public StreamingPlaybackThread(AudioInputStream ais,
40 CapturePlayBackPanel.FormatControls formatControls) {
41 this.ais = ais;
42 this.formatControls = formatControls;
43 createControlPanel();
44 }
45
46 long delay = 100;
47
48 private void setDelay(long d) {
49 delay = d;
50 }
51
52 private long getDelay() {
53 return delay;
54 }
55
56 OscopePanel osp = new OscopePanel();
57
58 private void createControlPanel() {
59 System.out.println("createControlPanel was called");
60 ClosableJFrame cf = new ClosableJFrame();
61 Container c = cf.getContentPane();
62 JPanel jp = new JPanel() {
63 public Dimension getPreferredSize() {
64 return new Dimension(100, 100);
65 }
66 };
67 jp.setLayout(new BoxLayout(jp, BoxLayout.PAGE_AXIS));
68 jp.add(new RunSlider() {
69 public void run() {
70 setDelay(this.getValue() * 10000);
71 }
72 });
73 jp.add(new RunSlider() {
74 public void run() {
75 setDelay(this.getValue() * 10000);
76 }
77 });
78 jp.add(new RunSlider() {
79 public void run() {
80 setDelay(this.getValue() * 10000);
81 }
82 });
83 jp.add(new RunSlider() {
84 public void run() {
85 setDelay(this.getValue() * 10000);
86 }
87 });
88 c.setLayout(new BorderLayout());
89 c.add(jp, BorderLayout.SOUTH);
90 c.add(osp, BorderLayout.CENTER);
91 cf.setSize(200, 200);
92 cf.setVisible(true);
93 }
94
95 private void shutDown(String message) {
96 if ((errStr = message) != null) {
97 System.err.println(errStr);
98 }
99 }
100
101 public static void printFormat(AudioFormat af) {
102 System.out.println("--------");
103 System.out.println(af);
104 }
105
106 public void run() {
107 AudioFormat format = getAudioFormat();
108
109 AudioInputStream playbackInputStream = AudioSystem.getAudioInputStream(format, ais);
110 DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
111 printFormat(format);
112 try {
113 line = (SourceDataLine) AudioSystem.getLine(info);
114 line.open(format, bufSize);
115 } catch (LineUnavailableException ex) {
116 shutDown("Unable to open the line: " + ex);
117 }
118 // play back the captured audio data
119
120 int frameSizeInBytes = format.getFrameSize();
121 int bufferLengthInFrames = line.getBufferSize() / 8;
122 int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
123 int numBytesRead = 0;
124
125 // start the source data line
126 line.start();
127 while (true) {
128 int n = (int) getDelay();
129 byte[] data = new byte[n];
130 try {
131 if ((numBytesRead = playbackInputStream.read(data)) == -1) {
132 // Thread.sleep(100);
133 }
134 int numBytesRemaining = numBytesRead;
135 processData(format, data, numBytesRemaining);
136 } catch (Exception e) {
137 shutDown("Error during playback: " + e);
138 break;
139 }
140 }
141 cleanUp();
142 }
143
144 private void processData(AudioFormat af, byte[] data, int numBytesRemaining) {
145 final double[] doubleData = Utils.getDoubleData(af,data);
146 osp.setData(doubleData);
147 Utils.echo(1,1,doubleData);
148 }
149
150 public static double[] getDoubleData(byte b[]) {
151 UlawCodec ulc = new UlawCodec(b);
152 return ulc.getDoubleArray();
153 }
154
155 private void cleanUp
156 () {
157 // we reached the end of the stream. let the data play out, then
158 // stop and close the line.
159
160 line.drain();
161 line.stop();
162 line.close();
163 line = null;
164 shutDown(null);
165 }
166
167 private AudioFormat getAudioFormat
168 () {
169 // make sure we have something to play
170 if (ais == null)
171 shutDown("No loaded audio to play back");
172
173 // get an AudioInputStream of the desired format for playback
174 AudioFormat format = formatControls.getFormat();
175 return format;
176 }
177 }
178
179