1/* 2 * ADX ADPCM codecs 3 * Copyright (c) 2001,2003 BERO 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/intreadwrite.h" 23#include "avcodec.h" 24#include "adx.h" 25 26/** 27 * @file 28 * SEGA CRI adx codecs. 29 * 30 * Reference documents: 31 * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html 32 * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ 33 */ 34 35static av_cold int adx_decode_init(AVCodecContext *avctx) 36{ 37 avctx->sample_fmt = SAMPLE_FMT_S16; 38 return 0; 39} 40 41/* 18 bytes <-> 32 samples */ 42 43static void adx_decode(short *out,const unsigned char *in,PREV *prev) 44{ 45 int scale = AV_RB16(in); 46 int i; 47 int s0,s1,s2,d; 48 49// printf("%x ",scale); 50 51 in+=2; 52 s1 = prev->s1; 53 s2 = prev->s2; 54 for(i=0;i<16;i++) { 55 d = in[i]; 56 // d>>=4; if (d&8) d-=16; 57 d = ((signed char)d >> 4); 58 s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; 59 s2 = s1; 60 s1 = av_clip_int16(s0); 61 *out++=s1; 62 63 d = in[i]; 64 //d&=15; if (d&8) d-=16; 65 d = ((signed char)(d<<4) >> 4); 66 s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; 67 s2 = s1; 68 s1 = av_clip_int16(s0); 69 *out++=s1; 70 } 71 prev->s1 = s1; 72 prev->s2 = s2; 73 74} 75 76static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) 77{ 78 short tmp[32*2]; 79 int i; 80 81 adx_decode(tmp ,in ,prev); 82 adx_decode(tmp+32,in+18,prev+1); 83 for(i=0;i<32;i++) { 84 out[i*2] = tmp[i]; 85 out[i*2+1] = tmp[i+32]; 86 } 87} 88 89/* return data offset or 0 */ 90static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) 91{ 92 int offset; 93 94 if (buf[0]!=0x80) return 0; 95 offset = (AV_RB32(buf)^0x80000000)+4; 96 if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0; 97 98 avctx->channels = buf[7]; 99 avctx->sample_rate = AV_RB32(buf+8); 100 avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; 101 102 return offset; 103} 104 105static int adx_decode_frame(AVCodecContext *avctx, 106 void *data, int *data_size, 107 AVPacket *avpkt) 108{ 109 const uint8_t *buf0 = avpkt->data; 110 int buf_size = avpkt->size; 111 ADXContext *c = avctx->priv_data; 112 short *samples = data; 113 const uint8_t *buf = buf0; 114 int rest = buf_size; 115 116 if (!c->header_parsed) { 117 int hdrsize = adx_decode_header(avctx,buf,rest); 118 if (hdrsize==0) return -1; 119 c->header_parsed = 1; 120 buf += hdrsize; 121 rest -= hdrsize; 122 } 123 124 /* 18 bytes of data are expanded into 32*2 bytes of audio, 125 so guard against buffer overflows */ 126 if(rest/18 > *data_size/64) 127 rest = (*data_size/64) * 18; 128 129 if (c->in_temp) { 130 int copysize = 18*avctx->channels - c->in_temp; 131 memcpy(c->dec_temp+c->in_temp,buf,copysize); 132 rest -= copysize; 133 buf += copysize; 134 if (avctx->channels==1) { 135 adx_decode(samples,c->dec_temp,c->prev); 136 samples += 32; 137 } else { 138 adx_decode_stereo(samples,c->dec_temp,c->prev); 139 samples += 32*2; 140 } 141 } 142 // 143 if (avctx->channels==1) { 144 while(rest>=18) { 145 adx_decode(samples,buf,c->prev); 146 rest-=18; 147 buf+=18; 148 samples+=32; 149 } 150 } else { 151 while(rest>=18*2) { 152 adx_decode_stereo(samples,buf,c->prev); 153 rest-=18*2; 154 buf+=18*2; 155 samples+=32*2; 156 } 157 } 158 // 159 c->in_temp = rest; 160 if (rest) { 161 memcpy(c->dec_temp,buf,rest); 162 buf+=rest; 163 } 164 *data_size = (uint8_t*)samples - (uint8_t*)data; 165// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); 166 return buf-buf0; 167} 168 169AVCodec adpcm_adx_decoder = { 170 "adpcm_adx", 171 AVMEDIA_TYPE_AUDIO, 172 CODEC_ID_ADPCM_ADX, 173 sizeof(ADXContext), 174 adx_decode_init, 175 NULL, 176 NULL, 177 adx_decode_frame, 178 .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), 179}; 180 181