/*
* Atrac 3 compatible decoder
- * Copyright (c) 2006-2007 Maxim Poliakovski
- * Copyright (c) 2006-2007 Benjamin Larsson
+ * Copyright (c) 2006-2008 Maxim Poliakovski
+ * Copyright (c) 2006-2008 Benjamin Larsson
*
* This file is part of FFmpeg.
*
/**
* @file atrac3.c
* Atrac 3 compatible decoder.
- * This decoder handles RealNetworks, RealAudio atrc data.
- * Atrac 3 is identified by the codec name atrc in RealMedia files.
+ * This decoder handles Sony's ATRAC3 data.
+ *
+ * Container formats used to store atrac 3 data:
+ * RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3).
*
* To use this decoder, a calling application must supply the extradata
- * bytes provided from the RealMedia container: 10 bytes or 14 bytes
- * from the WAV container.
+ * bytes provided in the containers above.
*/
#include <math.h>
* @param out pointer to 8 bit array of outdata
*/
-static int decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){
+static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){
int i, off;
uint32_t c;
- uint32_t* buf;
+ const uint32_t* buf;
uint32_t* obuf = (uint32_t*) out;
off = (int)((long)inbuffer & 3);
- buf = (uint32_t*) (inbuffer - off);
+ buf = (const uint32_t*) (inbuffer - off);
c = be2me_32((0x537F6103 >> (off*8)) | (0x537F6103 << (32-(off*8))));
bytes += 3 + off;
for (i = 0; i < bytes/4; i++)
pComponent[component_count].numCoefs = coded_values;
/* inverse quant */
- pCoef = pComponent[k].coef;
+ pCoef = pComponent[component_count].coef;
for (cnt = 0; cnt < coded_values; cnt++)
pCoef[cnt] = mantissa[cnt] * scalefactor;
/**
* Combine the tonal band spectrum and regular band spectrum
+ * Return position of the last tonal coefficient
*
* @param pSpectrum output spectrum buffer
* @param numComponents amount of tonal components
* @param pComponent tonal components for this band
*/
-static void addTonalComponents (float *pSpectrum, int numComponents, tonal_component *pComponent)
+static int addTonalComponents (float *pSpectrum, int numComponents, tonal_component *pComponent)
{
- int cnt, i;
+ int cnt, i, lastPos = -1;
float *pIn, *pOut;
for (cnt = 0; cnt < numComponents; cnt++){
+ lastPos = FFMAX(pComponent[cnt].pos + pComponent[cnt].numCoefs, lastPos);
pIn = pComponent[cnt].coef;
pOut = &(pSpectrum[pComponent[cnt].pos]);
for (i=0 ; i<pComponent[cnt].numCoefs ; i++)
pOut[i] += pIn[i];
}
+
+ return lastPos;
}
static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_unit *pSnd, float *pOut, int channelNum, int codingMode)
{
- int band, result=0, numSubbands, numBands;
+ int band, result=0, numSubbands, lastTonal, numBands;
if (codingMode == JOINT_STEREO && channelNum == 1) {
if (get_bits(gb,2) != 3) {
numSubbands = decodeSpectrum (gb, pSnd->spectrum);
/* Merge the decoded spectrum and tonal components. */
- addTonalComponents (pSnd->spectrum, pSnd->numComponents, pSnd->components);
+ lastTonal = addTonalComponents (pSnd->spectrum, pSnd->numComponents, pSnd->components);
- /* Convert number of subbands into number of MLT/QMF bands */
+ /* calculate number of used MLT/QMF bands according to the amount of coded spectral lines */
numBands = (subbandTab[numSubbands] - 1) >> 8;
+ if (lastTonal >= 0)
+ numBands = FFMAX((lastTonal + 256) >> 8, numBands);
/* Reconstruct time domain samples. */
static int atrac3_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
- uint8_t *buf, int buf_size) {
+ const uint8_t *buf, int buf_size) {
ATRAC3Context *q = avctx->priv_data;
int result = 0, i;
uint8_t* databuf;
if (q->channels == 1) {
/* mono */
for (i = 0; i<1024; i++)
- samples[i] = av_clip(round(q->outSamples[i]), -32768, 32767);
+ samples[i] = av_clip_int16(round(q->outSamples[i]));
*data_size = 1024 * sizeof(int16_t);
} else {
/* stereo */
for (i = 0; i < 1024; i++) {
- samples[i*2] = av_clip(round(q->outSamples[i]), -32768, 32767);
- samples[i*2+1] = av_clip(round(q->outSamples[1024+i]), -32768, 32767);
+ samples[i*2] = av_clip_int16(round(q->outSamples[i]));
+ samples[i*2+1] = av_clip_int16(round(q->outSamples[1024+i]));
}
*data_size = 2048 * sizeof(int16_t);
}
static int atrac3_decode_init(AVCodecContext *avctx)
{
int i;
- uint8_t *edata_ptr = avctx->extradata;
+ const uint8_t *edata_ptr = avctx->extradata;
ATRAC3Context *q = avctx->priv_data;
/* Take data from the AVCodecContext (RM container). */
AVCodec atrac3_decoder =
{
- .name = "atrac 3",
+ .name = "atrac3",
.type = CODEC_TYPE_AUDIO,
.id = CODEC_ID_ATRAC3,
.priv_data_size = sizeof(ATRAC3Context),
.init = atrac3_decode_init,
.close = atrac3_decode_close,
.decode = atrac3_decode_frame,
+ .long_name = "Atrac 3 (Adaptive TRansform Acoustic Coding 3)",
};