[MPlayer-dev-eng] [PATCH] new codec AIFF PCM Audio support

Jake Luck mplay at 10k.org
Sat Jul 17 08:38:55 CEST 2004


* added AIFF PCM playback
* properly skips Apple's embedded ID3 tags
* supports 16bit 44.1kHZ (for now)
* diffed against latest CVS

enjoy.

jake
-------------- next part --------------
diff -Nrup main/codec-cfg.c main-aiff/codec-cfg.c
--- main/codec-cfg.c	2004-07-16 02:30:26.000000000 -0400
+++ main-aiff/codec-cfg.c	2004-07-16 02:30:30.000000000 -0400
@@ -251,6 +251,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-07-16 02:30:27.000000000 -0400
+++ main-aiff/etc/codecs.conf	2004-07-16 02:30:31.000000000 -0400
@@ -2193,6 +2193,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-07-16 02:30:28.000000000 -0400
+++ main-aiff/libmpcodecs/Makefile	2004-07-16 02:30:33.000000000 -0400
@@ -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-16 02:30:28.000000000 -0400
+++ main-aiff/libmpcodecs/ad.c	2004-07-16 02:30:33.000000000 -0400
@@ -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-07-16 02:30:33.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+	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"
+
+static ad_info_t info = 
+{
+	"Uncompressed AIFF PCM audio decoder",
+	"aiffpcm",
+	"Jake Luck",
+	"",
+	""
+};
+
+LIBAD_EXTERN(aiffpcm)
+
+#include "aiff.h"
+
+static int preinit(sh_audio_t *sh)
+{
+	sh->audio_out_minsize=4096;
+  	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);
+
+	if (c->cSampleSize == 16)
+		sh->sample_format = AFMT_S16_BE;
+	
+	if ( memcmp(c->cSampleRate, "\x40\x0E\xAC\x44\x00\x00\x00\x00", 8) == 0 )
+  		sh->samplerate = 44100;
+  		
+  	sh->samplesize = c->cSampleSize >> 3;  	
+  	sh->channels = c->cNumChannels;
+  
+  	sh->i_bps = sh->samplesize * sh->samplerate * sh->channels ;
+  
+    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_audio,unsigned char *buf,int minlen,int maxlen)
+{
+	return demux_read_data(sh_audio->ds, buf, minlen);
+}
diff -Nrup main/libmpdemux/Makefile main-aiff/libmpdemux/Makefile
--- main/libmpdemux/Makefile	2004-07-16 02:30:29.000000000 -0400
+++ main-aiff/libmpdemux/Makefile	2004-07-16 02:30:33.000000000 -0400
@@ -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-07-16 02:30:33.000000000 -0400
@@ -0,0 +1,140 @@
+/*
+	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 <sys/uio.h>
+#include <unistd.h>
+
+#include "stream.h"
+#include "aiff.h"
+
+
+AIFF_HEADER * 
+get_aiff_header(stream_t *s)
+{
+	int		n;
+	
+	/*  direct map the first 54 bytes */
+	AIFF_HEADER		*h;
+	
+	h = (AIFF_HEADER *)malloc(sizeof(AIFF_HEADER));
+	if (h != NULL)
+	{
+		n = stream_read(s, h, sizeof(AIFF_HEADER));
+		// printf ("aiff header: %d bytes read\n", n);
+	}
+	
+	return h;
+}
+
+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;
+}
+
+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("Channels : %d\n", c->cNumChannels);
+	printf("Total Frames: %d\n", c->cSampleFrames);
+	printf("Bits Per Sample : %d\n", c->cSampleSize);
+	
+	printf("SSND  sample bytes: %d\n", s->sSize - 8);
+	printf("Total sample bytes: %d\n", c->cNumChannels * c->cSampleFrames * 
+									   c->cSampleSize>>3);
+	
+}
+
+
+// output a test header to make sure we are packing correctly
+void writetestheader(void);
+
+void 
+writetestheader(void)
+{
+	int				fd;
+	int				n;
+	AIFF_HEADER				h;
+	
+	AIFF_FORMCHUNK			*f;
+	AIFF_COMMONCHUNK		*c;
+	AIFF_SOUNDDATACHUNK		*s;
+	
+	f = &(h.f);
+	c = &(h.c);
+	s = &(h.s);
+	
+	// form chunk
+	f->fId[0]	= 'F';
+	f->fId[1]	= 'O';
+	f->fId[2]	= 'R';
+	f->fId[3]	= 'M';
+	f->fSize	= 4071216;
+	memcpy(f->fFormat, "AIFF", 4);
+	
+	// common chunk
+	memcpy(c->cId, "COMM", 4);
+	c->cSize			= 18;
+	c->cNumChannels 	= 2;
+	c->cSampleFrames	= 1017240;
+	c->cSampleSize		= 16;
+	memcpy(c->cSampleRate, "\x40\x0E\xAC\x44\x00\x00\x00\x00", 8);
+	c->cPadd[0] = '0';
+	c->cPadd[1] = '0';
+	
+	// sound data chunk
+	memcpy(s->sId, "SSND", 4);
+	s->sSize   		= 4068968;
+	s->sOffset 		= 0;
+	s->sAlignSize	= 0;
+
+	fd = open("testheader.aiff",  O_WRONLY);
+	n = write(fd, &h, sizeof(AIFF_HEADER));
+	printf("form = %d, common = %d, sounddata = %d\n", 
+			sizeof(AIFF_FORMCHUNK),
+			sizeof(AIFF_COMMONCHUNK),
+			sizeof(AIFF_SOUNDDATACHUNK));
+			
+	printf("%d bytes written\n", n);
+	close(fd);
+	
+}
+
+/*
+int main(void)
+{
+	writetestheader();	
+}
+*/
\ No newline at end of file
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-07-16 02:30:33.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+	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);
+
+#endif
\ No newline at end of file
diff -Nrup main/libmpdemux/demux_audio.c main-aiff/libmpdemux/demux_audio.c
--- main/libmpdemux/demux_audio.c	2004-07-16 02:30:28.000000000 -0400
+++ main-aiff/libmpdemux/demux_audio.c	2004-07-16 02:30:33.000000000 -0400
@@ -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
@@ -84,6 +86,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)
@@ -212,7 +218,19 @@ 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);
+	
+	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;
@@ -292,6 +310,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-07-16 02:30:28.000000000 -0400
+++ main-aiff/libmpdemux/demuxer.c	2004-07-16 02:30:33.000000000 -0400
@@ -89,6 +89,7 @@ sh_audio_t* new_sh_audio(demuxer_t *demu
 void free_sh_audio(sh_audio_t* sh){
     mp_msg(MSGT_DEMUXER,MSGL_V,"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-07-16 02:30:28.000000000 -0400
+++ main-aiff/libmpdemux/extension.c	2004-07-16 02:30:33.000000000 -0400
@@ -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-07-16 02:30:29.000000000 -0400
+++ main-aiff/libmpdemux/stheader.h	2004-07-16 02:30:33.000000000 -0400
@@ -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