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

📄 sound.c

📁 swf 解码源程序, 纯C代码
💻 C
字号:
/* Swfdec * Copyright (C) 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 <libswfdec/swfdec.h>static gbooleanaudio_diff (SwfdecBuffer *compare, SwfdecBuffer *original, const char *filename){  guint i;  gint16 *comp_data, *org_data;    /* must hold since we are rendering it */  g_assert (compare->length % 2 == 0);  if (original->length % 2 != 0) {    g_print ("  ERROR: %s: filesize (%u bytes) not multiple of 4\n", filename,	original->length);    return FALSE;  }  if (compare->length != original->length) {    /* we allow to cut 0 bytes off the comparison files - at least as long as we render additional 0s */    for (i = compare->length; i < original->length; i++) {      if (compare->data[i] != 0)	break;    }    if (i < original->length) {      g_print ("  ERROR: %s: sample count doesn't match (is %u, should be %u)\n", 	  filename, compare->length / 4, original->length / 4);      goto dump;    }  }  comp_data = (gint16 *) compare->data;  org_data = (gint16 *) original->data;  for (i = 0; i < original->length / 2; i++) {    /* original data is little endian */    if (comp_data[i] != GINT16_FROM_LE (org_data[i])) {      g_print ("  ERROR: %s: data mismatch at sample %u (is %04hX, should be %04hX)\n",	  filename, i, comp_data[i], GINT16_FROM_LE (org_data[i]));      goto dump;    }  }  return TRUE;dump:  if (g_getenv ("SWFDEC_TEST_DUMP")) {    GError *error = NULL;    char *dump = g_strdup_printf ("%s.dump", filename);    /* convert to LE */    comp_data = (gint16 *) compare->data;    for (i = 0; i < compare->length / 2; i++) {      comp_data[i] = GINT16_TO_LE (comp_data[i]);    }    if (!g_file_set_contents (dump, (char *) compare->data, compare->length, &error)) {      g_print ("  ERROR: failed to dump contents: %s\n", error->message);      g_error_free (error);    }    g_free (dump);  }  return FALSE;}typedef struct {  SwfdecAudio *		audio;  char *		name;  SwfdecBufferQueue *	queue;} TestStream;typedef struct {  const char *	filename;  GList *	files;  GList *	streams;  guint		current_frame;  guint		current_frame_audio;  gboolean	success;} TestData;static voidaudio_added (SwfdecPlayer *player, SwfdecAudio *audio, TestData *data){  char *name = g_strdup_printf ("%s.%u.%u.raw", data->filename, data->current_frame, data->current_frame_audio);  GList *found = g_list_find_custom (data->files, name, (GCompareFunc) strcmp);  if (found == NULL) {    g_print ("  ERROR: %s wasn't found\n", name);    data->success = FALSE;  } else {    TestStream *stream = g_new0 (TestStream, 1);    stream->audio = audio;    stream->name = found->data;    stream->queue = swfdec_buffer_queue_new ();    data->files = g_list_delete_link (data->files, found);    data->streams = g_list_prepend (data->streams, stream);  }  g_free (name);}static gbooleanfinish_stream (TestStream *stream){  SwfdecBuffer *buffer, *file;  GError *error = NULL;  gboolean ret = TRUE;  buffer = swfdec_buffer_queue_pull (stream->queue, swfdec_buffer_queue_get_depth (stream->queue));  swfdec_buffer_queue_unref (stream->queue);  file = swfdec_buffer_new_from_file (stream->name, &error);  if (file) {    ret = audio_diff (buffer, file, stream->name);    swfdec_buffer_unref (file);  } else {    g_print ("  ERROR: %s\n", error->message);    g_error_free (error);    ret = FALSE;  }  swfdec_buffer_unref (buffer);  g_free (stream->name);  g_free (stream);  return ret;}static voidaudio_removed (SwfdecPlayer *player, SwfdecAudio *audio, TestData *data){  TestStream *stream = NULL;  GList *walk;  for (walk = data->streams; walk; walk = walk->next) {    stream = walk->data;    if (stream->audio == audio)      break;    stream = NULL;  }  if (stream) {    data->streams = g_list_remove (data->streams, stream);    data->success &= finish_stream (stream);  }}static voidrender_all_streams (SwfdecPlayer *player, guint msecs, guint n_samples, TestData *data){  GList *walk;    for (walk = data->streams; walk; walk = walk->next) {    TestStream *stream = walk->data;    SwfdecBuffer *buffer = swfdec_buffer_new_and_alloc0 (n_samples * 4);    swfdec_audio_render (stream->audio, (gint16 *) buffer->data, 0, n_samples);    swfdec_buffer_queue_push (stream->queue, buffer);  }}static gbooleanrun_test (const char *filename){  SwfdecLoader *loader;  SwfdecPlayer *player = NULL;  guint i, msecs;  GError *error = NULL;  char *dirname, *basename, *file;  const char *name;  GDir *dir;  GList *walk;  TestData data = { filename, NULL, NULL, 0, 0, TRUE };  g_print ("Testing %s:\n", filename);  dirname = g_path_get_dirname (filename);  basename = g_path_get_basename (filename);  dir = g_dir_open (dirname, 0, &error);  if (!dir) {    g_print ("  ERROR: %s\n", error->message);    g_error_free (error);    return FALSE;  }  while ((name = g_dir_read_name (dir))) {    if (!g_str_has_prefix (name, basename))      continue;    if (!g_str_has_suffix (name, ".raw"))      continue;    file = g_build_filename (dirname, name, NULL);    data.files = g_list_prepend (data.files, file);  }  g_dir_close (dir);  g_free (dirname);  g_free (basename);  loader = swfdec_file_loader_new (filename);  if (loader->error) {    g_print ("  ERROR: %s\n", loader->error);    g_object_unref (loader);    goto error;  }  player = swfdec_player_new (NULL);  g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), &data);  g_signal_connect (player, "audio-removed", G_CALLBACK (audio_removed), &data);  g_signal_connect (player, "advance", G_CALLBACK (render_all_streams), &data);  swfdec_player_set_loader (player, loader);  for (i = 0; i < 10; i++) {    data.current_frame++;    data.current_frame_audio = 0;    msecs = swfdec_player_get_next_event (player);    swfdec_player_advance (player, msecs);  }  g_object_unref (player);  for (walk = data.streams; walk; walk = walk->next) {    data.success &= finish_stream (walk->data);  }  g_list_free (data.streams);  if (data.files) {    g_print ("  ERROR: streams not played:\n");    for (walk = data.files; walk; walk = walk->next) {      g_print ("         %s\n", (char *) walk->data);      g_free (walk->data);    }    g_list_free (data.files);  }  if (data.success) {    g_print ("  OK\n");    return TRUE;  } else {    return FALSE;  }error:  if (player)    g_object_unref (player);  g_list_foreach (data.files, (GFunc) g_free, NULL);  g_list_free (data.files);  return FALSE;}intmain (int argc, char **argv){  GList *failed_tests = NULL;  swfdec_init ();  if (argc > 1) {    int i;    for (i = 1; i < argc; i++) {      if (!run_test (argv[i]))	failed_tests = g_list_prepend (failed_tests, g_strdup (argv[i]));;    }  } else {    GDir *dir;    char *name;    const char *path, *file;    /* automake defines this */    path = g_getenv ("srcdir");    if (path == NULL)      path = ".";    dir = g_dir_open (path, 0, NULL);    while ((file = g_dir_read_name (dir))) {      if (!g_str_has_suffix (file, ".swf"))	continue;      name = g_build_filename (path, file, NULL);      if (!run_test (name)) {	failed_tests = g_list_prepend (failed_tests, name);      } else {	g_free (name);      }    }    g_dir_close (dir);  }  if (failed_tests) {    GList *walk;    failed_tests = g_list_sort (failed_tests, (GCompareFunc) strcmp);    g_print ("\nFAILURES: %u\n", g_list_length (failed_tests));    for (walk = failed_tests; walk; walk = walk->next) {      g_print ("          %s\n", (char *) walk->data);      g_free (walk->data);    }    g_list_free (failed_tests);    return 1;  } else {    g_print ("\nEVERYTHING OK\n");    return 0;  }}

⌨️ 快捷键说明

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