Statistics
| Branch: | Revision:

ffmpeg / libavcodec / audioconvert.c @ d3b9e7f1

History | View | Annotate | Download (5.79 KB)

1
/*
2
 * audio conversion
3
 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
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 audioconvert.c
24
 * audio conversion
25
 * @author Michael Niedermayer <michaelni@gmx.at>
26
 */
27

    
28
#include "avcodec.h"
29
#include "audioconvert.h"
30

    
31
typedef struct SampleFmtInfo {
32
    const char *name;
33
    int bits;
34
} SampleFmtInfo;
35

    
36
/** this table gives more information about formats */
37
static const SampleFmtInfo sample_fmt_info[SAMPLE_FMT_NB] = {
38
    [SAMPLE_FMT_U8]  = { .name = "u8",  .bits = 8 },
39
    [SAMPLE_FMT_S16] = { .name = "s16", .bits = 16 },
40
    [SAMPLE_FMT_S32] = { .name = "s32", .bits = 32 },
41
    [SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32 },
42
    [SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64 },
43
};
44

    
45
const char *avcodec_get_sample_fmt_name(int sample_fmt)
46
{
47
    if (sample_fmt < 0 || sample_fmt >= SAMPLE_FMT_NB)
48
        return NULL;
49
    return sample_fmt_info[sample_fmt].name;
50
}
51

    
52
enum SampleFormat avcodec_get_sample_fmt(const char* name)
53
{
54
    int i;
55

    
56
    for (i=0; i < SAMPLE_FMT_NB; i++)
57
        if (!strcmp(sample_fmt_info[i].name, name))
58
            return i;
59
    return SAMPLE_FMT_NONE;
60
}
61

    
62
void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt)
63
{
64
    /* print header */
65
    if (sample_fmt < 0)
66
        snprintf (buf, buf_size, "name  " " depth");
67
    else if (sample_fmt < SAMPLE_FMT_NB) {
68
        SampleFmtInfo info= sample_fmt_info[sample_fmt];
69
        snprintf (buf, buf_size, "%-6s" "   %2d ", info.name, info.bits);
70
    }
71
}
72

    
73
struct AVAudioConvert {
74
    int in_channels, out_channels;
75
    int fmt_pair;
76
};
77

    
78
AVAudioConvert *av_audio_convert_alloc(enum SampleFormat out_fmt, int out_channels,
79
                                       enum SampleFormat in_fmt, int in_channels,
80
                                       const float *matrix, int flags)
81
{
82
    AVAudioConvert *ctx;
83
    if (in_channels!=out_channels)
84
        return NULL;  /* FIXME: not supported */
85
    ctx = av_malloc(sizeof(AVAudioConvert));
86
    if (!ctx)
87
        return NULL;
88
    ctx->in_channels = in_channels;
89
    ctx->out_channels = out_channels;
90
    ctx->fmt_pair = out_fmt + SAMPLE_FMT_NB*in_fmt;
91
    return ctx;
92
}
93

    
94
void av_audio_convert_free(AVAudioConvert *ctx)
95
{
96
    av_free(ctx);
97
}
98

    
99
int av_audio_convert(AVAudioConvert *ctx,
100
                           void * const out[6], const int out_stride[6],
101
                     const void * const  in[6], const int  in_stride[6], int len)
102
{
103
    int ch;
104

    
105
    //FIXME optimize common cases
106

    
107
    for(ch=0; ch<ctx->out_channels; ch++){
108
        const int is=  in_stride[ch];
109
        const int os= out_stride[ch];
110
        uint8_t *pi=  in[ch];
111
        uint8_t *po= out[ch];
112
        uint8_t *end= po + os*len;
113
        if(!out[ch])
114
            continue;
115

    
116
#define CONV(ofmt, otype, ifmt, expr)\
117
if(ctx->fmt_pair == ofmt + SAMPLE_FMT_NB*ifmt){\
118
    do{\
119
        *(otype*)po = expr; pi += is; po += os;\
120
    }while(po < end);\
121
}
122

    
123
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
124
//FIXME rounding and clipping ?
125

    
126
             CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 ,  *(uint8_t*)pi)
127
        else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<8)
128
        else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<24)
129
        else CONV(SAMPLE_FMT_FLT, float  , SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
130
        else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
131
        else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S16, (*(int16_t*)pi>>8) + 0x80)
132
        else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S16,  *(int16_t*)pi)
133
        else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S16,  *(int16_t*)pi<<16)
134
        else CONV(SAMPLE_FMT_FLT, float  , SAMPLE_FMT_S16,  *(int16_t*)pi*(1.0 / (1<<15)))
135
        else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S16,  *(int16_t*)pi*(1.0 / (1<<15)))
136
        else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S32, (*(int32_t*)pi>>24) + 0x80)
137
        else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S32,  *(int32_t*)pi>>16)
138
        else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S32,  *(int32_t*)pi)
139
        else CONV(SAMPLE_FMT_FLT, float  , SAMPLE_FMT_S32,  *(int32_t*)pi*(1.0 / (1<<31)))
140
        else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S32,  *(int32_t*)pi*(1.0 / (1<<31)))
141
        else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<7)) + 0x80)
142
        else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<15)))
143
        else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<31)))
144
        else CONV(SAMPLE_FMT_FLT, float  , SAMPLE_FMT_FLT, *(float*)pi)
145
        else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_FLT, *(float*)pi)
146
        else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<7)) + 0x80)
147
        else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<15)))
148
        else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<31)))
149
        else CONV(SAMPLE_FMT_FLT, float  , SAMPLE_FMT_DBL, *(double*)pi)
150
        else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_DBL, *(double*)pi)
151
        else return -1;
152
    }
153
    return 0;
154
}