summaryrefslogtreecommitdiff
path: root/songdbj/org/tritonus/share/sampled/convert
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/org/tritonus/share/sampled/convert')
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TAsynchronousFilteredAudioInputStream.java256
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TAudioInputStream.java120
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TEncodingFormatConversionProvider.java129
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TFormatConversionProvider.java170
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TMatrixFormatConversionProvider.java182
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TSimpleFormatConversionProvider.java367
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/TSynchronousFilteredAudioInputStream.java271
-rw-r--r--songdbj/org/tritonus/share/sampled/convert/package.html17
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
31package org.tritonus.share.sampled.convert;
32
33import java.io.ByteArrayInputStream;
34import java.io.IOException;
35
36import javax.sound.sampled.AudioFormat;
37import javax.sound.sampled.AudioInputStream;
38
39import org.tritonus.share.TDebug;
40import 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*/
55public abstract class TAsynchronousFilteredAudioInputStream
56extends TAudioInputStream
57implements 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
29package org.tritonus.share.sampled.convert;
30
31import java.io.InputStream;
32
33import java.util.Collections;
34import java.util.HashMap;
35import java.util.Map;
36
37import javax.sound.sampled.AudioFormat;
38import 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
52public class TAudioInputStream
53extends 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
31package org.tritonus.share.sampled.convert;
32
33import java.util.Collection;
34import java.util.Iterator;
35
36import javax.sound.sampled.AudioFormat;
37import javax.sound.sampled.AudioSystem;
38
39import org.tritonus.share.TDebug;
40import 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 */
67public abstract class TEncodingFormatConversionProvider
68extends 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
31package org.tritonus.share.sampled.convert;
32
33import javax.sound.sampled.AudioSystem;
34import javax.sound.sampled.AudioFormat;
35import javax.sound.sampled.AudioInputStream;
36import javax.sound.sampled.spi.FormatConversionProvider;
37
38import org.tritonus.share.TDebug;
39import org.tritonus.share.sampled.AudioFormats;
40
41
42
43/** Base class for all conversion providers of Tritonus.
44 *
45 * @author Matthias Pfisterer
46 */
47public abstract class TFormatConversionProvider
48extends 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
26package org.tritonus.share.sampled.convert;
27
28
29import java.util.Collection;
30import java.util.List;
31import java.util.Map;
32import java.util.Set;
33import java.util.HashMap;
34import java.util.ArrayList;
35import java.util.Iterator;
36
37import javax.sound.sampled.AudioFormat;
38import javax.sound.sampled.AudioInputStream;
39import javax.sound.sampled.spi.FormatConversionProvider;
40
41import org.tritonus.share.sampled.AudioFormats;
42import org.tritonus.share.ArraySet;
43
44/**
45 * Base class for arbitrary formatConversionProviders.
46 *
47 * @author Matthias Pfisterer
48 */
49
50
51public 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
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 ***/
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
31package org.tritonus.share.sampled.convert;
32
33import java.io.IOException;
34
35import javax.sound.sampled.AudioSystem;
36import javax.sound.sampled.AudioFormat;
37import javax.sound.sampled.AudioInputStream;
38import javax.sound.sampled.spi.FormatConversionProvider;
39
40import org.tritonus.share.TDebug;
41import 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 */
52public abstract class TSynchronousFilteredAudioInputStream
53extends 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>