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

📄 wave_a.c

📁 MIDI解码程序(用VC编写)
💻 C
字号:
/*    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    wave_audio.c    Functions to output RIFF WAVE format data to a file or stdout.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#ifdef __W32__#include <io.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#ifdef STDC_HEADERS#include <string.h>#include <stdlib.h>#elif HAVE_STRINGS_H#include <strings.h>#endif#include <fcntl.h>#ifdef __FreeBSD__#include <stdio.h>#endif#include <ctype.h>#include "timidity.h"#include "common.h"#include "output.h"#include "controls.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.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 bytes);static int acntl(int request, void *arg);/* export the playback mode */#define dpm wave_play_modePlayMode dpm = {    DEFAULT_RATE,#ifdef LITTLE_ENDIAN    PE_16BIT|PE_SIGNED,#else    PE_16BIT|PE_SIGNED|PE_BYTESWAP,#endif    PF_PCM_STREAM,    -1,    {0,0,0,0,0},    "RIFF WAVE file", 'w',    NULL,    open_output,    close_output,    output_data,    acntl};#define UPDATE_HEADER_STEP (128*1024) /* 128KB */static uint32 bytes_output, next_bytes;static int already_warning_lseek;#ifdef __W32G__extern char *w32g_output_dir;extern int w32g_auto_output_mode;#endif/*************************************************************************/static char *orig_RIFFheader=  "RIFF" "\377\377\377\377"  "WAVE" "fmt " "\020\000\000\000" "\001\000"  /* 22: channels */ "\001\000"  /* 24: frequency */ "xxxx"  /* 28: bytes/second */ "xxxx"  /* 32: bytes/sample */ "\004\000"  /* 34: bits/sample */ "\020\000"  "data" "\377\377\377\377";/* We support follows WAVE format: * 8 bit unsigned pcm * 16 bit signed pcm (little endian) * A-law * U-law *//* Windows WAVE File Encoding Tags */#define WAVE_FORMAT_PCM       0x01#define WAVE_FORMAT_ALAW      0x06#define WAVE_FORMAT_MULAW     0x07static int wav_output_open(const char *fname){  int t;  char RIFFheader[44];  int fd;  if(strcmp(fname, "-") == 0)    fd = 1; /* data to 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;    }  }  /* Generate a (rather non-standard) RIFF header. We don't know yet     what the block lengths will be. We'll fix that at close if this     is a seekable file. */  memcpy(RIFFheader, orig_RIFFheader, 44);  if(dpm.encoding & PE_ALAW)    RIFFheader[20] = WAVE_FORMAT_ALAW;  else if(dpm.encoding & PE_ULAW)    RIFFheader[20] = WAVE_FORMAT_MULAW;  else    RIFFheader[20] = WAVE_FORMAT_PCM;  if(dpm.encoding & PE_MONO)    RIFFheader[22] = 1;  else    RIFFheader[22] = 2;  *((int *)(RIFFheader+24)) = LE_LONG(dpm.rate);  t = dpm.rate;  if(!(dpm.encoding & PE_MONO)) t *= 2;  if(dpm.encoding & PE_24BIT)   t *= 3;  else if(dpm.encoding & PE_16BIT)   t *= 2;  *((int *)(RIFFheader+28)) = LE_LONG(t);  if(dpm.encoding & PE_16BIT)    t = 2;  else if(dpm.encoding & PE_24BIT)    t = 3;  else    t = 1;  RIFFheader[34] = t * 8;  if(!(dpm.encoding & PE_MONO))    t *= 2;  RIFFheader[32] = t;  if(write(fd, RIFFheader, 44) == -1) {    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: write: %s",	      dpm.name, strerror(errno));    close_output();    return -1;  }  /* Reset the length counter */  bytes_output = 0;  next_bytes = bytes_output + UPDATE_HEADER_STEP;  already_warning_lseek = 0;  return fd;}static int auto_wav_output_open(const char *input_filename){  char *output_filename;#ifndef __W32G__  output_filename = create_auto_output_name(input_filename,"wav",NULL,0);#else  output_filename = create_auto_output_name(input_filename,"wav",w32g_output_dir,w32g_auto_output_mode);#endif  if(output_filename==NULL){	  return -1;  }  if((dpm.fd = wav_output_open(output_filename)) == -1) {    free(output_filename);    return -1;  }  if(dpm.name != NULL)    free(dpm.name);  dpm.name = output_filename;  ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Output %s", dpm.name);  return 0;}static int open_output(void){    int include_enc, exclude_enc;    include_enc = exclude_enc = 0;    if(dpm.encoding & (PE_16BIT | PE_24BIT))    {#ifdef LITTLE_ENDIAN	exclude_enc = PE_BYTESWAP;#else	include_enc = PE_BYTESWAP;#endif /* LITTLE_ENDIAN */	include_enc |= PE_SIGNED;    }	else if(!(dpm.encoding & (PE_ULAW|PE_ALAW)))    {	exclude_enc = PE_SIGNED;    }    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);#ifndef __W32G__    if(dpm.name == NULL) {      dpm.flag |= PF_AUTO_SPLIT_FILE;      dpm.name = NULL;    } else {      dpm.flag &= ~PF_AUTO_SPLIT_FILE;      if((dpm.fd = wav_output_open(dpm.name)) == -1)	return -1;    }#else	if(w32g_auto_output_mode>0){      dpm.flag |= PF_AUTO_SPLIT_FILE;      dpm.name = NULL;    } else {      dpm.flag &= ~PF_AUTO_SPLIT_FILE;      if((dpm.fd = wav_output_open(dpm.name)) == -1)		return -1;    }#endif    return 0;}static int update_header(void){    off_t save_point;    int32 tmp;    if(already_warning_lseek)	return 0;    save_point = lseek(dpm.fd, 0, SEEK_CUR);    if(save_point == -1 || lseek(dpm.fd, 4, SEEK_SET) == -1)    {	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		  "Warning: %s: %s: Can't make valid header",		  dpm.name, strerror(errno));	already_warning_lseek = 1;	return 0;    }    tmp = LE_LONG(bytes_output + 44 - 8);    if(write(dpm.fd, &tmp, 4) == -1)    {	lseek(dpm.fd, save_point, SEEK_SET);	return -1;    }    lseek(dpm.fd, 40, SEEK_SET);    tmp = LE_LONG(bytes_output);    write(dpm.fd, &tmp, 4);    lseek(dpm.fd, save_point, SEEK_SET);    ctl->cmsg(CMSG_INFO, VERB_DEBUG,	      "%s: Update RIFF WAVE header (size=%d)", dpm.name, bytes_output);    return 0;}static int output_data(char *buf, int32 bytes){    int n;    if(dpm.fd == -1)      return -1;    while(((n = write(dpm.fd, buf, bytes)) == -1) && errno == EINTR)	;    if(n == -1)    {	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",		  dpm.name, strerror(errno));	return -1;    }    bytes_output += bytes;#if UPDATE_HEADER_STEP > 0    if(bytes_output >= next_bytes)    {	if(update_header() == -1)	    return -1;	next_bytes = bytes_output + UPDATE_HEADER_STEP;    }#endif /* UPDATE_HEADER_STEP */    return n;}static void close_output(void){    if(dpm.fd != 1 && /* We don't close stdout */       dpm.fd != -1)    {	update_header();	close(dpm.fd);	dpm.fd = -1;    }}static int acntl(int request, void *arg){  switch(request) {  case PM_REQ_PLAY_START:    if(dpm.flag & PF_AUTO_SPLIT_FILE)      return auto_wav_output_open(current_file_info->filename);    break;  case PM_REQ_PLAY_END:    if(dpm.flag & PF_AUTO_SPLIT_FILE) {      close_output();      return 0;    }    break;  case PM_REQ_DISCARD:    return 0;  }  return -1;}

⌨️ 快捷键说明

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