timidity/playmidi.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 13 Oct 2018 23:02:04 +0300
branchSDL-1.2
changeset 908 6b860486ce24
parent 878 294db2bca9b0
permissions -rw-r--r--
Mix_InitMP3: unload dll if mpg123_init() fails.
slouken@0
     1
/*
slouken@0
     2
    TiMidity -- Experimental MIDI to WAVE converter
slouken@0
     3
    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
slouken@0
     4
slouken@0
     5
    This program is free software; you can redistribute it and/or modify
slouken@518
     6
    it under the terms of the Perl Artistic License, available in COPYING.
slouken@518
     7
 */
slouken@0
     8
slouken@0
     9
#include <stdio.h>
slouken@0
    10
#include <stdlib.h>
slouken@0
    11
#include <string.h>
slouken@0
    12
patmandin@265
    13
#include <SDL_rwops.h>
patmandin@265
    14
slouken@0
    15
#include "config.h"
slouken@0
    16
#include "common.h"
slouken@0
    17
#include "instrum.h"
slouken@0
    18
#include "playmidi.h"
slouken@0
    19
#include "readmidi.h"
slouken@0
    20
#include "output.h"
slouken@0
    21
#include "mix.h"
slouken@319
    22
#include "ctrlmode.h"
slouken@0
    23
#include "timidity.h"
slouken@0
    24
slouken@0
    25
#include "tables.h"
slouken@0
    26
slouken@245
    27
slouken@245
    28
static int opt_expression_curve = 2;
slouken@245
    29
static int opt_volume_curve = 2;
slouken@245
    30
static int opt_stereo_surround = 0;
slouken@245
    31
slouken@245
    32
slouken@245
    33
Channel channel[MAXCHAN];
slouken@0
    34
Voice voice[MAX_VOICES];
slouken@245
    35
signed char drumvolume[MAXCHAN][MAXNOTE];
slouken@245
    36
signed char drumpanpot[MAXCHAN][MAXNOTE];
slouken@245
    37
signed char drumreverberation[MAXCHAN][MAXNOTE];
slouken@245
    38
signed char drumchorusdepth[MAXCHAN][MAXNOTE];
slouken@0
    39
slouken@0
    40
int
slouken@0
    41
    voices=DEFAULT_VOICES;
slouken@0
    42
slouken@0
    43
int32
slouken@0
    44
    control_ratio=0,
slouken@0
    45
    amplification=DEFAULT_AMPLIFICATION;
slouken@0
    46
slouken@245
    47
FLOAT_T
slouken@0
    48
    master_volume;
slouken@0
    49
slouken@0
    50
int32 drumchannels=DEFAULT_DRUMCHANNELS;
slouken@0
    51
int adjust_panning_immediately=0;
slouken@0
    52
slouken@0
    53
struct _MidiSong {
slouken@0
    54
	int32 samples;
slouken@0
    55
	MidiEvent *events;
slouken@0
    56
};
slouken@0
    57
static int midi_playing = 0;
slouken@0
    58
static int32 lost_notes, cut_notes;
slouken@0
    59
static int32 *buffer_pointer;
slouken@0
    60
static int32 buffered_count;
slouken@0
    61
extern int32 *common_buffer;
patmandin@264
    62
extern resample_t *resample_buffer; /* to free it on Timidity_Close */
slouken@0
    63
slouken@0
    64
static MidiEvent *event_list, *current_event;
slouken@0
    65
static int32 sample_count, current_sample;
slouken@0
    66
slouken@245
    67
int GM_System_On=0;
slouken@245
    68
int XG_System_On=0;
slouken@245
    69
int GS_System_On=0;
slouken@245
    70
int XG_System_reverb_type;
slouken@245
    71
int XG_System_chorus_type;
slouken@245
    72
int XG_System_variation_type;
slouken@245
    73
slouken@245
    74
slouken@0
    75
static void adjust_amplification(void)
slouken@0
    76
{ 
slouken@245
    77
  master_volume = (FLOAT_T)(amplification) / (FLOAT_T)100.0;
slouken@245
    78
  master_volume /= 2;
slouken@0
    79
}
slouken@0
    80
slouken@245
    81
slouken@245
    82
static void adjust_master_volume(int32 vol)
slouken@245
    83
{ 
slouken@245
    84
  master_volume = (double)(vol*amplification) / 1638400.0L;
slouken@245
    85
  master_volume /= 2;
slouken@245
    86
}
slouken@245
    87
slouken@245
    88
slouken@0
    89
static void reset_voices(void)
slouken@0
    90
{
slouken@0
    91
  int i;
slouken@0
    92
  for (i=0; i<MAX_VOICES; i++)
slouken@0
    93
    voice[i].status=VOICE_FREE;
slouken@0
    94
}
slouken@0
    95
slouken@0
    96
/* Process the Reset All Controllers event */
slouken@0
    97
static void reset_controllers(int c)
slouken@0
    98
{
slouken@0
    99
  channel[c].volume=90; /* Some standard says, although the SCC docs say 0. */
slouken@0
   100
  channel[c].expression=127; /* SCC-1 does this. */
slouken@0
   101
  channel[c].sustain=0;
slouken@0
   102
  channel[c].pitchbend=0x2000;
slouken@0
   103
  channel[c].pitchfactor=0; /* to be computed */
slouken@245
   104
slouken@245
   105
  channel[c].reverberation = 0;
slouken@245
   106
  channel[c].chorusdepth = 0;
slouken@0
   107
}
slouken@0
   108
slouken@0
   109
static void redraw_controllers(int c)
slouken@0
   110
{
slouken@0
   111
  ctl->volume(c, channel[c].volume);
slouken@0
   112
  ctl->expression(c, channel[c].expression);
slouken@0
   113
  ctl->sustain(c, channel[c].sustain);
slouken@0
   114
  ctl->pitch_bend(c, channel[c].pitchbend);
slouken@0
   115
}
slouken@0
   116
slouken@0
   117
static void reset_midi(void)
slouken@0
   118
{
slouken@0
   119
  int i;
slouken@245
   120
  for (i=0; i<MAXCHAN; i++)
slouken@0
   121
    {
slouken@0
   122
      reset_controllers(i);
slouken@0
   123
      /* The rest of these are unaffected by the Reset All Controllers event */
slouken@0
   124
      channel[i].program=default_program;
slouken@0
   125
      channel[i].panning=NO_PANNING;
slouken@0
   126
      channel[i].pitchsens=2;
slouken@0
   127
      channel[i].bank=0; /* tone bank or drum set */
slouken@245
   128
      channel[i].harmoniccontent=64,
slouken@245
   129
      channel[i].releasetime=64,
slouken@245
   130
      channel[i].attacktime=64,
slouken@245
   131
      channel[i].brightness=64,
slouken@245
   132
      channel[i].sfx=0;
slouken@0
   133
    }
slouken@0
   134
  reset_voices();
slouken@0
   135
}
slouken@0
   136
slouken@0
   137
static void select_sample(int v, Instrument *ip)
slouken@0
   138
{
slouken@245
   139
  int32 f, cdiff, diff, midfreq;
slouken@0
   140
  int s,i;
slouken@0
   141
  Sample *sp, *closest;
slouken@0
   142
slouken@0
   143
  s=ip->samples;
slouken@0
   144
  sp=ip->sample;
slouken@0
   145
slouken@0
   146
  if (s==1)
slouken@0
   147
    {
slouken@0
   148
      voice[v].sample=sp;
slouken@0
   149
      return;
slouken@0
   150
    }
slouken@0
   151
slouken@0
   152
  f=voice[v].orig_frequency;
slouken@0
   153
  /* 
slouken@0
   154
     No suitable sample found! We'll select the sample whose root
slouken@0
   155
     frequency is closest to the one we want. (Actually we should
slouken@0
   156
     probably convert the low, high, and root frequencies to MIDI note
slouken@0
   157
     values and compare those.) */
slouken@0
   158
slouken@0
   159
  cdiff=0x7FFFFFFF;
slouken@0
   160
  closest=sp=ip->sample;
slouken@245
   161
  midfreq = (sp->low_freq + sp->high_freq) / 2;
slouken@0
   162
  for(i=0; i<s; i++)
slouken@0
   163
    {
slouken@0
   164
      diff=sp->root_freq - f;
slouken@245
   165
  /*  But the root freq. can perfectly well lie outside the keyrange
slouken@245
   166
   *  frequencies, so let's try:
slouken@245
   167
   */
slouken@245
   168
      /* diff=midfreq - f; */
slouken@0
   169
      if (diff<0) diff=-diff;
slouken@0
   170
      if (diff<cdiff)
slouken@0
   171
	{
slouken@0
   172
	  cdiff=diff;
slouken@0
   173
	  closest=sp;
slouken@0
   174
	}
slouken@0
   175
      sp++;
slouken@0
   176
    }
slouken@0
   177
  voice[v].sample=closest;
slouken@0
   178
  return;
slouken@0
   179
}
slouken@0
   180
slouken@245
   181
slouken@245
   182
slouken@245
   183
static void select_stereo_samples(int v, InstrumentLayer *lp)
slouken@245
   184
{
slouken@245
   185
  Instrument *ip;
slouken@245
   186
  InstrumentLayer *nlp, *bestvel;
slouken@245
   187
  int diffvel, midvel, mindiff;
slouken@245
   188
slouken@245
   189
/* select closest velocity */
slouken@245
   190
  bestvel = lp;
slouken@245
   191
  mindiff = 500;
slouken@245
   192
  for (nlp = lp; nlp; nlp = nlp->next) {
slouken@245
   193
	midvel = (nlp->hi + nlp->lo)/2;
slouken@245
   194
	if (!midvel) diffvel = 127;
slouken@245
   195
	else if (voice[v].velocity < nlp->lo || voice[v].velocity > nlp->hi)
slouken@245
   196
		diffvel = 200;
slouken@245
   197
	else diffvel = voice[v].velocity - midvel;
slouken@245
   198
	if (diffvel < 0) diffvel = -diffvel;
slouken@245
   199
	if (diffvel < mindiff) {
slouken@245
   200
		mindiff = diffvel;
slouken@245
   201
		bestvel = nlp;
slouken@245
   202
	}
slouken@245
   203
  }
slouken@245
   204
  ip = bestvel->instrument;
slouken@245
   205
slouken@245
   206
  if (ip->right_sample) {
slouken@245
   207
    ip->sample = ip->right_sample;
slouken@245
   208
    ip->samples = ip->right_samples;
slouken@245
   209
    select_sample(v, ip);
slouken@245
   210
    voice[v].right_sample = voice[v].sample;
slouken@245
   211
  }
slouken@245
   212
  else voice[v].right_sample = 0;
slouken@245
   213
  ip->sample = ip->left_sample;
slouken@245
   214
  ip->samples = ip->left_samples;
slouken@245
   215
  select_sample(v, ip);
slouken@245
   216
}
slouken@245
   217
slouken@245
   218
slouken@0
   219
