FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dsicinaudio.c
Go to the documentation of this file.
1 /*
2  * Delphine Software International CIN audio decoder
3  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
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 /**
23  * @file
24  * Delphine Software International CIN audio decoder
25  */
26 
28 
29 #include "avcodec.h"
30 #include "bytestream.h"
31 #include "internal.h"
32 #include "mathops.h"
33 
34 typedef struct CinAudioContext {
36  int delta;
38 
39 
40 /* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */
41 static const int16_t cinaudio_delta16_table[256] = {
42  0, 0, 0, 0, 0, 0, 0, 0,
43  0, 0, 0, 0, 0, 0, 0, 0,
44  0, 0, 0, -30210, -27853, -25680, -23677, -21829,
45  -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
46  -10508, -9689, -8933, -8236, -7593, -7001, -6455, -5951,
47  -5487, -5059, -4664, -4300, -3964, -3655, -3370, -3107,
48  -2865, -2641, -2435, -2245, -2070, -1908, -1759, -1622,
49  -1495, -1379, -1271, -1172, -1080, -996, -918, -847,
50  -781, -720, -663, -612, -564, -520, -479, -442,
51  -407, -376, -346, -319, -294, -271, -250, -230,
52  -212, -196, -181, -166, -153, -141, -130, -120,
53  -111, -102, -94, -87, -80, -74, -68, -62,
54  -58, -53, -49, -45, -41, -38, -35, -32,
55  -30, -27, -25, -23, -21, -20, -18, -17,
56  -15, -14, -13, -12, -11, -10, -9, -8,
57  -7, -6, -5, -4, -3, -2, -1, 0,
58  0, 1, 2, 3, 4, 5, 6, 7,
59  8, 9, 10, 11, 12, 13, 14, 15,
60  17, 18, 20, 21, 23, 25, 27, 30,
61  32, 35, 38, 41, 45, 49, 53, 58,
62  62, 68, 74, 80, 87, 94, 102, 111,
63  120, 130, 141, 153, 166, 181, 196, 212,
64  230, 250, 271, 294, 319, 346, 376, 407,
65  442, 479, 520, 564, 612, 663, 720, 781,
66  847, 918, 996, 1080, 1172, 1271, 1379, 1495,
67  1622, 1759, 1908, 2070, 2245, 2435, 2641, 2865,
68  3107, 3370, 3655, 3964, 4300, 4664, 5059, 5487,
69  5951, 6455, 7001, 7593, 8236, 8933, 9689, 10508,
70  11398, 12362, 13408, 14543, 15774, 17108, 18556, 20126,
71  21829, 23677, 25680, 27853, 30210, 0, 0, 0,
72  0, 0, 0, 0, 0, 0, 0, 0,
73  0, 0, 0, 0, 0, 0, 0, 0
74 };
75 
77 {
78  CinAudioContext *cin = avctx->priv_data;
79 
80  cin->initial_decode_frame = 1;
81  cin->delta = 0;
83  avctx->channels = 1;
85 
86  return 0;
87 }
88 
89 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
90  int *got_frame_ptr, AVPacket *avpkt)
91 {
92  AVFrame *frame = data;
93  const uint8_t *buf = avpkt->data;
94  CinAudioContext *cin = avctx->priv_data;
95  const uint8_t *buf_end = buf + avpkt->size;
96  int16_t *samples;
97  int delta, ret;
98 
99  /* get output buffer */
100  frame->nb_samples = avpkt->size - cin->initial_decode_frame;
101  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
102  return ret;
103  samples = (int16_t *)frame->data[0];
104 
105  delta = cin->delta;
106  if (cin->initial_decode_frame) {
107  cin->initial_decode_frame = 0;
108  delta = sign_extend(AV_RL16(buf), 16);
109  buf += 2;
110  *samples++ = delta;
111  }
112  while (buf < buf_end) {
113  delta += cinaudio_delta16_table[*buf++];
114  delta = av_clip_int16(delta);
115  *samples++ = delta;
116  }
117  cin->delta = delta;
118 
119  *got_frame_ptr = 1;
120 
121  return avpkt->size;
122 }
123 
125  .name = "dsicinaudio",
126  .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
127  .type = AVMEDIA_TYPE_AUDIO,
129  .priv_data_size = sizeof(CinAudioContext),
132  .capabilities = CODEC_CAP_DR1,
133 };