diff options
author | Kirill Belokurov <kirill.belokurov@gmail.com> | 2008-03-26 18:01:20 +0200 |
---|---|---|
committer | Kirill Belokurov <kirill.belokurov@gmail.com> | 2008-03-26 18:01:20 +0200 |
commit | fd4cb7f8687ded5d128cd8a63df99d69201f1b9a (patch) | |
tree | 57cdf2939e64841cb408bbfce1b8a92445dd412c | |
parent | 11da081690da7a299909dfba0a6ad913dc11a3e3 (diff) | |
download | xine-lib-fd4cb7f8687ded5d128cd8a63df99d69201f1b9a.tar.gz xine-lib-fd4cb7f8687ded5d128cd8a63df99d69201f1b9a.tar.bz2 |
calculate AIFF files samplerate from 80-bit float, fixes wrong playback of some AIFF files
-rw-r--r-- | src/demuxers/demux_aiff.c | 22 |
1 files changed, 21 insertions, 1 deletions
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; |