static void recompute_freq(int v)
slouken@0
   220
{
slouken@0
   221
  int 
slouken@0
   222
    sign=(voice[v].sample_increment < 0), /* for bidirectional loops */
slouken@0
   223
    pb=channel[voice[v].channel].pitchbend;
slouken@0
   224
  double a;
slouken@0
   225
  
slouken@0
   226
  if (!voice[v].sample->sample_rate)
slouken@0
   227
    return;
slouken@0
   228
slouken@0
   229
  if (voice[v].vibrato_control_ratio)
slouken@0
   230
    {
slouken@0
   231
      /* This instrument has vibrato. Invalidate any precomputed
slouken@0
   232
         sample_increments. */
slouken@0
   233
slouken@0
   234
      int i=VIBRATO_SAMPLE_INCREMENTS;
slouken@0
   235
      while (i--)
slouken@0
   236
	voice[v].vibrato_sample_increment[i]=0;
slouken@0
   237
    }
slouken@0
   238
slouken@0
   239
  if (pb==0x2000 || pb<0 || pb>0x3FFF)
slouken@0
   240
    voice[v].frequency=voice[v].orig_frequency;
slouken@0
   241
  else
slouken@0
   242
    {
slouken@0
   243
      pb-=0x2000;
slouken@0
   244
      if (!(channel[voice[v].channel].pitchfactor))
slouken@0
   245
	{
slouken@0
   246
	  /* Damn. Somebody bent the pitch. */
slouken@0
   247
	  int32 i=pb*channel[voice[v].channel].pitchsens;
slouken@0
   248
	  if (pb<0)
slouken@0
   249
	    i=-i;
slouken@0
   250
	  channel[voice[v].channel].pitchfactor=
slouken@245
   251
	    (FLOAT_T)(bend_fine[(i>>5) & 0xFF] * bend_coarse[i>>13]);
slouken@0
   252
	}
slouken@0
   253
      if (pb>0)
slouken@0
   254
	voice[v].frequency=
slouken@0
   255
	  (int32)(channel[voice[v].channel].pitchfactor *
slouken@0
   256
		  (double)(voice[v].orig_frequency));
slouken@0
   257
      else
slouken@0
   258
	voice[v].frequency=
slouken@0
   259
	  (int32)((double)(voice[v].orig_frequency) /
slouken@0
   260
		  channel[voice[v].channel].pitchfactor);
slouken@0
   261
    }
slouken@0
   262
slouken@0
   263
  a = FSCALE(((double)(voice[v].sample->sample_rate) *
slouken@0
   264
	      (double)(voice[v].frequency)) /
slouken@0
   265
	     ((double)(voice[v].sample->root_freq) *
slouken@0
   266
	      (double)(play_mode->rate)),
slouken@0
   267
	     FRACTION_BITS);
slouken@0
   268
slouken@0
   269
  if (sign) 
slouken@0
   270
    a = -a; /* need to preserve the loop direction */
slouken@0
   271
slouken@0
   272
  voice[v].sample_increment = (int32)(a);
slouken@0
   273
}
slouken@0
   274
slouken@245
   275
static int expr_curve[128] = {
slouken@245
   276
	7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 
slouken@245
   277
	11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 
slouken@245
   278
	15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21, 21, 22, 
slouken@245
   279
	22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 
slouken@245
   280
	32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 
slouken@245
   281
	45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 56, 57, 59, 60, 61, 63, 
slouken@245
   282
	64, 65, 67, 68, 70, 71, 73, 75, 76, 78, 80, 82, 83, 85, 87, 89, 
slouken@245
   283
	91, 93, 95, 97, 99, 102, 104, 106, 109, 111, 113, 116, 118, 121,
slouken@245
   284
	124, 127 
slouken@245
   285
};
slouken@245
   286
slouken@245
   287
static int panf(int pan, int speaker, int separation)
slouken@245
   288
{
slouken@245
   289
	int val;
slouken@245
   290
	val = abs(pan - speaker);
slouken@245
   291
	val = (val * 127) / separation;
slouken@245
   292
	val = 127 - val;
slouken@245
   293
	if (val < 0) val = 0;
slouken@245
   294
	if (val > 127) val = 127;
slouken@245
   295
	return expr_curve[val];
slouken@245
   296
}
slouken@245
   297
slouken@245
   298
slouken@245
   299
static int vcurve[128] = {
slouken@245
   300
0,0,18,29,36,42,47,51,55,58,
slouken@245
   301
60,63,65,67,69,71,73,74,76,77,
slouken@245
   302
79,80,81,82,83,84,85,86,87,88,
slouken@245
   303
89,90,91,92,92,93,94,95,95,96,
slouken@245
   304
97,97,98,99,99,100,100,101,101,102,
slouken@245
   305
103,103,104,104,105,105,106,106,106,107,
slouken@245
   306
107,108,108,109,109,109,110,110,111,111,
slouken@245
   307
111,112,112,112,113,113,114,114,114,115,
slouken@245
   308
115,115,116,116,116,116,117,117,117,118,
slouken@245
   309
118,118,119,119,119,119,120,120,120,120,
slouken@245
   310
121,121,121,122,122,122,122,123,123,123,
slouken@245
   311
123,123,124,124,124,124,125,125,125,125,
slouken@245
   312
126,126,126,126,126,127,127,127
slouken@245
   313
};
slouken@245
   314
slouken@0
   315
static void recompute_amp(int v)
slouken@0
   316
{
slouken@0
   317
  int32 tempamp;
slouken@245
   318
  int chan = voice[v].channel;
slouken@245
   319
  int panning = voice[v].panning;
slouken@245
   320
  int vol = channel[chan].volume;
slouken@245
   321
  int expr = channel[chan].expression;
slouken@245
   322
  int vel = vcurve[voice[v].velocity];
slouken@245
   323
  FLOAT_T curved_expression, curved_volume;
slouken@245
   324
slouken@245
   325
  if (channel[chan].kit)
slouken@245
   326
   {
slouken@245
   327
    int note = voice[v].sample->note_to_use;
slouken@245
   328
    if (note>0 && drumvolume[chan][note]>=0) vol = drumvolume[chan][note];
sezeroz@878
   329
    if (note>0 && drumpanpot[chan][note]>=0) panning = drumpanpot[chan][note];
slouken@245
   330
   }
slouken@245
   331
slouken@245
   332
  if (opt_expression_curve == 2) curved_expression = 127.0 * vol_table[expr];
slouken@245
   333
  else if (opt_expression_curve == 1) curved_expression = 127.0 * expr_table[expr];
slouken@245
   334
  else curved_expression = (FLOAT_T)expr;
slouken@245
   335
slouken@245
   336
  if (opt_volume_curve == 2) curved_volume = 127.0 * vol_table[vol];
slouken@245
   337
  else if (opt_volume_curve == 1) curved_volume = 127.0 * expr_table[vol];
slouken@245
   338
  else curved_volume = (FLOAT_T)vol;
slouken@245
   339
slouken@245
   340
  tempamp= (int32)((FLOAT_T)vel * curved_volume * curved_expression); /* 21 bits */
slouken@0
   341
slouken@0
   342
  /* TODO: use fscale */
slouken@0
   343
slouken@245
   344
  if (num_ochannels > 1)
slouken@0
   345
    {
slouken@245
   346
      if (panning > 60 && panning < 68)
slouken@0
   347
	{
slouken@0
   348
	  voice[v].panned=PANNED_CENTER;
slouken@0
   349
slouken@245
   350
	  if (num_ochannels == 6) voice[v].left_amp =
slouken@245
   351
		FSCALENEG((double) (tempamp) * voice[v].sample->volume *
slouken@245
   352
			    master_volume, 20);
slouken@245
   353
	  else voice[v].left_amp=
slouken@245
   354
	        FSCALENEG((double)(tempamp) * voice[v].sample->volume *
slouken@245
   355
			    master_volume, 21);
slouken@0
   356
	}
slouken@245
   357
      else if (panning<5)
slouken@0
   358
	{
slouken@0
   359
	  voice[v].panned = PANNED_LEFT;
slouken@0
   360
slouken@0
   361
	  voice[v].left_amp=
slouken@0
   362
	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
slouken@0
   363
		      20);
slouken@0
   364
	}
slouken@245
   365
      else if (panning>123)
slouken@0
   366
	{
slouken@0
   367
	  voice[v].panned = PANNED_RIGHT;
slouken@0
   368
slouken@0
   369
	  voice[v].left_amp= /* left_amp will be used */
slouken@0
   370
	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
slouken@0
   371
		      20);
slouken@0
   372
	}
slouken@0
   373
      else
slouken@0
   374
	{
slouken@245
   375
	  FLOAT_T refv = (double)(tempamp) * voice[v].sample->volume * master_volume;
slouken@245
   376
	  int wide_panning = 64;
slouken@245
   377
slouken@245
   378
	  if (num_ochannels == 4) wide_panning = 95;
slouken@245
   379
slouken@0
   380
	  voice[v].panned = PANNED_MYSTERY;
slouken@245
   381
	  voice[v].lfe_amp = FSCALENEG(refv * 64, 27);
slouken@0
   382
slouken@245
   383
		switch (num_ochannels)
slouken@245
   384
		{
slouken@245
   385
		    case 2:
slouken@245
   386
		      voice[v].lr_amp = 0;
slouken@245
   387
		      voice[v].left_amp = FSCALENEG(refv * (128-panning), 27);
slouken@245
   388
		      voice[v].ce_amp = 0;
slouken@245
   389
		      voice[v].right_amp = FSCALENEG(refv * panning, 27);
slouken@245
   390
		      voice[v].rr_amp = 0;
slouken@245
   391
		      break;
slouken@245
   392
		    case 4:
slouken@245
   393
		      voice[v].lr_amp = FSCALENEG(refv * panf(panning, 0, wide_panning), 27);
slouken@245
   394
		      voice[v].left_amp = FSCALENEG(refv * panf(panning, 32, wide_panning), 27);
slouken@245
   395
		      voice[v].ce_amp = 0;
slouken@245
   396
		      voice[v].right_amp = FSCALENEG(refv * panf(panning, 95, wide_panning), 27);
slouken@245
   397
		      voice[v].rr_amp = FSCALENEG(refv * panf(panning, 128, wide_panning), 27);
slouken@245
   398
		      break;
slouken@245
   399
		    case 6:
slouken@245
   400
		      voice[v].lr_amp = FSCALENEG(refv * panf(panning, 0, wide_panning), 27);
slouken@245
   401
		      voice[v].left_amp = FSCALENEG(refv * panf(panning, 32, wide_panning), 27);
slouken@245
   402
		      voice[v].ce_amp = FSCALENEG(refv * panf(panning, 64, wide_panning), 27);
slouken@245
   403
		      voice[v].right_amp = FSCALENEG(refv * panf(panning, 95, wide_panning), 27);
slouken@245
   404
		      voice[v].rr_amp = FSCALENEG(refv * panf(panning, 128, wide_panning), 27);
slouken@245
   405
		      break;
slouken@245
   406
		}
slouken@245
   407
slouken@0
   408
	}
slouken@0
   409
    }
slouken@0
   410
  else
slouken@0
   411
    {
slouken@0
   412
      voice[v].panned=PANNED_CENTER;
slouken@0
   413
slouken@0
   414
      voice[v].left_amp=
slouken@0
   415
	FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
slouken@0
   416
		  21);
slouken@0
   417
    }
slouken@0
   418
}
slouken@0
   419
slouken@245
   420
slouken@245
   421
#define NOT_CLONE 0
slouken@245
   422
#define STEREO_CLONE 1
slouken@245
   423
#define REVERB_CLONE 2
slouken@245
   424
#define CHORUS_CLONE 3
slouken@245
   425
slouken@245
   426
slouken@245
   427
/* just a variant of note_on() */
slouken@245
   428
static int vc_alloc(int j)
slouken@245
   429
{
slouken@245
   430
  int i=voices; 
slouken@245
   431
slouken@245
   432
  while (i--)
slouken@245
   433
    {
slouken@245
   434
      if (i == j) continue;
slouken@245
   435
      if (voice[i].status & VOICE_FREE) {
slouken@245
   436
	return i;
slouken@245
   437
      }
slouken@245
   438
    }
slouken@245
   439
  return -1;
slouken@245
   440
}
slouken@245
   441
