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

📄 downsample.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 <glib.h>static voidusage (const char *app){  g_print ("usage : %s INFILE OUTFILE\n\n", app);}static gbooleandownsample_to_mono (gint16 *dest, const gint16 *src, guint n_samples){  guint i;  for (i = 0; i < n_samples; i++) {    if (src[0] != src[1]) {      g_print ("Info: file is stereo (channel data differs in sample %u\n", i);      return FALSE;    }    *dest = *src;    dest++;    src += 2;  }  g_print ("Info: conversion stereo => mono done\n");  return TRUE;}static gbooleandownsample_rate_mono (gint16 *dest, const gint16 *src, guint n_samples){  guint i;  int last;  last = src[0];  for (i = 0; i < n_samples; i++) {    if (src[0] != (last + src[1]) / 2) {      g_print ("Info: file cannot be downsampled, difference at sample %u\n", i);      return FALSE;    }    last = *dest = src[1];    dest++;    src += 2;  }  *dest = last;  return TRUE;}static voidconvert_le_be (gint16 *data, guint n_samples){  guint i;  for (i = 0; i < n_samples; i++) {    data[i] = GINT16_FROM_LE (data[i]);  }}static guintcut_silence (char *data, guint length, guint steps){  guint i, new;  new = length * steps;  while (new > 0) {    for (i = 0; i < steps; i++) {      if (data[new - 1 - i] != 0)	goto out;    }    new -= steps;  }out:  if (new / steps < length) {    g_print ("Info: Cut %u zero sample(s) at end of file\n", length - new / steps);  } else {    g_print ("Info: No zero samples cut at end of file\n");  }  return length;}intmain (int argc, char **argv){  char *data, *copy;  gsize length;  GError *error = NULL;  if (argc != 3) {    usage (argv[0]);    return 0;  }  if (!g_file_get_contents (argv[1], &data, &length, &error)) {    g_printerr ("Error: %s\n", error->message);    g_error_free (error);    return 1;  }  if (length % 4 != 0) {    g_printerr ("Error: File size is no multiple of 4\n");    g_free (data);    return 1;  }  length /= 4;  copy = g_malloc (length * 2);  convert_le_be ((gint16 *) data, length * 2);  if (downsample_to_mono ((gint16 *) copy, (gint16 *) data, length)) {    guint rate;    char *tmp = data;    data = copy;    copy = tmp;    for (rate = 44100; rate > 5512 && length % 2 == 0; rate /= 2) {      if (!downsample_rate_mono ((gint16 *) copy, (gint16 *) data, length / 2))	break;      length /= 2;      g_print ("Info: downsampling from %u => %u successful\n", rate, rate / 2);      tmp = data;      data = copy;      copy = tmp;    }    if (length % 2 != 0) {      g_print ("No more downsampling possible, sample count (%zu) is not multiple of 2\n", length);    }    length = cut_silence (data, length,  2);  } else {    length *= 2;    /* FIXME: implement */    g_assert_not_reached ();    length = cut_silence (data, length / 2,  4);  }  convert_le_be ((gint16 *) data, length);  length *= 2;  if (!g_file_set_contents (argv[2], data, length, &error)) {    g_printerr ("Error: %s\n", error->message);    g_error_free (error);    g_free (data);    return 1;  }  g_free (data);  g_free (copy);  return 0;}

⌨️ 快捷键说明

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