[MPlayer-dev-eng] [PATCH] improved AIFF PCM Audio support

Jake Luck mplay at 10k.org
Thu Dec 9 11:02:32 CET 2004


Hello, everyone: 

Thank you for all the constructive comments regarding that patch I
submitted in July and for the insight you have shared on #mplayerdev.  
Here is an improved version of the patch which adds AIFF support to
mplayer. This patch was made against the CVS tree from a few hours ago and
has been tested on Cygwin 1.5.12(0.116/4/2), Mac OSX 10.3.6 and Xbox XBMC.
This new version:

* supports all sampling formats (48000,44100,32000,24000,22050,16000,11025,8000) 
* more robust header parser
* fully supports little endian architectures.

Sound data in AIFF is big endian native. On little endian environment such
as dsound and win32, the existing datapath doesn't perform the properly
byteswapping through either ad_pcm.c or -ao dsound/win32. Two solutions
are included in this patch to make the code fully compatible with little
endian architectures.

1) use the supplied ad_aiffpcm.c. This performs byteswapping in the
decode_audio() function.

2) use the supplied code snippet (commented out) in demux_audio.c which
tags the audio format and uses ad_pcm.c for processing once the datapath
issue has been addressed.

Please review and accept this into the source tree.

Thank you.

jake
-------------- next part --------------
diff -Nrup main/codec-cfg.c main-aiff/codec-cfg.c
--- main/codec-cfg.c    2004-11-15 04:09:27.000000000 -0500
+++ main-aiff/codec-cfg.c   2004-12-08 04:57:53.000000000 -0500
@@ -253,6 +253,7 @@ static short get_driver(char *s,int audi
        "alaw",
        "msgsm",
        "dshow",
+       "aiffpcm",
        "dvdpcm",
        "hwac3",
        "libvorbis",
diff -Nrup main/etc/codecs.conf main-aiff/etc/codecs.conf
--- main/etc/codecs.conf    2004-12-07 17:05:04.000000000 -0500
+++ main-aiff/etc/codecs.conf   2004-12-08 04:57:53.000000000 -0500
@@ -2288,6 +2288,12 @@ audiocodec ulaw
   format 0x77616c75  ; "ulaw" (MOV files)
   driver alaw
 
+audiocodec aiffpcm
+  info "Uncompressed AIFF PCM"
+  status untested
+  format 0x6669612E     ; ".aif"
+  driver aiffpcm
+  
 audiocodec dvdpcm
   info "Uncompressed DVD/VOB LPCM"
   status working
diff -Nrup main/libmpcodecs/Makefile main-aiff/libmpcodecs/Makefile
--- main/libmpcodecs/Makefile   2004-09-21 15:44:44.000000000 -0400
+++ main-aiff/libmpcodecs/Makefile  2004-12-08 04:57:58.000000000 -0500
@@ -5,7 +5,7 @@ LIBNAME = libmpcodecs.a
 LIBNAME2 = libmpencoders.a
 
 AUDIO_SRCS_LIB=ad_liba52.c ad_hwac3.c ad_mp3lib.c
-AUDIO_SRCS_NAT=ad_alaw.c ad_dk3adpcm.c ad_pcm.c ad_dvdpcm.c ad_imaadpcm.c ad_msadpcm.c ad_msgsm.c ad_ra1428.c
+AUDIO_SRCS_NAT=ad_alaw.c ad_dk3adpcm.c ad_pcm.c ad_aiffpcm.c ad_dvdpcm.c ad_imaadpcm.c ad_msadpcm.c ad_msgsm.c ad_ra1428.c
 AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c
 AUDIO_SRCS=dec_audio.c ad.c $(AUDIO_SRCS_LIB) $(AUDIO_SRCS_NAT) $(AUDIO_SRCS_OPT)
 
diff -Nrup main/libmpcodecs/ad.c main-aiff/libmpcodecs/ad.c
--- main/libmpcodecs/ad.c   2004-07-15 16:36:04.000000000 -0400
+++ main-aiff/libmpcodecs/ad.c  2004-12-08 04:57:58.000000000 -0500
@@ -21,6 +21,7 @@ extern ad_functions_t mpcodecs_ad_ffmpeg
 extern ad_functions_t mpcodecs_ad_liba52;
 extern ad_functions_t mpcodecs_ad_hwac3;
 extern ad_functions_t mpcodecs_ad_pcm;
+extern ad_functions_t mpcodecs_ad_aiffpcm;
 extern ad_functions_t mpcodecs_ad_dvdpcm;
 extern ad_functions_t mpcodecs_ad_alaw;
 extern ad_functions_t mpcodecs_ad_imaadpcm;
@@ -53,6 +54,7 @@ ad_functions_t* mpcodecs_ad_drivers[] =
   &mpcodecs_ad_ffmpeg,
 #endif
   &mpcodecs_ad_pcm,
+  &mpcodecs_ad_aiffpcm,
   &mpcodecs_ad_dvdpcm,
   &mpcodecs_ad_alaw,
   &mpcodecs_ad_imaadpcm,
diff -Nrup main/libmpcodecs/ad_aiffpcm.c main-aiff/libmpcodecs/ad_aiffpcm.c
--- main/libmpcodecs/ad_aiffpcm.c   1969-12-31 19:00:00.000000000 -0500
+++ main-aiff/libmpcodecs/ad_aiffpcm.c  2004-12-08 04:57:58.000000000 -0500
@@ -0,0 +1,119 @@
+/*
+   AIFF Audio Decoder
+   
+   Copyright (c) 2004, Jake Luck <mplay at 10k.org>
+   All rights reserved.
+   BSD License
+   http://www.opensource.org/licenses/bsd-license.php
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "ad_internal.h"
+#include "bswap.h"
+
+static ad_info_t info = 
+{
+   "Uncompressed AIFF PCM audio decoder",
+   "aiffpcm",
+   "Jake Luck",
+   "",
+   ""
+};
+
+LIBAD_EXTERN(aiffpcm)
+
+#include "aiff.h"
+
+static int aiff_decode_factor;
+    
+static int preinit(sh_audio_t *sh)
+{
+   return 1;
+}
+
+static int init(sh_audio_t *sh)
+{
+   AIFF_FORMCHUNK          *f;
+   AIFF_COMMONCHUNK        *c;
+   AIFF_SOUNDDATACHUNK     *s;
+   int                     n;
+   
+   f = &(sh->ah->f);
+   c = &(sh->ah->c);
+   s = &(sh->ah->s);
+
+    switch (c->cSampleSize)
+    {
+        case 16:
+            sh->sample_format = AFMT_S16_BE;
+            break;
+        case 8:
+            sh->sample_format = AFMT_S8;
+            break;
+        default:
+            break;
+    }
+    
+   if      ( memcmp(c->cSampleRate, "\x40\x0E\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+       sh->samplerate = 44100;
+    else if ( memcmp(c->cSampleRate, "\x40\x0E\xBB\x80\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 48000;    
+    else if ( memcmp(c->cSampleRate, "\x40\x0D\xFA\x00\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 32000; 
+    else if ( memcmp(c->cSampleRate, "\x40\x0D\xBB\x80\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 24000; 
+    else if ( memcmp(c->cSampleRate, "\x40\x0D\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 22050; 
+    else if ( memcmp(c->cSampleRate, "\x40\x0C\xFA\x00\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 16000; 
+    else if ( memcmp(c->cSampleRate, "\x40\x0C\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 11025; 
+    else if ( memcmp(c->cSampleRate, "\x40\x0B\xFA\x00\x00\x00\x00\x00", 8) == 0 )
+        sh->samplerate = 8000; 
+    
+   sh->samplesize = c->cSampleSize >> 3;   
+   sh->channels = c->cNumChannels;
+  
+   sh->i_bps = sh->samplesize * sh->samplerate * sh->channels ;
+  
+    aiff_decode_factor = sh->samplesize * sh->channels - 1;
+        
+    return 1;
+}
+
+static void uninit(sh_audio_t *sh)
+{
+   return;
+}
+
+static int control(sh_audio_t *sh, int cmd, void* arg, ...)
+{
+   return CONTROL_UNKNOWN;
+}
+
+static int decode_audio(sh_audio_t *sh, unsigned char *buf, int minlen, int maxlen)
+{
+    int             i;
+    int             n;
+    unsigned char   x;
+    
+    n = (minlen + aiff_decode_factor) & (~aiff_decode_factor);
+    n = demux_read_data(sh->ds, buf, n);
+  
+#ifndef WORDS_BIGENDIAN
+    for (i = 0 ; i < n; i = i + 2)
+    {
+        x = buf[i];
+        buf[i]=buf[i+1];
+        buf[i+1]=x;
+    }
+#endif
+
+    return  n;
+
+}
+
diff -Nrup main/libmpdemux/Makefile main-aiff/libmpdemux/Makefile
--- main/libmpdemux/Makefile    2004-11-20 09:46:22.000000000 -0500
+++ main-aiff/libmpdemux/Makefile   2004-12-08 04:58:04.000000000 -0500
@@ -3,7 +3,7 @@ LIBNAME = libmpdemux.a
 
 include ../config.mak
 
-SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c demux_bmp.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c
+SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c demux_bmp.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c aiff.c
 ifeq ($(XMMS_PLUGINS),yes)
 SRCS += demux_xmms.c
 endif 
diff -Nrup main/libmpdemux/aiff.c main-aiff/libmpdemux/aiff.c
--- main/libmpdemux/aiff.c  1969-12-31 19:00:00.000000000 -0500
+++ main-aiff/libmpdemux/aiff.c 2004-12-08 04:58:02.000000000 -0500
@@ -0,0 +1,169 @@
+/*
+   AIFF Audio Utilities
+   
+   Copyright (c) 2004, Jake Luck <mplay at 10k.org>
+   All rights reserved.
+   BSD License
+   http://www.opensource.org/licenses/bsd-license.php
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "stream.h"
+#include "aiff.h"
+#include "bswap.h"
+
+AIFF_HEADER * 
+get_aiff_header(stream_t *s)
+{
+   AIFF_HEADER             *h;
+    AIFF_FORMCHUNK          *fc;
+    AIFF_COMMONCHUNK        *cc;
+    AIFF_SOUNDDATACHUNK     *sc;
+   
+   h = (AIFF_HEADER *)malloc(sizeof(AIFF_HEADER));
+   if (h == NULL)      goto abort;
+
+    fc = &(h->f);
+    cc = &(h->c);
+    sc = &(h->s);
+
+    /* read form chunk */
+    if ( stream_read(s, (char *)&(fc->fId), 4) != 4 )      goto abort;
+    if ( stream_read(s, (char *)&(fc->fSize), 4) != 4)     goto abort;
+    if ( stream_read(s, (char *)&(fc->fFormat), 4) != 4)   goto abort;
+    
+    /* read common chunk */
+    if ( stream_read(s, (char *)&(cc->cId), 4) != 4)               goto abort;
+    if ( stream_read(s, (char *)&(cc->cSize), 4) != 4)             goto abort;
+    if ( stream_read(s, (char *)&(cc->cNumChannels), 2) != 2)      goto abort;
+    if ( stream_read(s, (char *)&(cc->cSampleFrames), 4) != 4)     goto abort;
+    if ( stream_read(s, (char *)&(cc->cSampleSize), 2) != 2)       goto abort;
+    if ( stream_read(s, (char *)&(cc->cSampleRate[0]), 4) != 4)    goto abort;
+    if ( stream_read(s, (char *)&(cc->cSampleRate[4]), 4) != 4)    goto abort;
+    if ( stream_read(s, (char *)&(cc->cPadd), 2) != 2)             goto abort;
+    
+    /* read sound data chunk */
+    if ( stream_read(s, (char *)&(sc->sId), 4) != 4)           goto abort;
+    if ( stream_read(s, (char *)&(sc->sSize), 4) != 4)         goto abort;
+    if ( stream_read(s, (char *)&(sc->sOffset), 4) != 4)       goto abort;
+    if ( stream_read(s, (char *)&(sc->sAlignSize), 4) != 4)    goto abort;
+    
+    /* fix endian issue */
+    fc->fSize        = be2me_32(fc->fSize);
+
+    cc->cSize        = be2me_32(cc->cSize);
+    cc->cNumChannels = be2me_16(cc->cNumChannels);
+    cc->cSampleFrames= be2me_32(cc->cSampleFrames);
+    cc->cSampleSize  = be2me_16(cc->cSampleSize);
+
+    sc->sSize        = be2me_32(sc->sSize);
+    sc->sOffset      = be2me_32(sc->sOffset);
+    sc->sAlignSize   = be2me_32(sc->sAlignSize);
+
+   return h;
+       
+abort:
+    if (h != NULL)  free(h);
+    return NULL;
+}
+
+/*
+    demuxer->movi_end uses absolute file location
+    
+    ssnd chunksize already includes
+        its offset field (4 bytes)
+        its align field (4 bytes)
+    
+    hence 
+    sounddata_end = ssnd_chunksize - partial ssnd header + headersize
+*/
+off_t  
+endpos_aiff_pcm(AIFF_HEADER *h)
+{
+   AIFF_FORMCHUNK          *f;
+   AIFF_COMMONCHUNK        *c;
+   AIFF_SOUNDDATACHUNK     *s;
+   int         n;
+   off_t       w;
+   
+   f = &(h->f);
+   c = &(h->c);
+   s = &(h->s);
+   
+   w = s->sSize - 8 + 54;
+   
+   return w;
+}
+
+/*  
+    convert the extended 8 byte sample rate to int
+*/
+int
+samplerate_aiff_pcm(unsigned char *sr)
+{
+    int     r;
+    
+   if      ( memcmp(sr, "\x40\x0E\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+       r = 44100;
+    else if ( memcmp(sr, "\x40\x0E\xBB\x80\x00\x00\x00\x00", 8) == 0 )
+        r = 48000;    
+    else if ( memcmp(sr, "\x40\x0D\xFA\x00\x00\x00\x00\x00", 8) == 0 )
+        r = 32000; 
+    else if ( memcmp(sr, "\x40\x0D\xBB\x80\x00\x00\x00\x00", 8) == 0 )
+        r = 24000; 
+    else if ( memcmp(sr, "\x40\x0D\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+        r = 22050; 
+    else if ( memcmp(sr, "\x40\x0C\xFA\x00\x00\x00\x00\x00", 8) == 0 )
+        r = 16000; 
+    else if ( memcmp(sr, "\x40\x0C\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+        r = 11025; 
+    else if ( memcmp(sr, "\x40\x0B\xFA\x00\x00\x00\x00\x00", 8) == 0 )
+        r = 8000; 
+        
+    return r;
+}
+
+void 
+print_aiff_header(AIFF_HEADER *h)
+{
+   AIFF_FORMCHUNK          *f;
+   AIFF_COMMONCHUNK        *c;
+   AIFF_SOUNDDATACHUNK     *s;
+   int     n;
+   
+   f = &(h->f);
+   c = &(h->c);
+   s = &(h->s);
+
+    printf("---------------------------------------\n");
+    printf("FORM id %c%c%c%c\n", f->fId[0], f->fId[1], f->fId[2], f->fId[3]);
+    printf("FORM size : %d\n",f->fSize);
+    printf("FORM format %c%c%c%c\n\n", f->fFormat[0], f->fFormat[1], 
+                                       f->fFormat[2], f->fFormat[3]);
+    
+    printf("COMMON id %c%c%c%c\n", c->cId[0], c->cId[1], c->cId[2], c->cId[3]);
+    printf("COMMON size : %d\n", c->cSize);
+    printf("COMMON channel: %d\n", c->cNumChannels);
+    printf("COMMON sample frames : %d\n", c->cSampleFrames);
+    printf("COMMON sample size : %d\n", c->cSampleSize);
+    printf("COMMON sample rate : %08X %08X\n", *((unsigned int *)(&(c->cSampleRate[0]))),
+                                               *((unsigned int *)(&(c->cSampleRate[4]))));
+    printf("COMMON pad %c%c\n\n", c->cPadd[0], c->cPadd[1]);
+    
+    printf("SSND id %c%c%c%c\n", s->sId[0], s->sId[1], s->sId[2], s->sId[3]);
+    printf("SSND size : %d\n", s->sSize);
+    printf("SSND offset : %d\n", s->sOffset);
+    printf("SSND alignsize : %d\n", s->sAlignSize);
+    printf("---------------------------------------\n");
+    printf("SSND  sample bytes: %d\n", s->sSize - 8);
+   printf("Total sample bytes: %d\n", c->cNumChannels * c->cSampleFrames * 
+                                      c->cSampleSize>>3);
+
+}
+
diff -Nrup main/libmpdemux/aiff.h main-aiff/libmpdemux/aiff.h
--- main/libmpdemux/aiff.h  1969-12-31 19:00:00.000000000 -0500
+++ main-aiff/libmpdemux/aiff.h 2004-12-08 04:58:02.000000000 -0500
@@ -0,0 +1,50 @@
+/*
+   AIFF Audio Header
+   based on the Apple specification documented at 
+   http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.36.htm
+   
+   Copyright (c) 2004, Jake Luck <mplay at 10k.org>
+   All rights reserved.
+   BSD License
+   http://www.opensource.org/licenses/bsd-license.php
+*/
+
+#ifndef __AIFF_HEADER_H
+#define __AIFF_HEADER_H 1
+
+typedef struct __attribute__((__packed__)) aiffformchunk_tag {
+   unsigned char   fId[4];
+   unsigned long   fSize;
+   unsigned char   fFormat[4];
+} AIFF_FORMCHUNK;  /* 12 bytes */
+
+typedef struct __attribute__((__packed__)) aiffcommonchunk_tag {
+   unsigned char   cId[4];
+   unsigned long   cSize;
+   unsigned short  cNumChannels;
+   unsigned long   cSampleFrames;
+   unsigned short  cSampleSize;
+   unsigned char   cSampleRate[8];
+   unsigned char   cPadd[2];
+} AIFF_COMMONCHUNK;    /* 26 bytes */
+
+typedef struct __attribute__((__packed__)) aiffsounddatachunk_tag {
+   unsigned char   sId[4];
+   unsigned long   sSize;
+   unsigned long   sOffset;
+   unsigned long   sAlignSize;
+} AIFF_SOUNDDATACHUNK; /* 16 bytes */
+
+
+typedef struct __attribute__((__packed__)) aiffheader_tag {
+   AIFF_FORMCHUNK          f;
+   AIFF_COMMONCHUNK        c;
+   AIFF_SOUNDDATACHUNK     s;
+} AIFF_HEADER;     /* 54 bytes */
+
+AIFF_HEADER *get_aiff_header(stream_t *s);
+void   print_aiff_header(AIFF_HEADER *h);
+off_t  endpos_aiff_pcm(AIFF_HEADER *h);
+int     samplerate_aiff_pcm(unsigned char *sr);
+
+#endif
diff -Nrup main/libmpdemux/demux_audio.c main-aiff/libmpdemux/demux_audio.c
--- main/libmpdemux/demux_audio.c   2004-09-28 13:05:44.000000000 -0400
+++ main-aiff/libmpdemux/demux_audio.c  2004-12-08 05:05:17.000000000 -0500
@@ -9,6 +9,7 @@
 #include "stheader.h"
 #include "genres.h"
 #include "mp3_hdr.h"
+#include "aiff.h"
 
 #include <string.h>
 #ifdef MP_DEBUG
@@ -18,6 +19,7 @@
 #define MP3 1
 #define WAV 2
 #define fLaC 3
+#define AIFF 4
 
 
 #define HDR_SIZE 4
@@ -167,6 +169,10 @@ int demux_audio_open(demuxer_t* demuxer)
       frmt = fLaC;
       stream_skip(s,-4);
       break;
+    } else if( hdr[0] == 'F' && hdr[1] == 'O' && hdr[2] == 'R' && hdr[3] == 'M' ) {
+      frmt = AIFF;
+      stream_skip(s,-4);
+      break;
     }
     // Add here some other audio format detection
     if(step < HDR_SIZE)
@@ -330,7 +336,41 @@ int demux_audio_open(demuxer_t* demuxer)
        demuxer->movi_start = stream_tell(s);
        demuxer->movi_end = s->end_pos;
        break;
+  case AIFF: {
+  
+   sh_audio->ah = get_aiff_header(s);
+   
+   if(verbose>0) print_aiff_header(sh_audio->ah);
+   
+/*  this code works and relies on ad_pcm.c to process the data.
+    unfortunately, neither the existing decode_audio()
+    in ad_pcm.c nor the -ao dsound and win32 performs the 
+    necessary byteswapping. hence big endian data are not 
+    correctly massaged when run on little endian machines.
+    this has been tested and verified on both cygwin and xbox
+    on 2004-12-08. in the meantime please use the included
+    ad_aiffpcm.c decoder as an interim solution
+
+   WAVEFORMATEX* w;
+   sh_audio->wf = w = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX));
+    w->wFormatTag = sh_audio->format = 0x20776172;      // "raw "
+    w->nChannels = sh_audio->channels = sh_audio->ah->c.cNumChannels;
+    w->nSamplesPerSec = sh_audio->samplerate = samplerate_aiff_pcm(sh_audio->ah->c.cSampleRate);
+    w->wBitsPerSample = sh_audio->samplesize = sh_audio->ah->c.cSampleSize ;
+    w->nAvgBytesPerSec = sh_audio->channels * sh_audio->samplerate * sh_audio->samplesize>>3;
+    w->nBlockAlign = (sh_audio->channels * sh_audio->samplesize)>>3;
+    w->cbSize = 0;
+    
+    if(verbose>0) print_wave_header(w);
+*/
+   sh_audio->format = 0x6669612E;  // ".aif"
+
+   demuxer->movi_start = stream_tell(s);
+   demuxer->movi_end = endpos_aiff_pcm(sh_audio->ah);
+   }
+    break;
   }
+  
 
   priv = (da_priv_t*)malloc(sizeof(da_priv_t));
   priv->frmt = frmt;
@@ -423,6 +463,16 @@ int demux_audio_fill_buffer(demux_stream
     ds_add_packet(ds,dp);
     return 1;
   }
+  case AIFF : {
+    int l = sh_audio->i_bps;
+    demux_packet_t*  dp = new_demux_packet(l);
+    l = stream_read(s,dp->buffer,l);
+    resize_demux_packet(dp, l);
+    priv->last_pts = priv->last_pts < 0 ? 0 : priv->last_pts + l/(float)sh_audio->i_bps;
+    ds->pts = priv->last_pts - (ds_tell_pts(demux->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
+    ds_add_packet(ds,dp);
+    return 1;
+  }
   default:
     printf("Audio demuxer : unknown format %d\n",priv->frmt);
   }
diff -Nrup main/libmpdemux/demuxer.c main-aiff/libmpdemux/demuxer.c
--- main/libmpdemux/demuxer.c   2004-11-25 17:24:00.000000000 -0500
+++ main-aiff/libmpdemux/demuxer.c  2004-12-08 05:11:21.000000000 -0500
@@ -102,6 +102,7 @@ sh_audio_t* new_sh_audio(demuxer_t *demu
 void free_sh_audio(sh_audio_t* sh){
     mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing sh_audio at %p\n",sh);
     if(sh->wf) free(sh->wf);
+    if(sh->ah) free(sh->ah);
     free(sh);
 }
 
diff -Nrup main/libmpdemux/extension.c main-aiff/libmpdemux/extension.c
--- main/libmpdemux/extension.c 2004-08-21 15:17:17.000000000 -0400
+++ main-aiff/libmpdemux/extension.c    2004-12-08 04:58:04.000000000 -0500
@@ -36,6 +36,7 @@ static struct {
         { "y4m", DEMUXER_TYPE_Y4M },
         { "mp3", DEMUXER_TYPE_AUDIO },
         { "wav", DEMUXER_TYPE_AUDIO },
+        { "aif", DEMUXER_TYPE_AUDIO },
         { "flac", DEMUXER_TYPE_AUDIO },
         { "fla", DEMUXER_TYPE_AUDIO },
         { "ogg", DEMUXER_TYPE_OGG },
diff -Nrup main/libmpdemux/stheader.h main-aiff/libmpdemux/stheader.h
--- main/libmpdemux/stheader.h  2004-04-28 06:18:33.000000000 -0400
+++ main-aiff/libmpdemux/stheader.h 2004-12-08 04:58:05.000000000 -0500
@@ -3,6 +3,7 @@
 
 #include "aviheader.h"
 #include "ms_hdr.h"
+#include "aiff.h"
 
 // Stream headers:
 
@@ -41,6 +42,8 @@ typedef struct {
   // win32-compatible codec parameters:
   AVIStreamHeader audio;
   WAVEFORMATEX* wf;
+  // aiff codec parameters:
+  AIFF_HEADER  *ah;
   // codec-specific:
   void* context; // codec-specific stuff (usually HANDLE or struct pointer)
   unsigned char* codecdata; // extra header data passed from demuxer to codec


More information about the MPlayer-dev-eng mailing list