summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Belokurov <kirill.belokurov@gmail.com>2008-03-26 18:01:20 +0200
committerKirill Belokurov <kirill.belokurov@gmail.com>2008-03-26 18:01:20 +0200
commitfd4cb7f8687ded5d128cd8a63df99d69201f1b9a (patch)
tree57cdf2939e64841cb408bbfce1b8a92445dd412c
parent11da081690da7a299909dfba0a6ad913dc11a3e3 (diff)
downloadxine-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.c22
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;