/**************************************************************************** | Digital Audio Processor | ======================= | | Filename : raw.c | | Object : None | | Description : Audiofile replacement code for linux (raw files) | | (c) Richard Kent 1998 | | $Id: raw.c,v 1.1 2003/09/10 00:06:24 rk Exp $ | ****************************************************************************/ static char raw_c [] = "$Id: raw.c,v 1.1 2003/09/10 00:06:24 rk Exp $"; #include "audiofile.h" #include "raw.h" #include "macros.h" #include #include /*--------------------------------------------------------------------------- | FUNCTION AFreadRAW ---------------------------------------------------------------------------*/ AFfilehandle AFreadRAW (FHandle file, rawType details) { struct stat s; aiffHandle handleAct; AFfilehandle handle = &handleAct; handle->mode = READONLY; handle->file = file; handle->actualBytes = 0; handle->actualFrames = 0; handle->ssndStart = 0; // Setup defaults in handle->aiff and set to RAW blankSetup (&(handle->aiff)); handle->aiff.sampleFormat = AF_FORMAT_RAW; if (!file) return AF_NULL_FILEHANDLE; // Update AIFF details from RAW details handle->aiff.rawDetails.channels = details.channels; handle->aiff.rawDetails.dataFormat = details.dataFormat; handle->aiff.rawDetails.signedData = details.signedData; handle->aiff.rawDetails.endian = details.endian; handle->aiff.channels = details.channels; // 8 bit for byte format - all others map to 16 bit if (details.dataFormat == AF_BYTE_FORMAT) handle->aiff.width = 8; else handle->aiff.width = 16; // Can calculate frames from size of file if (mStat (file,&s) == -1) return AF_NULL_FILEHANDLE; handle->aiff.framecount = s.st_size / details.channels; switch (details.dataFormat) { case AF_BYTE_FORMAT : break; case AF_SHORT_FORMAT : handle->aiff.framecount /= 2; break; case AF_LONG24_FORMAT : handle->aiff.framecount /= 4; break; case AF_LONG32_FORMAT : handle->aiff.framecount /= 4; break; case AF_FLOAT_FORMAT : handle->aiff.framecount /= 4; break; case AF_DOUBLE_FORMAT : handle->aiff.framecount /= 8; break; default: break; } handle = (AFfilehandle) calloc (1,sizeof (aiffHandle)); *handle = handleAct; return handle; } /*--------------------------------------------------------------------------- | FUNCTION AFwriteRAW ---------------------------------------------------------------------------*/ AFfilehandle AFwriteRAW (FHandle file,AFfilesetup setup) { aiffHandle handleAct; AFfilehandle handle = &handleAct; if (!setup) return AF_NULL_FILEHANDLE; handle->mode = WRITEONLY; handle->file = file; handle->actualBytes = 0; handle->actualFrames = 0; handle->ssndStart = 0; // Copy info from setup into handle->aiff copySetup (setup,&(handle->aiff)); if (!file) return AF_NULL_FILEHANDLE; handle = (AFfilehandle) calloc (1,sizeof (aiffHandle)); *handle = handleAct; return handle; } /*--------------------------------------------------------------------------- | FUNCTION AFclosefileRAW ---------------------------------------------------------------------------*/ int AFclosefileRAW (AFfilehandle handle) { // If error then return negative number if (!handle) return -1; if (mClose (handle->file) == -1) return -1; free (handle); return 0; } /*--------------------------------------------------------------------------- | FUNCTION AFreadframesRAW ---------------------------------------------------------------------------*/ int AFreadframesRAW (AFfilehandle handle,void *frames,int count) { int i; int j; int frameCount; FHandle file; unsigned char uctemp; signed char ctemp; unsigned short ustemp; short stemp; unsigned int uitemp; int itemp; float ftemp; double dtemp; int sample32; if (!handle) return 0; if (handle->mode != READONLY) return 0; file = handle->file; if (!file) return 0; i = 0; frameCount = 0; while (handle->actualFrames < handle->aiff.framecount && frameCount < count && !mEof (file)) { for (j=0; jaiff.channels; j++) { if (handle->aiff.rawDetails.signedData == AF_SIGNED_FORMAT) { switch (handle->aiff.rawDetails.dataFormat) { case AF_BYTE_FORMAT : if (!cRead (file,&ctemp)) return frameCount; sample32 = ctemp << 24; break; case AF_SHORT_FORMAT : if (!sRead (file,&stemp)) return frameCount; sample32 = stemp << 16; break; case AF_LONG24_FORMAT : if (!iRead (file,&itemp)) return frameCount; itemp = AFlimitIValue (itemp,-MAX23,MAX23_1); sample32 = itemp << 8; break; case AF_LONG32_FORMAT : if (!iRead (file,&itemp)) return frameCount; sample32 = itemp; break; case AF_FLOAT_FORMAT : if (!fRead (file,&ftemp)) return frameCount; ftemp = AFlimitFValue (ftemp,-1.0,1.0); sample32 = AFlimitIValue ((int)(ftemp * MAX15),-MAX15,MAX15_1) << 16; break; case AF_DOUBLE_FORMAT : if (!dRead (file,&dtemp)) return frameCount; dtemp = AFlimitDValue (dtemp,-1.0,1.0); sample32 = AFlimitIValue ((int)(dtemp * MAX15),-MAX15,MAX15_1) << 16; break; default : return frameCount; } } else { switch (handle->aiff.rawDetails.dataFormat) { case AF_BYTE_FORMAT : if (!ucRead (file,&uctemp)) return frameCount; sample32 = (uctemp - MAX7) << 24; break; case AF_SHORT_FORMAT : if (!usRead (file,&ustemp)) return frameCount; sample32 = (ustemp - MAX15) << 16; break; case AF_LONG24_FORMAT : if (!uiRead (file,&uitemp)) return frameCount; uitemp = AFlimitIValue (uitemp,0,MAX24_1); sample32 = (uitemp - MAX23) << 8; break; case AF_LONG32_FORMAT : if (!uiRead (file,&uitemp)) return frameCount; sample32 = ((uitemp >> 16) - MAX15) << 16; break; case AF_FLOAT_FORMAT : if (!fRead (file,&ftemp)) return frameCount; ftemp = AFlimitFValue (ftemp,0.0,1.0); sample32 = AFlimitIValue ((int)((ftemp - 0.5) * MAX16),-MAX15,MAX15_1) << 16; break; case AF_DOUBLE_FORMAT : if (!dRead (file,&dtemp)) return frameCount; dtemp = AFlimitDValue (dtemp,0.0,1.0); sample32 = AFlimitIValue ((int)((dtemp - 0.5) * MAX16),-MAX15,MAX15_1) << 16; break; default : return frameCount; } } if (handle->aiff.width <= 8) { (((signed char *) frames) [i++]) = sample32 >> 24; } else if (handle->aiff.width <= 16) { (((short *) frames) [i++]) = sample32 >> 16; } else if (handle->aiff.width <= 32) { (((int *) frames) [i++]) = sample32; } } frameCount++; handle->actualFrames++; } return frameCount; } /*--------------------------------------------------------------------------- | FUNCTION AFwriteframesRAW ---------------------------------------------------------------------------*/ int AFwriteframesRAW (AFfilehandle handle,void *frames,int count) { int i; int j; int frameCount; FHandle file; unsigned char uctemp; signed char ctemp; unsigned short ustemp; short stemp; unsigned int uitemp; int itemp; float ftemp; double dtemp; int sample32; if (!handle) return 0; if (handle->mode != WRITEONLY) return 0; file = handle->file; if (!file) return 0; i = 0; frameCount = 0; while (frameCount < count && !mEof (file)) { for (j=0; jaiff.channels; j++) { if (handle->aiff.width <= 8) { sample32 = (((signed char *) frames) [i++]) << 24; } else if (handle->aiff.width <= 16) { sample32 = (((short *) frames) [i++]) << 16; } else { sample32 = (((int *) frames) [i++]); } if (handle->aiff.rawDetails.signedData == AF_SIGNED_FORMAT) { switch (handle->aiff.rawDetails.dataFormat) { case AF_BYTE_FORMAT : ctemp = sample32 >> 24; if (!cWrite (file,ctemp)) return frameCount; handle->actualBytes += sizeof(ctemp); break; case AF_SHORT_FORMAT : stemp = sample32 >> 16; if (!sWrite (file,stemp)) return frameCount; handle->actualBytes += sizeof(stemp); break; case AF_LONG24_FORMAT : itemp = sample32 >> 8; if (!iWrite (file,itemp)) return frameCount; handle->actualBytes += sizeof(itemp); break; case AF_LONG32_FORMAT : itemp = sample32; if (!iWrite (file,itemp)) return frameCount; handle->actualBytes += sizeof(itemp); break; case AF_FLOAT_FORMAT : ftemp = ((float) sample32) / (float) MAX31; if (!fWrite (file,ftemp)) return frameCount; handle->actualBytes += sizeof(ftemp); break; case AF_DOUBLE_FORMAT : dtemp = ((double) sample32) / (double) MAX31; if (!dWrite (file,dtemp)) return frameCount; handle->actualBytes += sizeof(dtemp); break; default : return frameCount; } } else { switch (handle->aiff.rawDetails.dataFormat) { case AF_BYTE_FORMAT : uctemp = (sample32 >> 24) + MAX7; if (!ucWrite (file,uctemp)) return frameCount; handle->actualBytes += sizeof(uctemp); break; case AF_SHORT_FORMAT : ustemp = (sample32 >> 16) + MAX15; if (!usWrite (file,ustemp)) return frameCount; handle->actualBytes += sizeof(ustemp); break; case AF_LONG24_FORMAT : uitemp = (sample32 >> 8) + MAX23; if (!uiWrite (file,uitemp)) return frameCount; handle->actualBytes += sizeof(uitemp); break; case AF_LONG32_FORMAT : uitemp = ((sample32 >> 16) + MAX15) << 16; if (!uiWrite (file,uitemp)) return frameCount; handle->actualBytes += sizeof(uitemp); break; case AF_FLOAT_FORMAT : #ifdef USINGGCC ftemp = (((float) sample32) / (float) MAX32) + 0.5; #else ftemp = (((float) sample32) / (float) MAX16); ftemp = (ftemp / (float) MAX16) + 0.5; #endif if (!fWrite (file,ftemp)) return frameCount; handle->actualBytes += sizeof(ftemp); break; case AF_DOUBLE_FORMAT : #ifdef USINGGCC dtemp = (((double) sample32) / (double) MAX32) + 0.5; #else dtemp = (((double) sample32) / (double) MAX16); dtemp = (dtemp / (double) MAX16) + 0.5; #endif if (!dWrite (file,dtemp)) return frameCount; handle->actualBytes += sizeof(dtemp); break; default : return frameCount; } } } frameCount++; handle->actualFrames++; } return frameCount; } /*--------------------------------------------------------------------------- | FUNCTION limitValue ---------------------------------------------------------------------------*/ signed int AFlimitIValue (int value,int min,int max) { if (value < min) return min; if (value > max) return max; return value; } unsigned int AFlimitUIValue (unsigned int value,unsigned int min,unsigned int max) { if (value < min) return min; if (value > max) return max; return value; } float AFlimitFValue (float value,float min,float max) { if (value < min) return min; if (value > max) return max; return value; } double AFlimitDValue (double value,double min,double max) { if (value < min) return min; if (value > max) return max; return value; } /***************************************************************************/