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

📄 playmidi.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.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    playmidi.c -- random stuff in need of rearrangement*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#ifdef __W32__#include "interface.h"#endif#include <stdio.h>#include <stdlib.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <math.h>#ifdef __W32__#include <windows.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#include "timidity.h"#include "common.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#include "output.h"#include "mix.h"#include "controls.h"#include "miditrace.h"#include "recache.h"#include "arc.h"#include "reverb.h"#include "wrd.h"#include "aq.h"#include "freq.h"#include "quantity.h"extern void convert_mod_to_midi_file(MidiEvent * ev);#define ABORT_AT_FATAL 1 /*#################*/#define MYCHECK(s) do { if(s == 0) { printf("## L %d\n", __LINE__); abort(); } } while(0)extern VOLATILE int intr;/* #define SUPPRESS_CHANNEL_LAYER */#ifdef SOLARIS/* shut gcc warning up */int usleep(unsigned int useconds);#endif#ifdef SUPPORT_SOUNDSPEC#include "soundspec.h"#endif /* SUPPORT_SOUNDSPEC */#include "tables.h"#define PLAY_INTERLEAVE_SEC		1.0#define PORTAMENTO_TIME_TUNING		(1.0 / 5000.0)#define PORTAMENTO_CONTROL_RATIO	256	/* controls per sec */#define DEFAULT_CHORUS_DELAY1		0.02#define DEFAULT_CHORUS_DELAY2		0.003#define CHORUS_OPPOSITE_THRESHOLD	32#define CHORUS_VELOCITY_TUNING1		0.7#define CHORUS_VELOCITY_TUNING2		0.6#define EOT_PRESEARCH_LEN		32#define SPEED_CHANGE_RATE		1.0594630943592953  /* 2^(1/12) *//* Undefine if you don't want to use auto voice reduce implementation */#define REDUCE_VOICE_TIME_TUNING	(play_mode->rate/5) /* 0.2 sec */#ifdef REDUCE_VOICE_TIME_TUNINGstatic int max_good_nv = 1;static int min_bad_nv = 256;static int32 ok_nv_total = 32;static int32 ok_nv_counts = 1;static int32 ok_nv_sample = 0;static int ok_nv = 32;static int old_rate = -1;#endifstatic int midi_streaming = 0;int volatile stream_max_compute = 500; /* compute time limit (in msec) when streaming */static int prescanning_flag;static int32 midi_restart_time = 0;Channel channel[MAX_CHANNELS];int max_voices = DEFAULT_VOICES;Voice *voice = NULL;int8 current_keysig = 0;int8 current_temper_keysig = 0;int temper_adj = 0;int8 opt_init_keysig = 8;int8 opt_force_keysig = 8;int32 current_play_tempo = 500000;int opt_realtime_playing = 0;int reduce_voice_threshold = -1;static MBlockList playmidi_pool;int check_eot_flag;int special_tonebank = -1;int default_tonebank = 0;int playmidi_seek_flag = 0;int play_pause_flag = 0;static int file_from_stdin;int key_adjust = 0;FLOAT_T tempo_adjust = 1.0;int opt_pure_intonation = 0;int current_freq_table = 0;int current_temper_freq_table = 0;static void set_reverb_level(int ch, int level);static int make_rvid_flag = 0; /* For reverb optimization *//* Ring voice id for each notes.  This ID enables duplicated note. */static uint8 vidq_head[128 * MAX_CHANNELS], vidq_tail[128 * MAX_CHANNELS];#ifdef MODULATION_WHEEL_ALLOWint opt_modulation_wheel = 1;#elseint opt_modulation_wheel = 0;#endif /* MODULATION_WHEEL_ALLOW */#ifdef PORTAMENTO_ALLOWint opt_portamento = 1;#elseint opt_portamento = 0;#endif /* PORTAMENTO_ALLOW */#ifdef NRPN_VIBRATO_ALLOWint opt_nrpn_vibrato = 1;#elseint opt_nrpn_vibrato = 0;#endif /* NRPN_VIBRATO_ALLOW */#ifdef REVERB_CONTROL_ALLOWint opt_reverb_control = 1;#else#ifdef FREEVERB_CONTROL_ALLOWint opt_reverb_control = 3;#elseint opt_reverb_control = 0;#endif /* FREEVERB_CONTROL_ALLOW */#endif /* REVERB_CONTROL_ALLOW */#ifdef CHORUS_CONTROL_ALLOWint opt_chorus_control = 1;#elseint opt_chorus_control = 0;#endif /* CHORUS_CONTROL_ALLOW */#ifdef SURROUND_CHORUS_ALLOWint opt_surround_chorus = 1;#elseint opt_surround_chorus = 0;#endif /* SURROUND_CHORUS_ALLOW */#ifdef GM_CHANNEL_PRESSURE_ALLOWint opt_channel_pressure = 1;#elseint opt_channel_pressure = 0;#endif /* GM_CHANNEL_PRESSURE_ALLOW */#ifdef VOICE_CHAMBERLIN_LPF_ALLOWint opt_lpf_def = 1;#else#ifdef VOICE_MOOG_LPF_ALLOWint opt_lpf_def = 2;#elseint opt_lpf_def = 0;#endif /* VOICE_MOOG_LPF_ALLOW */#endif /* VOICE_CHAMBERLIN_LPF_ALLOW */#ifdef OVERLAP_VOICE_ALLOWint opt_overlap_voice_allow = 1;#elseint opt_overlap_voice_allow = 0;#endif /* OVERLAP_VOICE_ALLOW */#ifdef TEMPER_CONTROL_ALLOWint opt_temper_control = 1;#elseint opt_temper_control = 0;#endif /* TEMPER_CONTROL_ALLOW */int opt_tva_attack = 0;	/* attack envelope control */int opt_tva_decay = 0;	/* decay envelope control */int opt_tva_release = 0;	/* release envelope control */int opt_delay_control = 0;	/* CC#94 delay(celeste) effect control */int opt_eq_control = 0;		/* channel equalizer control */int opt_insertion_effect = 0;	/* insertion effect control */int opt_drum_effect = 0;	/* drumpart effect control */int32 opt_drum_power = 100;		/* coef. of drum amplitude */int opt_amp_compensation = 0;int opt_modulation_envelope = 0;int opt_pan_delay = 0;	/* phase difference between left ear and right ear. */int opt_user_volume_curve = 0;int opt_default_module = MODULE_TIMIDITY_DEFAULT;int voices=DEFAULT_VOICES, upper_voices;int32    control_ratio=0,    amplification=DEFAULT_AMPLIFICATION;static FLOAT_T    master_volume;static int32 master_volume_ratio = 0xFFFF;ChannelBitMask default_drumchannel_mask;ChannelBitMask default_drumchannels;ChannelBitMask drumchannel_mask;ChannelBitMask drumchannels;int adjust_panning_immediately = 1;int auto_reduce_polyphony = 1;double envelope_modify_rate = 1.0;int reduce_quality_flag = 0;int no_4point_interpolation = 0;char* pcm_alternate_file = NULL; /* NULL or "none": Nothing (default)				  * "auto": Auto select				  * filename: Use it				  */static int32 lost_notes, cut_notes;static int32 common_buffer[AUDIO_BUFFER_SIZE*2], /* stereo samples */             *buffer_pointer;static int16 wav_buffer[AUDIO_BUFFER_SIZE*2];static int32 buffered_count;static char *reverb_buffer = NULL; /* MAX_CHANNELS*AUDIO_BUFFER_SIZE*8 */#ifdef USE_DSP_EFFECTstatic int32 insertion_effect_buffer[AUDIO_BUFFER_SIZE * 2];#endif /* USE_DSP_EFFECT */#define VIBRATO_DEPTH_MAX 384	/* 600 cent */static MidiEvent *event_list;static MidiEvent *current_event;static int32 sample_count;	/* Length of event_list */int32 current_sample;		/* Number of calclated samples */int note_key_offset = 0;		/* For key up/down */FLOAT_T midi_time_ratio = 1.0;	/* For speed up/down */ChannelBitMask channel_mute;	/* For channel mute */int temper_type_mute;			/* For temperament type mute *//* for auto amplitude compensation */static int mainvolume_max; /* maximum value of mainvolume */static double compensation_ratio = 1.0; /* compensation ratio */static int find_samples(MidiEvent *, int *);static int select_play_sample(Sample *, int, int *, int *, MidiEvent *);static double get_play_note_ratio(int, int);static int find_voice(MidiEvent *);static void update_portamento_controls(int ch);static void update_rpn_map(int ch, int addr, int update_now);static void ctl_prog_event(int ch);static void ctl_timestamp(void);static void ctl_updatetime(int32 samples);static void ctl_pause_event(int pause, int32 samples);static void update_legato_controls(int ch);static void update_channel_freq(int ch);static void set_single_note_tuning(int, int, int, int);static void set_user_temper_entry(int, int, int);void recompute_bank_parameter(int, int);static void init_voice_filter(int);/* XG Part EQ */void init_part_eq_xg(struct part_eq_xg *);void recompute_part_eq_xg(struct part_eq_xg *);/* MIDI controllers (MW, Bend, CAf, PAf,...) */static void init_midi_controller(midi_controller *);static float get_midi_controller_amp(midi_controller *);static float get_midi_controller_filter_cutoff(midi_controller *);static float get_midi_controller_filter_depth(midi_controller *);static int32 get_midi_controller_pitch(midi_controller *);static int16 get_midi_controller_pitch_depth(midi_controller *);static int16 get_midi_controller_amp_depth(midi_controller *);/* Rx. ~ (Rcv ~) */static void init_rx(int);static void set_rx(int, int32, int);static int32 get_rx(int, int32);static void init_rx_drum(struct DrumParts *);static void set_rx_drum(struct DrumParts *, int32, int);static int32 get_rx_drum(struct DrumParts *, int32);#define IS_SYSEX_EVENT_TYPE(event) ((event)->type == ME_NONE || (event)->type >= ME_RANDOM_PAN || (event)->b == SYSEX_TAG)static char *event_name(int type){#define EVENT_NAME(X) case X: return #X	switch (type) {	EVENT_NAME(ME_NONE);	EVENT_NAME(ME_NOTEOFF);	EVENT_NAME(ME_NOTEON);	EVENT_NAME(ME_KEYPRESSURE);	EVENT_NAME(ME_PROGRAM);	EVENT_NAME(ME_CHANNEL_PRESSURE);	EVENT_NAME(ME_PITCHWHEEL);	EVENT_NAME(ME_TONE_BANK_MSB);	EVENT_NAME(ME_TONE_BANK_LSB);	EVENT_NAME(ME_MODULATION_WHEEL);	EVENT_NAME(ME_BREATH);	EVENT_NAME(ME_FOOT);	EVENT_NAME(ME_MAINVOLUME);	EVENT_NAME(ME_BALANCE);	EVENT_NAME(ME_PAN);	EVENT_NAME(ME_EXPRESSION);	EVENT_NAME(ME_SUSTAIN);	EVENT_NAME(ME_PORTAMENTO_TIME_MSB);	EVENT_NAME(ME_PORTAMENTO_TIME_LSB);	EVENT_NAME(ME_PORTAMENTO);	EVENT_NAME(ME_PORTAMENTO_CONTROL);	EVENT_NAME(ME_DATA_ENTRY_MSB);	EVENT_NAME(ME_DATA_ENTRY_LSB);	EVENT_NAME(ME_SOSTENUTO);	EVENT_NAME(ME_SOFT_PEDAL);	EVENT_NAME(ME_LEGATO_FOOTSWITCH);	EVENT_NAME(ME_HOLD2);	EVENT_NAME(ME_HARMONIC_CONTENT);	EVENT_NAME(ME_RELEASE_TIME);	EVENT_NAME(ME_ATTACK_TIME);	EVENT_NAME(ME_BRIGHTNESS);	EVENT_NAME(ME_REVERB_EFFECT);	EVENT_NAME(ME_TREMOLO_EFFECT);	EVENT_NAME(ME_CHORUS_EFFECT);	EVENT_NAME(ME_CELESTE_EFFECT);	EVENT_NAME(ME_PHASER_EFFECT);	EVENT_NAME(ME_RPN_INC);	EVENT_NAME(ME_RPN_DEC);	EVENT_NAME(ME_NRPN_LSB);	EVENT_NAME(ME_NRPN_MSB);	EVENT_NAME(ME_RPN_LSB);	EVENT_NAME(ME_RPN_MSB);	EVENT_NAME(ME_ALL_SOUNDS_OFF);	EVENT_NAME(ME_RESET_CONTROLLERS);	EVENT_NAME(ME_ALL_NOTES_OFF);	EVENT_NAME(ME_MONO);	EVENT_NAME(ME_POLY);#if 0	EVENT_NAME(ME_VOLUME_ONOFF);		/* Not supported */#endif	EVENT_NAME(ME_SCALE_TUNING);	EVENT_NAME(ME_BULK_TUNING_DUMP);	EVENT_NAME(ME_SINGLE_NOTE_TUNING);	EVENT_NAME(ME_RANDOM_PAN);	EVENT_NAME(ME_SET_PATCH);	EVENT_NAME(ME_DRUMPART);	EVENT_NAME(ME_KEYSHIFT);	EVENT_NAME(ME_PATCH_OFFS);	EVENT_NAME(ME_TEMPO);	EVENT_NAME(ME_CHORUS_TEXT);	EVENT_NAME(ME_LYRIC);	EVENT_NAME(ME_GSLCD);	EVENT_NAME(ME_MARKER);	EVENT_NAME(ME_INSERT_TEXT);	EVENT_NAME(ME_TEXT);	EVENT_NAME(ME_KARAOKE_LYRIC);	EVENT_NAME(ME_MASTER_VOLUME);	EVENT_NAME(ME_RESET);	EVENT_NAME(ME_NOTE_STEP);	EVENT_NAME(ME_TIMESIG);	EVENT_NAME(ME_KEYSIG);	EVENT_NAME(ME_TEMPER_KEYSIG);	EVENT_NAME(ME_TEMPER_TYPE);	EVENT_NAME(ME_MASTER_TEMPER_TYPE);	EVENT_NAME(ME_USER_TEMPER_ENTRY);	EVENT_NAME(ME_SYSEX_LSB);	EVENT_NAME(ME_SYSEX_MSB);	EVENT_NAME(ME_SYSEX_GS_LSB);	EVENT_NAME(ME_SYSEX_GS_MSB);	EVENT_NAME(ME_SYSEX_XG_LSB);	EVENT_NAME(ME_SYSEX_XG_MSB);	EVENT_NAME(ME_WRD);	EVENT_NAME(ME_SHERRY);	EVENT_NAME(ME_BARMARKER);	EVENT_NAME(ME_STEP);	EVENT_NAME(ME_LAST);	EVENT_NAME(ME_EOT);	}	return "Unknown";#undef EVENT_NAME}/*! convert Hz to internal vibrato control ratio. */static FLOAT_T cnv_Hz_to_vib_ratio(FLOAT_T freq){	return ((FLOAT_T)(play_mode->rate) / (freq * 2.0f * VIBRATO_SAMPLE_INCREMENTS));}static void adjust_amplification(void){    /* compensate master volume */    master_volume = (double)(amplification) / 100.0 *	((double)master_volume_ratio * (compensation_ratio/0xFFFF));}static int new_vidq(int ch, int note){    int i;    if(opt_overlap_voice_allow)    {	i = ch * 128 + note;	return vidq_head[i]++;    }    return 0;}static int last_vidq(int ch, int note){    int i;    if(opt_overlap_voice_allow)    {	i = ch * 128 + note;	if(vidq_head[i] == vidq_tail[i])	{	    ctl->cmsg(CMSG_WARNING, VERB_DEBUG_SILLY,		      "channel=%d, note=%d: Voice is already OFF", ch, note);	    return -1;	}	return vidq_tail[i]++;    }    return 0;}static void reset_voices(void){    int i;

⌨️ 快捷键说明

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