diff --git a/lib/cdda_interface/common_interface.c b/lib/cdda_interface/common_interface.c index e18293e8..e68a0f94 100644 --- a/lib/cdda_interface/common_interface.c +++ b/lib/cdda_interface/common_interface.c @@ -1,5 +1,5 @@ /* - $Id: common_interface.c,v 1.6 2005/01/09 12:32:19 rocky Exp $ + $Id: common_interface.c,v 1.7 2005/01/13 21:38:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein Copyright (C) 1998, 2002 Monty monty@xiph.org @@ -40,6 +40,8 @@ the transform is looked at to see which has data in the FFT (or audible) portion. (Or so that's how I understand it.) */ + +#if USELIBCDIO_ROUTINES int data_bigendianp(cdrom_drive_t *d) { @@ -51,7 +53,6 @@ data_bigendianp(cdrom_drive_t *d) float *b=calloc(1024,sizeof(float)); long readsectors=5; int16_t *buff=malloc(readsectors*CDIO_CD_FRAMESIZE_RAW); - memset(buff, 0, readsectors*CDIO_CD_FRAMESIZE_RAW); /* look at the starts of the audio tracks */ @@ -173,6 +174,126 @@ data_bigendianp(cdrom_drive_t *d) } } +#else +int data_bigendianp(cdrom_drive *d){ + float lsb_votes=0; + float msb_votes=0; + int i,checked; + int endiancache=d->bigendianp; + float *a=calloc(1024,sizeof(float)); + float *b=calloc(1024,sizeof(float)); + long readsectors=5; + int16_t *buff=malloc(readsectors*CDIO_CD_FRAMESIZE_RAW); + + /* look at the starts of the audio tracks */ + /* if real silence, tool in until some static is found */ + + /* Force no swap for now */ + d->bigendianp=-1; + + cdmessage(d,"\nAttempting to determine drive endianness from data..."); + d->enable_cdda(d,1); + for(i=0,checked=0;itracks;i++){ + float lsb_energy=0; + float msb_energy=0; + if(cdda_track_audiop(d,i+1)==1){ + long firstsector=cdda_track_firstsector(d,i+1); + long lastsector=cdda_track_lastsector(d,i+1); + int zeroflag=-1; + long beginsec=0; + + /* find a block with nonzero data */ + + while(firstsector+readsectors<=lastsector){ + int j; + + if(d->read_audio(d,buff,firstsector,readsectors)>0){ + + /* Avoid scanning through jitter at the edges */ + for(beginsec=0;beginsecenable_cdda(d,0); + free(a); + free(b); + free(buff); + return(-1); + } + } + + beginsec*=CDIO_CD_FRAMESIZE_RAW/2; + + /* un-interleave for an fft */ + if(!zeroflag){ + int j; + + for(j=0;j<128;j++)a[j]=le16_to_cpu(buff[j*2+beginsec+460]); + for(j=0;j<128;j++)b[j]=le16_to_cpu(buff[j*2+beginsec+461]); + fft_forward(128,a,NULL,NULL); + fft_forward(128,b,NULL,NULL); + for(j=0;j<128;j++)lsb_energy+=fabs(a[j])+fabs(b[j]); + + for(j=0;j<128;j++)a[j]=be16_to_cpu(buff[j*2+beginsec+460]); + for(j=0;j<128;j++)b[j]=be16_to_cpu(buff[j*2+beginsec+461]); + fft_forward(128,a,NULL,NULL); + fft_forward(128,b,NULL,NULL); + for(j=0;j<128;j++)msb_energy+=fabs(a[j])+fabs(b[j]); + } + } + if(lsb_energymsb_energy){ + msb_votes+=lsb_energy/msb_energy; + checked++; + } + + if(checked==5 && (lsb_votes==0 || msb_votes==0))break; + cdmessage(d,"."); + } + + free(buff); + free(a); + free(b); + d->bigendianp=endiancache; + d->enable_cdda(d,0); + + /* How did we vote? Be potentially noisy */ + if(lsb_votes>msb_votes){ + char buffer[256]; + cdmessage(d,"\n\tData appears to be coming back little endian.\n"); + sprintf(buffer,"\tcertainty: %d%%\n",(int) + (100.*lsb_votes/(lsb_votes+msb_votes)+.5)); + cdmessage(d,buffer); + return(0); + }else{ + if(msb_votes>lsb_votes){ + char buffer[256]; + cdmessage(d,"\n\tData appears to be coming back big endian.\n"); + sprintf(buffer,"\tcertainty: %d%%\n",(int) + (100.*msb_votes/(lsb_votes+msb_votes)+.5)); + cdmessage(d,buffer); + return(1); + } + + cdmessage(d,"\n\tCannot determine CDROM drive endianness.\n"); + return(bigendianp()); + return(-1); + } +} +#endif + /************************************************************************/ /*! Here we fix up a couple of things that will never happen. yeah, diff --git a/lib/cdda_interface/utils.h b/lib/cdda_interface/utils.h index 88ac4fce..3f96bbcf 100644 --- a/lib/cdda_interface/utils.h +++ b/lib/cdda_interface/utils.h @@ -1,5 +1,5 @@ /* - $Id: utils.h,v 1.3 2004/12/19 01:43:38 rocky Exp $ + $Id: utils.h,v 1.4 2005/01/13 21:38:21 rocky Exp $ Copyright (C) 2004 Rocky Bernstein Copyright (C) 1998 Monty xiphmont@mit.edu @@ -45,6 +45,75 @@ catstring(char *buff,const char *s){ return(buff); } +static inline int32_t swap32(int32_t x){ + return((((u_int32_t)x & 0x000000ffU) << 24) | + (((u_int32_t)x & 0x0000ff00U) << 8) | + (((u_int32_t)x & 0x00ff0000U) >> 8) | + (((u_int32_t)x & 0xff000000U) >> 24)); +} + +static inline int16_t swap16(int16_t x){ + return((((u_int16_t)x & 0x00ffU) << 8) | + (((u_int16_t)x & 0xff00U) >> 8)); +} + +/*#if BYTE_ORDER == LITTLE_ENDIAN*/ + +#ifndef WORDS_BIGENDIAN + +static inline int32_t be32_to_cpu(int32_t x){ + return(swap32(x)); +} + +static inline int16_t be16_to_cpu(int16_t x){ + return(swap16(x)); +} + +static inline int32_t le32_to_cpu(int32_t x){ + return(x); +} + +static inline int16_t le16_to_cpu(int16_t x){ + return(x); +} + +#else + +static inline int32_t be32_to_cpu(int32_t x){ + return(x); +} + +static inline int16_t be16_to_cpu(int16_t x){ + return(x); +} + +static inline int32_t le32_to_cpu(int32_t x){ + return(swap32(x)); +} + +static inline int16_t le16_to_cpu(int16_t x){ + return(swap16(x)); +} + + +#endif + +static inline int32_t cpu_to_be32(int32_t x){ + return(be32_to_cpu(x)); +} + +static inline int32_t cpu_to_le32(int32_t x){ + return(le32_to_cpu(x)); +} + +static inline int16_t cpu_to_be16(int16_t x){ + return(be16_to_cpu(x)); +} + +static inline int16_t cpu_to_le16(int16_t x){ + return(le16_to_cpu(x)); +} + void cderror(cdrom_drive_t *d, const char *s); void cdmessage(cdrom_drive_t *d,const char *s);