Fix few bugs in SwfdecGtkSocket that made it unusable
[swfdec.git] / swfdec / swfdec_audio_decoder_uncompressed.c
blob69a69226e80dc6a64b45e0021bf2fdb137e0eab1
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 src = (gint16 *) buffer->data;
63 dest = (gint16 *) ret->data;
64 for (i = 0; i < n_samples; i++) {
65 for (j = 0; j < granularity; j++) {
66 *dest++ = src[0];
67 *dest++ = src[channels - 1];
69 src += channels;
72 swfdec_buffer_unref (buffer);
73 return ret;
76 static SwfdecBuffer *
77 swfdec_audio_decoder_uncompressed_decode_8bit (SwfdecBuffer *buffer)
79 SwfdecBuffer *ret;
80 gint16 *out;
81 guint8 *in;
82 guint i;
84 ret = swfdec_buffer_new (buffer->length * 2);
85 out = (gint16 *) (void *) ret->data;
86 in = buffer->data;
87 for (i = 0; i < buffer->length; i++) {
88 *out = ((gint16) *in << 8) ^ (-1);
89 out++;
90 in++;
92 return ret;
95 static SwfdecBuffer *
96 swfdec_audio_decoder_uncompressed_decode_16bit (SwfdecBuffer *buffer)
98 SwfdecBuffer *ret;
99 gint16 *src, *dest;
100 guint i;
102 ret = swfdec_buffer_new (buffer->length);
103 src = (gint16 *) buffer->data;
104 dest = (gint16 *) ret->data;
105 for (i = 0; i < buffer->length; i += 2) {
106 *dest = GINT16_FROM_LE (*src);
107 dest++;
108 src++;
111 return ret;
114 static void
115 swfdec_audio_decoder_uncompressed_push (SwfdecAudioDecoder *decoder,
116 SwfdecBuffer *buffer)
118 SwfdecBuffer *tmp;
120 if (buffer == NULL)
121 return;
123 if (swfdec_audio_format_is_16bit (decoder->format))
124 tmp = swfdec_audio_decoder_uncompressed_decode_16bit (buffer);
125 else
126 tmp = swfdec_audio_decoder_uncompressed_decode_8bit (buffer);
128 tmp = swfdec_audio_decoder_uncompressed_upscale (tmp, decoder->format);
129 swfdec_buffer_queue_push (SWFDEC_AUDIO_DECODER_UNCOMPRESSED (decoder)->queue,
130 tmp);
133 static SwfdecBuffer *
134 swfdec_audio_decoder_uncompressed_pull (SwfdecAudioDecoder *decoder)
136 SwfdecAudioDecoderUncompressed *dec = (SwfdecAudioDecoderUncompressed *) decoder;
138 return swfdec_buffer_queue_pull_buffer (dec->queue);
141 static void
142 swfdec_audio_decoder_uncompressed_dispose (GObject *object)
144 SwfdecAudioDecoderUncompressed *dec = (SwfdecAudioDecoderUncompressed *) object;
146 swfdec_buffer_queue_unref (dec->queue);
148 G_OBJECT_CLASS (swfdec_audio_decoder_uncompressed_parent_class)->dispose (object);
151 static void
152 swfdec_audio_decoder_uncompressed_class_init (SwfdecAudioDecoderUncompressedClass *klass)
154 GObjectClass *object_class = G_OBJECT_CLASS (klass);
155 SwfdecAudioDecoderClass *decoder_class = SWFDEC_AUDIO_DECODER_CLASS (klass);
157 object_class->dispose = swfdec_audio_decoder_uncompressed_dispose;
159 decoder_class->prepare = swfdec_audio_decoder_uncompressed_prepare;
160 decoder_class->create = swfdec_audio_decoder_uncompressed_create;
161 decoder_class->pull = swfdec_audio_decoder_uncompressed_pull;
162 decoder_class->push = swfdec_audio_decoder_uncompressed_push;
165 static void
166 swfdec_audio_decoder_uncompressed_init (SwfdecAudioDecoderUncompressed *dec)
168 dec->queue = swfdec_buffer_queue_new ();