 /* lower the volumes so that the two notes add to roughly the orig. vol */ vol = voice[v1].velocity; voice[v1].velocity  = (uint8)(vol * CHORUS_VELOCITY_TUNING1); voice[v2].velocity  = (uint8)(vol * CHORUS_VELOCITY_TUNING1); 
static void new_chorus_voice_alternate(int v1, int level){    int v2, ch, panlevel;    uint8 vol, pan;    double delay;    double freq, frac;    int note_adjusted;    if((v2 = find_free_voice()) == -1)	return;    ch = voice[v1].channel;    voice[v2] = voice[v1];    /* NRPN Chorus Send Level of Drum */    if(ISDRUMCHANNEL(ch) && channel[ch].drums[voice[v1].note] != NULL) {	level *= (FLOAT_T)channel[ch].drums[voice[v1].note]->chorus_level / 127.0;    }    /* for our purposes, hard left will be equal to 1 instead of 0 */    pan = voice[v1].panning;    if (!pan) pan = 1;    /* Choose lower voice index for base voice (v1) */    if(v1 > v2)    {    	v1 ^= v2;    	v2 ^= v1;    	v1 ^= v2;    }    /* lower the volumes so that the two notes add to roughly the orig. vol */    vol = voice[v1].velocity;    voice[v1].velocity  = (uint8)(vol * CHORUS_VELOCITY_TUNING1);    voice[v2].velocity  = (uint8)(vol * CHORUS_VELOCITY_TUNING1);    /* Make doubled link v1 and v2 */    voice[v1].chorus_link = v2;    voice[v2].chorus_link = v1;    /* detune notes for chorus effect */    level >>= 2;		/* scale to a "better" value */    if (level)    {        if(channel[ch].pitchbend + level < 0x2000)            voice[v2].orig_frequency *= bend_fine[level];        else	    voice[v2].orig_frequency /= bend_fine[level];        voice[v2].cache = NULL;    }    MYCHECK(voice[v2].orig_frequency);    delay = 0.003;    /* Try to keep the delayed voice from cancelling out the other voice */    /* Pitch detection is used to find the real pitches for drums and MODs */    note_adjusted = voice[v1].note + voice[v1].sample->transpose_detected;    if (note_adjusted > 127) note_adjusted = 127;    else if (note_adjusted < 0) note_adjusted = 0;    freq = pitch_freq_table[note_adjusted];    delay *= freq;    frac = delay - floor(delay);    /* force the delay away from 0.5 period */    if (frac < 0.5 && frac > 0.40)    {    	delay = (floor(delay) + 0.40) / freq;    	if (!(play_mode->encoding & PE_MONO))    	    delay += (0.5 - frac) * (1.0 - labs(64 - pan) / 63.0) / freq;    }    else if (frac >= 0.5 && frac < 0.60)    {    	delay = (floor(delay) + 0.60) / freq;    	if (!(play_mode->encoding & PE_MONO))    	    delay += (0.5 - frac) * (1.0 - labs(64 - pan) / 63.0) / freq;    }    else	delay = 0.003;    /* set panning & delay for pseudo-surround effect */    if(play_mode->encoding & PE_MONO)    /* delay sounds good */        voice[v2].delay += (int)(play_mode->rate * delay);    else    {        panlevel = 63;        if (pan - panlevel < 1) panlevel = pan - 1;        if (pan + panlevel > 127) panlevel = 127 - pan;        voice[v1].panning -= panlevel;        voice[v2].panning += panlevel;        /* choose which voice is delayed based on panning */        if (voice[v1].panned == PANNED_CENTER) {            /* randomly choose which voice is delayed */            if (int_rand(2))                voice[v1].delay += (int)(play_mode->rate * delay);            else                voice[v2].delay += (int)(play_mode->rate * delay);        }        else if (pan - 64 < 0) {            voice[v2].delay += (int)(play_mode->rate * delay);        }        else {            voice[v1].delay += (int)(play_mode->rate * delay);        }    }    /* check for similar drums playing simultaneously with center pans */    if (!(play_mode->encoding & PE_MONO) &&    	ISDRUMCHANNEL(ch) && voice[v1].panned == PANNED_CENTER)    {    	int i, j;        	/* force Rimshot (37), Snare1 (38), Snare2 (40), and XG #34 to have    	 * the same delay, otherwise there will be bad voice cancellation.    	 */    	if (voice[v1].note == 37 ||    	    voice[v1].note == 38 ||    	    voice[v1].note == 40 ||    	    (voice[v1].note == 34 && play_system_mode == XG_SYSTEM_MODE))    	{    	    for (i = 0; i < upper_voices; i++)    	    {    	    	if (voice[i].status & (VOICE_DIE | VOICE_FREE))    	    	    continue;    	    	if (!ISDRUMCHANNEL(voice[i].channel))    	    	    continue;	    	if (i == v1 || i == v2)	    	    continue;	    	if (voice[i].note == 37 ||	    	    voice[i].note == 38 ||	    	    voice[i].note == 40 ||	    	    (voice[i].note == 34 &&	    	     play_system_mode == XG_SYSTEM_MODE))	    	{	    	    j = voice[i].chorus_link;	    	    if (voice[i].panned == PANNED_LEFT &&	    	        voice[j].panned == PANNED_RIGHT)	    	    {	    	    	voice[v1].delay = voice[i].delay;	    	    	voice[v2].delay = voice[j].delay;	    	    	break;	    	    }	    	}    	    }    	}    	/* force Kick1 (35), Kick2 (36), and XG Kick #33 to have the same    	 * delay, otherwise there will be bad voice cancellation.    	 */    	if (voice[v1].note == 35 ||    	    voice[v1].note == 36 ||    	    (voice[v1].note == 33 && play_system_mode == XG_SYSTEM_MODE))    	{    	    for (i = 0; i < upper_voices; i++)    	    {    	    	if (voice[i].status & (VOICE_DIE | VOICE_FREE))    	    	    continue;    	    	if (!ISDRUMCHANNEL(voice[i].channel))    	    	    continue;	    	if (i == v1 || i == v2)	    	    continue;	    	if (voice[i].note == 35 ||	    	    voice[i].note == 36 ||	    	    (voice[i].note == 33 &&	    	     play_system_mode == XG_SYSTEM_MODE))	    	{	    	    j = voice[i].chorus_link;	    	    if (voice[i].panned == PANNED_LEFT &&	    	        voice[j].panned == PANNED_RIGHT)	    	    {	    	    	voice[v1].delay = voice[i].delay;	    	    	voice[v2].delay = voice[j].delay;	    	    	break;	    	    }	    	}    	    }    	}    }    init_voice_pan_delay(v1);    init_voice_pan_delay(v2);    recompute_amp(v1);    apply_envelope_to_amp(v1);    recompute_amp(v2);    apply_envelope_to_amp(v2);    if (level) recompute_freq(v2);}
4357	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4357/f8cd4483677cb10133859fde9c7868a36ffee9a4/playmidi.c/buggy/timidity/playmidi.c