mirror of
https://gitee.com/openharmony/third_party_libsnd
synced 2025-02-17 01:20:02 +00:00
src/ALAC/* : Big code dump of code for Apple's ALAC file format.
This commit is contained in:
parent
cf5a13e84a
commit
297cb9c3bd
@ -1,3 +1,12 @@
|
||||
2012-02-03 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
|
||||
* src/ALAC/*
|
||||
Big code dump of code for Apple's ALAC file format. This copyyright to this
|
||||
code is owned by Apple who have released it under an Apache style license.
|
||||
A few modifications were made to allow this to be integrated into libsndfile
|
||||
but unfortunately the history of those changes were lost because they were
|
||||
developed in a Bzr tree and during that time libsndfile moved to Git.
|
||||
|
||||
2012-02-02 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
|
||||
* src/aiff.c src/wav.c
|
||||
|
3
README
3
README
@ -20,6 +20,9 @@ Bormann. Their original code can be found at :
|
||||
The src/G72x directory contains code written and released by Sun Microsystems
|
||||
under a suitably free license.
|
||||
|
||||
The src/ALAC directory contains code written and released by Apple Inc and
|
||||
released under the Apache license.
|
||||
|
||||
|
||||
LINUX
|
||||
-----
|
||||
|
200
src/ALAC/ALACAudioTypes.h
Normal file
200
src/ALAC/ALACAudioTypes.h
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: ALACAudioTypes.h
|
||||
*/
|
||||
|
||||
#ifndef ALACAUDIOTYPES_H
|
||||
#define ALACAUDIOTYPES_H
|
||||
|
||||
/* Force these Mac OS specific things to zero. */
|
||||
#define PRAGMA_STRUCT_ALIGN 0
|
||||
#define PRAGMA_STRUCT_PACKPUSH 0
|
||||
#define PRAGMA_STRUCT_PACK 0
|
||||
#define PRAGMA_ONCE 0
|
||||
#define PRAGMA_MARK 0
|
||||
|
||||
|
||||
#if PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sfendian.h"
|
||||
|
||||
#if CPU_IS_BIG_ENDIAN == 1
|
||||
#define TARGET_RT_BIG_ENDIAN 1
|
||||
#else
|
||||
#define TARGET_RT_BIG_ENDIAN 0
|
||||
#endif
|
||||
|
||||
#define kChannelAtomSize 12
|
||||
|
||||
enum
|
||||
{
|
||||
kALAC_UnimplementedError = -4,
|
||||
kALAC_FileNotFoundError = -43,
|
||||
kALAC_ParamError = -50,
|
||||
kALAC_MemFullError = -108,
|
||||
fALAC_FrameLengthError = -666,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kALACFormatAppleLossless = MAKE_MARKER ('a', 'l', 'a', 'c'),
|
||||
kALACFormatLinearPCM = MAKE_MARKER ('l', 'p', 'c', 'm')
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kALACMaxChannels = 8,
|
||||
kALACMaxEscapeHeaderBytes = 8,
|
||||
kALACMaxSearches = 16,
|
||||
kALACMaxCoefs = 16,
|
||||
kALACDefaultFramesPerPacket = 4096
|
||||
};
|
||||
|
||||
typedef uint32_t ALACChannelLayoutTag;
|
||||
|
||||
enum
|
||||
{
|
||||
kALACFormatFlagIsFloat = (1 << 0), // 0x1
|
||||
kALACFormatFlagIsBigEndian = (1 << 1), // 0x2
|
||||
kALACFormatFlagIsSignedInteger = (1 << 2), // 0x4
|
||||
kALACFormatFlagIsPacked = (1 << 3), // 0x8
|
||||
kALACFormatFlagIsAlignedHigh = (1 << 4), // 0x10
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
#if TARGET_RT_BIG_ENDIAN
|
||||
kALACFormatFlagsNativeEndian = kALACFormatFlagIsBigEndian
|
||||
#else
|
||||
kALACFormatFlagsNativeEndian = 0
|
||||
#endif
|
||||
};
|
||||
|
||||
// this is required to be an IEEE 64bit float
|
||||
typedef double alac_float64_t;
|
||||
|
||||
// These are the Channel Layout Tags used in the Channel Layout Info portion of the ALAC magic cookie
|
||||
enum
|
||||
{
|
||||
kALACChannelLayoutTag_Mono = (100<<16) | 1, // C
|
||||
kALACChannelLayoutTag_Stereo = (101<<16) | 2, // L R
|
||||
kALACChannelLayoutTag_MPEG_3_0_B = (113<<16) | 3, // C L R
|
||||
kALACChannelLayoutTag_MPEG_4_0_B = (116<<16) | 4, // C L R Cs
|
||||
kALACChannelLayoutTag_MPEG_5_0_D = (120<<16) | 5, // C L R Ls Rs
|
||||
kALACChannelLayoutTag_MPEG_5_1_D = (124<<16) | 6, // C L R Ls Rs LFE
|
||||
kALACChannelLayoutTag_AAC_6_1 = (142<<16) | 7, // C L R Ls Rs Cs LFE
|
||||
kALACChannelLayoutTag_MPEG_7_1_B = (127<<16) | 8 // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC)
|
||||
};
|
||||
|
||||
// ALAC currently only utilizes these channels layouts. There is a one for one correspondance between a
|
||||
// given number of channels and one of these layout tags
|
||||
static const ALACChannelLayoutTag ALACChannelLayoutTags[kALACMaxChannels] =
|
||||
{
|
||||
kALACChannelLayoutTag_Mono, // C
|
||||
kALACChannelLayoutTag_Stereo, // L R
|
||||
kALACChannelLayoutTag_MPEG_3_0_B, // C L R
|
||||
kALACChannelLayoutTag_MPEG_4_0_B, // C L R Cs
|
||||
kALACChannelLayoutTag_MPEG_5_0_D, // C L R Ls Rs
|
||||
kALACChannelLayoutTag_MPEG_5_1_D, // C L R Ls Rs LFE
|
||||
kALACChannelLayoutTag_AAC_6_1, // C L R Ls Rs Cs LFE
|
||||
kALACChannelLayoutTag_MPEG_7_1_B // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC)
|
||||
};
|
||||
|
||||
// AudioChannelLayout from CoreAudioTypes.h. We never need the AudioChannelDescription so we remove it
|
||||
struct ALACAudioChannelLayout
|
||||
{
|
||||
ALACChannelLayoutTag mChannelLayoutTag;
|
||||
uint32_t mChannelBitmap;
|
||||
uint32_t mNumberChannelDescriptions;
|
||||
};
|
||||
typedef struct ALACAudioChannelLayout ALACAudioChannelLayout;
|
||||
|
||||
struct AudioFormatDescription
|
||||
{
|
||||
alac_float64_t mSampleRate;
|
||||
uint32_t mFormatID;
|
||||
uint32_t mFormatFlags;
|
||||
uint32_t mBytesPerPacket;
|
||||
uint32_t mFramesPerPacket;
|
||||
uint32_t mBytesPerFrame;
|
||||
uint32_t mChannelsPerFrame;
|
||||
uint32_t mBitsPerChannel;
|
||||
uint32_t mReserved;
|
||||
};
|
||||
typedef struct AudioFormatDescription AudioFormatDescription;
|
||||
|
||||
/* Lossless Definitions */
|
||||
|
||||
enum
|
||||
{
|
||||
kALACCodecFormat = MAKE_MARKER ('a', 'l', 'a', 'c'),
|
||||
kALACVersion = 0,
|
||||
kALACCompatibleVersion = kALACVersion,
|
||||
kALACDefaultFrameSize = 4096
|
||||
};
|
||||
|
||||
// note: this struct is wrapped in an 'alac' atom in the sample description extension area
|
||||
// note: in QT movies, it will be further wrapped in a 'wave' atom surrounded by 'frma' and 'term' atoms
|
||||
typedef struct ALACSpecificConfig
|
||||
{
|
||||
uint32_t frameLength;
|
||||
uint8_t compatibleVersion;
|
||||
uint8_t bitDepth; // max 32
|
||||
uint8_t pb; // 0 <= pb <= 255
|
||||
uint8_t mb;
|
||||
uint8_t kb;
|
||||
uint8_t numChannels;
|
||||
uint16_t maxRun;
|
||||
uint32_t maxFrameBytes;
|
||||
uint32_t avgBitRate;
|
||||
uint32_t sampleRate;
|
||||
|
||||
} ALACSpecificConfig;
|
||||
|
||||
|
||||
// The AudioChannelLayout atom type is not exposed yet so define it here
|
||||
enum
|
||||
{
|
||||
AudioChannelLayoutAID = MAKE_MARKER ('c', 'h', 'a', 'n')
|
||||
};
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(pop)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ALACAUDIOTYPES_H */
|
262
src/ALAC/ALACBitUtilities.c
Normal file
262
src/ALAC/ALACBitUtilities.c
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
File: ALACBitUtilities.c
|
||||
|
||||
$NoKeywords: $
|
||||
=============================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ALACBitUtilities.h"
|
||||
|
||||
#define PRAGMA_MARK 0
|
||||
|
||||
// BitBufferInit
|
||||
//
|
||||
void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize )
|
||||
{
|
||||
bits->cur = buffer;
|
||||
bits->end = bits->cur + byteSize;
|
||||
bits->bitIndex = 0;
|
||||
bits->byteSize = byteSize;
|
||||
}
|
||||
|
||||
// BitBufferRead
|
||||
//
|
||||
uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits )
|
||||
{
|
||||
uint32_t returnBits;
|
||||
|
||||
//Assert( numBits <= 16 );
|
||||
|
||||
returnBits = ((uint32_t)bits->cur[0] << 16) | ((uint32_t)bits->cur[1] << 8) | ((uint32_t)bits->cur[2]);
|
||||
returnBits = returnBits << bits->bitIndex;
|
||||
returnBits &= 0x00FFFFFF;
|
||||
|
||||
bits->bitIndex += numBits;
|
||||
|
||||
returnBits = returnBits >> (24 - numBits);
|
||||
|
||||
bits->cur += (bits->bitIndex >> 3);
|
||||
bits->bitIndex &= 7;
|
||||
|
||||
//Assert( bits->cur <= bits->end );
|
||||
|
||||
return returnBits;
|
||||
}
|
||||
|
||||
// BitBufferReadSmall
|
||||
//
|
||||
// Reads up to 8 bits
|
||||
uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits )
|
||||
{
|
||||
uint16_t returnBits;
|
||||
|
||||
//Assert( numBits <= 8 );
|
||||
|
||||
returnBits = (bits->cur[0] << 8) | bits->cur[1];
|
||||
returnBits = returnBits << bits->bitIndex;
|
||||
|
||||
bits->bitIndex += numBits;
|
||||
|
||||
returnBits = returnBits >> (16 - numBits);
|
||||
|
||||
bits->cur += (bits->bitIndex >> 3);
|
||||
bits->bitIndex &= 7;
|
||||
|
||||
//Assert( bits->cur <= bits->end );
|
||||
|
||||
return (uint8_t)returnBits;
|
||||
}
|
||||
|
||||
// BitBufferReadOne
|
||||
//
|
||||
// Reads one byte
|
||||
uint8_t BitBufferReadOne( BitBuffer * bits )
|
||||
{
|
||||
uint8_t returnBits;
|
||||
|
||||
returnBits = (bits->cur[0] >> (7 - bits->bitIndex)) & 1;
|
||||
|
||||
bits->bitIndex++;
|
||||
|
||||
bits->cur += (bits->bitIndex >> 3);
|
||||
bits->bitIndex &= 7;
|
||||
|
||||
//Assert( bits->cur <= bits->end );
|
||||
|
||||
return returnBits;
|
||||
}
|
||||
|
||||
// BitBufferPeek
|
||||
//
|
||||
uint32_t BitBufferPeek( BitBuffer * bits, uint8_t numBits )
|
||||
{
|
||||
return ((((((uint32_t) bits->cur[0] << 16) | ((uint32_t) bits->cur[1] << 8) |
|
||||
((uint32_t) bits->cur[2])) << bits->bitIndex) & 0x00FFFFFF) >> (24 - numBits));
|
||||
}
|
||||
|
||||
// BitBufferPeekOne
|
||||
//
|
||||
uint32_t BitBufferPeekOne( BitBuffer * bits )
|
||||
{
|
||||
return ((bits->cur[0] >> (7 - bits->bitIndex)) & 1);
|
||||
}
|
||||
|
||||
// BitBufferUnpackBERSize
|
||||
//
|
||||
uint32_t BitBufferUnpackBERSize( BitBuffer * bits )
|
||||
{
|
||||
uint32_t size;
|
||||
uint8_t tmp;
|
||||
|
||||
for ( size = 0, tmp = 0x80u; tmp &= 0x80u; size = (size << 7u) | (tmp & 0x7fu) )
|
||||
tmp = (uint8_t) BitBufferReadSmall( bits, 8 );
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// BitBufferGetPosition
|
||||
//
|
||||
uint32_t BitBufferGetPosition( BitBuffer * bits )
|
||||
{
|
||||
uint8_t * begin;
|
||||
|
||||
begin = bits->end - bits->byteSize;
|
||||
|
||||
return ((uint32_t)(bits->cur - begin) * 8) + bits->bitIndex;
|
||||
}
|
||||
|
||||
// BitBufferByteAlign
|
||||
//
|
||||
void BitBufferByteAlign( BitBuffer * bits, int32_t addZeros )
|
||||
{
|
||||
// align bit buffer to next byte boundary, writing zeros if requested
|
||||
if ( bits->bitIndex == 0 )
|
||||
return;
|
||||
|
||||
if ( addZeros )
|
||||
BitBufferWrite( bits, 0, 8 - bits->bitIndex );
|
||||
else
|
||||
BitBufferAdvance( bits, 8 - bits->bitIndex );
|
||||
}
|
||||
|
||||
// BitBufferAdvance
|
||||
//
|
||||
void BitBufferAdvance( BitBuffer * bits, uint32_t numBits )
|
||||
{
|
||||
if ( numBits )
|
||||
{
|
||||
bits->bitIndex += numBits;
|
||||
bits->cur += (bits->bitIndex >> 3);
|
||||
bits->bitIndex &= 7;
|
||||
}
|
||||
}
|
||||
|
||||
// BitBufferRewind
|
||||
//
|
||||
void BitBufferRewind( BitBuffer * bits, uint32_t numBits )
|
||||
{
|
||||
uint32_t numBytes;
|
||||
|
||||
if ( numBits == 0 )
|
||||
return;
|
||||
|
||||
if ( bits->bitIndex >= numBits )
|
||||
{
|
||||
bits->bitIndex -= numBits;
|
||||
return;
|
||||
}
|
||||
|
||||
numBits -= bits->bitIndex;
|
||||
bits->bitIndex = 0;
|
||||
|
||||
numBytes = numBits / 8;
|
||||
numBits = numBits % 8;
|
||||
|
||||
bits->cur -= numBytes;
|
||||
|
||||
if ( numBits > 0 )
|
||||
{
|
||||
bits->bitIndex = 8 - numBits;
|
||||
bits->cur--;
|
||||
}
|
||||
|
||||
if ( bits->cur < (bits->end - bits->byteSize) )
|
||||
{
|
||||
//DebugCMsg("BitBufferRewind: Rewound too far.");
|
||||
|
||||
bits->cur = (bits->end - bits->byteSize);
|
||||
bits->bitIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// BitBufferWrite
|
||||
//
|
||||
void BitBufferWrite( BitBuffer * bits, uint32_t bitValues, uint32_t numBits )
|
||||
{
|
||||
uint32_t invBitIndex;
|
||||
|
||||
RequireAction( bits != NULL, return; );
|
||||
RequireActionSilent( numBits > 0, return; );
|
||||
|
||||
invBitIndex = 8 - bits->bitIndex;
|
||||
|
||||
while ( numBits > 0 )
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint8_t shift;
|
||||
uint8_t mask;
|
||||
uint32_t curNum;
|
||||
|
||||
curNum = MIN( invBitIndex, numBits );
|
||||
|
||||
tmp = bitValues >> (numBits - curNum);
|
||||
|
||||
shift = (uint8_t)(invBitIndex - curNum);
|
||||
mask = 0xffu >> (8 - curNum); // must be done in two steps to avoid compiler sequencing ambiguity
|
||||
mask <<= shift;
|
||||
|
||||
bits->cur[0] = (bits->cur[0] & ~mask) | (((uint8_t) tmp << shift) & mask);
|
||||
numBits -= curNum;
|
||||
|
||||
// increment to next byte if need be
|
||||
invBitIndex -= curNum;
|
||||
if ( invBitIndex == 0 )
|
||||
{
|
||||
invBitIndex = 8;
|
||||
bits->cur++;
|
||||
}
|
||||
}
|
||||
|
||||
bits->bitIndex = 8 - invBitIndex;
|
||||
}
|
||||
|
||||
void BitBufferReset( BitBuffer * bits )
|
||||
//void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize )
|
||||
{
|
||||
bits->cur = bits->end - bits->byteSize;
|
||||
bits->bitIndex = 0;
|
||||
}
|
||||
|
||||
#if PRAGMA_MARK
|
||||
#pragma mark -
|
||||
#endif
|
91
src/ALAC/ALACBitUtilities.h
Normal file
91
src/ALAC/ALACBitUtilities.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*=============================================================================
|
||||
File: ALACBitUtilities.h
|
||||
|
||||
$NoKeywords: $
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __ALACBITUTILITIES_H
|
||||
#define __ALACBITUTILITIES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ( (x)<(y) ?(x) :(y) )
|
||||
#endif //MIN
|
||||
#ifndef MAX
|
||||
#define MAX(x, y) ( (x)>(y) ?(x): (y) )
|
||||
#endif //MAX
|
||||
|
||||
#define RequireAction(condition, action) if (!(condition)) { action }
|
||||
#define RequireActionSilent(condition, action) if (!(condition)) { action }
|
||||
#define RequireNoErr(condition, action) if ((condition)) { action }
|
||||
|
||||
enum
|
||||
{
|
||||
ALAC_noErr = 0
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
||||
ID_SCE = 0, /* Single Channel Element */
|
||||
ID_CPE = 1, /* Channel Pair Element */
|
||||
ID_CCE = 2, /* Coupling Channel Element */
|
||||
ID_LFE = 3, /* LFE Channel Element */
|
||||
ID_DSE = 4, /* not yet supported */
|
||||
ID_PCE = 5,
|
||||
ID_FIL = 6,
|
||||
ID_END = 7
|
||||
} ELEMENT_TYPE;
|
||||
|
||||
// types
|
||||
typedef struct BitBuffer
|
||||
{
|
||||
uint8_t * cur;
|
||||
uint8_t * end;
|
||||
uint32_t bitIndex;
|
||||
uint32_t byteSize;
|
||||
|
||||
} BitBuffer;
|
||||
|
||||
/*
|
||||
BitBuffer routines
|
||||
- these routines take a fixed size buffer and read/write to it
|
||||
- bounds checking must be done by the client
|
||||
*/
|
||||
void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize );
|
||||
uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits ); // note: cannot read more than 16 bits at a time
|
||||
uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits );
|
||||
uint8_t BitBufferReadOne( BitBuffer * bits );
|
||||
uint32_t BitBufferPeek( BitBuffer * bits, uint8_t numBits ); // note: cannot read more than 16 bits at a time
|
||||
uint32_t BitBufferPeekOne( BitBuffer * bits );
|
||||
uint32_t BitBufferUnpackBERSize( BitBuffer * bits );
|
||||
uint32_t BitBufferGetPosition( BitBuffer * bits );
|
||||
void BitBufferByteAlign( BitBuffer * bits, int32_t addZeros );
|
||||
void BitBufferAdvance( BitBuffer * bits, uint32_t numBits );
|
||||
void BitBufferRewind( BitBuffer * bits, uint32_t numBits );
|
||||
void BitBufferWrite( BitBuffer * bits, uint32_t value, uint32_t numBits );
|
||||
void BitBufferReset( BitBuffer * bits);
|
||||
|
||||
#endif /* __BITUTILITIES_H */
|
61
src/ALAC/ALACDecoder.h
Normal file
61
src/ALAC/ALACDecoder.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: ALACDecoder.h
|
||||
*/
|
||||
|
||||
#ifndef _ALACDECODER_H
|
||||
#define _ALACDECODER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
struct BitBuffer;
|
||||
|
||||
class ALACDecoder
|
||||
{
|
||||
public:
|
||||
ALACDecoder();
|
||||
~ALACDecoder();
|
||||
|
||||
int32_t Init( void * inMagicCookie, uint32_t inMagicCookieSize );
|
||||
int32_t Decode( struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples );
|
||||
|
||||
public:
|
||||
// decoding parameters (public for use in the analyzer)
|
||||
ALACSpecificConfig mConfig;
|
||||
|
||||
protected:
|
||||
int32_t FillElement( struct BitBuffer * bits );
|
||||
int32_t DataStreamElement( struct BitBuffer * bits );
|
||||
|
||||
uint16_t mActiveElements;
|
||||
|
||||
// decoding buffers
|
||||
int32_t * mMixBufferU;
|
||||
int32_t * mMixBufferV;
|
||||
int32_t * mPredictor;
|
||||
uint16_t * mShiftBuffer; // note: this points to mPredictor's memory but different
|
||||
// variable for clarity and type difference
|
||||
};
|
||||
|
||||
#endif /* _ALACDECODER_H */
|
92
src/ALAC/ALACEncoder.h
Normal file
92
src/ALAC/ALACEncoder.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: ALACEncoder.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
|
||||
struct BitBuffer;
|
||||
|
||||
class ALACEncoder
|
||||
{
|
||||
public:
|
||||
ALACEncoder();
|
||||
virtual ~ALACEncoder();
|
||||
|
||||
virtual int32_t Encode(AudioFormatDescription theInputFormat, AudioFormatDescription theOutputFormat,
|
||||
unsigned char * theReadBuffer, unsigned char * theWriteBuffer, int32_t * ioNumBytes);
|
||||
virtual int32_t Finish( );
|
||||
|
||||
void SetFastMode( bool fast ) { mFastMode = fast; };
|
||||
|
||||
// this must be called *before* InitializeEncoder()
|
||||
void SetFrameSize( uint32_t frameSize ) { mFrameSize = frameSize; };
|
||||
|
||||
void GetConfig( ALACSpecificConfig & config );
|
||||
uint32_t GetMagicCookieSize(uint32_t inNumChannels);
|
||||
void GetMagicCookie( void * config, uint32_t * ioSize );
|
||||
|
||||
virtual int32_t InitializeEncoder(AudioFormatDescription theOutputFormat);
|
||||
|
||||
protected:
|
||||
virtual void GetSourceFormat( const AudioFormatDescription * source, AudioFormatDescription * output );
|
||||
|
||||
int32_t EncodeStereo( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
|
||||
int32_t EncodeStereoFast( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
|
||||
int32_t EncodeStereoEscape( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t numSamples );
|
||||
int32_t EncodeMono( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
|
||||
|
||||
|
||||
// ALAC encoder parameters
|
||||
int16_t mBitDepth;
|
||||
bool mFastMode;
|
||||
|
||||
// encoding state
|
||||
int16_t mLastMixRes[kALACMaxChannels];
|
||||
|
||||
// encoding buffers
|
||||
int32_t * mMixBufferU;
|
||||
int32_t * mMixBufferV;
|
||||
int32_t * mPredictorU;
|
||||
int32_t * mPredictorV;
|
||||
uint16_t * mShiftBufferUV;
|
||||
|
||||
uint8_t * mWorkBuffer;
|
||||
|
||||
// per-channel coefficients buffers
|
||||
int16_t mCoefsU[kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
|
||||
int16_t mCoefsV[kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
|
||||
|
||||
// encoding statistics
|
||||
uint32_t mTotalBytesGenerated;
|
||||
uint32_t mAvgBitRate;
|
||||
uint32_t mMaxFrameBytes;
|
||||
uint32_t mFrameSize;
|
||||
uint32_t mMaxOutputBytes;
|
||||
uint32_t mNumChannels;
|
||||
uint32_t mOutputSampleRate;
|
||||
};
|
175
src/ALAC/EndianPortable.c
Normal file
175
src/ALAC/EndianPortable.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
//
|
||||
// EndianPortable.c
|
||||
//
|
||||
// Copyright 2011 Apple Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "EndianPortable.h"
|
||||
|
||||
#define BSWAP16(x) (((x << 8) | ((x >> 8) & 0x00ff)))
|
||||
#define BSWAP32(x) (((x << 24) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff)))
|
||||
#define BSWAP64(x) ((((int64_t)x << 56) | (((int64_t)x << 40) & 0x00ff000000000000LL) | \
|
||||
(((int64_t)x << 24) & 0x0000ff0000000000LL) | (((int64_t)x << 8) & 0x000000ff00000000LL) | \
|
||||
(((int64_t)x >> 8) & 0x00000000ff000000LL) | (((int64_t)x >> 24) & 0x0000000000ff0000LL) | \
|
||||
(((int64_t)x >> 40) & 0x000000000000ff00LL) | (((int64_t)x >> 56) & 0x00000000000000ffLL)))
|
||||
|
||||
#if defined(__i386__)
|
||||
#define TARGET_RT_LITTLE_ENDIAN 1
|
||||
#elif defined(__x86_64__)
|
||||
#define TARGET_RT_LITTLE_ENDIAN 1
|
||||
#elif defined (TARGET_OS_WIN32)
|
||||
#define TARGET_RT_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
uint16_t Swap16NtoB(uint16_t inUInt16)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
return BSWAP16(inUInt16);
|
||||
#else
|
||||
return inUInt16;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t Swap16BtoN(uint16_t inUInt16)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
return BSWAP16(inUInt16);
|
||||
#else
|
||||
return inUInt16;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t Swap32NtoB(uint32_t inUInt32)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
return BSWAP32(inUInt32);
|
||||
#else
|
||||
return inUInt32;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t Swap32BtoN(uint32_t inUInt32)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
return BSWAP32(inUInt32);
|
||||
#else
|
||||
return inUInt32;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t Swap64BtoN(uint64_t inUInt64)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
return BSWAP64(inUInt64);
|
||||
#else
|
||||
return inUInt64;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t Swap64NtoB(uint64_t inUInt64)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
return BSWAP64(inUInt64);
|
||||
#else
|
||||
return inUInt64;
|
||||
#endif
|
||||
}
|
||||
|
||||
float SwapFloat32BtoN(float in)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
union {
|
||||
float f;
|
||||
int32_t i;
|
||||
} x;
|
||||
x.f = in;
|
||||
x.i = BSWAP32(x.i);
|
||||
return x.f;
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
}
|
||||
|
||||
float SwapFloat32NtoB(float in)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
union {
|
||||
float f;
|
||||
int32_t i;
|
||||
} x;
|
||||
x.f = in;
|
||||
x.i = BSWAP32(x.i);
|
||||
return x.f;
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
}
|
||||
|
||||
double SwapFloat64BtoN(double in)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
union {
|
||||
double f;
|
||||
int64_t i;
|
||||
} x;
|
||||
x.f = in;
|
||||
x.i = BSWAP64(x.i);
|
||||
return x.f;
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
}
|
||||
|
||||
double SwapFloat64NtoB(double in)
|
||||
{
|
||||
#if TARGET_RT_LITTLE_ENDIAN
|
||||
union {
|
||||
double f;
|
||||
int64_t i;
|
||||
} x;
|
||||
x.f = in;
|
||||
x.i = BSWAP64(x.i);
|
||||
return x.f;
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Swap16(uint16_t * inUInt16)
|
||||
{
|
||||
*inUInt16 = BSWAP16(*inUInt16);
|
||||
}
|
||||
|
||||
void Swap24(uint8_t * inUInt24)
|
||||
{
|
||||
uint8_t tempVal = inUInt24[0];
|
||||
inUInt24[0] = inUInt24[2];
|
||||
inUInt24[2] = tempVal;
|
||||
}
|
||||
|
||||
void Swap32(uint32_t * inUInt32)
|
||||
{
|
||||
*inUInt32 = BSWAP32(*inUInt32);
|
||||
}
|
||||
|
59
src/ALAC/EndianPortable.h
Normal file
59
src/ALAC/EndianPortable.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
//
|
||||
// EndianPortable.h
|
||||
//
|
||||
// Copyright 2011 Apple Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _EndianPortable_h
|
||||
#define _EndianPortable_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint16_t Swap16NtoB(uint16_t inUInt16);
|
||||
uint16_t Swap16BtoN(uint16_t inUInt16);
|
||||
|
||||
uint32_t Swap32NtoB(uint32_t inUInt32);
|
||||
uint32_t Swap32BtoN(uint32_t inUInt32);
|
||||
|
||||
uint64_t Swap64BtoN(uint64_t inUInt64);
|
||||
uint64_t Swap64NtoB(uint64_t inUInt64);
|
||||
|
||||
float SwapFloat32BtoN(float in);
|
||||
float SwapFloat32NtoB(float in);
|
||||
|
||||
double SwapFloat64BtoN(double in);
|
||||
double SwapFloat64NtoB(double in);
|
||||
|
||||
void Swap16(uint16_t * inUInt16);
|
||||
void Swap24(uint8_t * inUInt24);
|
||||
void Swap32(uint32_t * inUInt32);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
170
src/ALAC/LICENSE
Normal file
170
src/ALAC/LICENSE
Normal file
@ -0,0 +1,170 @@
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the
|
||||
copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other
|
||||
entities that control, are controlled by, or are under common control
|
||||
with that entity. For the purposes of this definition, "control" means
|
||||
(i) the power, direct or indirect, to cause the direction or management
|
||||
of such entity, whether by contract or otherwise, or (ii) ownership
|
||||
of fifty percent (50%) or more of the outstanding shares, or (iii)
|
||||
beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation source,
|
||||
and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but not
|
||||
limited to compiled object code, generated documentation, and
|
||||
conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object
|
||||
form, made available under the License, as indicated by a copyright
|
||||
notice that is included in or attached to the work (an example is
|
||||
provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original
|
||||
version of the Work and any modifications or additions to that Work or
|
||||
Derivative Works thereof, that is intentionally submitted to Licensor
|
||||
for inclusion in the Work by the copyright owner or by an individual
|
||||
or Legal Entity authorized to submit on behalf of the copyright owner.
|
||||
For the purposes of this definition, "submitted" means any form of
|
||||
electronic, verbal, or written communication sent to the Licensor
|
||||
or its representatives, including but not limited to communication
|
||||
on electronic mailing lists, source code control systems, and issue
|
||||
tracking systems that are managed by, or on behalf of, the Licensor
|
||||
for the purpose of discussing and improving the Work, but excluding
|
||||
communication that is conspicuously marked or otherwise designated in
|
||||
writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions
|
||||
of this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of, publicly
|
||||
display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except
|
||||
as stated in this section) patent license to make, have made, use,
|
||||
offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such
|
||||
Contributor that are necessarily infringed by their Contribution(s)
|
||||
alone or by combination of their Contribution(s) with the Work to which
|
||||
such Contribution(s) was submitted. If You institute patent litigation
|
||||
against any entity (including a cross-claim or counterclaim in a
|
||||
lawsuit) alleging that the Work or a Contribution incorporated within
|
||||
the Work constitutes direct or contributory patent infringement, then
|
||||
any patent licenses granted to You under this License for that Work
|
||||
shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You meet the
|
||||
following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a
|
||||
copy of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating
|
||||
that You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You
|
||||
distribute, all copyright, patent, trademark, and attribution notices
|
||||
from the Source form of the Work, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution,
|
||||
then any Derivative Works that You distribute must include a readable
|
||||
copy of the attribution notices contained within such NOTICE file,
|
||||
excluding those notices that do not pertain to any part of the
|
||||
Derivative Works, in at least one of the following places: within a
|
||||
NOTICE text file distributed as part of the Derivative Works; within
|
||||
the Source form or documentation, if provided along with the Derivative
|
||||
Works; or, within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents of the
|
||||
NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative
|
||||
Works that You distribute, alongside or as an addendum to the NOTICE
|
||||
text from the Work, provided that such additional attribution notices
|
||||
cannot be construed as modifying the License. You may add Your own
|
||||
copyright statement to Your modifications and may provide additional
|
||||
or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as
|
||||
a whole, provided Your use, reproduction, and distribution of the Work
|
||||
otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work by
|
||||
You to the Licensor shall be under the terms and conditions of this
|
||||
License, without any additional terms or conditions. Notwithstanding
|
||||
the above, nothing herein shall supersede or modify the terms of any
|
||||
separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed
|
||||
to in writing, Licensor provides the Work (and each Contributor
|
||||
provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied, including, without
|
||||
limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your
|
||||
exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise, unless
|
||||
required by applicable law (such as deliberate and grossly negligent
|
||||
acts) or agreed to in writing, shall any Contributor be liable to You
|
||||
for damages, including any direct, indirect, special, incidental, or
|
||||
consequential damages of any character arising as a result of this
|
||||
License or out of the use or inability to use the Work (including but
|
||||
not limited to damages for loss of goodwill, work stoppage, computer
|
||||
failure or malfunction, or any and all other commercial damages or
|
||||
losses), even if such Contributor has been advised of the possibility of
|
||||
such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the
|
||||
Work or Derivative Works thereof, You may choose to offer, and charge a
|
||||
fee for, acceptance of support, warranty, indemnity, or other liability
|
||||
obligations and/or rights consistent with this License. However, in
|
||||
accepting such obligations, You may act only on Your own behalf and
|
||||
on Your sole responsibility, not on behalf of any other Contributor,
|
||||
and only if You agree to indemnify, defend, and hold each Contributor
|
||||
harmless for any liability incurred by, or claims asserted against, such
|
||||
Contributor by reason of your accepting any such warranty or additional
|
||||
liability.
|
355
src/ALAC/ag_dec.c
Normal file
355
src/ALAC/ag_dec.c
Normal file
@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: ag_dec.c
|
||||
|
||||
Contains: Adaptive Golomb decode routines.
|
||||
|
||||
Copyright: (c) 2001-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#include "aglib.h"
|
||||
#include "ALACBitUtilities.h"
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CODE_TO_LONG_MAXBITS 32
|
||||
#define N_MAX_MEAN_CLAMP 0xffff
|
||||
#define N_MEAN_CLAMP_VAL 0xffff
|
||||
#define REPORT_VAL 40
|
||||
|
||||
#if __GNUC__
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
|
||||
to help the compiler out. In many cases this required manual inlining or a macro. Sorry
|
||||
if it is ugly but the performance gains are well worth it.
|
||||
- WSK 5/19/04
|
||||
*/
|
||||
|
||||
void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth)
|
||||
{
|
||||
/* Use
|
||||
fullwidth = sectorwidth = numOfSamples, for analog 1-dimensional type-short data,
|
||||
but use
|
||||
fullwidth = full image width, sectorwidth = sector (patch) width
|
||||
for such as image (2-dim.) data.
|
||||
*/
|
||||
set_ag_params( params, MB0, PB0, KB0, fullwidth, sectorwidth, MAX_RUN_DEFAULT );
|
||||
}
|
||||
|
||||
void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun)
|
||||
{
|
||||
params->mb = params->mb0 = m;
|
||||
params->pb = p;
|
||||
params->kb = k;
|
||||
params->wb = (1u<<params->kb)-1;
|
||||
params->qb = QB-params->pb;
|
||||
params->fw = f;
|
||||
params->sw = s;
|
||||
params->maxrun = maxrun;
|
||||
}
|
||||
|
||||
#if PRAGMA_MARK
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
|
||||
// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
|
||||
static inline int32_t lead( int32_t m )
|
||||
{
|
||||
long j;
|
||||
unsigned long c = (1ul << 31);
|
||||
|
||||
for(j=0; j < 32; j++)
|
||||
{
|
||||
if((c & m) != 0)
|
||||
break;
|
||||
c >>= 1;
|
||||
}
|
||||
return (j);
|
||||
}
|
||||
|
||||
#define arithmin(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
static inline int32_t ALWAYS_INLINE lg3a( int32_t x)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
x += 3;
|
||||
result = lead(x);
|
||||
|
||||
return 31 - result;
|
||||
}
|
||||
|
||||
static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer )
|
||||
{
|
||||
// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
|
||||
uint32_t value;
|
||||
|
||||
value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) |
|
||||
((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3];
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
#if PRAGMA_MARK
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
#define get_next_fromlong(inlong, suff) ((inlong) >> (32 - (suff)))
|
||||
|
||||
|
||||
static inline uint32_t ALWAYS_INLINE
|
||||
getstreambits( uint8_t *in, int32_t bitoffset, int32_t numbits )
|
||||
{
|
||||
uint32_t load1, load2;
|
||||
uint32_t byteoffset = bitoffset / 8;
|
||||
uint32_t result;
|
||||
|
||||
//Assert( numbits <= 32 );
|
||||
|
||||
load1 = read32bit( in + byteoffset );
|
||||
|
||||
if ( (numbits + (bitoffset & 0x7)) > 32)
|
||||
{
|
||||
int32_t load2shift;
|
||||
|
||||
result = load1 << (bitoffset & 0x7);
|
||||
load2 = (uint32_t) in[byteoffset+4];
|
||||
load2shift = (8-(numbits + (bitoffset & 0x7)-32));
|
||||
load2 >>= load2shift;
|
||||
result >>= (32-numbits);
|
||||
result |= load2;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = load1 >> (32-numbits-(bitoffset & 7));
|
||||
}
|
||||
|
||||
// a shift of >= "the number of bits in the type of the value being shifted" results in undefined
|
||||
// behavior so don't try to shift by 32
|
||||
if ( numbits != (sizeof(result) * 8) )
|
||||
result &= ~(0xfffffffful << numbits);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static inline int32_t dyn_get(unsigned char *in, uint32_t *bitPos, uint32_t m, uint32_t k)
|
||||
{
|
||||
uint32_t tempbits = *bitPos;
|
||||
uint32_t result;
|
||||
uint32_t pre = 0, v;
|
||||
uint32_t streamlong;
|
||||
|
||||
streamlong = read32bit( in + (tempbits >> 3) );
|
||||
streamlong <<= (tempbits & 7);
|
||||
|
||||
/* find the number of bits in the prefix */
|
||||
{
|
||||
uint32_t notI = ~streamlong;
|
||||
pre = lead( notI);
|
||||
}
|
||||
|
||||
if(pre >= MAX_PREFIX_16)
|
||||
{
|
||||
pre = MAX_PREFIX_16;
|
||||
tempbits += pre;
|
||||
streamlong <<= pre;
|
||||
result = get_next_fromlong(streamlong,MAX_DATATYPE_BITS_16);
|
||||
tempbits += MAX_DATATYPE_BITS_16;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// all of the bits must fit within the long we have loaded
|
||||
//Assert(pre+1+k <= 32);
|
||||
|
||||
tempbits += pre;
|
||||
tempbits += 1;
|
||||
streamlong <<= pre+1;
|
||||
v = get_next_fromlong(streamlong, k);
|
||||
tempbits += k;
|
||||
|
||||
result = pre*m + v-1;
|
||||
|
||||
if(v<2) {
|
||||
result -= (v-1);
|
||||
tempbits -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
*bitPos = tempbits;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static inline int32_t dyn_get_32bit( uint8_t * in, uint32_t * bitPos, int32_t m, int32_t k, int32_t maxbits )
|
||||
{
|
||||
uint32_t tempbits = *bitPos;
|
||||
uint32_t v;
|
||||
uint32_t streamlong;
|
||||
uint32_t result;
|
||||
|
||||
streamlong = read32bit( in + (tempbits >> 3) );
|
||||
streamlong <<= (tempbits & 7);
|
||||
|
||||
/* find the number of bits in the prefix */
|
||||
{
|
||||
uint32_t notI = ~streamlong;
|
||||
result = lead( notI);
|
||||
}
|
||||
|
||||
if(result >= MAX_PREFIX_32)
|
||||
{
|
||||
result = getstreambits(in, tempbits+MAX_PREFIX_32, maxbits);
|
||||
tempbits += MAX_PREFIX_32 + maxbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* all of the bits must fit within the long we have loaded*/
|
||||
//Assert(k<=14);
|
||||
//Assert(result<MAX_PREFIX_32);
|
||||
//Assert(result+1+k <= 32);
|
||||
|
||||
tempbits += result;
|
||||
tempbits += 1;
|
||||
|
||||
if (k != 1)
|
||||
{
|
||||
streamlong <<= result+1;
|
||||
v = get_next_fromlong(streamlong, k);
|
||||
tempbits += k;
|
||||
tempbits -= 1;
|
||||
result = result*m;
|
||||
|
||||
if(v>=2)
|
||||
{
|
||||
result += (v-1);
|
||||
tempbits += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*bitPos = tempbits;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t dyn_decomp( AGParamRecPtr params, BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits )
|
||||
{
|
||||
uint8_t *in;
|
||||
int32_t *outPtr = pc;
|
||||
uint32_t bitPos, startPos, maxPos;
|
||||
uint32_t j, m, k, n, c, mz;
|
||||
int32_t del, zmode;
|
||||
uint32_t mb;
|
||||
uint32_t pb_local = params->pb;
|
||||
uint32_t kb_local = params->kb;
|
||||
uint32_t wb_local = params->wb;
|
||||
int32_t status;
|
||||
|
||||
RequireAction( (bitstream != NULL) && (pc != NULL) && (outNumBits != NULL), return kALAC_ParamError; );
|
||||
*outNumBits = 0;
|
||||
|
||||
in = bitstream->cur;
|
||||
startPos = bitstream->bitIndex;
|
||||
maxPos = bitstream->byteSize * 8;
|
||||
bitPos = startPos;
|
||||
|
||||
mb = params->mb0;
|
||||
zmode = 0;
|
||||
|
||||
c = 0;
|
||||
status = ALAC_noErr;
|
||||
|
||||
while (c < (uint32_t) numSamples)
|
||||
{
|
||||
// bail if we've run off the end of the buffer
|
||||
RequireAction( bitPos < maxPos, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
m = (mb)>>QBSHIFT;
|
||||
k = lg3a(m);
|
||||
|
||||
k = arithmin(k, kb_local);
|
||||
m = (1<<k)-1;
|
||||
|
||||
n = dyn_get_32bit( in, &bitPos, m, k, maxSize );
|
||||
|
||||
// least significant bit is sign bit
|
||||
{
|
||||
uint32_t ndecode = n + zmode;
|
||||
int32_t multiplier = (- (ndecode&1));
|
||||
|
||||
multiplier |= 1;
|
||||
del = ((ndecode+1) >> 1) * (multiplier);
|
||||
}
|
||||
|
||||
*outPtr++ = del;
|
||||
|
||||
c++;
|
||||
|
||||
mb = pb_local*(n+zmode) + mb - ((pb_local*mb)>>QBSHIFT);
|
||||
|
||||
// update mean tracking
|
||||
if (n > N_MAX_MEAN_CLAMP)
|
||||
mb = N_MEAN_CLAMP_VAL;
|
||||
|
||||
zmode = 0;
|
||||
|
||||
if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples))
|
||||
{
|
||||
zmode = 1;
|
||||
k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT);
|
||||
mz = ((1<<k)-1) & wb_local;
|
||||
|
||||
n = dyn_get(in, &bitPos, mz, k);
|
||||
|
||||
RequireAction(c+n <= (uint32_t) numSamples, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
for(j=0; j < n; j++)
|
||||
{
|
||||
*outPtr++ = 0;
|
||||
++c;
|
||||
}
|
||||
|
||||
if(n >= 65535)
|
||||
zmode = 0;
|
||||
|
||||
mb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
*outNumBits = (bitPos - startPos);
|
||||
BitBufferAdvance( bitstream, *outNumBits );
|
||||
RequireAction( bitstream->cur <= bitstream->end, status = kALAC_ParamError; );
|
||||
|
||||
return status;
|
||||
}
|
363
src/ALAC/ag_enc.c
Normal file
363
src/ALAC/ag_enc.c
Normal file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: ag_enc.c
|
||||
|
||||
Contains: Adaptive Golomb encode routines.
|
||||
|
||||
Copyright: (c) 2001-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#include "aglib.h"
|
||||
#include "ALACBitUtilities.h"
|
||||
#include "EndianPortable.h"
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CODE_TO_LONG_MAXBITS 32
|
||||
#define N_MAX_MEAN_CLAMP 0xffff
|
||||
#define N_MEAN_CLAMP_VAL 0xffff
|
||||
#define REPORT_VAL 40
|
||||
|
||||
#if __GNUC__
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
|
||||
/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
|
||||
to help the compiler out. In many cases this required manual inlining or a macro. Sorry
|
||||
if it is ugly but the performance gains are well worth it.
|
||||
- WSK 5/19/04
|
||||
*/
|
||||
|
||||
// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
|
||||
static inline int32_t lead( int32_t m )
|
||||
{
|
||||
long j;
|
||||
unsigned long c = (1ul << 31);
|
||||
|
||||
for(j=0; j < 32; j++)
|
||||
{
|
||||
if((c & m) != 0)
|
||||
break;
|
||||
c >>= 1;
|
||||
}
|
||||
return (j);
|
||||
}
|
||||
|
||||
#define arithmin(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
static inline int32_t ALWAYS_INLINE lg3a( int32_t x)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
x += 3;
|
||||
result = lead(x);
|
||||
|
||||
return 31 - result;
|
||||
}
|
||||
|
||||
static inline int32_t ALWAYS_INLINE abs_func( int32_t a )
|
||||
{
|
||||
// note: the CW PPC intrinsic __abs() turns into these instructions so no need to try and use it
|
||||
int32_t isneg = a >> 31;
|
||||
int32_t xorval = a ^ isneg;
|
||||
int32_t result = xorval-isneg;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer )
|
||||
{
|
||||
// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
|
||||
uint32_t value;
|
||||
|
||||
value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) |
|
||||
((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3];
|
||||
return value;
|
||||
}
|
||||
|
||||
#if PRAGMA_MARK
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
static inline int32_t dyn_code(int32_t m, int32_t k, int32_t n, uint32_t *outNumBits)
|
||||
{
|
||||
uint32_t divx, mod, de;
|
||||
uint32_t numBits;
|
||||
uint32_t value;
|
||||
|
||||
//Assert( n >= 0 );
|
||||
|
||||
divx = n/m;
|
||||
|
||||
if(divx >= MAX_PREFIX_16)
|
||||
{
|
||||
numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16;
|
||||
value = (((1<<MAX_PREFIX_16)-1)<<MAX_DATATYPE_BITS_16) + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod = n%m;
|
||||
de = (mod == 0);
|
||||
numBits = divx + k + 1 - de;
|
||||
value = (((1<<divx)-1)<<(numBits-divx)) + mod + 1 - de;
|
||||
|
||||
// if coding this way is bigger than doing escape, then do escape
|
||||
if (numBits > MAX_PREFIX_16 + MAX_DATATYPE_BITS_16)
|
||||
{
|
||||
numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16;
|
||||
value = (((1<<MAX_PREFIX_16)-1)<<MAX_DATATYPE_BITS_16) + n;
|
||||
}
|
||||
}
|
||||
|
||||
*outNumBits = numBits;
|
||||
|
||||
return (int32_t) value;
|
||||
}
|
||||
|
||||
|
||||
static inline int32_t dyn_code_32bit(int32_t maxbits, uint32_t m, uint32_t k, uint32_t n, uint32_t *outNumBits, uint32_t *outValue, uint32_t *overflow, uint32_t *overflowbits)
|
||||
{
|
||||
uint32_t divx, mod, de;
|
||||
uint32_t numBits;
|
||||
uint32_t value;
|
||||
int32_t didOverflow = 0;
|
||||
|
||||
divx = n/m;
|
||||
|
||||
if (divx < MAX_PREFIX_32)
|
||||
{
|
||||
mod = n - (m * divx);
|
||||
|
||||
de = (mod == 0);
|
||||
numBits = divx + k + 1 - de;
|
||||
value = (((1<<divx)-1)<<(numBits-divx)) + mod + 1 - de;
|
||||
if (numBits > 25)
|
||||
goto codeasescape;
|
||||
}
|
||||
else
|
||||
{
|
||||
codeasescape:
|
||||
numBits = MAX_PREFIX_32;
|
||||
value = (((1<<MAX_PREFIX_32)-1));
|
||||
*overflow = n;
|
||||
*overflowbits = maxbits;
|
||||
didOverflow = 1;
|
||||
}
|
||||
|
||||
*outNumBits = numBits;
|
||||
*outValue = value;
|
||||
|
||||
return didOverflow;
|
||||
}
|
||||
|
||||
|
||||
static inline void ALWAYS_INLINE dyn_jam_noDeref(unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
|
||||
{
|
||||
uint32_t *i = (uint32_t *)(out + (bitPos >> 3));
|
||||
uint32_t mask;
|
||||
uint32_t curr;
|
||||
uint32_t shift;
|
||||
|
||||
//Assert( numBits <= 32 );
|
||||
|
||||
curr = *i;
|
||||
curr = Swap32NtoB( curr );
|
||||
|
||||
shift = 32 - (bitPos & 7) - numBits;
|
||||
|
||||
mask = ~0u >> (32 - numBits); // mask must be created in two steps to avoid compiler sequencing ambiguity
|
||||
mask <<= shift;
|
||||
|
||||
value = (value << shift) & mask;
|
||||
value |= curr & ~mask;
|
||||
|
||||
*i = Swap32BtoN( value );
|
||||
}
|
||||
|
||||
|
||||
static inline void ALWAYS_INLINE dyn_jam_noDeref_large(unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
|
||||
{
|
||||
uint32_t * i = (uint32_t *)(out + (bitPos>>3));
|
||||
uint32_t w;
|
||||
uint32_t curr;
|
||||
uint32_t mask;
|
||||
int32_t shiftvalue = (32 - (bitPos&7) - numBits);
|
||||
|
||||
//Assert(numBits <= 32);
|
||||
|
||||
curr = *i;
|
||||
curr = Swap32NtoB( curr );
|
||||
|
||||
if (shiftvalue < 0)
|
||||
{
|
||||
uint8_t tailbyte;
|
||||
uint8_t *tailptr;
|
||||
|
||||
w = value >> -shiftvalue;
|
||||
mask = ~0u >> -shiftvalue;
|
||||
w |= (curr & ~mask);
|
||||
|
||||
tailptr = ((uint8_t *)i) + 4;
|
||||
tailbyte = (value << ((8+shiftvalue))) & 0xff;
|
||||
*tailptr = (uint8_t)tailbyte;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = ~0u >> (32 - numBits);
|
||||
mask <<= shiftvalue; // mask must be created in two steps to avoid compiler sequencing ambiguity
|
||||
|
||||
w = (value << shiftvalue) & mask;
|
||||
w |= curr & ~mask;
|
||||
}
|
||||
|
||||
*i = Swap32BtoN( w );
|
||||
}
|
||||
|
||||
|
||||
int32_t dyn_comp( AGParamRecPtr params, int32_t * pc, BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits )
|
||||
{
|
||||
unsigned char * out;
|
||||
uint32_t bitPos, startPos;
|
||||
uint32_t m, k, n, c, mz, nz;
|
||||
uint32_t numBits;
|
||||
uint32_t value;
|
||||
int32_t del, zmode;
|
||||
uint32_t overflow, overflowbits;
|
||||
int32_t status;
|
||||
|
||||
// shadow the variables in params so there's not the dereferencing overhead
|
||||
uint32_t mb, pb, kb, wb;
|
||||
int32_t rowPos = 0;
|
||||
int32_t rowSize = params->sw;
|
||||
int32_t rowJump = (params->fw) - rowSize;
|
||||
int32_t * inPtr = pc;
|
||||
|
||||
*outNumBits = 0;
|
||||
RequireAction( (bitSize >= 1) && (bitSize <= 32), return kALAC_ParamError; );
|
||||
|
||||
out = bitstream->cur;
|
||||
startPos = bitstream->bitIndex;
|
||||
bitPos = startPos;
|
||||
|
||||
mb = params->mb = params->mb0;
|
||||
pb = params->pb;
|
||||
kb = params->kb;
|
||||
wb = params->wb;
|
||||
zmode = 0;
|
||||
|
||||
c=0;
|
||||
status = ALAC_noErr;
|
||||
|
||||
while (c < (uint32_t) numSamples)
|
||||
{
|
||||
m = mb >> QBSHIFT;
|
||||
k = lg3a(m);
|
||||
if ( k > kb)
|
||||
{
|
||||
k = kb;
|
||||
}
|
||||
m = (1<<k)-1;
|
||||
|
||||
del = *inPtr++;
|
||||
rowPos++;
|
||||
|
||||
n = (abs_func(del) << 1) - ((del >> 31) & 1) - zmode;
|
||||
//Assert( 32-lead(n) <= bitSize );
|
||||
|
||||
if ( dyn_code_32bit(bitSize, m, k, n, &numBits, &value, &overflow, &overflowbits) )
|
||||
{
|
||||
dyn_jam_noDeref(out, bitPos, numBits, value);
|
||||
bitPos += numBits;
|
||||
dyn_jam_noDeref_large(out, bitPos, overflowbits, overflow);
|
||||
bitPos += overflowbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
dyn_jam_noDeref(out, bitPos, numBits, value);
|
||||
bitPos += numBits;
|
||||
}
|
||||
|
||||
c++;
|
||||
if ( rowPos >= rowSize)
|
||||
{
|
||||
rowPos = 0;
|
||||
inPtr += rowJump;
|
||||
}
|
||||
|
||||
mb = pb * (n + zmode) + mb - ((pb *mb)>>QBSHIFT);
|
||||
|
||||
// update mean tracking if it's overflowed
|
||||
if (n > N_MAX_MEAN_CLAMP)
|
||||
mb = N_MEAN_CLAMP_VAL;
|
||||
|
||||
zmode = 0;
|
||||
|
||||
RequireAction(c <= (uint32_t) numSamples, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples))
|
||||
{
|
||||
zmode = 1;
|
||||
nz = 0;
|
||||
|
||||
while(c<(uint32_t) numSamples && *inPtr == 0)
|
||||
{
|
||||
/* Take care of wrap-around globals. */
|
||||
++inPtr;
|
||||
++nz;
|
||||
++c;
|
||||
if ( ++rowPos >= rowSize)
|
||||
{
|
||||
rowPos = 0;
|
||||
inPtr += rowJump;
|
||||
}
|
||||
|
||||
if(nz >= 65535)
|
||||
{
|
||||
zmode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT);
|
||||
mz = ((1<<k)-1) & wb;
|
||||
|
||||
value = dyn_code(mz, k, nz, &numBits);
|
||||
dyn_jam_noDeref(out, bitPos, numBits, value);
|
||||
bitPos += numBits;
|
||||
|
||||
mb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*outNumBits = (bitPos - startPos);
|
||||
BitBufferAdvance( bitstream, *outNumBits );
|
||||
|
||||
Exit:
|
||||
return status;
|
||||
}
|
81
src/ALAC/aglib.h
Normal file
81
src/ALAC/aglib.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: aglib.h
|
||||
|
||||
Copyright: (C) 2001-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#ifndef AGLIB_H
|
||||
#define AGLIB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define QBSHIFT 9
|
||||
#define QB (1<<QBSHIFT)
|
||||
#define PB0 40
|
||||
#define MB0 10
|
||||
#define KB0 14
|
||||
#define MAX_RUN_DEFAULT 255
|
||||
|
||||
#define MMULSHIFT 2
|
||||
#define MDENSHIFT (QBSHIFT - MMULSHIFT - 1)
|
||||
#define MOFF ((1<<(MDENSHIFT-2)))
|
||||
|
||||
#define BITOFF 24
|
||||
|
||||
/* Max. prefix of 1's. */
|
||||
#define MAX_PREFIX_16 9
|
||||
#define MAX_PREFIX_TOLONG_16 15
|
||||
#define MAX_PREFIX_32 9
|
||||
|
||||
/* Max. bits in 16-bit data type */
|
||||
#define MAX_DATATYPE_BITS_16 16
|
||||
|
||||
typedef struct AGParamRec
|
||||
{
|
||||
uint32_t mb, mb0, pb, kb, wb, qb;
|
||||
uint32_t fw, sw;
|
||||
|
||||
uint32_t maxrun;
|
||||
|
||||
// fw = 1, sw = 1;
|
||||
|
||||
} AGParamRec, *AGParamRecPtr;
|
||||
|
||||
struct BitBuffer;
|
||||
|
||||
void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth);
|
||||
void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun);
|
||||
|
||||
int32_t dyn_comp(AGParamRecPtr params, int32_t * pc, struct BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits);
|
||||
int32_t dyn_decomp(AGParamRecPtr params, struct BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //#ifndef AGLIB_H
|
102
src/ALAC/alac_codec.h
Normal file
102
src/ALAC/alac_codec.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: alac_codec.h
|
||||
*/
|
||||
|
||||
#ifndef ALAC_CODEC_H
|
||||
#define ALAC_CODEC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
#define ALAC_FRAME_LENGTH 4096
|
||||
|
||||
struct BitBuffer;
|
||||
|
||||
typedef struct alac_decoder_s
|
||||
{
|
||||
// decoding parameters (public for use in the analyzer)
|
||||
ALACSpecificConfig mConfig;
|
||||
|
||||
uint16_t mActiveElements;
|
||||
|
||||
// decoding buffers
|
||||
int32_t mMixBufferU [ALAC_FRAME_LENGTH];
|
||||
int32_t mMixBufferV [ALAC_FRAME_LENGTH];
|
||||
union
|
||||
{
|
||||
int32_t mPredictor [ALAC_FRAME_LENGTH];
|
||||
uint16_t mShiftBuffer [ALAC_FRAME_LENGTH];
|
||||
} ;
|
||||
} ALAC_DECODER ;
|
||||
|
||||
typedef struct alac_encoder_s
|
||||
{
|
||||
// ALAC encoder parameters
|
||||
int16_t mBitDepth;
|
||||
|
||||
// encoding state
|
||||
int16_t mLastMixRes [kALACMaxChannels];
|
||||
|
||||
int32_t mFastMode;
|
||||
|
||||
// encoding buffers
|
||||
int32_t mMixBufferU [ALAC_FRAME_LENGTH] ;
|
||||
int32_t mMixBufferV [ALAC_FRAME_LENGTH] ;
|
||||
int32_t mPredictorU [ALAC_FRAME_LENGTH] ;
|
||||
int32_t mPredictorV [ALAC_FRAME_LENGTH] ;
|
||||
uint16_t mShiftBufferUV [2 * ALAC_FRAME_LENGTH] ;
|
||||
uint8_t mWorkBuffer [4 * ALAC_FRAME_LENGTH];
|
||||
|
||||
// per-channel coefficients buffers
|
||||
int16_t mCoefsU [kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
|
||||
int16_t mCoefsV [kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
|
||||
|
||||
// encoding statistics
|
||||
uint32_t mTotalBytesGenerated;
|
||||
uint32_t mAvgBitRate;
|
||||
uint32_t mMaxFrameBytes;
|
||||
uint32_t mFrameSize;
|
||||
uint32_t mMaxOutputBytes;
|
||||
uint32_t mNumChannels;
|
||||
uint32_t mOutputSampleRate;
|
||||
} ALAC_ENCODER ;
|
||||
|
||||
|
||||
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,
|
||||
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 * ioNumBytes) ;
|
||||
|
||||
void alac_set_fastmode(ALAC_ENCODER * p, int32_t fast) ;
|
||||
|
||||
uint32_t alac_get_magic_cookie_size(uint32_t inNumChannels) ;
|
||||
void alac_get_magic_cookie(ALAC_ENCODER *p, void * config, uint32_t * ioSize) ;
|
||||
void alac_get_source_format(ALAC_ENCODER *p, const AudioFormatDescription * source, AudioFormatDescription * output) ;
|
||||
|
||||
#endif
|
696
src/ALAC/alac_decoder.c
Normal file
696
src/ALAC/alac_decoder.c
Normal file
@ -0,0 +1,696 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: ALACDecoder.cpp
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alac_codec.h"
|
||||
|
||||
#include "dplib.h"
|
||||
#include "aglib.h"
|
||||
#include "matrixlib.h"
|
||||
|
||||
#include "ALACBitUtilities.h"
|
||||
#include "EndianPortable.h"
|
||||
|
||||
typedef enum
|
||||
{ false = 0,
|
||||
true = 1
|
||||
} bool ;
|
||||
|
||||
// constants/data
|
||||
const uint32_t kMaxBitDepth = 32; // max allowed bit depth is 32
|
||||
|
||||
|
||||
// prototypes
|
||||
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 );
|
||||
|
||||
|
||||
/*
|
||||
Init()
|
||||
- initialize the decoder with the given configuration
|
||||
*/
|
||||
int32_t
|
||||
alac_decoder_init (ALAC_DECODER *p, void * inMagicCookie, uint32_t inMagicCookieSize)
|
||||
{
|
||||
int32_t status = ALAC_noErr;
|
||||
ALACSpecificConfig theConfig;
|
||||
uint8_t * theActualCookie = (uint8_t *)inMagicCookie;
|
||||
uint32_t theCookieBytesRemaining = inMagicCookieSize;
|
||||
|
||||
// For historical reasons the decoder needs to be resilient to magic cookies vended by older encoders.
|
||||
// As specified in the ALACMagicCookieDescription.txt document, there may be additional data encapsulating
|
||||
// the ALACSpecificConfig. This would consist of format ('frma') and 'alac' atoms which precede the
|
||||
// ALACSpecificConfig.
|
||||
// See ALACMagicCookieDescription.txt for additional documentation concerning the 'magic cookie'
|
||||
|
||||
// skip format ('frma') atom if present
|
||||
if (theActualCookie[4] == 'f' && theActualCookie[5] == 'r' && theActualCookie[6] == 'm' && theActualCookie[7] == 'a')
|
||||
{
|
||||
theActualCookie += 12;
|
||||
theCookieBytesRemaining -= 12;
|
||||
}
|
||||
|
||||
// skip 'alac' atom header if present
|
||||
if (theActualCookie[4] == 'a' && theActualCookie[5] == 'l' && theActualCookie[6] == 'a' && theActualCookie[7] == 'c')
|
||||
{
|
||||
theActualCookie += 12;
|
||||
theCookieBytesRemaining -= 12;
|
||||
}
|
||||
|
||||
// read the ALACSpecificConfig
|
||||
if (theCookieBytesRemaining >= sizeof(ALACSpecificConfig))
|
||||
{
|
||||
theConfig.frameLength = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->frameLength);
|
||||
|
||||
if (theConfig.frameLength > ALAC_FRAME_LENGTH)
|
||||
return fALAC_FrameLengthError ;
|
||||
|
||||
theConfig.compatibleVersion = ((ALACSpecificConfig *)theActualCookie)->compatibleVersion;
|
||||
theConfig.bitDepth = ((ALACSpecificConfig *)theActualCookie)->bitDepth;
|
||||
theConfig.pb = ((ALACSpecificConfig *)theActualCookie)->pb;
|
||||
theConfig.mb = ((ALACSpecificConfig *)theActualCookie)->mb;
|
||||
theConfig.kb = ((ALACSpecificConfig *)theActualCookie)->kb;
|
||||
theConfig.numChannels = ((ALACSpecificConfig *)theActualCookie)->numChannels;
|
||||
theConfig.maxRun = Swap16BtoN(((ALACSpecificConfig *)theActualCookie)->maxRun);
|
||||
theConfig.maxFrameBytes = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->maxFrameBytes);
|
||||
theConfig.avgBitRate = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->avgBitRate);
|
||||
theConfig.sampleRate = Swap32BtoN(((ALACSpecificConfig *)theActualCookie)->sampleRate);
|
||||
|
||||
p->mConfig = theConfig;
|
||||
|
||||
RequireAction( p->mConfig.compatibleVersion <= kALACVersion, return kALAC_ParamError; );
|
||||
|
||||
RequireAction( (p->mMixBufferU != NULL) && (p->mMixBufferV != NULL) && (p->mPredictor != NULL),
|
||||
status = kALAC_MemFullError; goto Exit; );
|
||||
}
|
||||
else
|
||||
{
|
||||
status = kALAC_ParamError;
|
||||
}
|
||||
|
||||
// skip to Channel Layout Info
|
||||
// theActualCookie += sizeof(ALACSpecificConfig);
|
||||
|
||||
// Currently, the Channel Layout Info portion of the magic cookie (as defined in the
|
||||
// ALACMagicCookieDescription.txt document) is unused by the decoder.
|
||||
|
||||
Exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
Decode()
|
||||
- the decoded samples are interleaved into the output buffer in the order they arrive in
|
||||
the bitstream
|
||||
*/
|
||||
int32_t
|
||||
alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples)
|
||||
{
|
||||
BitBuffer shiftBits;
|
||||
uint32_t bits1, bits2;
|
||||
uint8_t tag;
|
||||
uint8_t elementInstanceTag;
|
||||
AGParamRec agParams;
|
||||
uint32_t channelIndex;
|
||||
int16_t coefsU[32]; // max possible size is 32 although NUMCOEPAIRS is the current limit
|
||||
int16_t coefsV[32];
|
||||
uint8_t numU, numV;
|
||||
uint8_t mixBits;
|
||||
int8_t mixRes;
|
||||
uint16_t unusedHeader;
|
||||
uint8_t escapeFlag;
|
||||
uint32_t chanBits;
|
||||
uint8_t bytesShifted;
|
||||
uint32_t shift;
|
||||
uint8_t modeU, modeV;
|
||||
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;
|
||||
uint32_t extraBits;
|
||||
int32_t val;
|
||||
uint32_t i, j;
|
||||
int32_t status;
|
||||
|
||||
RequireAction( (bits != NULL) && (sampleBuffer != NULL) && (outNumSamples != NULL), return kALAC_ParamError; );
|
||||
RequireAction( numChannels > 0, return kALAC_ParamError; );
|
||||
|
||||
p->mActiveElements = 0;
|
||||
channelIndex = 0;
|
||||
|
||||
status = ALAC_noErr;
|
||||
*outNumSamples = numSamples;
|
||||
|
||||
while ( status == ALAC_noErr )
|
||||
{
|
||||
// bail if we ran off the end of the buffer
|
||||
RequireAction( bits->cur < bits->end, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
// copy global decode params for this element
|
||||
pb = p->mConfig.pb;
|
||||
|
||||
// read element tag
|
||||
tag = BitBufferReadSmall( bits, 3 );
|
||||
switch ( tag )
|
||||
{
|
||||
case ID_SCE:
|
||||
case ID_LFE:
|
||||
{
|
||||
// mono/LFE channel
|
||||
elementInstanceTag = BitBufferReadSmall( bits, 4 );
|
||||
p->mActiveElements |= (1u << elementInstanceTag);
|
||||
|
||||
// read the 12 unused header bits
|
||||
unusedHeader = (uint16_t) BitBufferRead( bits, 12 );
|
||||
RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
// read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 4 );
|
||||
|
||||
partialFrame = headerByte >> 3;
|
||||
|
||||
bytesShifted = (headerByte >> 1) & 0x3u;
|
||||
RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
shift = bytesShifted * 8;
|
||||
|
||||
escapeFlag = headerByte & 0x1;
|
||||
|
||||
chanBits = p->mConfig.bitDepth - (bytesShifted * 8);
|
||||
|
||||
// check for partial frame to override requested numSamples
|
||||
if ( partialFrame != 0 )
|
||||
{
|
||||
numSamples = BitBufferRead( bits, 16 ) << 16;
|
||||
numSamples |= BitBufferRead( bits, 16 );
|
||||
}
|
||||
|
||||
if ( escapeFlag == 0 )
|
||||
{
|
||||
// compressed frame, read rest of parameters
|
||||
mixBits = (uint8_t) BitBufferRead( bits, 8 );
|
||||
mixRes = (int8_t) BitBufferRead( bits, 8 );
|
||||
//Assert( (mixBits == 0) && (mixRes == 0) ); // no mixing for mono
|
||||
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 8 );
|
||||
modeU = headerByte >> 4;
|
||||
denShiftU = headerByte & 0xfu;
|
||||
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 8 );
|
||||
pbFactorU = headerByte >> 5;
|
||||
numU = headerByte & 0x1fu;
|
||||
|
||||
for ( i = 0; i < numU; i++ )
|
||||
coefsU[i] = (int16_t) BitBufferRead( bits, 16 );
|
||||
|
||||
// if shift active, skip the the shift buffer but remember where it starts
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
shiftBits = *bits;
|
||||
BitBufferAdvance( bits, (bytesShifted * 8) * numSamples );
|
||||
}
|
||||
|
||||
// decompress
|
||||
set_ag_params( &agParams, p->mConfig.mb, (pb * pbFactorU) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun );
|
||||
status = dyn_decomp( &agParams, bits, p->mPredictor, numSamples, chanBits, &bits1 );
|
||||
RequireNoErr( status, goto Exit; );
|
||||
|
||||
if ( modeU == 0 )
|
||||
{
|
||||
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
|
||||
}
|
||||
else
|
||||
{
|
||||
// the special "numActive == 31" mode can be done in-place
|
||||
unpc_block( p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0 );
|
||||
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Assert( bytesShifted == 0 );
|
||||
|
||||
// uncompressed frame, copy data into the mix buffer to use common output code
|
||||
shift = 32 - chanBits;
|
||||
if ( chanBits <= 16 )
|
||||
{
|
||||
for ( i = 0; i < numSamples; i++ )
|
||||
{
|
||||
val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits );
|
||||
val = (val << shift) >> shift;
|
||||
p->mMixBufferU[i] = val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// BitBufferRead() can't read more than 16 bits at a time so break up the reads
|
||||
extraBits = chanBits - 16;
|
||||
for ( i = 0; i < numSamples; i++ )
|
||||
{
|
||||
val = (int32_t) BitBufferRead( bits, 16 );
|
||||
val = (val << 16) >> shift;
|
||||
p->mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t) extraBits );
|
||||
}
|
||||
}
|
||||
|
||||
mixBits = mixRes = 0;
|
||||
bits1 = chanBits * numSamples;
|
||||
bytesShifted = 0;
|
||||
}
|
||||
|
||||
// now read the shifted values into the shift buffer
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
shift = bytesShifted * 8;
|
||||
//Assert( shift <= 16 );
|
||||
|
||||
for ( i = 0; i < numSamples; i++ )
|
||||
p->mShiftBuffer[i] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift );
|
||||
}
|
||||
|
||||
// convert 32-bit integers into output buffer
|
||||
switch ( p->mConfig.bitDepth )
|
||||
{
|
||||
case 16:
|
||||
out16 = &((int16_t *)sampleBuffer)[channelIndex];
|
||||
for ( i = 0, j = 0; i < numSamples; i++, j += numChannels )
|
||||
out16[j] = (int16_t) p->mMixBufferU[i];
|
||||
break;
|
||||
case 20:
|
||||
out20 = (uint8_t *)sampleBuffer + (channelIndex * 3);
|
||||
copyPredictorTo20( p->mMixBufferU, out20, numChannels, numSamples );
|
||||
break;
|
||||
case 24:
|
||||
out24 = (uint8_t *)sampleBuffer + (channelIndex * 3);
|
||||
if ( bytesShifted != 0 )
|
||||
copyPredictorTo24Shift( p->mMixBufferU, p->mShiftBuffer, out24, numChannels, numSamples, bytesShifted );
|
||||
else
|
||||
copyPredictorTo24( p->mMixBufferU, out24, numChannels, numSamples );
|
||||
break;
|
||||
case 32:
|
||||
out32 = &((int32_t *)sampleBuffer)[channelIndex];
|
||||
if ( bytesShifted != 0 )
|
||||
copyPredictorTo32Shift( p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted );
|
||||
else
|
||||
copyPredictorTo32( p->mMixBufferU, out32, numChannels, numSamples);
|
||||
break;
|
||||
}
|
||||
|
||||
channelIndex += 1;
|
||||
*outNumSamples = numSamples;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CPE:
|
||||
{
|
||||
// if decoding this pair would take us over the max channels limit, bail
|
||||
if ( (channelIndex + 2) > numChannels )
|
||||
goto NoMoreChannels;
|
||||
|
||||
// stereo channel pair
|
||||
elementInstanceTag = BitBufferReadSmall( bits, 4 );
|
||||
p->mActiveElements |= (1u << elementInstanceTag);
|
||||
|
||||
// read the 12 unused header bits
|
||||
unusedHeader = (uint16_t) BitBufferRead( bits, 12 );
|
||||
RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
// read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 4 );
|
||||
|
||||
partialFrame = headerByte >> 3;
|
||||
|
||||
bytesShifted = (headerByte >> 1) & 0x3u;
|
||||
RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; );
|
||||
|
||||
shift = bytesShifted * 8;
|
||||
|
||||
escapeFlag = headerByte & 0x1;
|
||||
|
||||
chanBits = p->mConfig.bitDepth - (bytesShifted * 8) + 1;
|
||||
|
||||
// check for partial frame length to override requested numSamples
|
||||
if ( partialFrame != 0 )
|
||||
{
|
||||
numSamples = BitBufferRead( bits, 16 ) << 16;
|
||||
numSamples |= BitBufferRead( bits, 16 );
|
||||
}
|
||||
|
||||
if ( escapeFlag == 0 )
|
||||
{
|
||||
// compressed frame, read rest of parameters
|
||||
mixBits = (uint8_t) BitBufferRead( bits, 8 );
|
||||
mixRes = (int8_t) BitBufferRead( bits, 8 );
|
||||
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 8 );
|
||||
modeU = headerByte >> 4;
|
||||
denShiftU = headerByte & 0xfu;
|
||||
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 8 );
|
||||
pbFactorU = headerByte >> 5;
|
||||
numU = headerByte & 0x1fu;
|
||||
for ( i = 0; i < numU; i++ )
|
||||
coefsU[i] = (int16_t) BitBufferRead( bits, 16 );
|
||||
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 8 );
|
||||
modeV = headerByte >> 4;
|
||||
denShiftV = headerByte & 0xfu;
|
||||
|
||||
headerByte = (uint8_t) BitBufferRead( bits, 8 );
|
||||
pbFactorV = headerByte >> 5;
|
||||
numV = headerByte & 0x1fu;
|
||||
for ( i = 0; i < numV; i++ )
|
||||
coefsV[i] = (int16_t) BitBufferRead( bits, 16 );
|
||||
|
||||
// if shift active, skip the interleaved shifted values but remember where they start
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
shiftBits = *bits;
|
||||
BitBufferAdvance( bits, (bytesShifted * 8) * 2 * numSamples );
|
||||
}
|
||||
|
||||
// decompress and run predictor for "left" channel
|
||||
set_ag_params( &agParams, p->mConfig.mb, (pb * pbFactorU) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun );
|
||||
status = dyn_decomp( &agParams, bits, p->mPredictor, numSamples, chanBits, &bits1 );
|
||||
RequireNoErr( status, goto Exit; );
|
||||
|
||||
if ( modeU == 0 )
|
||||
{
|
||||
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
|
||||
}
|
||||
else
|
||||
{
|
||||
// the special "numActive == 31" mode can be done in-place
|
||||
unpc_block( p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0 );
|
||||
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
|
||||
}
|
||||
|
||||
// decompress and run predictor for "right" channel
|
||||
set_ag_params( &agParams, p->mConfig.mb, (pb * pbFactorV) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun );
|
||||
status = dyn_decomp( &agParams, bits, p->mPredictor, numSamples, chanBits, &bits2 );
|
||||
RequireNoErr( status, goto Exit; );
|
||||
|
||||
if ( modeV == 0 )
|
||||
{
|
||||
unpc_block( p->mPredictor, p->mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV );
|
||||
}
|
||||
else
|
||||
{
|
||||
// the special "numActive == 31" mode can be done in-place
|
||||
unpc_block( p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0 );
|
||||
unpc_block( p->mPredictor, p->mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Assert( bytesShifted == 0 );
|
||||
|
||||
// uncompressed frame, copy data into the mix buffers to use common output code
|
||||
chanBits = p->mConfig.bitDepth;
|
||||
shift = 32 - chanBits;
|
||||
if ( chanBits <= 16 )
|
||||
{
|
||||
for ( i = 0; i < numSamples; i++ )
|
||||
{
|
||||
val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits );
|
||||
val = (val << shift) >> shift;
|
||||
p->mMixBufferU[i] = val;
|
||||
|
||||
val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits );
|
||||
val = (val << shift) >> shift;
|
||||
p->mMixBufferV[i] = val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// BitBufferRead() can't read more than 16 bits at a time so break up the reads
|
||||
extraBits = chanBits - 16;
|
||||
for ( i = 0; i < numSamples; i++ )
|
||||
{
|
||||
val = (int32_t) BitBufferRead( bits, 16 );
|
||||
val = (val << 16) >> shift;
|
||||
p->mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t)extraBits );
|
||||
|
||||
val = (int32_t) BitBufferRead( bits, 16 );
|
||||
val = (val << 16) >> shift;
|
||||
p->mMixBufferV[i] = val | BitBufferRead( bits, (uint8_t)extraBits );
|
||||
}
|
||||
}
|
||||
|
||||
bits1 = chanBits * numSamples;
|
||||
bits2 = chanBits * numSamples;
|
||||
mixBits = mixRes = 0;
|
||||
bytesShifted = 0;
|
||||
}
|
||||
|
||||
// now read the shifted values into the shift buffer
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
shift = bytesShifted * 8;
|
||||
//Assert( shift <= 16 );
|
||||
|
||||
for ( i = 0; i < (numSamples * 2); i += 2 )
|
||||
{
|
||||
p->mShiftBuffer[i + 0] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift );
|
||||
p->mShiftBuffer[i + 1] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift );
|
||||
}
|
||||
}
|
||||
|
||||
// un-mix the data and convert to output format
|
||||
// - note that mixRes = 0 means just interleave so we use that path for uncompressed frames
|
||||
switch ( p->mConfig.bitDepth )
|
||||
{
|
||||
case 16:
|
||||
out16 = &((int16_t *)sampleBuffer)[channelIndex];
|
||||
unmix16( p->mMixBufferU, p->mMixBufferV, out16, numChannels, numSamples, mixBits, mixRes );
|
||||
break;
|
||||
case 20:
|
||||
out20 = (uint8_t *)sampleBuffer + (channelIndex * 3);
|
||||
unmix20( p->mMixBufferU, p->mMixBufferV, out20, numChannels, numSamples, mixBits, mixRes );
|
||||
break;
|
||||
case 24:
|
||||
out24 = (uint8_t *)sampleBuffer + (channelIndex * 3);
|
||||
unmix24( p->mMixBufferU, p->mMixBufferV, out24, numChannels, numSamples,
|
||||
mixBits, mixRes, p->mShiftBuffer, bytesShifted );
|
||||
break;
|
||||
case 32:
|
||||
out32 = &((int32_t *)sampleBuffer)[channelIndex];
|
||||
unmix32( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
|
||||
mixBits, mixRes, p->mShiftBuffer, bytesShifted );
|
||||
break;
|
||||
}
|
||||
|
||||
channelIndex += 2;
|
||||
*outNumSamples = numSamples;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CCE:
|
||||
case ID_PCE:
|
||||
{
|
||||
// unsupported element, bail
|
||||
//AssertNoErr( tag );
|
||||
status = kALAC_ParamError;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_DSE:
|
||||
{
|
||||
// data stream element -- parse but ignore
|
||||
status = alac_data_stream_element (bits) ;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_FIL:
|
||||
{
|
||||
// fill element -- parse but ignore
|
||||
status = alac_fill_element (bits) ;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_END:
|
||||
{
|
||||
// frame end, all done so byte align the frame and check for overruns
|
||||
BitBufferByteAlign( bits, false );
|
||||
//Assert( bits->cur == bits->end );
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // ! DEBUG
|
||||
// if we've decoded all of our channels, bail (but not in debug b/c we want to know if we're seeing bad bits)
|
||||
// - this also protects us if the config does not match the bitstream or crap data bits follow the audio bits
|
||||
if ( channelIndex >= numChannels )
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
#if PRAGMA_MARK
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
/*
|
||||
FillElement()
|
||||
- they're just filler so we don't need 'em
|
||||
*/
|
||||
static int32_t
|
||||
alac_fill_element (struct BitBuffer * bits)
|
||||
{
|
||||
int16_t count;
|
||||
|
||||
// 4-bit count or (4-bit + 8-bit count) if 4-bit count == 15
|
||||
// - plus this weird -1 thing I still don't fully understand
|
||||
count = BitBufferReadSmall( bits, 4 );
|
||||
if ( count == 15 )
|
||||
count += (int16_t) BitBufferReadSmall( bits, 8 ) - 1;
|
||||
|
||||
BitBufferAdvance( bits, count * 8 );
|
||||
|
||||
RequireAction( bits->cur <= bits->end, return kALAC_ParamError; );
|
||||
|
||||
return ALAC_noErr;
|
||||
}
|
||||
|
||||
/*
|
||||
DataStreamElement()
|
||||
- we don't care about data stream elements so just skip them
|
||||
*/
|
||||
static int32_t
|
||||
alac_data_stream_element (struct BitBuffer * bits)
|
||||
{
|
||||
int32_t data_byte_align_flag;
|
||||
uint16_t count;
|
||||
|
||||
// the tag associates this data stream element with a given audio element
|
||||
|
||||
/* element_instance_tag = */ BitBufferReadSmall( bits, 4 );
|
||||
|
||||
data_byte_align_flag = BitBufferReadOne( bits );
|
||||
|
||||
// 8-bit count or (8-bit + 8-bit count) if 8-bit count == 255
|
||||
count = BitBufferReadSmall( bits, 8 );
|
||||
if ( count == 255 )
|
||||
count += BitBufferReadSmall( bits, 8 );
|
||||
|
||||
// the align flag means the bitstream should be byte-aligned before reading the following data bytes
|
||||
if ( data_byte_align_flag )
|
||||
BitBufferByteAlign( bits, false );
|
||||
|
||||
// skip the data bytes
|
||||
BitBufferAdvance( bits, count * 8 );
|
||||
|
||||
RequireAction( bits->cur <= bits->end, return kALAC_ParamError; );
|
||||
|
||||
return ALAC_noErr;
|
||||
}
|
||||
|
||||
/*
|
||||
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 )
|
||||
{
|
||||
memset( buffer, 0, numItems * sizeof(int32_t) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( uint32_t indx = 0; indx < (numItems * stride); indx += stride )
|
||||
buffer[indx] = 0;
|
||||
}
|
||||
}
|
61
src/ALAC/alac_decoder.h
Normal file
61
src/ALAC/alac_decoder.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: alac_decoder.h
|
||||
*/
|
||||
|
||||
#ifndef ALAC_DECODER_H
|
||||
#define ALAC_DECODER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
false = 0,
|
||||
ALAC_TRUE = 1
|
||||
} bool ;
|
||||
|
||||
struct BitBuffer;
|
||||
|
||||
typedef struct alac_decoder
|
||||
{
|
||||
// decoding parameters (public for use in the analyzer)
|
||||
ALACSpecificConfig mConfig;
|
||||
|
||||
uint16_t mActiveElements;
|
||||
|
||||
// decoding buffers
|
||||
int32_t * mMixBufferU;
|
||||
int32_t * mMixBufferV;
|
||||
int32_t * mPredictor;
|
||||
uint16_t * mShiftBuffer; // note: this points to mPredictor's memory but different
|
||||
// variable for clarity and type difference
|
||||
} alac_decoder ;
|
||||
|
||||
alac_decoder * alac_decoder_new (void) ;
|
||||
void alac_decoder_delete (alac_decoder *) ;
|
||||
|
||||
int32_t alac_init (alac_decoder *p, void * inMagicCookie, uint32_t inMagicCookieSize) ;
|
||||
int32_t alac_decode (alac_decoder *, struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples) ;
|
||||
|
||||
#endif /* ALAC_DECODER_H */
|
1358
src/ALAC/alac_encoder.c
Normal file
1358
src/ALAC/alac_encoder.c
Normal file
File diff suppressed because it is too large
Load Diff
98
src/ALAC/alac_encoder.h
Normal file
98
src/ALAC/alac_encoder.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: alac_encoder.h
|
||||
*/
|
||||
|
||||
#ifndef ALAC_ENCODER_H
|
||||
#define ALAC_ENCODER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ALACAudioTypes.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
false = 0,
|
||||
true = 1
|
||||
} bool ;
|
||||
|
||||
struct BitBuffer;
|
||||
|
||||
typedef struct alac_encoder
|
||||
{
|
||||
// ALAC encoder parameters
|
||||
int16_t mBitDepth;
|
||||
bool mFastMode;
|
||||
|
||||
// encoding state
|
||||
int16_t mLastMixRes[kALACMaxChannels];
|
||||
|
||||
// encoding buffers
|
||||
int32_t * mMixBufferU;
|
||||
int32_t * mMixBufferV;
|
||||
int32_t * mPredictorU;
|
||||
int32_t * mPredictorV;
|
||||
uint16_t * mShiftBufferUV;
|
||||
|
||||
uint8_t * mWorkBuffer;
|
||||
|
||||
// per-channel coefficients buffers
|
||||
int16_t mCoefsU[kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
|
||||
int16_t mCoefsV[kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
|
||||
|
||||
// encoding statistics
|
||||
uint32_t mTotalBytesGenerated;
|
||||
uint32_t mAvgBitRate;
|
||||
uint32_t mMaxFrameBytes;
|
||||
uint32_t mFrameSize;
|
||||
uint32_t mMaxOutputBytes;
|
||||
uint32_t mNumChannels;
|
||||
uint32_t mOutputSampleRate;
|
||||
} alac_encoder ;
|
||||
|
||||
alac_encoder * alac_encoder_new (void);
|
||||
void alac_encoder_delete (alac_encoder *);
|
||||
|
||||
int32_t Encode(alac_encoder *p, AudioFormatDescription theInputFormat,
|
||||
unsigned char * theReadBuffer, unsigned char * theWriteBuffer, int32_t * ioNumBytes);
|
||||
int32_t Finish(void);
|
||||
|
||||
static inline void
|
||||
SetFastMode(alac_encoder * p, bool fast ) { p->mFastMode = fast; }
|
||||
|
||||
// this must be called *before* InitializeEncoder()
|
||||
static inline void
|
||||
SetFrameSize(alac_encoder *p, uint32_t frameSize ) { p->mFrameSize = frameSize; }
|
||||
|
||||
void GetConfig(alac_encoder *p, ALACSpecificConfig * config );
|
||||
uint32_t GetMagicCookieSize(uint32_t inNumChannels);
|
||||
void GetMagicCookie(alac_encoder *p, void * config, uint32_t * ioSize );
|
||||
|
||||
int32_t InitializeEncoder(alac_encoder *p, AudioFormatDescription theOutputFormat);
|
||||
void GetSourceFormat(alac_encoder *p, const AudioFormatDescription * source, AudioFormatDescription * output );
|
||||
|
||||
int32_t EncodeStereo(alac_encoder *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
|
||||
int32_t EncodeStereoFast(alac_encoder *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
|
||||
int32_t EncodeStereoEscape(alac_encoder *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t numSamples );
|
||||
int32_t EncodeMono(alac_encoder *p, struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
|
||||
|
||||
#endif
|
375
src/ALAC/dp_dec.c
Normal file
375
src/ALAC/dp_dec.c
Normal file
@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: dp_dec.c
|
||||
|
||||
Contains: Dynamic Predictor decode routines
|
||||
|
||||
Copyright: (c) 2001-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include "dplib.h"
|
||||
#include <string.h>
|
||||
|
||||
#if __GNUC__
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
#define LOOP_ALIGN
|
||||
|
||||
static inline int32_t ALWAYS_INLINE sign_of_int( int32_t i )
|
||||
{
|
||||
int32_t negishift;
|
||||
|
||||
negishift = ((uint32_t)-i) >> 31;
|
||||
return negishift | (i >> 31);
|
||||
}
|
||||
|
||||
void unpc_block( int32_t * pc1, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift )
|
||||
{
|
||||
register int16_t a0, a1, a2, a3;
|
||||
register int32_t b0, b1, b2, b3;
|
||||
int32_t j, k, lim;
|
||||
int32_t sum1, sg, sgn, top, dd;
|
||||
int32_t * pout;
|
||||
int32_t del, del0;
|
||||
uint32_t chanshift = 32 - chanbits;
|
||||
int32_t denhalf = 1<<(denshift-1);
|
||||
|
||||
out[0] = pc1[0];
|
||||
if ( numactive == 0 )
|
||||
{
|
||||
// just copy if numactive == 0 (but don't bother if in/out pointers the same)
|
||||
if ( (num > 1) && (pc1 != out) )
|
||||
memcpy( &out[1], &pc1[1], (num - 1) * sizeof(int32_t) );
|
||||
return;
|
||||
}
|
||||
if ( numactive == 31 )
|
||||
{
|
||||
// short-circuit if numactive == 31
|
||||
int32_t prev;
|
||||
|
||||
/* this code is written such that the in/out buffers can be the same
|
||||
to conserve buffer space on embedded devices like the iPod
|
||||
|
||||
(original code)
|
||||
for ( j = 1; j < num; j++ )
|
||||
del = pc1[j] + out[j-1];
|
||||
out[j] = (del << chanshift) >> chanshift;
|
||||
*/
|
||||
prev = out[0];
|
||||
for ( j = 1; j < num; j++ )
|
||||
{
|
||||
del = pc1[j] + prev;
|
||||
prev = (del << chanshift) >> chanshift;
|
||||
out[j] = prev;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for ( j = 1; j <= numactive; j++ )
|
||||
{
|
||||
del = pc1[j] + out[j-1];
|
||||
out[j] = (del << chanshift) >> chanshift;
|
||||
}
|
||||
|
||||
lim = numactive + 1;
|
||||
|
||||
if ( numactive == 4 )
|
||||
{
|
||||
// optimization for numactive == 4
|
||||
register int16_t ia0, ia1, ia2, ia3;
|
||||
register int32_t ib0, ib1, ib2, ib3;
|
||||
|
||||
ia0 = coefs[0];
|
||||
ia1 = coefs[1];
|
||||
ia2 = coefs[2];
|
||||
ia3 = coefs[3];
|
||||
|
||||
for ( j = lim; j < num; j++ )
|
||||
{
|
||||
LOOP_ALIGN
|
||||
|
||||
top = out[j - lim];
|
||||
pout = out + j - 1;
|
||||
|
||||
ib0 = top - pout[0];
|
||||
ib1 = top - pout[-1];
|
||||
ib2 = top - pout[-2];
|
||||
ib3 = top - pout[-3];
|
||||
|
||||
sum1 = (denhalf - ia0 * ib0 - ia1 * ib1 - ia2 * ib2 - ia3 * ib3) >> denshift;
|
||||
|
||||
del = pc1[j];
|
||||
del0 = del;
|
||||
sg = sign_of_int(del);
|
||||
del += top + sum1;
|
||||
|
||||
out[j] = (del << chanshift) >> chanshift;
|
||||
|
||||
if ( sg > 0 )
|
||||
{
|
||||
sgn = sign_of_int( ib3 );
|
||||
ia3 -= sgn;
|
||||
del0 -= (4 - 3) * ((sgn * ib3) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( ib2 );
|
||||
ia2 -= sgn;
|
||||
del0 -= (4 - 2) * ((sgn * ib2) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( ib1 );
|
||||
ia1 -= sgn;
|
||||
del0 -= (4 - 1) * ((sgn * ib1) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
ia0 -= sign_of_int( ib0 );
|
||||
}
|
||||
else if ( sg < 0 )
|
||||
{
|
||||
// note: to avoid unnecessary negations, we flip the value of "sgn"
|
||||
sgn = -sign_of_int( ib3 );
|
||||
ia3 -= sgn;
|
||||
del0 -= (4 - 3) * ((sgn * ib3) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( ib2 );
|
||||
ia2 -= sgn;
|
||||
del0 -= (4 - 2) * ((sgn * ib2) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( ib1 );
|
||||
ia1 -= sgn;
|
||||
del0 -= (4 - 1) * ((sgn * ib1) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
ia0 += sign_of_int( ib0 );
|
||||
}
|
||||
}
|
||||
|
||||
coefs[0] = ia0;
|
||||
coefs[1] = ia1;
|
||||
coefs[2] = ia2;
|
||||
coefs[3] = ia3;
|
||||
}
|
||||
else if ( numactive == 8 )
|
||||
{
|
||||
register int16_t a4, a5, a6, a7;
|
||||
register int32_t b4, b5, b6, b7;
|
||||
|
||||
// optimization for numactive == 8
|
||||
a0 = coefs[0];
|
||||
a1 = coefs[1];
|
||||
a2 = coefs[2];
|
||||
a3 = coefs[3];
|
||||
a4 = coefs[4];
|
||||
a5 = coefs[5];
|
||||
a6 = coefs[6];
|
||||
a7 = coefs[7];
|
||||
|
||||
for ( j = lim; j < num; j++ )
|
||||
{
|
||||
LOOP_ALIGN
|
||||
|
||||
top = out[j - lim];
|
||||
pout = out + j - 1;
|
||||
|
||||
b0 = top - (*pout--);
|
||||
b1 = top - (*pout--);
|
||||
b2 = top - (*pout--);
|
||||
b3 = top - (*pout--);
|
||||
b4 = top - (*pout--);
|
||||
b5 = top - (*pout--);
|
||||
b6 = top - (*pout--);
|
||||
b7 = top - (*pout);
|
||||
pout += 8;
|
||||
|
||||
sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
|
||||
- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift;
|
||||
|
||||
del = pc1[j];
|
||||
del0 = del;
|
||||
sg = sign_of_int(del);
|
||||
del += top + sum1;
|
||||
|
||||
out[j] = (del << chanshift) >> chanshift;
|
||||
|
||||
if ( sg > 0 )
|
||||
{
|
||||
sgn = sign_of_int( b7 );
|
||||
a7 -= sgn;
|
||||
del0 -= 1 * ((sgn * b7) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b6 );
|
||||
a6 -= sgn;
|
||||
del0 -= 2 * ((sgn * b6) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b5 );
|
||||
a5 -= sgn;
|
||||
del0 -= 3 * ((sgn * b5) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b4 );
|
||||
a4 -= sgn;
|
||||
del0 -= 4 * ((sgn * b4) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b3 );
|
||||
a3 -= sgn;
|
||||
del0 -= 5 * ((sgn * b3) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b2 );
|
||||
a2 -= sgn;
|
||||
del0 -= 6 * ((sgn * b2) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b1 );
|
||||
a1 -= sgn;
|
||||
del0 -= 7 * ((sgn * b1) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
a0 -= sign_of_int( b0 );
|
||||
}
|
||||
else if ( sg < 0 )
|
||||
{
|
||||
// note: to avoid unnecessary negations, we flip the value of "sgn"
|
||||
sgn = -sign_of_int( b7 );
|
||||
a7 -= sgn;
|
||||
del0 -= 1 * ((sgn * b7) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b6 );
|
||||
a6 -= sgn;
|
||||
del0 -= 2 * ((sgn * b6) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b5 );
|
||||
a5 -= sgn;
|
||||
del0 -= 3 * ((sgn * b5) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b4 );
|
||||
a4 -= sgn;
|
||||
del0 -= 4 * ((sgn * b4) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b3 );
|
||||
a3 -= sgn;
|
||||
del0 -= 5 * ((sgn * b3) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b2 );
|
||||
a2 -= sgn;
|
||||
del0 -= 6 * ((sgn * b2) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b1 );
|
||||
a1 -= sgn;
|
||||
del0 -= 7 * ((sgn * b1) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
a0 += sign_of_int( b0 );
|
||||
}
|
||||
}
|
||||
|
||||
coefs[0] = a0;
|
||||
coefs[1] = a1;
|
||||
coefs[2] = a2;
|
||||
coefs[3] = a3;
|
||||
coefs[4] = a4;
|
||||
coefs[5] = a5;
|
||||
coefs[6] = a6;
|
||||
coefs[7] = a7;
|
||||
}
|
||||
else
|
||||
{
|
||||
// general case
|
||||
for ( j = lim; j < num; j++ )
|
||||
{
|
||||
LOOP_ALIGN
|
||||
|
||||
sum1 = 0;
|
||||
pout = out + j - 1;
|
||||
top = out[j-lim];
|
||||
|
||||
for ( k = 0; k < numactive; k++ )
|
||||
sum1 += coefs[k] * (pout[-k] - top);
|
||||
|
||||
del = pc1[j];
|
||||
del0 = del;
|
||||
sg = sign_of_int( del );
|
||||
del += top + ((sum1 + denhalf) >> denshift);
|
||||
out[j] = (del << chanshift) >> chanshift;
|
||||
|
||||
if ( sg > 0 )
|
||||
{
|
||||
for ( k = (numactive - 1); k >= 0; k-- )
|
||||
{
|
||||
dd = top - pout[-k];
|
||||
sgn = sign_of_int( dd );
|
||||
coefs[k] -= sgn;
|
||||
del0 -= (numactive - k) * ((sgn * dd) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( sg < 0 )
|
||||
{
|
||||
for ( k = (numactive - 1); k >= 0; k-- )
|
||||
{
|
||||
dd = top - pout[-k];
|
||||
sgn = sign_of_int( dd );
|
||||
coefs[k] += sgn;
|
||||
del0 -= (numactive - k) * ((-sgn * dd) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
380
src/ALAC/dp_enc.c
Normal file
380
src/ALAC/dp_enc.c
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: dp_enc.c
|
||||
|
||||
Contains: Dynamic Predictor encode routines
|
||||
|
||||
Copyright: (c) 2001-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#include "dplib.h"
|
||||
#include <string.h>
|
||||
|
||||
#if __GNUC__
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
#define LOOP_ALIGN
|
||||
|
||||
void init_coefs( int16_t * coefs, uint32_t denshift, int32_t numPairs )
|
||||
{
|
||||
int32_t k;
|
||||
int32_t den = 1 << denshift;
|
||||
|
||||
coefs[0] = (AINIT * den) >> 4;
|
||||
coefs[1] = (BINIT * den) >> 4;
|
||||
coefs[2] = (CINIT * den) >> 4;
|
||||
for ( k = 3; k < numPairs; k++ )
|
||||
coefs[k] = 0;
|
||||
}
|
||||
|
||||
void copy_coefs( int16_t * srcCoefs, int16_t * dstCoefs, int32_t numPairs )
|
||||
{
|
||||
int32_t k;
|
||||
|
||||
for ( k = 0; k < numPairs; k++ )
|
||||
dstCoefs[k] = srcCoefs[k];
|
||||
}
|
||||
|
||||
static inline int32_t ALWAYS_INLINE sign_of_int( int32_t i )
|
||||
{
|
||||
int32_t negishift;
|
||||
|
||||
negishift = ((uint32_t)-i) >> 31;
|
||||
return negishift | (i >> 31);
|
||||
}
|
||||
|
||||
void pc_block( int32_t * in, int32_t * pc1, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift )
|
||||
{
|
||||
register int16_t a0, a1, a2, a3;
|
||||
register int32_t b0, b1, b2, b3;
|
||||
int32_t j, k, lim;
|
||||
int32_t * pin;
|
||||
int32_t sum1, dd;
|
||||
int32_t sg, sgn;
|
||||
int32_t top;
|
||||
int32_t del, del0;
|
||||
uint32_t chanshift = 32 - chanbits;
|
||||
int32_t denhalf = 1 << (denshift - 1);
|
||||
|
||||
pc1[0] = in[0];
|
||||
if ( numactive == 0 )
|
||||
{
|
||||
// just copy if numactive == 0 (but don't bother if in/out pointers the same)
|
||||
if ( (num > 1) && (in != pc1) )
|
||||
memcpy( &pc1[1], &in[1], (num - 1) * sizeof(int32_t) );
|
||||
return;
|
||||
}
|
||||
if ( numactive == 31 )
|
||||
{
|
||||
// short-circuit if numactive == 31
|
||||
for( j = 1; j < num; j++ )
|
||||
{
|
||||
del = in[j] - in[j-1];
|
||||
pc1[j] = (del << chanshift) >> chanshift;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for ( j = 1; j <= numactive; j++ )
|
||||
{
|
||||
del = in[j] - in[j-1];
|
||||
pc1[j] = (del << chanshift) >> chanshift;
|
||||
}
|
||||
|
||||
lim = numactive + 1;
|
||||
|
||||
if ( numactive == 4 )
|
||||
{
|
||||
// optimization for numactive == 4
|
||||
a0 = coefs[0];
|
||||
a1 = coefs[1];
|
||||
a2 = coefs[2];
|
||||
a3 = coefs[3];
|
||||
|
||||
for ( j = lim; j < num; j++ )
|
||||
{
|
||||
LOOP_ALIGN
|
||||
|
||||
top = in[j - lim];
|
||||
pin = in + j - 1;
|
||||
|
||||
b0 = top - pin[0];
|
||||
b1 = top - pin[-1];
|
||||
b2 = top - pin[-2];
|
||||
b3 = top - pin[-3];
|
||||
|
||||
sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3) >> denshift;
|
||||
|
||||
del = in[j] - top - sum1;
|
||||
del = (del << chanshift) >> chanshift;
|
||||
pc1[j] = del;
|
||||
del0 = del;
|
||||
|
||||
sg = sign_of_int(del);
|
||||
if ( sg > 0 )
|
||||
{
|
||||
sgn = sign_of_int( b3 );
|
||||
a3 -= sgn;
|
||||
del0 -= (4 - 3) * ((sgn * b3) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b2 );
|
||||
a2 -= sgn;
|
||||
del0 -= (4 - 2) * ((sgn * b2) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b1 );
|
||||
a1 -= sgn;
|
||||
del0 -= (4 - 1) * ((sgn * b1) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
a0 -= sign_of_int( b0 );
|
||||
}
|
||||
else if ( sg < 0 )
|
||||
{
|
||||
// note: to avoid unnecessary negations, we flip the value of "sgn"
|
||||
sgn = -sign_of_int( b3 );
|
||||
a3 -= sgn;
|
||||
del0 -= (4 - 3) * ((sgn * b3) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b2 );
|
||||
a2 -= sgn;
|
||||
del0 -= (4 - 2) * ((sgn * b2) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b1 );
|
||||
a1 -= sgn;
|
||||
del0 -= (4 - 1) * ((sgn * b1) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
a0 += sign_of_int( b0 );
|
||||
}
|
||||
}
|
||||
|
||||
coefs[0] = a0;
|
||||
coefs[1] = a1;
|
||||
coefs[2] = a2;
|
||||
coefs[3] = a3;
|
||||
}
|
||||
else if ( numactive == 8 )
|
||||
{
|
||||
// optimization for numactive == 8
|
||||
register int16_t a4, a5, a6, a7;
|
||||
register int32_t b4, b5, b6, b7;
|
||||
|
||||
a0 = coefs[0];
|
||||
a1 = coefs[1];
|
||||
a2 = coefs[2];
|
||||
a3 = coefs[3];
|
||||
a4 = coefs[4];
|
||||
a5 = coefs[5];
|
||||
a6 = coefs[6];
|
||||
a7 = coefs[7];
|
||||
|
||||
for ( j = lim; j < num; j++ )
|
||||
{
|
||||
LOOP_ALIGN
|
||||
|
||||
top = in[j - lim];
|
||||
pin = in + j - 1;
|
||||
|
||||
b0 = top - (*pin--);
|
||||
b1 = top - (*pin--);
|
||||
b2 = top - (*pin--);
|
||||
b3 = top - (*pin--);
|
||||
b4 = top - (*pin--);
|
||||
b5 = top - (*pin--);
|
||||
b6 = top - (*pin--);
|
||||
b7 = top - (*pin);
|
||||
pin += 8;
|
||||
|
||||
sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
|
||||
- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift;
|
||||
|
||||
del = in[j] - top - sum1;
|
||||
del = (del << chanshift) >> chanshift;
|
||||
pc1[j] = del;
|
||||
del0 = del;
|
||||
|
||||
sg = sign_of_int(del);
|
||||
if ( sg > 0 )
|
||||
{
|
||||
sgn = sign_of_int( b7 );
|
||||
a7 -= sgn;
|
||||
del0 -= 1 * ((sgn * b7) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b6 );
|
||||
a6 -= sgn;
|
||||
del0 -= 2 * ((sgn * b6) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b5 );
|
||||
a5 -= sgn;
|
||||
del0 -= 3 * ((sgn * b5) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b4 );
|
||||
a4 -= sgn;
|
||||
del0 -= 4 * ((sgn * b4) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b3 );
|
||||
a3 -= sgn;
|
||||
del0 -= 5 * ((sgn * b3) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b2 );
|
||||
a2 -= sgn;
|
||||
del0 -= 6 * ((sgn * b2) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
sgn = sign_of_int( b1 );
|
||||
a1 -= sgn;
|
||||
del0 -= 7 * ((sgn * b1) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
continue;
|
||||
|
||||
a0 -= sign_of_int( b0 );
|
||||
}
|
||||
else if ( sg < 0 )
|
||||
{
|
||||
// note: to avoid unnecessary negations, we flip the value of "sgn"
|
||||
sgn = -sign_of_int( b7 );
|
||||
a7 -= sgn;
|
||||
del0 -= 1 * ((sgn * b7) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b6 );
|
||||
a6 -= sgn;
|
||||
del0 -= 2 * ((sgn * b6) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b5 );
|
||||
a5 -= sgn;
|
||||
del0 -= 3 * ((sgn * b5) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b4 );
|
||||
a4 -= sgn;
|
||||
del0 -= 4 * ((sgn * b4) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b3 );
|
||||
a3 -= sgn;
|
||||
del0 -= 5 * ((sgn * b3) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b2 );
|
||||
a2 -= sgn;
|
||||
del0 -= 6 * ((sgn * b2) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
sgn = -sign_of_int( b1 );
|
||||
a1 -= sgn;
|
||||
del0 -= 7 * ((sgn * b1) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
continue;
|
||||
|
||||
a0 += sign_of_int( b0 );
|
||||
}
|
||||
}
|
||||
|
||||
coefs[0] = a0;
|
||||
coefs[1] = a1;
|
||||
coefs[2] = a2;
|
||||
coefs[3] = a3;
|
||||
coefs[4] = a4;
|
||||
coefs[5] = a5;
|
||||
coefs[6] = a6;
|
||||
coefs[7] = a7;
|
||||
}
|
||||
else
|
||||
{
|
||||
//pc_block_general:
|
||||
// general case
|
||||
for ( j = lim; j < num; j++ )
|
||||
{
|
||||
LOOP_ALIGN
|
||||
|
||||
top = in[j - lim];
|
||||
pin = in + j - 1;
|
||||
|
||||
sum1 = 0;
|
||||
for ( k = 0; k < numactive; k++ )
|
||||
sum1 -= coefs[k] * (top - pin[-k]);
|
||||
|
||||
del = in[j] - top - ((sum1 + denhalf) >> denshift);
|
||||
del = (del << chanshift) >> chanshift;
|
||||
pc1[j] = del;
|
||||
del0 = del;
|
||||
|
||||
sg = sign_of_int( del );
|
||||
if ( sg > 0 )
|
||||
{
|
||||
for ( k = (numactive - 1); k >= 0; k-- )
|
||||
{
|
||||
dd = top - pin[-k];
|
||||
sgn = sign_of_int( dd );
|
||||
coefs[k] -= sgn;
|
||||
del0 -= (numactive - k) * ((sgn * dd) >> denshift);
|
||||
if ( del0 <= 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( sg < 0 )
|
||||
{
|
||||
for ( k = (numactive - 1); k >= 0; k-- )
|
||||
{
|
||||
dd = top - pin[-k];
|
||||
sgn = sign_of_int( dd );
|
||||
coefs[k] += sgn;
|
||||
del0 -= (numactive - k) * ((-sgn * dd) >> denshift);
|
||||
if ( del0 >= 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
src/ALAC/dplib.h
Normal file
61
src/ALAC/dplib.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: dplib.h
|
||||
|
||||
Contains: Dynamic Predictor routines
|
||||
|
||||
Copyright: Copyright (C) 2001-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __DPLIB_H__
|
||||
#define __DPLIB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// defines
|
||||
|
||||
#define DENSHIFT_MAX 15
|
||||
#define DENSHIFT_DEFAULT 9
|
||||
#define AINIT 38
|
||||
#define BINIT (-29)
|
||||
#define CINIT (-2)
|
||||
#define NUMCOEPAIRS 16
|
||||
|
||||
// prototypes
|
||||
|
||||
void init_coefs( int16_t * coefs, uint32_t denshift, int32_t numPairs );
|
||||
void copy_coefs( int16_t * srcCoefs, int16_t * dstCoefs, int32_t numPairs );
|
||||
|
||||
// NOTE: these routines read at least "numactive" samples so the i/o buffers must be at least that big
|
||||
|
||||
void pc_block( int32_t * in, int32_t * pc, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift );
|
||||
void unpc_block( int32_t * pc, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DPLIB_H__ */
|
390
src/ALAC/matrix_dec.c
Normal file
390
src/ALAC/matrix_dec.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: matrix_dec.c
|
||||
|
||||
Contains: ALAC mixing/matrixing decode routines.
|
||||
|
||||
Copyright: (c) 2004-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#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()
|
||||
and unmix() functions. These functions exploit a generalized middle-side
|
||||
transformation:
|
||||
|
||||
u := [(rL + (m-r)R)/m];
|
||||
v := L - R;
|
||||
|
||||
where [ ] denotes integer floor. The (lossless) inverse is
|
||||
|
||||
L = u + v - [rV/m];
|
||||
R = L - v;
|
||||
*/
|
||||
|
||||
// 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 )
|
||||
{
|
||||
int16_t * op = out;
|
||||
int32_t j;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
/* matrixed stereo */
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
int32_t l, r;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conventional separated stereo. */
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
op[0] = (int16_t) u[j];
|
||||
op[1] = (int16_t) v[j];
|
||||
op += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
uint8_t * op = out;
|
||||
int32_t j;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
/* matrixed stereo */
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
int32_t l, r;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
|
||||
{
|
||||
uint8_t * op = out;
|
||||
int32_t shift = bytesShifted * 8;
|
||||
int32_t l, r;
|
||||
int32_t j, k;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
/* matrixed stereo */
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
|
||||
{
|
||||
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
|
||||
r = l - v[j];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conventional separated stereo. */
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
|
||||
{
|
||||
l = u[j];
|
||||
r = v[j];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 32-bit routines
|
||||
// - note that these really expect the internal data width to be < 32 but the arrays are 32-bit
|
||||
// - otherwise, the calculations might overflow into the 33rd bit and be lost
|
||||
// - therefore, these routines deal with the specified "unused lower" bytes in the "shift" buffers
|
||||
|
||||
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 l, r;
|
||||
int32_t j, k;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
//Assert( bytesShifted != 0 );
|
||||
|
||||
/* matrixed stereo with shift */
|
||||
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
|
||||
{
|
||||
int32_t lt, rt;
|
||||
|
||||
lt = u[j];
|
||||
rt = v[j];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bytesShifted == 0 )
|
||||
{
|
||||
/* interleaving w/o shift */
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
op[0] = u[j];
|
||||
op[1] = v[j];
|
||||
op += stride;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
uint8_t * op = out;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, uint8_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted )
|
||||
{
|
||||
uint8_t * op = out;
|
||||
int32_t shiftVal = bytesShifted * 8;
|
||||
int32_t j;
|
||||
|
||||
//Assert( bytesShifted != 0 );
|
||||
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void copyPredictorTo20( int32_t * in, uint8_t * out, uint32_t stride, int32_t numSamples )
|
||||
{
|
||||
uint8_t * op = out;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples )
|
||||
{
|
||||
int32_t i, j;
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
//Assert( bytesShifted != 0 );
|
||||
|
||||
// this is only a subroutine to abstract the "iPod can only output 16-bit data" problem
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
op[0] = (in[j] << shiftVal) | (uint32_t) shift[j];
|
||||
op += stride;
|
||||
}
|
||||
}
|
342
src/ALAC/matrix_enc.c
Normal file
342
src/ALAC/matrix_enc.c
Normal file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: matrix_enc.c
|
||||
|
||||
Contains: ALAC mixing/matrixing encode routines.
|
||||
|
||||
Copyright: (c) 2004-2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#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()
|
||||
and unmix() functions. These functions exploit a generalized middle-side
|
||||
transformation:
|
||||
|
||||
u := [(rL + (m-r)R)/m];
|
||||
v := L - R;
|
||||
|
||||
where [ ] denotes integer floor. The (lossless) inverse is
|
||||
|
||||
L = u + v - [rV/m];
|
||||
R = L - v;
|
||||
*/
|
||||
|
||||
// 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 )
|
||||
{
|
||||
int16_t * ip = in;
|
||||
int32_t j;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
int32_t mod = 1 << mixbits;
|
||||
int32_t m2;
|
||||
|
||||
/* matrixed stereo */
|
||||
m2 = mod - mixres;
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
int32_t l, r;
|
||||
|
||||
l = (int32_t) ip[0];
|
||||
r = (int32_t) ip[1];
|
||||
ip += stride;
|
||||
u[j] = (mixres * l + m2 * r) >> mixbits;
|
||||
v[j] = l - r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conventional separated stereo. */
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
u[j] = (int32_t) ip[0];
|
||||
v[j] = (int32_t) ip[1];
|
||||
ip += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
int32_t l, r;
|
||||
uint8_t * ip = in;
|
||||
int32_t j;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
/* matrixed stereo */
|
||||
int32_t mod = 1 << mixbits;
|
||||
int32_t m2 = mod - mixres;
|
||||
|
||||
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;
|
||||
|
||||
u[j] = (mixres * l + m2 * r) >> mixbits;
|
||||
v[j] = l - r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
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;
|
||||
uint32_t mask = (1ul << shift) - 1;
|
||||
int32_t j, k;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
/* matrixed stereo */
|
||||
int32_t mod = 1 << mixbits;
|
||||
int32_t m2 = mod - mixres;
|
||||
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
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;
|
||||
|
||||
shiftUV[k + 0] = (uint16_t)(l & mask);
|
||||
shiftUV[k + 1] = (uint16_t)(r & mask);
|
||||
|
||||
l >>= shift;
|
||||
r >>= shift;
|
||||
|
||||
u[j] = (mixres * l + m2 * r) >> mixbits;
|
||||
v[j] = l - r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
u[j] = (mixres * l + m2 * r) >> mixbits;
|
||||
v[j] = l - r;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conventional separated stereo. */
|
||||
if ( bytesShifted != 0 )
|
||||
{
|
||||
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;
|
||||
|
||||
shiftUV[k + 0] = (uint16_t)(l & mask);
|
||||
shiftUV[k + 1] = (uint16_t)(r & mask);
|
||||
|
||||
l >>= shift;
|
||||
r >>= shift;
|
||||
|
||||
u[j] = l;
|
||||
v[j] = r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 32-bit routines
|
||||
// - note that these really expect the internal data width to be < 32 but the arrays are 32-bit
|
||||
// - otherwise, the calculations might overflow into the 33rd bit and be lost
|
||||
// - therefore, these routines deal with the specified "unused lower" bytes in the "shift" buffers
|
||||
|
||||
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;
|
||||
uint32_t mask = (1ul << shift) - 1;
|
||||
int32_t l, r;
|
||||
int32_t j, k;
|
||||
|
||||
if ( mixres != 0 )
|
||||
{
|
||||
int32_t mod = 1 << mixbits;
|
||||
int32_t m2;
|
||||
|
||||
//Assert( bytesShifted != 0 );
|
||||
|
||||
/* matrixed stereo with shift */
|
||||
m2 = mod - mixres;
|
||||
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
|
||||
{
|
||||
l = ip[0];
|
||||
r = ip[1];
|
||||
ip += stride;
|
||||
|
||||
shiftUV[k + 0] = (uint16_t)(l & mask);
|
||||
shiftUV[k + 1] = (uint16_t)(r & mask);
|
||||
|
||||
l >>= shift;
|
||||
r >>= shift;
|
||||
|
||||
u[j] = (mixres * l + m2 * r) >> mixbits;
|
||||
v[j] = l - r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bytesShifted == 0 )
|
||||
{
|
||||
/* de-interleaving w/o shift */
|
||||
for ( j = 0; j < numSamples; j++ )
|
||||
{
|
||||
u[j] = ip[0];
|
||||
v[j] = ip[1];
|
||||
ip += stride;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* de-interleaving with shift */
|
||||
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
|
||||
{
|
||||
l = ip[0];
|
||||
r = ip[1];
|
||||
ip += stride;
|
||||
|
||||
shiftUV[k + 0] = (uint16_t)(l & mask);
|
||||
shiftUV[k + 1] = (uint16_t)(r & mask);
|
||||
|
||||
l >>= shift;
|
||||
r >>= shift;
|
||||
|
||||
u[j] = l;
|
||||
v[j] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
80
src/ALAC/matrixlib.h
Normal file
80
src/ALAC/matrixlib.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
File: matrixlib.h
|
||||
|
||||
Contains: ALAC mixing/matrixing routines to/from 32-bit predictor buffers.
|
||||
|
||||
Copyright: Copyright (C) 2004 to 2011 Apple, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __MATRIXLIB_H
|
||||
#define __MATRIXLIB_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
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 );
|
||||
|
||||
// 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 );
|
||||
|
||||
// 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,
|
||||
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,
|
||||
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
|
||||
|
||||
// 32-bit routines
|
||||
// - note that these really expect the internal data width to be < 32-bit but the arrays are 32-bit
|
||||
// - otherwise, the calculations might overflow into the 33rd bit and be lost
|
||||
// - therefore, these routines deal with the specified "unused lower" bytes in the combined "shift" buffer
|
||||
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 );
|
||||
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 );
|
||||
|
||||
// 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 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 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 );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MATRIXLIB_H */
|
Loading…
x
Reference in New Issue
Block a user