summaryrefslogtreecommitdiffstats
path: root/libaf
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-05-16 10:48:59 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-05-16 10:48:59 +0000
commit9a43e3adbe82adabb57859d4d72420f53378bbba (patch)
tree1ad2d86207ba3a4f10c5181faaac97d47f960f6a /libaf
parent571c94b3a78d914b3da3b58ce4841553ba8576fd (diff)
downloadmpv-9a43e3adbe82adabb57859d4d72420f53378bbba.tar.bz2
mpv-9a43e3adbe82adabb57859d4d72420f53378bbba.tar.xz
support for 24 bit pcm/wav files
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12479 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libaf')
-rw-r--r--libaf/af_format.c81
-rw-r--r--libaf/af_mp.c6
2 files changed, 84 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<len;i++){
+ s=((uint8_t*)in)[3*i];
+ ((uint8_t*)out)[3*i]=((uint8_t*)in)[3*i+2];
+ ((uint8_t*)out)[3*i+2]=s;
+ }
+ break;
+ }
case(4):{
register uint32_t s;
for(i=0;i<len;i++){
@@ -388,6 +421,10 @@ static void si2us(void* in, void* out, int len, int bps)
for(i=0;i<len;i++)
((uint16_t*)out)[i]=(uint16_t)(SHRT_MAX+((int)((int16_t*)in)[i]));
break;
+ case(3):
+ for(i=0;i<len;i++)
+ store24bit(out, i, (uint32_t)(INT_MAX+(int32_t)load24bit(in, i)));
+ break;
case(4):
for(i=0;i<len;i++)
((uint32_t*)out)[i]=(uint32_t)(INT_MAX+((int32_t*)in)[i]);
@@ -407,6 +444,10 @@ static void us2si(void* in, void* out, int len, int bps)
for(i=0;i<len;i++)
((int16_t*)out)[i]=(int16_t)(SHRT_MIN+((int)((uint16_t*)in)[i]));
break;
+ case(3):
+ for(i=0;i<len;i++)
+ store24bit(out, i, (int32_t)(INT_MIN+(uint32_t)load24bit(in, i)));
+ break;
case(4):
for(i=0;i<len;i++)
((int32_t*)out)[i]=(int32_t)(INT_MIN+((uint32_t*)in)[i]);
@@ -424,6 +465,10 @@ static void change_bps(void* in, void* out, int len, int inbps, int outbps)
for(i=0;i<len;i++)
((uint16_t*)out)[i]=((uint16_t)((uint8_t*)in)[i])<<8;
break;
+ case(3):
+ for(i=0;i<len;i++)
+ store24bit(out, i, ((uint32_t)((uint8_t*)in)[i])<<24);
+ break;
case(4):
for(i=0;i<len;i++)
((uint32_t*)out)[i]=((uint32_t)((uint8_t*)in)[i])<<24;
@@ -436,12 +481,32 @@ static void change_bps(void* in, void* out, int len, int inbps, int outbps)
for(i=0;i<len;i++)
((uint8_t*)out)[i]=(uint8_t)((((uint16_t*)in)[i])>>8);
break;
+ case(3):
+ for(i=0;i<len;i++)
+ store24bit(out, i, ((uint32_t)((uint16_t*)in)[i])<<16);
+ break;
case(4):
for(i=0;i<len;i++)
((uint32_t*)out)[i]=((uint32_t)((uint16_t*)in)[i])<<16;
break;
}
break;
+ case(3):
+ switch(outbps){
+ case(1):
+ for(i=0;i<len;i++)
+ ((uint8_t*)out)[i]=(uint8_t)(load24bit(in, i)>>24);
+ break;
+ case(2):
+ for(i=0;i<len;i++)
+ ((uint16_t*)out)[i]=(uint16_t)(load24bit(in, i)>>16);
+ break;
+ case(4):
+ for(i=0;i<len;i++)
+ ((uint32_t*)out)[i]=(uint32_t)load24bit(in, i);
+ break;
+ }
+ break;
case(4):
switch(outbps){
case(1):
@@ -452,6 +517,10 @@ static void change_bps(void* in, void* out, int len, int inbps, int outbps)
for(i=0;i<len;i++)
((uint16_t*)out)[i]=(uint16_t)((((uint32_t*)in)[i])>>16);
break;
+ case(3):
+ for(i=0;i<len;i++)
+ store24bit(out, i, ((uint32_t*)in)[i]);
+ break;
}
break;
}
@@ -469,6 +538,10 @@ static void float2int(void* in, void* out, int len, int bps)
for(i=0;i<len;i++)
((int16_t*)out)[i]=(int16_t)lrintf(SHRT_MAX*((float*)in)[i]);
break;
+ case(3):
+ for(i=0;i<len;i++)
+ store24bit(out, i, (int32_t)lrintf(INT_MAX*((float*)in)[i]));
+ break;
case(4):
for(i=0;i<len;i++)
((int32_t*)out)[i]=(int32_t)lrintf(INT_MAX*((float*)in)[i]);
@@ -488,6 +561,10 @@ static void int2float(void* in, void* out, int len, int bps)
for(i=0;i<len;i++)
((float*)out)[i]=(1.0/SHRT_MAX)*((float)((int16_t*)in)[i]);
break;
+ case(3):
+ for(i=0;i<len;i++)
+ ((float*)out)[i]=(1.0/INT_MAX)*((float)((int32_t)load24bit(in, i)));
+ break;
case(4):
for(i=0;i<len;i++)
((float*)out)[i]=(1.0/INT_MAX)*((float)((int32_t*)in)[i]);
diff --git a/libaf/af_mp.c b/libaf/af_mp.c
index 835cba73a8..9dd4bd372a 100644
--- a/libaf/af_mp.c
+++ b/libaf/af_mp.c
@@ -35,6 +35,10 @@ int af_format_decode(int ifmt)
case(AFMT_FLOAT):
ofmt = AF_FORMAT_F | AF_FORMAT_NE; break;
default:
+ if (ifmt & AFMT_AF_FLAGS == AFMT_AF_FLAGS) {
+ ofmt = ifmt & ~AFMT_AF_FLAGS;
+ break;
+ }
//This can not happen ....
af_msg(AF_MSG_FATAL,"Unrecognized input audio format %i\n",ifmt);
break;
@@ -75,6 +79,6 @@ int af_format_encode(void* fmtp)
case AF_FORMAT_AC3: return AFMT_AC3;
case AF_FORMAT_IMA_ADPCM: return AFMT_IMA_ADPCM;
}
- return AFMT_S16_LE; // shouldn't happen
+ return (fmt->format | AFMT_AF_FLAGS);
}