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