00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "libavutil/avstring.h"
00029 #include "libavutil/common.h"
00030 #include "libavutil/libm.h"
00031 #include "libavutil/samplefmt.h"
00032 #include "avcodec.h"
00033 #include "audioconvert.h"
00034
00035 struct AVAudioConvert {
00036 int in_channels, out_channels;
00037 int fmt_pair;
00038 };
00039
00040 AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
00041 enum AVSampleFormat in_fmt, int in_channels,
00042 const float *matrix, int flags)
00043 {
00044 AVAudioConvert *ctx;
00045 if (in_channels!=out_channels)
00046 return NULL;
00047 ctx = av_malloc(sizeof(AVAudioConvert));
00048 if (!ctx)
00049 return NULL;
00050 ctx->in_channels = in_channels;
00051 ctx->out_channels = out_channels;
00052 ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
00053 return ctx;
00054 }
00055
00056 void av_audio_convert_free(AVAudioConvert *ctx)
00057 {
00058 av_free(ctx);
00059 }
00060
00061 int av_audio_convert(AVAudioConvert *ctx,
00062 void * const out[6], const int out_stride[6],
00063 const void * const in[6], const int in_stride[6], int len)
00064 {
00065 int ch;
00066
00067
00068
00069 for(ch=0; ch<ctx->out_channels; ch++){
00070 const int is= in_stride[ch];
00071 const int os= out_stride[ch];
00072 const uint8_t *pi= in[ch];
00073 uint8_t *po= out[ch];
00074 uint8_t *end= po + os*len;
00075 if(!out[ch])
00076 continue;
00077
00078 #define CONV(ofmt, otype, ifmt, expr)\
00079 if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\
00080 do{\
00081 *(otype*)po = expr; pi += is; po += os;\
00082 }while(po < end);\
00083 }
00084
00085
00086
00087
00088 CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi)
00089 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
00090 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
00091 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
00092 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
00093 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
00094 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi)
00095 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16)
00096 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
00097 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
00098 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
00099 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16)
00100 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi)
00101 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31)))
00102 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31)))
00103 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80))
00104 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15))))
00105 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
00106 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi)
00107 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
00108 else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80))
00109 else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15))))
00110 else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
00111 else CONV(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi)
00112 else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
00113 else return -1;
00114 }
00115 return 0;
00116 }