OSDN Git Service

Support for Delay L,C,R.
authorSaito <saito2@digitalme.com>
Fri, 5 Mar 2004 10:12:26 +0000 (10:12 +0000)
committerSaito <saito2@digitalme.com>
Fri, 5 Mar 2004 10:12:26 +0000 (10:12 +0000)
ChangeLog
timidity/playmidi.c
timidity/readmidi.c
timidity/readmidi.h
timidity/reverb.c
timidity/reverb.h

index cbf9c26..f0c9a63 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
 
        * timidity/sndfont.c:
          Fix for Soundfonts with strange loop points.
+       * timidity/playmidi.c, timidity/readmidi.[ch], timidity/reverb.[ch]:
+         Support for XG variation effect: Delay L,C,R.
 
 2004-03-05  TAMUKI Shoichi <tamuki@linet.gr.jp>
 
index 2cf7c32..ab1d172 100644 (file)
@@ -1867,10 +1867,10 @@ static int find_samples(MidiEvent *e, int *vlist)
                instrument_map(channel[ch].mapID, &bank, &note);
                if (! (ip = play_midi_load_instrument(1, bank, note)))
                        return 0;       /* No instrument? Then we can't play. */
-               if (ip->type == INST_GUS && ip->samples != 1)
+               /* if (ip->type == INST_GUS && ip->samples != 1)
                        ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
                                        "Strange: percussion instrument with %d samples!",
-                                       ip->samples);
+                                       ip->samples); */
                /* "keynum" of SF2, and patch option "note=" */
                if (ip->sample->note_to_use)
                        note = ip->sample->note_to_use;
@@ -4958,7 +4958,6 @@ static void play_midi_prescan(MidiEvent *ev)
 
          case ME_RESET:
            change_system_mode(ev->a);
-               init_all_effect_xg();
            reset_midi(0);
            break;
 
@@ -5700,7 +5699,6 @@ static void seek_forward(int32 until_time)
 
          case ME_RESET:
            change_system_mode(current_event->a);
-               init_all_effect_xg();
            reset_midi(0);
            break;
 
index dff5fbb..a41ff56 100644 (file)
@@ -102,6 +102,7 @@ void init_reverb_status_gs(void);
 void init_eq_status_gs(void);
 void init_insertion_effect_gs(void);
 void init_multi_eq_xg(void);
+static void init_all_effect_xg(void);
 
 /* MIDI ports will be merged in several channels in the future. */
 int midi_port_number;
@@ -4569,6 +4570,7 @@ void change_system_mode(int mode)
        vol_table = gs_vol_table;
        break;
       case XG_SYSTEM_MODE:
+    if (play_system_mode != XG_SYSTEM_MODE) {init_all_effect_xg();}
        play_system_mode = XG_SYSTEM_MODE;
        vol_table = xg_vol_table;
        break;
@@ -4578,6 +4580,7 @@ void change_system_mode(int mode)
                play_system_mode = GS_SYSTEM_MODE;
                break;
        } else if (is_xg_module()) {
+               if (play_system_mode != XG_SYSTEM_MODE) {init_all_effect_xg();}
                play_system_mode = XG_SYSTEM_MODE;
                break;
        }
@@ -4588,6 +4591,7 @@ void change_system_mode(int mode)
            vol_table = gs_vol_table;
            break;
          case 0x43:
+               if (play_system_mode != XG_SYSTEM_MODE) {init_all_effect_xg();}
            play_system_mode = XG_SYSTEM_MODE;
            vol_table = xg_vol_table;
            break;
@@ -6604,9 +6608,14 @@ void realloc_effect_xg(struct effect_xg_t *st)
 
        free_effect_list(st->ef);
        st->ef = NULL;
+       st->use_msb = 0;
 
        switch(type_msb) {
-       /* case delay: use_msb = 1;*/
+       case 0x05:
+               st->use_msb = 1;
+               st->ef = push_effect(st->ef, EFFECT_DELAY_LCR);
+               st->ef = push_effect(st->ef, EFFECT_DELAY_EQ2);
+               break;
        case 0x41:
        case 0x42:
                st->ef = push_effect(st->ef, EFFECT_CHORUS);
@@ -6654,10 +6663,9 @@ static void init_effect_xg(struct effect_xg_t *st)
 }
 
 /*! initialize XG effect parameters */
