diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst index d6361bcede..557ee193de 100644 --- a/DOCS/man/af.rst +++ b/DOCS/man/af.rst @@ -265,9 +265,8 @@ Available filters are: Filter for internal use only. Converts between 24-bit and 32-bit sample formats. -``convertsignendian`` - Filter for internal use only. Converts between signed/unsigned formats - and formats with different endian. +``convertsign`` + Filter for internal use only. Converts between signed/unsigned formats. ``volume[=[:...]]`` Implements software volume control. Use this filter with caution since it diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index afff84ef00..443cfdad54 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -96,25 +96,30 @@ static const struct pcm_map tag_map[] = { // For demux_rawaudio.c; needed because ffmpeg doesn't have these sample // formats natively. -static const struct pcm_map af_map[] = { +static const struct pcm_map af_map_le[] = { {AF_FORMAT_U8, {"pcm_u8"}}, {AF_FORMAT_S8, {"pcm_u8"}}, - {AF_FORMAT_U16_LE, {"pcm_u16le"}}, - {AF_FORMAT_U16_BE, {"pcm_u16be"}}, - {AF_FORMAT_S16_LE, {"pcm_s16le"}}, - {AF_FORMAT_S16_BE, {"pcm_s16be"}}, - {AF_FORMAT_U24_LE, {"pcm_u24le"}}, - {AF_FORMAT_U24_BE, {"pcm_u24be"}}, - {AF_FORMAT_S24_LE, {"pcm_s24le"}}, - {AF_FORMAT_S24_BE, {"pcm_s24be"}}, - {AF_FORMAT_U32_LE, {"pcm_u32le"}}, - {AF_FORMAT_U32_BE, {"pcm_u32be"}}, - {AF_FORMAT_S32_LE, {"pcm_s32le"}}, - {AF_FORMAT_S32_BE, {"pcm_s32be"}}, - {AF_FORMAT_FLOAT_LE, {"pcm_f32le"}}, - {AF_FORMAT_FLOAT_BE, {"pcm_f32be"}}, - {AF_FORMAT_DOUBLE_LE, {"pcm_f64le"}}, - {AF_FORMAT_DOUBLE_BE, {"pcm_f64be"}}, + {AF_FORMAT_U16, {"pcm_u16le"}}, + {AF_FORMAT_S16, {"pcm_s16le"}}, + {AF_FORMAT_U24, {"pcm_u24le"}}, + {AF_FORMAT_S24, {"pcm_s24le"}}, + {AF_FORMAT_U32, {"pcm_u32le"}}, + {AF_FORMAT_S32, {"pcm_s32le"}}, + {AF_FORMAT_FLOAT, {"pcm_f32le"}}, + {AF_FORMAT_DOUBLE, {"pcm_f64le"}}, + {-1}, +}; +static const struct pcm_map af_map_be[] = { + {AF_FORMAT_U8, {"pcm_u8"}}, + {AF_FORMAT_S8, {"pcm_u8"}}, + {AF_FORMAT_U16, {"pcm_u16be"}}, + {AF_FORMAT_S16, {"pcm_s16be"}}, + {AF_FORMAT_U24, {"pcm_u24be"}}, + {AF_FORMAT_S24, {"pcm_s24be"}}, + {AF_FORMAT_U32, {"pcm_u32be"}}, + {AF_FORMAT_S32, {"pcm_s32be"}}, + {AF_FORMAT_FLOAT, {"pcm_f32be"}}, + {AF_FORMAT_DOUBLE, {"pcm_f64be"}}, {-1}, }; @@ -198,7 +203,8 @@ static int init(struct dec_audio *da, const char *decoder) decoder = find_pcm_decoder(tag_map, sh->format, sh_audio->wf->wBitsPerSample); } else if (sh_audio->wf && strcmp(decoder, "mp-pcm") == 0) { - decoder = find_pcm_decoder(af_map, sh->format, 0); + const struct pcm_map *map = sh_audio->big_endian ? af_map_be : af_map_le; + decoder = find_pcm_decoder(map, sh->format, 0); ctx->force_channel_map = true; } diff --git a/audio/filter/af_bs2b.c b/audio/filter/af_bs2b.c index 0a2bd8e552..29d646a9a9 100644 --- a/audio/filter/af_bs2b.c +++ b/audio/filter/af_bs2b.c @@ -48,20 +48,12 @@ static int filter_##name(struct af_instance *af, struct mp_audio *data, int f) \ } FILTER(f, float) -FILTER(fbe, float) -FILTER(fle, float) -FILTER(s32be, int32_t) -FILTER(u32be, uint32_t) -FILTER(s32le, int32_t) -FILTER(u32le, uint32_t) -FILTER(s24be, bs2b_int24_t) -FILTER(u24be, bs2b_uint24_t) -FILTER(s24le, bs2b_int24_t) -FILTER(u24le, bs2b_uint24_t) -FILTER(s16be, int16_t) -FILTER(u16be, uint16_t) -FILTER(s16le, int16_t) -FILTER(u16le, uint16_t) +FILTER(s32, int32_t) +FILTER(u32, uint32_t) +FILTER(s24, bs2b_int24_t) +FILTER(u24, bs2b_uint24_t) +FILTER(s16, int16_t) +FILTER(u16, uint16_t) FILTER(s8, int8_t) FILTER(u8, uint8_t) @@ -85,47 +77,26 @@ static int control(struct af_instance *af, int cmd, void *arg) /* check for formats supported by libbs2b and assign corresponding handlers */ switch (format) { - case AF_FORMAT_FLOAT_BE: - af->filter = filter_fbe; + case AF_FORMAT_FLOAT: + af->filter = filter_f; break; - case AF_FORMAT_FLOAT_LE: - af->filter = filter_fle; + case AF_FORMAT_S32: + af->filter = filter_s32; break; - case AF_FORMAT_S32_BE: - af->filter = filter_s32be; + case AF_FORMAT_U32: + af->filter = filter_u32; break; - case AF_FORMAT_U32_BE: - af->filter = filter_u32be; + case AF_FORMAT_S24: + af->filter = filter_s24; break; - case AF_FORMAT_S32_LE: - af->filter = filter_s32le; + case AF_FORMAT_U24: + af->filter = filter_u24; break; - case AF_FORMAT_U32_LE: - af->filter = filter_u32le; + case AF_FORMAT_S16: + af->filter = filter_s16; break; - case AF_FORMAT_S24_BE: - af->filter = filter_s24be; - break; - case AF_FORMAT_U24_BE: - af->filter = filter_u24be; - break; - case AF_FORMAT_S24_LE: - af->filter = filter_s24le; - break; - case AF_FORMAT_U24_LE: - af->filter = filter_u24le; - break; - case AF_FORMAT_S16_BE: - af->filter = filter_s16be; - break; - case AF_FORMAT_U16_BE: - af->filter = filter_u16be; - break; - case AF_FORMAT_S16_LE: - af->filter = filter_s16le; - break; - case AF_FORMAT_U16_LE: - af->filter = filter_u16le; + case AF_FORMAT_U16: + af->filter = filter_u16; break; case AF_FORMAT_S8: af->filter = filter_s8; diff --git a/audio/filter/af_convert24.c b/audio/filter/af_convert24.c index 38799bd8fc..e59317fe1b 100644 --- a/audio/filter/af_convert24.c +++ b/audio/filter/af_convert24.c @@ -20,6 +20,7 @@ #include "audio/format.h" #include "af.h" +#include "osdep/endian.h" static bool test_conversion(int src_format, int dst_format) { diff --git a/audio/filter/af_convertsignendian.c b/audio/filter/af_convertsignendian.c index a0b47b38a3..7e7e436352 100644 --- a/audio/filter/af_convertsignendian.c +++ b/audio/filter/af_convertsignendian.c @@ -20,21 +20,16 @@ #include "af.h" #include "audio/format.h" -#include "osdep/mpbswap.h" +#include "osdep/endian.h" static bool test_conversion(int src_format, int dst_format) { if ((src_format & AF_FORMAT_PLANAR) || (dst_format & AF_FORMAT_PLANAR)) return false; - int src_noend = src_format & ~AF_FORMAT_END_MASK; - int dst_noend = dst_format & ~AF_FORMAT_END_MASK; - // We can swap endian for all formats, but sign only for integer formats. - if (src_noend == dst_noend) - return true; - if (((src_noend & ~AF_FORMAT_SIGN_MASK) == - (dst_noend & ~AF_FORMAT_SIGN_MASK)) && - ((src_noend & AF_FORMAT_POINT_MASK) == AF_FORMAT_I)) + if (((src_format & ~AF_FORMAT_SIGN_MASK) == + (dst_format & ~AF_FORMAT_SIGN_MASK)) && + ((src_format & AF_FORMAT_POINT_MASK) == AF_FORMAT_I)) return true; return false; } @@ -63,34 +58,11 @@ static int control(struct af_instance *af, int cmd, void *arg) return AF_UNKNOWN; } -static void endian(void *data, int len, int bps) -{ - switch (bps) { - case 2: - for (int i = 0; i < len; i++) { - ((uint16_t*)data)[i] = bswap_16(((uint16_t *)data)[i]); - } - break; - case 3: - for(int i = 0; i < len; i++) { - uint8_t s = ((uint8_t *)data)[3 * i]; - ((uint8_t *)data)[3 * i] = ((uint8_t *)data)[3 * i + 2]; - ((uint8_t *)data)[3 * i + 2] = s; - } - break; - case 4: - for(int i = 0; i < len; i++) { - ((uint32_t*)data)[i] = bswap_32(((uint32_t *)data)[i]); - } - break; - } -} - -static void si2us(void *data, int len, int bps, bool le) +static void si2us(void *data, int len, int bps) { ptrdiff_t i = -(len * bps); uint8_t *p = &((uint8_t *)data)[len * bps]; - if (le && bps > 1) + if (BYTE_ORDER == LITTLE_ENDIAN && bps > 1) p += bps - 1; if (len <= 0) return; @@ -105,12 +77,8 @@ static int filter(struct af_instance *af, struct mp_audio *data, int flags) int outfmt = af->data->format; size_t len = data->samples * data->nch; - if ((infmt & AF_FORMAT_END_MASK) != (outfmt & AF_FORMAT_END_MASK)) - endian(data->planes[0], len, data->bps); - if ((infmt & AF_FORMAT_SIGN_MASK) != (outfmt & AF_FORMAT_SIGN_MASK)) - si2us(data->planes[0], len, data->bps, - (outfmt & AF_FORMAT_END_MASK) == AF_FORMAT_LE); + si2us(data->planes[0], len, data->bps); mp_audio_set_format(data, outfmt); return 0; @@ -124,8 +92,8 @@ static int af_open(struct af_instance *af) } const struct af_info af_info_convertsignendian = { - .info = "Convert between sample format sign/endian", - .name = "convertsignendian", + .info = "Convert between sample format sign", + .name = "convertsign", .open = af_open, .test_conversion = test_conversion, }; diff --git a/audio/format.c b/audio/format.c index b10e574a9e..60a86ea5ae 100644 --- a/audio/format.c +++ b/audio/format.c @@ -109,35 +109,27 @@ bool af_fmt_is_planar(int format) return !!(format & AF_FORMAT_PLANAR); } -#define FMT(string, id) \ - {string, id}, - -#define FMT_ENDIAN(string, id) \ - {string, id}, \ - {string "le", MP_CONCAT(id, _LE)}, \ - {string "be", MP_CONCAT(id, _BE)}, \ - const struct af_fmt_entry af_fmtstr_table[] = { - FMT("mpeg2", AF_FORMAT_MPEG2) - FMT("ac3", AF_FORMAT_AC3) - FMT("iec61937", AF_FORMAT_IEC61937) + {"mpeg2", AF_FORMAT_MPEG2}, + {"ac3", AF_FORMAT_AC3}, + {"iec61937", AF_FORMAT_IEC61937}, - FMT("u8", AF_FORMAT_U8) - FMT("s8", AF_FORMAT_S8) - FMT_ENDIAN("u16", AF_FORMAT_U16) - FMT_ENDIAN("s16", AF_FORMAT_S16) - FMT_ENDIAN("u24", AF_FORMAT_U24) - FMT_ENDIAN("s24", AF_FORMAT_S24) - FMT_ENDIAN("u32", AF_FORMAT_U32) - FMT_ENDIAN("s32", AF_FORMAT_S32) - FMT_ENDIAN("float", AF_FORMAT_FLOAT) - FMT_ENDIAN("double", AF_FORMAT_DOUBLE) + {"u8", AF_FORMAT_U8}, + {"s8", AF_FORMAT_S8}, + {"u16", AF_FORMAT_U16}, + {"s16", AF_FORMAT_S16}, + {"u24", AF_FORMAT_U24}, + {"s24", AF_FORMAT_S24}, + {"u32", AF_FORMAT_U32}, + {"s32", AF_FORMAT_S32}, + {"float", AF_FORMAT_FLOAT}, + {"double", AF_FORMAT_DOUBLE}, - FMT("u8p", AF_FORMAT_U8P) - FMT("s16p", AF_FORMAT_S16P) - FMT("s32p", AF_FORMAT_S32P) - FMT("floatp", AF_FORMAT_FLOATP) - FMT("doublep", AF_FORMAT_DOUBLEP) + {"u8p", AF_FORMAT_U8P}, + {"s16p", AF_FORMAT_S16P}, + {"s32p", AF_FORMAT_S32P}, + {"floatp", AF_FORMAT_FLOATP}, + {"doublep", AF_FORMAT_DOUBLEP}, {0} }; @@ -199,17 +191,12 @@ int af_format_conversion_score(int dst_format, int src_format) return INT_MIN; if (dst_format == src_format) return 1024; - // Just endian swapping (separate because it works for special formats) - if ((dst_format & ~AF_FORMAT_END_MASK) == (src_format & ~AF_FORMAT_END_MASK)) - return 1024 - 2; // Can't be normally converted if (AF_FORMAT_IS_SPECIAL(dst_format) || AF_FORMAT_IS_SPECIAL(src_format)) return INT_MIN; int score = 1024; if (FMT_DIFF(AF_FORMAT_INTERLEAVING_MASK, dst_format, src_format)) score -= 1; // has to (de-)planarize - if (FMT_DIFF(AF_FORMAT_END_MASK, dst_format, src_format)) - score -= 2; // has to swap endian if (FMT_DIFF(AF_FORMAT_SIGN_MASK, dst_format, src_format)) score -= 4; // has to swap sign if (FMT_DIFF(AF_FORMAT_POINT_MASK, dst_format, src_format)) { diff --git a/audio/format.h b/audio/format.h index a14d8fe367..3662d817f1 100644 --- a/audio/format.h +++ b/audio/format.h @@ -25,22 +25,8 @@ #include -#include "osdep/endian.h" #include "misc/bstr.h" -#if BYTE_ORDER == BIG_ENDIAN -#define AF_SELECT_LE_BE(LE, BE) BE -#else -#define AF_SELECT_LE_BE(LE, BE) LE -#endif - -// Endianness -#define AF_FORMAT_BE (0<<0) // Big Endian -#define AF_FORMAT_LE (1<<0) // Little Endian -#define AF_FORMAT_END_MASK (1<<0) - -#define AF_FORMAT_NE AF_SELECT_LE_BE(AF_FORMAT_LE, AF_FORMAT_BE) - // Signed/unsigned #define AF_FORMAT_SI (0<<1) // Signed #define AF_FORMAT_US (1<<1) // Unsigned @@ -80,48 +66,28 @@ enum af_format { AF_FORMAT_UNKNOWN = 0, - AF_FORMAT_U8 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_8BIT|AF_FORMAT_NE), - AF_FORMAT_S8 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_8BIT|AF_FORMAT_NE), - AF_FORMAT_U16_LE = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_16BIT|AF_FORMAT_LE), - AF_FORMAT_U16_BE = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_16BIT|AF_FORMAT_BE), - AF_FORMAT_S16_LE = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_16BIT|AF_FORMAT_LE), - AF_FORMAT_S16_BE = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_16BIT|AF_FORMAT_BE), - AF_FORMAT_U24_LE = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_24BIT|AF_FORMAT_LE), - AF_FORMAT_U24_BE = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_24BIT|AF_FORMAT_BE), - AF_FORMAT_S24_LE = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_24BIT|AF_FORMAT_LE), - AF_FORMAT_S24_BE = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_24BIT|AF_FORMAT_BE), - AF_FORMAT_U32_LE = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_32BIT|AF_FORMAT_LE), - AF_FORMAT_U32_BE = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_32BIT|AF_FORMAT_BE), - AF_FORMAT_S32_LE = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_32BIT|AF_FORMAT_LE), - AF_FORMAT_S32_BE = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_32BIT|AF_FORMAT_BE), + AF_FORMAT_U8 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_8BIT), + AF_FORMAT_S8 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_8BIT), + AF_FORMAT_U16 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_16BIT), + AF_FORMAT_S16 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_16BIT), + AF_FORMAT_U24 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_24BIT), + AF_FORMAT_S24 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_24BIT), + AF_FORMAT_U32 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_32BIT), + AF_FORMAT_S32 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_32BIT), - AF_FORMAT_FLOAT_LE = (AF_FORMAT_F|AF_FORMAT_32BIT|AF_FORMAT_LE), - AF_FORMAT_FLOAT_BE = (AF_FORMAT_F|AF_FORMAT_32BIT|AF_FORMAT_BE), + AF_FORMAT_FLOAT = (AF_FORMAT_F|AF_FORMAT_32BIT), + AF_FORMAT_DOUBLE = (AF_FORMAT_F|AF_FORMAT_64BIT), - AF_FORMAT_DOUBLE_LE = (AF_FORMAT_F|AF_FORMAT_64BIT|AF_FORMAT_LE), - AF_FORMAT_DOUBLE_BE = (AF_FORMAT_F|AF_FORMAT_64BIT|AF_FORMAT_BE), - - AF_FORMAT_AC3 = (AF_FORMAT_S_AC3|AF_FORMAT_16BIT|AF_FORMAT_LE), - AF_FORMAT_IEC61937 = (AF_FORMAT_S_IEC61937|AF_FORMAT_16BIT|AF_FORMAT_LE), + AF_FORMAT_AC3 = (AF_FORMAT_S_AC3|AF_FORMAT_16BIT), + AF_FORMAT_IEC61937 = (AF_FORMAT_S_IEC61937|AF_FORMAT_16BIT), AF_FORMAT_MPEG2 = (AF_FORMAT_S_MPEG2), // Planar variants - AF_FORMAT_U8P = (AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT|AF_FORMAT_NE), - AF_FORMAT_S16P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT|AF_FORMAT_NE), - AF_FORMAT_S32P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT|AF_FORMAT_NE), - AF_FORMAT_FLOATP = (AF_FLTP|AF_FORMAT_32BIT|AF_FORMAT_NE), - AF_FORMAT_DOUBLEP = (AF_FLTP|AF_FORMAT_64BIT|AF_FORMAT_NE), - - // Native endian variants - AF_FORMAT_U16 = AF_SELECT_LE_BE(AF_FORMAT_U16_LE, AF_FORMAT_U16_BE), - AF_FORMAT_S16 = AF_SELECT_LE_BE(AF_FORMAT_S16_LE, AF_FORMAT_S16_BE), - AF_FORMAT_U24 = AF_SELECT_LE_BE(AF_FORMAT_U24_LE, AF_FORMAT_U24_BE), - AF_FORMAT_S24 = AF_SELECT_LE_BE(AF_FORMAT_S24_LE, AF_FORMAT_S24_BE), - AF_FORMAT_U32 = AF_SELECT_LE_BE(AF_FORMAT_U32_LE, AF_FORMAT_U32_BE), - AF_FORMAT_S32 = AF_SELECT_LE_BE(AF_FORMAT_S32_LE, AF_FORMAT_S32_BE), - - AF_FORMAT_FLOAT = AF_SELECT_LE_BE(AF_FORMAT_FLOAT_LE, AF_FORMAT_FLOAT_BE), - AF_FORMAT_DOUBLE = AF_SELECT_LE_BE(AF_FORMAT_DOUBLE_LE, AF_FORMAT_DOUBLE_BE), + AF_FORMAT_U8P = (AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT), + AF_FORMAT_S16P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT), + AF_FORMAT_S32P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT), + AF_FORMAT_FLOATP = (AF_FLTP|AF_FORMAT_32BIT), + AF_FORMAT_DOUBLEP = (AF_FLTP|AF_FORMAT_64BIT), }; #define AF_FORMAT_IS_AC3(fmt) \ diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 60b8338f9d..c344f6f20e 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -38,6 +38,7 @@ #include "options/options.h" #include "options/m_option.h" #include "common/msg.h" +#include "osdep/endian.h" #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API @@ -208,22 +209,17 @@ alsa_error: static const int mp_to_alsa_format[][2] = { {AF_FORMAT_S8, SND_PCM_FORMAT_S8}, {AF_FORMAT_U8, SND_PCM_FORMAT_U8}, - {AF_FORMAT_U16_LE, SND_PCM_FORMAT_U16_LE}, - {AF_FORMAT_U16_BE, SND_PCM_FORMAT_U16_BE}, - {AF_FORMAT_S16_LE, SND_PCM_FORMAT_S16_LE}, - {AF_FORMAT_S16_BE, SND_PCM_FORMAT_S16_BE}, - {AF_FORMAT_U32_LE, SND_PCM_FORMAT_U32_LE}, - {AF_FORMAT_U32_BE, SND_PCM_FORMAT_U32_BE}, - {AF_FORMAT_S32_LE, SND_PCM_FORMAT_S32_LE}, - {AF_FORMAT_S32_BE, SND_PCM_FORMAT_S32_BE}, - {AF_FORMAT_U24_LE, SND_PCM_FORMAT_U24_3LE}, - {AF_FORMAT_U24_BE, SND_PCM_FORMAT_U24_3BE}, - {AF_FORMAT_S24_LE, SND_PCM_FORMAT_S24_3LE}, - {AF_FORMAT_S24_BE, SND_PCM_FORMAT_S24_3BE}, - {AF_FORMAT_FLOAT_LE, SND_PCM_FORMAT_FLOAT_LE}, - {AF_FORMAT_FLOAT_BE, SND_PCM_FORMAT_FLOAT_BE}, - {AF_FORMAT_AC3, SND_PCM_FORMAT_S16_LE}, - {AF_FORMAT_IEC61937, SND_PCM_FORMAT_S16_LE}, + {AF_FORMAT_U16, SND_PCM_FORMAT_U16}, + {AF_FORMAT_S16, SND_PCM_FORMAT_S16}, + {AF_FORMAT_U32, SND_PCM_FORMAT_U32}, + {AF_FORMAT_S32, SND_PCM_FORMAT_S32}, + {AF_FORMAT_U24, + MP_SELECT_LE_BE(SND_PCM_FORMAT_U24_3LE, SND_PCM_FORMAT_U24_3BE)}, + {AF_FORMAT_S24, + MP_SELECT_LE_BE(SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE)}, + {AF_FORMAT_FLOAT, SND_PCM_FORMAT_FLOAT}, + {AF_FORMAT_AC3, SND_PCM_FORMAT_S16}, + {AF_FORMAT_IEC61937, SND_PCM_FORMAT_S16}, {AF_FORMAT_MPEG2, SND_PCM_FORMAT_MPEG}, {AF_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN}, }; @@ -417,13 +413,13 @@ static int init(struct ao *ao) if (err < 0) { MP_INFO(ao, "Format %s is not supported by hardware, trying default.\n", af_fmt_to_str(ao->format)); - p->alsa_fmt = SND_PCM_FORMAT_S16_LE; + p->alsa_fmt = SND_PCM_FORMAT_S16; if (AF_FORMAT_IS_AC3(ao->format)) ao->format = AF_FORMAT_AC3; else if (AF_FORMAT_IS_IEC61937(ao->format)) ao->format = AF_FORMAT_IEC61937; else - ao->format = AF_FORMAT_S16_LE; + ao->format = AF_FORMAT_S16; } err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt); diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index da06656e9d..b39323ce72 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -25,6 +25,7 @@ #include "audio/out/ao_coreaudio_utils.h" #include "audio/out/ao_coreaudio_properties.h" #include "osdep/timer.h" +#include "osdep/endian.h" #include "audio/format.h" void ca_print_device_list(struct ao *ao) @@ -142,7 +143,7 @@ void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd) if ((ao->format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_SI) asbd->mFormatFlags |= kAudioFormatFlagIsSignedInteger; - if ((ao->format & AF_FORMAT_END_MASK) == AF_FORMAT_BE) + if (BYTE_ORDER == BIG_ENDIAN) asbd->mFormatFlags |= kAudioFormatFlagIsBigEndian; asbd->mFramesPerPacket = 1; diff --git a/audio/out/ao_dsound.c b/audio/out/ao_dsound.c index da1742e077..78b39b17b9 100644 --- a/audio/out/ao_dsound.c +++ b/audio/out/ao_dsound.c @@ -392,14 +392,14 @@ static int init(struct ao *ao) } switch (format) { case AF_FORMAT_AC3: - case AF_FORMAT_S24_LE: - case AF_FORMAT_S16_LE: + case AF_FORMAT_S24: + case AF_FORMAT_S16: case AF_FORMAT_U8: break; default: MP_VERBOSE(ao, "format %s not supported defaulting to Signed 16-bit Little-Endian\n", af_fmt_to_str(format)); - format = AF_FORMAT_S16_LE; + format = AF_FORMAT_S16; } //set our audio parameters ao->samplerate = rate; diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c index b78f244a7b..de71017432 100644 --- a/audio/out/ao_oss.c +++ b/audio/out/ao_oss.c @@ -40,6 +40,7 @@ #include "options/options.h" #include "common/msg.h" #include "osdep/timer.h" +#include "osdep/endian.h" #if HAVE_SYS_SOUNDCARD_H #include @@ -89,39 +90,46 @@ static const struct mp_chmap oss_layouts[MP_NUM_CHANNELS + 1] = { MP_CHMAP8(FL, FR, BL, BR, FC, LFE, SL, SR), // 7.1 }; +#if !defined(AFMT_S16_NE) && defined(AFMT_S16_LE) && defined(AFMT_S16_BE) +#define AFMT_S16_NE MP_SELECT_LE_BE(AFMT_S16_LE, AFMT_S16_BE) +#endif + +#if !defined(AFMT_U16_NE) && defined(AFMT_U16_LE) && defined(AFMT_U16_BE) +#define AFMT_U16_NE MP_SELECT_LE_BE(AFMT_U16_LE, AFMT_U16_BE) +#endif + +#if !defined(AFMT_U24_NE) && defined(AFMT_U24_LE) && defined(AFMT_U24_BE) +#define AFMT_U24_NE MP_SELECT_LE_BE(AFMT_U24_LE, AFMT_U24_BE) +#endif + +#if !defined(AFMT_S24_NE) && defined(AFMT_S24_LE) && defined(AFMT_S24_BE) +#define AFMT_S24_NE MP_SELECT_LE_BE(AFMT_S24_LE, AFMT_S24_BE) +#endif + +#if !defined(AFMT_U32_NE) && defined(AFMT_U32_LE) && defined(AFMT_U32_BE) +#define AFMT_U32MP_SELECT_LE_BE(AFMT_U32_LE, AFMT_U32_BE) +#endif + +#if !defined(AFMT_S32_NE) && defined(AFMT_S32_LE) && defined(AFMT_S32_BE) +#define AFMT_S32MP_SELECT_LE_BE(AFMT_S32_LE, AFMT_S32_BE) +#endif + static const int format_table[][2] = { {AFMT_U8, AF_FORMAT_U8}, {AFMT_S8, AF_FORMAT_S8}, - {AFMT_U16_LE, AF_FORMAT_U16_LE}, - {AFMT_U16_BE, AF_FORMAT_U16_BE}, - {AFMT_S16_LE, AF_FORMAT_S16_LE}, - {AFMT_S16_BE, AF_FORMAT_S16_BE}, -#ifdef AFMT_S24_PACKED - {AFMT_S24_PACKED, AF_FORMAT_S24_LE}, + {AFMT_U16_NE, AF_FORMAT_U16}, + {AFMT_S16_NE, AF_FORMAT_S16}, +#ifdef AFMT_U24_NE + {AFMT_U24_NE, AF_FORMAT_U24}, #endif -#ifdef AFMT_U24_LE - {AFMT_U24_LE, AF_FORMAT_U24_LE}, +#ifdef AFMT_S24_NE + {AFMT_S24_NE, AF_FORMAT_S24}, #endif -#ifdef AFMT_U24_BE - {AFMT_U24_BE, AF_FORMAT_U24_BE}, +#ifdef AFMT_U32_NE + {AFMT_U32_NE, AF_FORMAT_U32}, #endif -#ifdef AFMT_S24_LE - {AFMT_S24_LE, AF_FORMAT_S24_LE}, -#endif -#ifdef AFMT_S24_BE - {AFMT_S24_BE, AF_FORMAT_S24_BE}, -#endif -#ifdef AFMT_U32_LE - {AFMT_U32_LE, AF_FORMAT_U32_LE}, -#endif -#ifdef AFMT_U32_BE - {AFMT_U32_BE, AF_FORMAT_U32_BE}, -#endif -#ifdef AFMT_S32_LE - {AFMT_S32_LE, AF_FORMAT_S32_LE}, -#endif -#ifdef AFMT_S32_BE - {AFMT_S32_BE, AF_FORMAT_S32_BE}, +#ifdef AFMT_S32_NE + {AFMT_S32_NE, AF_FORMAT_S32}, #endif #ifdef AFMT_FLOAT {AFMT_FLOAT, AF_FORMAT_FLOAT}, diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c index 3c1f46409a..eb089c6c42 100644 --- a/audio/out/ao_pcm.c +++ b/audio/out/ao_pcm.c @@ -35,6 +35,7 @@ #include "ao.h" #include "internal.h" #include "common/msg.h" +#include "osdep/endian.h" #ifdef __MINGW32__ // for GetFileType to detect pipes @@ -72,8 +73,7 @@ static void fput32le(uint32_t val, FILE *fp) static void write_wave_header(struct ao *ao, FILE *fp, uint64_t data_length) { bool use_waveex = true; - uint16_t fmt = ao->format == AF_FORMAT_FLOAT_LE ? - WAV_ID_FLOAT_PCM : WAV_ID_PCM; + uint16_t fmt = ao->format == AF_FORMAT_FLOAT ? WAV_ID_FLOAT_PCM : WAV_ID_PCM; uint32_t fmt_chunk_size = use_waveex ? 40 : 16; int bits = af_fmt2bits(ao->format); @@ -124,16 +124,23 @@ static int init(struct ao *ao) if (priv->waveheader) { // WAV files must have one of the following formats + // And they don't work in big endian; fixing it would be simple, but + // nobody cares. + if (BYTE_ORDER == BIG_ENDIAN) { + MP_FATAL(ao, "Not supported on big endian.\n"); + return -1; + } + switch (ao->format) { case AF_FORMAT_U8: - case AF_FORMAT_S16_LE: - case AF_FORMAT_S24_LE: - case AF_FORMAT_S32_LE: - case AF_FORMAT_FLOAT_LE: + case AF_FORMAT_S16: + case AF_FORMAT_S24: + case AF_FORMAT_S32: + case AF_FORMAT_FLOAT: case AF_FORMAT_AC3: break; default: - ao->format = AF_FORMAT_S16_LE; + ao->format = AF_FORMAT_S16; break; } } diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c index 790ecb23dc..fa8a6a46be 100644 --- a/audio/out/ao_pulse.c +++ b/audio/out/ao_pulse.c @@ -169,12 +169,9 @@ static const struct format_map { int mp_format; pa_sample_format_t pa_format; } format_maps[] = { - {AF_FORMAT_S16_LE, PA_SAMPLE_S16LE}, - {AF_FORMAT_S16_BE, PA_SAMPLE_S16BE}, - {AF_FORMAT_S32_LE, PA_SAMPLE_S32LE}, - {AF_FORMAT_S32_BE, PA_SAMPLE_S32BE}, - {AF_FORMAT_FLOAT_LE, PA_SAMPLE_FLOAT32LE}, - {AF_FORMAT_FLOAT_BE, PA_SAMPLE_FLOAT32BE}, + {AF_FORMAT_S16, PA_SAMPLE_S16NE}, + {AF_FORMAT_S32, PA_SAMPLE_S32NE}, + {AF_FORMAT_FLOAT, PA_SAMPLE_FLOAT32NE}, {AF_FORMAT_U8, PA_SAMPLE_U8}, {AF_FORMAT_UNKNOWN, 0} }; diff --git a/audio/out/ao_rsound.c b/audio/out/ao_rsound.c index e41a89ae37..fe187144a6 100644 --- a/audio/out/ao_rsound.c +++ b/audio/out/ao_rsound.c @@ -52,40 +52,26 @@ static int set_format(struct ao *ao) case AF_FORMAT_S8: rsd_format = RSD_S8; break; - case AF_FORMAT_S16_LE: - rsd_format = RSD_S16_LE; + case AF_FORMAT_S16: + rsd_format = RSD_S16_NE; break; - case AF_FORMAT_S16_BE: - rsd_format = RSD_S16_BE; + case AF_FORMAT_U16: + rsd_format = RSD_U16_NE; break; - case AF_FORMAT_U16_LE: - rsd_format = RSD_U16_LE; + case AF_FORMAT_S24: + case AF_FORMAT_U24: + rsd_format = RSD_S32_NE; + ao->format = AF_FORMAT_S32; break; - case AF_FORMAT_U16_BE: - rsd_format = RSD_U16_BE; + case AF_FORMAT_S32: + rsd_format = RSD_S32_NE; break; - case AF_FORMAT_S24_LE: - case AF_FORMAT_S24_BE: - case AF_FORMAT_U24_LE: - case AF_FORMAT_U24_BE: - rsd_format = RSD_S32_LE; - ao->format = AF_FORMAT_S32_LE; - break; - case AF_FORMAT_S32_LE: - rsd_format = RSD_S32_LE; - break; - case AF_FORMAT_S32_BE: - rsd_format = RSD_S32_BE; - break; - case AF_FORMAT_U32_LE: - rsd_format = RSD_U32_LE; - break; - case AF_FORMAT_U32_BE: - rsd_format = RSD_U32_BE; + case AF_FORMAT_U32: + rsd_format = RSD_U32_NE; break; default: - rsd_format = RSD_S16_LE; - ao->format = AF_FORMAT_S16_LE; + rsd_format = RSD_S16_NE; + ao->format = AF_FORMAT_S16; } return rsd_format; diff --git a/audio/out/ao_sdl.c b/audio/out/ao_sdl.c index 9af5db4021..d2362a723e 100644 --- a/audio/out/ao_sdl.c +++ b/audio/out/ao_sdl.c @@ -38,6 +38,20 @@ struct priv float buflen; }; +static int fmtmap[][2] = { + {AF_FORMAT_U8, AUDIO_U8}, + {AF_FORMAT_S8, AUDIO_S8}, + {AF_FORMAT_U16, AUDIO_U16SYS}, + {AF_FORMAT_S16, AUDIO_S16SYS}, +#ifdef AUDIO_S32SYS + {AF_FORMAT_S32, AUDIO_S32SYS}, +#endif +#ifdef AUDIO_F32SYS + {AF_FORMAT_FLOAT, AUDIO_F32SYS}, +#endif + {0} +}; + static void audio_callback(void *userdata, Uint8 *stream, int len) { struct ao *ao = userdata; @@ -104,26 +118,12 @@ static int init(struct ao *ao) SDL_AudioSpec desired, obtained; - switch (ao->format) { - case AF_FORMAT_U8: desired.format = AUDIO_U8; break; - case AF_FORMAT_S8: desired.format = AUDIO_S8; break; - case AF_FORMAT_U16_LE: desired.format = AUDIO_U16LSB; break; - case AF_FORMAT_U16_BE: desired.format = AUDIO_U16MSB; break; - default: - case AF_FORMAT_S16_LE: desired.format = AUDIO_S16LSB; break; - case AF_FORMAT_S16_BE: desired.format = AUDIO_S16MSB; break; -#ifdef AUDIO_S32LSB - case AF_FORMAT_S32_LE: desired.format = AUDIO_S32LSB; break; -#endif -#ifdef AUDIO_S32MSB - case AF_FORMAT_S32_BE: desired.format = AUDIO_S32MSB; break; -#endif -#ifdef AUDIO_F32LSB - case AF_FORMAT_FLOAT_LE: desired.format = AUDIO_F32LSB; break; -#endif -#ifdef AUDIO_F32MSB - case AF_FORMAT_FLOAT_BE: desired.format = AUDIO_F32MSB; break; -#endif + desired.format = AUDIO_S16SYS; + for (int n = 0; fmtmap[n][0]; n++) { + if (ao->format == fmtmap[n][0]) { + desired.format = fmtmap[n][1]; + break; + } } desired.freq = ao->samplerate; desired.channels = ao->channels.num; @@ -156,30 +156,18 @@ static int init(struct ao *ao) // large, this will help. ao->device_buffer = 3 * obtained.samples; - switch (obtained.format) { - case AUDIO_U8: ao->format = AF_FORMAT_U8; break; - case AUDIO_S8: ao->format = AF_FORMAT_S8; break; - case AUDIO_S16LSB: ao->format = AF_FORMAT_S16_LE; break; - case AUDIO_S16MSB: ao->format = AF_FORMAT_S16_BE; break; - case AUDIO_U16LSB: ao->format = AF_FORMAT_U16_LE; break; - case AUDIO_U16MSB: ao->format = AF_FORMAT_U16_BE; break; -#ifdef AUDIO_S32LSB - case AUDIO_S32LSB: ao->format = AF_FORMAT_S32_LE; break; -#endif -#ifdef AUDIO_S32MSB - case AUDIO_S32MSB: ao->format = AF_FORMAT_S32_BE; break; -#endif -#ifdef AUDIO_F32LSB - case AUDIO_F32LSB: ao->format = AF_FORMAT_FLOAT_LE; break; -#endif -#ifdef AUDIO_F32MSB - case AUDIO_F32MSB: ao->format = AF_FORMAT_FLOAT_BE; break; -#endif - default: - if (!ao->probing) - MP_ERR(ao, "could not find matching format\n"); - uninit(ao); - return -1; + ao->format = 0; + for (int n = 0; fmtmap[n][0]; n++) { + if (obtained.format == fmtmap[n][1]) { + ao->format = fmtmap[n][0]; + break; + } + } + if (!ao->format) { + if (!ao->probing) + MP_ERR(ao, "could not find matching format\n"); + uninit(ao); + return -1; } if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, obtained.channels)) { diff --git a/audio/out/ao_sndio.c b/audio/out/ao_sndio.c index c75027dffc..c1c4ef17ab 100644 --- a/audio/out/ao_sndio.c +++ b/audio/out/ao_sndio.c @@ -109,22 +109,16 @@ static int init(struct ao *ao) struct priv *p = ao->priv; struct af_to_par { - int format, bits, sig, le; + int format, bits, sig; } static const af_to_par[] = { - {AF_FORMAT_U8, 8, 0, 0}, - {AF_FORMAT_S8, 8, 1, 0}, - {AF_FORMAT_U16_LE, 16, 0, 1}, - {AF_FORMAT_U16_BE, 16, 0, 0}, - {AF_FORMAT_S16_LE, 16, 1, 1}, - {AF_FORMAT_S16_BE, 16, 1, 0}, - {AF_FORMAT_U24_LE, 16, 0, 1}, - {AF_FORMAT_U24_BE, 24, 0, 0}, - {AF_FORMAT_S24_LE, 24, 1, 1}, - {AF_FORMAT_S24_BE, 24, 1, 0}, - {AF_FORMAT_U32_LE, 32, 0, 1}, - {AF_FORMAT_U32_BE, 32, 0, 0}, - {AF_FORMAT_S32_LE, 32, 1, 1}, - {AF_FORMAT_S32_BE, 32, 1, 0} + {AF_FORMAT_U8, 8, 0}, + {AF_FORMAT_S8, 8, 1}, + {AF_FORMAT_U16, 16, 0}, + {AF_FORMAT_S16, 16, 1}, + {AF_FORMAT_U24, 16, 0}, + {AF_FORMAT_S24, 24, 1}, + {AF_FORMAT_U32, 32, 0}, + {AF_FORMAT_S32, 32, 1}, }, *ap; int i; @@ -149,7 +143,7 @@ static int init(struct ao *ao) p->par.bits = ap->bits; p->par.sig = ap->sig; if (ap->bits > 8) - p->par.le = ap->le; + p->par.le = SIO_LE_NATIVE; if (ap->bits != SIO_BPS(ap->bits)) p->par.bps = ap->bits / 8; break; @@ -175,20 +169,18 @@ static int init(struct ao *ao) MP_ERR(ao, "couldn't get params\n"); goto error; } + if (p->par.bps > 1 && p->par.le != SIO_LE_NATIVE) { + MP_ERR(ao, "swapped endian output not supported\n"); + goto error; + } if (p->par.bits == 8 && p->par.bps == 1) { ao->format = p->par.sig ? AF_FORMAT_S8 : AF_FORMAT_U8; } else if (p->par.bits == 16 && p->par.bps == 2) { - ao->format = p->par.sig ? - (p->par.le ? AF_FORMAT_S16_LE : AF_FORMAT_S16_BE) : - (p->par.le ? AF_FORMAT_U16_LE : AF_FORMAT_U16_BE); + ao->format = p->par.sig ? AF_FORMAT_S16 : AF_FORMAT_U16; } else if ((p->par.bits == 24 || p->par.msb) && p->par.bps == 3) { - ao->format = p->par.sig ? - (p->par.le ? AF_FORMAT_S24_LE : AF_FORMAT_S24_BE) : - (p->par.le ? AF_FORMAT_U24_LE : AF_FORMAT_U24_BE); + ao->format = p->par.sig ? AF_FORMAT_S24 : AF_FORMAT_U24; } else if ((p->par.bits == 32 || p->par.msb) && p->par.bps == 4) { - ao->format = p->par.sig ? - (p->par.le ? AF_FORMAT_S32_LE : AF_FORMAT_S32_BE) : - (p->par.le ? AF_FORMAT_U32_LE : AF_FORMAT_U32_BE); + ao->format = p->par.sig ? AF_FORMAT_S32 : AF_FORMAT_U32; } else { MP_ERR(ao, "couldn't set format\n"); goto error; diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index afa2ad6b40..c12f3baf61 100755 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -292,14 +292,13 @@ static int try_passthrough(struct wasapi_state *state, union WAVEFMT u; u.extensible = &wformat; - MP_VERBOSE(ao, "trying passthrough for %s...\n", - af_fmt_to_str((ao->format&~AF_FORMAT_END_MASK) | AF_FORMAT_LE)); + MP_VERBOSE(ao, "trying passthrough for %s...\n", af_fmt_to_str(ao->format)); HRESULT hr = IAudioClient_IsFormatSupported(state->pAudioClient, state->share_mode, u.ex, NULL); if (!FAILED(hr)) { - ao->format = (ao->format&~AF_FORMAT_END_MASK) | AF_FORMAT_LE; + ao->format = ao->format; state->format = wformat; return 1; } diff --git a/demux/demux_raw.c b/demux/demux_raw.c index 288a1c931c..5dae30308a 100644 --- a/demux/demux_raw.c +++ b/demux/demux_raw.c @@ -34,10 +34,13 @@ #include "video/img_format.h" #include "video/img_fourcc.h" +#include "osdep/endian.h" + struct demux_rawaudio_opts { struct mp_chmap channels; int samplerate; int aformat; + int endian; }; #define OPT_BASE_STRUCT struct demux_rawaudio_opts @@ -46,13 +49,16 @@ const struct m_sub_options demux_rawaudio_conf = { OPT_CHMAP("channels", channels, CONF_MIN, .min = 1), OPT_INTRANGE("rate", samplerate, 0, 1000, 8 * 48000), OPT_AUDIOFORMAT("format", aformat, 0), + OPT_CHOICE("endian", endian, 0, ({"native", 0}, {"le", 1}, {"be", 2})), {0} }, .size = sizeof(struct demux_rawaudio_opts), .defaults = &(const struct demux_rawaudio_opts){ + // Note that currently, stream_cdda expects exactly these parameters! .channels = MP_CHMAP_INIT_STEREO, .samplerate = 44100, .aformat = AF_FORMAT_S16, + .endian = 0, }, }; @@ -121,6 +127,10 @@ static int demux_rawaudio_open(demuxer_t *demuxer, enum demux_check check) w->nBlockAlign = w->nChannels * samplesize; w->wBitsPerSample = 8 * samplesize; w->cbSize = 0; + int machine_endian = BYTE_ORDER == BIG_ENDIAN ? 2 : 1; + int endian = opts->endian ? opts->endian : machine_endian; + // wav usually implies little endian + sh_audio->big_endian = endian == 2; struct priv *p = talloc_ptrtype(demuxer, p); demuxer->priv = p; diff --git a/demux/demux_tv.c b/demux/demux_tv.c index fe7584a387..a4421a86cf 100644 --- a/demux/demux_tv.c +++ b/demux/demux_tv.c @@ -11,6 +11,7 @@ #include "audio/format.h" #include "video/img_fourcc.h" +#include "osdep/endian.h" #include "stream/stream.h" #include "stream/tv.h" @@ -106,14 +107,10 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check) { case AF_FORMAT_U8: case AF_FORMAT_S8: - case AF_FORMAT_U16_LE: - case AF_FORMAT_U16_BE: - case AF_FORMAT_S16_LE: - case AF_FORMAT_S16_BE: - case AF_FORMAT_S32_LE: - case AF_FORMAT_S32_BE: + case AF_FORMAT_U16: + case AF_FORMAT_S16: + case AF_FORMAT_S32: break; - case AF_FORMAT_MPEG2: default: MP_ERR(tvh, "Audio type '%s' unsupported!\n", af_fmt_to_str(audio_format)); @@ -147,6 +144,8 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check) sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; sh_audio->wf->nBlockAlign = block_align; sh_audio->wf->nAvgBytesPerSec = bytes_per_second; + // wav header usually implies little endian + sh_audio->big_endian = BYTE_ORDER == BIG_ENDIAN; MP_VERBOSE(tvh, " TV audio: %d channels, %d bits, %d Hz\n", sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample, diff --git a/demux/stheader.h b/demux/stheader.h index af1e7bb44a..806f7d9c5a 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -70,6 +70,7 @@ typedef struct sh_audio { int bitrate; // compressed bits/sec // win32-compatible codec parameters: MP_WAVEFORMATEX *wf; + bool big_endian; // endianess with wf and mp-pcm // note codec extradata may be either under "wf" or "codecdata" unsigned char *codecdata; int codecdata_len; diff --git a/osdep/endian.h b/osdep/endian.h index b600f1c281..c6d13760ea 100644 --- a/osdep/endian.h +++ b/osdep/endian.h @@ -28,4 +28,10 @@ #endif /* !defined(BYTE_ORDER) */ +#if BYTE_ORDER == BIG_ENDIAN +#define MP_SELECT_LE_BE(LE, BE) BE +#else +#define MP_SELECT_LE_BE(LE, BE) LE +#endif + #endif diff --git a/stream/ai_alsa1x.c b/stream/ai_alsa1x.c index bf36443dfe..c279505221 100644 --- a/stream/ai_alsa1x.c +++ b/stream/ai_alsa1x.c @@ -51,7 +51,7 @@ int ai_alsa_setup(audio_in_t *ai) return -1; } - err = snd_pcm_hw_params_set_format(ai->alsa.handle, params, SND_PCM_FORMAT_S16_LE); + err = snd_pcm_hw_params_set_format(ai->alsa.handle, params, SND_PCM_FORMAT_S16); if (err < 0) { MP_ERR(ai, "Sample format not available.\n"); return -1; @@ -122,7 +122,7 @@ int ai_alsa_setup(audio_in_t *ai) snd_pcm_dump(ai->alsa.handle, ai->alsa.log); } - ai->alsa.bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE); + ai->alsa.bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16); ai->alsa.bits_per_frame = ai->alsa.bits_per_sample * ai->channels; ai->blocksize = ai->alsa.chunk_size * ai->alsa.bits_per_frame / 8; ai->samplesize = ai->alsa.bits_per_sample; diff --git a/stream/ai_oss.c b/stream/ai_oss.c index b7a7988bde..98477d10f3 100644 --- a/stream/ai_oss.c +++ b/stream/ai_oss.c @@ -100,10 +100,10 @@ int ai_oss_init(audio_in_t *ai) ioctl(ai->oss.audio_fd, SNDCTL_DSP_GETFMTS, &ioctl_param)); MP_VERBOSE(ai, "Supported formats: %x\n", ioctl_param); - if (!(ioctl_param & AFMT_S16_LE)) + if (!(ioctl_param & AFMT_S16_NE)) MP_ERR(ai, "unsupported format\n"); - ioctl_param = AFMT_S16_LE; + ioctl_param = AFMT_S16_NE; MP_VERBOSE(ai, "ioctl dsp setfmt: %d\n", err = ioctl(ai->oss.audio_fd, SNDCTL_DSP_SETFMT, &ioctl_param)); if (err < 0) { diff --git a/stream/ai_sndio.c b/stream/ai_sndio.c index dc3c66279d..2bb47955a4 100644 --- a/stream/ai_sndio.c +++ b/stream/ai_sndio.c @@ -15,7 +15,7 @@ int ai_sndio_setup(audio_in_t *ai) par.bits = 16; par.sig = 1; - par.le = 1; + par.le = SIO_LE_NATIVE; par.rchan = ai->req_channels; par.rate = ai->req_samplerate; par.appbufsz = ai->req_samplerate; /* 1 sec */ diff --git a/stream/tvi_v4l2.c b/stream/tvi_v4l2.c index 13067b8cab..f2ec84d4cf 100644 --- a/stream/tvi_v4l2.c +++ b/stream/tvi_v4l2.c @@ -922,7 +922,7 @@ static int do_control(priv_t *priv, int cmd, void *arg) case TVI_CONTROL_AUD_GET_FORMAT: init_audio(priv); if (!priv->audio_initialized) return TVI_CONTROL_FALSE; - *(int *)arg = AF_FORMAT_S16_LE; + *(int *)arg = AF_FORMAT_S16; MP_VERBOSE(priv, "%s: get audio format: %d\n", info.short_name, *(int *)arg); return TVI_CONTROL_TRUE;