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