diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index c7d7922..ac87454 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -926,7 +926,7 @@ int Cdrtrack_extract_audio(struct CdrtracK *track, int *fd, off_t *xtr_size, #ifdef Cdrskin_libburn_has_audioxtR struct libdax_audioxtr *xtr= NULL; char *fmt,*fmt_info; - int num_channels,sample_rate,bits_per_sample,ret; + int num_channels,sample_rate,bits_per_sample,msb_first,ret; #endif *fd= -1; @@ -952,7 +952,7 @@ int Cdrtrack_extract_audio(struct CdrtracK *track, int *fd, off_t *xtr_size, if(ret<=0) return(ret); libdax_audioxtr_get_id(xtr,&fmt,&fmt_info, - &num_channels,&sample_rate,&bits_per_sample,0); + &num_channels,&sample_rate,&bits_per_sample,&msb_first,0); if(strcmp(fmt,".wav")!=0 || num_channels!=2 || sample_rate!=44100 || bits_per_sample!=16) { fprintf(stderr,"cdrskin: ( %s )\n",fmt_info); diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 37bb709..facd8ee 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2006.10.23.134719" +#define Cdrskin_timestamP "2006.10.24.075039" diff --git a/libburn/libdax_audioxtr.c b/libburn/libdax_audioxtr.c index d6b1752..5f9037d 100644 --- a/libburn/libdax_audioxtr.c +++ b/libburn/libdax_audioxtr.c @@ -41,11 +41,16 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag) o->data_size= 0; o->extract_count= 0; - o->wav_num_channels= 0; - o->wav_sample_rate= 0; - o->wav_bits_per_sample= 0; + o->num_channels= 0; + o->sample_rate= 0; + o->bits_per_sample= 0; + o->msb_first= 0; + o->wav_subchunk2_size= 0; + o->au_data_location= 0; + o->au_data_size= 0xffffffff; + ret= libdax_audioxtr_open(o,0); if(ret<=0) {ret= -2*(ret<0); goto failure;} @@ -108,14 +113,19 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag) } -static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag) +static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag) { int ret; char buf[45]; - /* currently this only works for MS WAVE files .wav */ + /* check wether this is a MS WAVE file .wav */ /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ + if(o->fd!=0) { + ret= lseek(o->fd,0,SEEK_SET); + if(ret==-1) + return(0); + } ret= read(o->fd, buf, 44); if(ret<44) return(0); @@ -133,27 +143,99 @@ static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag) return(0); strcpy(o->fmt,".wav"); - o->wav_num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0); - o->wav_sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0); - o->wav_bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0); + o->msb_first= 0; + o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0); + o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0); + o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0); sprintf(o->fmt_info, ".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d", - o->wav_num_channels,o->wav_sample_rate,o->wav_bits_per_sample); + o->num_channels,o->sample_rate,o->bits_per_sample); o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0); o->data_size= o->wav_subchunk2_size; - return(1); } +static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag) +{ + int ret,encoding; + char buf[24]; + + /* Check wether this is a Sun Audio, .au file */ + /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ + + if(o->fd!=0) { + ret= lseek(o->fd,0,SEEK_SET); + if(ret==-1) + return(0); + } + ret= read(o->fd, buf, 24); + if(ret<24) + return(0); + + if(strncmp(buf,".snd",4)!=0) + return(0); + strcpy(o->fmt,".au"); + o->msb_first= 1; + o->au_data_location= libdax_audioxtr_to_int(o,(unsigned char *)buf+4,4,1); + o->au_data_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+8,4,1); + encoding= libdax_audioxtr_to_int(o,(unsigned char *)buf+12,4,1); + if(encoding==2) + o->bits_per_sample= 8; + else if(encoding==3) + o->bits_per_sample= 16; + else if(encoding==4) + o->bits_per_sample= 24; + else if(encoding==5) + o->bits_per_sample= 32; + else + o->bits_per_sample= -encoding; + o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *)buf+16,4,1); + o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *)buf+20,4,1); + if(o->au_data_size!=0xffffffff) + o->data_size= o->au_data_size; + else + o->data_size= 0; + sprintf(o->fmt_info, + ".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d", + o->num_channels,o->sample_rate,o->bits_per_sample); + + /* <<< for testing only */; + return(1); + + return(o->bits_per_sample>0); /* Audio format must be linear PCM */ +} + + +static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag) +{ + int ret; + + ret= libdax_audioxtr_identify_wav(o, 0); + if(ret!=0) + return(ret); + if(o->fd==0) /* cannot rewind stdin */ + return(0); + ret= libdax_audioxtr_identify_au(o, 0); + if(ret!=0) + return(ret); + return(0); +} + + +/* @param flag bit0=msb_first */ static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o, unsigned char *bytes, int len, int flag) { unsigned int ret= 0; int i; - for(i= len-1; i>=0; i--) - ret= ret*256+bytes[i]; + if(flag&1) + for(i= 0; i=0; i--) + ret= ret*256+bytes[i]; return(ret); } @@ -162,12 +244,18 @@ static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag) { int ret; - /* currently this only works for MS WAVE files .wav */; + + /* currently this only works for MS WAVE files .wav and Sun .au*/; if(o->fd==0) /* stdin: hope no read came after libdax_audioxtr_identify() */ return(1); o->extract_count= 0; - ret= lseek(o->fd,44,SEEK_SET); + if(strcmp(o->fmt,".wav")==0) + ret= lseek(o->fd,44,SEEK_SET); + else if(strcmp(o->fmt,".au")==0) + ret= lseek(o->fd,o->au_data_location,SEEK_SET); + else + ret= -1; if(ret==-1) return(0); @@ -178,28 +266,22 @@ static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag) int libdax_audioxtr_get_id(struct libdax_audioxtr *o, char **fmt, char **fmt_info, int *num_channels, int *sample_rate, int *bits_per_sample, - int flag) + int *msb_first, int flag) { *fmt= o->fmt; *fmt_info= o->fmt_info; - if(strcmp(o->fmt,".wav")==0) { - *num_channels= o->wav_num_channels; - *sample_rate= o->wav_sample_rate; - *bits_per_sample= o->wav_bits_per_sample; - } else - *num_channels= *sample_rate= *bits_per_sample= 0; + *num_channels= o->num_channels; + *sample_rate= o->sample_rate; + *bits_per_sample= o->bits_per_sample; + *msb_first= o->msb_first; return(1); } int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag) { - if(strcmp(o->fmt,".wav")==0) { - *size= o->wav_subchunk2_size; - return(1); - } - *size= 0; - return(0); + *size= o->data_size; + return(1); } @@ -226,7 +308,7 @@ int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag) { if(o->fd<0) return(-1); - if(strcmp(o->fmt,".wav")!=0) + if(strcmp(o->fmt,".wav")!=0 && strcmp(o->fmt,".au")!=0) return(0); if(flag&1) { *fd= o->fd; diff --git a/libburn/libdax_audioxtr.h b/libburn/libdax_audioxtr.h index 82ae06d..72b62bf 100644 --- a/libburn/libdax_audioxtr.h +++ b/libburn/libdax_audioxtr.h @@ -46,18 +46,19 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag); /** Obtain identification parameters of opened audio source. @param xtr Opaque handle to extractor - @param fmt Gets pointed to the audio file format id text: ".wav" + @param fmt Gets pointed to the audio file format id text: ".wav" , ".au" @param fmt_info Gets pointed to a format info text telling parameters @param num_channels e.g. 1=mono, 2=stereo, etc @param sample_rate e.g. 11025, 44100 @param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ... + @param msb_first Byte order of samples: 0=Intel 1=Motorola @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure */ int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr, char **fmt, char **fmt_info, int *num_channels, int *sample_rate, - int *bits_per_sample, int flag); + int *bits_per_sample, int *msb_first, int flag); /** Obtain a prediction about the extracted size based on internal information @@ -136,7 +137,7 @@ struct libdax_audioxtr { /* Source of the encoded audio data */ char path[LIBDAX_AUDIOXTR_STRLEN]; - /* File descriptor to path */ + /* File descriptor to path. Anything else than 0 must be lseek-able */ int fd; /* Format identifier. E.g. ".wav" */ @@ -145,6 +146,18 @@ struct libdax_audioxtr { /* Format parameter info text */ char fmt_info[LIBDAX_AUDIOXTR_STRLEN]; + /* 1= mono, 2= stereo, etc. */ + int num_channels; + + /* 8000, 44100, etc. */ + int sample_rate; + + /* 8 bits = 8, 16 bits = 16, etc. */ + int bits_per_sample; + + /* Byte order of samples: 0=Intel 1=Motorola */ + int msb_first; + /* Number of bytes to extract (0= unknown/unlimited) */ off_t data_size; @@ -157,19 +170,20 @@ struct libdax_audioxtr { /* MS WAVE Format */ /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ - /* 1= mono, 2= stereo, etc. */ - int wav_num_channels; - - /* 8000, 44100, etc. */ - int wav_sample_rate; - - /* 8 bits = 8, 16 bits = 16, etc. */ - int wav_bits_per_sample; - /* == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data. */ unsigned wav_subchunk2_size; + + /* Sun Audio, .au */ + /* info used: http://www.opengroup.org/public/pubs/external/auformat.html */ + + /* Number of bytes in non-payload header part */ + unsigned au_data_location; + + /* Number of payload bytes or 0xffffffff */ + unsigned au_data_size; + }; @@ -186,8 +200,15 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag); */ static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag); +/** Specialized identifier for .wav */ +static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag); +/** Specialized identifier for .au */ +static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag); + /** Convert a byte string into a number (currently only little endian) + @param flag Bitfield for control purposes + bit0=msb_first @return The resulting number */ static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o, diff --git a/test/dewav.c b/test/dewav.c index 00d7aee..8010fdd 100644 --- a/test/dewav.c +++ b/test/dewav.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) /* Inquired source parameters */ char *fmt, *fmt_info; - int num_channels, sample_rate, bits_per_sample; + int num_channels, sample_rate, bits_per_sample, msb_first; off_t data_size; /* Auxiliary variables */ @@ -142,7 +142,7 @@ help:; } /* Obtain and print parameters of audio source */ libdax_audioxtr_get_id(xtr, &fmt, &fmt_info, - &num_channels, &sample_rate, &bits_per_sample, 0); + &num_channels, &sample_rate, &bits_per_sample, &msb_first, 0); fprintf(stderr, "Detected format: %s\n", fmt_info); libdax_audioxtr_get_size(xtr, &data_size, 0); fprintf(stderr, "Data size : %.f bytes\n", (double) data_size);