slouken@245
   442
static void kill_note(int i);
slouken@245
   443
slouken@245
   444
static void kill_others(int i)
slouken@245
   445
{
slouken@245
   446
  int j=voices; 
slouken@245
   447
slouken@245
   448
  if (!voice[i].sample->exclusiveClass) return;
slouken@245
   449
slouken@245
   450
  while (j--)
slouken@245
   451
    {
slouken@245
   452
      if (voice[j].status & (VOICE_FREE|VOICE_OFF|VOICE_DIE)) continue;
slouken@245
   453
      if (i == j) continue;
slouken@245
   454
      if (voice[i].channel != voice[j].channel) continue;
slouken@245
   455
      if (voice[j].sample->note_to_use)
slouken@245
   456
      {
slouken@245
   457
    	if (voice[j].sample->exclusiveClass != voice[i].sample->exclusiveClass) continue;
slouken@245
   458
        kill_note(j);
slouken@245
   459
      }
slouken@245
   460
    }
slouken@245
   461
}
slouken@245
   462
slouken@245
   463
slouken@245
   464
static void clone_voice(Instrument *ip, int v, MidiEvent *e, int clone_type, int variationbank)
slouken@245
   465
{
slouken@250
   466
  int w, played_note, chorus=0, reverb=0, milli;
slouken@245
   467
  int chan = voice[v].channel;
slouken@245
   468
slouken@245
   469
  if (clone_type == STEREO_CLONE) {
slouken@245
   470
	if (!voice[v].right_sample && variationbank != 3) return;
slouken@245
   471
	if (variationbank == 6) return;
slouken@245
   472
  }
slouken@245
   473
slouken@245
   474
  if (channel[chan].kit) {
slouken@245
   475
	reverb = drumreverberation[chan][voice[v].note];
slouken@245
   476
	chorus = drumchorusdepth[chan][voice[v].note];
slouken@245
   477
  }
slouken@245
   478
  else {
slouken@245
   479
	reverb = channel[chan].reverberation;
slouken@245
   480
	chorus = channel[chan].chorusdepth;
slouken@245
   481
  }
slouken@245
   482
slouken@245
   483
  if (clone_type == REVERB_CLONE) chorus = 0;
slouken@245
   484
  else if (clone_type == CHORUS_CLONE) reverb = 0;
slouken@245
   485
  else if (clone_type == STEREO_CLONE) reverb = chorus = 0;
slouken@245
   486
slouken@245
   487
  if (reverb > 127) reverb = 127;
slouken@245
   488
  if (chorus > 127) chorus = 127;
slouken@245
   489
slouken@245
   490
  if (clone_type == CHORUS_CLONE) {
slouken@245
   491
	 if (variationbank == 32) chorus = 30;
slouken@245
   492
	 else if (variationbank == 33) chorus = 60;
slouken@245
   493
	 else if (variationbank == 34) chorus = 90;
slouken@245
   494
  }
slouken@245
   495
slouken@245
   496
  chorus /= 2;  /* This is an ad hoc adjustment. */
slouken@245
   497
slouken@245
   498
  if (!reverb && !chorus && clone_type != STEREO_CLONE) return;
slouken@245
   499
slouken@245
   500
  if ( (w = vc_alloc(v)) < 0 ) return;
slouken@245
   501
slouken@245
   502
  voice[w] = voice[v];
slouken@245
   503
  if (clone_type==STEREO_CLONE) voice[v].clone_voice = w;
slouken@245
   504
  voice[w].clone_voice = v;
slouken@245
   505
  voice[w].clone_type = clone_type;
slouken@245
   506
slouken@245
   507
  voice[w].sample = voice[v].right_sample;
slouken@245
   508
  voice[w].velocity= e->b;
slouken@245
   509
slouken@245
   510
  milli = play_mode->rate/1000;
slouken@245
   511
slouken@245
   512
  if (clone_type == STEREO_CLONE) {
slouken@245
   513
    int left, right, leftpan, rightpan;
slouken@245
   514
    int panrequest = voice[v].panning;
slouken@245
   515
    if (variationbank == 3) {
slouken@245
   516
	voice[v].panning = 0;
slouken@245
   517
	voice[w].panning = 127;
slouken@245
   518
    }
slouken@245
   519
    else {
slouken@245
   520
	if (voice[v].sample->panning > voice[w].sample->panning) {
slouken@245
   521
	  left = w;
slouken@245
   522
	  right = v;
slouken@245
   523
	}
slouken@245
   524
	else {
slouken@245
   525
	  left = v;
slouken@245
   526
	  right = w;
slouken@245
   527
	}
slouken@245
   528
#define INSTRUMENT_SEPARATION 12
slouken@245
   529
	leftpan = panrequest - INSTRUMENT_SEPARATION / 2;
slouken@245
   530
	rightpan = leftpan + INSTRUMENT_SEPARATION;
slouken@245
   531
	if (leftpan < 0) {
slouken@245
   532
		leftpan = 0;
slouken@245
   533
		rightpan = leftpan + INSTRUMENT_SEPARATION;
slouken@245
   534
	}
slouken@245
   535
	if (rightpan > 127) {
slouken@245
   536
		rightpan = 127;
slouken@245
   537
		leftpan = rightpan - INSTRUMENT_SEPARATION;
slouken@245
   538
	}
slouken@245
   539
	voice[left].panning = leftpan;
slouken@245
   540
	voice[right].panning = rightpan;
slouken@245
   541
	voice[right].echo_delay = 20 * milli;
slouken@245
   542
    }
slouken@245
   543
  }
slouken@245
   544
slouken@245
   545
  voice[w].volume = voice[w].sample->volume;
slouken@245
   546
slouken@245
   547
  if (reverb) {
slouken@245
   548
	if (opt_stereo_surround) {
slouken@245
   549
		if (voice[w].panning > 64) voice[w].panning = 127;
slouken@245
   550
		else voice[w].panning = 0;
slouken@245
   551
	}
slouken@245
   552
	else {
slouken@245
   553
		if (voice[v].panning < 64) voice[w].panning = 64 + reverb/2;
slouken@245
   554
		else voice[w].panning = 64 - reverb/2;
slouken@245
   555
	}
slouken@245
   556
slouken@245
   557
/* try 98->99 for melodic instruments ? (bit much for percussion) */
slouken@245
   558
	voice[w].volume *= vol_table[(127-reverb)/8 + 98];
slouken@245
   559
slouken@245
   560
	voice[w].echo_delay += reverb * milli;
slouken@245
   561
	voice[w].envelope_rate[DECAY] *= 2;
slouken@245
   562
	voice[w].envelope_rate[RELEASE] /= 2;
slouken@245
   563
slouken@245
   564
	if (XG_System_reverb_type >= 0) {
slouken@245
   565
	    int subtype = XG_System_reverb_type & 0x07;
slouken@245
   566
	    int rtype = XG_System_reverb_type >>3;
slouken@245
   567
	    switch (rtype) {
slouken@245
   568
		case 0: /* no effect */
slouken@245
   569
		  break;
slouken@245
   570
		case 1: /* hall */
slouken@245
   571
		  if (subtype) voice[w].echo_delay += 100 * milli;
slouken@245
   572
		  break;
slouken@245
   573
		case 2: /* room */
slouken@245
   574
		  voice[w].echo_delay /= 2;
slouken@245
   575
		  break;
slouken@245
   576
		case 3: /* stage */
slouken@245
   577
		  voice[w].velocity = voice[v].velocity;
slouken@245
   578
		  break;
slouken@245
   579
		case 4: /* plate */
slouken@245
   580
		  voice[w].panning = voice[v].panning;
slouken@245
   581
		  break;
slouken@245
   582
		case 16: /* white room */
slouken@245
   583
		  voice[w].echo_delay = 0;
slouken@245
   584
		  break;
slouken@245
   585
		case 17: /* tunnel */
slouken@245
   586
		  voice[w].echo_delay *= 2;
slouken@245
   587
		  voice[w].velocity /= 2;
slouken@245
   588
		  break;
slouken@245
   589
		case 18: /* canyon */
slouken@245
   590
		  voice[w].echo_delay *= 2;
slouken@245
   591
		  break;
slouken@245
   592
		case 19: /* basement */
slouken@245
   593
		  voice[w].velocity /= 2;
slouken@245
   594
		  break;
slouken@245
   595
	        default: break;
slouken@245
   596
	    }
slouken@245
   597
	}
slouken@245
   598
  }
slouken@245
   599
  played_note = voice[w].sample->note_to_use;
slouken@245
   600
  if (!played_note) {
slouken@245
   601
	played_note = e->a & 0x7f;
slouken@245
   602
	if (variationbank == 35) played_note += 12;
slouken@245
   603
	else if (variationbank == 36) played_note -= 12;
slouken@245
   604
	else if (variationbank == 37) played_note += 7;
slouken@245
   605
	else if (variationbank == 36) played_note -= 7;
slouken@245
   606
  }
slouken@245
   607
#if 0
slouken@245
   608
  played_note = ( (played_note - voice[w].sample->freq_center) * voice[w].sample->freq_scale ) / 1024 +
slouken@245
   609
		voice[w].sample->freq_center;
slouken@245
   610
#endif
slouken@245
   611
  voice[w].note = played_note;
slouken@245
   612
  voice[w].orig_frequency = freq_table[played_note];
slouken@245
   613
slouken@245
   614
  if (chorus) {
slouken@245
   615
	if (opt_stereo_surround) {
slouken@245
   616
	  if (voice[v].panning < 64) voice[w].panning = voice[v].panning + 32;
slouken@245
   617
	  else voice[w].panning = voice[v].panning - 32;
slouken@245
   618
	}
slouken@245
   619
slouken@245
   620
	if (!voice[w].vibrato_control_ratio) {
slouken@245
   621
		voice[w].vibrato_control_ratio = 100;
slouken@245
   622
		voice[w].vibrato_depth = 6;
slouken@245
   623
		voice[w].vibrato_sweep = 74;
slouken@245
   624
	}
slouken@245
   625
	voice[w].volume *= 0.40;
slouken@245
   626
	voice[v].volume = voice[w].volume;
slouken@245
   627
	recompute_amp(v);
slouken@245
   628
        apply_envelope_to_amp(v);
slouken@245
   629
	voice[w].vibrato_sweep = chorus/2;
slouken@245
   630
	voice[w].vibrato_depth /= 2;
slouken@245
   631
	if (!voice[w].vibrato_depth) voice[w].vibrato_depth = 2;
slouken@245
   632
	voice[w].vibrato_control_ratio /= 2;
slouken@245
   633
	voice[w].echo_delay += 30 * milli;
slouken@245
   634
slouken@245
   635
	if (XG_System_chorus_type >= 0) {
slouken@245
   636
	    int subtype = XG_System_chorus_type & 0x07;
slouken@245
   637
	    int chtype = 0x0f & (XG_System_chorus_type >> 3);
slouken@245
   638
	    switch (chtype) {
slouken@245
   639
		case 0: /* no effect */
slouken@245
   640
		  break;
slouken@245
   641
		case 1: /* chorus */
slouken@245
   642
		  chorus /= 3;
slouken@245
   643
		  if(channel[ voice[w].channel ].pitchbend + chorus < 0x2000)
slouken@245
   644
            		voice[w].orig_frequency =
slouken@245
   645
				(uint32)( (FLOAT_T)voice[w].orig_frequency * bend_fine[chorus] );
slouken@245
   646
        	  else voice[w].orig_frequency =
slouken@245
   647
			(uint32)( (FLOAT_T)voice[w].orig_frequency / bend_fine[chorus] );
slouken@245
   648
		  if (subtype) voice[w].vibrato_depth *= 2;
slouken@245
   649
		  break;
slouken@245
   650
		case 2: /* celeste */
slouken@245
   651
		  voice[w].orig_frequency += (voice[w].orig_frequency/128) * chorus;
slouken@245
   652
		  break;
slouken@245
   653
		case 3: /* flanger */
slouken@245
   654
		  voice[w].vibrato_control_ratio = 10;
slouken@245
   655
		  voice[w].vibrato_depth = 100;
slouken@245
   656
		  voice[w].vibrato_sweep = 8;
slouken@245
   657
		  voice[w].echo_delay += 200 * milli;
slouken@245
   658
		  break;
slouken@245
   659
		case 4: /* symphonic : cf Children of the Night /128 bad, /1024 ok */
slouken@245
   660
		  voice[w].orig_frequency += (voice[w].orig_frequency/512) * chorus;
slouken@245
   661
		  voice[v].orig_frequency -= (voice[v].orig_frequency/512) * chorus;
slouken@245
   662
		  recompute_freq(v);
slouken@245
   663
		  break;
slouken@245
   664
		case 8: /* phaser */
slouken@245
   665
		  break;
slouken@245
   666
	      default:
slouken@245
   667
		  break;
slouken@245
   668
	    }
slouken@245
   669
	}
slouken@245
   670
	else {
slouken@245
   671
	    chorus /= 3;
slouken@245
   672
	    if(channel[ voice[w].channel ].pitchbend + chorus < 0x2000)
slouken@245
   673
          	voice[w].orig_frequency =
slouken@245
   674
			(uint32)( (FLOAT_T)voice[w].orig_frequency * bend_fine[chorus] );
slouken@245
   675
            else voice[w].orig_frequency =
slouken@245
   676
		(uint32)( (FLOAT_T)voice[w].orig_frequency / bend_fine[chorus] );
slouken@245
   677
	}
slouken@245
   678
  }
slouken@245
   679
#if 0
slouken@245
   680
  voice[w].loop_start = voice[w].sample->loop_start;
slouken@245
   681
  voice[w].loop_end = voice[w].sample->loop_end;
slouken@245
   682
#endif
slouken@245
   683
  voice[w].echo_delay_count = voice[w].echo_delay;
slouken@245
   684
  if (reverb) voice[w].echo_delay *= 2;
slouken@245
   685
slouken@245
   686
  recompute_freq(w);
slouken@245
   687
  recompute_amp(w);
slouken@245
   688
  if (voice[w].sample->modes & MODES_ENVELOPE)
slouken@245
   689
    {
slouken@245
   690
      /* Ramp up from 0 */
slouken@245
   691
      voice[w].envelope_stage=ATTACK;
slouken@245
   692
      voice[w].modulation_stage=ATTACK;
slouken@245
   693
      voice[w].envelope_volume=0;
slouken@245
   694
      voice[w].modulation_volume=0;
slouken@245
   695
      voice[w].control_counter=0;
slouken@245
   696
      voice[w].modulation_counter=0;
slouken@245
   697
      recompute_envelope(w);
slouken@245
   698
      /*recompute_modulation(w);*/
slouken@245
   699
    }
slouken@245
   700
  else
slouken@245
   701
    {
slouken@245
   702
      voice[w].envelope_increment=0;
slouken@245
   703
      voice[w].modulation_increment=0;
slouken@245
   704
    }
slouken@245
   705
  apply_envelope_to_amp(w);
slouken@245
   706
}
slouken@245
   707
