123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /** (c) Nullsoft, Inc. C O N F I D E N T I A L
- ** Filename:
- ** Project:
- ** Description:
- ** Author: Ben Allison [email protected]
- ** Created:
- **/
- #include "main.h"
- #include <stddef.h>
- #include "DecodeFile.h"
- #include "ExtendedReader.h"
- #include "OutputPluginAudioStream.h"
- #include "ResamplingReader.h"
- #include "CommonReader.h"
- // "input" means input FROM the decoder, "output" means output TO the person using the ifc_audiostream
- static bool RequiresResampling(const AudioParameters *input, size_t outputChannels, size_t outputBits, size_t outputSampleRate)
- {
- if (outputChannels != input->channels)
- return true; // need to up or downmix
- if (outputBits != input->bitsPerSample)
- return true;
- if (outputSampleRate != input->sampleRate)
- return true;
- return false;
- }
- static void SetResamplingParameters(const AudioParameters *input, size_t &outputChannels, size_t &outputBits, size_t &outputSampleRate)
- {
- // channels
- if (!outputChannels)
- outputChannels=input->channels;
- else if ((input->flags & AUDIOPARAMETERS_MAXCHANNELS) && input->channels <= outputChannels)
- outputChannels = input->channels;
- // bits
- if (!outputBits) outputBits = input->bitsPerSample;
-
- // samplerate
- if (!outputSampleRate)
- outputSampleRate = input->sampleRate;
- else if ((input->flags & AUDIOPARAMETERS_MAXSAMPLERATE) && input->sampleRate <= outputSampleRate)
- outputSampleRate = input->sampleRate;
- }
- ifc_audiostream *DecodeFile::OpenAudio(const wchar_t *filename, AudioParameters *parameters)
- {
- // save some info
- size_t outputChannels = parameters->channels;
- size_t outputBits = parameters->bitsPerSample;
- size_t outputSampleRate = parameters->sampleRate;
- CommonReader *reader = MakeReader(filename, parameters, true);
- if (!reader)
- return 0;
- // check if they've requested certain output parameters
- if (outputChannels || outputBits || outputSampleRate)
- {
- SetResamplingParameters(parameters, outputChannels, outputBits, outputSampleRate);
- // check if we need any resampling/conversion
- if (RequiresResampling(parameters, outputChannels, outputBits, outputSampleRate))
- {
- Resampler *resampler = new Resampler(parameters->bitsPerSample, parameters->channels, parameters->sampleRate,
- outputBits, outputChannels, outputSampleRate, parameters->flags & AUDIOPARAMETERS_FLOAT);
- if (!resampler->OK())
- {
- parameters->errorCode = API_DECODEFILE_BAD_RESAMPLE;
- delete resampler;
- return 0;
- }
- parameters->bitsPerSample = (uint32_t)outputBits;
- parameters->channels = (uint32_t)outputChannels;
- parameters->sampleRate = (uint32_t)outputSampleRate;
- parameters->sizeBytes =(size_t)((double)parameters->sizeBytes * resampler->sizeFactor);
- ResamplingReader *resampleReader = new ResamplingReader(resampler, reader, outputChannels * outputBits / 8);
- return resampleReader;
- }
- }
- return reader;
- }
- ifc_audiostream *DecodeFile::OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters)
- {
- // save some info
- size_t outputChannels = parameters->channels;
- size_t outputBits = parameters->bitsPerSample;
- size_t outputSampleRate = parameters->sampleRate;
- CommonReader *reader = MakeReader(filename, parameters, false);
- if (!reader)
- return 0;
- // check if they've requested certain output parameters
- if (outputChannels || outputBits || outputSampleRate)
- {
- SetResamplingParameters(parameters, outputChannels, outputBits, outputSampleRate);
- // check if we need any resampling/conversion
- if (RequiresResampling(parameters, outputChannels, outputBits, outputSampleRate))
- {
- Resampler *resampler = new Resampler(parameters->bitsPerSample, parameters->channels, parameters->sampleRate,
- outputBits, outputChannels, outputSampleRate, parameters->flags & AUDIOPARAMETERS_FLOAT);
- if (!resampler->OK())
- {
- parameters->errorCode = API_DECODEFILE_BAD_RESAMPLE;
- delete resampler;
- delete reader;
- return 0;
- }
- parameters->bitsPerSample = (uint32_t)outputBits;
- parameters->channels = (uint32_t)outputChannels;
- parameters->sampleRate = (uint32_t)outputSampleRate;
- ResamplingReader *resampleReader = new ResamplingReader(resampler, reader, outputChannels * outputBits / 8);
-
- return resampleReader;
- }
- }
- return reader;
- }
- CommonReader *DecodeFile::MakeReader(const wchar_t *filename, AudioParameters *parameters, bool useUnagi)
- {
- In_Module *in;
- int a = 0;
- bool found = false;
- while (a >= 0)
- {
- OpenFunc open = 0, openFloat=0;
- OpenWFunc openW=0, openWFloat=0;
- GetDataFunc getData = 0;
- CloseFunc close = 0;
- SetTimeFunc setTime = 0;
- in = in_setmod_noplay(filename, &a);
- if (!in) break;
- if (a >= 0) a++;
- found = true;
- open = (OpenFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_open");
- openFloat = (OpenFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_open_float");
- openW = (OpenWFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_openW");
- openWFloat = (OpenWFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_openW_float");
- getData = (GetDataFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_getData");
- close = (CloseFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_close");
- setTime = (SetTimeFunc)GetProcAddress(in->hDllInstance, "winampGetExtendedRead_setTime"); //optional!
- if ((open || openW) && getData && close)
- {
- ExtendedReader *reader = new ExtendedReader(open, openW, openFloat, openWFloat, getData, close, setTime);
- if (reader->Open(filename, parameters))
- return reader;
- else
- delete reader;
- }
- }
- if (!found || !useUnagi)
- {
- parameters->errorCode = API_DECODEFILE_UNSUPPORTED;
- }
- else
- {
- OutputPluginAudioStream *reader = new OutputPluginAudioStream;
- in = in_setmod_noplay(filename, 0);
- if (reader->Open(in, filename, parameters))
- return reader;
- delete reader;
- }
- return 0;
- }
- void DecodeFile::CloseAudio(ifc_audiostream *audioStream)
- {
- CommonReader *reader = static_cast<CommonReader *>(audioStream);
- delete reader;
- //audioStream=0;
- }
- #define CBCLASS DecodeFile
- START_DISPATCH;
- CB(API_DECODEFILE_OPENAUDIO, OpenAudio)
- CB(API_DECODEFILE_OPENAUDIO2, OpenAudioBackground)
- VCB(API_DECODEFILE_CLOSEAUDIO, CloseAudio)
- END_DISPATCH;
|