1
0

DecodeFile.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author: Ben Allison [email protected]
  6. ** Created:
  7. **/
  8. #include "main.h"
  9. #include <stddef.h>
  10. #include "DecodeFile.h"
  11. #include "ExtendedReader.h"
  12. #include "OutputPluginAudioStream.h"
  13. #include "ResamplingReader.h"
  14. #include "CommonReader.h"
  15. // "input" means input FROM the decoder, "output" means output TO the person using the ifc_audiostream
  16. static bool RequiresResampling(const AudioParameters *input, size_t outputChannels, size_t outputBits, size_t outputSampleRate)
  17. {
  18. if (outputChannels != input->channels)
  19. return true; // need to up or downmix
  20. if (outputBits != input->bitsPerSample)
  21. return true;
  22. if (outputSampleRate != input->sampleRate)
  23. return true;
  24. return false;
  25. }
  26. static void SetResamplingParameters(const AudioParameters *input, size_t &outputChannels, size_t &outputBits, size_t &outputSampleRate)
  27. {
  28. // channels
  29. if (!outputChannels)
  30. outputChannels=input->channels;
  31. else if ((input->flags & AUDIOPARAMETERS_MAXCHANNELS) && input->channels <= outputChannels)
  32. outputChannels = input->channels;
  33. // bits
  34. if (!outputBits) outputBits = input->bitsPerSample;
  35. // samplerate
  36. if (!outputSampleRate)
  37. outputSampleRate = input->sampleRate;
  38. else if ((input->flags & AUDIOPARAMETERS_MAXSAMPLERATE) && input->sampleRate <= outputSampleRate)
  39. outputSampleRate = input->sampleRate;
  40. }
  41. ifc_audiostream *DecodeFile::OpenAudio(const wchar_t *filename, AudioParameters *parameters)
  42. {
  43. // save some info
  44. size_t outputChannels = parameters->channels;
  45. size_t outputBits = parameters->bitsPerSample;
  46. size_t outputSampleRate = parameters->sampleRate;
  47. CommonReader *reader = MakeReader(filename, parameters, true);
  48. if (!reader)
  49. return 0;
  50. // check if they've requested certain output parameters
  51. if (outputChannels || outputBits || outputSampleRate)
  52. {
  53. SetResamplingParameters(parameters, outputChannels, outputBits, outputSampleRate);
  54. // check if we need any resampling/conversion
  55. if (RequiresResampling(parameters, outputChannels, outputBits, outputSampleRate))
  56. {
  57. Resampler *resampler = new Resampler(parameters->bitsPerSample, parameters->channels, parameters->sampleRate,
  58. outputBits, outputChannels, outputSampleRate, parameters->flags & AUDIOPARAMETERS_FLOAT);
  59. if (!resampler->OK())
  60. {
  61. parameters->errorCode = API_DECODEFILE_BAD_RESAMPLE;
  62. delete resampler;
  63. return 0;
  64. }
  65. parameters->bitsPerSample = (uint32_t)outputBits;
  66. parameters->channels = (uint32_t)outputChannels;
  67. parameters->sampleRate = (uint32_t)outputSampleRate;
  68. parameters->sizeBytes =(size_t)((double)parameters->sizeBytes * resampler->sizeFactor);
  69. ResamplingReader *resampleReader = new ResamplingReader(resampler, reader, outputChannels * outputBits / 8);
  70. return resampleReader;
  71. }
  72. }
  73. return reader;
  74. }
  75. ifc_audiostream *DecodeFile::OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters)
  76. {
  77. // save some info
  78. size_t outputChannels = parameters->channels;
  79. size_t outputBits = parameters->bitsPerSample;
  80. size_t outputSampleRate = parameters->sampleRate;
  81. CommonReader *reader = MakeReader(filename, parameters, false);
  82. if (!reader)
  83. return 0;
  84. // check if they've requested certain output parameters
  85. if (outputChannels || outputBits || outputSampleRate)
  86. {
  87. SetResamplingParameters(parameters, outputChannels, outputBits, outputSampleRate);
  88. // check if we need any resampling/conversion
  89. if (RequiresResampling(parameters, outputChannels, outputBits, outputSampleRate))
  90. {
  91. Resampler *resampler = new Resampler(parameters->bitsPerSample, parameters->channels, parameters->sampleRate,
  92. outputBits, outputChannels, outputSampleRate, parameters->flags & AUDIOPARAMETERS_FLOAT);
  93. if (!resampler->OK())
  94. {
  95. parameters->errorCode = API_DECODEFILE_BAD_RESAMPLE;
  96. delete resampler;
  97. delete reader;
  98. return 0;
  99. }
  100. parameters->bitsPerSample = (uint32_t)outputBits;
  101. parameters->channels = (uint32_t)outputChannels;
  102. parameters->sampleRate = (uint32_t)outputSampleRate;
  103. ResamplingReader *resampleReader = new ResamplingReader(resampler, reader, outputChannels * outputBits / 8);
  104. return resampleReader;
  105. }
  106. }
  107. return reader;
  108. }
  109. CommonReader *DecodeFile::MakeReader(const wchar_t *filename, AudioParameters *parameters, bool useUnagi)
  110. {
  111. In_Module *in;
  112. int a = 0;
  113. bool found = false;
  114. while (a >= 0)
  115. {
  116. OpenFunc open = 0, openFloat=0;
  117. OpenWFunc openW=0, openWFloat=0;
  118. GetDataFunc getData = 0;
  119. CloseFunc close = 0;
  120. SetTimeFunc setTime = 0;
  121. in = in_setmod_noplay(filename, &a);
  122. if (!in) break;
  123. if (a >= 0) a++;
  124. found = true;
  125. open = (OpenFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_open");
  126. openFloat = (OpenFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_open_float");
  127. openW = (OpenWFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_openW");
  128. openWFloat = (OpenWFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_openW_float");
  129. getData = (GetDataFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_getData");
  130. close = (CloseFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_close");
  131. setTime = (SetTimeFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_setTime"); //optional!
  132. if ((open || openW) && getData && close)
  133. {
  134. ExtendedReader *reader = new ExtendedReader(open, openW, openFloat, openWFloat, getData, close, setTime);
  135. if (reader->Open(filename, parameters))
  136. return reader;
  137. else
  138. delete reader;
  139. }
  140. }
  141. if (!found || !useUnagi)
  142. {
  143. parameters->errorCode = API_DECODEFILE_UNSUPPORTED;
  144. }
  145. else
  146. {
  147. OutputPluginAudioStream *reader = new OutputPluginAudioStream;
  148. in = in_setmod_noplay(filename, 0);
  149. if (reader->Open(in, filename, parameters))
  150. return reader;
  151. delete reader;
  152. }
  153. return 0;
  154. }
  155. void DecodeFile::CloseAudio(ifc_audiostream *audioStream)
  156. {
  157. CommonReader *reader = static_cast<CommonReader *>(audioStream);
  158. delete reader;
  159. //audioStream=0;
  160. }
  161. #define CBCLASS DecodeFile
  162. START_DISPATCH;
  163. CB(API_DECODEFILE_OPENAUDIO, OpenAudio)
  164. CB(API_DECODEFILE_OPENAUDIO2, OpenAudioBackground)
  165. VCB(API_DECODEFILE_CLOSEAUDIO, CloseAudio)
  166. END_DISPATCH;