OSDN Git Service

Clean up around chorus effect.
authorSaito <saito2@digitalme.com>
Wed, 18 Feb 2004 07:55:23 +0000 (07:55 +0000)
committerSaito <saito2@digitalme.com>
Wed, 18 Feb 2004 07:55:23 +0000 (07:55 +0000)
ChangeLog
timidity/playmidi.c
timidity/readmidi.c
timidity/reverb.c
timidity/reverb.h

index aff3bdc..7e83a25 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2004-02-18  Saito <saito2@digitalme.com>
+
+       * timidity/reverb.[ch], timidity/playmidi.c, timidity/readmidi.c:
+         Clean up around chorus effect.
+
 2004-02-18  TAMUKI Shoichi <tamuki@linet.gr.jp>
 
        * doc/C/timidity.cfg.5, doc/ja_JP.ujis/timidity.cfg.5: Update
index 2a7ae9d..5c06565 100644 (file)
@@ -3859,46 +3859,46 @@ static void process_sysex_event(int ev, int ch, int val, int b)
                case 0x0E:      /* Chorus Pre-LPF */
                        if (val > 7) {val = 7;}
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Pre-LPF (%d)",val);
-                       chorus_param.chorus_pre_lpf = val;
+                       chorus_status.pre_lpf = val;
                        recompute_chorus_status_gs();
                        break;
                case 0x0F:      /* Chorus Level */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Level (%d)",val);
-                       chorus_param.chorus_level = val;
+                       chorus_status.level = val;
                        recompute_chorus_status_gs();
                        break;
                case 0x10:      /* Chorus Feedback */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Feedback (%d)",val);
-                       chorus_param.chorus_feedback = val;
+                       chorus_status.feedback = val;
                        recompute_chorus_status_gs();
                        break;
                case 0x11:      /* Chorus Delay */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Delay (%d)",val);
-                       chorus_param.chorus_delay = val;
+                       chorus_status.delay = val;
                        init_ch_chorus();
                        recompute_chorus_status_gs();
                        init_chorus_lfo();
                        break;
                case 0x12:      /* Chorus Rate */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Rate (%d)",val);
-                       chorus_param.chorus_rate = val;
+                       chorus_status.rate = val;
                        recompute_chorus_status_gs();
                        init_chorus_lfo();
                        break;
                case 0x13:      /* Chorus Depth */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Depth (%d)",val);
-                       chorus_param.chorus_depth = val;
+                       chorus_status.depth = val;
                        recompute_chorus_status_gs();
                        init_chorus_lfo();
                        break;
                case 0x14:      /* Chorus Send Level to Reverb */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Send Level to Reverb (%d)",val);
-                       chorus_param.chorus_send_level_to_reverb = val;
+                       chorus_status.send_reverb = val;
                        recompute_chorus_status_gs();
                        break;
                case 0x15:      /* Chorus Send Level to Delay */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Send Level to Delay (%d)",val);
-                       chorus_param.chorus_send_level_to_delay = val;
+                       chorus_status.send_delay = val;
                        recompute_chorus_status_gs();
                        break;
                case 0x16:      /* Delay Macro */
@@ -4177,7 +4177,7 @@ static void process_sysex_event(int ev, int ch, int val, int b)
                        break;
                case 0x01:      /* Chorus Return */
                        ctl->cmsg(CMSG_INFO,VERB_NOISY,"Chorus Return (%d)", val);
-                       chorus_param.chorus_level = val;
+                       chorus_status.level = val;
                        recompute_chorus_status_gs();
                        break;
                case 0x50:      /* EQ type */
