• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "avcodec.h"
23 #include "adx.h"
24 #include "bytestream.h"
25 #include "codec_internal.h"
26 #include "encode.h"
27 #include "put_bits.h"
28 
29 /**
30  * @file
31  * SEGA CRI adx codecs.
32  *
33  * Reference documents:
34  * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
35  * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
36  */
37 
adx_encode(ADXContext * c,uint8_t * adx,const int16_t * wav,ADXChannelState * prev,int channels)38 static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav,
39                        ADXChannelState *prev, int channels)
40 {
41     PutBitContext pb;
42     int scale;
43     int i, j;
44     int s0, s1, s2, d;
45     int max = 0;
46     int min = 0;
47 
48     s1 = prev->s1;
49     s2 = prev->s2;
50     for (i = 0, j = 0; j < 32; i += channels, j++) {
51         s0 = wav[i];
52         d = s0 + ((-c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS);
53         if (max < d)
54             max = d;
55         if (min > d)
56             min = d;
57         s2 = s1;
58         s1 = s0;
59     }
60 
61     if (max == 0 && min == 0) {
62         prev->s1 = s1;
63         prev->s2 = s2;
64         memset(adx, 0, BLOCK_SIZE);
65         return;
66     }
67 
68     if (max / 7 > -min / 8)
69         scale = max / 7;
70     else
71         scale = -min / 8;
72 
73     if (scale == 0)
74         scale = 1;
75 
76     AV_WB16(adx, scale);
77 
78     init_put_bits(&pb, adx + 2, 16);
79 
80     s1 = prev->s1;
81     s2 = prev->s2;
82     for (i = 0, j = 0; j < 32; i += channels, j++) {
83         d = wav[i] + ((-c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS);
84 
85         d = av_clip_intp2(ROUNDED_DIV(d, scale), 3);
86 
87         put_sbits(&pb, 4, d);
88 
89         s0 = d * scale + ((c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS);
90         s2 = s1;
91         s1 = s0;
92     }
93     prev->s1 = s1;
94     prev->s2 = s2;
95 
96     flush_put_bits(&pb);
97 }
98 
99 #define HEADER_SIZE 36
100 
adx_encode_header(AVCodecContext * avctx,uint8_t * buf,int bufsize)101 static int adx_encode_header(AVCodecContext *avctx, uint8_t *buf, int bufsize)
102 {
103     ADXContext *c = avctx->priv_data;
104 
105     bytestream_put_be16(&buf, 0x8000);              /* header signature */
106     bytestream_put_be16(&buf, HEADER_SIZE - 4);     /* copyright offset */
107     bytestream_put_byte(&buf, 3);                   /* encoding */
108     bytestream_put_byte(&buf, BLOCK_SIZE);          /* block size */
109     bytestream_put_byte(&buf, 4);                   /* sample size */
110     bytestream_put_byte(&buf, avctx->ch_layout.nb_channels); /* channels */
111     bytestream_put_be32(&buf, avctx->sample_rate);  /* sample rate */
112     bytestream_put_be32(&buf, 0);                   /* total sample count */
113     bytestream_put_be16(&buf, c->cutoff);           /* cutoff frequency */
114     bytestream_put_byte(&buf, 3);                   /* version */
115     bytestream_put_byte(&buf, 0);                   /* flags */
116     bytestream_put_be32(&buf, 0);                   /* unknown */
117     bytestream_put_be32(&buf, 0);                   /* loop enabled */
118     bytestream_put_be16(&buf, 0);                   /* padding */
119     bytestream_put_buffer(&buf, "(c)CRI", 6);       /* copyright signature */
120 
121     return HEADER_SIZE;
122 }
123 
adx_encode_init(AVCodecContext * avctx)124 static av_cold int adx_encode_init(AVCodecContext *avctx)
125 {
126     ADXContext *c = avctx->priv_data;
127 
128     if (avctx->ch_layout.nb_channels > 2) {
129         av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
130         return AVERROR(EINVAL);
131     }
132     avctx->frame_size = BLOCK_SAMPLES;
133 
134     /* the cutoff can be adjusted, but this seems to work pretty well */
135     c->cutoff = 500;
136     ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
137 
138     return 0;
139 }
140 
adx_encode_frame(AVCodecContext * avctx,AVPacket * avpkt,const AVFrame * frame,int * got_packet_ptr)141 static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
142                             const AVFrame *frame, int *got_packet_ptr)
143 {
144     ADXContext *c          = avctx->priv_data;
145     const int16_t *samples = frame ? (const int16_t *)frame->data[0] : NULL;
146     uint8_t *dst;
147     int channels = avctx->ch_layout.nb_channels;
148     int ch, out_size, ret;
149 
150     if (!samples) {
151         if (c->eof)
152             return 0;
153         if ((ret = ff_get_encode_buffer(avctx, avpkt, 18, 0)) < 0)
154             return ret;
155         c->eof = 1;
156         dst = avpkt->data;
157         bytestream_put_be16(&dst, 0x8001);
158         bytestream_put_be16(&dst, 0x000E);
159         bytestream_put_be64(&dst, 0x0);
160         bytestream_put_be32(&dst, 0x0);
161         bytestream_put_be16(&dst, 0x0);
162         *got_packet_ptr = 1;
163         return 0;
164     }
165 
166     out_size = BLOCK_SIZE * channels + !c->header_parsed * HEADER_SIZE;
167     if ((ret = ff_get_encode_buffer(avctx, avpkt, out_size, 0)) < 0)
168         return ret;
169     dst = avpkt->data;
170 
171     if (!c->header_parsed) {
172         int hdrsize;
173         if ((hdrsize = adx_encode_header(avctx, dst, avpkt->size)) < 0) {
174             av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
175             return AVERROR(EINVAL);
176         }
177         dst      += hdrsize;
178         c->header_parsed = 1;
179     }
180 
181     for (ch = 0; ch < channels; ch++) {
182         adx_encode(c, dst, samples + ch, &c->prev[ch], channels);
183         dst += BLOCK_SIZE;
184     }
185 
186     avpkt->pts = frame->pts;
187     avpkt->duration = frame->nb_samples;
188     *got_packet_ptr = 1;
189     return 0;
190 }
191 
192 const FFCodec ff_adpcm_adx_encoder = {
193     .p.name         = "adpcm_adx",
194     .p.long_name    = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
195     .p.type         = AVMEDIA_TYPE_AUDIO,
196     .p.id           = AV_CODEC_ID_ADPCM_ADX,
197     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
198     .priv_data_size = sizeof(ADXContext),
199     .init           = adx_encode_init,
200     FF_CODEC_ENCODE_CB(adx_encode_frame),
201     .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
202                                                       AV_SAMPLE_FMT_NONE },
203     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
204 };
205