GainLayer.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #include "main.h"
  2. #include "GainLayer.h"
  3. #include <malloc.h>
  4. #include <math.h>
  5. #include <locale.h>
  6. #include "api.h"
  7. static void FillFloat(float *floatBuf, void *samples, size_t bps, size_t numSamples, size_t numChannels, float preamp)
  8. {
  9. switch (bps)
  10. {
  11. case 8:
  12. {
  13. unsigned __int8 *samples8 = (unsigned __int8 *)samples;
  14. size_t totalSamples = numSamples * numChannels;
  15. for (size_t x = 0; x != totalSamples; x ++)
  16. {
  17. floatBuf[x] = (float)(samples8[x] - 128) * preamp;
  18. }
  19. }
  20. break;
  21. case 16:
  22. {
  23. short *samples16 = (short *)samples;
  24. size_t totalSamples = numSamples * numChannels;
  25. for (size_t x = 0; x != totalSamples; x ++)
  26. {
  27. floatBuf[x] = (float)samples16[x] * preamp;
  28. }
  29. }
  30. break;
  31. case 24:
  32. {
  33. unsigned __int8 *samples8 = (unsigned __int8 *)samples;
  34. size_t totalSamples = numSamples * numChannels;
  35. for (size_t x = 0; x != totalSamples; x ++)
  36. {
  37. long temp = (((long)samples8[0]) << 8);
  38. temp = temp | (((long)samples8[1]) << 16);
  39. temp = temp | (((long)samples8[2]) << 24);
  40. floatBuf[x] = (float)temp * preamp;
  41. samples8 += 3;
  42. }
  43. }
  44. break;
  45. }
  46. }
  47. inline static float fastclip(float x, const float a, const float b)
  48. {
  49. float x1 = (float)fabs (x - a);
  50. float x2 = (float)fabs (x - b);
  51. x = x1 + (a + b);
  52. x -= x2;
  53. x *= 0.5f;
  54. return (x);
  55. }
  56. #define PA_CLIP_( val, min, max )\
  57. { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
  58. void Float32_To_Int16_Clip(
  59. void *destinationBuffer, signed int destinationStride,
  60. void *sourceBuffer, signed int sourceStride,
  61. unsigned int count)
  62. {
  63. float *src = (float*)sourceBuffer;
  64. signed short *dest = (signed short*)destinationBuffer;
  65. while ( count-- )
  66. {
  67. long samp = lrint(*src);
  68. PA_CLIP_( samp, -0x8000, 0x7FFF );
  69. *dest = (signed short) samp;
  70. src += sourceStride;
  71. dest += destinationStride;
  72. }
  73. }
  74. inline static void clip(double &x, double a, double b)
  75. {
  76. double x1 = fabs (x - a);
  77. double x2 = fabs (x - b);
  78. x = x1 + (a + b);
  79. x -= x2;
  80. x *= 0.5;
  81. }
  82. void Float32_To_Int24_Clip(
  83. void *destinationBuffer, signed int destinationStride,
  84. void *sourceBuffer, signed int sourceStride,
  85. unsigned int count)
  86. {
  87. float *src = (float*)sourceBuffer;
  88. unsigned char *dest = (unsigned char*)destinationBuffer;
  89. while ( count-- )
  90. {
  91. /* convert to 32 bit and drop the low 8 bits */
  92. double scaled = *src;
  93. clip( scaled, -2147483648., 2147483647. );
  94. signed long temp = (signed long) scaled;
  95. dest[0] = (unsigned char)(temp >> 8);
  96. dest[1] = (unsigned char)(temp >> 16);
  97. dest[2] = (unsigned char)(temp >> 24);
  98. src += sourceStride;
  99. dest += destinationStride * 3;
  100. }
  101. }
  102. static void FillSamples(void *samples, float *floatBuf, size_t bps, size_t numSamples, size_t numChannels)
  103. {
  104. switch (bps)
  105. {
  106. case 16:
  107. Float32_To_Int16_Clip(samples, 1, floatBuf, 1, numSamples*numChannels);
  108. break;
  109. case 24:
  110. Float32_To_Int24_Clip(samples, 1, floatBuf, 1, numSamples*numChannels);
  111. break;
  112. }
  113. }
  114. float GetGain(WMInformation *info, bool allowDefault)
  115. {
  116. if (AGAVE_API_CONFIG && AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain", false))
  117. {
  118. float dB = 0, peak = 1.0f;
  119. wchar_t gain[64]=L"", peakVal[64]=L"";
  120. switch (AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_source", 0))
  121. {
  122. case 0: // track
  123. info->GetAttribute(L"replaygain_track_gain", gain, 64);
  124. if (!gain[0] && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
  125. info->GetAttribute(L"replaygain_album_gain", gain, 64);
  126. info->GetAttribute(L"replaygain_track_peak", peakVal, 64);
  127. if (!peakVal[0] && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
  128. info->GetAttribute(L"replaygain_album_peak", peakVal, 64);
  129. break;
  130. case 1:
  131. info->GetAttribute(L"replaygain_album_gain", gain, 64);
  132. if (!gain[0] && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
  133. info->GetAttribute(L"replaygain_track_gain", gain, 64);
  134. info->GetAttribute(L"replaygain_album_peak", peakVal, 64);
  135. if (!peakVal[0] && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
  136. info->GetAttribute(L"replaygain_track_peak", peakVal, 64);
  137. break;
  138. }
  139. _locale_t C_locale = WASABI_API_LNG->Get_C_NumericLocale();
  140. if (gain[0])
  141. {
  142. if (gain[0] == L'+')
  143. dB = static_cast<float>(_wtof_l(&gain[1],C_locale));
  144. else
  145. dB = static_cast<float>(_wtof_l(gain,C_locale));
  146. }
  147. else if (allowDefault)
  148. {
  149. dB = AGAVE_API_CONFIG->GetFloat(playbackConfigGroupGUID, L"non_replaygain", -6.0);
  150. return powf(10.0f, dB / 20.0f);
  151. }
  152. if (peakVal[0])
  153. {
  154. peak = static_cast<float>(_wtof_l(peakVal,C_locale));
  155. }
  156. switch (AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_mode", 1))
  157. {
  158. case 0: // apply gain
  159. return powf(10.0f, dB / 20.0f);
  160. case 1: // apply gain, but don't clip
  161. return min(powf(10.0f, dB / 20.0f), 1.0f / peak);
  162. case 2: // normalize
  163. return 1.0f / peak;
  164. case 3: // prevent clipping
  165. if (peak > 1.0f)
  166. return 1.0f / peak;
  167. else
  168. return 1.0f;
  169. }
  170. }
  171. return 1.0f; // no gain
  172. }
  173. void GainLayer::AudioDataReceived(void *_data, unsigned long sizeBytes, DWORD timestamp)
  174. {
  175. if (enabled)
  176. {
  177. size_t samples = audio->AudioBytesToSamples(sizeBytes);
  178. int channels = audio->Channels();
  179. if (floatSize < (samples * channels))
  180. {
  181. delete [] floatData;
  182. floatSize = samples * channels;
  183. floatData = new float[floatSize];
  184. }
  185. if (outSize < sizeBytes)
  186. {
  187. delete [] outData;
  188. outSize=sizeBytes;
  189. outData = (void *)new __int8[sizeBytes];
  190. }
  191. FillFloat(floatData, _data, audio->BitSize(), samples , channels, replayGain);
  192. FillSamples(outData, floatData, audio->BitSize(), samples , channels);
  193. WMHandler::AudioDataReceived(outData, sizeBytes, timestamp);
  194. }
  195. else
  196. WMHandler::AudioDataReceived(_data, sizeBytes, timestamp);
  197. }
  198. void GainLayer::Opened()
  199. {
  200. enabled= (AGAVE_API_CONFIG && AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain", false));
  201. if (enabled)
  202. replayGain = GetGain(info, true);
  203. WMHandler::Opened();
  204. }