slouken@245
   708
slouken@245
   709
static void xremap(int *banknumpt, int *this_notept, int this_kit) {
slouken@245
   710
	int i, newmap;
slouken@245
   711
	int banknum = *banknumpt;
slouken@245
   712
	int this_note = *this_notept;
slouken@245
   713
	int newbank, newnote;
slouken@245
   714
slouken@245
   715
	if (!this_kit) {
slouken@245
   716
		if (banknum == SFXBANK && tonebank[SFXBANK]) return;
slouken@245
   717
		if (banknum == SFXBANK && tonebank[120]) *banknumpt = 120;
slouken@245
   718
		return;
slouken@245
   719
	}
slouken@245
   720
slouken@245
   721
	if (this_kit != 127 && this_kit != 126) return;
slouken@245
   722
slouken@245
   723
	for (i = 0; i < XMAPMAX; i++) {
slouken@245
   724
		newmap = xmap[i][0];
slouken@245
   725
		if (!newmap) return;
slouken@245
   726
		if (this_kit == 127 && newmap != XGDRUM) continue;
slouken@245
   727
		if (this_kit == 126 && newmap != SFXDRUM1) continue;
slouken@245
   728
		if (xmap[i][1] != banknum) continue;
slouken@245
   729
		if (xmap[i][3] != this_note) continue;
slouken@245
   730
		newbank = xmap[i][2];
slouken@245
   731
		newnote = xmap[i][4];
slouken@245
   732
		if (newbank == banknum && newnote == this_note) return;
slouken@245
   733
		if (!drumset[newbank]) return;
slouken@245
   734
		if (!drumset[newbank]->tone[newnote].layer) return;
slouken@245
   735
		if (drumset[newbank]->tone[newnote].layer == MAGIC_LOAD_INSTRUMENT) return;
slouken@245
   736
		*banknumpt = newbank;
slouken@245
   737
		*this_notept = newnote;
slouken@245
   738
		return;
slouken@245
   739
	}
slouken@245
   740
}
slouken@245
   741
slouken@245
   742
slouken@0
   743
static void start_note(MidiEvent *e, int i)
slouken@0
   744
{
slouken@245
   745
  InstrumentLayer *lp;
slouken@0
   746
  Instrument *ip;
slouken@245
   747
  int j, banknum, ch=e->channel;
slouken@245
   748
  int played_note, drumpan=NO_PANNING;
slouken@245
   749
  int32 rt;
slouken@245
   750
  int attacktime, releasetime, decaytime, variationbank;
slouken@245
   751
  int brightness = channel[ch].brightness;
slouken@245
   752
  int harmoniccontent = channel[ch].harmoniccontent;
slouken@245
   753
  int this_note = e->a;
slouken@245
   754
  int this_velocity = e->b;
slouken@245
   755
  int drumsflag = channel[ch].kit;
slouken@245
   756
  int this_prog = channel[ch].program;
slouken@0
   757
slouken@245
   758
  if (channel[ch].sfx) banknum=channel[ch].sfx;
slouken@245
   759
  else banknum=channel[ch].bank;
slouken@245
   760
slouken@245
   761
  voice[i].velocity=this_velocity;
slouken@245
   762
slouken@245
   763
  if (XG_System_On) xremap(&banknum, &this_note, drumsflag);
slouken@245
   764
  /*   if (current_config_pc42b) pcmap(&banknum, &this_note, &this_prog, &drumsflag); */
slouken@245
   765
slouken@245
   766
  if (drumsflag)
slouken@0
   767
    {
slouken@245
   768
      if (!(lp=drumset[banknum]->tone[this_note].layer))
slouken@0
   769
	{
slouken@245
   770
	  if (!(lp=drumset[0]->tone[this_note].layer))
slouken@0
   771
	    return; /* No instrument? Then we can't play. */
slouken@0
   772
	}
slouken@245
   773
      ip = lp->instrument;
slouken@245
   774
      if (ip->type == INST_GUS && ip->samples != 1)
slouken@0
   775
	{
slouken@0
   776
	  ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 
slouken@0
   777
	       "Strange: percussion instrument with %d samples!", ip->samples);
slouken@0
   778
	}
slouken@0
   779
slouken@0
   780
      if (ip->sample->note_to_use) /* Do we have a fixed pitch? */
slouken@245
   781
	{
slouken@245
   782
	  voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
slouken@245
   783
	  drumpan=drumpanpot[ch][(int)ip->sample->note_to_use];
slouken@245
   784
	}
slouken@0
   785
      else
slouken@245
   786
	voice[i].orig_frequency=freq_table[this_note & 0x7F];
slouken@245
   787
slouken@0
   788
    }
slouken@0
   789
  else
slouken@0
   790
    {
slouken@245
   791
      if (channel[ch].program==SPECIAL_PROGRAM)
slouken@245
   792
	lp=default_instrument;
slouken@245
   793
      else if (!(lp=tonebank[channel[ch].bank]->
slouken@245
   794
		 tone[channel[ch].program].layer))
slouken@0
   795
	{
slouken@245
   796
	  if (!(lp=tonebank[0]->tone[this_prog].layer))
slouken@0
   797
	    return; /* No instrument? Then we can't play. */
slouken@0
   798
	}
slouken@245
   799
      ip = lp->instrument;
slouken@0
   800
      if (ip->sample->note_to_use) /* Fixed-pitch instrument? */
slouken@0
   801
	voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
slouken@0
   802
      else
slouken@245
   803
	voice[i].orig_frequency=freq_table[this_note & 0x7F];
slouken@0
   804
    }
slouken@0
   805
slouken@245
   806
    select_stereo_samples(i, lp);
slouken@245
   807
slouken@245
   808
  voice[i].starttime = e->time;
slouken@245
   809
  played_note = voice[i].sample->note_to_use;
slouken@245
   810
slouken@245
   811
  if (!played_note || !drumsflag) played_note = this_note & 0x7f;
slouken@245
   812
#if 0
slouken@245
   813
  played_note = ( (played_note - voice[i].sample->freq_center) * voice[i].sample->freq_scale ) / 1024 +
slouken@245
   814
		voice[i].sample->freq_center;
slouken@245
   815
#endif
slouken@0
   816
  voice[i].status=VOICE_ON;
slouken@245
   817
  voice[i].channel=ch;
slouken@245
   818
  voice[i].note=played_note;
slouken@245
   819
  voice[i].velocity=this_velocity;
slouken@0
   820
  voice[i].sample_offset=0;
slouken@0
   821
  voice[i].sample_increment=0; /* make sure it isn't negative */
slouken@0
   822
slouken@0
   823
  voice[i].tremolo_phase=0;
slouken@0
   824
  voice[i].tremolo_phase_increment=voice[i].sample->tremolo_phase_increment;
slouken@0
   825
  voice[i].tremolo_sweep=voice[i].sample->tremolo_sweep_increment;
slouken@0
   826
  voice[i].tremolo_sweep_position=0;
slouken@0
   827
slouken@0
   828
  voice[i].vibrato_sweep=voice[i].sample->vibrato_sweep_increment;
slouken@0
   829
  voice[i].vibrato_sweep_position=0;
slouken@245
   830
  voice[i].vibrato_depth=voice[i].sample->vibrato_depth;
slouken@0
   831
  voice[i].vibrato_control_ratio=voice[i].sample->vibrato_control_ratio;
slouken@0
   832
  voice[i].vibrato_control_counter=voice[i].vibrato_phase=0;
slouken@245
   833
  voice[i].vibrato_delay = voice[i].sample->vibrato_delay;
slouken@245
   834
slouken@245
   835
  kill_others(i);
slouken@245
   836
slouken@0
   837
  for (j=0; j<VIBRATO_SAMPLE_INCREMENTS; j++)
slouken@0
   838
    voice[i].vibrato_sample_increment[j]=0;
slouken@0
   839
slouken@245
   840
slouken@245
   841
  attacktime = channel[ch].attacktime;
slouken@245
   842
  releasetime = channel[ch].releasetime;
