00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023 #include "adx.h"
00024 #include "bytestream.h"
00025 #include "internal.h"
00026 #include "put_bits.h"
00027
00037 static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav,
00038 ADXChannelState *prev, int channels)
00039 {
00040 PutBitContext pb;
00041 int scale;
00042 int i, j;
00043 int s0, s1, s2, d;
00044 int max = 0;
00045 int min = 0;
00046 int data[BLOCK_SAMPLES];
00047
00048 s1 = prev->s1;
00049 s2 = prev->s2;
00050 for (i = 0, j = 0; j < 32; i += channels, j++) {
00051 s0 = wav[i];
00052 d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS;
00053 data[j] = d;
00054 if (max < d)
00055 max = d;
00056 if (min > d)
00057 min = d;
00058 s2 = s1;
00059 s1 = s0;
00060 }
00061 prev->s1 = s1;
00062 prev->s2 = s2;
00063
00064 if (max == 0 && min == 0) {
00065 memset(adx, 0, BLOCK_SIZE);
00066 return;
00067 }
00068
00069 if (max / 7 > -min / 8)
00070 scale = max / 7;
00071 else
00072 scale = -min / 8;
00073
00074 if (scale == 0)
00075 scale = 1;
00076
00077 AV_WB16(adx, scale);
00078
00079 init_put_bits(&pb, adx + 2, 16);
00080 for (i = 0; i < BLOCK_SAMPLES; i++)
00081 put_sbits(&pb, 4, av_clip(data[i] / scale, -8, 7));
00082 flush_put_bits(&pb);
00083 }
00084
00085 #define HEADER_SIZE 36
00086
00087 static int adx_encode_header(AVCodecContext *avctx, uint8_t *buf, int bufsize)
00088 {
00089 ADXContext *c = avctx->priv_data;
00090
00091 bytestream_put_be16(&buf, 0x8000);
00092 bytestream_put_be16(&buf, HEADER_SIZE - 4);
00093 bytestream_put_byte(&buf, 3);
00094 bytestream_put_byte(&buf, BLOCK_SIZE);
00095 bytestream_put_byte(&buf, 4);
00096 bytestream_put_byte(&buf, avctx->channels);
00097 bytestream_put_be32(&buf, avctx->sample_rate);
00098 bytestream_put_be32(&buf, 0);
00099 bytestream_put_be16(&buf, c->cutoff);
00100 bytestream_put_byte(&buf, 3);
00101 bytestream_put_byte(&buf, 0);
00102 bytestream_put_be32(&buf, 0);
00103 bytestream_put_be32(&buf, 0);
00104 bytestream_put_be16(&buf, 0);
00105 bytestream_put_buffer(&buf, "(c)CRI", 6);
00106
00107 return HEADER_SIZE;
00108 }
00109
00110 static av_cold int adx_encode_init(AVCodecContext *avctx)
00111 {
00112 ADXContext *c = avctx->priv_data;
00113
00114 if (avctx->channels > 2) {
00115 av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
00116 return AVERROR(EINVAL);
00117 }
00118 avctx->frame_size = BLOCK_SAMPLES;
00119
00120 #if FF_API_OLD_ENCODE_AUDIO
00121 avcodec_get_frame_defaults(&c->frame);
00122 avctx->coded_frame = &c->frame;
00123 #endif
00124
00125
00126 c->cutoff = 500;
00127 ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
00128
00129 return 0;
00130 }
00131
00132 static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
00133 const AVFrame *frame, int *got_packet_ptr)
00134 {
00135 ADXContext *c = avctx->priv_data;
00136 const int16_t *samples = (const int16_t *)frame->data[0];
00137 uint8_t *dst;
00138 int ch, out_size, ret;
00139
00140 out_size = BLOCK_SIZE * avctx->channels + !c->header_parsed * HEADER_SIZE;
00141 if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)) < 0)
00142 return ret;
00143 dst = avpkt->data;
00144
00145 if (!c->header_parsed) {
00146 int hdrsize;
00147 if ((hdrsize = adx_encode_header(avctx, dst, avpkt->size)) < 0) {
00148 av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
00149 return AVERROR(EINVAL);
00150 }
00151 dst += hdrsize;
00152 c->header_parsed = 1;
00153 }
00154
00155 for (ch = 0; ch < avctx->channels; ch++) {
00156 adx_encode(c, dst, samples + ch, &c->prev[ch], avctx->channels);
00157 dst += BLOCK_SIZE;
00158 }
00159
00160 *got_packet_ptr = 1;
00161 return 0;
00162 }
00163
00164 AVCodec ff_adpcm_adx_encoder = {
00165 .name = "adpcm_adx",
00166 .type = AVMEDIA_TYPE_AUDIO,
00167 .id = AV_CODEC_ID_ADPCM_ADX,
00168 .priv_data_size = sizeof(ADXContext),
00169 .init = adx_encode_init,
00170 .encode2 = adx_encode_frame,
00171 .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
00172 AV_SAMPLE_FMT_NONE },
00173 .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
00174 };