Statistics
| Branch: | Revision:

ffmpeg / libavcodec / pcm.c @ b928ec64

History | View | Annotate | Download (9.42 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
        t = (a_val & QUANT_MASK) << 4;
49
        seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
50
        switch (seg) {
51
        case 0:
52
                t += 8;
53
                break;
54
        case 1:
55
                t += 0x108;
56
                break;
57
        default:
58
                t += 0x108;
59
                t <<= seg - 1;
60
        }
61
        return ((a_val & SIGN_BIT) ? t : -t);
62
}
63
64
static int ulaw2linear(unsigned char        u_val)
65
{
66
        int                t;
67
68
        /* Complement to obtain normal u-law value. */
69
        u_val = ~u_val;
70
71
        /*
72
         * Extract and bias the quantization bits. Then
73
         * shift up by the segment number and subtract out the bias.
74
         */
75
        t = ((u_val & QUANT_MASK) << 3) + BIAS;
76
        t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
77
78
        return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
79
}
80
81
/* 16384 entries per table */
82 0c1a9eda Zdenek Kabelac
static uint8_t *linear_to_alaw = NULL;
83 a96b68b7 Fabrice Bellard
static int linear_to_alaw_ref = 0;
84
85 0c1a9eda Zdenek Kabelac
static uint8_t *linear_to_ulaw = NULL;
86 a96b68b7 Fabrice Bellard
static int linear_to_ulaw_ref = 0;
87
88 0c1a9eda Zdenek Kabelac
static void build_xlaw_table(uint8_t *linear_to_xlaw, 
89 a96b68b7 Fabrice Bellard
                             int (*xlaw2linear)(unsigned char),
90
                             int mask) 
91
{
92
    int i, j, v, v1, v2;
93
94
    j = 0;
95
    for(i=0;i<128;i++) {
96
        if (i != 127) {
97
            v1 = xlaw2linear(i ^ mask);
98
            v2 = xlaw2linear((i + 1) ^ mask);
99
            v = (v1 + v2 + 4) >> 3;
100
        } else {
101
            v = 8192;
102
        }
103
        for(;j<v;j++) {
104
            linear_to_xlaw[8192 + j] = (i ^ mask);
105
            if (j > 0)
106
                linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80));
107
        }
108
    }
109
    linear_to_xlaw[0] = linear_to_xlaw[1];
110
}
111
112 cd4af68a Zdenek Kabelac
static int pcm_encode_init(AVCodecContext *avctx)
113 a96b68b7 Fabrice Bellard
{
114
    avctx->frame_size = 1;
115
    switch(avctx->codec->id) {
116
    case CODEC_ID_PCM_ALAW:
117
        if (linear_to_alaw_ref == 0) {
118 6000abfa Fabrice Bellard
            linear_to_alaw = av_malloc(16384);
119 a96b68b7 Fabrice Bellard
            if (!linear_to_alaw)
120
                return -1;
121
            build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5);
122
        }
123
        linear_to_alaw_ref++;
124
        break;
125
    case CODEC_ID_PCM_MULAW:
126
        if (linear_to_ulaw_ref == 0) {
127 6000abfa Fabrice Bellard
            linear_to_ulaw = av_malloc(16384);
128 a96b68b7 Fabrice Bellard
            if (!linear_to_ulaw)
129
                return -1;
130
            build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff);
131
        }
132
        linear_to_ulaw_ref++;
133
        break;
134
    default:
135
        break;
136
    }
137 492cd3a9 Michael Niedermayer
    
138
    avctx->coded_frame= avcodec_alloc_frame();
139
    avctx->coded_frame->key_frame= 1;
140
    
141 a96b68b7 Fabrice Bellard
    return 0;
