Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* * gus_vol.c - Compute volume for GUS. * * Greg Lee 1993. */ #include "sound_config.h" #ifndef EXCLUDE_GUS #include "gus_linearvol.h" #define GUS_VOLUME gus_wave_volume extern int gus_wave_volume; /* * Calculate gus volume from note velocity, main volume, expression, and * intrinsic patch volume given in patch library. Expression is multiplied * in, so it emphasizes differences in note velocity, while main volume is * added in -- I don't know whether this is right, but it seems reasonable to * me. (In the previous stage, main volume controller messages were changed * to expression controller messages, if they were found to be used for * dynamic volume adjustments, so here, main volume can be assumed to be * constant throughout a song.) * * Intrinsic patch volume is added in, but if over 64 is also multiplied in, so * we can give a big boost to very weak voices like nylon guitar and the * basses. The normal value is 64. Strings are assigned lower values. */ unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev) { int i, m, n, x; /* * A voice volume of 64 is considered neutral, so adjust the main volume if * something other than this neutral value was assigned in the patch * library. */ x = 256 + 6 * (voicev - 64); /* * Boost expression by voice volume above neutral. */ if (voicev > 65) xpn += voicev - 64; xpn += (voicev - 64) / 2; /* * Combine multiplicative and level components. */ x = vel * xpn * 6 + (voicev / 4) * x; #ifdef GUS_VOLUME /* * Further adjustment by installation-specific master volume control * (default 60). */ x = (x * GUS_VOLUME * GUS_VOLUME) / 10000; #endif #ifdef GUS_USE_CHN_MAIN_VOLUME /* * Experimental support for the channel main volume */ mainv = (mainv / 2) + 64; /* Scale to 64 to 127 */ x = (x * mainv * mainv) / 16384; #endif if (x < 2) return (0); else if (x >= 65535) return ((15 << 8) | 255); /* * Convert to gus's logarithmic form with 4 bit exponent i and 8 bit * mantissa m. */ n = x; i = 7; if (n < 128) { while (i > 0 && n < (1 << i)) i--; } else while (n > 255) { n >>= 1; i++; } /* * Mantissa is part of linear volume not expressed in exponent. (This is * not quite like real logs -- I wonder if it's right.) */ m = x - (1 << i); /* * Adjust mantissa to 8 bits. */ if (m > 0) { if (i > 8) m >>= i - 8; else if (i < 8) m <<= 8 - i; } return ((i << 8) + m); } /* * Volume-values are interpreted as linear values. Volume is based on the * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in) * and the volume set by the mixer-device (default 60%). */ unsigned short gus_linear_vol (int vol, int mainvol) { int mixer_mainvol; if (vol <= 0) vol = 0; else if (vol >= 127) vol = 127; #ifdef GUS_VOLUME mixer_mainvol = GUS_VOLUME; #else mixer_mainvol = 100; #endif #ifdef GUS_USE_CHN_MAIN_VOLUME if (mainvol <= 0) mainvol = 0; else if (mainvol >= 127) mainvol = 127; #else mainvol = 128; #endif return gus_linearvol[(((vol * mainvol) / 128) * mixer_mainvol) / 100]; } #endif |