Statistics
| Branch: | Revision:

ffmpeg / libavcodec / pcm.c @ fbb89806

History | View | Annotate | Download (9.38 KB)

1 a96b68b7 Fabrice Bellard
/*
2
 * PCM codecs
3 ff4ec49e Fabrice Bellard
 * Copyright (c) 2001 Fabrice Bellard.
4 a96b68b7 Fabrice Bellard
 *
5 ff4ec49e Fabrice Bellard
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9 a96b68b7 Fabrice Bellard
 *
10 ff4ec49e Fabrice Bellard
 * This library is distributed in the hope that it will be useful,
11 a96b68b7 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ff4ec49e Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14 a96b68b7 Fabrice Bellard
 *
15 ff4ec49e Fabrice Bellard
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 a96b68b7 Fabrice Bellard
 */
19 1ab3d669 Michael Niedermayer
 
20
/**
21
 * @file pcm.c
22
 * PCM codecs
23
 */
24
 
25 a96b68b7 Fabrice Bellard
#include "avcodec.h"
26
27
/* from g711.c by SUN microsystems (unrestricted use) */
28
29
#define        SIGN_BIT        (0x80)                /* Sign bit for a A-law byte. */
30
#define        QUANT_MASK        (0xf)                /* Quantization field mask. */
31
#define        NSEGS                (8)                /* Number of A-law segments. */
32
#define        SEG_SHIFT        (4)                /* Left shift for segment number. */
33
#define        SEG_MASK        (0x70)                /* Segment field mask. */
34
35
#define        BIAS                (0x84)                /* Bias for linear code. */
36
37
/*
38
 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
39
 *
40
 */
41
static int alaw2linear(unsigned char        a_val)
42
{
43
        int                t;
44
        int                seg;
45
46
        a_val ^= 0x55;
47
48 cd1f22f9 Michael Niedermayer
        t = a_val & QUANT_MASK;
49 a96b68b7 Fabrice Bellard
        seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
50 cd1f22f9 Michael Niedermayer
        if(seg) t= (t + t + 1 + 32) << (seg + 2);
51
        else    t= (t + t + 1     ) << 3;
52
53 a96b68b7 Fabrice Bellard
        return ((a_val & SIGN_BIT) ? t : -t);
54
}
55
56
static int ulaw2linear(unsigned char        u_val)
57
{
58
        int                t;
59
60
        /* Complement to obtain normal u-law value. */
61
        u_val = ~u_val;
62
63
        /*
64
         * Extract and bias the quantization bits. Then
65
         * shift up by the segment number and subtract out the bias.
66
         */
67
        t = ((u_val & QUANT_MASK) << 3) + BIAS;
68
        t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
69
70
        return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
71
}
72
73
/* 16384 entries per table */
74 0c1a9eda Zdenek Kabelac
static uint8_t *linear_to_alaw = NULL;
75 a96b68b7 Fabrice Bellard
static int linear_to_alaw_ref = 0;
76
77 0c1a9eda Zdenek Kabelac
static uint8_t *linear_to_ulaw = NULL;
78 a96b68b7 Fabrice Bellard
static int linear_to_ulaw_ref = 0;
79
80 0c1a9eda Zdenek Kabelac
static void build_xlaw_table(uint8_t *linear_to_xlaw, 
81 a96b68b7 Fabrice Bellard
                             int (*xlaw2linear)(unsigned char),
82
                             int mask) 
83
{
84
    int i, j, v, v1, v2;
85
86
    j = 0;
87
    for(i=0;i<128;i++) {
88
        if (i != 127) {
89
            v1 = xlaw2linear(i ^ mask);
90
            v2 = xlaw2linear((i + 1) ^ mask);
91
            v = (v1 + v2 + 4) >> 3;
92
        } else {
93
            v = 8192;
94
        }
95
        for(;j<v;j++) {
96
            linear_to_xlaw[8192 + j] = (i ^ mask);
97
            if (j > 0)
98
                linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80));
99
        }
100
    }
101
    linear_to_xlaw[0] = linear_to_xlaw[1];
102
}
103
104 cd4af68a Zdenek Kabelac
static int pcm_encode_init(AVCodecContext *avctx)
105 a96b68b7 Fabrice Bellard
{
106
    avctx->frame_size = 1;
107
    switch(avctx->codec->id) {
108
    case CODEC_ID_PCM_ALAW:
109
        if (linear_to_alaw_ref == 0) {
110 6000abfa Fabrice Bellard
            linear_to_alaw = av_malloc(16384);
111 a96b68b7 Fabrice Bellard
            if (!linear_to_alaw)
112
                return -1;
113
            build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5);
114
        }
115
        linear_to_alaw_ref++;
116
        break;
117
    case CODEC_ID_PCM_MULAW:
118
        if (linear_to_ulaw_ref == 0) {
119 6000abfa Fabrice Bellard
            linear_to_ulaw = av_malloc(16384);
120 a96b68b7 Fabrice Bellard
            if (!linear_to_ulaw)
121
                return -1;
122
            build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff);
123
        }
