*/
/**
- * @file audioconvert.c
+ * @file libavcodec/audioconvert.c
* audio conversion
* @author Michael Niedermayer <michaelni@gmx.at>
*/
+#include "libavutil/avstring.h"
#include "avcodec.h"
#include "audioconvert.h"
-#include <libavutil/avstring.h>
typedef struct SampleFmtInfo {
const char *name;
int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name)
{
switch(nb_channels) {
- case 1: return CHANNEL_LAYOUT_MONO;
- case 2: return CHANNEL_LAYOUT_STEREO;
- case 3: return CHANNEL_LAYOUT_SURROUND;
- case 4: return CHANNEL_LAYOUT_QUAD;
- case 5: return CHANNEL_LAYOUT_5POINT0;
- case 6: return CHANNEL_LAYOUT_5POINT1;
- case 8: return CHANNEL_LAYOUT_7POINT1;
+ case 1: return CH_LAYOUT_MONO;
+ case 2: return CH_LAYOUT_STEREO;
+ case 3: return CH_LAYOUT_SURROUND;
+ case 4: return CH_LAYOUT_QUAD;
+ case 5: return CH_LAYOUT_5POINT0;
+ case 6: return CH_LAYOUT_5POINT1;
+ case 8: return CH_LAYOUT_7POINT1;
default: return 0;
}
}
const char *name;
int nb_channels;
int64_t layout;
-} const channel_layout_map[] = {
- { "mono", 1, CHANNEL_LAYOUT_MONO },
- { "stereo", 2, CHANNEL_LAYOUT_STEREO },
- { "surround", 3, CHANNEL_LAYOUT_SURROUND },
- { "quad", 4, CHANNEL_LAYOUT_QUAD },
- { "5.0", 5, CHANNEL_LAYOUT_5POINT0 },
- { "5.1", 6, CHANNEL_LAYOUT_5POINT1 },
- { "5.1+downmix", 8, CHANNEL_LAYOUT_5POINT1|CHANNEL_LAYOUT_STEREO_DOWNMIX, },
- { "7.1", 8, CHANNEL_LAYOUT_7POINT1 },
- { "7.1(wide)", 8, CHANNEL_LAYOUT_7POINT1_WIDE },
- { "7.1+downmix", 10, CHANNEL_LAYOUT_7POINT1|CHANNEL_LAYOUT_STEREO_DOWNMIX, },
+} channel_layout_map[] = {
+ { "mono", 1, CH_LAYOUT_MONO },
+ { "stereo", 2, CH_LAYOUT_STEREO },
+ { "4.0", 4, CH_LAYOUT_4POINT0 },
+ { "quad", 4, CH_LAYOUT_QUAD },
+ { "5.0", 5, CH_LAYOUT_5POINT0 },
+ { "5.0", 5, CH_LAYOUT_5POINT0_BACK },
+ { "5.1", 6, CH_LAYOUT_5POINT1 },
+ { "5.1", 6, CH_LAYOUT_5POINT1_BACK },
+ { "5.1+downmix", 8, CH_LAYOUT_5POINT1|CH_LAYOUT_STEREO_DOWNMIX, },
+ { "7.1", 8, CH_LAYOUT_7POINT1 },
+ { "7.1(wide)", 8, CH_LAYOUT_7POINT1_WIDE },
+ { "7.1+downmix", 10, CH_LAYOUT_7POINT1|CH_LAYOUT_STEREO_DOWNMIX, },
{ 0 }
};
{
int i;
- if (channel_layout==0)
- channel_layout = avcodec_guess_channel_layout(nb_channels, CODEC_ID_NONE, NULL);
-
for (i=0; channel_layout_map[i].name; i++)
if (nb_channels == channel_layout_map[i].nb_channels &&
channel_layout == channel_layout_map[i].layout) {
- snprintf(buf, buf_size, channel_layout_map[i].name);
+ av_strlcpy(buf, channel_layout_map[i].name, buf_size);
return;
}
}
}
+int avcodec_channel_layout_num_channels(int64_t channel_layout)
+{
+ int count;
+ uint64_t x = channel_layout;
+ for (count = 0; x; count++)
+ x &= x-1; // unset lowest set bit
+ return count;
+}
+
struct AVAudioConvert {
int in_channels, out_channels;
int fmt_pair;
for(ch=0; ch<ctx->out_channels; ch++){
const int is= in_stride[ch];
const int os= out_stride[ch];
- uint8_t *pi= in[ch];
+ const uint8_t *pi= in[ch];
uint8_t *po= out[ch];
uint8_t *end= po + os*len;
if(!out[ch])
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
//FIXME rounding and clipping ?
- CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 , *(uint8_t*)pi)
- else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<8)
- else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<24)
- else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
- else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
- else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S16, (*(int16_t*)pi>>8) + 0x80)
- else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S16, *(int16_t*)pi)
- else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S16, *(int16_t*)pi<<16)
- else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S16, *(int16_t*)pi*(1.0 / (1<<15)))
- else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S16, *(int16_t*)pi*(1.0 / (1<<15)))
- else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S32, (*(int32_t*)pi>>24) + 0x80)
- else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S32, *(int32_t*)pi>>16)
- else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S32, *(int32_t*)pi)
- else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S32, *(int32_t*)pi*(1.0 / (1<<31)))
- else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S32, *(int32_t*)pi*(1.0 / (1<<31)))
- else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<7)) + 0x80)
- else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<15)))
- else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<31)))
- else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_FLT, *(float*)pi)
- else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_FLT, *(float*)pi)
- else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<7)) + 0x80)
- else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<15)))
- else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<31)))
- else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_DBL, *(double*)pi)
- else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_DBL, *(double*)pi)
+ CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 , *(const uint8_t*)pi)
+ else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
+ else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
+ else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
+ else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
+ else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
+ else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S16, *(const int16_t*)pi)
+ else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S16, *(const int16_t*)pi<<16)
+ else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
+ else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
+ else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
+ else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S32, *(const int32_t*)pi>>16)
+ else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S32, *(const int32_t*)pi)
+ else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31)))
+ else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31)))
+ else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_FLT, lrintf(*(const float*)pi * (1<<7)) + 0x80)
+ else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_FLT, lrintf(*(const float*)pi * (1<<15)))
+ else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_FLT, lrintf(*(const float*)pi * (1<<31)))
+ else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_FLT, *(const float*)pi)
+ else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_FLT, *(const float*)pi)
+ else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_DBL, lrint(*(const double*)pi * (1<<7)) + 0x80)
+ else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_DBL, lrint(*(const double*)pi * (1<<15)))
+ else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_DBL, lrint(*(const double*)pi * (1<<31)))
+ else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_DBL, *(const double*)pi)
+ else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_DBL, *(const double*)pi)
else return -1;
}
return 0;