001: /**********************************************************************************
002: * $URL$
003: * $Id$
004: ***********************************************************************************
005: *
006: * Copyright (c) 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the"License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.tool.assessment.audio;
021:
022: import java.io.ByteArrayInputStream;
023: import java.io.ByteArrayOutputStream;
024: import java.io.File;
025: import java.io.IOException;
026: import java.text.AttributedCharacterIterator;
027: import java.text.AttributedString;
028: import java.util.Enumeration;
029: import java.util.Locale;
030: import java.util.ResourceBundle;
031: import java.util.Vector;
032: import javax.sound.sampled.AudioFileFormat;
033: import javax.sound.sampled.AudioFormat;
034: import javax.sound.sampled.AudioInputStream;
035: import javax.sound.sampled.AudioSystem;
036: import javax.sound.sampled.DataLine;
037: import javax.sound.sampled.LineUnavailableException;
038: import javax.sound.sampled.SourceDataLine;
039: import javax.sound.sampled.TargetDataLine;
040:
041: import java.awt.BasicStroke;
042: import java.awt.BorderLayout;
043: import java.awt.Color;
044: import java.awt.Dimension;
045: import java.awt.Font;
046: import java.awt.Graphics;
047: import java.awt.Graphics2D;
048: import java.awt.GridLayout;
049: import java.awt.Toolkit;
050: import java.awt.event.ActionEvent;
051: import java.awt.event.ActionListener;
052: import java.awt.event.WindowAdapter;
053: import java.awt.event.WindowEvent;
054: import java.awt.font.FontRenderContext;
055: import java.awt.font.LineBreakMeasurer;
056: import java.awt.font.TextAttribute;
057: import java.awt.font.TextLayout;
058: import java.awt.geom.Line2D;
059: import javax.swing.AbstractButton;
060: import javax.swing.BoxLayout;
061: import javax.swing.ButtonGroup;
062: import javax.swing.JButton;
063: import javax.swing.JFileChooser;
064: import javax.swing.JFrame;
065: import javax.swing.JLabel;
066: import javax.swing.JPanel;
067: import javax.swing.JTextField;
068: import javax.swing.JToggleButton;
069: import javax.swing.border.BevelBorder;
070: import javax.swing.border.CompoundBorder;
071: import javax.swing.border.EmptyBorder;
072: import javax.swing.border.SoftBevelBorder;
073: import javax.swing.filechooser.FileFilter;
074: import javax.swing.border.Border;
075:
076: public class AudioFormatPanel extends JPanel {
077: static ResourceBundle res = AudioUtil.getInstance()
078: .getResourceBundle();
079:
080: protected AudioRecorderParams params;
081: Vector groups = new Vector();
082: JToggleButton linrB, ulawB, alawB, rate8B, rate11B, rate16B,
083: rate22B, rate44B;
084: JToggleButton size8B, size16B, signB, unsignB, litB, bigB, monoB,
085: sterB;
086:
087: public AudioFormatPanel(AudioRecorderParams params) {
088: this .params = params;
089: setLayout(new GridLayout(0, 1));
090: EmptyBorder eb = new EmptyBorder(0, 0, 0, 5);
091: BevelBorder bb = new BevelBorder(BevelBorder.LOWERED);
092: CompoundBorder cb = new CompoundBorder(eb, bb);
093: setBorder(new CompoundBorder(cb, new EmptyBorder(8, 5, 5, 5)));
094: JPanel p1 = new ColorBackgroundPanel(false);
095:
096: ButtonGroup encodingGroup = makeEncodingGroup(params, p1);
097: add(p1);
098: groups.addElement(encodingGroup);
099:
100: JPanel p2 = new ColorBackgroundPanel(false);
101: JPanel p2b = new ColorBackgroundPanel(false);
102:
103: ButtonGroup sampleRateGroup = makeSampleRateGroup(params, p2,
104: p2b);
105: add(p2);
106: add(p2b);
107: groups.addElement(sampleRateGroup);
108:
109: JPanel p3 = new ColorBackgroundPanel(false);
110:
111: ButtonGroup sampleSizeInBitsGroup = makeSizeInBitsGroup(params,
112: p3);
113: add(p3);
114: groups.addElement(sampleSizeInBitsGroup);
115:
116: JPanel p4 = new ColorBackgroundPanel(false);
117:
118: ButtonGroup signGroup = makeSignGroup(params, p4);
119: add(p4);
120: groups.addElement(signGroup);
121:
122: JPanel p5 = new ColorBackgroundPanel(false);
123:
124: ButtonGroup endianGroup = makeEndianGroup(params, p5);
125: add(p5);
126: groups.addElement(endianGroup);
127:
128: JPanel p6 = new ColorBackgroundPanel(false);
129: ButtonGroup channelsGroup = makeChannelsGroup(params, p6);
130: add(p6);
131: groups.addElement(channelsGroup);
132: }
133:
134: private ButtonGroup makeEncodingGroup(AudioRecorderParams params,
135: JPanel p1) {
136: ButtonGroup encodingGroup = new ButtonGroup();
137:
138: boolean linear = false;
139: boolean ulaw = false;
140: boolean alaw = false;
141:
142: if ("linear".equals(params.getCompression())) {
143: linear = true;
144: } else if ("ulaw".equals(params.getCompression())) {
145: ulaw = true;
146: } else {
147: alaw = true;
148: }
149:
150: linrB = addToggleButton(p1, encodingGroup, res
151: .getString("linear"), linear);
152: ulawB = addToggleButton(p1, encodingGroup, res
153: .getString("ulaw"), ulaw);
154: alawB = addToggleButton(p1, encodingGroup, res
155: .getString("alaw"), alaw);
156: return encodingGroup;
157: }
158:
159: private ButtonGroup makeSampleRateGroup(AudioRecorderParams params,
160: JPanel p2, JPanel p2b) {
161: ButtonGroup sampleRateGroup = new ButtonGroup();
162:
163: boolean rates[] = { false, false, false, false, false, };
164:
165: int rate = params.getFrequency();
166:
167: for (int i = 0; i < params.frequenciesAllowed.length; i++) {
168: if (rate == params.frequenciesAllowed[i]) {
169: rates[i] = true;
170: break;
171: }
172:
173: }
174:
175: rate8B = addToggleButton(p2, sampleRateGroup, "8000", rates[0]);
176: rate11B = addToggleButton(p2, sampleRateGroup, "11025",
177: rates[1]);
178: rate16B = addToggleButton(p2b, sampleRateGroup, "16000",
179: rates[2]);
180: rate22B = addToggleButton(p2b, sampleRateGroup, "22050",
181: rates[3]);
182: rate44B = addToggleButton(p2b, sampleRateGroup, "44100",
183: rates[4]);
184: return sampleRateGroup;
185: }
186:
187: private ButtonGroup makeSizeInBitsGroup(AudioRecorderParams params,
188: JPanel p3) {
189: ButtonGroup sampleSizeInBitsGroup = new ButtonGroup();
190:
191: boolean bit8 = params.getBits() == 8 ? true : false;
192:
193: size8B = addToggleButton(p3, sampleSizeInBitsGroup, "8", bit8);
194: size16B = addToggleButton(p3, sampleSizeInBitsGroup, "16",
195: !bit8);
196: return sampleSizeInBitsGroup;
197: }
198:
199: private ButtonGroup makeSignGroup(AudioRecorderParams params,
200: JPanel p4) {
201: ButtonGroup signGroup = new ButtonGroup();
202:
203: signB = addToggleButton(p4, signGroup, res.getString("signed"),
204: params.isSigned());
205: unsignB = addToggleButton(p4, signGroup, res
206: .getString("unsigned"), !params.isSigned());
207: return signGroup;
208: }
209:
210: private ButtonGroup makeEndianGroup(AudioRecorderParams params,
211: JPanel p5) {
212: ButtonGroup endianGroup = new ButtonGroup();
213: litB = addToggleButton(p5, endianGroup, res
214: .getString("little_endian"), !params.isBigendian());
215: bigB = addToggleButton(p5, endianGroup, res
216: .getString("big_endian"), params.isBigendian());
217: return endianGroup;
218: }
219:
220: private ButtonGroup makeChannelsGroup(AudioRecorderParams params,
221: JPanel p6) {
222: ButtonGroup channelsGroup = new ButtonGroup();
223: monoB = addToggleButton(p6, channelsGroup, res
224: .getString("mono"), !params.isStereo());
225: sterB = addToggleButton(p6, channelsGroup, res
226: .getString("stereo"), params.isStereo());
227: return channelsGroup;
228: }
229:
230: private JToggleButton addToggleButton(JPanel p, ButtonGroup g,
231: String name, boolean state) {
232: JToggleButton b = new JToggleButton(name, state);
233: p.add(b);
234: g.add(b);
235: return b;
236: }
237:
238: public AudioFormat getFormat() {
239:
240: Vector v = new Vector(groups.size());
241: for (int i = 0; i < groups.size(); i++) {
242: ButtonGroup g = (ButtonGroup) groups.get(i);
243: for (Enumeration e = g.getElements(); e.hasMoreElements();) {
244: AbstractButton b = (AbstractButton) e.nextElement();
245: if (b.isSelected()) {
246: v.add(b.getText());
247: break;
248: }
249: }
250: }
251:
252: AudioFormat.Encoding encoding = AudioFormat.Encoding.ULAW;
253: String encString = (String) v.get(0);
254: float rate = Float.valueOf((String) v.get(1)).floatValue();
255: int sampleSize = Integer.valueOf((String) v.get(2)).intValue();
256: String signedString = (String) v.get(3);
257: boolean bigEndian = ((String) v.get(4)).startsWith(res
258: .getString("big"));
259: int channels = ((String) v.get(5))
260: .equals(res.getString("mono")) ? 1 : 2;
261:
262: if (encString.equals(res.getString("linear"))) {
263: if (signedString.equals(res.getString("signed"))) {
264: encoding = AudioFormat.Encoding.PCM_SIGNED;
265: } else {
266: encoding = AudioFormat.Encoding.PCM_UNSIGNED;
267: }
268: } else if (encString.equals(res.getString("alaw"))) {
269: encoding = AudioFormat.Encoding.ALAW;
270: }
271: return new AudioFormat(encoding, rate, sampleSize, channels,
272: (sampleSize / 8) * channels, rate, bigEndian);
273: }
274:
275: public void setFormat(AudioFormat format) {
276: AudioFormat.Encoding type = format.getEncoding();
277: if (type == AudioFormat.Encoding.ULAW) {
278: ulawB.doClick();
279: } else if (type == AudioFormat.Encoding.ALAW) {
280: alawB.doClick();
281: } else if (type == AudioFormat.Encoding.PCM_SIGNED) {
282: linrB.doClick();
283: signB.doClick();
284: } else if (type == AudioFormat.Encoding.PCM_UNSIGNED) {
285: linrB.doClick();
286: unsignB.doClick();
287: }
288: float rate = format.getFrameRate();
289: if (rate == 8000) {
290: rate8B.doClick();
291: } else if (rate == 11025) {
292: rate11B.doClick();
293: } else if (rate == 16000) {
294: rate16B.doClick();
295: } else if (rate == 22050) {
296: rate22B.doClick();
297: } else if (rate == 44100) {
298: rate44B.doClick();
299: }
300: switch (format.getSampleSizeInBits()) {
301: case 8:
302: size8B.doClick();
303: break;
304: case 16:
305: size16B.doClick();
306: break;
307: }
308: if (format.isBigEndian()) {
309: bigB.doClick();
310: } else {
311: litB.doClick();
312: }
313: if (format.getChannels() == 1) {
314: monoB.doClick();
315: } else {
316: sterB.doClick();
317: }
318: }
319:
320: }
|