-void init_all_effect_xg(void)
+static void init_all_effect_xg(void)
 {
        int i;
-       if (play_system_mode != XG_SYSTEM_MODE) {return;}
        init_effect_xg(&reverb_status_xg);
        reverb_status_xg.type_msb = 0x01;
        reverb_status_xg.connection = XG_CONN_SYSTEM_REVERB;
index a0778fa..245d64f 100644 (file)
@@ -163,7 +163,6 @@ extern void recompute_multi_eq_xg(void);
 extern void set_multi_eq_type_xg(int);
 extern void realloc_effect_xg(struct effect_xg_t *st);
 extern void recompute_effect_xg(struct effect_xg_t *st);
-extern void init_all_effect_xg(void);
 
 extern void recompute_userdrum(int bank, int prog);
 extern void free_userdrum();
index 7081077..b68f63b 100644 (file)
@@ -3286,6 +3286,113 @@ static void do_stereo_od(int32 *buf, int32 count, EffectList *ef)
     lpfr->ay1 = ay1r, lpfr->ay2 = ay2r, lpfr->aout = aoutr, lpfr->lastin = lastinr;
 }
 
+static void do_delay_lcr(int32 *buf, int32 count, EffectList *ef)
+{
+       int32 i, x;
+       InfoDelayLCR *info = (InfoDelayLCR *)ef->info;
+       delay *delayL = &(info->delayL), *delayR = &(info->delayR);
+       filter_lowpass1 *lpf = &(info->lpf);
+       int32 *bufL = delayL->buf, *bufR = delayR->buf;
+       int32 buf_index = delayL->index, buf_size = delayL->size;
+       int32 index0 = info->index[0], index1 = info->index[1], index2 = info->index[2],
+               x1l = lpf->x1l, x1r = lpf->x1r;
+       int32 cleveli = info->cleveli, feedbacki = info->feedbacki, 
+               dryi = info->dryi, weti = info->weti, ai = lpf->ai, iai = lpf->iai;
+
+       if(count == MAGIC_INIT_EFFECT_INFO) {
+               info->size[0] = info->ldelay * play_mode->rate / 1000.0f;
+               info->size[1] = info->cdelay * play_mode->rate / 1000.0f;
+               info->size[2] = info->rdelay * play_mode->rate / 1000.0f;
+               x = info->fdelay * play_mode->rate / 1000.0f;
+               for (i = 0; i < 3; i++) {
+                       if (info->size[i] > x) {info->size[i] = x;}
+               }
+               x += 1; /* allowance */
+               set_delay(&(info->delayL), x);
+               set_delay(&(info->delayR), x);
+               for (i = 0; i < 3; i++) {       /* set start-point */
+                       info->index[i] = x - info->size[i];
+               }
+               info->feedbacki = TIM_FSCALE(info->feedback, 24);
+               info->cleveli = TIM_FSCALE(info->clevel, 24);
+               info->dryi = TIM_FSCALE(info->dry, 24);
+               info->weti = TIM_FSCALE(info->wet, 24);
+               lpf->a = (1.0f - info->high_damp) * 44100.0f / play_mode->rate;
+               init_filter_lowpass1(lpf);
+               return;
+       } else if(count == MAGIC_FREE_EFFECT_INFO) {
+               free_delay(&(info->delayL));
+               free_delay(&(info->delayR));
+               return;
+       }
+
+       for (i = 0; i < count; i++)
+       {
+               x = imuldiv24(bufL[buf_index], feedbacki);
+               do_filter_lowpass1(x, x1l, ai, iai);
+               bufL[buf_index] = buf[i] + x;
+               x = bufL[index0] + imuldiv24(bufL[index1], cleveli);
+               buf[i] = imuldiv24(buf[i], dryi) + imuldiv24(x, weti);
+
+               x = imuldiv24(bufR[buf_index], feedbacki);
+               do_filter_lowpass1(x, x1r, ai, iai);
+               bufR[buf_index] = buf[++i] + x;
+               x = bufR[index2] + imuldiv24(bufR[index1], cleveli);
+               buf[i] = imuldiv24(buf[i], dryi) + imuldiv24(x, weti);
+
+               if (++index0 == buf_size) {index0 = 0;}
+               if (++index1 == buf_size) {index1 = 0;}
+               if (++index2 == buf_size) {index2 = 0;}
+               if (++buf_index == buf_size) {buf_index = 0;}
+       }
+       info->index[0] = index0, info->index[1] = index1, info->index[2] = index2;
+       lpf->x1l = x1l, lpf->x1r = x1r;
+       delayL->index = delayR->index = buf_index;
+}
+
+static void conv_xg_delay_eq2(struct effect_xg_t *st, EffectList *ef)
+{
+       InfoEQ2 *info = (InfoEQ2 *)ef->info;
+       int val;
+
+       val = st->param_lsb[12];
+       val = (val > 40) ? 40 : (val < 4) ? 4 : val;
+       info->low_freq = eq_freq_table_xg[val];
+       val = st->param_lsb[13] - 64;
+       info->low_gain = (val > 12) ? 12 : (val < -12) ? -12 : val;
+       val = st->param_lsb[14];
+       val = (val > 58) ? 58 : (val < 28) ? 28 : val;
+       info->high_freq = eq_freq_table_xg[val];
+       val = st->param_lsb[15] - 64;
+       info->high_gain = (val > 12) ? 12 : (val < -12) ? -12 : val;
+}
+
+static void conv_xg_delay_lcr(struct effect_xg_t *st, EffectList *ef)
+{
+       InfoDelayLCR *info = (InfoDelayLCR *)ef->info;
+       int val;
+
+       val = st->param_msb[0] * 128 + st->param_lsb[0];
+       val = (val < 1) ? 1 : val;
+       info->ldelay = (double)val / 10.0f;
+       val = st->param_msb[1] * 128 + st->param_lsb[1];
+       val = (val < 1) ? 1 : val;
+       info->rdelay = (double)val / 10.0f;
+       val = st->param_msb[2] * 128 + st->param_lsb[2];
+       val = (val < 1) ? 1 : val;
+       info->cdelay = (double)val / 10.0f;
+       val = st->param_msb[3] * 128 + st->param_lsb[3];
+       val = (val < 1) ? 1 : val;
+       info->fdelay = (double)val / 10.0f;
+       info->feedback = (double)(st->param_lsb[4] - 64) * (0.763f * 2.0f / 100.0f);
+       info->clevel = (double)st->param_lsb[5] / 127.0f;
+       val = st->param_lsb[6];
+       val = (val > 10) ? 10 : (val < 1) ? 1 : val;
+       info->high_damp = (double)val / 10.0f;
+       info->dry = calc_dry_xg(st->param_lsb[9], st);
+       info->wet = calc_wet_xg(st->param_lsb[9], st);
+}
+
 struct _EffectEngine effect_engine[] = {
        EFFECT_NONE, "None", NULL, NULL, NULL, 0,
        EFFECT_EQ2, "2-Band EQ", do_eq2, conv_gs_eq2, NULL, sizeof(InfoEQ2),
@@ -3300,35 +3407,39 @@ struct _EffectEngine effect_engine[] = {
        EFFECT_STEREO_OVERDRIVE, "Stereo Overdrive", do_stereo_od, NULL, conv_xg_overdrive, sizeof(InfoStereoOD),
        EFFECT_STEREO_DISTORTION, "Stereo Distortion", do_stereo_od, NULL, conv_xg_distortion, sizeof(InfoStereoOD),
        EFFECT_OD_EQ3, "2-Band EQ (XG OD built-in)", do_eq3, NULL, conv_xg_od_eq3, sizeof(InfoEQ3),
+       EFFECT_DELAY_LCR, "Delay L,C,R", do_delay_lcr, NULL, conv_xg_delay_lcr, sizeof(InfoDelayLCR),
+       EFFECT_DELAY_EQ2, "2-Band EQ (XG Delay built-in)", do_eq2, NULL, conv_xg_delay_eq2, sizeof(InfoEQ2),
        -1, "EOF", NULL, NULL, NULL, 0, 
 };
 
 struct effect_parameter_xg_t effect_parameter_xg[] = {
        0, 0, "NO EFFECT", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0x05, 0, "DELAY L,C,R", 0x1A, 0x0D, 0x27, 0x27, 0, 0, 0, 0, 0, 0,
+       0x05, 0x03, 0x08, 0x08, 74, 100, 10, 0, 0, 32, 0, 0, 28, 64, 46, 64, 9,
        0x41, 0, "CHORUS 1", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       6, 54, 77, 106, 0, 28, 64, 46, 64, 64, 46, 64, 10, 0, 0, 0,
+       6, 54, 77, 106, 0, 28, 64, 46, 64, 64, 46, 64, 10, 0, 0, 0, 9,
        0x43, 0, "FLANGER 1", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       14, 14, 104, 2, 0, 28, 64, 46, 64, 96, 40, 64, 10, 4, 0, 0,
+       14, 14, 104, 2, 0, 28, 64, 46, 64, 96, 40, 64, 10, 4, 0, 0, 9, 
        0x49, 0, "DISTORTION", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       40, 20, 72, 53, 48, 0, 43, 74, 10, 127, 120, 0, 0, 0, 0, 0,
+       40, 20, 72, 53, 48, 0, 43, 74, 10, 127, 120, 0, 0, 0, 0, 0, 0, 
        0x4A, 0, "OVERDRIVE", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       29, 24, 68, 45, 55, 0, 41, 72, 10, 127, 104, 0, 0, 0, 0, 0,
+       29, 24, 68, 45, 55, 0, 41, 72, 10, 127, 104, 0, 0, 0, 0, 0, 0, 
        -1, -1, "EOF", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 };
 
 struct effect_parameter_gs_t effect_parameter_gs[] = {
        0, 0, "None", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0x01, 0x10, "Overdrive", 48, 1, 1, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0x40, 0x40, 0x40, 96,
+       0, 0, 0, 0, 0, 0, 0x40, 0x40, 0x40, 96, 0, 18,
        0x01, 0x11, "Distrotion", 76, 3, 1, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0x40, 0x38, 0x40, 84,
+       0, 0, 0, 0, 0, 0, 0x40, 0x38, 0x40, 84, 0, 18, 
        0x11, 0x03, "OD1/OD2", 0, 48, 1, 1, 0, 1, 76, 3, 1, 0,
-       0, 0, 0, 0, 0, 0x40, 96, 0x40, 84, 127,
+       0, 0, 0, 0, 0, 0x40, 96, 0x40, 84, 127, 1, 6, 
        0x01, 0x40, "Hexa Chorus", 0x18, 0x08, 127, 5, 66, 16, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 64, 0x40, 0x40, 112,
+       0, 0, 0, 0, 0, 0, 64, 0x40, 0x40, 112, 1, 15, 
        -1, -1, "EOF", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 };
index 01b77c1..efa2e71 100644 (file)
@@ -185,6 +185,8 @@ enum {
        EFFECT_STEREO_DISTORTION,
        EFFECT_OD_EQ3,
        EFFECT_HEXA_CHORUS,
+       EFFECT_DELAY_LCR,
+       EFFECT_DELAY_EQ2,
 };
 
 #define MAGIC_INIT_EFFECT_INFO -1
@@ -233,6 +235,7 @@ struct effect_parameter_gs_t {
        int8 type_msb, type_lsb;
        char *name;
        int8 param[20];
+       int8 control1, control2;
 };
 
 extern struct effect_parameter_gs_t effect_parameter_gs[];
@@ -241,6 +244,7 @@ struct effect_parameter_xg_t {
        int8 type_msb, type_lsb;
        char *name;
        int8 param_msb[10], param_lsb[16];
+       int8 control;
 };
 
 extern struct effect_parameter_xg_t effect_parameter_xg[];
@@ -353,7 +357,7 @@ typedef struct {
        int32 leveli, feedbacki, send_reverbi, send_delayi;
 } InfoStereoChorus;
 
-/*! Chorus Effect */
+/*! Chorus */
 typedef struct {
        delay delayL, delayR;
        lfo lfoL, lfoR;
@@ -372,6 +376,16 @@ typedef struct {
        filter_lpf18 lpf18l, lpf18r;
 } InfoStereoOD;
 
+/*! Delay L,C,R */
+typedef struct {
+       delay delayL, delayR;
+       int32 index[3], size[3];        /* L,C,R */
+       double rdelay, ldelay, cdelay, fdelay;  /* in ms */
+       double dry, wet, feedback, clevel, high_damp;
+       int32 dryi, weti, feedbacki, cleveli;
+       filter_lowpass1 lpf;
+} InfoDelayLCR;
+
 /*                             */
 /*        System Effect        */
 /*                             */