gus_vol.c 3.3 KB

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