version 1.1.2.2, 2009/01/22 20:21:28 |
version 1.2, 2009/12/01 10:44:02 |
|
|
|
|
--- libaudiofile/wave.c.orig 2004-03-06 07:39:23.000000000 +0100 |
--- libaudiofile/wave.c.orig 2004-03-06 07:39:23.000000000 +0100 |
+++ libaudiofile/wave.c |
+++ libaudiofile/wave.c |
@@ -220,7 +220,8 @@ static status ParseFormat (AFfilehandle |
@@ -199,11 +199,13 @@ static status ParseFormat (AFfilehandle |
|
case WAVE_FORMAT_ADPCM: |
|
{ |
|
u_int16_t bitsPerSample, extraByteCount, |
|
- samplesPerBlock, numCoefficients; |
|
+ samplesPerBlock, numCoefficients,
|
|
+ framesPerBlock;
|
|
int i; |
|
AUpvlist pv; |
|
long l; |
|
void *v; |
|
+ int minBlockLength;
|
|
|
|
if (track->f.channelCount != 1 && |
|
track->f.channelCount != 2) |
|
@@ -216,11 +218,33 @@ static status ParseFormat (AFfilehandle |
|
af_fread(&bitsPerSample, 1, 2, fp); |
|
bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample); |
|
|
|
+ if (bitsPerSample != 4)
|
|
+ {
|
|
+ _af_error(AF_BAD_WIDTH,
|
|
+ "bad sample width of %hd bits",
|
|
+ bitsPerSample);
|
|
+ return AF_FAIL;
|
|
+ }
|
|
+
|
|
af_fread(&extraByteCount, 1, 2, fp); |
extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount); |
extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount); |
|
|
af_fread(&samplesPerBlock, 1, 2, fp); |
- af_fread(&samplesPerBlock, 1, 2, fp); |
- samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock); |
- samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock); |
+ samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock) |
+ af_fread(&framesPerBlock, 1, 2, fp);
|
+ * track->f.channelCount; |
+ framesPerBlock = LENDIAN_TO_HOST_INT16(framesPerBlock);
|
|
+
|
|
+ minBlockLength = 7 * channelCount; /* header */
|
|
+ if (framesPerBlock > 2)
|
|
+ minBlockLength += ( ( framesPerBlock - 2 ) * channelCount + 1) / 2;
|
|
+
|
|
+ if (blockAlign < minBlockLength)
|
|
+ {
|
|
+ _af_error(AF_BAD_FRAMECNT,
|
|
+ "blockAlign %hd too small for %hd samplesPerBlock",
|
|
+ blockAlign, samplesPerBlock);
|
|
+ return AF_FAIL;
|
|
+ }
|
|
+
|
|
+ samplesPerBlock = framesPerBlock *channelCount;
|
|
|
af_fread(&numCoefficients, 1, 2, fp); |
af_fread(&numCoefficients, 1, 2, fp); |
numCoefficients = LENDIAN_TO_HOST_INT16(numCoefficients); |
numCoefficients = LENDIAN_TO_HOST_INT16(numCoefficients); |
@@ -281,6 +282,12 @@ static status ParseFormat (AFfilehandle |
@@ -242,6 +266,7 @@ static status ParseFormat (AFfilehandle |
|
wave->msadpcmCoefficients[i][1] = a1; |
|
} |
|
|
|
+
|
|
track->f.sampleWidth = 16; |
|
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; |
|
track->f.compressionType = AF_COMPRESSION_MS_ADPCM; |
|
@@ -277,18 +302,44 @@ static status ParseFormat (AFfilehandle |
|
{ |
|
AUpvlist pv; |
|
long l; |
|
+ int minBlockLength;
|
|
|
u_int16_t bitsPerSample, extraByteCount, |
u_int16_t bitsPerSample, extraByteCount, |
samplesPerBlock; |
- samplesPerBlock; |
|
+ samplesPerBlock, framesPerBlock;
|
|
|
+ if (track->f.channelCount != 1) { |
|
+ _af_error(AF_BAD_CHANNELS, |
|
+ "WAVE file with IMA compression: " |
|
+ "can only handle 1 channel"); |
|
+ } |
|
+ |
|
af_fread(&bitsPerSample, 1, 2, fp); |
af_fread(&bitsPerSample, 1, 2, fp); |
bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample); |
bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample); |
|
|
|
+ if (bitsPerSample != 4)
|
|
+ {
|
|
+ _af_error(AF_BAD_WIDTH,
|
|
+ "bad sample width of %hd bits",
|
|
+ bitsPerSample);
|
|
+ return AF_FAIL;
|
|
+ }
|
|
+
|
|
af_fread(&extraByteCount, 1, 2, fp); |
|
extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount); |
|
|
|
- af_fread(&samplesPerBlock, 1, 2, fp); |
|
- samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock); |
|
+ af_fread(&framesPerBlock, 1, 2, fp);
|
|
+ framesPerBlock = LENDIAN_TO_HOST_INT16(framesPerBlock);
|
|
+ samplesPerBlock = framesPerBlock * channelCount;
|
|
+
|
|
+ /* per channel, ima has blocks of len 4, the 1st has 1st sample, the others
|
|
+ * up to 8 samples per block,
|
|
+ * so number of later blocks is (nsamp-1 + 7)/8, total blocks/chan is
|
|
+ * (nsamp-1+7)/8 + 1 = (nsamp+14)/8
|
|
+ */
|
|
+
|
|
+ minBlockLength = ( framesPerBlock + 14 )/8 * 4 * channelCount;
|
|
+
|
|
+ if (blockAlign < minBlockLength)
|
|
+ {
|
|
+ _af_error(AF_BAD_FRAMECNT,
|
|
+ "blockAlign %hd too small for %hd samplesPerBlock",
|
|
+ blockAlign, samplesPerBlock);
|
|
+ return AF_FAIL;
|
|
+ }
|
|
|
|
track->f.sampleWidth = 16; |
|
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; |