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

📄 speex_a.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program 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 General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    speex_a.c	Written by Iwata <b6330015@kit.jp>    Functions to output Ogg Speex (*.ogg).*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#if HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#include <speex.h>#include <speex_header.h>#include <ogg/ogg.h>#include "timidity.h"#include "output.h"#include "controls.h"#include "timer.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#include "miditrace.h"static int open_output(void); /* 0=success, 1=warning, -1=fatal error */static void close_output(void);static int output_data(char *buf, int32 nbytes);static int acntl(int request, void *arg);/* export the playback mode */#define dpm speex_play_modePlayMode dpm = {  DEFAULT_RATE, PE_SIGNED|PE_16BIT, PF_PCM_STREAM,  -1,  {0},  "Ogg Speex", 'S',  NULL,  open_output,  close_output,  output_data,  acntl};#define MAX_FRAME_SIZE 2000#define MAX_FRAME_BYTES 2000typedef struct {  /* Ogg */  ogg_stream_state os;  ogg_page         og;  ogg_packet       op;  int              ogg_packetid;  /* Speex */  SpeexHeader      header;  SpeexBits        bits;  SpeexMode*       mode;  void*            state;  int              frame_size;  int              nframes;  int              channels;  /* state */  unsigned long    in_bytes;  unsigned long    out_bytes;  /* simple buffer */  float            *input;  int              input_idx;} Speex_ctx;static int ogg_seqnum = 0;static Speex_ctx *speex_ctx = NULL;typedef struct {  int quality;  int vbr;  int abr;  int vad;  int dtx;  int complexity;  int nframes;} Speex_options;Speex_options speex_options = {  8, /* quality */  0, /* vbr */  0, /* abr */  0, /* vad */  0, /* dtx */  3, /* complexity */  1  /* nframes */};/*  code from speexenc.c */static int speex_mode_preset(){  int rate = dpm.rate;  Speex_ctx *ctx = speex_ctx;  if (speex_ctx == NULL)    return 0;  if (ctx->mode == NULL) {    if (rate > 48000) {      ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		"sampling rate too high: %d Hz,\n"		"try down-sampling\n", rate);      return 0;    }    else if (rate > 25000) {      ctx->mode = &speex_uwb_mode;    }    else if (rate > 12500) {      ctx->mode = &speex_wb_mode;    }    else if (rate >= 6000) {      ctx->mode = &speex_nb_mode;    }    else {      ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		"Sampling rate too low: %d Hz\n", rate);      return 0;    }  }   if (rate != 8000 && rate != 16000 && rate != 32000)    ctl->cmsg(CMSG_WARNING, VERB_NORMAL,	      "Speex is only optimized for 8, 16 and 32 kHz.\n"	      "It will still work at %d Hz but your mileage may vary", rate);  return 1;}void speex_set_option_quality(int quality){  speex_options.quality = quality;  if (quality < 0)    speex_options.quality = 0;  if (10 < quality)    speex_options.quality = 10;}void speex_set_option_vbr(int vbr){  speex_options.vbr = vbr;}void speex_set_option_abr(int rate){  speex_options.abr = rate;}void speex_set_option_vad(int vad){  speex_options.vad = vad;}void speex_set_option_dtx(int dtx){  speex_options.dtx = dtx;}void speex_set_option_complexity(int complexity){  speex_options.complexity = complexity;  if (complexity < 0)    speex_options.complexity = 0;  if (10 < complexity)      speex_options.complexity = 10;}void speex_set_option_nframes(int nframes){  speex_options.nframes = nframes;  if (nframes < 1)    speex_options.nframes = 0;  if (10 < nframes)    speex_options.nframes = 10;}/*  Write an Ogg page to a file pointer  code from speexenc.c*/int oe_write_page(ogg_page *page, int fd){  int written = 0;  written += write(fd, page->header, page->header_len);  written += write(fd, page->body,   page->body_len);  return written;}#define writeint(buf, base, val) do { buf[base+3]=((val)>>24)&0xff; \                                      buf[base+2]=((val)>>16)&0xff; \                                      buf[base+1]=((val)>>8)&0xff; \                                      buf[base]=(val)&0xff; \                                 } while(0)void comment_init(char **comments, int* length, char *vendor_string){  int vendor_length = strlen(vendor_string);  int user_comment_list_length = 0;  int len= 4 + vendor_length + 4;  char *p = (char*)safe_malloc(len);  writeint(p, 0, vendor_length);  memcpy(p + 4, vendor_string, vendor_length);  writeint(p, 4 + vendor_length, user_comment_list_length);  *length = len;  *comments = p;}/*  Write header (format will change)  code from speexenc.c*/int write_ogg_header(Speex_ctx *ctx, int fd, char *comments){  int ret, result;  char *vendor_string = "Encoded with Timidity++-" VERSION "(compiled " __DATE__ ")";  int comments_length = strlen(comments);  comment_init(&comments, &comments_length, vendor_string);  ctx->op.packet = (unsigned char *)speex_header_to_packet(&ctx->header, (int*)&(ctx->op.bytes));  ctx->op.b_o_s = 1;  ctx->op.e_o_s = 0;  ctx->op.granulepos = 0;  ctx->op.packetno = 0;  ogg_stream_packetin(&ctx->os, &ctx->op);  free(ctx->op.packet);  ctx->op.packet = (unsigned char *)comments;  ctx->op.bytes = comments_length;  ctx->op.b_o_s = 0;  ctx->op.e_o_s = 0;  ctx->op.granulepos = 0;  ctx->op.packetno = 1;  ogg_stream_packetin(&ctx->os, &ctx->op);  while((result = ogg_stream_flush(&ctx->os, &ctx->og))) {    if(!result) break;    ret = oe_write_page(&ctx->og, fd);    if(ret != ctx->og.header_len + ctx->og.body_len) {      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "failed writing header to output Ogg stream\n");      return 1;    }    else      ctx->out_bytes += ret;  }  return 0;}static int speex_output_open(const char *fname, const char *comment){  Speex_ctx *ctx;  int fd;  if (!(speex_ctx = (Speex_ctx *)calloc(sizeof(Speex_ctx), 1))) {    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s", strerror(errno));    return -1;  }  ctx = speex_ctx;  /* init id */  ctx->in_bytes = ctx->out_bytes = 0;  ctx->ogg_packetid = -1;  ctx->channels = (dpm.encoding & PE_MONO) ? 1 : 2;  if(strcmp(fname, "-") == 0) {    fd = 1; /* data to stdout */    if(comment == NULL)      comment = "(stdout)";  } else {    /* Open the audio file */    fd = open(fname, FILE_OUTPUT_MODE);    if (fd < 0) {      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",                fname, strerror(errno));      return -1;    }  }  /*Initialize Ogg stream struct*/  if (ogg_seqnum == 0) {    srand(time(NULL));    ogg_seqnum = rand();  }  if (ogg_stream_init(&ctx->os, ogg_seqnum++) == -1) {    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Ogg stream init failed\n");    return -1;  }  if (!speex_mode_preset())    return -1;  speex_init_header(&ctx->header, dpm.rate, 1, ctx->mode);

⌨️ 快捷键说明

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