124
        linear_to_ulaw_ref++;
125
        break;
126
    default:
127
        break;
128
    }
129 492cd3a9 Michael Niedermayer
    
130
    avctx->coded_frame= avcodec_alloc_frame();
131
    avctx->coded_frame->key_frame= 1;
132
    
133 a96b68b7 Fabrice Bellard
    return 0;
134
}
135
136 cd4af68a Zdenek Kabelac
static int pcm_encode_close(AVCodecContext *avctx)
137 a96b68b7 Fabrice Bellard
{
138 492cd3a9 Michael Niedermayer
    av_freep(&avctx->coded_frame);
139
140 a96b68b7 Fabrice Bellard
    switch(avctx->codec->id) {
141
    case CODEC_ID_PCM_ALAW:
142
        if (--linear_to_alaw_ref == 0)
143 6000abfa Fabrice Bellard
            av_free(linear_to_alaw);
144 a96b68b7 Fabrice Bellard
        break;
145
    case CODEC_ID_PCM_MULAW:
146
        if (--linear_to_ulaw_ref == 0)
147 6000abfa Fabrice Bellard
            av_free(linear_to_ulaw);
148 a96b68b7 Fabrice Bellard
        break;
149
    default:
150
        /* nothing to free */
151
        break;
152
    }
153
    return 0;
154
}
155
156 cd4af68a Zdenek Kabelac
static int pcm_encode_frame(AVCodecContext *avctx,
157
                            unsigned char *frame, int buf_size, void *data)
158 a96b68b7 Fabrice Bellard
{
159
    int n, sample_size, v;
160
    short *samples;
161
    unsigned char *dst;
162
163
    switch(avctx->codec->id) {
164
    case CODEC_ID_PCM_S16LE:
165
    case CODEC_ID_PCM_S16BE:
166
    case CODEC_ID_PCM_U16LE:
167
    case CODEC_ID_PCM_U16BE:
168
        sample_size = 2;
169
        break;
170
    default:
171
        sample_size = 1;
172
        break;
173
    }
174
    n = buf_size / sample_size;
175
    samples = data;
176
    dst = frame;
177
178
    switch(avctx->codec->id) {
179
    case CODEC_ID_PCM_S16LE:
180
        for(;n>0;n--) {
181
            v = *samples++;
182
            dst[0] = v & 0xff;
183
            dst[1] = v >> 8;
184
            dst += 2;
185
        }
186
        break;
187
    case CODEC_ID_PCM_S16BE:
188
        for(;n>0;n--) {
189
            v = *samples++;
190
            dst[0] = v >> 8;
191
            dst[1] = v;
192
            dst += 2;
193
        }
194
        break;
195
    case CODEC_ID_PCM_U16LE:
196
        for(;n>0;n--) {
197
            v = *samples++;
198
            v += 0x8000;
199
            dst[0] = v & 0xff;
200
            dst[1] = v >> 8;
201
            dst += 2;
202
        }
203
        break;
204
    case CODEC_ID_PCM_U16BE:
205
        for(;n>0;n--) {
206
            v = *samples++;
207
            v += 0x8000;
208
            dst[0] = v >> 8;
209
            dst[1] = v;
210
            dst += 2;
211
        }
212
        break;
213
    case CODEC_ID_PCM_S8:
214
        for(;n>0;n--) {
215
            v = *samples++;
216 0eaec105 Nikolai Zhubr
            dst[0] = v >> 8;
217 a96b68b7 Fabrice Bellard
            dst++;
218
        }
219
        break;
220
    case CODEC_ID_PCM_U8:
221
        for(;n>0;n--) {
222
            v = *samples++;
223 0eaec105 Nikolai Zhubr
            dst[0] = (v >> 8) + 128;
224 a96b68b7 Fabrice Bellard
            dst++;
225
        }
226
        break;
227
    case CODEC_ID_PCM_ALAW:
228
        for(;n>0;n--) {
229
            v = *samples++;
230
            dst[0] = linear_to_alaw[(v + 32768) >> 2];
231
            dst++;
232
        }
233
        break;
234
    case CODEC_ID_PCM_MULAW:
235
        for(;n>0;n--) {
236
            v = *samples++;
237
            dst[0] = linear_to_ulaw[(v + 32768) >> 2];
238
            dst++;
239
        }
240
        break;
241
    default:
242
        return -1;
243
    }
244 13a0314f Philip Gladstone
    //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels);
245 4c3d2e5f Philip Gladstone
246 a96b68b7 Fabrice Bellard
    return dst - frame;
247
}
248
249
typedef struct PCMDecode {
250
    short table[256];
251
} PCMDecode;
252
253 cd4af68a Zdenek Kabelac
static int pcm_decode_init(AVCodecContext * avctx)
254 a96b68b7 Fabrice Bellard
{
255
    PCMDecode *s = avctx->priv_data;
256
    int i;
257
258
    switch(avctx->codec->id) {
259
    case CODEC_ID_PCM_ALAW:
260
        for(i=0;i<256;i++)
261
            s->table[i] = alaw2linear(i);
262
        break;
263
    case CODEC_ID_PCM_MULAW:
264
        for(i=0;i<256;i++)
265
            s->table[i] = ulaw2linear(i);
266
        break;
267
    default:
268
        break;
269
    }
270
    return 0;
271
}
272
273 cd4af68a Zdenek Kabelac
static int pcm_decode_frame(AVCodecContext *avctx,
274
                            void *data, int *data_size,
275 0c1a9eda Zdenek Kabelac
                            uint8_t *buf, int buf_size)