142
}
143
144 cd4af68a Zdenek Kabelac
static int pcm_encode_close(AVCodecContext *avctx)
145 a96b68b7 Fabrice Bellard
{
146 492cd3a9 Michael Niedermayer
    av_freep(&avctx->coded_frame);
147
148 a96b68b7 Fabrice Bellard
    switch(avctx->codec->id) {
149
    case CODEC_ID_PCM_ALAW:
150
        if (--linear_to_alaw_ref == 0)
151 6000abfa Fabrice Bellard
            av_free(linear_to_alaw);
152 a96b68b7 Fabrice Bellard
        break;
153
    case CODEC_ID_PCM_MULAW:
154
        if (--linear_to_ulaw_ref == 0)
155 6000abfa Fabrice Bellard
            av_free(linear_to_ulaw);
156 a96b68b7 Fabrice Bellard
        break;
157
    default:
158
        /* nothing to free */
159
        break;
160
    }
161
    return 0;
162
}
163
164 cd4af68a Zdenek Kabelac
static int pcm_encode_frame(AVCodecContext *avctx,
165
                            unsigned char *frame, int buf_size, void *data)
166 a96b68b7 Fabrice Bellard
{
167
    int n, sample_size, v;
168
    short *samples;
169
    unsigned char *dst;
170
171
    switch(avctx->codec->id) {
172
    case CODEC_ID_PCM_S16LE:
173
    case CODEC_ID_PCM_S16BE:
174
    case CODEC_ID_PCM_U16LE:
175
    case CODEC_ID_PCM_U16BE:
176
        sample_size = 2;
177
        break;
178
    default:
179
        sample_size = 1;
180
        break;
181
    }
182
    n = buf_size / sample_size;
183
    samples = data;
184
    dst = frame;
185
186
    switch(avctx->codec->id) {
187
    case CODEC_ID_PCM_S16LE:
188
        for(;n>0;n--) {
189
            v = *samples++;
190
            dst[0] = v & 0xff;
191
            dst[1] = v >> 8;
192
            dst += 2;
193
        }
194
        break;
195
    case CODEC_ID_PCM_S16BE:
196
        for(;n>0;n--) {
197
            v = *samples++;
198
            dst[0] = v >> 8;
199
            dst[1] = v;
200
            dst += 2;
201
        }
202
        break;
203
    case CODEC_ID_PCM_U16LE:
204
        for(;n>0;n--) {
205
            v = *samples++;
206
            v += 0x8000;
207
            dst[0] = v & 0xff;
208
            dst[1] = v >> 8;
209
            dst += 2;
210
        }
211
        break;
212
    case CODEC_ID_PCM_U16BE:
213
        for(;n>0;n--) {
214
            v = *samples++;
215
            v += 0x8000;
216
            dst[0] = v >> 8;
217
            dst[1] = v;
218
            dst += 2;
219
        }
220
        break;
221
    case CODEC_ID_PCM_S8:
222
        for(;n>0;n--) {
223
            v = *samples++;
224 0eaec105 Nikolai Zhubr
            dst[0] = v >> 8;
225 a96b68b7 Fabrice Bellard
            dst++;
226
        }
227
        break;
228
    case CODEC_ID_PCM_U8:
229
        for(;n>0;n--) {
230
            v = *samples++;
231 0eaec105 Nikolai Zhubr
            dst[0] = (v >> 8) + 128;
232 a96b68b7 Fabrice Bellard
            dst++;
233
        }
234
        break;
235
    case CODEC_ID_PCM_ALAW:
236
        for(;n>0;n--) {
237
            v = *samples++;
238
            dst[0] = linear_to_alaw[(v + 32768) >> 2];
239
            dst++;
240
        }
241
        break;
242
    case CODEC_ID_PCM_MULAW:
243
        for(;n>0;n--) {
244
            v = *samples++;
245
            dst[0] = linear_to_ulaw[(v + 32768) >> 2];
246
            dst++;
247
        }
248
        break;
249
    default:
250
        return -1;
251
    }
252 13a0314f Philip Gladstone
    //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels);
253 4c3d2e5f Philip Gladstone
254 a96b68b7 Fabrice Bellard
    return dst - frame;
255
}
256
257
typedef struct PCMDecode {
258
    short table[256];
259
} PCMDecode;
260
261 cd4af68a Zdenek Kabelac
static int pcm_decode_init(AVCodecContext * avctx)
262 a96b68b7 Fabrice Bellard
{
263
    PCMDecode *s = avctx->priv_data;
264
    int i;
265
266
    switch(avctx->codec->id) {
267
    case CODEC_ID_PCM_ALAW:
268
        for(i=0;i<256;i++)
269
            s->table[i] = alaw2linear(i);
270
        break;
271
    case CODEC_ID_PCM_MULAW:
272
        for(i=0;i<256;i++)
273
            s->table[i] = ulaw2linear(i);
274
        break;
275
    default:
276
        break;
277
    }
278
    return 0;
279
}
280
281 cd4af68a Zdenek Kabelac
static int pcm_decode_frame(AVCodecContext *avctx,
282
                            void *data, int *data_size,
283 0c1a9eda Zdenek Kabelac
                            uint8_t *buf, int buf_size)
