summaryrefslogtreecommitdiff
path: root/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java')
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java367
1 files changed, 367 insertions, 0 deletions
diff --git a/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java b/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java
new file mode 100644
index 0000000000..71b055ff79
--- /dev/null
+++ b/songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java
@@ -0,0 +1,367 @@
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
30package org.tritonus.share.sampled.convert;
31
32import java.util.Collection;
33import java.util.Iterator;
34
35import javax.sound.sampled.AudioFormat;
36import javax.sound.sampled.AudioSystem;
37
38import org.tritonus.share.sampled.AudioFormats;
39import org.tritonus.share.ArraySet;
40import 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
61public abstract class TSimpleFormatConversionProvider
62extends 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 ***/