~gryle-devel/gryle/trunk-deleted

« back to all changes in this revision

Viewing changes to src/javazoom/jl/player/JavaSoundAudioDevice.java

  • Committer: Richard Leo Marsh Warburton
  • Date: 2007-01-13 22:08:02 UTC
  • mto: (1.1.6 gryle)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: rlmw@viglab-28-20070113220802-6cjjur0hdk1rce47
added src files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * 11/26/04             Buffer size modified to support JRE 1.5 optimizations.
 
3
 *              (CPU usage < 1% under P4/2Ghz, RAM < 12MB).
 
4
 *              jlayer@javazoom.net
 
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.
 
13
 *
 
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.
 
18
 *
 
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
 *----------------------------------------------------------------------
 
23
 */
 
24
 
 
25
package javazoom.jl.player;
 
26
 
 
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;
 
33
 
 
34
import javazoom.jl.decoder.Decoder;
 
35
import javazoom.jl.decoder.JavaLayerException;
 
36
 
 
37
/**
 
38
 * The <code>JavaSoundAudioDevice</code> implements an audio device by using
 
39
 * the JavaSound API.
 
40
 * 
 
41
 * @since 0.0.8
 
42
 * @author Mat McGowan
 
43
 */
 
44
public class JavaSoundAudioDevice extends AudioDeviceBase {
 
45
        private SourceDataLine source = null;
 
46
 
 
47
        private AudioFormat fmt = null;
 
48
 
 
49
        private byte[] byteBuf = new byte[4096];
 
50
 
 
51
        protected void setAudioFormat(AudioFormat fmt0) {
 
52
                fmt = fmt0;
 
53
        }
 
54
 
 
55
        protected AudioFormat getAudioFormat() {
 
56
                if (fmt == null) {
 
57
                        Decoder decoder = getDecoder();
 
58
                        fmt = new AudioFormat(decoder.getOutputFrequency(), 16, decoder
 
59
                                        .getOutputChannels(), true, false);
 
60
                }
 
61
                return fmt;
 
62
        }
 
63
 
 
64
        protected DataLine.Info getSourceLineInfo() {
 
65
                AudioFormat fmt = getAudioFormat();
 
66
                // DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt,
 
67
                // 4000);
 
68
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt);
 
69
                return info;
 
70
        }
 
71
 
 
72
        public void open(AudioFormat fmt) throws JavaLayerException {
 
73
                if (!isOpen()) {
 
74
                        setAudioFormat(fmt);
 
75
                        openImpl();
 
76
                        setOpen(true);
 
77
                }
 
78
        }
 
79
 
 
80
        protected void openImpl() throws JavaLayerException {
 
81
        }
 
82
 
 
83
        // createSource fix.
 
84
        protected void createSource() throws JavaLayerException {
 
85
                Throwable t = null;
 
86
                try {
 
87
                        Line line = AudioSystem.getLine(getSourceLineInfo());
 
88
                        if (line instanceof SourceDataLine) {
 
89
                                source = (SourceDataLine) line;
 
90
                                // source.open(fmt, millisecondsToBytes(fmt, 2000));
 
91
                                source.open(fmt);
 
92
                                /*
 
93
                                 * if (source.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
 
94
                                 * FloatControl c =
 
95
                                 * (FloatControl)source.getControl(FloatControl.Type.MASTER_GAIN);
 
96
                                 * c.setValue(c.getMaximum()); }
 
97
                                 */
 
98
                                source.start();
 
99
 
 
100
                        }
 
101
                } catch (RuntimeException ex) {
 
102
                        t = ex;
 
103
                } catch (LinkageError ex) {
 
104
                        t = ex;
 
105
                } catch (LineUnavailableException ex) {
 
106
                        t = ex;
 
107
                }
 
108
                if (source == null)
 
109
                        throw new JavaLayerException("cannot obtain source audio line", t);
 
110
        }
 
111
 
 
112
        public int millisecondsToBytes(AudioFormat fmt, int time) {
 
113
                return (int) (time
 
114
                                * (fmt.getSampleRate() * fmt.getChannels() * fmt
 
115
                                                .getSampleSizeInBits()) / 8000.0);
 
116
        }
 
117
 
 
118
        protected void closeImpl() {
 
119
                if (source != null) {
 
120
                        source.close();
 
121
                }
 
122
        }
 
123
 
 
124
        protected void writeImpl(short[] samples, int offs, int len)
 
125
                        throws JavaLayerException {
 
126
                if (source == null)
 
127
                        createSource();
 
128
 
 
129
                byte[] b = toByteArray(samples, offs, len);
 
130
                source.write(b, 0, len * 2);
 
131
        }
 
132
 
 
133
        protected byte[] getByteArray(int length) {
 
134
                if (byteBuf.length < length) {
 
135
                        byteBuf = new byte[length + 1024];
 
136
                }
 
137
                return byteBuf;
 
138
        }
 
139
 
 
140
        protected byte[] toByteArray(short[] samples, int offs, int len) {
 
141
                byte[] b = getByteArray(len * 2);
 
142
                int idx = 0;
 
143
                short s;
 
144
                while (len-- > 0) {
 
145
                        s = samples[offs++];
 
146
                        b[idx++] = (byte) s;
 
147
                        b[idx++] = (byte) (s >>> 8);
 
148
                }
 
149
                return b;
 
150
        }
 
151
 
 
152
        protected void flushImpl() {
 
153
                if (source != null) {
 
154
                        source.drain();
 
155
                }
 
156
        }
 
157
 
 
158
        public int getPosition() {
 
159
                int pos = 0;
 
160
                if (source != null) {
 
161
                        pos = (int) (source.getMicrosecondPosition() / 1000);
 
162
                }
 
163
                return pos;
 
164
        }
 
165
 
 
166
        /**
 
167
         * Runs a short test by playing a short silent sound.
 
168
         */
 
169
        public void test() throws JavaLayerException {
 
170
                try {
 
171
                        open(new AudioFormat(22050, 16, 1, true, false));
 
172
                        short[] data = new short[22050 / 10];
 
173
                        write(data, 0, data.length);
 
174
                        flush();
 
175
                        close();
 
176
                } catch (RuntimeException ex) {
 
177
                        throw new JavaLayerException("Device test failed: " + ex);
 
178
                }
 
179
 
 
180
        }
 
181
}