2
* 11/26/04 Buffer size modified to support JRE 1.5 optimizations.
3
* (CPU usage < 1% under P4/2Ghz, RAM < 12MB).
5
* 11/19/04 1.0 moved to LGPL.
6
* 06/04/01 Too fast playback fixed. mdm@techie.com
7
* 29/01/00 Initial version. mdm@techie.com
8
*-----------------------------------------------------------------------
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU Library General Public License as published
11
* by the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU Library General Public License for more details.
19
* You should have received a copy of the GNU Library General Public
20
* License along with this program; if not, write to the Free Software
21
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
*----------------------------------------------------------------------
25
package javazoom.jl.player;
27
import javax.sound.sampled.AudioFormat;
28
import javax.sound.sampled.AudioSystem;
29
import javax.sound.sampled.DataLine;
30
import javax.sound.sampled.Line;
31
import javax.sound.sampled.LineUnavailableException;
32
import javax.sound.sampled.SourceDataLine;
34
import javazoom.jl.decoder.Decoder;
35
import javazoom.jl.decoder.JavaLayerException;
38
* The <code>JavaSoundAudioDevice</code> implements an audio device by using
44
public class JavaSoundAudioDevice extends AudioDeviceBase {
45
private SourceDataLine source = null;
47
private AudioFormat fmt = null;
49
private byte[] byteBuf = new byte[4096];
51
protected void setAudioFormat(AudioFormat fmt0) {
55
protected AudioFormat getAudioFormat() {
57
Decoder decoder = getDecoder();
58
fmt = new AudioFormat(decoder.getOutputFrequency(), 16, decoder
59
.getOutputChannels(), true, false);
64
protected DataLine.Info getSourceLineInfo() {
65
AudioFormat fmt = getAudioFormat();
66
// DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt,
68
DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt);
72
public void open(AudioFormat fmt) throws JavaLayerException {
80
protected void openImpl() throws JavaLayerException {
84
protected void createSource() throws JavaLayerException {
87
Line line = AudioSystem.getLine(getSourceLineInfo());
88
if (line instanceof SourceDataLine) {
89
source = (SourceDataLine) line;
90
// source.open(fmt, millisecondsToBytes(fmt, 2000));
93
* if (source.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
95
* (FloatControl)source.getControl(FloatControl.Type.MASTER_GAIN);
96
* c.setValue(c.getMaximum()); }
101
} catch (RuntimeException ex) {
103
} catch (LinkageError ex) {
105
} catch (LineUnavailableException ex) {
109
throw new JavaLayerException("cannot obtain source audio line", t);
112
public int millisecondsToBytes(AudioFormat fmt, int time) {
114
* (fmt.getSampleRate() * fmt.getChannels() * fmt
115
.getSampleSizeInBits()) / 8000.0);
118
protected void closeImpl() {
119
if (source != null) {
124
protected void writeImpl(short[] samples, int offs, int len)
125
throws JavaLayerException {
129
byte[] b = toByteArray(samples, offs, len);
130
source.write(b, 0, len * 2);
133
protected byte[] getByteArray(int length) {
134
if (byteBuf.length < length) {
135
byteBuf = new byte[length + 1024];
140
protected byte[] toByteArray(short[] samples, int offs, int len) {
141
byte[] b = getByteArray(len * 2);
147
b[idx++] = (byte) (s >>> 8);
152
protected void flushImpl() {
153
if (source != null) {
158
public int getPosition() {
160
if (source != null) {
161
pos = (int) (source.getMicrosecondPosition() / 1000);
167
* Runs a short test by playing a short silent sound.
169
public void test() throws JavaLayerException {
171
open(new AudioFormat(22050, 16, 1, true, false));
172
short[] data = new short[22050 / 10];
173
write(data, 0, data.length);
176
} catch (RuntimeException ex) {
177
throw new JavaLayerException("Device test failed: " + ex);