⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_sound.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> *		 2005-2006 Eric Anholt <eric@anholt.net> *		 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "swfdec_audio_internal.h"#include "swfdec_sound.h"#include "swfdec_bits.h"#include "swfdec_buffer.h"#include "swfdec_button.h"#include "swfdec_debug.h"#include "swfdec_sprite.h"#include "swfdec_swf_decoder.h"G_DEFINE_TYPE (SwfdecSound, swfdec_sound, SWFDEC_TYPE_CACHED)static voidswfdec_sound_unload (SwfdecCached *cached){  SwfdecSound * sound = SWFDEC_SOUND (cached);  if (sound->decoded) {    swfdec_buffer_unref (sound->decoded);    sound->decoded = NULL;  }}static voidswfdec_sound_dispose (GObject *object){  SwfdecSound * sound = SWFDEC_SOUND (object);  if (sound->encoded)    swfdec_buffer_unref (sound->encoded);  G_OBJECT_CLASS (swfdec_sound_parent_class)->dispose (object);}static voidswfdec_sound_class_init (SwfdecSoundClass * g_class){  GObjectClass *object_class = G_OBJECT_CLASS (g_class);  SwfdecCachedClass *cached_class = SWFDEC_CACHED_CLASS (g_class);  object_class->dispose = swfdec_sound_dispose;  cached_class->unload = swfdec_sound_unload;}static voidswfdec_sound_init (SwfdecSound * sound){}inttag_func_sound_stream_block (SwfdecSwfDecoder * s, guint tag){  SwfdecSound *sound;  SwfdecBuffer *chunk;  int n_samples;  int skip;  sound = SWFDEC_SOUND (s->parse_sprite->frames[s->parse_sprite->parse_frame].sound_head);  if (!sound) {    SWFDEC_WARNING ("no streaming sound block");    return SWFDEC_STATUS_OK;  }  n_samples = swfdec_bits_get_u16 (&s->b);  if (sound->format == SWFDEC_AUDIO_FORMAT_MP3) {    skip = swfdec_bits_get_s16 (&s->b);  } else {    skip = 0;  }  if (swfdec_bits_left (&s->b) == 0) {    SWFDEC_DEBUG ("empty sound block n_samples=%d skip=%d", n_samples,        skip);    chunk = NULL;    return SWFDEC_STATUS_OK;  } else {    chunk = swfdec_bits_get_buffer (&s->b, -1);    if (chunk == NULL) {      SWFDEC_ERROR ("empty sound chunk");      return SWFDEC_STATUS_OK;    }    SWFDEC_LOG ("got a buffer with %u samples, %d skip and %u bytes mp3 data", n_samples, skip,	chunk->length);    /* use this to write out the stream data to stdout - nice way to get an mp3 file :) */    //write (1, (void *) chunk->data, chunk->length);  }  swfdec_sprite_add_sound_chunk (s->parse_sprite, s->parse_sprite->parse_frame, chunk, skip, n_samples);  return SWFDEC_STATUS_OK;}inttag_func_define_sound (SwfdecSwfDecoder * s, guint tag){  SwfdecBits *b = &s->b;  int id;  int format;  int rate;  int size;  int type;  int n_samples;  SwfdecSound *sound;  id = swfdec_bits_get_u16 (b);  format = swfdec_bits_getbits (b, 4);  rate = swfdec_bits_getbits (b, 2);  size = swfdec_bits_getbits (b, 1);  type = swfdec_bits_getbits (b, 1);  n_samples = swfdec_bits_get_u32 (b);  sound = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_SOUND);  if (!sound)    return SWFDEC_STATUS_OK;  sound->width = size;  rate = 1 << (3 - rate);  sound->original_format = SWFDEC_AUDIO_OUT_GET (type ? 2 : 1, 44100 / rate);  sound->n_samples = n_samples;  SWFDEC_DEBUG ("%u samples, %sLE, %uch, %ukHz", n_samples,      size ? "S16" : "U8", SWFDEC_AUDIO_OUT_N_CHANNELS (sound->original_format),      SWFDEC_AUDIO_OUT_RATE (sound->original_format));  switch (format) {    case 0:      if (size == 1)	SWFDEC_WARNING ("undefined endianness for s16 sound");      /* just assume LE and hope it works (FIXME: want a switch for this?) */      /* fall through */    case 3:      sound->format = SWFDEC_AUDIO_FORMAT_UNCOMPRESSED;      sound->encoded = swfdec_bits_get_buffer (&s->b, -1);      break;    case 2:      sound->format = SWFDEC_AUDIO_FORMAT_MP3;      sound->skip = swfdec_bits_get_u16 (b);      sound->encoded = swfdec_bits_get_buffer (&s->b, -1);      break;    case 1:    case 5:    case 6:      sound->format = format;      sound->encoded = swfdec_bits_get_buffer (&s->b, -1);      break;    default:      SWFDEC_WARNING ("unknown format %d", format);      sound->format = format;  }  sound->n_samples *= rate;  return SWFDEC_STATUS_OK;}static SwfdecBuffer *swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioOut *format){  gpointer decoder;  SwfdecBuffer *tmp;  SwfdecBufferQueue *queue;  guint sample_bytes;  g_return_val_if_fail (SWFDEC_IS_SOUND (sound), NULL);  g_return_val_if_fail (format != NULL, NULL);  if (sound->decoded) {    swfdec_cached_use (SWFDEC_CACHED (sound));    *format = sound->decoded_format;    return sound->decoded;  }  if (sound->encoded == NULL)    return NULL;  decoder = swfdec_audio_decoder_new (sound->format, sound->width, sound->original_format);  if (decoder == NULL)    return NULL;  sound->decoded_format = swfdec_audio_decoder_get_format (decoder);  sample_bytes = 2 * SWFDEC_AUDIO_OUT_N_CHANNELS (sound->decoded_format);  /* FIXME: The size is only a guess */  swfdec_cached_load (SWFDEC_CACHED (sound), sound->n_samples * sample_bytes);  swfdec_audio_decoder_push (decoder, sound->encoded);  swfdec_audio_decoder_push (decoder, NULL);  queue = swfdec_buffer_queue_new ();  while ((tmp = swfdec_audio_decoder_pull (decoder)))    swfdec_buffer_queue_push (queue, tmp);  swfdec_audio_decoder_free (decoder);  tmp = swfdec_buffer_queue_pull (queue, swfdec_buffer_queue_get_depth (queue));  swfdec_buffer_queue_unref (queue);  SWFDEC_LOG ("after decoding, got %u samples, should get %u and skip %u",       tmp->length / sample_bytes, sound->n_samples, sound->skip);  if (sound->skip) {    SwfdecBuffer *tmp2 = swfdec_buffer_new_subbuffer (tmp, sound->skip * sample_bytes, 	tmp->length - sound->skip * sample_bytes);    swfdec_buffer_unref (tmp);    tmp = tmp2;  }  /* sound buffer may be bigger due to mp3 not having sample boundaries */  if (tmp->length * SWFDEC_AUDIO_OUT_GRANULARITY (sound->decoded_format)       > sound->n_samples * sample_bytes) {    SwfdecBuffer *tmp2 = swfdec_buffer_new_subbuffer (tmp, 0, 	sound->n_samples * sample_bytes / SWFDEC_AUDIO_OUT_GRANULARITY (sound->decoded_format));    swfdec_buffer_unref (tmp);    tmp = tmp2;  }  if (tmp->length * SWFDEC_AUDIO_OUT_GRANULARITY (sound->decoded_format)       < sound->n_samples * sample_bytes) {    /* we handle this case in swfdec_sound_render */    /* FIXME: this message is important when writing new codecs, so I made it a warning.     * It's probably not worth more than INFO for the usual case though */    SWFDEC_WARNING ("%u samples in %u bytes should be available, but only %u bytes are",	sound->n_samples / SWFDEC_AUDIO_OUT_GRANULARITY (sound->decoded_format), 	sound->n_samples * sample_bytes / SWFDEC_AUDIO_OUT_GRANULARITY (sound->decoded_format), 	tmp->length);  }  /* only assign here, the decoding code checks this variable */  sound->decoded = tmp;  *format = sound->decoded_format;  return sound->decoded;}inttag_func_sound_stream_head (SwfdecSwfDecoder * s, guint tag){  SwfdecBits *b = &s->b;  int format;  int rate;  int size;  int type;  int n_samples;  int latency;  SwfdecSound *sound;  /* we don't care about playback suggestions */  swfdec_bits_getbits (b, 8);  format = swfdec_bits_getbits (b, 4);  rate = swfdec_bits_getbits (b, 2);  size = swfdec_bits_getbits (b, 1);  type = swfdec_bits_getbits (b, 1);  n_samples = swfdec_bits_get_u16 (b);  sound = g_object_new (SWFDEC_TYPE_SOUND, NULL);  if (s->parse_sprite->frames[s->parse_sprite->parse_frame].sound_head)    g_object_unref (s->parse_sprite->frames[s->parse_sprite->parse_frame].sound_head);  s->parse_sprite->frames[s->parse_sprite->parse_frame].sound_head = sound;  sound->width = size;  sound->original_format = SWFDEC_AUDIO_OUT_GET (type ? 2 : 1, 44100 / (1 << (3 - rate)));  switch (format) {    case 0:      if (size == 1)	SWFDEC_WARNING ("undefined endianness for s16 sound");      /* just assume LE and hope it works (FIXME: want a switch for this?) */      /* fall through */    case 3:      sound->format = SWFDEC_AUDIO_FORMAT_UNCOMPRESSED;      break;    case 1:      sound->format = SWFDEC_AUDIO_FORMAT_ADPCM;      break;    case 2:      sound->format = SWFDEC_AUDIO_FORMAT_MP3;      /* latency seek */      latency = swfdec_bits_get_s16 (b);      break;    case 6:      sound->format = SWFDEC_AUDIO_FORMAT_NELLYMOSER;      break;    default:      SWFDEC_WARNING ("unknown format %d", format);      sound->format = format;  }  return SWFDEC_STATUS_OK;}void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -