Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
202
Src/Winamp/DecodeFile.cpp
Normal file
202
Src/Winamp/DecodeFile.cpp
Normal file
|
@ -0,0 +1,202 @@
|
|||
/** (c) Nullsoft, Inc. C O N F I D E N T I A L
|
||||
** Filename:
|
||||
** Project:
|
||||
** Description:
|
||||
** Author: Ben Allison benski@nullsoft.com
|
||||
** 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;
|
Loading…
Add table
Add a link
Reference in a new issue