index a4434eb..fc53f88 100644 (file)
@@ -504,19 +504,14 @@ static uint16 gm_convert_master_vol(uint16 v1, uint16 v2)
 
 static void check_chorus_text_start(void)
 {
-    if(chorus_status.status != CHORUS_ST_OK &&
-       chorus_status.voice_reserve[17] &&
-       chorus_status.macro[2] &&
-       chorus_status.pre_lpf[2] &&
-       chorus_status.level[2] &&
-       chorus_status.feed_back[2] &&
-       chorus_status.delay[2] &&
-       chorus_status.rate[2] &&
-       chorus_status.depth[2] &&
-       chorus_status.send_level[2])
+       struct chorus_text_t *p = &(chorus_status.text);
+    if(p->status != CHORUS_ST_OK && p->voice_reserve[17] &&
+       p->macro[2] && p->pre_lpf[2] && p->level[2] &&
+       p->feed_back[2] && p->delay[2] && p->rate[2] &&
+       p->depth[2] && p->send_level[2])
     {
        ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Chorus text start");
-       chorus_status.status = CHORUS_ST_OK;
+       p->status = CHORUS_ST_OK;
     }
 }
 
@@ -3730,31 +3725,32 @@ int parse_sysex_event(uint8 *val, int32 len, MidiEvent *ev)
 
        if((addr & 0xFFFFF0) == 0x400130) /* Changing Effects */
        {
+               struct chorus_text_t *chorus_text = &(chorus_status.text);
            switch(addr & 0xF)
            {
              case 0x8: /* macro */
-               memcpy(chorus_status.macro, body, 3);
+               memcpy(chorus_text->macro, body, 3);
                break;
              case 0x9: /* PRE-LPF */
-               memcpy(chorus_status.pre_lpf, body, 3);
+               memcpy(chorus_text->pre_lpf, body, 3);
                break;
              case 0xa: /* level */
-               memcpy(chorus_status.level, body, 3);
+               memcpy(chorus_text->level, body, 3);
                break;
              case 0xb: /* feed back */
-               memcpy(chorus_status.feed_back, body, 3);
+               memcpy(chorus_text->feed_back, body, 3);
                break;
              case 0xc: /* delay */
-               memcpy(chorus_status.delay, body, 3);
+               memcpy(chorus_text->delay, body, 3);
                break;
              case 0xd: /* rate */
-               memcpy(chorus_status.rate, body, 3);
+               memcpy(chorus_text->rate, body, 3);
                break;
              case 0xe: /* depth */
-               memcpy(chorus_status.depth, body, 3);
+               memcpy(chorus_text->depth, body, 3);
                break;
              case 0xf: /* send level */
-               memcpy(chorus_status.send_level, body, 3);
+               memcpy(chorus_text->send_level, body, 3);
                break;
                  default: break;
            }
@@ -3769,7 +3765,7 @@ int parse_sysex_event(uint8 *val, int32 len, MidiEvent *ev)
        if(addr == 0x400110) /* Voice Reserve */
        {
            if(len >= 25)
-               memcpy(chorus_status.voice_reserve, body, 18);
+               memcpy(chorus_status.text.voice_reserve, body, 18);
            check_chorus_text_start();
            return 0;
        }
@@ -4169,7 +4165,7 @@ static int read_smf_track(struct timidity_file *tf, int trackno, int rewindp)
                if(type == 5 || /* Lyric */
                   (type == 1 && (opt_trace_text_meta_event ||
                                  karaoke_format == 2 ||
-                                 chorus_status.status == CHORUS_ST_OK)) ||
+                                 chorus_status.text.status == CHORUS_ST_OK)) ||
                   (type == 6 &&  (current_file_info->format == 0 ||
                                   (current_file_info->format == 1 &&
                                    current_read_track == 0))))
@@ -4232,7 +4228,7 @@ static int read_smf_track(struct timidity_file *tf, int trackno, int rewindp)
                            readmidi_add_event(&ev);
                            continue;
                        }