276 a96b68b7 Fabrice Bellard
{
277
    PCMDecode *s = avctx->priv_data;
278
    int n;
279
    short *samples;
280 0c1a9eda Zdenek Kabelac
    uint8_t *src;
281 a96b68b7 Fabrice Bellard
282
    samples = data;
283
    src = buf;
284
285
    switch(avctx->codec->id) {
286
    case CODEC_ID_PCM_S16LE:
287
        n = buf_size >> 1;
288
        for(;n>0;n--) {
289
            *samples++ = src[0] | (src[1] << 8);
290
            src += 2;
291
        }
292
        break;
293
    case CODEC_ID_PCM_S16BE:
294
        n = buf_size >> 1;
295
        for(;n>0;n--) {
296
            *samples++ = (src[0] << 8) | src[1];
297
            src += 2;
298
        }
299
        break;
300
    case CODEC_ID_PCM_U16LE:
301
        n = buf_size >> 1;
302
        for(;n>0;n--) {
303
            *samples++ = (src[0] | (src[1] << 8)) - 0x8000;
304
            src += 2;
305
        }
306
        break;
307
    case CODEC_ID_PCM_U16BE:
308
        n = buf_size >> 1;
309
        for(;n>0;n--) {
310
            *samples++ = ((src[0] << 8) | src[1]) - 0x8000;
311
            src += 2;
312
        }
313
        break;
314
    case CODEC_ID_PCM_S8:
315
        n = buf_size;
316
        for(;n>0;n--) {
317
            *samples++ = src[0] << 8;
318
            src++;
319
        }
320
        break;
321
    case CODEC_ID_PCM_U8:
322
        n = buf_size;
323
        for(;n>0;n--) {
324
            *samples++ = ((int)src[0] - 128) << 8;
325
            src++;
326
        }
327
        break;
328
    case CODEC_ID_PCM_ALAW:
329
    case CODEC_ID_PCM_MULAW:
330
        n = buf_size;
331
        for(;n>0;n--) {
332
            *samples++ = s->table[src[0]];
333
            src++;
334
        }
335
        break;
336
    default:
337
        *data_size = 0;
338
        return -1;
339
    }
340 0c1a9eda Zdenek Kabelac
    *data_size = (uint8_t *)samples - (uint8_t *)data;
341 a96b68b7 Fabrice Bellard
    return src - buf;
342
}
343
344
#define PCM_CODEC(id, name)                     \
345
AVCodec name ## _encoder = {                    \
346
    #name,                                      \
347
    CODEC_TYPE_AUDIO,                           \
348
    id,                                         \
349
    0,                                          \
350 cd4af68a Zdenek Kabelac
    pcm_encode_init,                                \
351
    pcm_encode_frame,                                \
352
    pcm_encode_close,                                \
353 a96b68b7 Fabrice Bellard
    NULL,                                       \
354
};                                              \
355
AVCodec name ## _decoder = {                    \
356
    #name,                                      \
357
    CODEC_TYPE_AUDIO,                           \
358
    id,                                         \
359
    sizeof(PCMDecode),                          \
360 cd4af68a Zdenek Kabelac
    pcm_decode_init,                                \
361 a96b68b7 Fabrice Bellard
    NULL,                                       \
362
    NULL,                                       \
363 cd4af68a Zdenek Kabelac
    pcm_decode_frame,                           \
364 ef9f7306 Måns Rullgård
}
365 a96b68b7 Fabrice Bellard
366
PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le);
367
PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be);
368
PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le);
369
PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be);
370
PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8);
371
PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8);
372
PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw);
373
PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw);
374 cd4af68a Zdenek Kabelac
375
#undef PCM_CODEC