diff --git a/main.c b/main.c index 6296d34..a2e5321 100644 --- a/main.c +++ b/main.c @@ -242,7 +242,10 @@ void process_sample(FILE* in, FILE* out, wav_data* header, float volume) uint32_t u32; float f; } un; + uint8_t u8[4]; + int16_t i16; + int32_t i32; float src[8]; float dst[2]; @@ -252,11 +255,82 @@ void process_sample(FILE* in, FILE* out, wav_data* header, float volume) src[i] = 0; } - for (int i = 0; i < header->channel_count; ++i) + if (3 == header->data_fmt) { - fread(u8, sizeof(uint8_t), 4, in); - wavtoh32(u8, &un.u32, header->is_be); - src[i] = un.f; + // Read float + for (int i = 0; i < header->channel_count; ++i) + { + fread(u8, sizeof(uint8_t), 4, in); + wavtoh32(u8, &un.u32, header->is_be); + src[i] = un.f; + } + } + else + { + // Read PCM + for (int i = 0; i < header->channel_count; ++i) + { + fread(u8, sizeof(uint8_t), header->bits_per_sample/8, in); + switch (header->bits_per_sample) + { + // 8 bit is unsigned + case 8: + src[i] = u8[0]; + src[i] -= 128; + if (src[i] < 0) + { + src[i] /= 128.0; + } + else + { + src[i] /= 127.0; + } + break; + + case 16: + wavtoh16(u8, (uint16_t*)&i16, header->is_be); + src[i] = i16; + if (src[i] < 0) + { + src[i] /= 32768.0; + } + else + { + src[i] /= 32767.0; + } + break; + + case 24: + wavtoh24(u8, (uint32_t*)&i32, header->is_be); + src[i] = i32; + if (src[i] < 0) + { + src[i] /= 8388608.0; + } + else + { + src[i] /= 8388607.0; + } + break; + + case 32: + wavtoh32(u8, (uint32_t*)&i32, header->is_be); + src[i] = i32; + if (src[i] < 0) + { + src[i] /= 2147483648.0; + } + else + { + src[i] /= 2147483647.0; + } + break; + + default: + printf("BITS PER SAMPLE WTF - %u\n", header->bits_per_sample); + return; + } + } } #ifdef LFE_ENABLE @@ -320,7 +394,8 @@ int main(int argc, char** argv) } // 1 is PCM, 3 is float - if ((in_header.data_fmt != 3) || (in_header.bits_per_sample != 32) || + if (((in_header.data_fmt != 3) && (in_header.data_fmt != 1)) || + ((in_header.bits_per_sample != 8) && (in_header.bits_per_sample != 16) && (in_header.bits_per_sample != 32)) || ((in_header.channel_count != 8) && (in_header.channel_count != 2))) { printf("Weird Header\n"); @@ -348,6 +423,8 @@ int main(int argc, char** argv) out_header = in_header; out_header.channel_count = 2; + out_header.data_fmt = 3; + out_header.bits_per_sample=32; out_header.is_be = 0; write_header(out_file, &out_header); diff --git a/wav_convert.c b/wav_convert.c index 9157a06..c36f287 100644 --- a/wav_convert.c +++ b/wav_convert.c @@ -63,6 +63,37 @@ void wavtoh32(uint8_t* in, uint32_t* out, uint8_t is_be) } } +void wavtoh24(uint8_t* in, uint32_t* out, uint8_t is_be) +{ + wav_u un; + int adjust; + + if (0 == is_be) + { + adjust = 0; + un.u8[3] = 0; + } + else + { + adjust = 1; + un.u8[0] = 0; + } + + for (int i = 0; i < 3; ++i) + { + un.u8[i + adjust] = in[i]; + } + + if (0 == is_be) + { + *out = un.u32; + } + else + { + *out = endian_swap32(un.u32); + } +} + void wavtoh16(uint8_t* in, uint16_t* out, uint8_t is_be) { wav_u un; @@ -99,6 +130,24 @@ void htowav32(uint32_t* in, uint8_t* out, uint8_t is_be) } } +void htowav24(uint32_t* in, uint8_t* out, uint8_t is_be) +{ + wav_u un; + if (0 == is_be) + { + un.u32 = *in; + } + else + { + un.u32 = endian_swap32(*in); + } + + for (int i = 0; i < 4; ++i) + { + out[i] = un.u8[i]; + } +} + void htowav16(uint16_t* in, uint8_t* out, uint8_t is_be) { wav_u un; diff --git a/wav_convert.h b/wav_convert.h index 4705ba3..498273b 100644 --- a/wav_convert.h +++ b/wav_convert.h @@ -4,9 +4,11 @@ #include void wavtoh32(uint8_t* in, uint32_t* out, uint8_t is_be); +void wavtoh24(uint8_t* in, uint32_t* out, uint8_t is_be); void wavtoh16(uint8_t* in, uint16_t* out, uint8_t is_be); void htowav32(uint32_t* in, uint8_t* out, uint8_t is_be); +void htowav24(uint32_t* in, uint8_t* out, uint8_t is_be); void htowav16(uint16_t* in, uint8_t* out, uint8_t is_be); #endif // WAV_CONVERT_H_