diff options
author | Björn Stenberg <bjorn@haxx.se> | 2007-01-08 23:53:00 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2007-01-08 23:53:00 +0000 |
commit | 7039a05147b8bbfc829babea1c65bd436450b505 (patch) | |
tree | 4ba555eb84ed97b72b0575034d5b0530a393713e /songdbj/org/tritonus/share/sampled/convert | |
parent | 6d4c19707ef95942e323cbdc89fbbfdbe45e7cc5 (diff) | |
download | rockbox-7039a05147b8bbfc829babea1c65bd436450b505.tar.gz rockbox-7039a05147b8bbfc829babea1c65bd436450b505.zip |
Splitting out songdbj
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11953 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'songdbj/org/tritonus/share/sampled/convert')
8 files changed, 0 insertions, 1512 deletions
diff --git a/songdbj/org/tritonus/share/sampled/convert/TAsynchronousFilteredAudioInputStream.java b/songdbj/org/tritonus/share/sampled/convert/TAsynchronousFilteredAudioInputStream.java deleted file mode 100644 index 83349439eb..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TAsynchronousFilteredAudioInputStream.java +++ /dev/null | |||
@@ -1,256 +0,0 @@ | |||
1 | /* | ||
2 | * TAsynchronousFilteredAudioInputStream.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 1999, 2000 by Matthias Pfisterer | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU Library General Public License as published | ||
13 | * by the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU Library General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Library General Public | ||
22 | * License along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | |<--- this code is formatted to fit into 80 columns --->| | ||
29 | */ | ||
30 | |||
31 | package org.tritonus.share.sampled.convert; | ||
32 | |||
33 | import java.io.ByteArrayInputStream; | ||
34 | import java.io.IOException; | ||
35 | |||
36 | import javax.sound.sampled.AudioFormat; | ||
37 | import javax.sound.sampled.AudioInputStream; | ||
38 | |||
39 | import org.tritonus.share.TDebug; | ||
40 | import org.tritonus.share.TCircularBuffer; | ||
41 | |||
42 | |||
43 | |||
44 | /** Base class for asynchronus converters. | ||
45 | This class serves as base class for | ||
46 | converters that do not have a fixed | ||
47 | ratio between the size of a block of input | ||
48 | data and the size of a block of output data. | ||
49 | These types of converters therefore need an | ||
50 | internal buffer, which is realized in this | ||
51 | class. | ||
52 | |||
53 | @author Matthias Pfisterer | ||
54 | */ | ||
55 | public abstract class TAsynchronousFilteredAudioInputStream | ||
56 | extends TAudioInputStream | ||
57 | implements TCircularBuffer.Trigger | ||
58 | { | ||
59 | private static final int DEFAULT_BUFFER_SIZE = 327670; | ||
60 | private static final int DEFAULT_MIN_AVAILABLE = 4096; | ||
61 | private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; | ||
62 | |||
63 | |||
64 | private TCircularBuffer m_circularBuffer; | ||
65 | private int m_nMinAvailable; | ||
66 | private byte[] m_abSingleByte; | ||
67 | |||
68 | |||
69 | |||
70 | /** Constructor. | ||
71 | This constructor uses the default buffer size and the default | ||
72 | min available amount. | ||
73 | |||
74 | @param lLength length of this stream in frames. May be | ||
75 | AudioSystem.NOT_SPECIFIED. | ||
76 | */ | ||
77 | public TAsynchronousFilteredAudioInputStream(AudioFormat outputFormat, long lLength) | ||
78 | { | ||
79 | this(outputFormat, lLength, | ||
80 | DEFAULT_BUFFER_SIZE, | ||
81 | DEFAULT_MIN_AVAILABLE); | ||
82 | } | ||
83 | |||
84 | |||
85 | |||
86 | /** Constructor. | ||
87 | With this constructor, the buffer size and the minimum | ||
88 | available amount can be specified as parameters. | ||
89 | |||
90 | @param lLength length of this stream in frames. May be | ||
91 | AudioSystem.NOT_SPECIFIED. | ||
92 | |||
93 | @param nBufferSize size of the circular buffer in bytes. | ||
94 | */ | ||
95 | public TAsynchronousFilteredAudioInputStream( | ||
96 | AudioFormat outputFormat, long lLength, | ||
97 | int nBufferSize, | ||
98 | int nMinAvailable) | ||
99 | { | ||
100 | /* The usage of a ByteArrayInputStream is a hack. | ||
101 | * (the infamous "JavaOne hack", because I did it on June | ||
102 | * 6th 2000 in San Francisco, only hours before a | ||
103 | * JavaOne session where I wanted to show mp3 playback | ||
104 | * with Java Sound.) It is necessary because in the FCS | ||
105 | * version of the Sun jdk1.3, the constructor of | ||
106 | * AudioInputStream throws an exception if its first | ||
107 | * argument is null. So we have to pass a dummy non-null | ||
108 | * value. | ||
109 | */ | ||
110 | super(new ByteArrayInputStream(EMPTY_BYTE_ARRAY), | ||
111 | outputFormat, | ||
112 | lLength); | ||
113 | if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.<init>(): begin"); } | ||
114 | m_circularBuffer = new TCircularBuffer( | ||
115 | nBufferSize, | ||
116 | false, // blocking read | ||
117 | true, // blocking write | ||
118 | this); // trigger | ||
119 | m_nMinAvailable = nMinAvailable; | ||
120 | if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.<init>(): end"); } | ||
121 | } | ||
122 | |||
123 | |||
124 | /** Returns the circular buffer. | ||
125 | */ | ||
126 | protected TCircularBuffer getCircularBuffer() | ||
127 | { | ||
128 | return m_circularBuffer; | ||
129 | } | ||
130 | |||
131 | |||
132 | |||
133 | /** Check if writing more data to the circular buffer is recommanded. | ||
134 | This checks the available write space in the circular buffer | ||
135 | against the minimum available property. If the available write | ||
136 | space is greater than th minimum available property, more | ||
137 | writing is encouraged, so this method returns true. | ||
138 | Note that this is only a hint to subclasses. However, | ||
139 | it is an important hint. | ||
140 | |||
141 | @return true if more writing to the circular buffer is | ||
142 | recommanden. Otherwise, false is returned. | ||
143 | */ | ||
144 | protected boolean writeMore() | ||
145 | { | ||
146 | return getCircularBuffer().availableWrite() > m_nMinAvailable; | ||
147 | } | ||
148 | |||
149 | |||
150 | |||
151 | public int read() | ||
152 | throws IOException | ||
153 | { | ||
154 | // if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.read(): begin"); } | ||
155 | int nByte = -1; | ||
156 | if (m_abSingleByte == null) | ||
157 | { | ||
158 | m_abSingleByte = new byte[1]; | ||
159 | } | ||
160 | int nReturn = read(m_abSingleByte); | ||
161 | if (nReturn == -1) | ||
162 | { | ||
163 | nByte = -1; | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | //$$fb 2001-04-14 nobody really knows that... | ||
168 | nByte = m_abSingleByte[0] & 0xFF; | ||
169 | } | ||
170 | // if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.read(): end"); } | ||
171 | return nByte; | ||
172 | } | ||
173 | |||
174 | |||
175 | |||
176 | public int read(byte[] abData) | ||
177 | throws IOException | ||
178 | { | ||
179 | if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.read(byte[]): begin"); } | ||
180 | int nRead = read(abData, 0, abData.length); | ||
181 | if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.read(byte[]): end"); } | ||
182 | return nRead; | ||
183 | } | ||
184 | |||
185 | |||
186 | |||
187 | public int read(byte[] abData, int nOffset, int nLength) | ||
188 | throws IOException | ||
189 | { | ||
190 | if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.read(byte[], int, int): begin"); } | ||
191 | //$$fb 2001-04-22: this returns at maximum circular buffer | ||
192 | // length. This is not very efficient... | ||
193 | //$$fb 2001-04-25: we should check that we do not exceed getFrameLength() ! | ||
194 | int nRead = m_circularBuffer.read(abData, nOffset, nLength); | ||
195 | if (TDebug.TraceAudioConverter) { TDebug.out("TAsynchronousFilteredAudioInputStream.read(byte[], int, int): end"); } | ||
196 | return nRead; | ||
197 | } | ||
198 | |||
199 | |||
200 | |||
201 | public long skip(long lSkip) | ||
202 | throws IOException | ||
203 | { | ||
204 | // TODO: this is quite inefficient | ||
205 | for (long lSkipped = 0; lSkipped < lSkip; lSkipped++) | ||
206 | { | ||
207 | int nReturn = read(); | ||
208 | if (nReturn == -1) | ||
209 | { | ||
210 | return lSkipped; | ||
211 | } | ||
212 | } | ||
213 | return lSkip; | ||
214 | } | ||
215 | |||
216 | |||
217 | |||
218 | public int available() | ||
219 | throws IOException | ||
220 | { | ||
221 | return m_circularBuffer.availableRead(); | ||
222 | } | ||
223 | |||
224 | |||
225 | |||
226 | public void close() | ||
227 | throws IOException | ||
228 | { | ||
229 | m_circularBuffer.close(); | ||
230 | } | ||
231 | |||
232 | |||
233 | |||
234 | public boolean markSupported() | ||
235 | { | ||
236 | return false; | ||
237 | } | ||
238 | |||
239 | |||
240 | |||
241 | public void mark(int nReadLimit) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | |||
246 | |||
247 | public void reset() | ||
248 | throws IOException | ||
249 | { | ||
250 | throw new IOException("mark not supported"); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | |||
255 | |||
256 | /*** TAsynchronousFilteredAudioInputStream.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/TAudioInputStream.java b/songdbj/org/tritonus/share/sampled/convert/TAudioInputStream.java deleted file mode 100644 index d84530e115..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TAudioInputStream.java +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * TAudioInputStream.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2003 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | |<--- this code is formatted to fit into 80 columns --->| | ||
27 | */ | ||
28 | |||
29 | package org.tritonus.share.sampled.convert; | ||
30 | |||
31 | import java.io.InputStream; | ||
32 | |||
33 | import java.util.Collections; | ||
34 | import java.util.HashMap; | ||
35 | import java.util.Map; | ||
36 | |||
37 | import javax.sound.sampled.AudioFormat; | ||
38 | import javax.sound.sampled.AudioInputStream; | ||
39 | |||
40 | |||
41 | /** AudioInputStream base class. This class implements "dynamic" | ||
42 | properties. "Dynamic" properties are properties that may change | ||
43 | during the life time of the objects. This is typically used to | ||
44 | pass information like the current frame number, volume of subbands | ||
45 | and similar values. "Dynamic" properties are different from | ||
46 | properties in AudioFormat and AudioFileFormat, which are | ||
47 | considered "static", as they aren't allowed to change after | ||
48 | creating of the object, thereby maintaining the immutable | ||
49 | character of these classes. | ||
50 | */ | ||
51 | |||
52 | public class TAudioInputStream | ||
53 | extends AudioInputStream | ||
54 | { | ||
55 | private Map<String, Object> m_properties; | ||
56 | private Map<String, Object> m_unmodifiableProperties; | ||
57 | |||
58 | |||
59 | /** Constructor without properties. | ||
60 | Creates an empty properties map. | ||
61 | */ | ||
62 | public TAudioInputStream(InputStream inputStream, | ||
63 | AudioFormat audioFormat, | ||
64 | long lLengthInFrames) | ||
65 | { | ||
66 | super(inputStream, audioFormat, lLengthInFrames); | ||
67 | initMaps(new HashMap<String, Object>()); | ||
68 | } | ||
69 | |||
70 | |||
71 | /** Constructor with properties. | ||
72 | The passed properties map is not copied. This allows subclasses | ||
73 | to change values in the map after creation, and the changes are | ||
74 | reflected in the map the application program can obtain. | ||
75 | */ | ||
76 | public TAudioInputStream(InputStream inputStream, | ||
77 | AudioFormat audioFormat, | ||
78 | long lLengthInFrames, | ||
79 | Map<String, Object> properties) | ||
80 | { | ||
81 | super(inputStream, audioFormat, lLengthInFrames); | ||
82 | initMaps(properties); | ||
83 | } | ||
84 | |||
85 | |||
86 | private void initMaps(Map<String, Object> properties) | ||
87 | { | ||
88 | /* Here, we make a shallow copy of the map. It's unclear if this | ||
89 | is sufficient (of if a deep copy should be made). | ||
90 | */ | ||
91 | m_properties = properties; | ||
92 | m_unmodifiableProperties = Collections.unmodifiableMap(m_properties); | ||
93 | } | ||
94 | |||
95 | |||
96 | /** Obtain a Map containing the properties. This method returns a | ||
97 | Map that cannot be modified by the application program, but | ||
98 | reflects changes to the map made by the implementation. | ||
99 | |||
100 | @return a map containing the properties. | ||
101 | */ | ||
102 | public Map<String, Object> properties() | ||
103 | { | ||
104 | return m_unmodifiableProperties; | ||
105 | } | ||
106 | |||
107 | |||
108 | /** Set a property. Unlike in AudioFormat and AudioFileFormat, | ||
109 | this method may be used anywhere by subclasses - it is not | ||
110 | restricted to be used in the constructor. | ||
111 | */ | ||
112 | protected void setProperty(String key, Object value) | ||
113 | { | ||
114 | m_properties.put(key, value); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | |||
119 | |||
120 | /*** TAudioInputStream.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/TEncodingFormatConversionProvider.java b/songdbj/org/tritonus/share/sampled/convert/TEncodingFormatConversionProvider.java deleted file mode 100644 index 6b83403c43..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TEncodingFormatConversionProvider.java +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
1 | /* | ||
2 | * TEncodingFormatConversionProvider.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 by Florian Bomers <http://www.bomers.de> | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU Library General Public License as published | ||
13 | * by the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU Library General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Library General Public | ||
22 | * License along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | |<--- this code is formatted to fit into 80 columns --->| | ||
29 | */ | ||
30 | |||
31 | package org.tritonus.share.sampled.convert; | ||
32 | |||
33 | import java.util.Collection; | ||
34 | import java.util.Iterator; | ||
35 | |||
36 | import javax.sound.sampled.AudioFormat; | ||
37 | import javax.sound.sampled.AudioSystem; | ||
38 | |||
39 | import org.tritonus.share.TDebug; | ||
40 | import org.tritonus.share.ArraySet; | ||
41 | |||
42 | |||
43 | // this class depends on handling of AudioSystem.NOT_SPECIFIED in AudioFormat.matches() | ||
44 | |||
45 | /** | ||
46 | * This is a base class for FormatConversionProviders that only | ||
47 | * change the encoding, i.e. they never | ||
48 | * <ul> | ||
49 | * <li> change the sample size in bits without changing the encoding | ||
50 | * <li> change the sample rate | ||
51 | * <li> change the number of channels | ||
52 | * </ul> | ||
53 | * <p>It is assumed that each source format can be encoded to all | ||
54 | * target formats. | ||
55 | * <p>In the sourceFormats and targetFormats collections that are passed to | ||
56 | * the constructor of this class, fields may be set to AudioSystem.NOT_SPECIFIED. | ||
57 | * This means that it handles all values of that field, but cannot change it. | ||
58 | * <p>This class prevents that a conversion is done (e.g. for sample rates), | ||
59 | * because the overriding class specified AudioSystem.NOT_SPECIFIED as sample rate, | ||
60 | * meaning it handles all sample rates. | ||
61 | * <p>Overriding classes must implement at least | ||
62 | * <code>AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream)</code> | ||
63 | * and provide a constructor that calls the protected constructor of this class. | ||
64 | * | ||
65 | * @author Florian Bomers | ||
66 | */ | ||
67 | public abstract class TEncodingFormatConversionProvider | ||
68 | extends TSimpleFormatConversionProvider | ||
69 | { | ||
70 | protected TEncodingFormatConversionProvider( | ||
71 | Collection<AudioFormat> sourceFormats, | ||
72 | Collection<AudioFormat> targetFormats) | ||
73 | { | ||
74 | super(sourceFormats, targetFormats); | ||
75 | } | ||
76 | |||
77 | |||
78 | |||
79 | /** | ||
80 | * This implementation assumes that the converter can convert | ||
81 | * from each of its source formats to each of its target | ||
82 | * formats. If this is not the case, the converter has to | ||
83 | * override this method. | ||
84 | * <p>When conversion is supported, for every target encoding, | ||
85 | * the fields sample size in bits, channels and sample rate are checked: | ||
86 | * <ul> | ||
87 | * <li>When a field in both the source and target format is AudioSystem.NOT_SPECIFIED, | ||
88 | * one instance of that targetFormat is returned with this field set to AudioSystem.NOT_SPECIFIED. | ||
89 | * <li>When a field in sourceFormat is set and it is AudioSystem.NOT_SPECIFIED in the target format, | ||
90 | * the value of the field of source format is set in the returned format. | ||
91 | * <li>The same applies for the other way round. | ||
92 | * </ul> | ||
93 | * For this, <code>replaceNotSpecified(sourceFormat, targetFormat)</code> in the base | ||
94 | * class TSimpleFormatConversionProvider is used - and accordingly, the frameSize | ||
95 | * is recalculated with <code>getFrameSize(...)</code> if a field with AudioSystem.NOT_SPECIFIED | ||
96 | * is replaced. Inheriting classes may wish to override this method if the | ||
97 | * default mode of calculating the frame size is not appropriate. | ||
98 | */ | ||
99 | public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) { | ||
100 | if (TDebug.TraceAudioConverter) { | ||
101 | TDebug.out(">TEncodingFormatConversionProvider.getTargetFormats(AudioFormat.Encoding, AudioFormat):"); | ||
102 | TDebug.out("checking if conversion possible"); | ||
103 | TDebug.out("from: " + sourceFormat); | ||
104 | TDebug.out("to: " + targetEncoding); | ||
105 | } | ||
106 | if (isConversionSupported(targetEncoding, sourceFormat)) { | ||
107 | // TODO: check that no duplicates may occur... | ||
108 | ArraySet<AudioFormat> result=new ArraySet<AudioFormat>(); | ||
109 | Iterator<AudioFormat> iterator = getCollectionTargetFormats().iterator(); | ||
110 | while (iterator.hasNext()) { | ||
111 | AudioFormat targetFormat = iterator.next(); | ||
112 | targetFormat=replaceNotSpecified(sourceFormat, targetFormat); | ||
113 | result.add(targetFormat); | ||
114 | } | ||
115 | if (TDebug.TraceAudioConverter) { | ||
116 | TDebug.out("< returning "+result.size()+" elements."); | ||
117 | } | ||
118 | return result.toArray(EMPTY_FORMAT_ARRAY); | ||
119 | } else { | ||
120 | if (TDebug.TraceAudioConverter) { | ||
121 | TDebug.out("< returning empty array."); | ||
122 | } | ||
123 | return EMPTY_FORMAT_ARRAY; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | } | ||
128 | |||
129 | /*** TEncodingFormatConversionProvider.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/TFormatConversionProvider.java b/songdbj/org/tritonus/share/sampled/convert/TFormatConversionProvider.java deleted file mode 100644 index eaec65bb06..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TFormatConversionProvider.java +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | /* | ||
2 | * TFormatConversionProvider.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 1999, 2000 by Matthias Pfisterer | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU Library General Public License as published | ||
13 | * by the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU Library General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Library General Public | ||
22 | * License along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | |<--- this code is formatted to fit into 80 columns --->| | ||
29 | */ | ||
30 | |||
31 | package org.tritonus.share.sampled.convert; | ||
32 | |||
33 | import javax.sound.sampled.AudioSystem; | ||
34 | import javax.sound.sampled.AudioFormat; | ||
35 | import javax.sound.sampled.AudioInputStream; | ||
36 | import javax.sound.sampled.spi.FormatConversionProvider; | ||
37 | |||
38 | import org.tritonus.share.TDebug; | ||
39 | import org.tritonus.share.sampled.AudioFormats; | ||
40 | |||
41 | |||
42 | |||
43 | /** Base class for all conversion providers of Tritonus. | ||
44 | * | ||
45 | * @author Matthias Pfisterer | ||
46 | */ | ||
47 | public abstract class TFormatConversionProvider | ||
48 | extends FormatConversionProvider | ||
49 | { | ||
50 | protected static final AudioFormat.Encoding[] EMPTY_ENCODING_ARRAY = new AudioFormat.Encoding[0]; | ||
51 | protected static final AudioFormat[] EMPTY_FORMAT_ARRAY = new AudioFormat[0]; | ||
52 | |||
53 | |||
54 | |||
55 | // $$fb2000-10-04: use AudioSystem.NOT_SPECIFIED for all fields. | ||
56 | public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream audioInputStream) | ||
57 | { | ||
58 | AudioFormat sourceFormat = audioInputStream.getFormat(); | ||
59 | AudioFormat targetFormat = new AudioFormat( | ||
60 | targetEncoding, | ||
61 | AudioSystem.NOT_SPECIFIED, // sample rate | ||
62 | AudioSystem.NOT_SPECIFIED, // sample size in bits | ||
63 | AudioSystem.NOT_SPECIFIED, // channels | ||
64 | AudioSystem.NOT_SPECIFIED, // frame size | ||
65 | AudioSystem.NOT_SPECIFIED, // frame rate | ||
66 | sourceFormat.isBigEndian()); // big endian | ||
67 | if (TDebug.TraceAudioConverter) | ||
68 | { | ||
69 | TDebug.out("TFormatConversionProvider.getAudioInputStream(AudioFormat.Encoding, AudioInputStream):"); | ||
70 | TDebug.out("trying to convert to " + targetFormat); | ||
71 | } | ||
72 | return getAudioInputStream(targetFormat, audioInputStream); | ||
73 | } | ||
74 | |||
75 | |||
76 | |||
77 | /** | ||
78 | * WARNING: this method uses <code>getTargetFormats(AudioFormat.Encoding, AudioFormat)</code> | ||
79 | * which may create infinite loops if the latter is overwritten. | ||
80 | * <p> | ||
81 | * This method is overwritten here to make use of org.tritonus.share.sampled.AudioFormats.matches | ||
82 | * and is considered temporary until AudioFormat.matches is corrected in the JavaSound API. | ||
83 | */ | ||
84 | /* $$mp: if we decide to use getMatchingFormat(), this method should be | ||
85 | implemented by simply calling getMatchingFormat() and comparing the | ||
86 | result against null. | ||
87 | */ | ||
88 | public boolean isConversionSupported( | ||
89 | AudioFormat targetFormat, | ||
90 | AudioFormat sourceFormat) | ||
91 | { | ||
92 | if (TDebug.TraceAudioConverter) | ||
93 | { | ||
94 | TDebug.out(">TFormatConversionProvider.isConversionSupported(AudioFormat, AudioFormat):"); | ||
95 | TDebug.out("class: "+getClass().getName()); | ||
96 | TDebug.out("checking if conversion possible"); | ||
97 | TDebug.out("from: " + sourceFormat); | ||
98 | TDebug.out("to: " + targetFormat); | ||
99 | } | ||
100 | AudioFormat[] aTargetFormats = getTargetFormats(targetFormat.getEncoding(), sourceFormat); | ||
101 | for (int i = 0; i < aTargetFormats.length; i++) | ||
102 | { | ||
103 | if (TDebug.TraceAudioConverter) | ||
104 | { | ||
105 | TDebug.out("checking against possible target format: " + aTargetFormats[i]); | ||
106 | } | ||
107 | if (aTargetFormats[i] != null | ||
108 | && AudioFormats.matches(aTargetFormats[i], targetFormat)) | ||
109 | { | ||
110 | if (TDebug.TraceAudioConverter) | ||
111 | { | ||
112 | TDebug.out("<result=true"); | ||
113 | } | ||
114 | return true; | ||
115 | } | ||
116 | } | ||
117 | if (TDebug.TraceAudioConverter) { | ||
118 | TDebug.out("<result=false"); | ||
119 | } | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | |||
124 | /** | ||
125 | * WARNING: this method uses <code>getTargetFormats(AudioFormat.Encoding, AudioFormat)</code> | ||
126 | * which may create infinite loops if the latter is overwritten. | ||
127 | * <p> | ||
128 | * This method is overwritten here to make use of org.tritonus.share.sampled.AudioFormats.matches | ||
129 | * and is considered temporary until AudioFormat.matches is corrected in the JavaSound API. | ||
130 | */ | ||
131 | public AudioFormat getMatchingFormat( | ||
132 | AudioFormat targetFormat, | ||
133 | AudioFormat sourceFormat) | ||
134 | { | ||
135 | if (TDebug.TraceAudioConverter) | ||
136 | { | ||
137 | TDebug.out(">TFormatConversionProvider.isConversionSupported(AudioFormat, AudioFormat):"); | ||
138 | TDebug.out("class: "+getClass().getName()); | ||
139 | TDebug.out("checking if conversion possible"); | ||
140 | TDebug.out("from: " + sourceFormat); | ||
141 | TDebug.out("to: " + targetFormat); | ||
142 | } | ||
143 | AudioFormat[] aTargetFormats = getTargetFormats(targetFormat.getEncoding(), sourceFormat); | ||
144 | for (int i = 0; i < aTargetFormats.length; i++) | ||
145 | { | ||
146 | if (TDebug.TraceAudioConverter) | ||
147 | { | ||
148 | TDebug.out("checking against possible target format: " + aTargetFormats[i]); | ||
149 | } | ||
150 | if (aTargetFormats[i] != null | ||
151 | && AudioFormats.matches(aTargetFormats[i], targetFormat)) | ||
152 | { | ||
153 | if (TDebug.TraceAudioConverter) | ||
154 | { | ||
155 | TDebug.out("<result=true"); | ||
156 | } | ||
157 | return aTargetFormats[i]; | ||
158 | } | ||
159 | } | ||
160 | if (TDebug.TraceAudioConverter) { | ||
161 | TDebug.out("<result=false"); | ||
162 | } | ||
163 | return null; | ||
164 | } | ||
165 | |||
166 | } | ||
167 | |||
168 | |||
169 | |||
170 | /*** TFormatConversionProvider.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/TMatrixFormatConversionProvider.java b/songdbj/org/tritonus/share/sampled/convert/TMatrixFormatConversionProvider.java deleted file mode 100644 index 05dca90309..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TMatrixFormatConversionProvider.java +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | /* | ||
2 | * TMatrixFormatConversionProvider.java | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * Copyright (c) 1999, 2000 by Matthias Pfisterer <Matthias.Pfisterer@gmx.de> | ||
7 | * | ||
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 | |||
26 | package org.tritonus.share.sampled.convert; | ||
27 | |||
28 | |||
29 | import java.util.Collection; | ||
30 | import java.util.List; | ||
31 | import java.util.Map; | ||
32 | import java.util.Set; | ||
33 | import java.util.HashMap; | ||
34 | import java.util.ArrayList; | ||
35 | import java.util.Iterator; | ||
36 | |||
37 | import javax.sound.sampled.AudioFormat; | ||
38 | import javax.sound.sampled.AudioInputStream; | ||
39 | import javax.sound.sampled.spi.FormatConversionProvider; | ||
40 | |||
41 | import org.tritonus.share.sampled.AudioFormats; | ||
42 | import org.tritonus.share.ArraySet; | ||
43 | |||
44 | /** | ||
45 | * Base class for arbitrary formatConversionProviders. | ||
46 | * | ||
47 | * @author Matthias Pfisterer | ||
48 | */ | ||
49 | |||
50 | |||
51 | public abstract class TMatrixFormatConversionProvider | ||
52 | extends TSimpleFormatConversionProvider | ||
53 | { | ||
54 | /* | ||
55 | * keys: source AudioFormat | ||
56 | * values: collection of possible target encodings | ||
57 | * | ||
58 | * Note that accessing values with get() is not appropriate, | ||
59 | * since the equals() method in AudioFormat is not overloaded. | ||
60 | * The hashtable is just used as a convenient storage | ||
61 | * organization. | ||
62 | */ | ||
63 | private Map m_targetEncodingsFromSourceFormat; | ||
64 | |||
65 | |||
66 | /* | ||
67 | * keys: source AudioFormat | ||
68 | * values: a Map that contains a mapping from target encodings | ||
69 | * (keys) to a collection of target formats (values). | ||
70 | * | ||
71 | * Note that accessing values with get() is not appropriate, | ||
72 | * since the equals() method in AudioFormat is not overloaded. | ||
73 | * The hashtable is just used as a convenient storage | ||
74 | * organization. | ||
75 | */ | ||
76 | private Map m_targetFormatsFromSourceFormat; | ||
77 | |||
78 | |||
79 | |||
80 | protected TMatrixFormatConversionProvider( | ||
81 | List sourceFormats, | ||
82 | List targetFormats, | ||
83 | boolean[][] abConversionPossible) | ||
84 | { | ||
85 | super(sourceFormats, | ||
86 | targetFormats); | ||
87 | m_targetEncodingsFromSourceFormat = new HashMap(); | ||
88 | m_targetFormatsFromSourceFormat = new HashMap(); | ||
89 | |||
90 | for (int nSourceFormat = 0; | ||
91 | nSourceFormat < sourceFormats.size(); | ||
92 | nSourceFormat++) | ||
93 | { | ||
94 | AudioFormat sourceFormat = (AudioFormat) sourceFormats.get(nSourceFormat); | ||
95 | List supportedTargetEncodings = new ArraySet(); | ||
96 | m_targetEncodingsFromSourceFormat.put(sourceFormat, supportedTargetEncodings); | ||
97 | Map targetFormatsFromTargetEncodings = new HashMap(); | ||
98 | m_targetFormatsFromSourceFormat.put(sourceFormat, targetFormatsFromTargetEncodings); | ||
99 | for (int nTargetFormat = 0; | ||
100 | nTargetFormat < targetFormats.size(); | ||
101 | nTargetFormat++) | ||
102 | { | ||
103 | AudioFormat targetFormat = (AudioFormat) targetFormats.get(nTargetFormat); | ||
104 | if (abConversionPossible[nSourceFormat][nTargetFormat]) | ||
105 | { | ||
106 | AudioFormat.Encoding targetEncoding = targetFormat.getEncoding(); | ||
107 | supportedTargetEncodings.add(targetEncoding); | ||
108 | Collection supportedTargetFormats = (Collection) targetFormatsFromTargetEncodings.get(targetEncoding); | ||
109 | if (supportedTargetFormats == null) | ||
110 | { | ||
111 | supportedTargetFormats = new ArraySet(); | ||
112 | targetFormatsFromTargetEncodings.put(targetEncoding, supportedTargetFormats); | ||
113 | } | ||
114 | supportedTargetFormats.add(targetFormat); | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
120 | |||
121 | |||
122 | public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat) | ||
123 | { | ||
124 | Iterator iterator = m_targetEncodingsFromSourceFormat.entrySet().iterator(); | ||
125 | while (iterator.hasNext()) | ||
126 | { | ||
127 | Map.Entry entry = (Map.Entry) iterator.next(); | ||
128 | AudioFormat format = (AudioFormat) entry.getKey(); | ||
129 | if (AudioFormats.matches(format, sourceFormat)) | ||
130 | { | ||
131 | Collection targetEncodings = (Collection) entry.getValue(); | ||
132 | return (AudioFormat.Encoding[]) targetEncodings.toArray(EMPTY_ENCODING_ARRAY); | ||
133 | } | ||
134 | |||
135 | } | ||
136 | return EMPTY_ENCODING_ARRAY; | ||
137 | } | ||
138 | |||
139 | |||
140 | |||
141 | // TODO: this should work on the array returned by getTargetEncodings(AudioFormat) | ||
142 | /* | ||
143 | public boolean isConversionSupported(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) | ||
144 | { | ||
145 | return isAllowedSourceFormat(sourceFormat) && | ||
146 | isTargetEncodingSupported(targetEncoding); | ||
147 | } | ||
148 | */ | ||
149 | |||
150 | |||
151 | |||
152 | public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) | ||
153 | { | ||
154 | Iterator iterator = m_targetFormatsFromSourceFormat.entrySet().iterator(); | ||
155 | while (iterator.hasNext()) | ||
156 | { | ||
157 | Map.Entry entry = (Map.Entry) iterator.next(); | ||
158 | AudioFormat format = (AudioFormat) entry.getKey(); | ||
159 | if (AudioFormats.matches(format, sourceFormat)) | ||
160 | { | ||
161 | Map targetEncodings = (Map) entry.getValue(); | ||
162 | Collection targetFormats = (Collection) targetEncodings.get(targetEncoding); | ||
163 | if (targetFormats != null) | ||
164 | { | ||
165 | return (AudioFormat[]) targetFormats.toArray(EMPTY_FORMAT_ARRAY); | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | return EMPTY_FORMAT_ARRAY; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | } | ||
174 | return EMPTY_FORMAT_ARRAY; | ||
175 | } | ||
176 | |||
177 | |||
178 | } | ||
179 | |||
180 | |||
181 | |||
182 | /*** TMatrixFormatConversionProvider.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java b/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java deleted file mode 100644 index 71b055ff79..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java +++ /dev/null | |||
@@ -1,367 +0,0 @@ | |||
1 | /* | ||
2 | * TSimpleFormatConversionProvider.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 1999 - 2004 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | |<--- this code is formatted to fit into 80 columns --->| | ||
28 | */ | ||
29 | |||
30 | package org.tritonus.share.sampled.convert; | ||
31 | |||
32 | import java.util.Collection; | ||
33 | import java.util.Iterator; | ||
34 | |||
35 | import javax.sound.sampled.AudioFormat; | ||
36 | import javax.sound.sampled.AudioSystem; | ||
37 | |||
38 | import org.tritonus.share.sampled.AudioFormats; | ||
39 | import org.tritonus.share.ArraySet; | ||
40 | import org.tritonus.share.TDebug; | ||
41 | |||
42 | |||
43 | /** | ||
44 | * This is a base class for FormatConversionProviders that can convert | ||
45 | * from each source encoding/format to each target encoding/format. | ||
46 | * If this is not the case, use TEncodingFormatConversionProvider. | ||
47 | * | ||
48 | * <p>Overriding classes must | ||
49 | * provide a constructor that calls the protected constructor of this class and override | ||
50 | * <code>AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream)</code>. | ||
51 | * The latter method should be able to handle the case that all fields are NOT_SPECIFIED | ||
52 | * and provide appropriate default values. | ||
53 | * | ||
54 | * @author Matthias Pfisterer | ||
55 | */ | ||
56 | |||
57 | // todo: | ||
58 | // - declare a constant ALL_BUT_SAME_VALUE (==-2) or so that can be used in format lists | ||
59 | // - consistent implementation of replacing NOT_SPECIFIED when not given in conversion | ||
60 | |||
61 | public abstract class TSimpleFormatConversionProvider | ||
62 | extends TFormatConversionProvider | ||
63 | { | ||
64 | private Collection<AudioFormat.Encoding> m_sourceEncodings; | ||
65 | private Collection<AudioFormat.Encoding> m_targetEncodings; | ||
66 | private Collection<AudioFormat> m_sourceFormats; | ||
67 | private Collection<AudioFormat> m_targetFormats; | ||
68 | |||
69 | |||
70 | |||
71 | protected TSimpleFormatConversionProvider( | ||
72 | Collection<AudioFormat> sourceFormats, | ||
73 | Collection<AudioFormat> targetFormats) | ||
74 | { | ||
75 | m_sourceEncodings = new ArraySet<AudioFormat.Encoding>(); | ||
76 | m_targetEncodings = new ArraySet<AudioFormat.Encoding>(); | ||
77 | m_sourceFormats = sourceFormats; | ||
78 | m_targetFormats = targetFormats; | ||
79 | collectEncodings(m_sourceFormats, m_sourceEncodings); | ||
80 | collectEncodings(m_targetFormats, m_targetEncodings); | ||
81 | } | ||
82 | |||
83 | |||
84 | |||
85 | /** Disables this FormatConversionProvider. | ||
86 | This may be useful when e.g. native libraries are not present. | ||
87 | TODO: enable method, better implementation | ||
88 | */ | ||
89 | protected void disable() | ||
90 | { | ||
91 | if (TDebug.TraceAudioConverter) { TDebug.out("TSimpleFormatConversionProvider.disable(): disabling " + getClass().getName()); } | ||
92 | m_sourceEncodings = new ArraySet<AudioFormat.Encoding>(); | ||
93 | m_targetEncodings = new ArraySet<AudioFormat.Encoding>(); | ||
94 | m_sourceFormats = new ArraySet<AudioFormat>(); | ||
95 | m_targetFormats = new ArraySet<AudioFormat>(); | ||
96 | } | ||
97 | |||
98 | |||
99 | |||
100 | private static void collectEncodings(Collection<AudioFormat> formats, | ||
101 | Collection<AudioFormat.Encoding> encodings) | ||
102 | { | ||
103 | Iterator<AudioFormat> iterator = formats.iterator(); | ||
104 | while (iterator.hasNext()) | ||
105 | { | ||
106 | AudioFormat format = iterator.next(); | ||
107 | encodings.add(format.getEncoding()); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | public AudioFormat.Encoding[] getSourceEncodings() | ||
114 | { | ||
115 | return m_sourceEncodings.toArray(EMPTY_ENCODING_ARRAY); | ||
116 | } | ||
117 | |||
118 | |||
119 | |||
120 | public AudioFormat.Encoding[] getTargetEncodings() | ||
121 | { | ||
122 | return m_targetEncodings.toArray(EMPTY_ENCODING_ARRAY); | ||
123 | } | ||
124 | |||
125 | |||
126 | |||
127 | // overwritten of FormatConversionProvider | ||
128 | public boolean isSourceEncodingSupported(AudioFormat.Encoding sourceEncoding) | ||
129 | { | ||
130 | return m_sourceEncodings.contains(sourceEncoding); | ||
131 | } | ||
132 | |||
133 | |||
134 | |||
135 | // overwritten of FormatConversionProvider | ||
136 | public boolean isTargetEncodingSupported(AudioFormat.Encoding targetEncoding) | ||
137 | { | ||
138 | return m_targetEncodings.contains(targetEncoding); | ||
139 | } | ||
140 | |||
141 | |||
142 | |||
143 | /** | ||
144 | * This implementation assumes that the converter can convert | ||
145 | * from each of its source encodings to each of its target | ||
146 | * encodings. If this is not the case, the converter has to | ||
147 | * override this method. | ||
148 | */ | ||
149 | public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat) | ||
150 | { | ||
151 | if (isAllowedSourceFormat(sourceFormat)) | ||
152 | { | ||
153 | return getTargetEncodings(); | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | return EMPTY_ENCODING_ARRAY; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | |||
162 | |||
163 | /** | ||
164 | * This implementation assumes that the converter can convert | ||
165 | * from each of its source formats to each of its target | ||
166 | * formats. If this is not the case, the converter has to | ||
167 | * override this method. | ||
168 | */ | ||
169 | public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) | ||
170 | { | ||
171 | if (isConversionSupported(targetEncoding, sourceFormat)) | ||
172 | { | ||
173 | return m_targetFormats.toArray(EMPTY_FORMAT_ARRAY); | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | return EMPTY_FORMAT_ARRAY; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | |||
182 | // TODO: check if necessary | ||
183 | protected boolean isAllowedSourceEncoding(AudioFormat.Encoding sourceEncoding) | ||
184 | { | ||
185 | return m_sourceEncodings.contains(sourceEncoding); | ||
186 | } | ||
187 | |||
188 | |||
189 | |||
190 | protected boolean isAllowedTargetEncoding(AudioFormat.Encoding targetEncoding) | ||
191 | { | ||
192 | return m_targetEncodings.contains(targetEncoding); | ||
193 | } | ||
194 | |||
195 | |||
196 | |||
197 | protected boolean isAllowedSourceFormat(AudioFormat sourceFormat) | ||
198 | { | ||
199 | Iterator<AudioFormat> iterator = m_sourceFormats.iterator(); | ||
200 | while (iterator.hasNext()) | ||
201 | { | ||
202 | AudioFormat format = iterator.next(); | ||
203 | if (AudioFormats.matches(format, sourceFormat)) | ||
204 | { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | return false; | ||
209 | } | ||
210 | |||
211 | |||
212 | |||
213 | protected boolean isAllowedTargetFormat(AudioFormat targetFormat) | ||
214 | { | ||
215 | Iterator<AudioFormat> iterator = m_targetFormats.iterator(); | ||
216 | while (iterator.hasNext()) | ||
217 | { | ||
218 | AudioFormat format = iterator.next(); | ||
219 | if (AudioFormats.matches(format, targetFormat)) | ||
220 | { | ||
221 | return true; | ||
222 | } | ||
223 | } | ||
224 | return false; | ||
225 | } | ||
226 | |||
227 | // $$fb 2000-04-02 added some convenience methods for overriding classes | ||
228 | protected Collection<AudioFormat.Encoding> getCollectionSourceEncodings() | ||
229 | { | ||
230 | return m_sourceEncodings; | ||
231 | } | ||
232 | |||
233 | protected Collection<AudioFormat.Encoding> getCollectionTargetEncodings() | ||
234 | { | ||
235 | return m_targetEncodings; | ||
236 | } | ||
237 | |||
238 | protected Collection<AudioFormat> getCollectionSourceFormats() { | ||
239 | return m_sourceFormats; | ||
240 | } | ||
241 | |||
242 | protected Collection<AudioFormat> getCollectionTargetFormats() { | ||
243 | return m_targetFormats; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Utility method to check whether these values match, | ||
248 | * taking into account AudioSystem.NOT_SPECIFIED. | ||
249 | * @return true if any of the values is AudioSystem.NOT_SPECIFIED | ||
250 | * or both values have the same value. | ||
251 | */ | ||
252 | //$$fb 2000-08-16: moved from TEncodingFormatConversionProvider | ||
253 | protected static boolean doMatch(int i1, int i2) { | ||
254 | return i1==AudioSystem.NOT_SPECIFIED | ||
255 | || i2==AudioSystem.NOT_SPECIFIED | ||
256 | || i1==i2; | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * @see #doMatch(int,int) | ||
261 | */ | ||
262 | //$$fb 2000-08-16: moved from TEncodingFormatConversionProvider | ||
263 | protected static boolean doMatch(float f1, float f2) { | ||
264 | return f1==AudioSystem.NOT_SPECIFIED | ||
265 | || f2==AudioSystem.NOT_SPECIFIED | ||
266 | || Math.abs(f1 - f2) < 1.0e-9; | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * Utility method, replaces all occurences of AudioSystem.NOT_SPECIFIED | ||
271 | * in <code>targetFormat</code> with the corresponding value in <code>sourceFormat</code>. | ||
272 | * If <code>targetFormat</code> does not contain any fields with AudioSystem.NOT_SPECIFIED, | ||
273 | * it is returned unmodified. The endian-ness and encoding remain the same in all cases. | ||
274 | * <p> | ||
275 | * If any of the fields is AudioSystem.NOT_SPECIFIED in both <code>sourceFormat</code> and | ||
276 | * <code>targetFormat</code>, it will remain not specified. | ||
277 | * <p> | ||
278 | * This method uses <code>getFrameSize(...)</code> (see below) to set the new frameSize, | ||
279 | * if a new AudioFormat instance is created. | ||
280 | * <p> | ||
281 | * This method isn't used in TSimpleFormatConversionProvider - it is solely there | ||
282 | * for inheriting classes. | ||
283 | */ | ||
284 | //$$fb 2000-08-16: moved from TEncodingFormatConversionProvider | ||
285 | protected AudioFormat replaceNotSpecified(AudioFormat sourceFormat, AudioFormat targetFormat) { | ||
286 | boolean bSetSampleSize=false; | ||
287 | boolean bSetChannels=false; | ||
288 | boolean bSetSampleRate=false; | ||
289 | boolean bSetFrameRate=false; | ||
290 | if (targetFormat.getSampleSizeInBits()==AudioSystem.NOT_SPECIFIED | ||
291 | && sourceFormat.getSampleSizeInBits()!=AudioSystem.NOT_SPECIFIED) { | ||
292 | bSetSampleSize=true; | ||
293 | } | ||
294 | if (targetFormat.getChannels()==AudioSystem.NOT_SPECIFIED | ||
295 | && sourceFormat.getChannels()!=AudioSystem.NOT_SPECIFIED) { | ||
296 | bSetChannels=true; | ||
297 | } | ||
298 | if (targetFormat.getSampleRate()==AudioSystem.NOT_SPECIFIED | ||
299 | && sourceFormat.getSampleRate()!=AudioSystem.NOT_SPECIFIED) { | ||
300 | bSetSampleRate=true; | ||
301 | } | ||
302 | if (targetFormat.getFrameRate()==AudioSystem.NOT_SPECIFIED | ||
303 | && sourceFormat.getFrameRate()!=AudioSystem.NOT_SPECIFIED) { | ||
304 | bSetFrameRate=true; | ||
305 | } | ||
306 | if (bSetSampleSize || bSetChannels || bSetSampleRate || bSetFrameRate | ||
307 | || (targetFormat.getFrameSize()==AudioSystem.NOT_SPECIFIED | ||
308 | && sourceFormat.getFrameSize()!=AudioSystem.NOT_SPECIFIED)) { | ||
309 | // create new format in place of the original target format | ||
310 | float sampleRate=bSetSampleRate? | ||
311 | sourceFormat.getSampleRate():targetFormat.getSampleRate(); | ||
312 | float frameRate=bSetFrameRate? | ||
313 | sourceFormat.getFrameRate():targetFormat.getFrameRate(); | ||
314 | int sampleSize=bSetSampleSize? | ||
315 | sourceFormat.getSampleSizeInBits():targetFormat.getSampleSizeInBits(); | ||
316 | int channels=bSetChannels? | ||
317 | sourceFormat.getChannels():targetFormat.getChannels(); | ||
318 | int frameSize=getFrameSize( | ||
319 | targetFormat.getEncoding(), | ||
320 | sampleRate, | ||
321 | sampleSize, | ||
322 | channels, | ||
323 | frameRate, | ||
324 | targetFormat.isBigEndian(), | ||
325 | targetFormat.getFrameSize()); | ||
326 | targetFormat= new AudioFormat( | ||
327 | targetFormat.getEncoding(), | ||
328 | sampleRate, | ||
329 | sampleSize, | ||
330 | channels, | ||
331 | frameSize, | ||
332 | frameRate, | ||
333 | targetFormat.isBigEndian()); | ||
334 | } | ||
335 | return targetFormat; | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * Calculates the frame size for the given format description. | ||
340 | * The default implementation returns AudioSystem.NOT_SPECIFIED | ||
341 | * if either <code>sampleSize</code> or <code>channels</code> is AudioSystem.NOT_SPECIFIED, | ||
342 | * otherwise <code>sampleSize*channels/8</code> is returned. | ||
343 | * <p> | ||
344 | * If this does not reflect the way to calculate the right frame size, | ||
345 | * inheriting classes should overwrite this method if they use | ||
346 | * replaceNotSpecified(...). It is not used elsewhere in this class. | ||
347 | */ | ||
348 | //$$fb 2000-08-16: added | ||
349 | protected int getFrameSize( | ||
350 | AudioFormat.Encoding encoding, | ||
351 | float sampleRate, | ||
352 | int sampleSize, | ||
353 | int channels, | ||
354 | float frameRate, | ||
355 | boolean bigEndian, | ||
356 | int oldFrameSize) { | ||
357 | if (sampleSize==AudioSystem.NOT_SPECIFIED || channels==AudioSystem.NOT_SPECIFIED) { | ||
358 | return AudioSystem.NOT_SPECIFIED; | ||
359 | } | ||
360 | return sampleSize*channels/8; | ||
361 | } | ||
362 | |||
363 | |||
364 | |||
365 | } | ||
366 | |||
367 | /*** TSimpleFormatConversionProvider.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/TSynchronousFilteredAudioInputStream.java b/songdbj/org/tritonus/share/sampled/convert/TSynchronousFilteredAudioInputStream.java deleted file mode 100644 index 8a588e5c3e..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/TSynchronousFilteredAudioInputStream.java +++ /dev/null | |||
@@ -1,271 +0,0 @@ | |||
1 | /* | ||
2 | * TSynchronousFilteredAudioInputStream.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 1999,2000 by Florian Bomers <http://www.bomers.de> | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU Library General Public License as published | ||
13 | * by the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU Library General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Library General Public | ||
22 | * License along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | |<--- this code is formatted to fit into 80 columns --->| | ||
29 | */ | ||
30 | |||
31 | package org.tritonus.share.sampled.convert; | ||
32 | |||
33 | import java.io.IOException; | ||
34 | |||
35 | import javax.sound.sampled.AudioSystem; | ||
36 | import javax.sound.sampled.AudioFormat; | ||
37 | import javax.sound.sampled.AudioInputStream; | ||
38 | import javax.sound.sampled.spi.FormatConversionProvider; | ||
39 | |||
40 | import org.tritonus.share.TDebug; | ||
41 | import org.tritonus.share.sampled.AudioUtils; | ||
42 | |||
43 | |||
44 | |||
45 | /** | ||
46 | * Base class for types of audio filter/converter that translate one frame to another frame.<br> | ||
47 | * It provides all the transformation of frame sizes.<br> | ||
48 | * It does NOT handle different sample rates of original stream and this stream ! | ||
49 | * | ||
50 | * @author Florian Bomers | ||
51 | */ | ||
52 | public abstract class TSynchronousFilteredAudioInputStream | ||
53 | extends TAudioInputStream { | ||
54 | |||
55 | private AudioInputStream originalStream; | ||
56 | private AudioFormat originalFormat; | ||
57 | /** 1 if original format's frame size is NOT_SPECIFIED */ | ||
58 | private int originalFrameSize; | ||
59 | /** 1 if original format's frame size is NOT_SPECIFIED */ | ||
60 | private int newFrameSize; | ||
61 | |||
62 | /** | ||
63 | * The intermediate buffer used during convert actions | ||
64 | * (if not convertInPlace is used). | ||
65 | * It remains until this audioStream is closed or destroyed | ||
66 | * and grows with the time - it always has the size of the | ||
67 | * largest intermediate buffer ever needed. | ||
68 | */ | ||
69 | protected byte[] buffer=null; | ||
70 | |||
71 | /** | ||
72 | * For use of the more efficient method convertInPlace. | ||
73 | * it will be set to true when (frameSizeFactor==1) | ||
74 | */ | ||
75 | private boolean m_bConvertInPlace = false; | ||
76 | |||
77 | public TSynchronousFilteredAudioInputStream(AudioInputStream audioInputStream, AudioFormat newFormat) { | ||
78 | // the super class will do nothing... we override everything | ||
79 | super(audioInputStream, newFormat, audioInputStream.getFrameLength()); | ||
80 | originalStream=audioInputStream; | ||
81 | originalFormat=audioInputStream.getFormat(); | ||
82 | originalFrameSize=(originalFormat.getFrameSize()<=0) ? | ||
83 | 1 : originalFormat.getFrameSize(); | ||
84 | newFrameSize=(getFormat().getFrameSize()<=0) ? | ||
85 | 1 : getFormat().getFrameSize(); | ||
86 | if (TDebug.TraceAudioConverter) { | ||
87 | TDebug.out("TSynchronousFilteredAudioInputStream: original format =" | ||
88 | +AudioUtils.format2ShortStr(originalFormat)); | ||
89 | TDebug.out("TSynchronousFilteredAudioInputStream: converted format=" | ||
90 | +AudioUtils.format2ShortStr(getFormat())); | ||
91 | } | ||
92 | //$$fb 2000-07-17: convert in place has to be enabled explicitly with "enableConvertInPlace" | ||
93 | //if (getFormat().getFrameSize() == originalFormat.getFrameSize()) { | ||
94 | // m_bConvertInPlace = true; | ||
95 | //} | ||
96 | m_bConvertInPlace = false; | ||
97 | } | ||
98 | |||
99 | protected boolean enableConvertInPlace() { | ||
100 | if (newFrameSize >= originalFrameSize) { | ||
101 | m_bConvertInPlace = true; | ||
102 | } | ||
103 | return m_bConvertInPlace; | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Override this method to do the actual conversion. | ||
109 | * inBuffer starts always at index 0 (it is an internal buffer) | ||
110 | * You should always override this. | ||
111 | * inFrameCount is the number of frames in inBuffer. These | ||
112 | * frames are of the format originalFormat. | ||
113 | * @return the resulting number of <B>frames</B> converted and put into | ||
114 | * outBuffer. The return value is in the format of this stream. | ||
115 | */ | ||
116 | protected abstract int convert(byte[] inBuffer, byte[] outBuffer, int outByteOffset, int inFrameCount); | ||
117 | |||
118 | |||
119 | |||
120 | /** | ||
121 | * Override this method to provide in-place conversion of samples. | ||
122 | * To use it, call "enableConvertInPlace()". It will only be used when | ||
123 | * input bytes per frame >= output bytes per frame. | ||
124 | * This method must always convert frameCount frames, so no return value is necessary. | ||
125 | */ | ||
126 | protected void convertInPlace(byte[] buffer, int byteOffset, int frameCount) { | ||
127 | throw new RuntimeException("Illegal call to convertInPlace"); | ||
128 | } | ||
129 | |||
130 | public int read() | ||
131 | throws IOException { | ||
132 | if (newFrameSize != 1) { | ||
133 | throw new IOException("frame size must be 1 to read a single byte"); | ||
134 | } | ||
135 | // very ugly, but efficient. Who uses this method anyway ? | ||
136 | // TODO: use an instance variable | ||
137 | byte[] temp = new byte[1]; | ||
138 | int result = read(temp); | ||
139 | if (result == -1) { | ||
140 | return -1; | ||
141 | } | ||
142 | if (result == 0) { | ||
143 | // what in this case ??? Let's hope it never occurs. | ||
144 | return -1; | ||
145 | } | ||
146 | return temp[0] & 0xFF; | ||
147 | } | ||
148 | |||
149 | |||
150 | |||
151 | private void clearBuffer() { | ||
152 | buffer = null; | ||
153 | } | ||
154 | |||
155 | public AudioInputStream getOriginalStream() { | ||
156 | return originalStream; | ||
157 | } | ||
158 | |||
159 | public AudioFormat getOriginalFormat() { | ||
160 | return originalFormat; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Read nLength bytes that will be the converted samples | ||
165 | * of the original InputStream. | ||
166 | * When nLength is not an integral number of frames, | ||
167 | * this method may read less than nLength bytes. | ||
168 | */ | ||
169 | public int read(byte[] abData, int nOffset, int nLength) | ||
170 | throws IOException { | ||
171 | // number of frames that we have to read from the underlying stream. | ||
172 | int nFrameLength = nLength/newFrameSize; | ||
173 | |||
174 | // number of bytes that we need to read from underlying stream. | ||
175 | int originalBytes = nFrameLength * originalFrameSize; | ||
176 | |||
177 | if (TDebug.TraceAudioConverter) { | ||
178 | TDebug.out("> TSynchronousFilteredAIS.read(buffer["+abData.length+"], " | ||
179 | +nOffset+" ,"+nLength+" bytes ^="+nFrameLength+" frames)"); | ||
180 | } | ||
181 | int nFramesConverted = 0; | ||
182 | |||
183 | // set up buffer to read | ||
184 | byte readBuffer[]; | ||
185 | int readOffset; | ||
186 | if (m_bConvertInPlace) { | ||
187 | readBuffer=abData; | ||
188 | readOffset=nOffset; | ||
189 | } else { | ||
190 | // assert that the buffer fits | ||
191 | if (buffer == null || buffer.length < originalBytes) { | ||
192 | buffer = new byte[originalBytes]; | ||
193 | } | ||
194 | readBuffer=buffer; | ||
195 | readOffset=0; | ||
196 | } | ||
197 | int nBytesRead = originalStream.read(readBuffer, readOffset, originalBytes); | ||
198 | if (nBytesRead == -1) { | ||
199 | // end of stream | ||
200 | clearBuffer(); | ||
201 | return -1; | ||
202 | } | ||
203 | int nFramesRead = nBytesRead / originalFrameSize; | ||
204 | if (TDebug.TraceAudioConverter) { | ||
205 | TDebug.out("original.read returned " | ||
206 | +nBytesRead+" bytes ^="+nFramesRead+" frames"); | ||
207 | } | ||
208 | if (m_bConvertInPlace) { | ||
209 | convertInPlace(abData, nOffset, nFramesRead); | ||
210 | nFramesConverted=nFramesRead; | ||
211 | } else { | ||
212 | nFramesConverted = convert(buffer, abData, nOffset, nFramesRead); | ||
213 | } | ||
214 | if (TDebug.TraceAudioConverter) { | ||
215 | TDebug.out("< converted "+nFramesConverted+" frames"); | ||
216 | } | ||
217 | return nFramesConverted*newFrameSize; | ||
218 | } | ||
219 | |||
220 | |||
221 | public long skip(long nSkip) | ||
222 | throws IOException { | ||
223 | // only returns integral frames | ||
224 | long skipFrames = nSkip / newFrameSize; | ||
225 | long originalSkippedBytes = originalStream.skip(skipFrames*originalFrameSize); | ||
226 | long skippedFrames = originalSkippedBytes/originalFrameSize; | ||
227 | return skippedFrames * newFrameSize; | ||
228 | } | ||
229 | |||
230 | |||
231 | public int available() | ||
232 | throws IOException { | ||
233 | int origAvailFrames = originalStream.available()/originalFrameSize; | ||
234 | return origAvailFrames*newFrameSize; | ||
235 | } | ||
236 | |||
237 | |||
238 | public void close() | ||
239 | throws IOException { | ||
240 | originalStream.close(); | ||
241 | clearBuffer(); | ||
242 | } | ||
243 | |||
244 | |||
245 | |||
246 | public void mark(int readlimit) { | ||
247 | int readLimitFrames=readlimit/newFrameSize; | ||
248 | originalStream.mark(readLimitFrames*originalFrameSize); | ||
249 | } | ||
250 | |||
251 | |||
252 | |||
253 | public void reset() | ||
254 | throws IOException { | ||
255 | originalStream.reset(); | ||
256 | } | ||
257 | |||
258 | |||
259 | public boolean markSupported() { | ||
260 | return originalStream.markSupported(); | ||
261 | } | ||
262 | |||
263 | |||
264 | private int getFrameSize() { | ||
265 | return getFormat().getFrameSize(); | ||
266 | } | ||
267 | |||
268 | } | ||
269 | |||
270 | |||
271 | /*** TSynchronousFilteredAudioInputStream.java ***/ | ||
diff --git a/songdbj/org/tritonus/share/sampled/convert/package.html b/songdbj/org/tritonus/share/sampled/convert/package.html deleted file mode 100644 index d0cc35c408..0000000000 --- a/songdbj/org/tritonus/share/sampled/convert/package.html +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | <html> | ||
3 | <head> | ||
4 | </head> | ||
5 | |||
6 | <body> | ||
7 | <p>Base classes for the implementation of FormatConversionProviders. | ||
8 | The classes provided here .</p> | ||
9 | |||
10 | @see javax.sound.sampled.spi.FormatConversionProvider | ||
11 | @see org.tritonus.sampled.convert | ||
12 | @see org.tritonus.sampled.convert.gsm | ||
13 | @see org.tritonus.sampled.convert.jorbis | ||
14 | @see org.tritonus.sampled.convert.lame | ||
15 | @see org.tritonus.sampled.convert.vorbis | ||
16 | </body> | ||
17 | </html> | ||