Revert "make creating audio decoders take codec data, too"
[swfdec.git] / swfdec / swfdec_audio_decoder_uncompressed.c
blob6a4caf6ce54a70b813f82a9666280bdfac710dce
1 /* Swfdec
2 * Copyright (C) 2006-2008 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.
8 *
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
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "swfdec_audio_decoder_uncompressed.h"
25 #include "swfdec_debug.h"
26 #include "swfdec_internal.h"
28 G_DEFINE_TYPE (SwfdecAudioDecoderUncompressed, swfdec_audio_decoder_uncompressed, SWFDEC_TYPE_AUDIO_DECODER)
30 static gboolean
31 swfdec_audio_decoder_uncompressed_prepare (guint codec, SwfdecAudioFormat format, char **missing)
33 return codec == SWFDEC_AUDIO_CODEC_UNDEFINED ||
34 codec == SWFDEC_AUDIO_CODEC_UNCOMPRESSED;
37 static SwfdecAudioDecoder *
38 swfdec_audio_decoder_uncompressed_create (guint codec, SwfdecAudioFormat format)
40 if (codec != SWFDEC_AUDIO_CODEC_UNDEFINED &&
41 codec != SWFDEC_AUDIO_CODEC_UNCOMPRESSED)
42 return NULL;
44 return g_object_new (SWFDEC_TYPE_AUDIO_DECODER_UNCOMPRESSED, NULL);
47 static SwfdecBuffer *
48 swfdec_audio_decoder_uncompressed_upscale (SwfdecBuffer *buffer, SwfdecAudioFormat format)
50 guint channels = swfdec_audio_format_get_channels (format);
51 guint granularity = swfdec_audio_format_get_granularity (format);
52 SwfdecBuffer *ret;
53 guint i, j, n_samples;
54 gint16 *src, *dest;
56 n_samples = buffer->length / 2 / channels;
57 if (n_samples * 2 * channels != buffer->length) {
58 SWFDEC_ERROR ("incorrect buffer size, %"G_GSIZE_FORMAT" bytes overhead",
59 buffer->length - n_samples * 2 * channels);
61 ret = swfdec_buffer_new (n_samples * 4 * granularity);
62 /* can be upscaled, because the input buffer and the newly allocated buffer
63 * are aligned properly */
64 src = (gint16 *) (gpointer) buffer->data;
65 dest = (gint16 *) (gpointer) ret->data;
66 for (i = 0; i < n_samples; i++) {
67 for (j = 0; j < granularity; j++) {
68 *dest++ = src[0];
69 *dest++ = src[channels - 1];
71 src += channels;
74 swfdec_buffer_unref (buffer);
75 return ret;
78 static SwfdecBuffer *
79 swfdec_audio_decoder_uncompressed_decode_8bit (SwfdecBuffer *buffer)
81 SwfdecBuffer *ret;
82 gint16 *out;
83 guint8 *in;
84 guint i;
86 ret = swfdec_buffer_new (buffer->length * 2);
87 out = (gint16 *) (void *) ret->data;
88 in = buffer->data;
89 for (i = 0; i < buffer->length; i++) {
90 *out = ((gint16) *in << 8) ^ (-1);
91 out++;
92 in++;
94 return ret;
97 static SwfdecBuffer *
98 swfdec_audio_decoder_uncompressed_decode_16bit (SwfdecBuffer *buffer)
100 SwfdecBuffer *ret;
101 SwfdecBits bits;
102 gint16 *dest;
103 guint i;
105 if (buffer->length & 2) {
106 SWFDEC_ERROR ("buffer length not a multiple of 16bit");
108 ret = swfdec_buffer_new (buffer->length & ~1);
109 swfdec_bits_init (&bits, buffer);
110 dest = (gint16 *) (gpointer) ret->data;
111 for (i = 0; i < ret->length; i += 2) {
112 *dest = swfdec_bits_get_u16 (&bits);
113 dest++;
116 return ret;
119 static void
120 swfdec_audio_decoder_uncompressed_push (SwfdecAudioDecoder *decoder,
121 SwfdecBuffer *buffer)
123 SwfdecBuffer *tmp;
125 if (buffer == NULL)
126 return;
128 if (swfdec_audio_format_is_16bit (decoder->format))
129 tmp = swfdec_audio_decoder_uncompressed_decode_16bit (buffer);
130 else
131 tmp = swfdec_audio_decoder_uncompressed_decode_8bit (buffer);
133 tmp = swfdec_audio_decoder_uncompressed_upscale (tmp, decoder->format);
134 swfdec_buffer_queue_push (SWFDEC_AUDIO_DECODER_UNCOMPRESSED (decoder)->queue,
135 tmp);
138 static SwfdecBuffer *
139 swfdec_audio_decoder_uncompressed_pull (SwfdecAudioDecoder *decoder)
141 SwfdecAudioDecoderUncompressed *dec = (SwfdecAudioDecoderUncompressed *) decoder;
143 return swfdec_buffer_queue_pull_buffer (dec->queue);
146 static void
147 swfdec_audio_decoder_uncompressed_dispose (GObject *object)
149 SwfdecAudioDecoderUncompressed *dec = (SwfdecAudioDecoderUncompressed *) object;
151 swfdec_buffer_queue_unref (dec->queue);
153 G_OBJECT_CLASS (swfdec_audio_decoder_uncompressed_parent_class)->dispose (object);
156 static void
157 swfdec_audio_decoder_uncompressed_class_init (SwfdecAudioDecoderUncompressedClass *klass)
159 GObjectClass *object_class = G_OBJECT_CLASS (klass);
160 SwfdecAudioDecoderClass *decoder_class = SWFDEC_AUDIO_DECODER_CLASS (klass);
162 object_class->dispose = swfdec_audio_decoder_uncompressed_dispose;
164 decoder_class->prepare = swfdec_audio_decoder_uncompressed_prepare;
165 decoder_class->create = swfdec_audio_decoder_uncompressed_create;
166 decoder_class->pull = swfdec_audio_decoder_uncompressed_pull;
167 decoder_class->push = swfdec_audio_decoder_uncompressed_push;
170 static void
171 swfdec_audio_decoder_uncompressed_init (SwfdecAudioDecoderUncompressed *dec)
173 dec->queue = swfdec_buffer_queue_new ();