From 9a43e3adbe82adabb57859d4d72420f53378bbba Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 16 May 2004 10:48:59 +0000 Subject: [PATCH] support for 24 bit pcm/wav files git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12479 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libaf/af_format.c | 81 ++++++++++++++++++++++++++++++++++++++++++-- libaf/af_mp.c | 6 +++- libao2/afmt.h | 5 +++ libmpcodecs/ad_pcm.c | 4 +++ 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/libaf/af_format.c b/libaf/af_format.c index 8d9f3e69cd..7a5fd04af1 100644 --- a/libaf/af_format.c +++ b/libaf/af_format.c @@ -131,9 +131,9 @@ char* fmt2str(int format, char* str, size_t size) // Sanity check for bytes per sample int check_bps(int bps) { - if(bps != 4 && bps != 2 && bps != 1){ + if(bps != 4 && bps != 3 && bps != 2 && bps != 1){ af_msg(AF_MSG_ERROR,"[format] The number of bytes per sample" - " must be 1, 2 or 4. Current value is %i \n",bps); + " must be 1, 2, 3 or 4. Current value is %i \n",bps); return AF_ERROR; } return AF_OK; @@ -349,6 +349,30 @@ af_info_t af_info_format = { open }; +static inline uint32_t load24bit(void* data, int pos) { +#if WORDS_BIGENDIAN + return (((uint32_t)((uint8_t*)data)[3*pos])<<24) | + (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | + (((uint32_t)((uint8_t*)data)[3*pos+2])<<8); +#else + return (((uint32_t)((uint8_t*)data)[3*pos])<<8) | + (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | + (((uint32_t)((uint8_t*)data)[3*pos+2])<<24); +#endif +} + +static inline void store24bit(void* data, int pos, uint32_t expanded_value) { +#if WORDS_BIGENDIAN + ((uint8_t*)data)[3*pos]=expanded_value>>24; + ((uint8_t*)data)[3*pos+1]=expanded_value>>16; + ((uint8_t*)data)[3*pos+2]=expanded_value>>8; +#else + ((uint8_t*)data)[3*pos]=expanded_value>>8; + ((uint8_t*)data)[3*pos+1]=expanded_value>>16; + ((uint8_t*)data)[3*pos+2]=expanded_value>>24; +#endif +} + // Function implementations used by play static void endian(void* in, void* out, int len, int bps) { @@ -362,6 +386,15 @@ static void endian(void* in, void* out, int len, int bps) } break; } + case(3):{ + register uint8_t s; + for(i=0;i>8); break; + case(3): + for(i=0;i>24); + break; + case(2): + for(i=0;i>16); + break; + case(4): + for(i=0;i>16); break; + case(3): + for(i=0;iformat | AFMT_AF_FLAGS); } diff --git a/libao2/afmt.h b/libao2/afmt.h index f7c4fcd616..fbef3af89b 100644 --- a/libao2/afmt.h +++ b/libao2/afmt.h @@ -53,3 +53,8 @@ #ifndef AFMT_FLOAT # define AFMT_FLOAT 0x00004000 #endif + +/* for formats that don't have a corresponding AFMT_* type, + * use the flags from libaf/af_format.h or'ed with this */ +#define AFMT_AF_FLAGS 0x70000000 + diff --git a/libmpcodecs/ad_pcm.c b/libmpcodecs/ad_pcm.c index aedcedf2fb..0d03fe5d30 100644 --- a/libmpcodecs/ad_pcm.c +++ b/libmpcodecs/ad_pcm.c @@ -4,6 +4,7 @@ #include "config.h" #include "ad_internal.h" +#include "../libaf/af_format.h" static ad_info_t info = { @@ -29,6 +30,9 @@ static int init(sh_audio_t *sh_audio) switch (sh_audio->samplesize) { case 1: sh_audio->sample_format=AFMT_U8; break; case 2: sh_audio->sample_format=AFMT_S16_LE; break; + case 3: sh_audio->sample_format=AFMT_AF_FLAGS | AF_FORMAT_I | + AF_FORMAT_LE | AF_FORMAT_SI; + break; case 4: sh_audio->sample_format=AFMT_S32_LE; break; } break;