slouken@245
   843
  decaytime = 64;
slouken@245
   844
  variationbank = channel[ch].variationbank;
slouken@245
   845
slouken@245
   846
  switch (variationbank) {
slouken@245
   847
	case  8:
slouken@245
   848
		attacktime = 64+32;
slouken@245
   849
		break;
slouken@245
   850
	case 12:
slouken@245
   851
		decaytime = 64-32;
slouken@245
   852
		break;
slouken@245
   853
	case 16:
slouken@245
   854
		brightness = 64+16;
slouken@245
   855
		break;
slouken@245
   856
	case 17:
slouken@245
   857
		brightness = 64+32;
slouken@245
   858
		break;
slouken@245
   859
	case 18:
slouken@245
   860
		brightness = 64-16;
slouken@245
   861
		break;
slouken@245
   862
	case 19:
slouken@245
   863
		brightness = 64-32;
slouken@245
   864
		break;
slouken@245
   865
	case 20:
slouken@245
   866
		harmoniccontent = 64+16;
slouken@245
   867
		break;
slouken@245
   868
#if 0
slouken@245
   869
	case 24:
slouken@245
   870
		voice[i].modEnvToFilterFc=2.0;
slouken@245
   871
      		voice[i].sample->cutoff_freq = 800;
slouken@245
   872
		break;
slouken@245
   873
	case 25:
slouken@245
   874
		voice[i].modEnvToFilterFc=-2.0;
slouken@245
   875
      		voice[i].sample->cutoff_freq = 800;
slouken@245
   876
		break;
slouken@245
   877
	case 27:
slouken@245
   878
		voice[i].modLfoToFilterFc=2.0;
slouken@245
   879
		voice[i].lfo_phase_increment=109;
slouken@245
   880
		voice[i].lfo_sweep=122;
slouken@245
   881
      		voice[i].sample->cutoff_freq = 800;
slouken@245
   882
		break;
slouken@245
   883
	case 28:
slouken@245
   884
		voice[i].modLfoToFilterFc=-2.0;
slouken@245
   885
		voice[i].lfo_phase_increment=109;
slouken@245
   886
		voice[i].lfo_sweep=122;
slouken@245
   887
      		voice[i].sample->cutoff_freq = 800;
slouken@245
   888
		break;
slouken@245
   889
#endif
slouken@245
   890
	default:
slouken@245
   891
		break;
slouken@245
   892
  }
slouken@245
   893
slouken@245
   894
slouken@245
   895
  for (j=ATTACK; j<MAXPOINT; j++)
slouken@245
   896
    {
slouken@245
   897
	voice[i].envelope_rate[j]=voice[i].sample->envelope_rate[j];
slouken@245
   898
	voice[i].envelope_offset[j]=voice[i].sample->envelope_offset[j];
slouken@245
   899
    }
slouken@245
   900
slouken@245
   901
  voice[i].echo_delay=voice[i].envelope_rate[DELAY];
slouken@245
   902
  voice[i].echo_delay_count = voice[i].echo_delay;
slouken@245
   903
slouken@245
   904
  if (attacktime!=64)
slouken@245
   905
    {
slouken@245
   906
	rt = voice[i].envelope_rate[ATTACK];
slouken@245
   907
	rt = rt + ( (64-attacktime)*rt ) / 100;
slouken@245
   908
	if (rt > 1000) voice[i].envelope_rate[ATTACK] = rt;
slouken@245
   909
    }
slouken@245
   910
  if (releasetime!=64)
slouken@245
   911
    {
slouken@245
   912
	rt = voice[i].envelope_rate[RELEASE];
slouken@245
   913
	rt = rt + ( (64-releasetime)*rt ) / 100;
slouken@245
   914
	if (rt > 1000) voice[i].envelope_rate[RELEASE] = rt;
slouken@245
   915
    }
slouken@245
   916
  if (decaytime!=64)
slouken@245
   917
    {
slouken@245
   918
	rt = voice[i].envelope_rate[DECAY];
slouken@245
   919
	rt = rt + ( (64-decaytime)*rt ) / 100;
slouken@245
   920
	if (rt > 1000) voice[i].envelope_rate[DECAY] = rt;
slouken@245
   921
    }
slouken@245
   922
slouken@245
   923
  if (channel[ch].panning != NO_PANNING)
slouken@245
   924
    voice[i].panning=channel[ch].panning;
slouken@0
   925
  else
slouken@0
   926
    voice[i].panning=voice[i].sample->panning;
slouken@245
   927
  if (drumpan != NO_PANNING)
slouken@245
   928
    voice[i].panning=drumpan;
slouken@245
   929
slouken@245
   930
  if (variationbank == 1) {
slouken@245
   931
    int pan = voice[i].panning;
slouken@245
   932
    int disturb = 0;
slouken@245
   933
    /* If they're close up (no reverb) and you are behind the pianist,
slouken@245
   934
     * high notes come from the right, so we'll spread piano etc. notes
slouken@245
   935
     * out horizontally according to their pitches.
slouken@245
   936
     */
slouken@245
   937
    if (this_prog < 21) {
slouken@245
   938
	    int n = voice[i].velocity - 32;
slouken@245
   939
	    if (n < 0) n = 0;
slouken@245
   940
	    if (n > 64) n = 64;
slouken@245
   941
	    pan = pan/2 + n;
slouken@245
   942
	}
slouken@245
   943
    /* For other types of instruments, the music sounds more alive if
slouken@245
   944
     * notes come from slightly different directions.  However, instruments
slouken@245
   945
     * do drift around in a sometimes disconcerting way, so the following
slouken@245
   946
     * might not be such a good idea.
slouken@245
   947
     */
slouken@245
   948
    else disturb = (voice[i].velocity/32 % 8) +
slouken@245
   949
	(voice[i].note % 8); /* /16? */
slouken@245
   950
slouken@245
   951
    if (pan < 64) pan += disturb;
slouken@245
   952
    else pan -= disturb;
slouken@245
   953
    if (pan < 0) pan = 0;
slouken@245
   954
    else if (pan > 127) pan = 127;
slouken@245
   955
    voice[i].panning = pan;
slouken@245
   956
  }
slouken@0
   957
slouken@0
   958
  recompute_freq(i);
slouken@0
   959
  recompute_amp(i);
slouken@0
   960
  if (voice[i].sample->modes & MODES_ENVELOPE)
slouken@0
   961
    {
slouken@0
   962
      /* Ramp up from 0 */
slouken@245
   963
      voice[i].envelope_stage=ATTACK;
slouken@0
   964
      voice[i].envelope_volume=0;
slouken@0
   965
      voice[i].control_counter=0;
slouken@0
   966
      recompute_envelope(i);
slouken@0
   967
    }
slouken@0
   968
  else
slouken@0
   969
    {
slouken@0
   970
      voice[i].envelope_increment=0;
slouken@0
   971
    }
slouken@245
   972
  apply_envelope_to_amp(i);
slouken@245
   973
slouken@245
   974
  voice[i].clone_voice = -1;
slouken@245
   975
  voice[i].clone_type = NOT_CLONE;
slouken@245
   976
slouken@245
   977
  clone_voice(ip, i, e, STEREO_CLONE, variationbank);
slouken@245
   978
  clone_voice(ip, i, e, CHORUS_CLONE, variationbank);
slouken@245
   979
  clone_voice(ip, i, e, REVERB_CLONE, variationbank);
slouken@245
   980
slouken@0
   981
  ctl->note(i);
slouken@0
   982
}
slouken@0
   983
slouken@0
   984
static void kill_note(int i)
slouken@0
   985
{
slouken@0
   986
  voice[i].status=VOICE_DIE;
slouken@245
   987
  if (voice[i].clone_voice >= 0)
slouken@245
   988
	voice[ voice[i].clone_voice ].status=VOICE_DIE;
slouken@0
   989
  ctl->note(i);
slouken@0
   990
}
slouken@0
   991
slouken@245
   992
slouken@0
   993
/* Only one instance of a note can be playing on a single channel. */
slouken@0
   994
static void note_on(MidiEvent *e)
slouken@0
   995
{
slouken@0
   996
  int i=voices, lowest=-1; 
slouken@0
   997
  int32 lv=0x7FFFFFFF, v;
slouken@0
   998
slouken@0
   999
  while (i--)
slouken@0
  1000
    {
slouken@0
  1001
      if (voice[i].status == VOICE_FREE)
slouken@0
  1002
	lowest=i; /* Can't get a lower volume than silence */
slouken@0
  1003
      else if (voice[i].channel==e->channel && 
slouken@0
  1004
	       (voice[i].note==e->a || channel[voice[i].channel].mono))
slouken@0
  1005
	kill_note(i);
slouken@0
  1006
    }
slouken@0
  1007
slouken@0
  1008
  if (lowest != -1)
slouken@0
  1009
    {
slouken@0
  1010
      /* Found a free voice. */
slouken@0
  1011
      start_note(e,lowest);
slouken@0
  1012
      return;
slouken@0
  1013
    }
slouken@0
  1014
  
slouken@245
  1015
#if 0
slouken@0
  1016
  /* Look for the decaying note with the lowest volume */
slouken@0
  1017
  i=voices;
slouken@0
  1018
  while (i--)
slouken@0
  1019
    {
slouken@245
  1020
      if (voice[i].status & ~(VOICE_ON | VOICE_DIE | VOICE_FREE))
slouken@0
  1021
	{
slouken@0
  1022
	  v=voice[i].left_mix;
slouken@0
  1023
	  if ((voice[i].panned==PANNED_MYSTERY) && (voice[i].right_mix>v))
slouken@0
  1024
	    v=voice[i].right_mix;
slouken@0
  1025
	  if (v<lv)
slouken@0
  1026
	    {
slouken@0
  1027
	      lv=v;
slouken@0
  1028
	      lowest=i;
slouken@0
  1029
	    }
slouken@0
  1030
	}
slouken@0
  1031
    }
slouken@245
  1032
#endif
slouken@245
  1033
slouken@245
  1034
  /* Look for the decaying note with the lowest volume */
slouken@245
  1035
  if (lowest==-1)
slouken@245
  1036
   {
slouken@245
  1037
   i=voices;
slouken@245
  1038
   while (i--)
slouken@245
  1039
    {
slouken@245
  1040
      if ( (voice[i].status & ~(VOICE_ON | VOICE_DIE | VOICE_FREE)) &&
slouken@245
  1041
	  (!voice[i].clone_type))
slouken@245
  1042
	{
slouken@245
  1043
	  v=voice[i].left_mix;
slouken@245
  1044
	  if ((voice[i].panned==PANNED_MYSTERY) && (voice[i].right_mix>v))
slouken@245
  1045
	    v=voice[i].right_mix;
slouken@245
  1046
	  if (v<lv)
slouken@245
  1047
	    {
slouken@245
  1048
	      lv=v;
slouken@245
  1049
	      lowest=i;
slouken@245
  1050
	    }
slouken@245
  1051
	}
slouken@245
  1052
    }
slouken@245
  1053
   }
slouken@0
  1054
slouken@0
  1055
  if (lowest != -1)
slouken@0
  1056
    {
slouken@245
  1057
      int cl = voice[lowest].clone_voice;
slouken@245
  1058
slouken@0
  1059
      /* This can still cause a click, but if we had a free voice to
slouken@0
  1060
	 spare for ramping down this note, we wouldn't need to kill it
slouken@0
  1061
	 in the first place... Still, this needs to be fixed. Perhaps
slouken@0
  1062
	 we could use a reserve of voices to play dying notes only. */
slouken@245
  1063
slouken@245
  1064
      if (cl >= 0) {
slouken@245
  1065
	if (voice[cl].clone_type==STEREO_CLONE ||
slouken@245
  1066
		       	(!voice[cl].clone_type && voice[lowest].clone_type==STEREO_CLONE))
slouken@245
  1067
	   voice[cl].status=VOICE_FREE;
slouken@245
  1068
	else if (voice[cl].clone_voice==lowest) voice[cl].clone_voice=-1;
slouken@245
  1069
      }
slouken@245
  1070
slouken@0
  1071
      cut_notes++;
slouken@0
  1072
      voice[lowest].status=VOICE_FREE;
slouken@0
  1073
      ctl->note(lowest);
slouken@0
  1074
      start_note(e,lowest);
slouken@0
  1075
    }
slouken@0
  1076
  else
slouken@0
  1077
    lost_notes++;
slouken@0
  1078
}
slouken@0
  1079