-                       if(chorus_status.status == CHORUS_ST_OK)
+                       if(chorus_status.text.status == CHORUS_ST_OK)
                        {
                            *text = ME_CHORUS_TEXT;
                            ev.type = ME_CHORUS_TEXT;
@@ -6247,16 +6243,16 @@ void set_reverb_macro_gs(int macro)
 /*! initialize Chorus Effect (GS) */
 void init_chorus_status_gs(void)
 {
-       struct chorus_param_t *p = &chorus_param;
-       p->chorus_macro = 0;
-       p->chorus_pre_lpf = 0;
-       p->chorus_level = 0x40;
-       p->chorus_feedback = 0x08;
-       p->chorus_delay = 0x50;
-       p->chorus_rate = 0x03;
-       p->chorus_depth = 0x13;
-       p->chorus_send_level_to_reverb = 0;
-       p->chorus_send_level_to_delay = 0;
+       struct chorus_status_t *p = &chorus_status;
+       p->macro = 0;
+       p->pre_lpf = 0;
+       p->level = 0x40;
+       p->feedback = 0x08;
+       p->delay = 0x50;
+       p->rate = 0x03;
+       p->depth = 0x13;
+       p->send_reverb = 0;
+       p->send_delay = 0;
        recompute_chorus_status_gs();
        init_chorus_lfo();
 }
@@ -6264,20 +6260,20 @@ void init_chorus_status_gs(void)
 /*! recompute Chorus Effect (GS) */
 void recompute_chorus_status_gs()
 {
-       struct chorus_param_t *p = &chorus_param;
-       p->delay_in_sample = chorus_delay_time_table[p->chorus_delay] * (double)play_mode->rate / 1000.0;
-       p->depth_in_sample = (double)(p->chorus_depth + 1) / 3.2f * (double)play_mode->rate / 1000.0;
+       struct chorus_status_t *p = &chorus_status;
+       p->delay_in_sample = chorus_delay_time_table[p->delay] * (double)play_mode->rate / 1000.0;
+       p->depth_in_sample = (double)(p->depth + 1) / 3.2f * (double)play_mode->rate / 1000.0;
        p->delay_in_sample -= p->depth_in_sample / 2;   /* NOMINAL_DELAY to delay */
        if (p->delay_in_sample < 1) {p->delay_in_sample = 1;}
-       p->cycle_in_sample = play_mode->rate / ((double)p->chorus_rate * 0.122f);
-       if (p->chorus_rate < 1) {p->cycle_in_sample = 0x7fffffff;}
-       p->feedback_ratio = (double)p->chorus_feedback * 0.763f / 100.0f;
-       p->level_ratio = (double)p->chorus_level / 127.0f;
-       p->send_reverb_ratio = (double)p->chorus_send_level_to_reverb * 0.787f / 100.0f;
-       p->send_delay_ratio = (double)p->chorus_send_level_to_delay * 0.787f / 100.0f;
-
-       if(p->chorus_pre_lpf) {
-               p->lpf.a = (double)(7 - p->chorus_pre_lpf) / 7.0 * 0.9 + 0.05;
+       p->cycle_in_sample = play_mode->rate / ((double)p->rate * 0.122f);
+       if (p->rate < 1) {p->cycle_in_sample = 0x7fffffff;}
+       p->feedback_ratio = (double)p->feedback * 0.763f / 100.0f;
+       p->level_ratio = (double)p->level / 127.0f;
+       p->send_reverb_ratio = (double)p->send_reverb * 0.787f / 100.0f;
+       p->send_delay_ratio = (double)p->send_delay * 0.787f / 100.0f;
+
+       if(p->pre_lpf) {
+               p->lpf.a = (double)(7 - p->pre_lpf) / 7.0 * 0.9 + 0.05;
                init_filter_lowpass1(&(p->lpf));
        }
 }
@@ -6285,16 +6281,16 @@ void recompute_chorus_status_gs()
 /*! Chorus Macro (GS), Chorus Type (GM2) */
 void set_chorus_macro_gs(int macro)
 {
-       struct chorus_param_t *p = &chorus_param;
+       struct chorus_status_t *p = &chorus_status;
        macro *= 8;
-       p->chorus_pre_lpf = chorus_macro_presets[macro];
-       p->chorus_level = chorus_macro_presets[macro + 1];
-       p->chorus_feedback = chorus_macro_presets[macro + 2];
-       p->chorus_delay = chorus_macro_presets[macro + 3];
-       p->chorus_rate = chorus_macro_presets[macro + 4];
-       p->chorus_depth = chorus_macro_presets[macro + 5];
-       p->chorus_send_level_to_reverb = chorus_macro_presets[macro + 6];
-       p->chorus_send_level_to_delay = chorus_macro_presets[macro + 7];
+       p->pre_lpf = chorus_macro_presets[macro];
+       p->level = chorus_macro_presets[macro + 1];
+       p->feedback = chorus_macro_presets[macro + 2];
+       p->delay = chorus_macro_presets[macro + 3];
+       p->rate = chorus_macro_presets[macro + 4];
+       p->depth = chorus_macro_presets[macro + 5];
+       p->send_reverb = chorus_macro_presets[macro + 6];
+       p->send_delay = chorus_macro_presets[macro + 7];
 }
 
 /*! initialize EQ (GS) */
index d70d1d8..d839f26 100644 (file)
@@ -2013,7 +2013,7 @@ void init_chorus_lfo(void)
 #ifdef USE_DSP_EFFECT
        int32 i;
 
-       chorus_cyc0 = chorus_param.cycle_in_sample;
+       chorus_cyc0 = chorus_status.cycle_in_sample;
        if(chorus_cyc0 == 0) {chorus_cyc0 = 1;}
 
        for(i=0;i<SINE_CYCLE_LENGTH;i++) {
@@ -2033,7 +2033,7 @@ void init_ch_chorus()
        memset(chorus_buf0_R, 0, sizeof(chorus_buf0_R));
        memset(chorus_effect_buffer, 0, sizeof(chorus_effect_buffer));
        /* clear delay-line of LPF */
-       init_filter_lowpass1(&(chorus_param.lpf));
+       init_filter_lowpass1(&(chorus_status.lpf));
 
        chorus_cnt0 = chorus_wpt0 = chorus_wpt1 = 0;
        chorus_spt0 = chorus_spt1 = chorus_hist0 = chorus_hist1 = 0;
@@ -2048,12 +2048,12 @@ void do_stereo_chorus(int32* buf, register int32 count)
        int32 i, level, feedback, send_reverb, send_delay, pdelay,
                depth, output, icycle, hist0, hist1, f0, f1, v0, v1;
 
-       level = TIM_FSCALE(chorus_param.level_ratio * MASTER_CHORUS_LEVEL, 24);
-       feedback = TIM_FSCALE(chorus_param.feedback_ratio, 24);
-       send_reverb = TIM_FSCALE(chorus_param.send_reverb_ratio * REV_INP_LEV, 24);
-       send_delay = TIM_FSCALE(chorus_param.send_delay_ratio, 24);
-       depth = chorus_param.depth_in_sample;
-       pdelay = chorus_param.delay_in_sample;
+       level = TIM_FSCALE(chorus_status.level_ratio * MASTER_CHORUS_LEVEL, 24);
+       feedback = TIM_FSCALE(chorus_status.feedback_ratio, 24);
+       send_reverb = TIM_FSCALE(chorus_status.send_reverb_ratio * REV_INP_LEV, 24);
+       send_delay = TIM_FSCALE(chorus_status.send_delay_ratio, 24);
+       depth = chorus_status.depth_in_sample;
+       pdelay = chorus_status.delay_in_sample;
        icycle = TIM_FSCALE((SINE_CYCLE_LENGTH - 1) / (double)chorus_cyc0, 24) - 0.5;
        hist0 = chorus_hist0, hist1 = chorus_hist1;
 
@@ -2110,6 +2110,35 @@ void do_stereo_chorus(int32* buf, register int32 count)
 #endif /* OPT_MODE != 0 */
 }
 
+#if 0
+/*! Stereo Chorus; this implementation is specialized for system effect. */
+static void do_ch_stereo_chorus(int32 *buf, int32 count, InfoStereoChorus *info)
+{
+       int32 i;
+
+       if(count == MAGIC_INIT_EFFECT_INFO) {
+               init_lfo(lfoL, /*Hz*/, LFO_SINE);
+               init_lfo(lfoR, /*Hz*/, LFO_COSINE);
+               return;
+       } else if(count == MAGIC_FREE_EFFECT_INFO) {
+               return;
+       }
+
+       for (i = 0; i < count; i++)
+       {
+               outr = outl = 0;
+               x = (reverb_effect_buffer[i] + reverb_effect_buffer[i + 1]) >> 1;
+               reverb_effect_buffer[i] = reverb_effect_buffer[i + 1] = 0;
+
+               buf[i] += outl;
+               buf[i + 1] += outr;
+
+               ++i;
+       }
+       info->t1 = t1, info->t1d = t1d;
+}
+#endif
+
 #if OPT_MODE != 0      /* fixed-point implementation */
 #if _MSC_VER
 void set_ch_chorus(int32 *buf, int32 count, int32 level)
@@ -2170,8 +2199,8 @@ void do_ch_chorus(int32 *buf, int32 count)
 {
 #ifdef SYS_EFFECT_PRE_LPF
        if ((opt_reverb_control == 3 || opt_reverb_control == 4
-                       || (opt_reverb_control < 0 && ! (opt_reverb_control & 0x100))) && chorus_param.chorus_pre_lpf)
-               do_filter_lowpass1_stereo(chorus_effect_buffer, count, &(chorus_param.lpf));
+                       || (opt_reverb_control < 0 && ! (opt_reverb_control & 0x100))) && chorus_status.pre_lpf)
+               do_filter_lowpass1_stereo(chorus_effect_buffer, count, &(chorus_status.lpf));
 #endif /* SYS_EFFECT_PRE_LPF */
 
        do_stereo_chorus(buf, count);
index f72d39f..c9646f0 100644 (file)
@@ -273,6 +273,16 @@ typedef struct {
        int32 leveli[3], feedbacki, send_reverbi;
 } InfoDelay3;
 
+/*! Stereo Chorus Effect */
+typedef struct {
+       delay delayL, delayR;
+       lfo lfoL, lfoR;
+       int32 wpt0, wpt1, spt0, spt1, hist0, hist1;
+       int32 rpt0, depth, pdelay;
+       double level, feedback, send_reverb, send_delay;
+       int32 leveli, feedbacki, send_reverbi, send_delayi;
+} InfoStereoChorus;
+
 /*                             */
 /*        System Effect        */
 /*                             */
@@ -314,27 +324,27 @@ struct reverb_status_t
        filter_lowpass1 lpf;
 } reverb_status;
 
