Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | |
| 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 | |
| 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 | } |