timidity/mix.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 13 Oct 2018 23:02:04 +0300
branchSDL-1.2
changeset 908 6b860486ce24
parent 518 8bc9b5fd2aae
child 782 e7d3a8f73e88
permissions -rw-r--r--
Mix_InitMP3: unload dll if mpg123_init() fails.
     1 /*
     2     TiMidity -- Experimental MIDI to WAVE converter
     3     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
     4 
     5     This program is free software; you can redistribute it and/or modify
     6     it under the terms of the Perl Artistic License, available in COPYING.
     7  */
     8 
     9 #include <math.h>
    10 #include <stdio.h>
    11 #include <stdlib.h>
    12 
    13 #include "config.h"
    14 #include "common.h"
    15 #include "instrum.h"
    16 #include "playmidi.h"
    17 #include "output.h"
    18 #include "ctrlmode.h"
    19 #include "tables.h"
    20 #include "resample.h"
    21 #include "mix.h"
    22 
    23 /* Returns 1 if envelope runs out */
    24 int recompute_envelope(int v)
    25 {
    26   int stage;
    27 
    28   stage = voice[v].envelope_stage;
    29 
    30   if (stage>5)
    31     {
    32       /* Envelope ran out. */
    33       int tmp=(voice[v].status == VOICE_DIE); /* Already displayed as dead */
    34       voice[v].status = VOICE_FREE;
    35       if(!tmp)
    36 	ctl->note(v);
    37       return 1;
    38     }
    39 
    40   if (voice[v].sample->modes & MODES_ENVELOPE)
    41     {
    42       if (voice[v].status==VOICE_ON || voice[v].status==VOICE_SUSTAINED)
    43 	{
    44 	  if (stage>2)
    45 	    {
    46 	      /* Freeze envelope until note turns off. Trumpets want this. */
    47 	      voice[v].envelope_increment=0;
    48 	      return 0;
    49 	    }
    50 	}
    51     }
    52   voice[v].envelope_stage=stage+1;
    53 
    54   if (voice[v].envelope_volume==voice[v].sample->envelope_offset[stage])
    55     return recompute_envelope(v);
    56   voice[v].envelope_target=voice[v].sample->envelope_offset[stage];
    57   voice[v].envelope_increment = voice[v].sample->envelope_rate[stage];
    58   if (voice[v].envelope_target<voice[v].envelope_volume)
    59     voice[v].envelope_increment = -voice[v].envelope_increment;
    60   return 0;
    61 }
    62 
    63 void apply_envelope_to_amp(int v)
    64 {
    65   FLOAT_T lamp=voice[v].left_amp, ramp, lramp, rramp, ceamp, lfeamp;
    66   int32 la,ra, lra, rra, cea, lfea;
    67   if (voice[v].panned == PANNED_MYSTERY)
    68     {
    69       lramp=voice[v].lr_amp;
    70       ramp=voice[v].right_amp;
    71       ceamp=voice[v].ce_amp;
    72       rramp=voice[v].rr_amp;
    73       lfeamp=voice[v].lfe_amp;
    74 
    75       if (voice[v].tremolo_phase_increment)
    76 	{
    77 	  FLOAT_T tv = voice[v].tremolo_volume;
    78 	  lramp *= tv;
    79 	  lamp *= tv;
    80 	  ceamp *= tv;
    81 	  ramp *= tv;
    82 	  rramp *= tv;
    83 	  lfeamp *= tv;
    84 	}
    85       if (voice[v].sample->modes & MODES_ENVELOPE)
    86 	{
    87 	  FLOAT_T ev = (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
    88 	  lramp *= ev;
    89 	  lamp *= ev;
    90 	  ceamp *= ev;
    91 	  ramp *= ev;
    92 	  rramp *= ev;
    93 	  lfeamp *= ev;
    94 	}
    95 
    96       la = (int32)FSCALE(lamp,AMP_BITS);
    97       ra = (int32)FSCALE(ramp,AMP_BITS);
    98       lra = (int32)FSCALE(lramp,AMP_BITS);
    99       rra = (int32)FSCALE(rramp,AMP_BITS);
   100       cea = (int32)FSCALE(ceamp,AMP_BITS);
   101       lfea = (int32)FSCALE(lfeamp,AMP_BITS);
   102       
   103       if (la>MAX_AMP_VALUE) la=MAX_AMP_VALUE;
   104       if (ra>MAX_AMP_VALUE) ra=MAX_AMP_VALUE;
   105       if (lra>MAX_AMP_VALUE) lra=MAX_AMP_VALUE;
   106       if (rra>MAX_AMP_VALUE) rra=MAX_AMP_VALUE;
   107       if (cea>MAX_AMP_VALUE) cea=MAX_AMP_VALUE;
   108       if (lfea>MAX_AMP_VALUE) lfea=MAX_AMP_VALUE;
   109 
   110       voice[v].lr_mix=FINAL_VOLUME(lra);
   111       voice[v].left_mix=FINAL_VOLUME(la);
   112       voice[v].ce_mix=FINAL_VOLUME(cea);
   113       voice[v].right_mix=FINAL_VOLUME(ra);
   114       voice[v].rr_mix=FINAL_VOLUME(rra);
   115       voice[v].lfe_mix=FINAL_VOLUME(lfea);
   116     }
   117   else
   118     {
   119       if (voice[v].tremolo_phase_increment)
   120 	lamp *= voice[v].tremolo_volume;
   121       if (voice[v].sample->modes & MODES_ENVELOPE)
   122 	lamp *= (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
   123 
   124       la = (int32)FSCALE(lamp,AMP_BITS);
   125 
   126       if (la>MAX_AMP_VALUE)
   127 	la=MAX_AMP_VALUE;
   128 
   129       voice[v].left_mix=FINAL_VOLUME(la);
   130     }
   131 }
   132 
   133 static int update_envelope(int v)
   134 {
   135   voice[v].envelope_volume += voice[v].envelope_increment;
   136   /* Why is there no ^^ operator?? */
   137   if (((voice[v].envelope_increment < 0) &&
   138        (voice[v].envelope_volume <= voice[v].envelope_target)) ||
   139       ((voice[v].envelope_increment > 0) &&
   140 	   (voice[v].envelope_volume >= voice[v].envelope_target)))
   141     {
   142       voice[v].envelope_volume = voice[v].envelope_target;
   143       if (recompute_envelope(v))
   144 	return 1;
   145     }
   146   return 0;
   147 }
   148 
   149 static void update_tremolo(int v)
   150 {
   151   int32 depth=voice[v].sample->tremolo_depth<<7;
   152 
   153   if (voice[v].tremolo_sweep)
   154     {
   155       /* Update sweep position */
   156 
   157       voice[v].tremolo_sweep_position += voice[v].tremolo_sweep;
   158       if (voice[v].tremolo_sweep_position>=(1<<SWEEP_SHIFT))
   159 	voice[v].tremolo_sweep=0; /* Swept to max amplitude */
   160       else
   161 	{
   162 	  /* Need to adjust depth */
   163 	  depth *= voice[v].tremolo_sweep_position;
   164 	  depth >>= SWEEP_SHIFT;
   165 	}
   166     }
   167 
   168   voice[v].tremolo_phase += voice[v].tremolo_phase_increment;
   169 
   170   /* if (voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
   171      voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT;  */
   172 
   173   voice[v].tremolo_volume = (FLOAT_T) 
   174     (1.0 - FSCALENEG((sine(voice[v].tremolo_phase >> RATE_SHIFT) + 1.0)
   175 		    * depth * TREMOLO_AMPLITUDE_TUNING,
   176 		    17));
   177 
   178   /* I'm not sure about the +1.0 there -- it makes tremoloed voices'
   179      volumes on average the lower the higher the tremolo amplitude. */
   180 }
   181 
   182 /* Returns 1 if the note died */
   183 static int update_signal(int v)
   184 {
   185   if (voice[v].envelope_increment && update_envelope(v))
   186     return 1;
   187 
   188   if (voice[v].tremolo_phase_increment)
   189     update_tremolo(v);
   190 
   191   apply_envelope_to_amp(v);
   192   return 0;
   193 }
   194 
   195 #ifdef LOOKUP_HACK
   196 #  define MIXATION(a)	*lp++ += mixup[(a<<8) | (uint8)s];
   197 #else
   198 #  define MIXATION(a)	*lp++ += (a)*s;
   199 #endif
   200 
   201 #define MIXSKIP lp++
   202 #define MIXMAX(a,b) *lp++ += ((a>b)?a:b) * s
   203 #define MIXCENT(a,b) *lp++ += (a/2+b/2) * s
   204 #define MIXHALF(a)	*lp++ += (a>>1)*s;
   205 
   206 static void mix_mystery_signal(resample_t *sp, int32 *lp, int v, int count)
   207 {
   208   Voice *vp = voice + v;
   209   final_volume_t 
   210     left_rear=vp->lr_mix, 
   211     left=vp->left_mix, 
   212     center=vp->ce_mix, 
   213     right=vp->right_mix, 
   214     right_rear=vp->rr_mix, 
   215     lfe=vp->lfe_mix;
   216   int cc;
   217   resample_t s;
   218 
   219   if (!(cc = vp->control_counter))
   220     {
   221       cc = control_ratio;
   222       if (update_signal(v))
   223 	return;	/* Envelope ran out */
   224 
   225 	left_rear = vp->lr_mix;
   226 	left = vp->left_mix;
   227 	center = vp->ce_mix;
   228 	right = vp->right_mix;
   229 	right_rear = vp->rr_mix;
   230 	lfe = vp->lfe_mix;
   231     }
   232   
   233   while (count)
   234     if (cc < count)
   235       {
   236 	count -= cc;
   237 	while (cc--)
   238 	  {
   239 	    s = *sp++;
   240 	      	MIXATION(left);
   241 	      	MIXATION(right);
   242 		if (num_ochannels >= 4) {
   243 			MIXATION(left_rear);
   244 			MIXATION(right_rear);
   245 		}
   246 		if (num_ochannels == 6) {
   247 			MIXATION(center);
   248 			MIXATION(lfe);
   249 		}
   250 	  }
   251 	cc = control_ratio;
   252 	if (update_signal(v))
   253 	  return;	/* Envelope ran out */
   254 	left_rear = vp->lr_mix;
   255 	left = vp->left_mix;
   256 	center = vp->ce_mix;
   257 	right = vp->right_mix;
   258 	right_rear = vp->rr_mix;
   259 	lfe = vp->lfe_mix;
   260       }
   261     else
   262       {
   263 	vp->control_counter = cc - count;
   264 	while (count--)
   265 	  {
   266 	    s = *sp++;
   267 	      	MIXATION(left);
   268 	      	MIXATION(right);
   269 		if (num_ochannels >= 4) {
   270 			MIXATION(left_rear);
   271 			MIXATION(right_rear);
   272 		}
   273 		if (num_ochannels == 6) {
   274 			MIXATION(center);
   275 			MIXATION(lfe);
   276 		}
   277 	  }
   278 	return;
   279       }
   280 }
   281 
   282 static void mix_center_signal(resample_t *sp, int32 *lp, int v, int count)
   283 {
   284   Voice *vp = voice + v;
   285   final_volume_t 
   286     left=vp->left_mix;
   287   int cc;
   288   resample_t s;
   289 
   290   if (!(cc = vp->control_counter))
   291     {
   292       cc = control_ratio;
   293       if (update_signal(v))
   294 	return;	/* Envelope ran out */
   295       left = vp->left_mix;
   296     }
   297   
   298   while (count)
   299     if (cc < count)
   300       {
   301 	count -= cc;
   302 	while (cc--)
   303 	  {
   304 	    s = *sp++;
   305 		if (num_ochannels == 2) {
   306 	    		MIXATION(left);
   307 	    		MIXATION(left);
   308 		}
   309 		else if (num_ochannels == 4) {
   310 			MIXATION(left);
   311 			MIXSKIP;
   312 			MIXATION(left);
   313 			MIXSKIP;
   314 		}
   315 		else if (num_ochannels == 6) {
   316 			MIXSKIP;
   317 			MIXSKIP;
   318 			MIXSKIP;
   319 			MIXSKIP;
   320 			MIXATION(left);
   321 			MIXATION(left);
   322 		}
   323 	  }
   324 	cc = control_ratio;
   325 	if (update_signal(v))
   326 	  return;	/* Envelope ran out */
   327 	left = vp->left_mix;
   328       }
   329     else
   330       {
   331 	vp->control_counter = cc - count;
   332 	while (count--)
   333 	  {
   334 	    s = *sp++;
   335 		if (num_ochannels == 2) {
   336 	    		MIXATION(left);
   337 	    		MIXATION(left);
   338 		}
   339 		else if (num_ochannels == 4) {
   340 			MIXATION(left);
   341 			MIXSKIP;
   342 			MIXATION(left);
   343 			MIXSKIP;
   344 		}
   345 		else if (num_ochannels == 6) {
   346 			MIXSKIP;
   347 			MIXSKIP;
   348 			MIXSKIP;
   349 			MIXSKIP;
   350 			MIXATION(left);
   351 			MIXATION(left);
   352 		}
   353 	  }
   354 	return;
   355       }
   356 }
   357 
   358 static void mix_single_left_signal(resample_t *sp, int32 *lp, int v, int count)
   359 {
   360   Voice *vp = voice + v;
   361   final_volume_t 
   362     left=vp->left_mix;
   363   int cc;
   364   resample_t s;
   365   
   366   if (!(cc = vp->control_counter))
   367     {
   368       cc = control_ratio;
   369       if (update_signal(v))
   370 	return;	/* Envelope ran out */
   371       left = vp->left_mix;
   372     }
   373   
   374   while (count)
   375     if (cc < count)
   376       {
   377 	count -= cc;
   378 	while (cc--)
   379 	  {
   380 	    s = *sp++;
   381 		if (num_ochannels == 2) {
   382 			MIXATION(left);
   383 	    		MIXSKIP;
   384 		}
   385 		if (num_ochannels >= 4) {
   386 			MIXHALF(left);
   387 	    		MIXSKIP;
   388 			MIXATION(left);
   389 	    		MIXSKIP;
   390 		}
   391 		if (num_ochannels == 6) {
   392 	    		MIXSKIP;
   393 			MIXATION(left);
   394 		}
   395 	  }
   396 	cc = control_ratio;
   397 	if (update_signal(v))
   398 	  return;	/* Envelope ran out */
   399 	left = vp->left_mix;
   400       }
   401     else
   402       {
   403 	vp->control_counter = cc - count;
   404 	while (count--)
   405 	  {
   406 	    s = *sp++;
   407 		if (num_ochannels == 2) {
   408 			MIXATION(left);
   409 	    		MIXSKIP;
   410 		}
   411 		if (num_ochannels >= 4) {
   412 			MIXHALF(left);
   413 	    		MIXSKIP;
   414 			MIXATION(left);
   415 	    		MIXSKIP;
   416 		}
   417 		if (num_ochannels == 6) {
   418 	    		MIXSKIP;
   419 			MIXATION(left);
   420 		}
   421 	  }
   422 	return;
   423       }
   424 }
   425 
   426 static void mix_single_right_signal(resample_t *sp, int32 *lp, int v, int count)
   427 {
   428   Voice *vp = voice + v;
   429   final_volume_t 
   430     left=vp->left_mix;
   431   int cc;
   432   resample_t s;
   433   
   434   if (!(cc = vp->control_counter))
   435     {
   436       cc = control_ratio;
   437       if (update_signal(v))
   438 	return;	/* Envelope ran out */
   439       left = vp->left_mix;
   440     }
   441   
   442   while (count)
   443     if (cc < count)
   444       {
   445 	count -= cc;
   446 	while (cc--)
   447 	  {
   448 	    s = *sp++;
   449 		if (num_ochannels == 2) {
   450 	    		MIXSKIP;
   451 			MIXATION(left);
   452 		}
   453 		if (num_ochannels >= 4) {
   454 	    		MIXSKIP;
   455 			MIXHALF(left);
   456 	    		MIXSKIP;
   457 			MIXATION(left);
   458 		} if (num_ochannels == 6) {
   459 	    		MIXSKIP;
   460 			MIXATION(left);
   461 		}
   462 	  }
   463 	cc = control_ratio;
   464 	if (update_signal(v))
   465 	  return;	/* Envelope ran out */
   466 	left = vp->left_mix;
   467       }
   468     else
   469       {
   470 	vp->control_counter = cc - count;
   471 	while (count--)
   472 	  {
   473 	    s = *sp++;
   474 		if (num_ochannels == 2) {
   475 	    		MIXSKIP;
   476 			MIXATION(left);
   477 		}
   478 		if (num_ochannels >= 4) {
   479 	    		MIXSKIP;
   480 			MIXHALF(left);
   481 	    		MIXSKIP;
   482 			MIXATION(left);
   483 		} if (num_ochannels == 6) {
   484 	    		MIXSKIP;
   485 			MIXATION(left);
   486 		}
   487 	  }
   488 	return;
   489       }
   490 }
   491 
   492 static void mix_mono_signal(resample_t *sp, int32 *lp, int v, int count)
   493 {
   494   Voice *vp = voice + v;
   495   final_volume_t 
   496     left=vp->left_mix;
   497   int cc;
   498   resample_t s;
   499   
   500   if (!(cc = vp->control_counter))
   501     {
   502       cc = control_ratio;
   503       if (update_signal(v))
   504 	return;	/* Envelope ran out */
   505       left = vp->left_mix;
   506     }
   507   
   508   while (count)
   509     if (cc < count)
   510       {
   511 	count -= cc;
   512 	while (cc--)
   513 	  {
   514 	    s = *sp++;
   515 	    MIXATION(left);
   516 	  }
   517 	cc = control_ratio;
   518 	if (update_signal(v))
   519 	  return;	/* Envelope ran out */
   520 	left = vp->left_mix;
   521       }
   522     else
   523       {
   524 	vp->control_counter = cc - count;
   525 	while (count--)
   526 	  {
   527 	    s = *sp++;
   528 	    MIXATION(left);
   529 	  }
   530 	return;
   531       }
   532 }
   533 
   534 static void mix_mystery(resample_t *sp, int32 *lp, int v, int count)
   535 {
   536   final_volume_t 
   537     left_rear=voice[v].lr_mix, 
   538     left=voice[v].left_mix, 
   539     center=voice[v].ce_mix, 
   540     right=voice[v].right_mix, 
   541     right_rear=voice[v].rr_mix, 
   542     lfe=voice[v].lfe_mix;
   543   resample_t s;
   544   
   545   while (count--)
   546     {
   547       s = *sp++;
   548 	      	MIXATION(left);
   549 	      	MIXATION(right);
   550 		if (num_ochannels >= 4) {
   551 			MIXATION(left_rear);
   552 			MIXATION(right_rear);
   553 		}
   554 		if (num_ochannels == 6) {
   555 			MIXATION(center);
   556 			MIXATION(lfe);
   557 		}
   558     }
   559 }
   560 
   561 static void mix_center(resample_t *sp, int32 *lp, int v, int count)
   562 {
   563   final_volume_t 
   564     left=voice[v].left_mix;
   565   resample_t s;
   566   
   567   while (count--)
   568     {
   569       s = *sp++;
   570 		if (num_ochannels == 2) {
   571       			MIXATION(left);
   572       			MIXATION(left);
   573 		}
   574 		else if (num_ochannels == 4) {
   575       			MIXATION(left);
   576       			MIXATION(left);
   577 			MIXSKIP;
   578 			MIXSKIP;
   579 		}
   580 		else if (num_ochannels == 6) {
   581 			MIXSKIP;
   582 			MIXSKIP;
   583 			MIXSKIP;
   584 			MIXSKIP;
   585 			MIXATION(left);
   586 			MIXATION(left);
   587 		}
   588     }
   589 }
   590 
   591 static void mix_single_left(resample_t *sp, int32 *lp, int v, int count)
   592 {
   593   final_volume_t 
   594     left=voice[v].left_mix;
   595   resample_t s;
   596   
   597   while (count--)
   598     {
   599       s = *sp++;
   600 		if (num_ochannels == 2) {
   601 			MIXATION(left);
   602       			MIXSKIP;
   603 		}
   604 		if (num_ochannels >= 4) {
   605 			MIXHALF(left);
   606       			MIXSKIP;
   607 			MIXATION(left);
   608       			MIXSKIP;
   609 		}
   610 	       	if (num_ochannels == 6) {
   611       			MIXSKIP;
   612 			MIXATION(left);
   613 		}
   614     }
   615 }
   616 static void mix_single_right(resample_t *sp, int32 *lp, int v, int count)
   617 {
   618   final_volume_t 
   619     left=voice[v].left_mix;
   620   resample_t s;
   621   
   622   while (count--)
   623     {
   624       s = *sp++;
   625 		if (num_ochannels == 2) {
   626       			MIXSKIP;
   627 			MIXATION(left);
   628 		}
   629 		if (num_ochannels >= 4) {
   630       			MIXSKIP;
   631 			MIXHALF(left);
   632       			MIXSKIP;
   633 			MIXATION(left);
   634 		}
   635 	       	if (num_ochannels == 6) {
   636       			MIXSKIP;
   637 			MIXATION(left);
   638 		}
   639     }
   640 }
   641 
   642 static void mix_mono(resample_t *sp, int32 *lp, int v, int count)
   643 {
   644   final_volume_t 
   645     left=voice[v].left_mix;
   646   resample_t s;
   647   
   648   while (count--)
   649     {
   650       s = *sp++;
   651       MIXATION(left);
   652     }
   653 }
   654 
   655 /* Ramp a note out in c samples */
   656 static void ramp_out(resample_t *sp, int32 *lp, int v, int32 c)
   657 {
   658 
   659   /* should be final_volume_t, but uint8 gives trouble. */
   660   int32 left_rear, left, center, right, right_rear, lfe, li, ri;
   661 
   662   resample_t s = 0; /* silly warning about uninitialized s */
   663 
   664   /* Fix by James Caldwell */
   665   if ( c == 0 ) c = 1;
   666 
   667   left = voice[v].left_mix;
   668   li = -(left/c);
   669   if (!li) li = -1;
   670 
   671   /* printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */
   672 
   673   if (!(play_mode->encoding & PE_MONO))
   674     {
   675       if (voice[v].panned==PANNED_MYSTERY)
   676 	{
   677 	  left_rear = voice[v].lr_mix;
   678 	  center=voice[v].ce_mix;
   679 	  right=voice[v].right_mix;
   680 	  right_rear = voice[v].rr_mix;
   681 	  lfe = voice[v].lfe_mix;
   682 
   683 	  ri=-(right/c);
   684 	  while (c--)
   685 	    {
   686 	      left_rear += li; if (left_rear<0) left_rear=0;
   687 	      left += li; if (left<0) left=0;
   688 	      center += li; if (center<0) center=0;
   689 	      right += ri; if (right<0) right=0;
   690 	      right_rear += ri; if (right_rear<0) right_rear=0;
   691 	      lfe += li; if (lfe<0) lfe=0;
   692 	      s=*sp++;
   693 	      	MIXATION(left);
   694 	      	MIXATION(right);
   695 		if (num_ochannels >= 4) {
   696 			MIXATION(left_rear);
   697 			MIXATION(right_rear);
   698 		}
   699 		if (num_ochannels == 6) {
   700 			MIXATION(center);
   701 			MIXATION(lfe);
   702 		}
   703 	    }
   704 	}
   705       else if (voice[v].panned==PANNED_CENTER)
   706 	{
   707 	  while (c--)
   708 	    {
   709 	      left += li;
   710 	      if (left<0)
   711 		return;
   712 	      s=*sp++;	
   713 		if (num_ochannels == 2) {
   714 	      		MIXATION(left);
   715 	      		MIXATION(left);
   716 		}
   717 		else if (num_ochannels == 4) {
   718 			MIXATION(left);
   719 	      		MIXATION(left);
   720 			MIXSKIP;
   721 			MIXSKIP;
   722 		}
   723 		else if (num_ochannels == 6) {
   724 			MIXSKIP;
   725 			MIXSKIP;
   726 			MIXSKIP;
   727 			MIXSKIP;
   728 	      		MIXATION(left);
   729 	      		MIXATION(left);
   730 		}
   731 	    }
   732 	}
   733       else if (voice[v].panned==PANNED_LEFT)
   734 	{
   735 	  while (c--)
   736 	    {
   737 	      left += li;
   738 	      if (left<0)
   739 		return;
   740 	      s=*sp++;
   741 	      MIXATION(left);
   742 	      MIXSKIP;
   743 		if (num_ochannels >= 4) {
   744 			MIXATION(left);
   745 	      		MIXSKIP;
   746 		} if (num_ochannels == 6) {
   747 			MIXATION(left);
   748 			MIXATION(left);
   749 		}
   750 	    }
   751 	}
   752       else if (voice[v].panned==PANNED_RIGHT)
   753 	{
   754 	  while (c--)
   755 	    {
   756 	      left += li;
   757 	      if (left<0)
   758 		return;
   759 	      s=*sp++;
   760 	      MIXSKIP;
   761 	      MIXATION(left);
   762 		if (num_ochannels >= 4) {
   763 	      		MIXSKIP;
   764 			MIXATION(left);
   765 		} if (num_ochannels == 6) {
   766 			MIXATION(left);
   767 			MIXATION(left);
   768 		}
   769 	    }
   770 	}
   771     }
   772   else
   773     {
   774       /* Mono output.  */
   775       while (c--)
   776 	{
   777 	  left += li;
   778 	  if (left<0)
   779 	    return;
   780 	  s=*sp++;
   781 	  MIXATION(left);
   782 	}
   783     }
   784 }
   785 
   786 
   787 /**************** interface function ******************/
   788 
   789 void mix_voice(int32 *buf, int v, int32 c)
   790 {
   791   Voice *vp=voice+v;
   792   int32 count=c;
   793   resample_t *sp;
   794   if (c<0) return;
   795   if (vp->status==VOICE_DIE)
   796     {
   797       if (count>=MAX_DIE_TIME)
   798 	count=MAX_DIE_TIME;
   799       sp=resample_voice(v, &count);
   800       ramp_out(sp, buf, v, count);
   801       vp->status=VOICE_FREE;
   802     }
   803   else
   804     {
   805       sp=resample_voice(v, &count);
   806       if (count<0) return;
   807       if (play_mode->encoding & PE_MONO)
   808 	{
   809 	  /* Mono output. */
   810 	  if (vp->envelope_increment || vp->tremolo_phase_increment)
   811 	    mix_mono_signal(sp, buf, v, count);
   812 	  else
   813 	    mix_mono(sp, buf, v, count);
   814 	}
   815       else
   816 	{
   817 	  if (vp->panned == PANNED_MYSTERY)
   818 	    {
   819 	      if (vp->envelope_increment || vp->tremolo_phase_increment)
   820 		mix_mystery_signal(sp, buf, v, count);
   821 	      else
   822 		mix_mystery(sp, buf, v, count);
   823 	    }
   824 	  else if (vp->panned == PANNED_CENTER)
   825 	    {
   826 	      if (vp->envelope_increment || vp->tremolo_phase_increment)
   827 		mix_center_signal(sp, buf, v, count);
   828 	      else
   829 		mix_center(sp, buf, v, count);
   830 	    }
   831 	  else
   832 	    { 
   833 	      /* It's either full left or full right. In either case,
   834 		 every other sample is 0. Just get the offset right: */
   835 	      
   836 	      if (vp->envelope_increment || vp->tremolo_phase_increment)
   837 	      {
   838 	        if (vp->panned == PANNED_RIGHT)
   839 			mix_single_right_signal(sp, buf, v, count);
   840 		else mix_single_left_signal(sp, buf, v, count);
   841 	      }
   842 	      else 
   843 	      {
   844 	        if (vp->panned == PANNED_RIGHT)
   845 			mix_single_right(sp, buf, v, count);
   846 		else mix_single_left(sp, buf, v, count);
   847 	      }
   848 	    }
   849 	}
   850     }
   851 }