slouken@0
  1080
static void finish_note(int i)
slouken@0
  1081
{
slouken@0
  1082
  if (voice[i].sample->modes & MODES_ENVELOPE)
slouken@0
  1083
    {
slouken@0
  1084
      /* We need to get the envelope out of Sustain stage */
slouken@0
  1085
      voice[i].envelope_stage=3;
slouken@0
  1086
      voice[i].status=VOICE_OFF;
slouken@0
  1087
      recompute_envelope(i);
slouken@0
  1088
      apply_envelope_to_amp(i);
slouken@0
  1089
      ctl->note(i);
slouken@0
  1090
    }
slouken@0
  1091
  else
slouken@0
  1092
    {
slouken@0
  1093
      /* Set status to OFF so resample_voice() will let this voice out
slouken@0
  1094
         of its loop, if any. In any case, this voice dies when it
slouken@0
  1095
         hits the end of its data (ofs>=data_length). */
slouken@0
  1096
      voice[i].status=VOICE_OFF;
slouken@0
  1097
    }
slouken@245
  1098
slouken@245
  1099
  { int v;
slouken@245
  1100
    if ( (v=voice[i].clone_voice) >= 0)
slouken@245
  1101
      {
slouken@245
  1102
	voice[i].clone_voice = -1;
slouken@245
  1103
        finish_note(v);
slouken@245
  1104
      }
slouken@245
  1105
  }
slouken@0
  1106
}
slouken@0
  1107
slouken@0
  1108
static void note_off(MidiEvent *e)
slouken@0
  1109
{
slouken@245
  1110
  int i=voices, v;
slouken@0
  1111
  while (i--)
slouken@0
  1112
    if (voice[i].status==VOICE_ON &&
slouken@0
  1113
	voice[i].channel==e->channel &&
slouken@0
  1114
	voice[i].note==e->a)
slouken@0
  1115
      {
slouken@0
  1116
	if (channel[e->channel].sustain)
slouken@0
  1117
	  {
slouken@0
  1118
	    voice[i].status=VOICE_SUSTAINED;
slouken@245
  1119
slouken@245
  1120
    	    if ( (v=voice[i].clone_voice) >= 0)
slouken@245
  1121
	      {
slouken@245
  1122
		if (voice[v].status == VOICE_ON)
slouken@245
  1123
		  voice[v].status=VOICE_SUSTAINED;
slouken@245
  1124
	      }
slouken@245
  1125
slouken@0
  1126
	    ctl->note(i);
slouken@0
  1127
	  }
slouken@0
  1128
	else
slouken@0
  1129
	  finish_note(i);
slouken@0
  1130
	return;
slouken@0
  1131
      }
slouken@0
  1132
}
slouken@0
  1133
slouken@0
  1134
/* Process the All Notes Off event */
slouken@0
  1135
static void all_notes_off(int c)
slouken@0
  1136
{
slouken@0
  1137
  int i=voices;
slouken@0
  1138
  ctl->cmsg(CMSG_INFO, VERB_DEBUG, "All notes off on channel %d", c);
slouken@0
  1139
  while (i--)
slouken@0
  1140
    if (voice[i].status==VOICE_ON &&
slouken@0
  1141
	voice[i].channel==c)
slouken@0
  1142
      {
slouken@0
  1143
	if (channel[c].sustain) 
slouken@0
  1144
	  {
slouken@0
  1145
	    voice[i].status=VOICE_SUSTAINED;
slouken@0
  1146
	    ctl->note(i);
slouken@0
  1147
	  }
slouken@0
  1148
	else
slouken@0
  1149
	  finish_note(i);
slouken@0
  1150
      }
slouken@0
  1151
}
slouken@0
  1152
slouken@0
  1153
/* Process the All Sounds Off event */
slouken@0
  1154
static void all_sounds_off(int c)
slouken@0
  1155
{
slouken@0
  1156
  int i=voices;
slouken@0
  1157
  while (i--)
slouken@0
  1158
    if (voice[i].channel==c && 
slouken@0
  1159
	voice[i].status != VOICE_FREE &&
slouken@0
  1160
	voice[i].status != VOICE_DIE)
slouken@0
  1161
      {
slouken@0
  1162
	kill_note(i);
slouken@0
  1163
      }
slouken@0
  1164
}
slouken@0
  1165
slouken@0
  1166
static void adjust_pressure(MidiEvent *e)
slouken@0
  1167
{
slouken@0
  1168
  int i=voices;
slouken@0
  1169
  while (i--)
slouken@0
  1170
    if (voice[i].status==VOICE_ON &&
slouken@0
  1171
	voice[i].channel==e->channel &&
slouken@0
  1172
	voice[i].note==e->a)
slouken@0
  1173
      {
slouken@0
  1174
	voice[i].velocity=e->b;
slouken@0
  1175
	recompute_amp(i);
slouken@0
  1176
	apply_envelope_to_amp(i);
slouken@0
  1177
	return;
slouken@0
  1178
      }
slouken@0
  1179
}
slouken@0
  1180
slouken@0
  1181
static void adjust_panning(int c)
slouken@0
  1182
{
slouken@0
  1183
  int i=voices;
slouken@0
  1184
  while (i--)
slouken@0
  1185
    if ((voice[i].channel==c) &&
slouken@0
  1186
	(voice[i].status==VOICE_ON || voice[i].status==VOICE_SUSTAINED))
slouken@0
  1187
      {
slouken@245
  1188
	if (voice[i].clone_type != NOT_CLONE) continue;
slouken@0
  1189
	voice[i].panning=channel[c].panning;
slouken@0
  1190
	recompute_amp(i);
slouken@0
  1191
	apply_envelope_to_amp(i);
slouken@0
  1192
      }
slouken@0
  1193
}
slouken@0
  1194
slouken@0
  1195
static void drop_sustain(int c)
slouken@0
  1196
{
slouken@0
  1197
  int i=voices;
slouken@0
  1198
  while (i--)
slouken@0
  1199
    if (voice[i].status==VOICE_SUSTAINED && voice[i].channel==c)
slouken@0
  1200
      finish_note(i);
slouken@0
  1201
}
slouken@0
  1202
slouken@0
  1203
static void adjust_pitchbend(int c)
slouken@0
  1204
{
slouken@0
  1205
  int i=voices;
slouken@0
  1206
  while (i--)
slouken@0
  1207
    if (voice[i].status!=VOICE_FREE && voice[i].channel==c)
slouken@0
  1208
      {
slouken@0
  1209
	recompute_freq(i);
slouken@0
  1210
      }
slouken@0
  1211
}
slouken@0
  1212
slouken@0
  1213
static void adjust_volume(int c)
slouken@0
  1214
{
slouken@0
  1215
  int i=voices;
slouken@0
  1216
  while (i--)
slouken@0
  1217
    if (voice[i].channel==c &&
slouken@0
  1218
	(voice[i].status==VOICE_ON || voice[i].status==VOICE_SUSTAINED))
slouken@0
  1219
      {
slouken@0
  1220
	recompute_amp(i);
slouken@0
  1221
	apply_envelope_to_amp(i);
slouken@0
  1222
      }
slouken@0
  1223
}
slouken@0
  1224
slouken@0
  1225
static void seek_forward(int32 until_time)
slouken@0
  1226
{
slouken@0
  1227
  reset_voices();
slouken@0
  1228
  while (current_event->time < until_time)
slouken@0
  1229
    {
slouken@0
  1230
      switch(current_event->type)
slouken@0
  1231
	{
slouken@0
  1232
	  /* All notes stay off. Just handle the parameter changes. */
slouken@0
  1233
slouken@0
  1234
	case ME_PITCH_SENS:
slouken@0
  1235
	  channel[current_event->channel].pitchsens=
slouken@0
  1236
	    current_event->a;
slouken@0
  1237
	  channel[current_event->channel].pitchfactor=0;
slouken@0
  1238
	  break;
slouken@0
  1239
	  
slouken@0
  1240
	case ME_PITCHWHEEL:
slouken@0
  1241
	  channel[current_event->channel].pitchbend=
slouken@0
  1242
	    current_event->a + current_event->b * 128;
slouken@0
  1243
	  channel[current_event->channel].pitchfactor=0;
slouken@0
  1244
	  break;
slouken@0
  1245
	  
slouken@0
  1246
	case ME_MAINVOLUME:
slouken@0
  1247
	  channel[current_event->channel].volume=current_event->a;
slouken@0
  1248
	  break;
slouken@0
  1249
	  
slouken@245
  1250
	case ME_MASTERVOLUME:
slouken@245
  1251
	  adjust_master_volume(current_event->a + (current_event->b <<7));
slouken@245
  1252
	  break;
slouken@245
  1253
	  
slouken@0
  1254
	case ME_PAN:
slouken@0
  1255
	  channel[current_event->channel].panning=current_event->a;
slouken@0
  1256
	  break;
slouken@0
  1257
	      
slouken@0
  1258
	case ME_EXPRESSION:
slouken@0
  1259
	  channel[current_event->channel].expression=current_event->a;
slouken@0
  1260
	  break;
slouken@0
  1261
	  
slouken@0
  1262
	case ME_PROGRAM:
slouken@245
  1263
	  /* if (ISDRUMCHANNEL(current_event->channel)) */
slouken@245
  1264
	  if (channel[current_event->channel].kit)
slouken@0
  1265
	    /* Change drum set */
slouken@0
  1266
	    channel[current_event->channel].bank=current_event->a;
slouken@0
  1267
	  else
slouken@0
  1268
	    channel[current_event->channel].program=current_event->a;
slouken@0
  1269
	  break;
slouken@0
  1270
slouken@0
  1271
	case ME_SUSTAIN:
slouken@0
  1272
	  channel[current_event->channel].sustain=current_event->a;
slouken@0
  1273
	  break;
slouken@0
  1274
slouken@245
  1275
slouken@245
  1276
	case ME_REVERBERATION:
slouken@245
  1277
	  channel[current_event->channel].reverberation=current_event->a;
slouken@245
  1278
	  break;
slouken@245
  1279
slouken@245
  1280
	case ME_CHORUSDEPTH:
slouken@245
  1281
	  channel[current_event->channel].chorusdepth=current_event->a;
slouken@245
  1282
	  break;
slouken@245
  1283
slouken@245
  1284
	case ME_HARMONICCONTENT:
slouken@245
  1285
	  channel[current_event->channel].harmoniccontent=current_event->a;
slouken@245
  1286
	  break;
slouken@245
  1287
slouken@245
  1288
	case ME_RELEASETIME:
slouken@245
  1289
	  channel[current_event->channel].releasetime=current_event->a;
slouken@245
  1290
	  break;
slouken@245
  1291
slouken@245
  1292
	case ME_ATTACKTIME:
slouken@245
  1293
	  channel[current_event->channel].attacktime=current_event->a;
slouken@245
  1294
	  break;
slouken@245
  1295
slouken@245
  1296
	case ME_BRIGHTNESS:
slouken@245
  1297
	  channel[current_event->channel].brightness=current_event->a;
slouken@245
  1298
	  break;
slouken@245
  1299
slouken@245
  1300
	case ME_TONE_KIT:
slouken@245
  1301
	  if (current_event->a==SFX_BANKTYPE)
slouken@245
  1302
		{
slouken@245
  1303
		    channel[current_event->channel].sfx=SFXBANK;
slouken@245
  1304
		    channel[current_event->channel].kit=0;
slouken@245
  1305
		}
slouken@245
  1306
	  else
slouken@245
  1307
		{
slouken@245
  1308
		    channel[current_event->channel].sfx=0;
slouken@245
  1309
		    channel[current_event->channel].kit=current_event->a;
slouken@245
  1310
		}
slouken@245
  1311
	  break;
slouken@245
  1312
slouken@245
  1313
slouken@0
  1314
	case ME_RESET_CONTROLLERS:
slouken@0
  1315
	  reset_controllers(current_event->channel);
slouken@0
  1316
	  break;
slouken@0
  1317
	      
slouken@0
  1318
	case ME_TONE_BANK:
slouken@0
  1319
	  channel[current_event->channel].bank=current_event->a;
slouken@0
  1320
	  break;
slouken@0
  1321
	  
slouken@0
  1322
	case ME_EOT:
slouken@0
  1323
	  current_sample=current_event->time;
slouken@0
  1324
	  return;
slouken@0
  1325
	}
slouken@0
  1326
      current_event++;
slouken@0
  1327
    }
slouken@0
  1328
  /*current_sample=current_event->time;*/
slouken@0
  1329
  if (current_event != event_list)
slouken@0
  1330
    current_event--;
slouken@0
  1331
  current_sample=until_time;
slouken@0
  1332
}
slouken@0
  1333
