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

📄 swfdec_audio_stream.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
字号:
/* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> *		 2005-2006 Eric Anholt <eric@anholt.net> *		      2006 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_stream.h"#include "swfdec_debug.h"#include "swfdec_sound.h"#include "swfdec_sprite.h"G_DEFINE_TYPE (SwfdecAudioStream, swfdec_audio_stream, SWFDEC_TYPE_AUDIO)static voidswfdec_audio_stream_dispose (GObject *object){  SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (object);  if (stream->decoder != NULL) {    SwfdecBuffer *buffer = swfdec_audio_codec_finish (stream->codec, stream->decoder);    stream->decoder = NULL;    if (buffer)      swfdec_buffer_unref (buffer);  }  g_queue_foreach (stream->playback_queue, (GFunc) swfdec_buffer_unref, NULL);  g_queue_free (stream->playback_queue);  G_OBJECT_CLASS (swfdec_audio_stream_parent_class)->dispose (object);}static SwfdecBuffer *swfdec_audio_stream_decode_one (SwfdecAudioStream *stream){  SwfdecSpriteFrame *frame;  SwfdecBuffer *buffer;  g_assert (!stream->done);  while (!stream->done) {    if (stream->current_frame >= stream->sprite->n_frames)      break;    frame = &stream->sprite->frames[stream->current_frame];    stream->current_frame++;    if (frame->sound_head != stream->sound)       break;    if (frame->sound_samples == 0)      continue;    /* FIXME: with this method and mad not giving out full samples, we end up      * putting silence too early */    if (frame->sound_block) {      buffer = swfdec_audio_codec_decode (stream->codec, stream->decoder, frame->sound_block);      if (buffer == NULL)	continue;    } else {      /* wanna speed this up by not allocating buffers? */      buffer = swfdec_buffer_new_and_alloc (frame->sound_samples * 4);      memset (buffer->data, 0, buffer->length);    }    g_queue_push_tail (stream->playback_queue, buffer);    return buffer;  }  buffer = swfdec_audio_codec_finish (stream->codec, stream->decoder);  stream->decoder = NULL;  stream->done = TRUE;  if (buffer)    g_queue_push_tail (stream->playback_queue, buffer);  return buffer;}static voidswfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,    guint start, guint n_samples){  SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (audio);  GList *walk;  guint samples;  SwfdecBuffer *buffer, *previous;  g_assert (start < G_MAXINT);  start += stream->playback_skip;  SWFDEC_LOG ("stream %p rendering offset %u, samples %u", stream, start, n_samples);  walk = g_queue_peek_head_link (stream->playback_queue);  previous = NULL;  while (n_samples) {    if (walk) {      buffer = walk->data;      walk = walk->next;    } else {      if (stream->done)	break;      buffer = swfdec_audio_stream_decode_one (stream);      if (!buffer)	break;    }    samples = swfdec_sound_buffer_get_n_samples (buffer, stream->format);    if (start) {      if (samples <= start) {	start -= samples;	continue;      }      samples -= start;      SWFDEC_LOG ("rendering %u samples, skipping %u",	  samples, start);    } else {      SWFDEC_LOG ("rendering %u samples", samples);    }    samples = MIN (samples, n_samples);    swfdec_sound_buffer_render (dest, buffer, stream->format, previous, start, samples);    start = 0;    n_samples -= samples;    dest += 2 * samples;    previous = buffer;  }}static guintswfdec_audio_stream_iterate (SwfdecAudio *audio, guint remove){  SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (audio);  SwfdecBuffer *buffer;  stream->playback_skip += remove;  buffer = g_queue_peek_head (stream->playback_queue);  while (buffer && stream->playback_skip >= 	 swfdec_sound_buffer_get_n_samples (buffer, stream->format) 	 + SWFDEC_AUDIO_OUT_GRANULARITY (stream->format)) {    buffer = g_queue_pop_head (stream->playback_queue);    SWFDEC_LOG ("removing buffer with %u samples", 	swfdec_sound_buffer_get_n_samples (buffer, stream->format));    stream->playback_skip -= swfdec_sound_buffer_get_n_samples (buffer, stream->format);    swfdec_buffer_unref (buffer);    buffer = g_queue_peek_head (stream->playback_queue);  }    if (!stream->done) {    return G_MAXUINT;  } else {    GList *walk;    guint ret = 0;        for (walk = g_queue_peek_head_link (stream->playback_queue); walk; walk = walk->next) {      ret += swfdec_sound_buffer_get_n_samples (walk->data, stream->format);    }    return ret - stream->playback_skip;  }}static voidswfdec_audio_stream_class_init (SwfdecAudioStreamClass *klass){  GObjectClass *object_class = G_OBJECT_CLASS (klass);  SwfdecAudioClass *audio_class = SWFDEC_AUDIO_CLASS (klass);  object_class->dispose = swfdec_audio_stream_dispose;  audio_class->iterate = swfdec_audio_stream_iterate;  audio_class->render = swfdec_audio_stream_render;}static voidswfdec_audio_stream_init (SwfdecAudioStream *stream){  stream->playback_queue = g_queue_new ();}SwfdecAudio *swfdec_audio_stream_new (SwfdecPlayer *player, SwfdecSprite *sprite, guint start_frame){  SwfdecAudioStream *stream;  SwfdecSpriteFrame *frame;    stream = g_object_new (SWFDEC_TYPE_AUDIO_STREAM, NULL);  SWFDEC_DEBUG ("new audio stream for sprite %d, starting at %u",       SWFDEC_CHARACTER (sprite)->id, start_frame);  stream->sprite = sprite;  frame = &sprite->frames[start_frame];  g_assert (frame->sound_head);  stream->sound = frame->sound_head;  stream->playback_skip = frame->sound_skip;  stream->current_frame = start_frame;  stream->codec = swfdec_codec_get_audio (stream->sound->format);  if (stream->codec)    stream->decoder = swfdec_audio_codec_init (stream->codec, 	stream->sound->width, stream->sound->original_format);  if (stream->decoder)    stream->format = swfdec_audio_codec_get_format (stream->codec, stream->decoder);  swfdec_audio_add (SWFDEC_AUDIO (stream), player);  return SWFDEC_AUDIO (stream);}

⌨️ 快捷键说明

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