+struct chorus_text_t
+{
+    int status;
+    uint8 voice_reserve[18], macro[3], pre_lpf[3], level[3], feed_back[3],
+               delay[3], rate[3], depth[3], send_level[3];
+};
+
 /* GS parameters of chorus effect */
-struct chorus_param_t
+struct chorus_status_t
 {
        /* GS parameters */
-       int8 chorus_macro, chorus_pre_lpf, chorus_level, chorus_feedback,
-               chorus_delay, chorus_rate, chorus_depth, chorus_send_level_to_reverb,
-               chorus_send_level_to_delay;
+       int8 macro, pre_lpf, level, feedback, delay, rate, depth, send_reverb, send_delay;
 
        /* for pre-calculation */
        double level_ratio, feedback_ratio, send_reverb_ratio, send_delay_ratio;
        int32 cycle_in_sample, depth_in_sample, delay_in_sample;
 
-       filter_lowpass1 lpf;
-} chorus_param;
+       struct chorus_text_t text;
 
-/* dummy. see also readmidi.c */
-struct chorus_status_t
-{
-    int status;
-    uint8 voice_reserve[18], macro[3], pre_lpf[3], level[3], feed_back[3],
-               delay[3], rate[3], depth[3], send_level[3];
+       InfoStereoChorus info_stereo_chorus;
+       filter_lowpass1 lpf;
 } chorus_status;
 
 /* GS parameters of delay effect */