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