ALAC : Unify interface between libsndfile and ALAC codec.

This commit is contained in:
Erik de Castro Lopo 2012-03-10 10:55:44 +11:00
parent 80f0c07126
commit d93bfaaa75
8 changed files with 304 additions and 783 deletions

View File

@ -1,3 +1,13 @@
2012-02-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/ALAC/ src/alac.c
Unify the interface between libsndfile and Apple ALAC codec. Regardless of
file bit width samples are now passed between the two as int32_t that are
justified towards the most significant bit. Without this modification, 16
conversion functions would have been needed between the libsndfile (short,
int, float, double) types and the ALAC types (16, 20, 24 and 32 bit). With
this mod, only 4 are needed.
2012-02-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* configure.ac src/sfconfig.h src/sfendian.h

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
@ -86,11 +87,11 @@ typedef struct alac_encoder_s
int32_t alac_decoder_init (ALAC_DECODER *p, void * inMagicCookie, uint32_t inMagicCookieSize) ;
int32_t alac_encoder_init (ALAC_ENCODER *p, uint32_t samplerate, uint32_t channels, uint32_t format_flags, uint32_t frameSize) ;
int32_t alac_decode (ALAC_DECODER *, struct BitBuffer * bits, uint8_t * sampleBuffer,
int32_t alac_decode (ALAC_DECODER *, struct BitBuffer * bits, int32_t * sampleBuffer,
uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples) ;
int32_t alac_encode (ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
unsigned char * theReadBuffer, unsigned char * theWriteBuffer,
int32_t alac_encode (ALAC_ENCODER *p, uint32_t numChannels, uint32_t numSamples,
int32_t * theReadBuffer, unsigned char * theWriteBuffer,
int32_t * ioNumBytes) ;
void alac_set_fastmode(ALAC_ENCODER * p, int32_t fast) ;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
@ -47,8 +48,6 @@ const uint32_t kMaxBitDepth = 32; // max allowed bit depth is 32
static int32_t alac_fill_element (struct BitBuffer * bits) ;
static int32_t alac_data_stream_element (struct BitBuffer * bits) ;
static void Zero16( int16_t * buffer, uint32_t numItems, uint32_t stride );
static void Zero24( uint8_t * buffer, uint32_t numItems, uint32_t stride );
static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride );
@ -131,7 +130,7 @@ Exit:
the bitstream
*/
int32_t
alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples)
alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples)
{
BitBuffer shiftBits;
uint32_t bits1, bits2;
@ -153,9 +152,6 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, uint8_t * sampleBuffer, u
uint32_t denShiftU, denShiftV;
uint16_t pbFactorU, pbFactorV;
uint16_t pb;
int16_t * out16;
uint8_t * out20;
uint8_t * out24;
int32_t * out32;
uint8_t headerByte;
uint8_t partialFrame;
@ -304,23 +300,23 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, uint8_t * sampleBuffer, u
switch ( p->mConfig.bitDepth )
{
case 16:
out16 = &((int16_t *)sampleBuffer)[channelIndex];
out32 = sampleBuffer + channelIndex;
for ( i = 0, j = 0; i < numSamples; i++, j += numChannels )
out16[j] = (int16_t) p->mMixBufferU[i];
out32[j] = p->mMixBufferU[i] << 16;
break;
case 20:
out20 = (uint8_t *)sampleBuffer + (channelIndex * 3);
copyPredictorTo20( p->mMixBufferU, out20, numChannels, numSamples );
out32 = sampleBuffer + channelIndex;
copyPredictorTo20( p->mMixBufferU, out32, numChannels, numSamples );
break;
case 24:
out24 = (uint8_t *)sampleBuffer + (channelIndex * 3);
out32 = sampleBuffer + channelIndex;
if ( bytesShifted != 0 )
copyPredictorTo24Shift( p->mMixBufferU, p->mShiftBuffer, out24, numChannels, numSamples, bytesShifted );
copyPredictorTo24Shift( p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted );
else
copyPredictorTo24( p->mMixBufferU, out24, numChannels, numSamples );
copyPredictorTo24( p->mMixBufferU, out32, numChannels, numSamples );
break;
case 32:
out32 = &((int32_t *)sampleBuffer)[channelIndex];
out32 = sampleBuffer + channelIndex;
if ( bytesShifted != 0 )
copyPredictorTo32Shift( p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted );
else
@ -493,20 +489,20 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, uint8_t * sampleBuffer, u
switch ( p->mConfig.bitDepth )
{
case 16:
out16 = &((int16_t *)sampleBuffer)[channelIndex];
unmix16( p->mMixBufferU, p->mMixBufferV, out16, numChannels, numSamples, mixBits, mixRes );
out32 = sampleBuffer + channelIndex;
unmix16( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples, mixBits, mixRes );
break;
case 20:
out20 = (uint8_t *)sampleBuffer + (channelIndex * 3);
unmix20( p->mMixBufferU, p->mMixBufferV, out20, numChannels, numSamples, mixBits, mixRes );
out32 = sampleBuffer + channelIndex;
unmix20( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples, mixBits, mixRes );
break;
case 24:
out24 = (uint8_t *)sampleBuffer + (channelIndex * 3);
unmix24( p->mMixBufferU, p->mMixBufferV, out24, numChannels, numSamples,
out32 = sampleBuffer + channelIndex;
unmix24( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
mixBits, mixRes, p->mShiftBuffer, bytesShifted );
break;
case 32:
out32 = &((int32_t *)sampleBuffer)[channelIndex];
out32 = sampleBuffer + channelIndex;
unmix32( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
mixBits, mixRes, p->mShiftBuffer, bytesShifted );
break;
@ -562,27 +558,8 @@ NoMoreChannels:
// if we get here and haven't decoded all of the requested channels, fill the remaining channels with zeros
for ( ; channelIndex < numChannels; channelIndex++ )
{
switch ( p->mConfig.bitDepth )
{
case 16:
{
int16_t * fill16 = &((int16_t *)sampleBuffer)[channelIndex];
Zero16( fill16, numSamples, numChannels );
break;
}
case 24:
{
uint8_t * fill24 = (uint8_t *)sampleBuffer + (channelIndex * 3);
Zero24( fill24, numSamples, numChannels );
break;
}
case 32:
{
int32_t * fill32 = &((int32_t *)sampleBuffer)[channelIndex];
Zero32( fill32, numSamples, numChannels );
break;
}
}
int32_t * fill32 = sampleBuffer + channelIndex;
Zero32( fill32, numSamples, numChannels );
}
Exit:
@ -652,36 +629,6 @@ alac_data_stream_element (struct BitBuffer * bits)
ZeroN()
- helper routines to clear out output channel buffers when decoding fewer channels than requested
*/
static void Zero16( int16_t * buffer, uint32_t numItems, uint32_t stride )
{
if ( stride == 1 )
{
memset( buffer, 0, numItems * sizeof(int16_t) );
}
else
{
for ( uint32_t indx = 0; indx < (numItems * stride); indx += stride )
buffer[indx] = 0;
}
}
static void Zero24( uint8_t * buffer, uint32_t numItems, uint32_t stride )
{
if ( stride == 1 )
{
memset( buffer, 0, numItems * 3 );
}
else
{
for ( uint32_t indx = 0; indx < (numItems * stride * 3); indx += (stride * 3) )
{
buffer[indx + 0] = 0;
buffer[indx + 1] = 0;
buffer[indx + 2] = 0;
}
}
}
static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride )
{
if ( stride == 1 )

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
@ -24,6 +25,7 @@
// build stuff
#define VERBOSE_DEBUG 0
#define DebugMsg printf
// headers
#include <stdio.h>
@ -50,10 +52,10 @@ typedef enum
static void GetConfig(ALAC_ENCODER *p, ALACSpecificConfig * config );
static int32_t EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
static int32_t EncodeStereoFast(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
static int32_t EncodeStereoEscape(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t numSamples );
static int32_t EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
static int32_t EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
static int32_t EncodeStereoFast(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
static int32_t EncodeStereoEscape(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * input, uint32_t stride, uint32_t numSamples );
static int32_t EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
@ -64,9 +66,9 @@ typedef int16_t (*SearchCoefs)[kALACMaxCoefs];
// defines/constants
const uint32_t kALACEncoderMagic = MAKE_MARKER ('d', 'p', 'g', 'e');
const uint32_t kMaxSampleSize = 32; // max allowed bit width is 32
const uint32_t kDefaultMixBits = 2;
const uint32_t kDefaultMixBits = 2;
const uint32_t kDefaultMixRes = 0;
const uint32_t kMaxRes = 4;
const uint32_t kMaxRes = 4;
const uint32_t kDefaultNumUV = 8;
const uint32_t kMinUV = 4;
const uint32_t kMaxUV = 8;
@ -223,28 +225,28 @@ alac_set_fastmode (ALAC_ENCODER * p, int32_t fast )
- encode a channel pair
*/
static int32_t
EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples )
EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples )
{
BitBuffer workBits;
BitBuffer startBits = *bitstream; // squirrel away copy of current state in case we need to go back and do an escape packet
AGParamRec agParams;
uint32_t bits1, bits2;
uint32_t dilate;
uint32_t bits1, bits2;
uint32_t dilate;
int32_t mixBits, mixRes, maxRes;
uint32_t minBits, minBits1, minBits2;
uint32_t numU, numV;
uint32_t mode;
uint32_t pbFactor;
uint32_t chanBits;
uint32_t minBits, minBits1, minBits2;
uint32_t numU, numV;
uint32_t mode;
uint32_t pbFactor;
uint32_t chanBits;
uint8_t bytesShifted;
SearchCoefs coefsU;
SearchCoefs coefsV;
uint32_t indx;
uint32_t indx;
uint8_t partialFrame;
uint32_t escapeBits;
uint32_t escapeBits;
bool doEscape;
int32_t status = ALAC_noErr;
int32_t bestRes;
int32_t status = ALAC_noErr;
int32_t bestRes;
// make sure we handle this bit-depth before we get going
RequireAction( (p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError; );
@ -291,19 +293,19 @@ EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer,
switch ( p->mBitDepth )
{
case 16:
mix16( (int16_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate, mixBits, mixRes );
mix16( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate, mixBits, mixRes );
break;
case 20:
mix20( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate, mixBits, mixRes );
mix20( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate, mixBits, mixRes );
break;
case 24:
// includes extraction of shifted-off bytes
mix24( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate,
mix24( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate,
mixBits, mixRes, p->mShiftBufferUV, bytesShifted );
break;
case 32:
// includes extraction of shifted-off bytes
mix32( (int32_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate,
mix32( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples/dilate,
mixBits, mixRes, p->mShiftBufferUV, bytesShifted );
break;
}
@ -338,19 +340,19 @@ EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer,
switch ( p->mBitDepth )
{
case 16:
mix16( (int16_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
mix16( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
break;
case 20:
mix20( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
mix20( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
break;
case 24:
// also extracts the shifted off bytes into the shift buffers
mix24( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mix24( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mixBits, mixRes, p->mShiftBufferUV, bytesShifted );
break;
case 32:
// also extracts the shifted off bytes into the shift buffers
mix32( (int32_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mix32( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mixBits, mixRes, p->mShiftBufferUV, bytesShifted );
break;
}
@ -492,7 +494,7 @@ EncodeStereo(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer,
status = EncodeStereoEscape(p, bitstream, inputBuffer, stride, numSamples );
#if VERBOSE_DEBUG
DebugMsg( "escape!: %lu vs %lu", minBits, escapeBits );
DebugMsg( "escape!: %u vs %u\n", minBits, escapeBits );
#endif
}
@ -505,25 +507,25 @@ Exit:
- encode a channel pair without the search loop for maximum possible speed
*/
static int32_t
EncodeStereoFast(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples )
EncodeStereoFast(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples )
{
BitBuffer startBits = *bitstream; // squirrel away current bit position in case we decide to use escape hatch
AGParamRec agParams;
uint32_t bits1, bits2;
uint32_t bits1, bits2;
int32_t mixBits, mixRes;
uint32_t minBits, minBits1, minBits2;
uint32_t numU, numV;
uint32_t mode;
uint32_t pbFactor;
uint32_t chanBits;
uint32_t minBits, minBits1, minBits2;
uint32_t numU, numV;
uint32_t mode;
uint32_t pbFactor;
uint32_t chanBits;
uint8_t bytesShifted;
SearchCoefs coefsU;
SearchCoefs coefsV;
uint32_t indx;
uint32_t indx;
uint8_t partialFrame;
uint32_t escapeBits;
uint32_t escapeBits;
bool doEscape;
int32_t status;
int32_t status;
// make sure we handle this bit-depth before we get going
RequireAction( (p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError; );
@ -564,19 +566,19 @@ EncodeStereoFast(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuff
switch ( p->mBitDepth )
{
case 16:
mix16( (int16_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
mix16( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
break;
case 20:
mix20( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
mix20( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes );
break;
case 24:
// also extracts the shifted off bytes into the shift buffers
mix24( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mix24( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mixBits, mixRes, p->mShiftBufferUV, bytesShifted );
break;
case 32:
// also extracts the shifted off bytes into the shift buffers
mix32( (int32_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mix32( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples,
mixBits, mixRes, p->mShiftBufferUV, bytesShifted );
break;
}
@ -674,7 +676,7 @@ EncodeStereoFast(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuff
status = EncodeStereoEscape(p, bitstream, inputBuffer, stride, numSamples );
#if VERBOSE_DEBUG
DebugMsg( "escape!: %u vs %u", minBits, (numSamples * mBitDepth * 2) );
DebugMsg( "escape!: %u vs %u\n", minBits, (numSamples * p->mBitDepth * 2) );
#endif
}
@ -687,12 +689,10 @@ Exit:
- encode stereo escape frame
*/
static int32_t
EncodeStereoEscape(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, uint32_t stride, uint32_t numSamples )
EncodeStereoEscape(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * inputBuffer, uint32_t stride, uint32_t numSamples )
{
int16_t * input16;
int32_t * input32;
uint8_t partialFrame;
uint32_t indx;
uint32_t indx;
// flag whether or not this is a partial frame
partialFrame = (numSamples == p->mFrameSize) ? 0 : 1;
@ -707,39 +707,33 @@ EncodeStereoEscape(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBu
switch ( p->mBitDepth )
{
case 16:
input16 = (int16_t *) inputBuffer;
for ( indx = 0; indx < (numSamples * stride); indx += stride )
{
BitBufferWrite( bitstream, input16[indx + 0], 16 );
BitBufferWrite( bitstream, input16[indx + 1], 16 );
BitBufferWrite( bitstream, inputBuffer[indx + 0] >> 16, 16 );
BitBufferWrite( bitstream, inputBuffer[indx + 1] >> 16, 16 );
}
break;
case 20:
// mix20() with mixres param = 0 means de-interleave so use it to simplify things
mix20( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, 0, 0 );
for ( indx = 0; indx < numSamples; indx++ )
for ( indx = 0; indx < (numSamples * stride); indx += stride )
{
BitBufferWrite( bitstream, p->mMixBufferU[indx], 20 );
BitBufferWrite( bitstream, p->mMixBufferV[indx], 20 );
BitBufferWrite( bitstream, inputBuffer[indx + 0] >> 12, 16 );
BitBufferWrite( bitstream, inputBuffer[indx + 1] >> 12, 16 );
}
break;
case 24:
// mix24() with mixres param = 0 means de-interleave so use it to simplify things
mix24( (uint8_t *) inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, 0, 0, p->mShiftBufferUV, 0 );
mix24( inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, 0, 0, p->mShiftBufferUV, 0 );
for ( indx = 0; indx < numSamples; indx++ )
{
BitBufferWrite( bitstream, p->mMixBufferU[indx], 24 );
BitBufferWrite( bitstream, p->mMixBufferV[indx], 24 );
BitBufferWrite( bitstream, p->mMixBufferU[indx] >> 8, 24 );
BitBufferWrite( bitstream, p->mMixBufferV[indx] >> 8, 24 );
}
break;
case 32:
input32 = (int32_t *) inputBuffer;
for ( indx = 0; indx < (numSamples * stride); indx += stride )
{
BitBufferWrite( bitstream, input32[indx + 0], 32 );
BitBufferWrite( bitstream, input32[indx + 1], 32 );
BitBufferWrite( bitstream, inputBuffer[indx + 0], 32 );
BitBufferWrite( bitstream, inputBuffer[indx + 1], 32 );
}
break;
}
@ -752,34 +746,31 @@ EncodeStereoEscape(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBu
- encode a mono input buffer
*/
static int32_t
EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples )
EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, int32_t * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples )
{
BitBuffer startBits = *bitstream; // squirrel away copy of current state in case we need to go back and do an escape packet
AGParamRec agParams;
uint32_t bits1;
uint32_t numU;
uint32_t bits1;
uint32_t numU;
SearchCoefs coefsU;
uint32_t dilate;
uint32_t minBits, bestU;
uint32_t minU, maxU;
uint32_t indx, indx2;
uint32_t dilate;
uint32_t minBits, bestU;
uint32_t minU, maxU;
uint32_t indx, indx2;
uint8_t bytesShifted;
uint32_t shift;
uint32_t mask;
uint32_t chanBits;
uint32_t shift;
uint32_t mask;
uint32_t chanBits;
uint8_t pbFactor;
uint8_t partialFrame;
int16_t * input16;
int32_t * input32;
uint32_t escapeBits;
uint32_t escapeBits;
bool doEscape;
int32_t status;
int32_t status = ALAC_noErr;
// make sure we handle this bit-depth before we get going
RequireAction( (p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError; );
status = ALAC_noErr;
// reload coefs array from previous frame
coefsU = (SearchCoefs) p->mCoefsU[channelIndex];
@ -803,40 +794,34 @@ EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, ui
switch ( p->mBitDepth )
{
case 16:
{
// convert 16-bit data to 32-bit for predictor
input16 = (int16_t *) inputBuffer;
for ( indx = 0, indx2 = 0; indx < numSamples; indx++, indx2 += stride )
p->mMixBufferU[indx] = (int32_t) input16[indx2];
p->mMixBufferU[indx] = inputBuffer[indx2] >> 16;
break;
}
case 20:
// convert 20-bit data to 32-bit for predictor
copy20ToPredictor( (uint8_t *) inputBuffer, stride, p->mMixBufferU, numSamples );
for ( indx = 0, indx2 = 0; indx < numSamples; indx++, indx2 += stride )
p->mMixBufferU[indx] = inputBuffer[indx2] >> 12;
break;
case 24:
// convert 24-bit data to 32-bit for the predictor and extract the shifted off byte(s)
copy24ToPredictor( (uint8_t *) inputBuffer, stride, p->mMixBufferU, numSamples );
for ( indx = 0; indx < numSamples; indx++ )
for ( indx = 0, indx2 = 0; indx < numSamples; indx++, indx2 += stride )
{
p->mMixBufferU[indx] = inputBuffer[indx2] >> 8;
p->mShiftBufferUV[indx] = (uint16_t)(p->mMixBufferU[indx] & mask);
p->mMixBufferU[indx] >>= shift;
}
break;
case 32:
{
// just copy the 32-bit input data for the predictor and extract the shifted off byte(s)
input32 = (int32_t *) inputBuffer;
for ( indx = 0, indx2 = 0; indx < numSamples; indx++, indx2 += stride )
{
int32_t val = input32[indx2];
p->mShiftBufferUV[indx] = (uint16_t)(val & mask);
p->mMixBufferU[indx] = val >> shift;
p->mShiftBufferUV[indx] = (uint16_t)(inputBuffer[indx2] & mask);
p->mMixBufferU[indx] = inputBuffer[indx2] >> shift;
}
break;
}
}
// brute-force encode optimization loop (implied "encode depth" of 0 if comparing to cmd line tool)
@ -846,13 +831,12 @@ EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, ui
minBits = 1ul << 31;
pbFactor = 4;
minBits = 1ul << 31;
bestU = minU;
for ( numU = minU; numU <= maxU; numU += 4 )
{
BitBuffer workBits;
uint32_t numBits;
uint32_t numBits;
BitBufferInit( &workBits, p->mWorkBuffer, p->mMaxOutputBytes );
@ -941,30 +925,29 @@ EncodeMono(ALAC_ENCODER *p, struct BitBuffer * bitstream, void * inputBuffer, ui
switch ( p->mBitDepth )
{
case 16:
input16 = (int16_t *) inputBuffer;
for ( indx = 0; indx < (numSamples * stride); indx += stride )
BitBufferWrite( bitstream, input16[indx], 16 );
BitBufferWrite( bitstream, inputBuffer[indx] >> 16, 16 );
break;
case 20:
// convert 20-bit data to 32-bit for simplicity
copy20ToPredictor( (uint8_t *) inputBuffer, stride, p->mMixBufferU, numSamples );
for ( indx = 0; indx < numSamples; indx++ )
BitBufferWrite( bitstream, p->mMixBufferU[indx], 20 );
for ( indx = 0; indx < (numSamples * stride); indx += stride )
BitBufferWrite( bitstream, inputBuffer[indx] >> 12, 20 );
break;
case 24:
// convert 24-bit data to 32-bit for simplicity
copy24ToPredictor( (uint8_t *) inputBuffer, stride, p->mMixBufferU, numSamples );
for ( indx = 0; indx < numSamples; indx++ )
for ( indx = 0, indx2 = 0; indx < numSamples; indx++, indx2 += stride )
{
p->mMixBufferU[indx] = inputBuffer[indx2] >> 8;
BitBufferWrite( bitstream, p->mMixBufferU[indx], 24 );
}
break;
case 32:
input32 = (int32_t *) inputBuffer;
for ( indx = 0; indx < (numSamples * stride); indx += stride )
BitBufferWrite( bitstream, input32[indx], 32 );
BitBufferWrite( bitstream, inputBuffer[indx], 32 );
break;
}
#if VERBOSE_DEBUG
DebugMsg( "escape!: %lu vs %lu", minBits, (numSamples * mBitDepth) );
DebugMsg( "escape!: %u vs %u\n", minBits, (numSamples * p->mBitDepth) );
#endif
}
@ -981,16 +964,13 @@ Exit:
- encode the next block of samples
*/
int32_t
alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
unsigned char * theReadBuffer, unsigned char * theWriteBuffer, int32_t * ioNumBytes)
alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t numSamples,
int32_t * theReadBuffer, unsigned char * theWriteBuffer, int32_t * ioNumBytes)
{
uint32_t numFrames;
uint32_t outputSize;
BitBuffer bitstream;
uint32_t outputSize;
BitBuffer bitstream;
int32_t status;
numFrames = *ioNumBytes/bytesPerPacket;
// create a bit buffer structure pointing to our output buffer
BitBufferInit( &bitstream, theWriteBuffer, p->mMaxOutputBytes );
@ -1002,9 +982,9 @@ alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
// encode stereo input buffer
if ( p->mFastMode == false )
status = EncodeStereo(p, &bitstream, theReadBuffer, 2, 0, numFrames );
status = EncodeStereo(p, &bitstream, theReadBuffer, 2, 0, numSamples );
else
status = EncodeStereoFast(p, &bitstream, theReadBuffer, 2, 0, numFrames );
status = EncodeStereoFast(p, &bitstream, theReadBuffer, 2, 0, numSamples );
RequireNoErr( status, goto Exit; );
}
else if ( numChannels == 1 )
@ -1014,20 +994,20 @@ alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
BitBufferWrite( &bitstream, 0, 4 );
// encode mono input buffer
status = EncodeMono(p, &bitstream, theReadBuffer, 1, 0, numFrames );
status = EncodeMono(p, &bitstream, theReadBuffer, 1, 0, numSamples );
RequireNoErr( status, goto Exit; );
}
else
{
char * inputBuffer;
uint32_t tag;
uint32_t channelIndex;
uint32_t inputIncrement;
int32_t * inputBuffer;
uint32_t tag;
uint32_t channelIndex;
uint32_t inputIncrement;
uint8_t stereoElementTag;
uint8_t monoElementTag;
uint8_t lfeElementTag;
inputBuffer = (char *) theReadBuffer;
inputBuffer = theReadBuffer;
inputIncrement = ((p->mBitDepth + 7) / 8);
stereoElementTag = 0;
@ -1045,7 +1025,7 @@ alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
// mono
BitBufferWrite( &bitstream, monoElementTag, 4 );
status = EncodeMono(p, &bitstream, inputBuffer, numChannels, channelIndex, numFrames );
status = EncodeMono(p, &bitstream, inputBuffer, numChannels, channelIndex, numSamples );
inputBuffer += inputIncrement;
channelIndex++;
@ -1056,7 +1036,7 @@ alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
// stereo
BitBufferWrite( &bitstream, stereoElementTag, 4 );
status = EncodeStereo(p,&bitstream, inputBuffer, numChannels, channelIndex, numFrames );
status = EncodeStereo(p,&bitstream, inputBuffer, numChannels, channelIndex, numSamples );
inputBuffer += (inputIncrement * 2);
channelIndex += 2;
@ -1067,7 +1047,7 @@ alac_encode(ALAC_ENCODER *p, uint32_t numChannels, uint32_t bytesPerPacket,
// LFE channel (subwoofer)
BitBufferWrite( &bitstream, lfeElementTag, 4 );
status = EncodeMono(p, &bitstream, inputBuffer, numChannels, channelIndex, numFrames );
status = EncodeMono(p, &bitstream, inputBuffer, numChannels, channelIndex, numSamples );
inputBuffer += inputIncrement;
channelIndex++;
@ -1135,7 +1115,7 @@ GetConfig(ALAC_ENCODER *p, ALACSpecificConfig * config )
{
config->frameLength = Swap32NtoB(p->mFrameSize);
config->compatibleVersion = (uint8_t) kALACCompatibleVersion;
config->bitDepth = (uint8_t) p->mBitDepth;
config->bitDepth = (uint8_t) p->mBitDepth;
config->pb = (uint8_t) PB0;
config->kb = (uint8_t) KB0;
config->mb = (uint8_t) MB0;
@ -1293,7 +1273,7 @@ alac_get_source_format(ALAC_ENCODER *p, const AudioFormatDescription * source, A
static void AddFiller( BitBuffer * bits, int32_t numBytes )
{
uint8_t tag;
uint32_t indx;
int32_t indx;
// out of lameness, subtract 6 bytes to deal with header + alignment as required for fill/data elements
numBytes -= 6;
@ -1321,7 +1301,7 @@ static void AddFiller( BitBuffer * bits, int32_t numBytes )
// - for example, to really mean 15 bytes you must encode extensionSize = 1
// - why it's not like data stream elements I have no idea
extensionSize = (numBytes - 15) + 1;
Assert( extensionSize <= 255 );
//Assert( extensionSize <= 255 );
BitBufferWrite( bits, extensionSize, 8 );
}
else

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
@ -57,10 +58,9 @@
// 16-bit routines
void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres )
void unmix16( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int16_t * op = out;
int32_t j;
int32_t j;
if ( mixres != 0 )
{
@ -72,9 +72,9 @@ void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
op[0] = (int16_t) l;
op[1] = (int16_t) r;
op += stride;
out[0] = l << 16;
out[1] = r << 16;
out += stride;
}
}
else
@ -82,9 +82,9 @@ void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
op[0] = (int16_t) u[j];
op[1] = (int16_t) v[j];
op += stride;
out[0] = u[j] << 16;
out[1] = v[j] << 16;
out += stride;
}
}
}
@ -92,10 +92,9 @@ void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t
// 20-bit routines
// - the 20 bits of data are left-justified in 3 bytes of storage but right-aligned for input/output predictor buffers
void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres )
void unmix20( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
uint8_t * op = out;
int32_t j;
int32_t j;
if ( mixres != 0 )
{
@ -107,19 +106,9 @@ void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
l <<= 4;
r <<= 4;
op[HBYTE] = (uint8_t)((l >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((l >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((l >> 0) & 0xffu);
op += 3;
op[HBYTE] = (uint8_t)((r >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((r >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((r >> 0) & 0xffu);
op += (stride - 1) * 3;
out[0] = l << 12;
out[1] = r << 12;
out += stride;
}
}
else
@ -127,20 +116,9 @@ void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
int32_t val;
val = u[j] << 4;
op[HBYTE] = (uint8_t)((val >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((val >> 0) & 0xffu);
op += 3;
val = v[j] << 4;
op[HBYTE] = (uint8_t)((val >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((val >> 0) & 0xffu);
op += (stride - 1) * 3;
out[0] = u[j] << 12;
out[1] = v[j] << 12;
out += stride;
}
}
}
@ -148,11 +126,10 @@ void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
// 24-bit routines
// - the 24 bits of data are right-justified in the input/output predictor buffers
void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples,
void unmix24( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
uint8_t * op = out;
int32_t shift = bytesShifted * 8;
int32_t shift = bytesShifted * 8;
int32_t l, r;
int32_t j, k;
@ -169,16 +146,9 @@ void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
l = (l << shift) | (uint32_t) shiftUV[k + 0];
r = (r << shift) | (uint32_t) shiftUV[k + 1];
op[HBYTE] = (uint8_t)((l >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((l >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((l >> 0) & 0xffu);
op += 3;
op[HBYTE] = (uint8_t)((r >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((r >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((r >> 0) & 0xffu);
op += (stride - 1) * 3;
out[0] = l << 8;
out[1] = r << 8;
out += stride;
}
}
else
@ -188,16 +158,9 @@ void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
op[HBYTE] = (uint8_t)((l >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((l >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((l >> 0) & 0xffu);
op += 3;
op[HBYTE] = (uint8_t)((r >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((r >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((r >> 0) & 0xffu);
op += (stride - 1) * 3;
out[0] = l << 8;
out[1] = r << 8;
out += stride;
}
}
}
@ -214,36 +177,18 @@ void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
l = (l << shift) | (uint32_t) shiftUV[k + 0];
r = (r << shift) | (uint32_t) shiftUV[k + 1];
op[HBYTE] = (uint8_t)((l >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((l >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((l >> 0) & 0xffu);
op += 3;
op[HBYTE] = (uint8_t)((r >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((r >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((r >> 0) & 0xffu);
op += (stride - 1) * 3;
out[0] = l << 8;
out[1] = r << 8;
out += stride;
}
}
else
{
for ( j = 0; j < numSamples; j++ )
{
int32_t val;
val = u[j];
op[HBYTE] = (uint8_t)((val >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((val >> 0) & 0xffu);
op += 3;
val = v[j];
op[HBYTE] = (uint8_t)((val >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((val >> 0) & 0xffu);
op += (stride - 1) * 3;
out[0] = u[j] << 8;
out[1] = v[j] << 8;
out += stride;
}
}
}
@ -257,10 +202,9 @@ void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t
void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t * op = out;
int32_t shift = bytesShifted * 8;
int32_t shift = bytesShifted * 8;
int32_t l, r;
int32_t j, k;
int32_t j, k;
if ( mixres != 0 )
{
@ -277,9 +221,9 @@ void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t
l = lt + rt - ((mixres * rt) >> mixbits);
r = l - rt;
op[0] = (l << shift) | (uint32_t) shiftUV[k + 0];
op[1] = (r << shift) | (uint32_t) shiftUV[k + 1];
op += stride;
out[0] = (l << shift) | (uint32_t) shiftUV[k + 0];
out[1] = (r << shift) | (uint32_t) shiftUV[k + 1];
out += stride;
}
}
else
@ -289,9 +233,9 @@ void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t
/* interleaving w/o shift */
for ( j = 0; j < numSamples; j++ )
{
op[0] = u[j];
op[1] = v[j];
op += stride;
out[0] = u[j];
out[1] = v[j];
out += stride;
}
}
else
@ -299,9 +243,9 @@ void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t
/* interleaving with shift */
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
op[0] = (u[j] << shift) | (uint32_t) shiftUV[k + 0];
op[1] = (v[j] << shift) | (uint32_t) shiftUV[k + 1];
op += stride;
out[0] = (u[j] << shift) | (uint32_t) shiftUV[k + 0];
out[1] = (v[j] << shift) | (uint32_t) shiftUV[k + 1];
out += stride;
}
}
}
@ -309,27 +253,21 @@ void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t
// 20/24-bit <-> 32-bit helper routines (not really matrixing but convenient to put here)
void copyPredictorTo24( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples )
void copyPredictorTo24( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples )
{
uint8_t * op = out;
int32_t j;
int32_t j;
for ( j = 0; j < numSamples; j++ )
{
int32_t val = in[j];
op[HBYTE] = (uint8_t)((val >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((val >> 0) & 0xffu);
op += (stride * 3);
out[0] = in[j] << 8;
out += stride;
}
}
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted )
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted )
{
uint8_t * op = out;
int32_t shiftVal = bytesShifted * 8;
int32_t j;
int32_t shiftVal = bytesShifted * 8;
int32_t j;
//Assert( bytesShifted != 0 );
@ -338,29 +276,21 @@ void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, uint8_t * out, uint
int32_t val = in[j];
val = (val << shiftVal) | (uint32_t) shift[j];
op[HBYTE] = (uint8_t)((val >> 16) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 8) & 0xffu);
op[LBYTE] = (uint8_t)((val >> 0) & 0xffu);
op += (stride * 3);
out[0] = val << 8;
out += stride;
}
}
void copyPredictorTo20( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples )
void copyPredictorTo20( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples )
{
uint8_t * op = out;
int32_t j;
int32_t j;
// 32-bit predictor values are right-aligned but 20-bit output values should be left-aligned
// in the 24-bit output buffer
for ( j = 0; j < numSamples; j++ )
{
int32_t val = in[j];
op[HBYTE] = (uint8_t)((val >> 12) & 0xffu);
op[MBYTE] = (uint8_t)((val >> 4) & 0xffu);
op[LBYTE] = (uint8_t)((val << 4) & 0xffu);
op += (stride * 3);
out[0] = in[j] << 12;
out += stride;
}
}
@ -370,14 +300,14 @@ void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t nu
// this is only a subroutine to abstract the "iPod can only output 16-bit data" problem
for ( i = 0, j = 0; i < numSamples; i++, j += stride )
out[j] = in[i];
out[j] = in[i] << 8;
}
void copyPredictorTo32Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted )
{
int32_t * op = out;
uint32_t shiftVal = bytesShifted * 8;
int32_t j;
int32_t j;
//Assert( bytesShifted != 0 );

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
@ -29,17 +30,6 @@
#include "matrixlib.h"
#include "ALACAudioTypes.h"
// up to 24-bit "offset" macros for the individual bytes of a 20/24-bit word
#if TARGET_RT_BIG_ENDIAN
#define LBYTE 2
#define MBYTE 1
#define HBYTE 0
#else
#define LBYTE 0
#define MBYTE 1
#define HBYTE 2
#endif
/*
There is no plain middle-side option; instead there are various mixing
modes including middle-side, each lossless, as embodied in the mix()
@ -57,10 +47,9 @@
// 16-bit routines
void mix16( int16_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres )
void mix16( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int16_t * ip = in;
int32_t j;
int32_t j;
if ( mixres != 0 )
{
@ -73,9 +62,9 @@ void mix16( int16_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
{
int32_t l, r;
l = (int32_t) ip[0];
r = (int32_t) ip[1];
ip += stride;
l = in[0] >> 16;
r = in[1] >> 16;
in += stride;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
@ -85,9 +74,9 @@ void mix16( int16_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
u[j] = (int32_t) ip[0];
v[j] = (int32_t) ip[1];
ip += stride;
u[j] = in[0] >> 16;
v[j] = in[1] >> 16;
in += stride;
}
}
}
@ -95,11 +84,10 @@ void mix16( int16_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
// 20-bit routines
// - the 20 bits of data are left-justified in 3 bytes of storage but right-aligned for input/output predictor buffers
void mix20( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres )
void mix20( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int32_t l, r;
uint8_t * ip = in;
int32_t j;
int32_t j;
if ( mixres != 0 )
{
@ -109,13 +97,9 @@ void mix20( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
for ( j = 0; j < numSamples; j++ )
{
l = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
l = (l << 8) >> 12;
ip += 3;
r = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
r = (r << 8) >> 12;
ip += (stride - 1) * 3;
l = in[0] >> 12;
r = in[1] >> 12;
in += stride;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
@ -126,13 +110,9 @@ void mix20( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
l = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
u[j] = (l << 8) >> 12;
ip += 3;
r = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
v[j] = (r << 8) >> 12;
ip += (stride - 1) * 3;
u[j] = in[0] >> 12;
v[j] = in[1] >> 12;
in += stride;
}
}
}
@ -140,14 +120,13 @@ void mix20( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
// 24-bit routines
// - the 24 bits of data are right-justified in the input/output predictor buffers
void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
void mix24( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t l, r;
uint8_t * ip = in;
int32_t shift = bytesShifted * 8;
int32_t shift = bytesShifted * 8;
uint32_t mask = (1ul << shift) - 1;
int32_t j, k;
int32_t j, k;
if ( mixres != 0 )
{
@ -159,13 +138,9 @@ void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
{
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
l = (l << 8) >> 8;
ip += 3;
r = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
r = (r << 8) >> 8;
ip += (stride - 1) * 3;
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
@ -181,13 +156,9 @@ void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
{
for ( j = 0; j < numSamples; j++ )
{
l = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
l = (l << 8) >> 8;
ip += 3;
r = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
r = (r << 8) >> 8;
ip += (stride - 1) * 3;
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
@ -201,13 +172,9 @@ void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
{
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
l = (l << 8) >> 8;
ip += 3;
r = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
r = (r << 8) >> 8;
ip += (stride - 1) * 3;
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
@ -223,13 +190,9 @@ void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
{
for ( j = 0; j < numSamples; j++ )
{
l = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
u[j] = (l << 8) >> 8;
ip += 3;
r = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
v[j] = (r << 8) >> 8;
ip += (stride - 1) * 3;
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
}
}
}
@ -243,11 +206,10 @@ void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t * ip = in;
int32_t shift = bytesShifted * 8;
int32_t shift = bytesShifted * 8;
uint32_t mask = (1ul << shift) - 1;
int32_t l, r;
int32_t j, k;
int32_t j, k;
if ( mixres != 0 )
{
@ -260,9 +222,9 @@ void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
m2 = mod - mixres;
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = ip[0];
r = ip[1];
ip += stride;
l = in[0];
r = in[1];
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
@ -281,9 +243,9 @@ void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
/* de-interleaving w/o shift */
for ( j = 0; j < numSamples; j++ )
{
u[j] = ip[0];
v[j] = ip[1];
ip += stride;
u[j] = in[0];
v[j] = in[1];
in += stride;
}
}
else
@ -291,9 +253,9 @@ void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
/* de-interleaving with shift */
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = ip[0];
r = ip[1];
ip += stride;
l = in[0];
r = in[1];
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
@ -308,35 +270,3 @@ void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t num
}
}
// 20/24-bit <-> 32-bit helper routines (not really matrixing but convenient to put here)
void copy20ToPredictor( uint8_t * in, uint32_t stride, int32_t * out, int32_t numSamples )
{
uint8_t * ip = in;
int32_t j;
for ( j = 0; j < numSamples; j++ )
{
int32_t val;
// 20-bit values are left-aligned in the 24-bit input buffer but right-aligned in the 32-bit output buffer
val = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
out[j] = (val << 8) >> 12;
ip += stride * 3;
}
}
void copy24ToPredictor( uint8_t * in, uint32_t stride, int32_t * out, int32_t numSamples )
{
uint8_t * ip = in;
int32_t j;
for ( j = 0; j < numSamples; j++ )
{
int32_t val;
val = (int32_t)( ((uint32_t)ip[HBYTE] << 16) | ((uint32_t)ip[MBYTE] << 8) | (uint32_t)ip[LBYTE] );
out[j] = (val << 8) >> 8;
ip += stride * 3;
}
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
@ -38,19 +39,19 @@ extern "C" {
#endif
// 16-bit routines
void mix16( int16_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres );
void unmix16( int32_t * u, int32_t * v, int16_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres );
void mix16( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres );
void unmix16( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres );
// 20-bit routines
void mix20( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres );
void unmix20( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres );
void mix20( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres );
void unmix20( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres );
// 24-bit routines
// - 24-bit data sometimes compresses better by shifting off the bottom byte so these routines deal with
// the specified "unused lower bytes" in the combined "shift" buffer
void mix24( uint8_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
void mix24( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
void unmix24( int32_t * u, int32_t * v, uint8_t * out, uint32_t stride, int32_t numSamples,
void unmix24( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
// 32-bit routines
@ -63,12 +64,12 @@ void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
// 20/24/32-bit <-> 32-bit helper routines (not really matrixing but convenient to put here)
void copy20ToPredictor( uint8_t * in, uint32_t stride, int32_t * out, int32_t numSamples );
void copy24ToPredictor( uint8_t * in, uint32_t stride, int32_t * out, int32_t numSamples );
void copy20ToPredictor( int32_t * in, uint32_t stride, int32_t * out, int32_t numSamples );
void copy24ToPredictor( int32_t * in, uint32_t stride, int32_t * out, int32_t numSamples );
void copyPredictorTo24( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted );
void copyPredictorTo20( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo24( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted );
void copyPredictorTo20( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo32Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted );

View File

@ -29,7 +29,7 @@
#include "ALAC/alac_codec.h"
#include "ALAC/ALACBitUtilities.h"
#define ALAC_MAX_FRAME_SIZE 16400
#define ALAC_MAX_FRAME_SIZE 32800
#define ALAC_PACKET_MARKER 0xa1acc0d3
@ -49,7 +49,7 @@ typedef struct ALAC_PRIVATE_tag
int channels, final_write_block ;
uint32_t frames_this_block, partial_block_frames, frames_per_block, kuki_size ;
uint32_t bits_per_sample, bytes_per_packet, decode_bytes_per_frame_is_this_needed ;
uint32_t bits_per_sample, decode_bytes_per_frame_is_this_needed ;
/* Can't have a decoder and an encoder at the same time so stick
@ -63,11 +63,8 @@ typedef struct ALAC_PRIVATE_tag
char enctmpname [256] ;
FILE *enctmp ;
union
{ uint8_t ucbuf [ALAC_MAX_FRAME_SIZE] ;
short sbuf [ALAC_MAX_FRAME_SIZE / 2] ;
int ibuf [ALAC_MAX_FRAME_SIZE / 4] ;
} ;
int buffer [ALAC_MAX_FRAME_SIZE / 4] ;
} ALAC_PRIVATE ;
/*============================================================================================
@ -78,25 +75,15 @@ static int alac_writer_init (SF_PRIVATE *psf) ;
static sf_count_t alac_reader_calc_frames (SF_PRIVATE *psf, ALAC_PRIVATE *plac) ;
static sf_count_t alac_read16_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t alac_read16_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t alac_read16_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t alac_read16_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t alac_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t alac_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t alac_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t alac_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t alac_read32_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t alac_read32_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t alac_read32_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t alac_read32_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t alac_write16_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t alac_write16_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t alac_write16_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t alac_write16_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t alac_write32_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t alac_write32_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t alac_write32_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t alac_write32_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t alac_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t alac_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t alac_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t alac_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t alac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
@ -269,17 +256,13 @@ alac_reader_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info)
switch (info->bits_per_sample)
{ case 16 :
psf->read_short = alac_read16_s ;
psf->read_int = alac_read16_i ;
psf->read_float = alac_read16_f ;
psf->read_double = alac_read16_d ;
break ;
case 20 :
case 24 :
case 32 :
psf->read_short = alac_read32_s ;
psf->read_int = alac_read32_i ;
psf->read_float = alac_read32_f ;
psf->read_double = alac_read32_d ;
psf->read_short = alac_read_s ;
psf->read_int = alac_read_i ;
psf->read_float = alac_read_f ;
psf->read_double = alac_read_d ;
break ;
default :
@ -313,43 +296,34 @@ alac_writer_init (SF_PRIVATE *psf)
plac->channels = psf->sf.channels ;
plac->kuki_size = alac_get_magic_cookie_size (psf->sf.channels) ;
psf->write_short = alac_write_s ;
psf->write_int = alac_write_i ;
psf->write_float = alac_write_f ;
psf->write_double = alac_write_d ;
switch (SF_CODEC (psf->sf.format))
{ case SF_FORMAT_ALAC_16 :
psf->write_short = alac_write16_s ;
psf->write_int = alac_write16_i ;
psf->write_float = alac_write16_f ;
psf->write_double = alac_write16_d ;
alac_format_flags = 1 ;
plac->bits_per_sample = 16 ;
plac->bytes_per_packet = plac->channels * (plac->bits_per_sample >> 3) ;
break ;
case SF_FORMAT_ALAC_20 :
alac_format_flags = 2 ;
plac->bits_per_sample = 20 ;
plac->bytes_per_packet = lrint (plac->channels * 2.5 + 0.5) ;
break ;
case SF_FORMAT_ALAC_24 :
alac_format_flags = 3 ;
plac->bits_per_sample = 24 ;
plac->bytes_per_packet = plac->channels * (plac->bits_per_sample >> 3) ;
break ;
case SF_FORMAT_ALAC_32 :
psf->write_short = alac_write32_s ;
psf->write_int = alac_write32_i ;
psf->write_float = alac_write32_f ;
psf->write_double = alac_write32_d ;
alac_format_flags = 4 ;
plac->bits_per_sample = 32 ;
plac->bytes_per_packet = plac->channels * (plac->bits_per_sample >> 3) ;
break ;
default :
psf_log_printf (psf, "%20s : Can;t figure out bits per sample.\n", __func__) ;
psf_log_printf (psf, "%s : Can;t figure out bits per sample.\n", __func__) ;
return SFE_UNIMPLEMENTED ;
} ;
@ -436,7 +410,7 @@ alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
if ((packet_size != psf_fread (byte_buffer, 1, packet_size, psf)))
return 0 ;
alac_decode (pdec, &bit_buffer, plac->ucbuf, plac->frames_per_block, psf->sf.channels, &plac->frames_this_block) ;
alac_decode (pdec, &bit_buffer, plac->buffer, plac->frames_per_block, psf->sf.channels, &plac->frames_this_block) ;
BitBufferReset (&bit_buffer) ;
@ -450,11 +424,11 @@ static int
alac_encode_block (SF_PRIVATE * UNUSED (psf), ALAC_PRIVATE *plac)
{ ALAC_ENCODER *penc = &plac->encoder ;
uint8_t byte_buffer [ALAC_MAX_FRAME_SIZE] ;
int32_t num_bytes ;
int32_t num_bytes = 0 ;
num_bytes = plac->partial_block_frames * plac->channels * (plac->bits_per_sample >> 3) ;
alac_encode (penc, plac->channels, plac->bytes_per_packet, plac->ucbuf, byte_buffer, &num_bytes) ;
// printf ("%s : raw_bytes %d -> ", __func__, plac->partial_block_frames * plac->bits_per_sample / 8) ;
alac_encode (penc, plac->channels, plac->partial_block_frames, plac->buffer, byte_buffer, &num_bytes) ;
// printf ("encoded_bytes %d\n", num_bytes) ;
fwrite (byte_buffer, 1, num_bytes, plac->enctmp) ;
alac_pakt_append (plac->pakt_info, num_bytes) ;
@ -471,134 +445,7 @@ alac_encode_block (SF_PRIVATE * UNUSED (psf), ALAC_PRIVATE *plac)
*/
static sf_count_t
alac_read16_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
short *sptr ;
int k, readcount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = sptr [k] ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read16_s */
static sf_count_t
alac_read16_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
short *sptr ;
int k, readcount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = sptr [k] << 16 ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read16_i */
static sf_count_t
alac_read16_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
short *sptr ;
int k, readcount ;
sf_count_t total = 0 ;
float normfact ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * sptr [k] ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read16_f */
static sf_count_t
alac_read16_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
short *sptr ;
int k, readcount ;
sf_count_t total = 0 ;
double normfact ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * sptr [k] ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read16_d */
static sf_count_t
alac_read32_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
alac_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
@ -614,7 +461,7 @@ alac_read32_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = iptr [k] >> 16 ;
@ -625,10 +472,10 @@ alac_read32_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
} ;
return total ;
} /* alac_read32_s */
} /* alac_read_s */
static sf_count_t
alac_read32_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
alac_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
@ -644,7 +491,7 @@ alac_read32_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = iptr [k] ;
@ -655,10 +502,10 @@ alac_read32_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
} ;
return total ;
} /* alac_read32_i */
} /* alac_read_i */
static sf_count_t
alac_read32_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
alac_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
@ -677,7 +524,7 @@ alac_read32_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * iptr [k] ;
@ -688,10 +535,10 @@ alac_read32_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
} ;
return total ;
} /* alac_read32_f */
} /* alac_read_f */
static sf_count_t
alac_read32_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
alac_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
@ -710,7 +557,7 @@ alac_read32_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * iptr [k] ;
@ -721,7 +568,7 @@ alac_read32_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
} ;
return total ;
} /* alac_read32_d */
} /* alac_read_d */
/*============================================================================================
*/
@ -778,132 +625,7 @@ alac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
*/
static sf_count_t
alac_write16_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
short *sptr ;
int k, writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = ptr [total + k] ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write16_s */
static sf_count_t
alac_write16_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
short *sptr ;
int k, writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = psf_short_of_int (ptr [total + k]) ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write16_i */
static sf_count_t
alac_write16_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
void (*convert) (const float *, short *t, int, int) ;
short *sptr ;
int writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
convert = (psf->add_clipping) ? psf_f2s_clip_array : psf_f2s_array ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
convert (ptr, sptr, writecount, psf->norm_float) ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write16_f */
static sf_count_t
alac_write16_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
void (*convert) (const double *, short *t, int, int) ;
short *sptr ;
int writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
convert = (psf->add_clipping) ? psf_d2s_clip_array : psf_d2s_array ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
sptr = plac->sbuf + plac->partial_block_frames * plac->channels ;
convert (ptr, sptr, writecount, psf->norm_float) ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write16_d */
static sf_count_t
alac_write32_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
alac_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, writecount ;
@ -916,7 +638,7 @@ alac_write32_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = ptr [total + k] << 16 ;
@ -930,10 +652,10 @@ alac_write32_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
} ;
return total ;
} /* alac_write32_s */
} /* alac_write_s */
static sf_count_t
alac_write32_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
alac_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, writecount ;
@ -946,7 +668,7 @@ alac_write32_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = ptr [total + k] ;
@ -960,10 +682,10 @@ alac_write32_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
} ;
return total ;
} /* alac_write32_i */
} /* alac_write_i */
static sf_count_t
alac_write32_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
alac_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
void (*convert) (const float *, int *t, int, int) ;
int *iptr ;
@ -979,7 +701,7 @@ alac_write32_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
convert (ptr, iptr, writecount, psf->norm_float) ;
@ -992,10 +714,10 @@ alac_write32_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
} ;
return total ;
} /* alac_write32_f */
} /* alac_write_f */
static sf_count_t
alac_write32_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
alac_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
void (*convert) (const double *, int *t, int, int) ;
int *iptr ;
@ -1011,7 +733,7 @@ alac_write32_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->ibuf + plac->partial_block_frames * plac->channels ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
convert (ptr, iptr, writecount, psf->norm_float) ;
@ -1024,7 +746,7 @@ alac_write32_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
} ;
return total ;
} /* alac_write32_d */
} /* alac_write_d */
/*==============================================================================
** PAKT_INFO handling.