gus_vol.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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.  
  43. if (voicev > 65)
  44. xpn += voicev - 64;
  45. xpn += (voicev - 64) / 2;
  46. /*
  47.  * Combine multiplicative and level components.
  48.  */
  49. x = vel * xpn * 6 + (voicev / 4) * x;
  50. #ifdef GUS_VOLUME
  51. /*
  52.  * Further adjustment by installation-specific master volume control
  53.  * (default 60).
  54.  */
  55. x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
  56. #endif
  57. #ifdef GUS_USE_CHN_MAIN_VOLUME
  58. /*
  59.  * Experimental support for the channel main volume
  60.  */
  61. mainv = (mainv / 2) + 64; /* Scale to 64 to 127 */
  62. x = (x * mainv * mainv) / 16384;
  63. #endif
  64. if (x < 2)
  65. return (0);
  66. else if (x >= 65535)
  67. return ((15 << 8) | 255);
  68. /*
  69.  * Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit
  70.  * mantissa m.
  71.  */
  72.  
  73. n = x;
  74. i = 7;
  75. if (n < 128)
  76. {
  77.   while (i > 0 && n < (1 << i))
  78.   i--;
  79. }
  80. else
  81. {
  82. while (n > 255)
  83. {
  84.   n >>= 1;
  85.   i++;
  86. }
  87. }
  88. /*
  89.  * Mantissa is part of linear volume not expressed in exponent.  (This is
  90.  * not quite like real logs -- I wonder if it's right.)
  91.  */
  92. m = x - (1 << i);
  93. /*
  94.  * Adjust mantissa to 8 bits.
  95.  */
  96. if (m > 0)
  97. {
  98. if (i > 8)
  99. m >>= i - 8;
  100. else if (i < 8)
  101. m <<= 8 - i;
  102. }
  103. return ((i << 8) + m);
  104. }
  105. /*
  106.  * Volume-values are interpreted as linear values. Volume is based on the
  107.  * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
  108.  * and the volume set by the mixer-device (default 60%).
  109.  */
  110. unsigned short gus_linear_vol(int vol, int mainvol)
  111. {
  112. int mixer_mainvol;
  113. if (vol <= 0)
  114. vol = 0;
  115. else if (vol >= 127)
  116. vol = 127;
  117. #ifdef GUS_VOLUME
  118. mixer_mainvol = GUS_VOLUME;
  119. #else
  120. mixer_mainvol = 100;
  121. #endif
  122. #ifdef GUS_USE_CHN_MAIN_VOLUME
  123. if (mainvol <= 0)
  124. mainvol = 0;
  125. else if (mainvol >= 127)
  126. mainvol = 127;
  127. #else
  128. mainvol = 127;
  129. #endif
  130. return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
  131. }