2 * Copyright (C) 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.
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
25 #include "swfdec_audio_swf_stream.h"
26 #include "swfdec_debug.h"
27 #include "swfdec_sprite.h"
28 #include "swfdec_tag.h"
31 G_DEFINE_TYPE (SwfdecAudioSwfStream
, swfdec_audio_swf_stream
, SWFDEC_TYPE_AUDIO_STREAM
)
34 swfdec_audio_swf_stream_dispose (GObject
*object
)
36 SwfdecAudioSwfStream
*stream
= SWFDEC_AUDIO_SWF_STREAM (object
);
38 if (stream
->sprite
!= NULL
) {
39 g_object_unref (stream
->sprite
);
40 stream
->sprite
= NULL
;
43 G_OBJECT_CLASS (swfdec_audio_swf_stream_parent_class
)->dispose (object
);
47 swfdec_audio_swf_stream_head (SwfdecAudioSwfStream
*stream
, SwfdecBuffer
*buffer
)
50 SwfdecAudioFormat playback_format
, format
;
51 guint playback_codec
, codec
;
55 swfdec_bits_init (&bits
, buffer
);
57 /* we don't care about playback suggestions */
58 playback_codec
= swfdec_bits_getbits (&bits
, 4);
59 playback_format
= swfdec_audio_format_parse (&bits
);
60 SWFDEC_LOG (" suggested playback format: %s", swfdec_audio_format_to_string (playback_format
));
62 codec
= swfdec_bits_getbits (&bits
, 4);
63 format
= swfdec_audio_format_parse (&bits
);
64 n_samples
= swfdec_bits_get_u16 (&bits
);
65 SWFDEC_LOG (" codec: %u", codec
);
66 SWFDEC_LOG (" format: %s", swfdec_audio_format_to_string (format
));
67 SWFDEC_LOG (" samples: %u", n_samples
);
70 case SWFDEC_AUDIO_CODEC_UNDEFINED
:
71 if (swfdec_audio_format_is_16bit (format
)) {
72 SWFDEC_WARNING ("undefined endianness for s16 sound");
73 /* just assume LE and hope it works (FIXME: want a switch for this?) */
74 codec
= SWFDEC_AUDIO_CODEC_UNCOMPRESSED
;
77 case SWFDEC_AUDIO_CODEC_MP3
:
79 latency
= swfdec_bits_get_u16 (&bits
);
81 case SWFDEC_AUDIO_CODEC_ADPCM
:
82 case SWFDEC_AUDIO_CODEC_UNCOMPRESSED
:
83 case SWFDEC_AUDIO_CODEC_NELLYMOSER_8KHZ
:
84 case SWFDEC_AUDIO_CODEC_NELLYMOSER
:
87 SWFDEC_WARNING ("unknown codec %u", codec
);
91 swfdec_audio_stream_use_decoder (SWFDEC_AUDIO_STREAM (stream
), codec
, format
);
95 swfdec_audio_swf_stream_block (SwfdecAudioSwfStream
*stream
, SwfdecBuffer
*buffer
)
101 swfdec_bits_init (&bits
, buffer
);
103 /* FIXME: we want accessor functions for this */
104 if (SWFDEC_AUDIO_STREAM (stream
)->decoder
->codec
== SWFDEC_AUDIO_CODEC_MP3
) {
105 n_samples
= swfdec_bits_get_u16 (&bits
);
106 skip
= swfdec_bits_get_s16 (&bits
);
108 buffer
= swfdec_bits_get_buffer (&bits
, -1);
109 /* use this to write out the stream data to stdout - nice way to get an mp3 file :) */
110 //write (1, (void *) buffer->data, buffer->length);
115 static SwfdecBuffer
*
116 swfdec_audio_swf_stream_pull (SwfdecAudioStream
*audio
)
118 SwfdecAudioSwfStream
*stream
= SWFDEC_AUDIO_SWF_STREAM (audio
);
119 SwfdecBuffer
*buffer
;
123 if (!swfdec_sprite_get_action (stream
->sprite
, stream
->id
, &tag
, &buffer
)) {
124 if (swfdec_sprite_is_loaded (stream
->sprite
))
125 swfdec_audio_stream_done (audio
);
131 case SWFDEC_TAG_SOUNDSTREAMHEAD
:
132 case SWFDEC_TAG_SOUNDSTREAMHEAD2
:
133 swfdec_audio_swf_stream_head (stream
, buffer
);
135 case SWFDEC_TAG_SOUNDSTREAMBLOCK
:
136 buffer
= swfdec_audio_swf_stream_block (stream
, buffer
);
141 } while (tag
!= SWFDEC_TAG_SOUNDSTREAMBLOCK
);
147 swfdec_audio_swf_stream_class_init (SwfdecAudioSwfStreamClass
*klass
)
149 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
150 SwfdecAudioStreamClass
*stream_class
= SWFDEC_AUDIO_STREAM_CLASS (klass
);
152 object_class
->dispose
= swfdec_audio_swf_stream_dispose
;
154 stream_class
->pull
= swfdec_audio_swf_stream_pull
;
158 swfdec_audio_swf_stream_init (SwfdecAudioSwfStream
*stream
)
163 swfdec_audio_swf_stream_new (SwfdecPlayer
*player
, SwfdecSprite
*sprite
,
166 SwfdecAudioSwfStream
*stream
;
168 SwfdecBuffer
*buffer
;
170 g_return_val_if_fail (SWFDEC_IS_PLAYER (player
), NULL
);
171 g_return_val_if_fail (SWFDEC_IS_SPRITE (sprite
), NULL
);
173 stream
= g_object_new (SWFDEC_TYPE_AUDIO_SWF_STREAM
, NULL
);
174 stream
->sprite
= g_object_ref (sprite
);
180 if (!swfdec_sprite_get_action (sprite
, i
, &tag
, &buffer
)) {
181 g_assert_not_reached ();
183 if (tag
== SWFDEC_TAG_SOUNDSTREAMHEAD
||
184 tag
== SWFDEC_TAG_SOUNDSTREAMHEAD2
) {
185 swfdec_audio_swf_stream_head (stream
, buffer
);
189 SWFDEC_ERROR ("No SoundStreamHead tag found in sprite %u",
190 SWFDEC_CHARACTER (sprite
)->id
);
191 swfdec_audio_stream_done (SWFDEC_AUDIO_STREAM (stream
));
194 swfdec_audio_add (SWFDEC_AUDIO (stream
), player
);
195 return SWFDEC_AUDIO (stream
);