284 a96b68b7 Fabrice Bellard
{
285
    PCMDecode *s = avctx->priv_data;
286
    int n;
287
    short *samples;
288 0c1a9eda Zdenek Kabelac
    uint8_t *src;
289 a96b68b7 Fabrice Bellard
290
    samples = data;
291
    src = buf;
292
293
    switch(avctx->codec->id) {
294
    case CODEC_ID_PCM_S16LE:
295
        n = buf_size >> 1;
296
        for(;n>0;n--) {
297
            *samples++ = src[0] | (src[1] << 8);
298
            src += 2;
299
        }
300
        break;
301
    case CODEC_ID_PCM_S16BE:
302
        n = buf_size >> 1;
303
        for(;n>0;n--) {
304
            *samples++ = (src[0] << 8) | src[1];
305
            src += 2;
306
        }
307
        break;
308
    case CODEC_ID_PCM_U16LE:
309
        n = buf_size >> 1;
310
        for(;n>0;n--) {
311
            *samples++ = (src[0] | (src[1] << 8)) - 0x8000;
312
            src += 2;
313
        }
314
        break;
315
    case CODEC_ID_PCM_U16BE:
316
        n = buf_size >> 1;
317
        for(;n>0;n--) {
318
            *samples++ = ((src[0] << 8) | src[1]) - 0x8000;
319
            src += 2;
320
        }
321
        break;
322
    case CODEC_ID_PCM_S8:
323
        n = buf_size;
324
        for(;n>0;n--) {
325
            *samples++ = src[0] << 8;
326
            src++;
327
        }
328
        break;
329
    case CODEC_ID_PCM_U8:
330
        n = buf_size;
331
        for(;n>0;n--) {
332
            *samples++ = ((int)src[0] - 128) << 8;
333
            src++;
334
        }
335
        break;
336
    case CODEC_ID_PCM_ALAW:
337
    case CODEC_ID_PCM_MULAW:
338
        n = buf_size;
339
        for(;n>0;n--) {
340
            *samples++ = s->table[src[0]];
341
            src++;
342
        }
343
        break;
344
    default:
345
        *data_size = 0;
346
        return -1;
347
    }
348 0c1a9eda Zdenek Kabelac
    *data_size = (uint8_t *)samples - (uint8_t *)data;
349 a96b68b7 Fabrice Bellard
    return src - buf;
350
}
351
352
#define PCM_CODEC(id, name)                     \
353
AVCodec name ## _encoder = {                    \
354
    #name,                                      \
355
    CODEC_TYPE_AUDIO,                           \
356
    id,                                         \
357
    0,                                          \
358 cd4af68a Zdenek Kabelac
    pcm_encode_init,                                \
359
    pcm_encode_frame,                                \
360
    pcm_encode_close,                                \
361 a96b68b7 Fabrice Bellard
    NULL,                                       \
362
};                                              \
363
AVCodec name ## _decoder = {                    \
364
    #name,                                      \
365
    CODEC_TYPE_AUDIO,                           \
366
    id,                                         \
367
    sizeof(PCMDecode),                          \
368 cd4af68a Zdenek Kabelac
    pcm_decode_init,                                \
369 a96b68b7 Fabrice Bellard
    NULL,                                       \
370
    NULL,                                       \
371 cd4af68a Zdenek Kabelac
    pcm_decode_frame,                           \
372 ef9f7306 Måns Rullgård
}
373 a96b68b7 Fabrice Bellard
374
PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le);
375
PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be);
376
PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le);
377
PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be);
378
PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8);
379
PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8);
380
PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw);
381
PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw);
382 cd4af68a Zdenek Kabelac
383
#undef PCM_CODEC