2 * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
24 #include "swfdec_codec_audio.h"
25 #include "swfdec_debug.h"
26 #include "swfdec_internal.h"
28 /*** UNCOMPRESSED SOUND ***/
31 SwfdecAudioDecoder decoder
;
32 SwfdecBufferQueue
* queue
; /* queue collecting output buffers */
33 } SwfdecAudioDecoderUncompressed
;
36 swfdec_audio_decoder_uncompressed_decode_8bit (SwfdecAudioDecoder
*decoder
,
47 ret
= swfdec_buffer_new_and_alloc (buffer
->length
* 2);
48 out
= (gint16
*) ret
->data
;
50 for (i
= 0; i
< buffer
->length
; i
++) {
51 *out
= ((gint16
) *in
<< 8) ^ (-1);
55 swfdec_buffer_queue_push (((SwfdecAudioDecoderUncompressed
*) decoder
)->queue
, ret
);
59 swfdec_audio_decoder_uncompressed_decode_16bit (SwfdecAudioDecoder
*decoder
,
65 swfdec_buffer_ref (buffer
);
66 swfdec_buffer_queue_push (((SwfdecAudioDecoderUncompressed
*) decoder
)->queue
, buffer
);
70 swfdec_audio_decoder_uncompressed_pull (SwfdecAudioDecoder
*decoder
)
72 SwfdecAudioDecoderUncompressed
*dec
= (SwfdecAudioDecoderUncompressed
*) decoder
;
74 return swfdec_buffer_queue_pull_buffer (dec
->queue
);
78 swfdec_audio_decoder_uncompressed_free (SwfdecAudioDecoder
*decoder
)
80 SwfdecAudioDecoderUncompressed
*dec
= (SwfdecAudioDecoderUncompressed
*) decoder
;
82 swfdec_buffer_queue_unref (dec
->queue
);
86 static SwfdecAudioDecoder
*
87 swfdec_audio_decoder_uncompressed_new (guint type
, SwfdecAudioFormat format
)
89 SwfdecAudioDecoderUncompressed
*dec
;
91 if (type
!= SWFDEC_AUDIO_CODEC_UNDEFINED
&&
92 type
!= SWFDEC_AUDIO_CODEC_UNCOMPRESSED
)
94 if (type
== SWFDEC_AUDIO_CODEC_UNDEFINED
) {
95 SWFDEC_WARNING ("endianness of audio unknown, assuming little endian");
97 dec
= g_new (SwfdecAudioDecoderUncompressed
, 1);
98 dec
->decoder
.format
= format
;
99 if (swfdec_audio_format_is_16bit (format
))
100 dec
->decoder
.push
= swfdec_audio_decoder_uncompressed_decode_16bit
;
102 dec
->decoder
.push
= swfdec_audio_decoder_uncompressed_decode_8bit
;
103 dec
->decoder
.pull
= swfdec_audio_decoder_uncompressed_pull
;
104 dec
->decoder
.free
= swfdec_audio_decoder_uncompressed_free
;
105 dec
->queue
= swfdec_buffer_queue_new ();
107 return &dec
->decoder
;
112 static SwfdecAudioDecoder
*
113 swfdec_audio_decoder_builtin_new (guint codec
, SwfdecAudioFormat format
)
115 SwfdecAudioDecoder
*ret
;
117 ret
= swfdec_audio_decoder_uncompressed_new (codec
, format
);
119 ret
= swfdec_audio_decoder_adpcm_new (codec
, format
);
126 SwfdecAudioDecoder
* (* func
) (guint
, SwfdecAudioFormat
);
128 { "builtin", swfdec_audio_decoder_builtin_new
},
130 { "gst", swfdec_audio_decoder_gst_new
},
133 { "mad", swfdec_audio_decoder_mad_new
},
136 { "ffmpeg", swfdec_audio_decoder_ffmpeg_new
},
142 * swfdec_audio_decoder_new:
143 * @format: #SwfdecAudioCodec to decode
145 * Creates a decoder suitable for decoding @format. If no decoder is available
146 * for the given for mat, %NULL is returned.
148 * Returns: a new decoder or %NULL
151 swfdec_audio_decoder_new (guint codec
, SwfdecAudioFormat format
)
153 SwfdecAudioDecoder
*ret
;
156 g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (format
), NULL
);
158 list
= g_getenv ("SWFDEC_CODEC_AUDIO");
160 list
= g_getenv ("SWFDEC_CODEC");
164 for (i
= 0; audio_codecs
[i
].name
!= NULL
; i
++) {
165 ret
= audio_codecs
[i
].func (codec
, format
);
170 char **split
= g_strsplit (list
, ",", -1);
173 SWFDEC_LOG ("codecs limited to \"%s\"", list
);
174 for (i
= 0; split
[i
] != NULL
&& ret
== NULL
; i
++) {
175 for (j
= 0; audio_codecs
[j
].name
!= NULL
; j
++) {
176 if (g_ascii_strcasecmp (audio_codecs
[j
].name
, split
[i
]) != 0)
178 ret
= audio_codecs
[j
].func (codec
, format
);
188 g_return_val_if_fail (ret
->push
, NULL
);
189 g_return_val_if_fail (ret
->pull
, NULL
);
190 g_return_val_if_fail (ret
->free
, NULL
);
192 SWFDEC_ERROR ("no suitable decoder for audio codec %u", codec
);
199 * swfdec_audio_decoder_free:
200 * @decoder: a #SwfdecAudioDecoder
202 * Frees the given decoder. When finishing decoding, be sure to pass a %NULL
203 * buffer to swfdec_audio_decoder_push() first to flush the decoder. See that
204 * function for details.
207 swfdec_audio_decoder_free (SwfdecAudioDecoder
*decoder
)
209 g_return_if_fail (decoder
!= NULL
);
211 decoder
->free (decoder
);
215 * swfdec_audio_decoder_get_format:
216 * @decoder: a #SwfdecAudioDecoder
218 * Queries the format that is used by the decoder for its produced output.
219 * The format will only be valid after swfdec_audio_decoder_pull () has been
220 * called at least once.
222 * Returns: the format of the decoded data
225 swfdec_audio_decoder_get_format (SwfdecAudioDecoder
*decoder
)
227 g_return_val_if_fail (decoder
!= NULL
, 0);
228 g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (decoder
->format
), 0);
230 return decoder
->format
;
234 * swfdec_audio_decoder_push:
235 * @decoder: a #SwfdecAudioDecoder
236 * @buffer: a #SwfdecBuffer to process or %NULL to flush
238 * Pushes a new buffer into the decoding pipeline. After this the results can
239 * be queried using swfdec_audio_decoder_pull(). Some decoders may not decode
240 * all available data immediately. So when you are done decoding, you may want
241 * to flush the decoder. Flushing can be achieved by passing %NULL as the
242 * @buffer argument. Do this when you are finished decoding.
245 swfdec_audio_decoder_push (SwfdecAudioDecoder
*decoder
, SwfdecBuffer
*buffer
)
247 g_return_if_fail (decoder
!= NULL
);
249 decoder
->push (decoder
, buffer
);
253 * swfdec_audio_decoder_pull:
254 * @decoder: a #SwfdecAudioDecoder
256 * Gets the next buffer of decoded audio data. Since some decoders do not
257 * produce one output buffer per input buffer, any number of buffers may be
258 * available after calling swfdec_audio_decoder_push(), even none. When no more
259 * buffers are available, this function returns %NULL. You need to provide more
260 * input in then. A simple decoding pipeline would look like this:
261 * <informalexample><programlisting>do {
262 * input = next_input_buffer ();
263 * swfdec_audio_decoder_push (decoder, input);
264 * while ((output = swfdec_audio_decoder_pull (decoder))) {
265 * ... process output ...
267 * } while (input != NULL); </programlisting></informalexample>
269 * Returns: the next buffer or %NULL if no more buffers are available.
272 swfdec_audio_decoder_pull (SwfdecAudioDecoder
*decoder
)
276 g_return_val_if_fail (decoder
!= NULL
, NULL
);
278 ret
= decoder
->pull (decoder
);
281 g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (decoder
->format
), ret
);