3 * Copyright (c) 2001,2003 BERO
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "bytestream.h"
30 * SEGA CRI adx codecs.
32 * Reference documents:
33 * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
34 * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
37 static void adx_encode(ADXContext
*c
, uint8_t *adx
, const int16_t *wav
,
38 ADXChannelState
*prev
, int channels
)
49 for (i
= 0, j
= 0; j
< 32; i
+= channels
, j
++) {
51 d
= ((s0
<< COEFF_BITS
) - c
->coeff
[0] * s1
- c
->coeff
[1] * s2
) >> COEFF_BITS
;
60 if (max
== 0 && min
== 0) {
63 memset(adx
, 0, BLOCK_SIZE
);
67 if (max
/ 7 > -min
/ 8)
77 init_put_bits(&pb
, adx
+ 2, 16);
81 for (i
= 0, j
= 0; j
< 32; i
+= channels
, j
++) {
82 d
= ((wav
[i
] << COEFF_BITS
) - c
->coeff
[0] * s1
- c
->coeff
[1] * s2
) >> COEFF_BITS
;
84 d
= av_clip(ROUNDED_DIV(d
, scale
), -8, 7);
88 s0
= ((d
<< COEFF_BITS
) * scale
+ c
->coeff
[0] * s1
+ c
->coeff
[1] * s2
) >> COEFF_BITS
;
98 #define HEADER_SIZE 36
100 static int adx_encode_header(AVCodecContext
*avctx
, uint8_t *buf
, int bufsize
)
102 ADXContext
*c
= avctx
->priv_data
;
104 bytestream_put_be16(&buf
, 0x8000); /* header signature */
105 bytestream_put_be16(&buf
, HEADER_SIZE
- 4); /* copyright offset */
106 bytestream_put_byte(&buf
, 3); /* encoding */
107 bytestream_put_byte(&buf
, BLOCK_SIZE
); /* block size */
108 bytestream_put_byte(&buf
, 4); /* sample size */
109 bytestream_put_byte(&buf
, avctx
->channels
); /* channels */
110 bytestream_put_be32(&buf
, avctx
->sample_rate
); /* sample rate */
111 bytestream_put_be32(&buf
, 0); /* total sample count */
112 bytestream_put_be16(&buf
, c
->cutoff
); /* cutoff frequency */
113 bytestream_put_byte(&buf
, 3); /* version */
114 bytestream_put_byte(&buf
, 0); /* flags */
115 bytestream_put_be32(&buf
, 0); /* unknown */
116 bytestream_put_be32(&buf
, 0); /* loop enabled */
117 bytestream_put_be16(&buf
, 0); /* padding */
118 bytestream_put_buffer(&buf
, "(c)CRI", 6); /* copyright signature */
123 static av_cold
int adx_encode_init(AVCodecContext
*avctx
)
125 ADXContext
*c
= avctx
->priv_data
;
127 if (avctx
->channels
> 2) {
128 av_log(avctx
, AV_LOG_ERROR
, "Invalid number of channels\n");
129 return AVERROR(EINVAL
);
131 avctx
->frame_size
= BLOCK_SAMPLES
;
133 /* the cutoff can be adjusted, but this seems to work pretty well */
135 ff_adx_calculate_coeffs(c
->cutoff
, avctx
->sample_rate
, COEFF_BITS
, c
->coeff
);
140 static int adx_encode_frame(AVCodecContext
*avctx
, AVPacket
*avpkt
,
141 const AVFrame
*frame
, int *got_packet_ptr
)
143 ADXContext
*c
= avctx
->priv_data
;
144 const int16_t *samples
= (const int16_t *)frame
->data
[0];
146 int ch
, out_size
, ret
;
148 out_size
= BLOCK_SIZE
* avctx
->channels
+ !c
->header_parsed
* HEADER_SIZE
;
149 if ((ret
= ff_alloc_packet2(avctx
, avpkt
, out_size
)) < 0)
153 if (!c
->header_parsed
) {
155 if ((hdrsize
= adx_encode_header(avctx
, dst
, avpkt
->size
)) < 0) {
156 av_log(avctx
, AV_LOG_ERROR
, "output buffer is too small\n");
157 return AVERROR(EINVAL
);
160 c
->header_parsed
= 1;
163 for (ch
= 0; ch
< avctx
->channels
; ch
++) {
164 adx_encode(c
, dst
, samples
+ ch
, &c
->prev
[ch
], avctx
->channels
);
172 AVCodec ff_adpcm_adx_encoder
= {
174 .long_name
= NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
175 .type
= AVMEDIA_TYPE_AUDIO
,
176 .id
= AV_CODEC_ID_ADPCM_ADX
,
177 .priv_data_size
= sizeof(ADXContext
),
178 .init
= adx_encode_init
,
179 .encode2
= adx_encode_frame
,
180 .sample_fmts
= (const enum AVSampleFormat
[]) { AV_SAMPLE_FMT_S16
,
181 AV_SAMPLE_FMT_NONE
},