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

📄 swfdec_codec_mad.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
字号:
/* Swfdec * Copyright (C) 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 <config.h>#include <liboil/liboil.h>#include <mad.h>#include "swfdec_codec_audio.h"#include "swfdec_debug.h"#include "swfdec_internal.h"typedef struct {  SwfdecAudioDecoder	decoder;  struct mad_stream	stream;  struct mad_frame	frame;  struct mad_synth	synth;  guint8		data[MAD_BUFFER_MDLEN * 3];  guint			data_len;  SwfdecBufferQueue *	queue;} MadData;static SwfdecBuffer *convert_synth_to_buffer (MadData *mdata){  SwfdecBuffer *buffer;  int n_samples;  short *data;  int i;  short c0,c1;#define MAD_F_TO_S16(x) (CLAMP (x, -MAD_F_ONE, MAD_F_ONE) >> (MAD_F_FRACBITS - 14))  n_samples = mdata->synth.pcm.length;  if (n_samples == 0) {    return NULL;  }  switch (mdata->synth.pcm.samplerate) {    case 11025:      n_samples *= 4;      break;    case 22050:      n_samples *= 2;      break;    case 44100:      break;    default:      SWFDEC_ERROR ("sample rate not handled (%d)",          mdata->synth.pcm.samplerate);      return NULL;  }  buffer = swfdec_buffer_new_and_alloc (n_samples * 2 * 2);  data = (gint16 *) buffer->data;  if (mdata->synth.pcm.samplerate == 11025) {    if (mdata->synth.pcm.channels == 2) {      for (i = 0; i < mdata->synth.pcm.length; i++) {        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);        c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);        *data++ = c0;        *data++ = c1;        *data++ = c0;        *data++ = c1;        *data++ = c0;        *data++ = c1;        *data++ = c0;        *data++ = c1;      }    } else {      for (i = 0; i < mdata->synth.pcm.length; i++) {        c0 = MAD_F_TO_S16( mdata->synth.pcm.samples[0][i]);        *data++ = c0;        *data++ = c0;        *data++ = c0;        *data++ = c0;        *data++ = c0;        *data++ = c0;        *data++ = c0;        *data++ = c0;      }    }  } else if (mdata->synth.pcm.samplerate == 22050) {    if (mdata->synth.pcm.channels == 2) {      for (i = 0; i < mdata->synth.pcm.length; i++) {        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);        c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);        *data++ = c0;        *data++ = c1;        *data++ = c0;        *data++ = c1;      }    } else {      for (i = 0; i < mdata->synth.pcm.length; i++) {        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);        *data++ = c0;        *data++ = c0;        *data++ = c0;        *data++ = c0;      }    }  } else if (mdata->synth.pcm.samplerate == 44100) {    if (mdata->synth.pcm.channels == 2) {      for (i = 0; i < mdata->synth.pcm.length; i++) {        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);        c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);        *data++ = c0;        *data++ = c1;      }    } else {      for (i = 0; i < mdata->synth.pcm.length; i++) {        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);        *data++ = c0;        *data++ = c0;      }    }  } else {    SWFDEC_ERROR ("sample rate not handled (%d)",        mdata->synth.pcm.samplerate);  }  return buffer;}static voidswfdec_audio_decoder_mad_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer){  MadData *data = (MadData *) dec;  SwfdecBuffer *out, *empty = NULL;  guint amount = 0, size;  if (buffer == NULL) {    buffer = empty = swfdec_buffer_new ();    empty->data = g_malloc0 (MAD_BUFFER_GUARD * 3);    empty->length = MAD_BUFFER_GUARD * 3;  }  //write (1, buffer->data, buffer->length);  //g_print ("buffer %p gave us %u bytes\n", buffer, buffer->length);  while (amount < buffer->length) {    size = MIN (buffer->length - amount, MAD_BUFFER_MDLEN * 3 - data->data_len);    memcpy (&data->data[data->data_len], buffer->data + amount, size);    //write (1, buffer->data + amount, size);    amount += size;    data->data_len += size;    mad_stream_buffer (&data->stream, data->data, data->data_len);    while (1) {      if (mad_frame_decode (&data->frame, &data->stream)) {	if (data->stream.error == MAD_ERROR_BUFLEN)	  break;	if (MAD_RECOVERABLE (data->stream.error)) {	  SWFDEC_LOG ("recoverable error 0x%04x", data->stream.error);	  continue;	}	SWFDEC_ERROR ("stream error 0x%04x", data->stream.error);	break;      }      mad_synth_frame (&data->synth, &data->frame);      out = convert_synth_to_buffer (data);      if (out)	swfdec_buffer_queue_push (data->queue, out);    }    if (data->stream.next_frame == NULL) {      data->data_len = 0;    } else {      data->data_len = data->stream.bufend - data->stream.next_frame;      memmove (data->data, data->stream.next_frame, data->data_len);    }  }  //g_print ("%u bytes left\n", data->data_len);  if (empty)    swfdec_buffer_unref (empty);}static voidswfdec_audio_decoder_mad_free (SwfdecAudioDecoder *dec){  MadData *data = (MadData *) dec;  mad_synth_finish (&data->synth);  mad_frame_finish (&data->frame);  mad_stream_finish (&data->stream);  swfdec_buffer_queue_unref (data->queue);  g_slice_free (MadData, data);}static SwfdecBuffer *swfdec_audio_decoder_mad_pull (SwfdecAudioDecoder *dec){  return swfdec_buffer_queue_pull_buffer (((MadData *) dec)->queue);}SwfdecAudioDecoder *swfdec_audio_decoder_mad_new (SwfdecAudioFormat type, gboolean width, SwfdecAudioOut format){  MadData *data;    if (type != SWFDEC_AUDIO_FORMAT_MP3)    return NULL;  data = g_slice_new (MadData);  data->decoder.out_format = SWFDEC_AUDIO_OUT_STEREO_44100;  data->decoder.push = swfdec_audio_decoder_mad_push;  data->decoder.pull = swfdec_audio_decoder_mad_pull;  data->decoder.free = swfdec_audio_decoder_mad_free;  mad_stream_init (&data->stream);  mad_frame_init (&data->frame);  mad_synth_init (&data->synth);  data->data_len = 0;  data->queue = swfdec_buffer_queue_new ();  return &data->decoder;}

⌨️ 快捷键说明

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