slouken@0
  1334
static void skip_to(int32 until_time)
slouken@0
  1335
{
slouken@0
  1336
  if (current_sample > until_time)
slouken@0
  1337
    current_sample=0;
slouken@0
  1338
slouken@0
  1339
  reset_midi();
slouken@0
  1340
  buffered_count=0;
slouken@0
  1341
  buffer_pointer=common_buffer;
slouken@0
  1342
  current_event=event_list;
slouken@0
  1343
  
slouken@0
  1344
  if (until_time)
slouken@0
  1345
    seek_forward(until_time);
slouken@0
  1346
  ctl->reset();
slouken@0
  1347
}
slouken@0
  1348
slouken@0
  1349
static int apply_controls(void)
slouken@0
  1350
{
slouken@0
  1351
  int rc, i, did_skip=0;
slouken@0
  1352
  int32 val;
slouken@0
  1353
  /* ASCII renditions of CD player pictograms indicate approximate effect */
slouken@0
  1354
  do
slouken@0
  1355
    switch(rc=ctl->read(&val))
slouken@0
  1356
      {
slouken@0
  1357
      case RC_QUIT: /* [] */
slouken@0
  1358
      case RC_LOAD_FILE:	  
slouken@0
  1359
      case RC_NEXT: /* >>| */
slouken@0
  1360
      case RC_REALLY_PREVIOUS: /* |<< */
slouken@0
  1361
	return rc;
slouken@0
  1362
	
slouken@0
  1363
      case RC_CHANGE_VOLUME:
slouken@0
  1364
	if (val>0 || amplification > -val)
slouken@0
  1365
	  amplification += val;
slouken@0
  1366
	else 
slouken@0
  1367
	  amplification=0;
slouken@0
  1368
	if (amplification > MAX_AMPLIFICATION)
slouken@0
  1369
	  amplification=MAX_AMPLIFICATION;
slouken@0
  1370
	adjust_amplification();
slouken@0
  1371
	for (i=0; i<voices; i++)
slouken@0
  1372
	  if (voice[i].status != VOICE_FREE)
slouken@0
  1373
	    {
slouken@0
  1374
	      recompute_amp(i);
slouken@0
  1375
	      apply_envelope_to_amp(i);
slouken@0
  1376
	    }
slouken@0
  1377
	ctl->master_volume(amplification);
slouken@0
  1378
	break;
slouken@0
  1379
slouken@0
  1380
      case RC_PREVIOUS: /* |<< */
slouken@0
  1381
	if (current_sample < 2*play_mode->rate)
slouken@0
  1382
	  return RC_REALLY_PREVIOUS;
slouken@0
  1383
	return RC_RESTART;
slouken@0
  1384
slouken@0
  1385
      case RC_RESTART: /* |<< */
slouken@0
  1386
	skip_to(0);
slouken@0
  1387
	did_skip=1;
slouken@0
  1388
	break;
slouken@0
  1389
	
slouken@0
  1390
      case RC_JUMP:
slouken@0
  1391
	if (val >= sample_count)
slouken@0
  1392
	  return RC_NEXT;
slouken@0
  1393
	skip_to(val);
slouken@0
  1394
	return rc;
slouken@0
  1395
	
slouken@0
  1396
      case RC_FORWARD: /* >> */
slouken@0
  1397
	if (val+current_sample >= sample_count)
slouken@0
  1398
	  return RC_NEXT;
slouken@0
  1399
	skip_to(val+current_sample);
slouken@0
  1400
	did_skip=1;
slouken@0
  1401
	break;
slouken@0
  1402
	
slouken@0
  1403
      case RC_BACK: /* << */
slouken@0
  1404
	if (current_sample > val)
slouken@0
  1405
	  skip_to(current_sample-val);
slouken@0
  1406
	else
slouken@0
  1407
	  skip_to(0); /* We can't seek to end of previous song. */
slouken@0
  1408
	did_skip=1;
slouken@0
  1409
	break;
slouken@0
  1410
      }
slouken@0
  1411
  while (rc!= RC_NONE);
slouken@0
  1412
 
slouken@0
  1413
  /* Advertise the skip so that we stop computing the audio buffer */
slouken@0
  1414
  if (did_skip)
slouken@0
  1415
    return RC_JUMP; 
slouken@0
  1416
  else
slouken@0
  1417
    return rc;
slouken@0
  1418
}
slouken@0
  1419
slouken@245
  1420
static void do_compute_data(uint32 count)
slouken@0
  1421
{
slouken@0
  1422
  int i;
slouken@245
  1423
  if (!count) return; /* (gl) */
slouken@245
  1424
  memset(buffer_pointer, 0, count * num_ochannels * 4);
slouken@0
  1425
  for (i=0; i<voices; i++)
slouken@0
  1426
    {
slouken@0
  1427
      if(voice[i].status != VOICE_FREE)
slouken@245
  1428
	{
slouken@245
  1429
	  if (!voice[i].sample_offset && voice[i].echo_delay_count)
slouken@245
  1430
	    {
slouken@250
  1431
		if ((uint32)voice[i].echo_delay_count >= count) voice[i].echo_delay_count -= count;
slouken@245
  1432
		else
slouken@245
  1433
		  {
slouken@245
  1434
	            mix_voice(buffer_pointer+voice[i].echo_delay_count, i, count-voice[i].echo_delay_count);
slouken@245
  1435
		    voice[i].echo_delay_count = 0;
slouken@245
  1436
		  }
slouken@245
  1437
	    }
slouken@245
  1438
	  else mix_voice(buffer_pointer, i, count);
slouken@245
  1439
	}
slouken@0
  1440
    }
slouken@0
  1441
  current_sample += count;
slouken@0
  1442
}
slouken@0
  1443
slouken@245
  1444
slouken@0
  1445
/* count=0 means flush remaining buffered data to output device, then
slouken@0
  1446
   flush the device itself */
slouken@0
  1447
static int compute_data(void *stream, int32 count)
slouken@0
  1448
{
slouken@0
  1449
  int rc, channels;
slouken@0
  1450
slouken@0
  1451
  if ( play_mode->encoding & PE_MONO )
slouken@0
  1452
    channels = 1;
slouken@0
  1453
  else
slouken@245
  1454
    channels = num_ochannels;
slouken@0
  1455
slouken@0
  1456
  if (!count)
slouken@0
  1457
    {
slouken@0
  1458
      if (buffered_count)
slouken@0
  1459
          s32tobuf(stream, common_buffer, channels*buffered_count);
slouken@0
  1460
      buffer_pointer=common_buffer;
slouken@0
  1461
      buffered_count=0;
slouken@0
  1462
      return RC_NONE;
slouken@0
  1463
    }
slouken@0
  1464
slouken@0
  1465
  while ((count+buffered_count) >= AUDIO_BUFFER_SIZE)
slouken@0
  1466
    {
slouken@0
  1467
      do_compute_data(AUDIO_BUFFER_SIZE-buffered_count);
slouken@0
  1468
      count -= AUDIO_BUFFER_SIZE-buffered_count;
slouken@0
  1469
      s32tobuf(stream, common_buffer, channels*AUDIO_BUFFER_SIZE);
slouken@0
  1470
      buffer_pointer=common_buffer;
slouken@0
  1471
      buffered_count=0;
slouken@0
  1472
      
slouken@0
  1473
      ctl->current_time(current_sample);
slouken@0
  1474
      if ((rc=apply_controls())!=RC_NONE)
slouken@0
  1475
	return rc;
slouken@0
  1476
    }
slouken@0
  1477
  if (count>0)
slouken@0
  1478
    {
slouken@0
  1479
      do_compute_data(count);
slouken@0
  1480
      buffered_count += count;
slouken@245
  1481
      buffer_pointer += count * channels;
slouken@0
  1482
    }
slouken@0
  1483
  return RC_NONE;
slouken@0
  1484
}
slouken@0
  1485
slouken@0
  1486
int Timidity_PlaySome(void *stream, int samples)
slouken@0
  1487
{
slouken@142
  1488
  int rc = RC_NONE;
slouken@0
  1489
  int32 end_sample;
slouken@0
  1490
  
slouken@0
  1491
  if ( ! midi_playing ) {
slouken@0
  1492
    return RC_NONE;
slouken@0
  1493
  }
slouken@0
  1494
  end_sample = current_sample+samples;
slouken@0
  1495
  while ( current_sample < end_sample ) {
slouken@0
  1496
    /* Handle all events that should happen at this time */
slouken@0
  1497
    while (current_event->time <= current_sample) {
slouken@0
  1498
      switch(current_event->type) {
slouken@0
  1499
slouken@0
  1500
        /* Effects affecting a single note */
slouken@0
  1501
slouken@0
  1502
        case ME_NOTEON:
slouken@245
  1503
	  current_event->a += channel[current_event->channel].transpose;
slouken@0
  1504
          if (!(current_event->b)) /* Velocity 0? */
slouken@0
  1505
            note_off(current_event);
slouken@0
  1506
          else
slouken@0
  1507
            note_on(current_event);
slouken@0
  1508
          break;
slouken@0
  1509
  
slouken@0
  1510
        case ME_NOTEOFF:
slouken@245
  1511
	  current_event->a += channel[current_event->channel].transpose;
slouken@0
  1512
          note_off(current_event);
slouken@0
  1513
          break;
slouken@0
  1514
  
slouken@0
  1515
        case ME_KEYPRESSURE:
slouken@0
  1516
          adjust_pressure(current_event);
slouken@0
  1517
          break;
slouken@0
  1518
  
slouken@0
  1519
          /* Effects affecting a single channel */
slouken@0
  1520
  
slouken@0
  1521
        case ME_PITCH_SENS:
slouken@0
  1522
          channel[current_event->channel].pitchsens=current_event->a;
slouken@0
  1523
          channel[current_event->channel].pitchfactor=0;
slouken@0
  1524
          break;
slouken@0
  1525
          
slouken@0
  1526
        case ME_PITCHWHEEL:
slouken@0
  1527
          channel[current_event->channel].pitchbend=
slouken@0
  1528
            current_event->a + current_event->b * 128;
slouken@0
  1529
          channel[current_event->channel].pitchfactor=0;
slouken@0
  1530
          /* Adjust pitch for notes already playing */
slouken@0
  1531
          adjust_pitchbend(current_event->channel);
slouken@0
  1532
          ctl->pitch_bend(current_event->channel, 
slouken@0
  1533
              channel[current_event->channel].pitchbend);
slouken@0
  1534
          break;
slouken@0
  1535
          
slouken@0
  1536
        case ME_MAINVOLUME:
slouken@0
  1537
          channel[current_event->channel].volume=current_event->a;
slouken@0
  1538
          adjust_volume(current_event->channel);
slouken@0
  1539
          ctl->volume(current_event->channel, current_event->a);
slouken@0
  1540
          break;
slouken@245
  1541
slouken@245
  1542
	case ME_MASTERVOLUME:
slouken@245
  1543
	  adjust_master_volume(current_event->a + (current_event->b <<7));
slouken@245
  1544
	  break;
slouken@245
  1545
	      
slouken@245
  1546
	case ME_REVERBERATION:
slouken@245
  1547
	  channel[current_event->channel].reverberation=current_event->a;
slouken@245
  1548
	  break;
slouken@245
  1549
slouken@245
  1550
	case ME_CHORUSDEPTH:
slouken@245
  1551
	  channel[current_event->channel].chorusdepth=current_event->a;
slouken@245
  1552
	  break;
slouken@245
  1553
slouken@0
  1554
        case ME_PAN:
slouken@0
  1555
          channel[current_event->channel].panning=current_event->a;
slouken@0
  1556
          if (adjust_panning_immediately)
slouken@0
  1557
            adjust_panning(current_event->channel);
slouken@0
  1558
          ctl->panning(current_event->channel, current_event->a);
slouken@0
  1559
          break;
slouken@0
  1560
          
slouken@0
  1561
        case ME_EXPRESSION:
slouken@0
  1562
          channel[current_event->channel].expression=current_event->a;
slouken@0
  1563
          adjust_volume(current_event->channel);
slouken@0
  1564
          ctl->expression(current_event->channel, current_event->a);
slouken@0
  1565
          break;
slouken@0
  1566
  
slouken@0
  1567
        case ME_PROGRAM:
slouken@245
  1568
          /* if (ISDRUMCHANNEL(current_event->channel)) { */
slouken@245
  1569
	  if (channel[current_event->channel].kit) {
slouken@0
  1570
            /* Change drum set */
slouken@0
  1571
            channel[current_event->channel].bank=current_event->a;
slouken@0
  1572
          }
slouken@0
  1573
          else
slouken@0
  1574
          {
slouken@0
  1575
            channel[current_event->channel].program=current_event->a;
slouken@0
  1576
          }
slouken@0
  1577
          ctl->program(current_event->channel, current_event->a);
slouken@0
  1578
          break;
slouken@0
  1579
  
slouken@0
  1580
        case ME_SUSTAIN:
slouken@0
  1581
          channel[current_event->channel].sustain=current_event->a;
slouken@0
  1582
          if (!current_event->a)
slouken@0
  1583
            drop_sustain(current_event->channel);
slouken@0
  1584
          ctl->sustain(current_event->channel, current_event->a);
slouken@0
  1585
          break;
slouken@0
  1586
          
slouken@0
  1587
        case ME_RESET_CONTROLLERS:
slouken@0
  1588
          reset_controllers(current_event->channel);
slouken@0
  1589
          redraw_controllers(current_event->channel);
slouken@0
  1590
          break;
slouken@0
  1591
  
slouken@0
  1592
        case ME_ALL_NOTES_OFF:
slouken@0
  1593
          all_notes_off(current_event->channel);
slouken@0
  1594
          break;
slouken@0
  1595
          
slouken@0
  1596
        case ME_ALL_SOUNDS_OFF:
slouken@0
  1597
          all_sounds_off(current_event->channel);
slouken@0
  1598
          break;
slouken@245
  1599
slouken@245
  1600
	case ME_HARMONICCONTENT:
slouken@245
  1601
	  channel[current_event->channel].harmoniccontent=current_event->a;
slouken@245
  1602
	  break;
slouken@245
  1603
slouken@245
  1604
	case ME_RELEASETIME:
slouken@245
  1605
	  channel[current_event->channel].releasetime=current_event->a;
slouken@245
  1606
	  break;
slouken@245
  1607
slouken@245
  1608
	case ME_ATTACKTIME:
slouken@245
  1609
	  channel[current_event->channel].attacktime=current_event->a;
slouken@245
  1610
	  break;
slouken@245
  1611
slouken@245
  1612
	case ME_BRIGHTNESS:
slouken@245
  1613
	  channel[current_event->channel].brightness=current_event->a;
slouken@245
  1614
	  break;
slouken@245
  1615
slouken@0
  1616
        case ME_TONE_BANK:
slouken@0
  1617
          channel[current_event->channel].bank=current_event->a;
slouken@0
  1618
          break;
slouken@245
  1619
slouken@245
  1620
slouken@245
  1621
	case ME_TONE_KIT:
slouken@245
  1622
	  if (current_event->a==SFX_BANKTYPE)
slouken@245
  1623
	  {
slouken@245
  1624
	    channel[current_event->channel].sfx=SFXBANK;
slouken@245
  1625
	    channel[current_event->channel].kit=0;
slouken@245
  1626
	  }
slouken@245
  1627
	  else
slouken@245
  1628
	  {
slouken@245
  1629
	    channel[current_event->channel].sfx=0;
slouken@245
  1630
	    channel[current_event->channel].kit=current_event->a;
slouken@245
  1631
	  }
slouken@245
  1632
	  break;
slouken@245
  1633
slouken@0
  1634
        case ME_EOT:
slouken@0
  1635
          /* Give the last notes a couple of seconds to decay  */
slouken@0
  1636
          ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
slouken@0
  1637
            "Playing time: ~%d seconds", current_sample/play_mode->rate+2);
slouken@0
  1638
          ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
slouken@0
  1639
            "Notes cut: %d", cut_notes);
slouken@0
  1640
          ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
slouken@0
  1641
          "Notes lost totally: %d", lost_notes);
slouken@0
  1642
          midi_playing = 0;
slouken@0
  1643
          return RC_TUNE_END;
slouken@0
  1644
        }
slouken@0
  1645
      current_event++;
slouken@0
  1646
    }
slouken@0
  1647
    if (current_event->time > end_sample)
slouken@0
  1648
      rc=compute_data(stream, end_sample-current_sample);
slouken@0
  1649
    else
slouken@0
  1650
      rc=compute_data(stream, current_event->time-current_sample);
slouken@0
  1651
    ctl->refresh();
slouken@0
  1652
    if ( (rc!=RC_NONE) && (rc!=RC_JUMP))
slouken@0
  1653
      break;
slouken@0
  1654
  }
slouken@0
  1655
  return rc;
slouken@0
  1656
}
slouken@0
  1657
slouken@0
  1658
slouken@0
  1659
void Timidity_SetVolume(int volume)
slouken@0
  1660
{
slouken@0
  1661
  int i;
slouken@0
  1662
  if (volume > MAX_AMPLIFICATION)
slouken@0
  1663
    amplification=MAX_AMPLIFICATION;
slouken@0
  1664
  else
slouken@0
  1665
  if (volume < 0)
slouken@0
  1666
    amplification=0;
slouken@0
  1667
  else
slouken@0
  1668
    amplification=volume;
slouken@0
  1669
  adjust_amplification();
slouken@0
  1670
  for (i=0; i<voices; i++)
slouken@0
  1671
    if (voice[i].status != VOICE_FREE)
slouken@0
  1672
      {
slouken@0
  1673
        recompute_amp(i);
slouken@0
  1674
        apply_envelope_to_amp(i);
slouken@0
  1675
      }
slouken@0
  1676
  ctl->master_volume(amplification);
slouken@0
  1677
}
slouken@0
  1678
slouken@521
  1679
MidiSong *Timidity_LoadSong_RW(SDL_RWops *rw, int freerw)
patmandin@265
  1680
{
patmandin@265
  1681
  MidiSong *song;
patmandin@265
  1682
  int32 events;
patmandin@265
  1683
patmandin@265
  1684
  /* Allocate memory for the song */
patmandin@265
  1685
  song = (MidiSong *)safe_malloc(sizeof(*song));
patmandin@265
  1686
  memset(song, 0, sizeof(*song));
patmandin@265
  1687
patmandin@265
  1688
  strcpy(midi_name, "SDLrwops source");
patmandin@265
  1689
slouken@521
  1690
  song->events = read_midi_file(rw, &events, &song->samples);
slouken@521
  1691
  if (freerw) {
slouken@521
  1692
    SDL_RWclose(rw);
slouken@521
  1693
  }
patmandin@265
  1694
patmandin@265
  1695
  /* Make sure everything is okay */
patmandin@265
  1696
  if (!song->events) {
patmandin@265
  1697
    free(song);
patmandin@265
  1698
    song = NULL;
patmandin@265
  1699
  }
patmandin@265
  1700
  return(song);
patmandin@265
  1701
}
patmandin@265
  1702
slouken@0
  1703
void Timidity_Start(MidiSong *song)
slouken@0
  1704
{
slouken@0
  1705
  load_missing_instruments();
slouken@0
  1706
  adjust_amplification();
slouken@0
  1707
  sample_count = song->samples;
slouken@0
  1708
  event_list = song->events;
slouken@0
  1709
  lost_notes=cut_notes=0;
slouken@0
  1710
slouken@0
  1711
  skip_to(0);
slouken@0
  1712
  midi_playing = 1;
slouken@0
  1713
}
slouken@0
  1714
slouken@0
  1715
int Timidity_Active(void)
slouken@0
  1716
{
slouken@0
  1717
	return(midi_playing);
slouken@0
  1718
}
slouken@0
  1719
slouken@0
  1720
void Timidity_Stop(void)
slouken@0
  1721
{
slouken@0
  1722
  midi_playing = 0;
slouken@0
  1723
}
slouken@0
  1724
slouken@0
  1725
void Timidity_FreeSong(MidiSong *song)
slouken@0
  1726
{
slouken@0
  1727
  if (free_instruments_afterwards)
patmandin@264
  1728
    free_instruments();
slouken@0
  1729
  
slouken@0
  1730
  free(song->events);
slouken@0
  1731
  free(song);
slouken@0
  1732
}
slouken@0
  1733
patmandin@264
  1734
void Timidity_Close(void)
patmandin@264
  1735
{
patmandin@264
  1736
  if (resample_buffer) {
patmandin@264
  1737
    free(resample_buffer);
patmandin@264
  1738
    resample_buffer=NULL;
patmandin@264
  1739
  }
patmandin@264
  1740
  if (common_buffer) {
patmandin@264
  1741
    free(common_buffer);
patmandin@264
  1742
    common_buffer=NULL;
patmandin@264
  1743
  }
patmandin@264
  1744
  free_instruments();
patmandin@264
  1745
  free_pathlist();
patmandin@264
  1746
}
patmandin@264
  1747