mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 08:41:59 +00:00
Import volume handling changes from current WildMidi git
- Description there reads: > Major work done on “log” volumes. Calculations are now based on decibels.
This commit is contained in:
parent
5b4a6483b5
commit
268d2faaf6
1 changed files with 175 additions and 202 deletions
|
@ -116,24 +116,24 @@ struct _note {
|
||||||
unsigned char velocity;
|
unsigned char velocity;
|
||||||
struct _patch *patch;
|
struct _patch *patch;
|
||||||
struct _sample *sample;
|
struct _sample *sample;
|
||||||
unsigned long int sample_pos;
|
unsigned int sample_pos;
|
||||||
unsigned long int sample_inc;
|
unsigned int sample_inc;
|
||||||
signed long int env_inc;
|
signed int env_inc;
|
||||||
unsigned char env;
|
unsigned char env;
|
||||||
signed long int env_level;
|
signed int env_level;
|
||||||
unsigned char modes;
|
unsigned char modes;
|
||||||
unsigned char hold;
|
unsigned char hold;
|
||||||
unsigned char active;
|
unsigned char active;
|
||||||
struct _note *replay;
|
struct _note *replay;
|
||||||
struct _note *next;
|
struct _note *next;
|
||||||
unsigned long int vol_lvl;
|
unsigned int left_mix_volume;
|
||||||
|
unsigned int right_mix_volume;
|
||||||
unsigned char is_off;
|
unsigned char is_off;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct _event_data {
|
struct _event_data {
|
||||||
unsigned char channel;
|
unsigned char channel;
|
||||||
unsigned long int data;
|
unsigned int data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _mdi {
|
struct _mdi {
|
||||||
|
@ -274,30 +274,64 @@ static signed short int lin_volume[] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72,
|
||||||
878, 886, 894, 903, 911, 919, 927, 935, 943, 951, 959, 967, 975, 983,
|
878, 886, 894, 903, 911, 919, 927, 935, 943, 951, 959, 967, 975, 983,
|
||||||
991, 999, 1007, 1015, 1024 };
|
991, 999, 1007, 1015, 1024 };
|
||||||
|
|
||||||
/* f: pow(( VOLUME / 127.0 ), 2.0 ) * 1024.0 */
|
/* f: As per midi 2 standard */
|
||||||
static signed short int sqr_volume[] = { 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 9,
|
static float dBm_volume[] = { -999999.999999f, -84.15214884f, -72.11094901f,
|
||||||
10, 12, 14, 16, 18, 20, 22, 25, 27, 30, 33, 36, 39, 42, 46, 49, 53, 57,
|
-65.06729865f, -60.06974919f, -56.19334866f, -53.02609882f, -50.34822724f,
|
||||||
61, 65, 69, 73, 77, 82, 86, 91, 96, 101, 106, 111, 117, 122, 128, 134,
|
-48.02854936f, -45.98244846f, -44.15214884f, -42.49644143f, -40.984899f,
|
||||||
140, 146, 152, 158, 165, 171, 178, 185, 192, 199, 206, 213, 221, 228,
|
-39.59441475f, -38.30702741f, -37.10849848f, -35.98734953f, -34.93419198f,
|
||||||
236, 244, 251, 260, 268, 276, 284, 293, 302, 311, 320, 329, 338, 347,
|
-33.94124863f, -33.0020048f, -32.11094901f, -31.26337705f, -30.45524161f,
|
||||||
357, 366, 376, 386, 396, 406, 416, 426, 437, 447, 458, 469, 480, 491,
|
-29.6830354f, -28.94369917f, -28.23454849f, -27.55321492f, -26.89759827f,
|
||||||
502, 514, 525, 537, 549, 560, 572, 585, 597, 609, 622, 634, 647, 660,
|
-26.26582758f, -25.65622892f, -25.06729865f, -24.49768108f, -23.94614971f,
|
||||||
673, 686, 699, 713, 726, 740, 754, 768, 782, 796, 810, 825, 839, 854,
|
-23.41159124f, -22.89299216f, -22.38942706f, -21.90004881f, -21.42407988f,
|
||||||
869, 884, 899, 914, 929, 944, 960, 976, 992, 1007, 1024 };
|
-20.96080497f, -20.50956456f, -20.06974919f, -19.64079457f, -19.22217722f,
|
||||||
|
-18.81341062f, -18.41404178f, -18.02364829f, -17.64183557f, -17.26823452f,
|
||||||
|
-16.90249934f, -16.54430564f, -16.19334866f, -15.84934179f, -15.51201509f,
|
||||||
|
-15.18111405f, -14.85639845f, -14.53764126f, -14.22462776f, -13.91715461f,
|
||||||
|
-13.6150291f, -13.31806837f, -13.02609882f, -12.73895544f, -12.45648126f,
|
||||||
|
-12.17852686f, -11.90494988f, -11.63561457f, -11.37039142f, -11.10915673f,
|
||||||
|
-10.85179233f, -10.59818521f, -10.34822724f, -10.10181489f, -9.858848981f,
|
||||||
|
-9.619234433f, -9.382880049f, -9.149698303f, -8.919605147f, -8.692519831f,
|
||||||
|
-8.468364731f, -8.247065187f, -8.028549359f, -7.812748083f, -7.599594743f,
|
||||||
|
-7.389025143f, -7.180977396f, -6.97539181f, -6.772210788f, -6.571378733f,
|
||||||
|
-6.372841952f, -6.176548572f, -5.982448461f, -5.790493145f, -5.600635744f,
|
||||||
|
-5.412830896f, -5.227034694f, -5.043204627f, -4.861299517f, -4.681279468f,
|
||||||
|
-4.503105811f, -4.326741054f, -4.152148838f, -3.979293887f, -3.808141968f,
|
||||||
|
-3.63865985f, -3.470815266f, -3.304576875f, -3.139914228f, -2.976797731f,
|
||||||
|
-2.815198619f, -2.655088921f, -2.496441432f, -2.339229687f, -2.183427931f,
|
||||||
|
-2.029011099f, -1.875954785f, -1.724235224f, -1.573829269f, -1.424714368f,
|
||||||
|
-1.276868546f, -1.130270383f, -0.9848989963f, -0.8407340256f, -0.6977556112f,
|
||||||
|
-0.5559443807f, -0.4152814317f, -0.2757483179f, -0.1373270335f, 0 };
|
||||||
|
|
||||||
/* f: pow(( VOLUME / 127.0 ), 0.5 ) * 1024.0 */
|
/* f: As per midi 2 standard */
|
||||||
static signed short int pan_volume[] = { 0, 90, 128, 157, 181, 203, 222, 240,
|
static float dBm_pan_volume[] = { -999999.999999f, -38.15389834f -32.13396282f,
|
||||||
257, 272, 287, 301, 314, 327, 339, 351, 363, 374, 385, 396, 406, 416,
|
-28.61324502f, -26.1160207f, -24.179814f, -22.5986259f, -21.26257033f,
|
||||||
426, 435, 445, 454, 463, 472, 480, 489, 497, 505, 514, 521, 529, 537,
|
-20.10605521f, -19.08677237f, -18.17583419f, -17.35263639f, -16.60196565f,
|
||||||
545, 552, 560, 567, 574, 581, 588, 595, 602, 609, 616, 622, 629, 636,
|
-15.91226889f, -15.2745658f, -14.6817375f, -14.12804519f, -13.60879499f,
|
||||||
642, 648, 655, 661, 667, 673, 679, 686, 692, 697, 703, 709, 715, 721,
|
-13.12009875f, -12.65869962f, -12.22184237f, -11.80717543f, -11.41267571f,
|
||||||
726, 732, 738, 743, 749, 754, 760, 765, 771, 776, 781, 786, 792, 797,
|
-11.03659017f, -10.67738981f, -10.33373306f, -10.00443638f, -9.6884504f,
|
||||||
802, 807, 812, 817, 822, 827, 832, 837, 842, 847, 852, 857, 862, 866,
|
-9.384840381f, -9.092770127f, -8.811488624f, -8.540318866f, -8.278648457f,
|
||||||
871, 876, 880, 885, 890, 894, 899, 904, 908, 913, 917, 922, 926, 931,
|
-8.025921658f, -7.781632628f, -7.545319633f, -7.316560087f, -7.094966257f,
|
||||||
935, 939, 944, 948, 953, 957, 961, 965, 970, 974, 978, 982, 987, 991,
|
-6.880181552f, -6.671877289f, -6.46974987f, -6.273518306f, -6.082922045f,
|
||||||
995, 999, 1003, 1007, 1011, 1015, 1019, 1024 };
|
-5.897719045f, -5.717684082f, -5.542607236f, -5.372292553f, -5.206556845f,
|
||||||
|
-5.045228616f, -4.888147106f, -4.735161423f, -4.586129765f, -4.44091872f,
|
||||||
|
-4.299402626f, -4.161462998f, -4.026988004f, -3.895871989f, -3.76801504f,
|
||||||
|
-3.643322591f, -3.52170506f, -3.403077519f, -3.287359388f, -3.174474158f,
|
||||||
|
-3.064349129f, -2.956915181f, -2.852106549f, -2.749860626f, -2.650117773f,
|
||||||
|
-2.55282115f, -2.457916557f, -2.36535228f, -2.27507896f, -2.187049463f,
|
||||||
|
-2.101218759f, -2.017543814f, -1.935983486f,-1.856498429f, -1.779051001f,
|
||||||
|
-1.703605184f, -1.630126502f, -1.558581949f, -1.48893992f, -1.421170148f,
|
||||||
|
-1.35524364f, -1.291132623f, -1.228810491f, -1.168251755f, -1.109431992f,
|
||||||
|
-1.052327808f, -0.9969167902f, -0.9431774708f, -0.8910892898f, -0.8406325604f,
|
||||||
|
-0.7917884361f, -0.7445388804f, -0.6988666373f, -0.6547552046f, -0.612188808f,
|
||||||
|
-0.5711523768f, -0.5316315211f, -0.4936125107f, -0.4570822543f, -0.4220282808f,
|
||||||
|
-0.3884387214f, -0.3563022927f, -0.3256082808f, -0.2963465264f, -0.2685074109f,
|
||||||
|
-0.2420818435f, -0.2170612483f, -0.1934375538f, -0.1712031815f, -0.1503510361f,
|
||||||
|
-0.1308744964f, -0.1127674066f, -0.09602406855f, -0.08063923423f,
|
||||||
|
-0.06660809932f, -0.05392629701f, -0.04258989258f, -0.03259537844f,
|
||||||
|
-0.02393966977f, -0.01662010072f, -0.01063442111f, -0.005980793601f,
|
||||||
|
-0.002657791522f, -0.000664397052f, 0 };
|
||||||
|
|
||||||
static unsigned long int freq_table[] = { 837201792, 837685632, 838169728,
|
static unsigned int freq_table[] = { 837201792, 837685632, 838169728,
|
||||||
838653568, 839138240, 839623232, 840108480, 840593984, 841079680,
|
838653568, 839138240, 839623232, 840108480, 840593984, 841079680,
|
||||||
841565184, 842051648, 842538240, 843025152, 843512320, 843999232,
|
841565184, 842051648, 842538240, 843025152, 843512320, 843999232,
|
||||||
844486976, 844975040, 845463360, 845951936, 846440320, 846929536,
|
844486976, 844975040, 845463360, 845951936, 846440320, 846929536,
|
||||||
|
@ -1179,7 +1213,6 @@ static int load_sample(struct _patch *sample_patch) {
|
||||||
samp_max = tmp_sample->data[i];
|
samp_max = tmp_sample->data[i];
|
||||||
if (tmp_sample->data[i] < samp_min)
|
if (tmp_sample->data[i] < samp_min)
|
||||||
samp_min = tmp_sample->data[i];
|
samp_min = tmp_sample->data[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
if (samp_max > tmp_max)
|
if (samp_max > tmp_max)
|
||||||
tmp_max = samp_max;
|
tmp_max = samp_max;
|
||||||
|
@ -1374,6 +1407,78 @@ get_sample_data(struct _patch *sample_patch, unsigned long int freq) {
|
||||||
return return_sample;
|
return return_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Should be called in any function that effects note volumes */
|
||||||
|
void _WM_AdjustNoteVolumes(struct _mdi *mdi, unsigned char ch, struct _note *nte) {
|
||||||
|
double premix_dBm;
|
||||||
|
double premix_lin;
|
||||||
|
unsigned char pan_ofs;
|
||||||
|
double premix_dBm_left;
|
||||||
|
double premix_dBm_right;
|
||||||
|
double premix_left;
|
||||||
|
double premix_right;
|
||||||
|
double volume_adj;
|
||||||
|
unsigned vol_ofs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Pointless CPU heating checks to shoosh up a compiler
|
||||||
|
*/
|
||||||
|
if (ch > 0x0f) ch = 0x0f;
|
||||||
|
|
||||||
|
pan_ofs = mdi->channel[ch].balance + mdi->channel[ch].pan - 64;
|
||||||
|
|
||||||
|
vol_ofs = (nte->velocity * ((mdi->channel[ch].expression * mdi->channel[ch].volume) / 127)) / 127;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This value is to reduce the chance of clipping.
|
||||||
|
Higher value means lower overall volume,
|
||||||
|
Lower value means higher overall volume.
|
||||||
|
NOTE: The lower the value the higher the chance of clipping.
|
||||||
|
FIXME: Still needs tuning. Clipping heard at a value of 3.75
|
||||||
|
*/
|
||||||
|
#define VOL_DIVISOR 4.0
|
||||||
|
volume_adj = ((float)WM_MasterVolume / 1024.0) / VOL_DIVISOR;
|
||||||
|
|
||||||
|
if (pan_ofs > 127) pan_ofs = 127;
|
||||||
|
premix_dBm_left = dBm_pan_volume[(127-pan_ofs)];
|
||||||
|
premix_dBm_right = dBm_pan_volume[pan_ofs];
|
||||||
|
|
||||||
|
if (mdi->info.mixer_options & WM_MO_LOG_VOLUME) {
|
||||||
|
premix_dBm = dBm_volume[vol_ofs];
|
||||||
|
|
||||||
|
premix_dBm_left += premix_dBm;
|
||||||
|
premix_dBm_right += premix_dBm;
|
||||||
|
|
||||||
|
premix_left = (pow(10.0,(premix_dBm_left / 20.0))) * volume_adj;
|
||||||
|
premix_right = (pow(10.0,(premix_dBm_right / 20.0))) * volume_adj;
|
||||||
|
} else {
|
||||||
|
premix_lin = (float)(lin_volume[vol_ofs]) / 1024.0;
|
||||||
|
|
||||||
|
premix_left = premix_lin * pow(10.0, (premix_dBm_left / 20)) * volume_adj;
|
||||||
|
premix_right = premix_lin * pow(10.0, (premix_dBm_right / 20)) * volume_adj;
|
||||||
|
}
|
||||||
|
nte->left_mix_volume = (int)(premix_left * 1024.0);
|
||||||
|
nte->right_mix_volume = (int)(premix_right * 1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should be called in any function that effects channel volumes */
|
||||||
|
/* Calling this function with a value > 15 will make it adjust notes on all channels */
|
||||||
|
void _WM_AdjustChannelVolumes(struct _mdi *mdi, unsigned char ch) {
|
||||||
|
struct _note *nte = mdi->note;
|
||||||
|
if (nte != NULL) {
|
||||||
|
do {
|
||||||
|
if (ch <= 15) {
|
||||||
|
if ((nte->noteid >> 8) == ch) {
|
||||||
|
goto _DO_ADJUST;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_DO_ADJUST:
|
||||||
|
_WM_AdjustNoteVolumes(mdi, ch, nte);
|
||||||
|
if (nte->replay) _WM_AdjustNoteVolumes(mdi, ch, nte->replay);
|
||||||
|
}
|
||||||
|
nte = nte->next;
|
||||||
|
} while (nte != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void do_note_off_extra(struct _note *nte) {
|
static void do_note_off_extra(struct _note *nte) {
|
||||||
|
|
||||||
|
@ -1435,7 +1540,10 @@ static void do_note_off(struct _mdi *mdi, struct _event_data *data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nte->env == 0) {
|
if ((nte->modes & SAMPLE_ENVELOPE) && (nte->env == 0)) {
|
||||||
|
// This is a fix for notes that end before the
|
||||||
|
// initial step of the envelope has completed
|
||||||
|
// making it impossible to hear them at times.
|
||||||
nte->is_off = 1;
|
nte->is_off = 1;
|
||||||
} else {
|
} else {
|
||||||
do_note_off_extra(nte);
|
do_note_off_extra(nte);
|
||||||
|
@ -1463,24 +1571,6 @@ static inline unsigned long int get_inc(struct _mdi *mdi, struct _note *nte) {
|
||||||
/ nte->sample->inc_div));
|
/ nte->sample->inc_div));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long int get_volume(struct _mdi *mdi, unsigned char ch,
|
|
||||||
struct _note *nte) {
|
|
||||||
signed long int volume;
|
|
||||||
|
|
||||||
if (mdi->info.mixer_options & WM_MO_LOG_VOLUME) {
|
|
||||||
volume = (sqr_volume[mdi->channel[ch].volume]
|
|
||||||
* sqr_volume[mdi->channel[ch].expression]
|
|
||||||
* sqr_volume[nte->velocity]) / 1048576;
|
|
||||||
} else {
|
|
||||||
volume = (lin_volume[mdi->channel[ch].volume]
|
|
||||||
* lin_volume[mdi->channel[ch].expression]
|
|
||||||
* lin_volume[nte->velocity]) / 1048576;
|
|
||||||
}
|
|
||||||
|
|
||||||
volume = volume * nte->patch->amp / 100;
|
|
||||||
return (volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_note_on(struct _mdi *mdi, struct _event_data *data) {
|
static void do_note_on(struct _mdi *mdi, struct _event_data *data) {
|
||||||
struct _note *nte;
|
struct _note *nte;
|
||||||
struct _note *prev_nte;
|
struct _note *prev_nte;
|
||||||
|
@ -1490,7 +1580,7 @@ static void do_note_on(struct _mdi *mdi, struct _event_data *data) {
|
||||||
struct _sample *sample;
|
struct _sample *sample;
|
||||||
unsigned char ch = data->channel;
|
unsigned char ch = data->channel;
|
||||||
unsigned char note = (unsigned char)(data->data >> 8);
|
unsigned char note = (unsigned char)(data->data >> 8);
|
||||||
unsigned char velocity = (data->data & 0xFF);
|
unsigned char velocity = (unsigned char)(data->data & 0xFF);
|
||||||
|
|
||||||
if (velocity == 0x00) {
|
if (velocity == 0x00) {
|
||||||
do_note_off(mdi, data);
|
do_note_off(mdi, data);
|
||||||
|
@ -1568,9 +1658,9 @@ static void do_note_on(struct _mdi *mdi, struct _event_data *data) {
|
||||||
nte->env_level = 0;
|
nte->env_level = 0;
|
||||||
nte->modes = sample->modes;
|
nte->modes = sample->modes;
|
||||||
nte->hold = mdi->channel[ch].hold;
|
nte->hold = mdi->channel[ch].hold;
|
||||||
nte->vol_lvl = get_volume(mdi, ch, nte);
|
|
||||||
nte->replay = NULL;
|
nte->replay = NULL;
|
||||||
nte->is_off = 0;
|
nte->is_off = 0;
|
||||||
|
_WM_AdjustNoteVolumes(mdi, ch, nte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_aftertouch(struct _mdi *mdi, struct _event_data *data) {
|
static void do_aftertouch(struct _mdi *mdi, struct _event_data *data) {
|
||||||
|
@ -1587,40 +1677,14 @@ static void do_aftertouch(struct _mdi *mdi, struct _event_data *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nte->velocity = data->data & 0xff;
|
nte->velocity = (unsigned char)data->data;
|
||||||
nte->vol_lvl = get_volume(mdi, ch, nte);
|
_WM_AdjustNoteVolumes(mdi, ch, nte);
|
||||||
|
|
||||||
if (nte->replay) {
|
if (nte->replay) {
|
||||||
nte->replay->velocity = data->data & 0xff;
|
nte->replay->velocity = (unsigned char)data->data;
|
||||||
nte->replay->vol_lvl = get_volume(mdi, ch, nte->replay);
|
_WM_AdjustNoteVolumes(mdi, ch, nte->replay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_pan_adjust(struct _mdi *mdi, unsigned char ch) {
|
|
||||||
signed short int pan_adjust = mdi->channel[ch].balance
|
|
||||||
+ mdi->channel[ch].pan;
|
|
||||||
signed short int left, right;
|
|
||||||
int amp = 32;
|
|
||||||
|
|
||||||
if (pan_adjust > 63) {
|
|
||||||
pan_adjust = 63;
|
|
||||||
} else if (pan_adjust < -64) {
|
|
||||||
pan_adjust = -64;
|
|
||||||
}
|
|
||||||
|
|
||||||
pan_adjust += 64;
|
|
||||||
/* if (mdi->info.mixer_options & WM_MO_LOG_VOLUME) {*/
|
|
||||||
left = (pan_volume[127 - pan_adjust] * WM_MasterVolume * amp) / 1048576;
|
|
||||||
right = (pan_volume[pan_adjust] * WM_MasterVolume * amp) / 1048576;
|
|
||||||
/* } else {
|
|
||||||
left = (lin_volume[127 - pan_adjust] * WM_MasterVolume * amp) / 1048576;
|
|
||||||
right= (lin_volume[pan_adjust] * WM_MasterVolume * amp) / 1048576;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
mdi->channel[ch].left_adjust = left;
|
|
||||||
mdi->channel[ch].right_adjust = right;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_control_bank_select(struct _mdi *mdi, struct _event_data *data) {
|
static void do_control_bank_select(struct _mdi *mdi, struct _event_data *data) {
|
||||||
unsigned char ch = data->channel;
|
unsigned char ch = data->channel;
|
||||||
mdi->channel[ch].bank = (unsigned char)data->data;
|
mdi->channel[ch].bank = (unsigned char)data->data;
|
||||||
|
@ -1646,33 +1710,22 @@ static void do_control_channel_volume(struct _mdi *mdi,
|
||||||
unsigned char ch = data->channel;
|
unsigned char ch = data->channel;
|
||||||
|
|
||||||
mdi->channel[ch].volume = (unsigned char)data->data;
|
mdi->channel[ch].volume = (unsigned char)data->data;
|
||||||
|
_WM_AdjustChannelVolumes(mdi, ch);
|
||||||
if (note_data) {
|
|
||||||
do {
|
|
||||||
if ((note_data->noteid >> 8) == ch) {
|
|
||||||
note_data->vol_lvl = get_volume(mdi, ch, note_data);
|
|
||||||
if (note_data->replay)
|
|
||||||
note_data->replay->vol_lvl = get_volume(mdi, ch,
|
|
||||||
note_data->replay);
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
} while (note_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_control_channel_balance(struct _mdi *mdi,
|
static void do_control_channel_balance(struct _mdi *mdi,
|
||||||
struct _event_data *data) {
|
struct _event_data *data) {
|
||||||
unsigned char ch = data->channel;
|
unsigned char ch = data->channel;
|
||||||
|
|
||||||
mdi->channel[ch].balance = (signed char)(data->data - 64);
|
mdi->channel[ch].balance = (signed char)(data->data);
|
||||||
do_pan_adjust(mdi, ch);
|
_WM_AdjustChannelVolumes(mdi, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_control_channel_pan(struct _mdi *mdi, struct _event_data *data) {
|
static void do_control_channel_pan(struct _mdi *mdi, struct _event_data *data) {
|
||||||
unsigned char ch = data->channel;
|
unsigned char ch = data->channel;
|
||||||
|
|
||||||
mdi->channel[ch].pan = (signed char)(data->data - 64);
|
mdi->channel[ch].pan = (signed char)(data->data);
|
||||||
do_pan_adjust(mdi, ch);
|
_WM_AdjustChannelVolumes(mdi, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_control_channel_expression(struct _mdi *mdi,
|
static void do_control_channel_expression(struct _mdi *mdi,
|
||||||
|
@ -1681,18 +1734,7 @@ static void do_control_channel_expression(struct _mdi *mdi,
|
||||||
unsigned char ch = data->channel;
|
unsigned char ch = data->channel;
|
||||||
|
|
||||||
mdi->channel[ch].expression = (unsigned char)data->data;
|
mdi->channel[ch].expression = (unsigned char)data->data;
|
||||||
|
_WM_AdjustChannelVolumes(mdi, ch);
|
||||||
if (note_data) {
|
|
||||||
do {
|
|
||||||
if ((note_data->noteid >> 8) == ch) {
|
|
||||||
note_data->vol_lvl = get_volume(mdi, ch, note_data);
|
|
||||||
if (note_data->replay)
|
|
||||||
note_data->replay->vol_lvl = get_volume(mdi, ch,
|
|
||||||
note_data->replay);
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
} while (note_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_control_data_entry_fine(struct _mdi *mdi,
|
static void do_control_data_entry_fine(struct _mdi *mdi,
|
||||||
|
@ -1839,33 +1881,13 @@ static void do_control_channel_controllers_off(struct _mdi *mdi,
|
||||||
|
|
||||||
mdi->channel[ch].expression = 127;
|
mdi->channel[ch].expression = 127;
|
||||||
mdi->channel[ch].pressure = 127;
|
mdi->channel[ch].pressure = 127;
|
||||||
mdi->channel[ch].volume = 100;
|
|
||||||
mdi->channel[ch].pan = 0;
|
|
||||||
mdi->channel[ch].balance = 0;
|
|
||||||
mdi->channel[ch].reg_data = 0xffff;
|
mdi->channel[ch].reg_data = 0xffff;
|
||||||
mdi->channel[ch].pitch_range = 200;
|
mdi->channel[ch].pitch_range = 200;
|
||||||
mdi->channel[ch].pitch = 0;
|
mdi->channel[ch].pitch = 0;
|
||||||
mdi->channel[ch].pitch_adjust = 0;
|
mdi->channel[ch].pitch_adjust = 0;
|
||||||
mdi->channel[ch].hold = 0;
|
mdi->channel[ch].hold = 0;
|
||||||
do_pan_adjust(mdi, ch);
|
|
||||||
|
|
||||||
if (note_data) {
|
_WM_AdjustChannelVolumes(mdi, ch);
|
||||||
do {
|
|
||||||
if ((note_data->noteid >> 8) == ch) {
|
|
||||||
note_data->sample_inc = get_inc(mdi, note_data);
|
|
||||||
note_data->velocity = 0;
|
|
||||||
note_data->vol_lvl = get_volume(mdi, ch, note_data);
|
|
||||||
note_data->hold = 0;
|
|
||||||
|
|
||||||
if (note_data->replay) {
|
|
||||||
note_data->replay->velocity = (unsigned char)data->data;
|
|
||||||
note_data->replay->vol_lvl = get_volume(mdi, ch,
|
|
||||||
note_data->replay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
} while (note_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_control_channel_notes_off(struct _mdi *mdi,
|
static void do_control_channel_notes_off(struct _mdi *mdi,
|
||||||
|
@ -1917,20 +1939,16 @@ static void do_channel_pressure(struct _mdi *mdi, struct _event_data *data) {
|
||||||
|
|
||||||
MIDI_EVENT_DEBUG(__FUNCTION__,ch);
|
MIDI_EVENT_DEBUG(__FUNCTION__,ch);
|
||||||
|
|
||||||
if (note_data) {
|
while (note_data) {
|
||||||
do {
|
if ((note_data->noteid >> 8) == ch) {
|
||||||
if ((note_data->noteid >> 8) == ch) {
|
note_data->velocity = (unsigned char)data->data;
|
||||||
note_data->velocity = (unsigned char)data->data;
|
_WM_AdjustNoteVolumes(mdi, ch, note_data);
|
||||||
note_data->vol_lvl = get_volume(mdi, ch, note_data);
|
if (note_data->replay) {
|
||||||
|
note_data->replay->velocity = (unsigned char)data->data;
|
||||||
if (note_data->replay) {
|
_WM_AdjustNoteVolumes(mdi, ch, note_data->replay);
|
||||||
note_data->replay->velocity = (unsigned char)data->data;
|
|
||||||
note_data->replay->vol_lvl = get_volume(mdi, ch,
|
|
||||||
note_data->replay);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
note_data = note_data->next;
|
}
|
||||||
} while (note_data);
|
note_data = note_data->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1987,16 +2005,17 @@ static void do_sysex_gm_reset(struct _mdi *mdi, struct _event_data *data) {
|
||||||
mdi->channel[i].volume = 100;
|
mdi->channel[i].volume = 100;
|
||||||
mdi->channel[i].pressure = 127;
|
mdi->channel[i].pressure = 127;
|
||||||
mdi->channel[i].expression = 127;
|
mdi->channel[i].expression = 127;
|
||||||
mdi->channel[i].balance = 0;
|
mdi->channel[i].balance = 64;
|
||||||
mdi->channel[i].pan = 0;
|
mdi->channel[i].pan = 64;
|
||||||
mdi->channel[i].left_adjust = 1;
|
|
||||||
mdi->channel[i].right_adjust = 1;
|
|
||||||
mdi->channel[i].pitch = 0;
|
mdi->channel[i].pitch = 0;
|
||||||
mdi->channel[i].pitch_range = 200;
|
mdi->channel[i].pitch_range = 200;
|
||||||
mdi->channel[i].reg_data = 0xFFFF;
|
mdi->channel[i].reg_data = 0xFFFF;
|
||||||
mdi->channel[i].isdrum = 0;
|
mdi->channel[i].isdrum = 0;
|
||||||
do_pan_adjust(mdi, i);
|
|
||||||
}
|
}
|
||||||
|
/* I would not expect notes to be active when this event
|
||||||
|
triggers but we'll adjust active notes as well just in case */
|
||||||
|
_WM_AdjustChannelVolumes(mdi,16); // A setting > 15 adjusts all channels
|
||||||
|
|
||||||
mdi->channel[9].isdrum = 1;
|
mdi->channel[9].isdrum = 1;
|
||||||
UNUSED(data); /* NOOP, to please the compiler gods */
|
UNUSED(data); /* NOOP, to please the compiler gods */
|
||||||
}
|
}
|
||||||
|
@ -2095,7 +2114,6 @@ static int *WM_Mix_Linear(midi * handle, int * buffer, unsigned long int count)
|
||||||
struct _mdi *mdi = (struct _mdi *)handle;
|
struct _mdi *mdi = (struct _mdi *)handle;
|
||||||
unsigned long int data_pos;
|
unsigned long int data_pos;
|
||||||
signed int premix, left_mix, right_mix;
|
signed int premix, left_mix, right_mix;
|
||||||
signed int vol_mul;
|
|
||||||
struct _note *note_data = NULL;
|
struct _note *note_data = NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -2109,20 +2127,11 @@ static int *WM_Mix_Linear(midi * handle, int * buffer, unsigned long int count)
|
||||||
* ===================
|
* ===================
|
||||||
*/
|
*/
|
||||||
data_pos = note_data->sample_pos >> FPBITS;
|
data_pos = note_data->sample_pos >> FPBITS;
|
||||||
vol_mul = ((note_data->vol_lvl
|
premix = ((note_data->sample->data[data_pos] + (((note_data->sample->data[data_pos + 1] - note_data->sample->data[data_pos]) * (int)(note_data->sample_pos & FPMASK)) / 1024)) * (note_data->env_level >> 12)) / 1024;
|
||||||
* (note_data->env_level >> 12)) >> FPBITS);
|
|
||||||
|
|
||||||
premix = (note_data->sample->data[data_pos]
|
|
||||||
+ ((note_data->sample->data[data_pos + 1]
|
|
||||||
- note_data->sample->data[data_pos])
|
|
||||||
* (signed long int) (note_data->sample_pos
|
|
||||||
& FPMASK)>> FPBITS)) * vol_mul
|
|
||||||
/ 1024;
|
|
||||||
|
|
||||||
left_mix += premix
|
left_mix += (premix * (int)note_data->left_mix_volume) / 1024;
|
||||||
* mdi->channel[note_data->noteid >> 8].left_adjust;
|
right_mix += (premix * (int)note_data->right_mix_volume) / 1024;
|
||||||
right_mix += premix
|
|
||||||
* mdi->channel[note_data->noteid >> 8].right_adjust;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ========================
|
* ========================
|
||||||
|
@ -2269,10 +2278,7 @@ static int *WM_Mix_Linear(midi * handle, int * buffer, unsigned long int count)
|
||||||
* mix the channels together
|
* mix the channels together
|
||||||
* =========================
|
* =========================
|
||||||
*/
|
*/
|
||||||
left_mix /= 1024;
|
|
||||||
right_mix /= 1024;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*buffer++ = left_mix;
|
*buffer++ = left_mix;
|
||||||
*buffer++ = right_mix;
|
*buffer++ = right_mix;
|
||||||
} while (--count);
|
} while (--count);
|
||||||
|
@ -2286,7 +2292,6 @@ static int *WM_Mix_Gauss(midi * handle, int * buffer, unsigned long int count)
|
||||||
struct _mdi *mdi = (struct _mdi *)handle;
|
struct _mdi *mdi = (struct _mdi *)handle;
|
||||||
unsigned long int data_pos;
|
unsigned long int data_pos;
|
||||||
signed int premix, left_mix, right_mix;
|
signed int premix, left_mix, right_mix;
|
||||||
signed int vol_mul;
|
|
||||||
struct _note *note_data = NULL;
|
struct _note *note_data = NULL;
|
||||||
signed short int *sptr;
|
signed short int *sptr;
|
||||||
double y, xd;
|
double y, xd;
|
||||||
|
@ -2305,8 +2310,6 @@ static int *WM_Mix_Gauss(midi * handle, int * buffer, unsigned long int count)
|
||||||
* ===================
|
* ===================
|
||||||
*/
|
*/
|
||||||
data_pos = note_data->sample_pos >> FPBITS;
|
data_pos = note_data->sample_pos >> FPBITS;
|
||||||
vol_mul = ((note_data->vol_lvl
|
|
||||||
* (note_data->env_level >> 12)) >> FPBITS);
|
|
||||||
|
|
||||||
/* check to see if we're near one of the ends */
|
/* check to see if we're near one of the ends */
|
||||||
left = data_pos;
|
left = data_pos;
|
||||||
|
@ -2346,12 +2349,10 @@ static int *WM_Mix_Gauss(midi * handle, int * buffer, unsigned long int count)
|
||||||
} while (gptr <= gend);
|
} while (gptr <= gend);
|
||||||
}
|
}
|
||||||
|
|
||||||
premix = (long) (y * vol_mul / 1024);
|
premix = (int)((y * (note_data->env_level >> 12)) / 1024);
|
||||||
|
|
||||||
left_mix += premix
|
left_mix += (premix * (int)note_data->left_mix_volume) / 1024;
|
||||||
* mdi->channel[note_data->noteid >> 8].left_adjust;
|
right_mix += (premix * (int)note_data->right_mix_volume) / 1024;
|
||||||
right_mix += premix
|
|
||||||
* mdi->channel[note_data->noteid >> 8].right_adjust;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ========================
|
* ========================
|
||||||
|
@ -2502,10 +2503,7 @@ static int *WM_Mix_Gauss(midi * handle, int * buffer, unsigned long int count)
|
||||||
* mix the channels together
|
* mix the channels together
|
||||||
* =========================
|
* =========================
|
||||||
*/
|
*/
|
||||||
left_mix /= 1024;
|
|
||||||
right_mix /= 1024;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*buffer++ = left_mix;
|
*buffer++ = left_mix;
|
||||||
*buffer++ = right_mix;
|
*buffer++ = right_mix;
|
||||||
} while (--count);
|
} while (--count);
|
||||||
|
@ -2598,16 +2596,6 @@ WM_SYMBOL int WildMidi_MasterVolume(unsigned char master_volume) {
|
||||||
|
|
||||||
WM_MasterVolume = lin_volume[master_volume];
|
WM_MasterVolume = lin_volume[master_volume];
|
||||||
|
|
||||||
if (tmp_handle) {
|
|
||||||
while (tmp_handle) {
|
|
||||||
mdi = (struct _mdi *) tmp_handle->handle;
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
do_pan_adjust(mdi, i);
|
|
||||||
}
|
|
||||||
tmp_handle = tmp_handle->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2688,7 +2676,6 @@ midi *WildMidi_NewMidi() {
|
||||||
WM_SYMBOL int WildMidi_SetOption(midi * handle, unsigned short int options,
|
WM_SYMBOL int WildMidi_SetOption(midi * handle, unsigned short int options,
|
||||||
unsigned short int setting) {
|
unsigned short int setting) {
|
||||||
struct _mdi *mdi;
|
struct _mdi *mdi;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!WM_Initialized) {
|
if (!WM_Initialized) {
|
||||||
_WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0);
|
_WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0);
|
||||||
|
@ -2719,22 +2706,8 @@ WM_SYMBOL int WildMidi_SetOption(midi * handle, unsigned short int options,
|
||||||
| (options & setting));
|
| (options & setting));
|
||||||
|
|
||||||
if (options & WM_MO_LOG_VOLUME) {
|
if (options & WM_MO_LOG_VOLUME) {
|
||||||
struct _note *note_data = mdi->note;
|
_WM_AdjustChannelVolumes(mdi, 16); // Settings greater than 15
|
||||||
|
// adjust all channels
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
do_pan_adjust(mdi, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note_data) {
|
|
||||||
do {
|
|
||||||
note_data->vol_lvl = get_volume(mdi, (note_data->noteid >> 8),
|
|
||||||
note_data);
|
|
||||||
if (note_data->replay)
|
|
||||||
note_data->replay->vol_lvl = get_volume(mdi,
|
|
||||||
(note_data->noteid >> 8), note_data->replay);
|
|
||||||
note_data = note_data->next;
|
|
||||||
} while (note_data);
|
|
||||||
}
|
|
||||||
} else if (options & WM_MO_REVERB) {
|
} else if (options & WM_MO_REVERB) {
|
||||||
_WM_reset_reverb(mdi->reverb);
|
_WM_reset_reverb(mdi->reverb);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue