From fd4cb7f8687ded5d128cd8a63df99d69201f1b9a Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Wed, 26 Mar 2008 18:01:20 +0200 Subject: calculate AIFF files samplerate from 80-bit float, fixes wrong playback of some AIFF files --- src/demuxers/demux_aiff.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index b30b74910..8a2811ac6 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -84,6 +84,24 @@ typedef struct { demux_class_t demux_class; } demux_aiff_class_t; +/* converts IEEE 80bit extended into int, based on FFMPEG code */ +int extended_to_int(const unsigned char p[10]) +{ + uint64_t m = 0; + int e, i; + + for (i = 0; i < 8; i++) + m = (m<<8) + p[2+i];; + e = (((int)p[0]&0x7f)<<8) | p[1]; + if (e == 0x7fff && m) + return 0.0/0.0; + e -= 16383 + 63; + + if (p[0]&0x80) + m= -m; + return (int) ldexp(m, e); +} + /* returns 1 if the AIFF file was opened successfully, 0 otherwise */ static int open_aiff_file(demux_aiff_t *this) { @@ -91,6 +109,7 @@ static int open_aiff_file(demux_aiff_t *this) { unsigned char preamble[PREAMBLE_SIZE]; unsigned int chunk_type; unsigned int chunk_size; + unsigned char extended_sample_rate[10]; if (_x_demux_read_header(this->input, signature, AIFF_SIGNATURE_SIZE) != AIFF_SIGNATURE_SIZE) return 0; @@ -139,7 +158,8 @@ static int open_aiff_file(demux_aiff_t *this) { this->audio_channels = _X_BE_16(&buffer[0]); this->audio_frames = _X_BE_32(&buffer[2]); this->audio_bits = _X_BE_16(&buffer[6]); - this->audio_sample_rate = _X_BE_16(&buffer[0x0A]); + memcpy(&extended_sample_rate, &buffer[8], sizeof(extended_sample_rate)); + this->audio_sample_rate = extended_to_int(extended_sample_rate); this->audio_bytes_per_second = this->audio_channels * (this->audio_bits / 8) * this->audio_sample_rate; -- cgit v1.2.3