📄 gogo_a.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 gogo_a.c Functions to output mp3 by gogo.lib or gogo.dll.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include "interface.h"#include <stdio.h>#include <stdlib.h>#ifdef AU_GOGO#ifdef __W32__#include <io.h>#include <windows.h>#include <process.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <fcntl.h>/* #include <musenc.h> /* for gogo */#include <gogo/gogo.h> /* for gogo */#include "w32_gogo.h"#include "gogo_a.h"#include "timidity.h"#include "common.h"#include "output.h"#include "controls.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#if defined(__W32__) && !defined ( IA_W32GUI ) && !defined ( IA_W32G_SYN )#include "w32g.h" //for crt_beginthreadex();#endifstatic 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 gogo_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}, "MP3 GOGO", 'g', NULL, open_output, close_output, output_data, acntl};static char *tag_title = NULL;#if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )#if defined(_MSC_VER) || defined(__WATCOMC__)//typedef void (__cdecl *MSVC_BEGINTHREAD_START_ADDRESS)(void *);typedef LPTHREAD_START_ROUTINE MSVC_BEGINTHREAD_START_ADDRESS;#elif defined(_BORLANDC_)// typedef _USERENTRY (*BCC_BEGINTHREAD_START_ADDRESS)(void *);typedef LPTHREAD_START_ROUTINE BCC_BEGINTHREAD_START_ADDRESS;#endif// (HANDLE)crt_beginthreadex(LPSECURITY_ATTRIBUTES security, DWORD stack_size, LPTHREAD_START_ROUTINE start_address, LPVOID arglist, DWORD initflag, LPDWORD thrdaddr );#if defined(_MSC_VER) || defined(__WATCOMC__)#define crt_beginthreadex(security,stack_size,start_address,arglist,initflag,thrdaddr ) \(HANDLE)_beginthreadex((void *)security,(unsigned)stack_size,(MSVC_BEGINTHREAD_START_ADDRESS)start_address,(void *)arglist,(unsigned)initflag,(unsigned *)thrdaddr)#elif defined(_BORLANDC_)#define crt_beginthreadex(security,stack_size,start_address,arglist,initflag,thrdaddr ) \(HANDLE)_beginthreadNT((BCC_BEGINTHREAD_START_ADDRESS)start_address,(unsigned)stack_size,(void *)arglist,(void *)security_attrib,(unsigned long)create_flags,(unsigned long *)thread_id)#else#define crt_beginthreadex(security,stack_size,start_address,arglist,initflag,thrdaddr ) \(HANDLE)CreateThread((LPSECURITY_ATTRIBUTES)security,(DWORD)stack_size,(LPTHREAD_START_ROUTINE)start_address,(LPVOID)arglist,(DWORD)initflag,(LPDWORD)thrdaddr)#endifvolatile extern char *w32g_output_dir;volatile extern int w32g_auto_output_mode;extern int gogo_ConfigDialogInfoApply(void);#endif#ifdef __W32__volatile static HANDLE hMPGEthread = NULL;volatile static HANDLE hMutexgogo = NULL;volatile static DWORD dwMPGEthreadID = 0;#endifvolatile gogo_opts_t gogo_opts;/*************************************************************************/static int gogo_error(MERET rval){ switch(rval){ case ME_NOERR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : return normally (%d).",rval); break; case ME_EMPTYSTREAM: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : stream becomes empty (%d).",rval); break; case ME_HALTED: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : stopped by user (%d).",rval); break; case ME_INTERNALERROR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : internal error (%d).",rval); break; case ME_PARAMERROR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : parameters error (%d).",rval); break; case ME_NOFPU: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : no FPU (%d).",rval); break; case ME_INFILE_NOFOUND: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : can't open input file (%d).",rval); break; case ME_OUTFILE_NOFOUND: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : can't open output file (%d).",rval); break; case ME_FREQERROR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : frequency is not good (%d).",rval); break; case ME_BITRATEERROR : ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : bitrate is not good (%d).",rval); break; case ME_WAVETYPE_ERR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : WAV format is not good (%d).",rval); break; case ME_CANNOT_SEEK: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : can't seek (%d).",rval); break; case ME_BITRATE_ERR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : only for compatibility (%d).",rval); break; case ME_BADMODEORLAYER: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : mode/layer not good (%d).",rval); break; case ME_NOMEMORY: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : fail to allocate memory (%d).",rval); break; case ME_CANNOT_SET_SCOPE: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : thread error (%d).",rval); break; case ME_CANNOT_CREATE_THREAD: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : fail to create thear (%d).",rval); break; case ME_WRITEERROR: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : lack of capacity of disk (%d).",rval); break; default: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "gogo_a : unknown error (%d).",rval); break; } return 0;}/* mode 0,1: Default mode. 2: Remove the directory path of input_filename, then add output_dir. 3: Replace directory separator characters ('/','\',':') with '_', then add output_dir. */extern char *create_auto_output_name(const char *input_filename, char *ext_str, char *output_dir, int mode); volatile static int gogo_lock_flag = 0;static int gogo_lock(){#ifndef __W32__ while(gogo_lock_flag){ usleep(100); } gogo_lock_flag++; return 0;#else if(hMutexgogo==NULL){ hMutexgogo = CreateMutex(NULL,FALSE,NULL); if(hMutexgogo==NULL) return -1; } if(WaitForSingleObject(hMutexgogo,INFINITE)==WAIT_FAILED){ return -1; } return 0;#endif}static int gogo_unlock(){#ifndef __W32__ if(gogo_lock_flag) gogo_lock_flag--; return 0;#else if(hMutexgogo!=NULL){ ReleaseMutex(hMutexgogo); Sleep(0); } return 0;#endif}//volatile int32 gogo_buffer_size = 1024*1024;volatile int32 gogo_buffer_size = 1024*256;volatile static char *gogo_buffer = NULL; // loop buffervolatile static char *gogo_buffer_from = NULL;volatile static char *gogo_buffer_start = NULL;volatile static char *gogo_buffer_end = NULL;volatile static int32 gogo_buffer_cur_size = 0;volatile static int gogo_buffer_termination = 0;volatile int gogo_buffer_initflag = 0;static void gogo_buffer_init(void){ gogo_lock(); if(!gogo_buffer_initflag){ gogo_buffer = (char *)safe_malloc(sizeof(char)*(gogo_buffer_size+1)); gogo_buffer_from = gogo_buffer; gogo_buffer_start = gogo_buffer; gogo_buffer_end = gogo_buffer + gogo_buffer_size - 1; gogo_buffer_cur_size = 0; } gogo_buffer_initflag = 1; gogo_unlock();}static void gogo_buffer_reset(void){ gogo_lock(); if(!gogo_buffer_initflag) gogo_buffer_init(); gogo_buffer_from = gogo_buffer; gogo_buffer_cur_size = 0; gogo_unlock();}// 摨婜僲乕僠僃僢僋// gogo_buffer_cur_size 傑偱 buf 偵 gogo_buffer 偺撪梕傪 size 偩偗// 僐僺乕偡傞丅moveflag 偑偁傞偲偒偼丄僐僺乕偟偨暘偩偗// gogo_buffer_from 偲 gogo_buffer_cur_size 傪曄壔偝偣傞丅// 僐僺乕偟偨僒僀僘傪曉偡丅static int32 __gogo_buffer_copy(char *buf, int32 size, int moveflag){ int i; int32 size1, ret = 0; gogo_buffer_init(); if(size>gogo_buffer_cur_size) size = gogo_buffer_cur_size; for(i=0;i<2;i++){ size1 = gogo_buffer_end-gogo_buffer_from+1; if(size<=size1) size1 = size; memcpy(buf,(char *)gogo_buffer_from,size1); ret += size1; size -= size1; buf += size1; if(moveflag){ gogo_buffer_from += size1; if(gogo_buffer_from>=gogo_buffer_end+1) gogo_buffer_from = gogo_buffer_start; gogo_buffer_cur_size -= size1; } if(size<=0){ return ret; } } return ret;}// 摨婜僲乕僠僃僢僋// gogo_buffer_cur_size 傑偱 buf 偺撪梕傪 size 偩偗 gogo_buffer 偵// 奿擺偡傞丅奿擺偟偨僒僀僘傪曉偡丅static int32 __gogo_buffer_push(char *buf, int32 size){ int i; int32 size1, ret = 0; char *gogo_buffer_pointer; gogo_buffer_init(); if(size>gogo_buffer_size-gogo_buffer_cur_size) size = gogo_buffer_size-gogo_buffer_cur_size; if(gogo_buffer+gogo_buffer_size>gogo_buffer_from+gogo_buffer_cur_size){ gogo_buffer_pointer = (char *)gogo_buffer_from + gogo_buffer_cur_size; i = 0; } else { gogo_buffer_pointer = (char *)gogo_buffer_from+gogo_buffer_cur_size-gogo_buffer_size; i = 1; } for(;i<2;i++){ size1 = gogo_buffer_end-gogo_buffer_pointer+1; if(size<=size1) size1 = size; memcpy(gogo_buffer_pointer,buf,size1); ret += size1; size -= size1; buf += size1; gogo_buffer_cur_size += size1; gogo_buffer_pointer += size1; if(gogo_buffer_pointer>=gogo_buffer_end+1) gogo_buffer_pointer = (char *)gogo_buffer_start; if(size<=0) return ret; } return ret;}static int __cdecl gogoUserFunc(char *buf, unsigned long nLength ){ int flag = 0; gogo_buffer_init(); if(buf==NULL || nLength==0){ if(!gogo_buffer_termination) gogo_buffer_termination = 1; return ME_NOERR; } for(;;){ int32 size; if(gogo_buffer_termination<0){ return ME_EMPTYSTREAM; } if(gogo_lock()){ gogo_buffer_termination = -1; return ME_EMPTYSTREAM; } size = __gogo_buffer_copy(buf,nLength,1); buf += size; nLength -= size; if(nLength<=0){ gogo_unlock(); if(size>0) return ME_NOERR; else return ME_EMPTYSTREAM; } if(gogo_buffer_termination>0){ gogo_unlock(); if(size>0 && nLength>0){ if(dpm.encoding & PE_16BIT){ memset(buf,0x00,nLength); } else { memset(buf,0x80,nLength); } return ME_NOERR; } else { return ME_EMPTYSTREAM; } } if(gogo_buffer_termination<0){ gogo_unlock(); return ME_EMPTYSTREAM; } if(gogo_buffer_cur_size<=0){ gogo_unlock();#ifndef __W32__ usleep(100);#else Sleep(0); Sleep(100);#endif } else { gogo_unlock(); } }}void gogo_opts_reset(void){ gogo_opts.optENCODEMODE = -1; gogo_opts.optINPFREQ = -1; gogo_opts.optOUTFREQ = -1; gogo_opts.optSTARTOFFSET = -1; gogo_opts.optUSEPSY = -1; gogo_opts.optUSELPF16 = -1; gogo_opts.optUSEMMX = -1; gogo_opts.optUSE3DNOW = -1; gogo_opts.optUSEKNI = -1; gogo_opts.optUSEE3DNOW = -1; gogo_opts.optADDTAGnum = 0; // 捛壛偡傞偨傃偵僀儞僋儕儊儞僩偝傟傞偨傔僨僼僅儖僩偼0 gogo_opts.optEMPHASIS = -1; gogo_opts.optVBR = -1; gogo_opts.optCPU = -1; gogo_opts.optBYTE_SWAP = -1; gogo_opts.opt8BIT_PCM = -1; gogo_opts.optMONO_PCM = -1; gogo_opts.optTOWNS_SND = -1; gogo_opts.optTHREAD_PRIORITY = -10000; gogo_opts.optREADTHREAD_PRIORITY = -10000; gogo_opts.optOUTPUT_FORMAT = -1; gogo_opts.optENHANCEDFILTER_A = -1; gogo_opts.optENHANCEDFILTER_B = -1; gogo_opts.optVBRBITRATE_low = -1; gogo_opts.optVBRBITRATE_high = -1; gogo_opts.optMSTHRESHOLD_threshold = -1; gogo_opts.optMSTHRESHOLD_mspower = -1; gogo_opts.optVERIFY = -1; gogo_opts.optOUTPUTDIR[0] = '\0'; gogo_opts.optBITRATE1 = -1; gogo_opts.optBITRATE2 = -1;}static volatile int gogo_opts_initflag = 0;void gogo_opts_init(void){ gogo_lock(); if(!gogo_opts_initflag){ gogo_opts_initflag = 1; gogo_opts.optADDTAGnum = 0; gogo_opts.output_name[0] = '\0'; } gogo_opts_reset(); gogo_unlock();}void gogo_opts_reset_tag(void){ if (gogo_opts.optADDTAGnum >= 0) { int i; for (i = 0; i < gogo_opts.optADDTAGnum; i++) { gogo_opts.optADDTAG_len[i] = 0; if (gogo_opts.optADDTAG_buf[i] != NULL) { free(gogo_opts.optADDTAG_buf[i]); gogo_opts.optADDTAG_buf[i] = NULL; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -