123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /* copyright 2006 Ben Allison */
- #include "ALACMP4Decoder.h"
- #include "alac/ALACBitUtilities.h"
- #include "api__alac.h"
- #include "decomp.h"
- #include <math.h>
- #include <string.h>
- #include "../external_dependencies/libmp4v2/mp4.h"
- #include "../Plugins/Input/in_mp4/mpeg4audio.h"
- // {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
- static const GUID playbackConfigGroupGUID =
- { 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
- int ALACMP4Decoder::OpenMP4(MP4FileHandle mp4_file, MP4TrackId mp4_track, size_t output_bits, size_t maxChannels, bool useFloat)
- {
- if (useFloat)
- return MP4_FAILURE;
- // get requested output bits
- this->output_bits = (int)output_bits;
- use_rg = false;
- rg = 1.0f;
- uint64_t val;
- if (MP4GetTrackIntegerProperty(mp4_file, mp4_track, "mdia.minf.stbl.stsd.*[0].channels", &val))
- channels = (int)val;
- else
- channels=2;
- if (MP4GetTrackIntegerProperty(mp4_file, mp4_track, "mdia.minf.stbl.stsd.*[0].sampleSize", &val))
- bps= (int)val;
- else
- bps=16;
- return MP4_SUCCESS;
- }
- int ALACMP4Decoder::GetCurrentBitrate(unsigned int *bitrate)
- {
- if (mpAlacDecoder->mConfig.avgBitRate)
- {
- *bitrate = mpAlacDecoder->mConfig.avgBitRate;
- return MP4_SUCCESS;
- }
- return MP4_GETCURRENTBITRATE_UNKNOWN; // TODO
- }
- /*
- * 32 bits atom size
- * 32 bits tag ("alac")
- *
- * Following data is passed to the function, ALACSpecificConfig structure (24 Bytes) does not contain
- * "tag version", check and skip if data contains it
- *
- * 32 bits tag version (0)
- * 32 bits samples per frame (used when not set explicitly in the frames) --> frameLength
- * 8 bits compatible version (0)
- * 8 bits sample size --> bitDepth
- * 8 bits history mult (40)
- * 8 bits initial history (10)
- * 8 bits rice param limit (14)
- * 8 bits channels --> numChannels
- * 16 bits maxRun (255)
- * 32 bits max coded frame size (0 means unknown) --> maxFrameBytes
- * 32 bits average bitrate (0 means unknown)
- * 32 bits samplerate
- */
- int ALACMP4Decoder::AudioSpecificConfiguration(void *buffer, size_t buffer_size)
- {
- mpAlacDecoder = new ALACDecoder();
- if (buffer_size > sizeof(ALACSpecificConfig))
- {
- // we have the "tag version" embedded;
- // just skip
- size_t skip = sizeof(uint32_t);
- mpAlacDecoder->Init((void*)((char*)buffer + skip), sizeof(ALACSpecificConfig));
- }
- else
- {
- mpAlacDecoder->Init(buffer, buffer_size);
- }
- /*alac = create_alac(bps, channels);
- alac_set_info(alac, reinterpret_cast<char *>(buffer));*/
- return MP4_SUCCESS;
- }
- void ALACMP4Decoder::Flush()
- {
- // TODO
- }
- void ALACMP4Decoder::Close()
- {
- if (mpAlacDecoder)
- {
- delete mpAlacDecoder;
- mpAlacDecoder = 0;
- }
- }
- int ALACMP4Decoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample)
- {
- *sampleRate = mpAlacDecoder->mConfig.sampleRate; // TODO: verify
- *channels = mpAlacDecoder->mConfig.numChannels;
- *bitsPerSample = mpAlacDecoder->mConfig.bitDepth;
- return MP4_SUCCESS;
- }
- int ALACMP4Decoder::OutputFrameSize(size_t *frameSize)
- {
- *frameSize = mpAlacDecoder->mConfig.frameLength; // TODO: verify
- return MP4_SUCCESS;
- }
- #define PA_CLIP_( val, min, max )\
- { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
- inline static void clip(double &x, double a, double b)
- {
- double x1 = fabs (x - a);
- double x2 = fabs (x - b);
- x = x1 + (a + b);
- x -= x2;
- x *= 0.5;
- }
- int ALACMP4Decoder::DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
- {
- struct BitBuffer inputChunk;
- BitBufferInit(&inputChunk, (uint8_t*)(inputBuffer), inputBufferBytes);
- uint32_t numFrames = 0;
- mpAlacDecoder->Decode(&inputChunk, (uint8_t*)(outputBuffer), mpAlacDecoder->mConfig.frameLength , mpAlacDecoder->mConfig.numChannels, &numFrames);
- size_t bytesPerSample = (mpAlacDecoder->mConfig.bitDepth / 8) * mpAlacDecoder->mConfig.numChannels;
- *outputBufferBytes = mpAlacDecoder->mConfig.frameLength * bytesPerSample;
- if (use_rg && mpAlacDecoder->mConfig.bitDepth == 16)
- {
- size_t numSamples = *outputBufferBytes / (mpAlacDecoder->mConfig.bitDepth / 8);
- //if (bitsPerSample == 16)
- {
- // TODO: this algorithm assumes ALAC bps is 16!!
- int16_t* audioBuffer = (int16_t*)outputBuffer;
- for (size_t i = 0; i != numSamples; i++)
- {
- float sample = (float)audioBuffer[i];
- int32_t temp = (int32_t)(sample * rg);
- PA_CLIP_(temp, -0x8000, 0x7FFF);
- audioBuffer[i] = (uint16_t)temp;
- }
- }
- }
- return MP4_SUCCESS;
- }
- const char *ALACMP4Decoder::GetCodecInfoString()
- {
- return "mdia.minf.stbl.stsd.alac.alac.decoderConfig";
- }
- int ALACMP4Decoder::CanHandleCodec(const char *codecName)
- {
- return !strcmp(codecName, "alac");
- }
- int ALACMP4Decoder::SetGain(float gain)
- {
- if (gain != 1.0f)
- {
- use_rg = true;
- rg = gain;
- }
- return MP4_SUCCESS;
- }
- #ifdef CBCLASS
- #undef CBCLASS
- #endif
- #define CBCLASS ALACMP4Decoder
- START_DISPATCH;
- CB(MPEG4_AUDIO_OPENMP4, OpenMP4)
- CB(MPEG4_AUDIO_ASC, AudioSpecificConfiguration)
- CB(MPEG4_AUDIO_BITRATE, GetCurrentBitrate)
- CB(MPEG4_AUDIO_FRAMESIZE, OutputFrameSize)
- CB(MPEG4_AUDIO_OUTPUTINFO, GetOutputProperties)
- CB(MPEG4_AUDIO_DECODE, DecodeSample)
- VCB(MPEG4_AUDIO_FLUSH, Flush)
- VCB(MPEG4_AUDIO_CLOSE, Close)
- CB(MPEG4_AUDIO_CODEC_INFO_STRING, GetCodecInfoString)
- CB(MPEG4_AUDIO_HANDLES_CODEC, CanHandleCodec)
- CB(MPEG4_AUDIO_SET_GAIN, SetGain)
- END_DISPATCH;
|