ref: 361710b16b1b6e564351178000d871f66a334849
parent: f8ce704d16fe11b50067f4397674f703cfa4ae54
author: cbagwell <cbagwell>
date: Tue Nov 30 16:39:29 EST 1999
Additional adpcm updates. Additional updates to configure.in for new alsa support.
--- a/configure.in
+++ b/configure.in
@@ -3,7 +3,7 @@
dnl configure.in
dnl
-AC_REVISION([configure.in 0.3])
+AC_REVISION([configure.in 0.4])
AC_INIT(sox.c)
dnl AC_CONFIG_HEADER(config.h)
@@ -29,7 +29,7 @@
[gsminc=auto])
AC_ARG_WITH(alsa_dsp,
- [ --with-alsa-dsp Force support for /dev/snd/pcm00 (ALSA)],
+ [ --with-alsa-dsp Force support for /dev/snd/pcmABXY (ALSA)],
[alsa_dsp="$withval"],
[alsa_dsp=auto])
@@ -133,17 +133,19 @@
if test "$alsa_dsp" = auto
then
AC_CACHE_CHECK(
- [whether /dev/snd/pcm00 is functional (ALSA)],
+ [whether /proc/asound is functional (ALSA)],
ac_cv_dev_alsa_dsp,
AC_TRY_RUN(
[
+ void *opendir(const char *);
+ void *closedir(const char *);
int
main()
{
- int fd = open("/dev/snd/pcm00", 0);
- if (fd != -1)
+ void *vp = opendir("/proc/asound");
+ if (vp != 0)
{
- close(fd);
+ closedir(vp);
return 0;
}
return 1;
@@ -156,11 +158,19 @@
if test "$ac_cv_dev_alsa_dsp" = yes
then
- alsa_dsp=yes
+ AC_CHECK_HEADERS(linux/asound.h, alsa_dsp=yes)
+ if test "$alsa_dsp" = auto
+ then
+ AC_WARN([No asound.h to compile with ALSA /dev/snd/pcmABXY])
+ fi
fi
fi
if test "$alsa_dsp" = yes
then
+ if test "$ac_cv_dev_alsa_dsp" = ""
+ then
+ AC_CHECK_HEADERS(linux/asound.h)
+ fi
CFLAGS="$CFLAGS -DALSA_PLAYER"
NEED_ALSA=1
PLAY_SUPPORT=1
@@ -173,6 +183,8 @@
ac_cv_dev_oss_dsp,
AC_TRY_RUN(
[
+ int open(const char *, int);
+ int close(int);
int
main()
{
@@ -202,7 +214,7 @@
then
if test "$ac_cv_dev_oss_dsp" = ""
then
- AC_CHECK_HEADERS(sys/soundcard.h machine/soundcard.h,)
+ AC_CHECK_HEADERS(sys/soundcard.h machine/soundcard.h)
fi
CFLAGS="$CFLAGS -DOSS_PLAYER"
NEED_OSS=1
@@ -216,6 +228,8 @@
ac_cv_dev_sun_audio,
AC_TRY_RUN(
[
+ int open(const char *, int);
+ int close(int);
int
main()
{
@@ -234,8 +248,7 @@
)
if test "$ac_cv_dev_sun_audio" = yes
then
- AC_CHECK_HEADER(sys/audioio.h, sun_audio=yes)
- AC_CHECK_HEADER(sun/audioio.h, sun_audio=yes)
+ AC_CHECK_HEADER(sys/audioio.h, sun/audioio.h, sun_audio=yes)
if test "$sun_audio" = auto
then
AC_WARN([No audioio.h to compile with SUN /dev/audio])
@@ -246,7 +259,7 @@
then
if test "$ac_cv_dev_sun_audio" = ""
then
- AC_CHECK_HEADERS(sys/audioio.h, sun/audioio.h,)
+ AC_CHECK_HEADERS(sys/audioio.h sun/audioio.h)
fi
CFLAGS="$CFLAGS -DSUNAUDIO_PLAYER"
NEED_SUNAU=1
--- a/src/adpcm.c
+++ b/src/adpcm.c
@@ -110,6 +110,8 @@
/* AdpcmBlockExpandI() outputs interleaved samples into one output buffer */
const char *AdpcmBlockExpandI(
int chans, /* total channels */
+ int nCoef,
+ const short *iCoef,
const u_char *ibuff,/* input buffer[blockAlign] */
SAMPL *obuff, /* output samples, n*chans */
int n /* samples to decode PER channel */
@@ -124,12 +126,13 @@
ip = ibuff;
for (ch = 0; ch < chans; ch++) {
u_char bpred = *ip++;
- if (bpred >= 7) {
- errmsg = "MSADPCM bpred >= 7, arbitrarily using 0\n";
+ if (bpred >= nCoef) {
+ errmsg = "MSADPCM bpred >= nCoef, arbitrarily using 0\n";
bpred = 0;
}
- state[ch].iCoef[0] = iCoef[(int)bpred][0];
- state[ch].iCoef[1] = iCoef[(int)bpred][1];
+ state[ch].iCoef[0] = iCoef[(int)bpred*2+0];
+ state[ch].iCoef[1] = iCoef[(int)bpred*2+1];
+
}
for (ch = 0; ch < chans; ch++)
@@ -373,8 +376,8 @@
const SAMPL *ip, /* ip[n*chans] is interleaved input samples */
int n, /* samples to encode PER channel */
int *st, /* input/output steps, 16<=st[i] */
- u_char *obuff, /* output buffer[blockAlign] */
- int blockAlign, /* >= 7*chans + n/2 */
+ u_char *obuff, /* output buffer[blockAlign] */
+ int blockAlign, /* >= 7*chans + chans*(n-2)/2.0 */
int opt /* non-zero allows some cpu-intensive code to improve output */
)
{
@@ -389,3 +392,50 @@
for (ch=0; ch<chans; ch++)
AdpcmMashChannel(ch, chans, ip, n, st+ch, obuff, opt);
}
+
+/*
+ * AdpcmSamplesIn(dataLen, chans, blockAlign, samplesPerBlock)
+ * returns the number of samples/channel which would be
+ * in the dataLen, given the other parameters ...
+ * if input samplesPerBlock is 0, then returns the max
+ * samplesPerBlock which would go into a block of size blockAlign
+ * Yes, it is confusing usage.
+ */
+ULONG AdpcmSamplesIn(
+ ULONG dataLen,
+ unsigned short chans,
+ unsigned short blockAlign,
+ unsigned short samplesPerBlock
+)
+{
+ ULONG m, n;
+
+ if (samplesPerBlock) {
+ n = (dataLen / blockAlign) * samplesPerBlock;
+ m = (dataLen % blockAlign);
+ } else {
+ n = 0;
+ m = blockAlign;
+ }
+ if (m >= 7*chans) {
+ m -= 7*chans; /* bytes beyond block-header */
+ m = (2*m)/chans + 2; /* nibbles/chans + 2 in header */
+ if (samplesPerBlock && m > samplesPerBlock) m = samplesPerBlock;
+ n += m;
+ }
+ return n;
+ /* wSamplesPerBlock = 2*(wBlockAlign - 7*wChannels)/wChannels + 2; */
+}
+
+ULONG AdpcmBytesPerBlock(
+ unsigned short chans,
+ unsigned short samplesPerBlock
+)
+{
+ ULONG n;
+ n = 7*chans; /* header */
+ if (samplesPerBlock > 2)
+ n += (((ULONG)samplesPerBlock-2)*chans + 1)/2;
+ return n;
+}
+
--- a/src/adpcm.h
+++ b/src/adpcm.h
@@ -7,6 +7,7 @@
#ifndef LONG
#define LONG long
#endif
+/* FIXME: This breaks on Alphas! */
#ifndef ULONG
#define ULONG u_long
#endif
@@ -17,6 +18,8 @@
/* AdpcmBlockExpandI() outputs interleaved samples into one output buffer */
extern const char *AdpcmBlockExpandI(
int chans, /* total channels */
+ int nCoef,
+ const short *iCoef,
const u_char *ibuff,/* input buffer[blockAlign] */
SAMPL *obuff, /* output samples, n*chans */
int n /* samples to decode PER channel, REQUIRE n % 8 == 1 */
@@ -32,3 +35,29 @@
int opt /* non-zero allows some cpu-intensive code to improve output */
);
+/* Some helper functions for computing samples/block and blockalign */
+
+/*
+ * AdpcmSamplesIn(dataLen, chans, blockAlign, samplesPerBlock)
+ * returns the number of samples/channel which would be
+ * in the dataLen, given the other parameters ...
+ * if input samplesPerBlock is 0, then returns the max
+ * samplesPerBlock which would go into a block of size blockAlign
+ * Yes, it is confusing usage.
+ */
+extern ULONG AdpcmSamplesIn(
+ ULONG dataLen,
+ unsigned short chans,
+ unsigned short blockAlign,
+ unsigned short samplesPerBlock
+);
+
+/*
+ * ULONG AdpcmBytesPerBlock(chans, samplesPerBlock)
+ * return minimum blocksize which would be required
+ * to encode number of chans with given samplesPerBlock
+ */
+extern ULONG AdpcmBytesPerBlock(
+ unsigned short chans,
+ unsigned short samplesPerBlock
+);
--- a/src/ima_rw.c
+++ b/src/ima_rw.c
@@ -333,6 +333,61 @@
ImaMashChannel(ch, chans, ip, n, st+ch, obuff, opt);
}
+/*
+ * ImaSamplesIn(dataLen, chans, blockAlign, samplesPerBlock)
+ * returns the number of samples/channel which would go
+ * in the dataLen, given the other parameters ...
+ * if input samplesPerBlock is 0, then returns the max
+ * samplesPerBlock which would go into a block of size blockAlign
+ * Yes, it is confusing.
+ */
+ULONG ImaSamplesIn(
+ ULONG dataLen,
+ unsigned short chans,
+ unsigned short blockAlign,
+ unsigned short samplesPerBlock
+)
+{
+ ULONG m, n;
+
+ if (samplesPerBlock) {
+ n = (dataLen / blockAlign) * samplesPerBlock;
+ m = (dataLen % blockAlign);
+ } else {
+ n = 0;
+ m = blockAlign;
+ }
+ if (m >= 4*chans) {
+ m -= 4*chans; /* number of bytes beyond block-header */
+ m /= 4*chans; /* number of 4-byte blocks/channel beyond header */
+ m = 8*m + 1; /* samples/chan beyond header + 1 in header */
+ if (samplesPerBlock && m > samplesPerBlock) m = samplesPerBlock;
+ n += m;
+ }
+ return n;
+ /*wSamplesPerBlock = ((wBlockAlign - 4*wChannels)/(4*wChannels))*8 + 1;*/
+}
+
+/*
+ * ULONG ImaBytesPerBlock(chans, samplesPerBlock)
+ * return minimum blocksize which would be required
+ * to encode number of chans with given samplesPerBlock
+ */
+ULONG ImaBytesPerBlock(
+ unsigned short chans,
+ unsigned short samplesPerBlock
+)
+{
+ ULONG n;
+ /* 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
+ */
+ n = ((ULONG)samplesPerBlock + 14)/8 * 4 * chans;
+ return n;
+}
+
#if 0
static void ImaMashChannel(int ch, const SAMPL *ip, int n, int *st)
{
--- a/src/ima_rw.h
+++ b/src/ima_rw.h
@@ -21,6 +21,10 @@
#ifndef SAMPL
# define SAMPL short
#endif
+/* FIXME: This breaks on Alphas! */
+#ifndef ULONG
+# define ULONG unsigned long
+#endif
/* #undef STRICT_IMA makes code a bit faster, but not
* strictly compatible with the real IMA spec, which
@@ -62,5 +66,32 @@
int *st, /* input/output state[chans], REQUIRE 0 <= st[ch] <= ISSTMAX */
u_char *obuff, /* output buffer[blockAlign] */
int opt /* non-zero allows some cpu-intensive code to improve output */
+);
+
+/* Some helper functions for computing samples/block and blockalign */
+
+/*
+ * ImaSamplesIn(dataLen, chans, blockAlign, samplesPerBlock)
+ * returns the number of samples/channel which would go
+ * in the dataLen, given the other parameters ...
+ * if input samplesPerBlock is 0, then returns the max
+ * samplesPerBlock which would go into a block of size blockAlign
+ * Yes, it is confusing usage.
+ */
+extern ULONG ImaSamplesIn(
+ ULONG dataLen,
+ unsigned short chans,
+ unsigned short blockAlign,
+ unsigned short samplesPerBlock
+);
+
+/*
+ * ULONG ImaBytesPerBlock(chans, samplesPerBlock)
+ * return minimum blocksize which would be required
+ * to encode number of chans with given samplesPerBlock
+ */
+extern ULONG ImaBytesPerBlock(
+ unsigned short chans,
+ unsigned short samplesPerBlock
);
--- a/src/wav.c
+++ b/src/wav.c
@@ -86,20 +86,18 @@
LONG numSamples;
LONG dataLength; /* needed for ADPCM writing */
unsigned short formatTag; /* What type of encoding file is using */
-
- /* The following are only needed for ADPCM wav files */
unsigned short samplesPerBlock;
- unsigned short bytesPerBlock;
unsigned short blockAlign;
+
+ /* following used by *ADPCM wav files */
unsigned short nCoefs; /* ADPCM: number of coef sets */
short *iCoefs; /* ADPCM: coef sets */
unsigned char *packet; /* Temporary buffer for packets */
short *samples; /* interleaved samples buffer */
- short *samplePtr; /* Pointer to current samples */
+ short *samplePtr; /* Pointer to current sample */
short *sampleTop; /* End of samples-buffer */
- unsigned short blockSamplesRemaining;/* Samples remaining in each channel */
- /* state holds step-size info for ADPCM or IMA_ADPCM writes */
- int state[16]; /* last, because maybe longer */
+ unsigned short blockSamplesRemaining;/* Samples remaining per channel */
+ int state[16]; /* step-size info for *ADPCM writes */
/* following used by GSM 6.10 wav */
#ifdef HAVE_LIBGSM
@@ -122,9 +120,16 @@
void rawwrite(P3(ft_t, LONG *, LONG));
void wavwritehdr(P2(ft_t, int));
+
/****************************************************************************/
/* IMA ADPCM Support Functions Section */
/****************************************************************************/
+
+/*
+ *
+ * ImaAdpcmReadBlock - Grab and decode complete block of samples
+ *
+ */
unsigned short ImaAdpcmReadBlock(ft)
ft_t ft;
{
@@ -134,27 +139,22 @@
/* Pull in the packet and check the header */
bytesRead = fread(wav->packet,1,wav->blockAlign,ft->fp);
+ samplesThisBlock = wav->samplesPerBlock;
if (bytesRead < wav->blockAlign)
{
/* If it looks like a valid header is around then try and */
/* work with partial blocks. Specs say it should be null */
/* padded but I guess this is better than trailing quiet. */
- if (bytesRead >= (4 * ft->info.channels))
- { /* SJB: FIXME this is incorrect */
- samplesThisBlock = (wav->blockAlign - (3 * ft->info.channels));
- }
- else
+ samplesThisBlock = ImaSamplesIn(0, ft->info.channels, bytesRead, 0);
+ if (samplesThisBlock == 0)
{
warn ("Premature EOF on .wav input file");
return 0;
}
}
- else
- samplesThisBlock = wav->samplesPerBlock;
wav->samplePtr = wav->samples;
-
/* For a full block, the following should be true: */
/* wav->samplesPerBlock = blockAlign - 8byte header + 1 sample in header */
ImaBlockExpandI(ft->info.channels, wav->packet, wav->samples, samplesThisBlock);
@@ -165,6 +165,7 @@
/****************************************************************************/
/* MS ADPCM Support Functions Section */
/****************************************************************************/
+
/*
*
* AdpcmReadBlock - Grab and decode complete block of samples
@@ -180,25 +181,21 @@
/* Pull in the packet and check the header */
bytesRead = fread(wav->packet,1,wav->blockAlign,ft->fp);
+ samplesThisBlock = wav->samplesPerBlock;
if (bytesRead < wav->blockAlign)
{
/* If it looks like a valid header is around then try and */
/* work with partial blocks. Specs say it should be null */
- /* padded but I guess this is better than trailing quite. */
- if (bytesRead >= (7 * ft->info.channels))
- { /* SJB: FIXME this is incorrect */
- samplesThisBlock = (wav->blockAlign - (6 * ft->info.channels));
- }
- else
+ /* padded but I guess this is better than trailing quiet. */
+ samplesThisBlock = AdpcmSamplesIn(0, ft->info.channels, bytesRead, 0);
+ if (samplesThisBlock == 0)
{
warn ("Premature EOF on .wav input file");
return 0;
}
}
- else
- samplesThisBlock = wav->samplesPerBlock;
- errmsg = AdpcmBlockExpandI(ft->info.channels, wav->packet, wav->samples, samplesThisBlock);
+ errmsg = AdpcmBlockExpandI(ft->info.channels, wav->nCoefs, wav->iCoefs, wav->packet, wav->samples, samplesThisBlock);
if (errmsg)
warn((char*)errmsg);
@@ -207,8 +204,9 @@
}
/****************************************************************************/
-/* Common ADPCM Support Function */
+/* Common ADPCM Write Function */
/****************************************************************************/
+
static void xxxAdpcmWriteBlock(ft)
ft_t ft;
{
@@ -441,17 +439,22 @@
unsigned short wExtSize = 0; /* extended field for non-PCM */
ULONG wDataLength; /* length of sound data in bytes */
+ ULONG bytesPerBlock = 0;
ULONG bytespersample; /* bytes per sample (per channel */
- /* This is needed for rawread() */
+ if (sizeof(struct wavstuff)> PRIVSIZE)
+ fail("struct wav_t too big (%d); increase PRIVSIZE in st.h and recompile sox",sizeof(struct wavstuff));
+ /* This is needed for rawread(), rshort, etc */
rawstartread(ft);
endptr = (char *) &littlendian;
if (!*endptr) ft->swap = ft->swap ? 0 : 1;
+#if 0
/* If you need to seek around the input file. */
- if (0 && ! ft->seekable)
+ if (! ft->seekable)
fail("WAVE input file must be a file, not a pipe");
+#endif
if ( fread(magic, 1, 4, ft->fp) != 4 || strncmp("RIFF", magic, 4))
fail("WAVE: RIFF header not found");
@@ -561,7 +564,7 @@
ft->info.channels = wChannels;
else
warn("User options overriding channels read in .wav header");
-
+
if (ft->info.rate == 0 || ft->info.rate == wSamplesPerSecond)
ft->info.rate = wSamplesPerSecond;
else
@@ -587,17 +590,21 @@
switch (wav->formatTag)
{
+ /* ULONG max_spb; */
case WAVE_FORMAT_ADPCM:
if (wExtSize < 4)
- fail("wave header error: format[%s] expects wExtSize >= %d",
- wav_format_str(wav->formatTag), 4);
+ fail("format[%s]: expects wExtSize >= %d",
+ wav_format_str(wav->formatTag), 4);
if (wBitsPerSample != 4)
fail("Can only handle 4-bit MS ADPCM in wav files");
wav->samplesPerBlock = rshort(ft);
- wav->bytesPerBlock = ((wav->samplesPerBlock-2)*ft->info.channels + 1)/2
- + 7*ft->info.channels;
+ bytesPerBlock = AdpcmBytesPerBlock(ft->info.channels, wav->samplesPerBlock);
+ if (bytesPerBlock > wav->blockAlign)
+ fail("format[%s]: samplesPerBlock(%d) incompatible with blockAlign(%d)",
+ wav_format_str(wav->formatTag), wav->samplesPerBlock, wav->blockAlign);
+
wav->nCoefs = rshort(ft);
if (wav->nCoefs < 7 || wav->nCoefs > 0x100) {
fail("ADPCM file nCoefs (%.4hx) makes no sense\n", wav->nCoefs);
@@ -610,15 +617,17 @@
wav->samples = (short *)malloc(wChannels*wav->samplesPerBlock*sizeof(short));
- /* SJB: will need iCoefs later for adpcm.c */
+ /* nCoefs, iCoefs used by adpcm.c */
wav->iCoefs = (short *)malloc(wav->nCoefs * 2 * sizeof(short));
{
- int i;
+ int i, errct=0;
for (i=0; len>=2 && i < 2*wav->nCoefs; i++) {
wav->iCoefs[i] = rshort(ft);
- /* fprintf(stderr,"iCoefs[%2d] %4d\n",i,wav->iCoefs[i]); */
len -= 2;
+ if (i<14) errct += (wav->iCoefs[i] != iCoef[i/2][i%2]);
+ /* fprintf(stderr,"iCoefs[%2d] %4d\n",i,wav->iCoefs[i]); */
}
+ if (errct) warn("base iCoefs differ in %d/14 positions",errct);
}
bytespersample = WORD; /* AFTER de-compression */
@@ -626,7 +635,7 @@
case WAVE_FORMAT_IMA_ADPCM:
if (wExtSize < 2)
- fail("wave header error: format[%s] expects wExtSize >= %d",
+ fail("format[%s]: expects wExtSize >= %d",
wav_format_str(wav->formatTag), 2);
if (wBitsPerSample != 4)
@@ -633,7 +642,11 @@
fail("Can only handle 4-bit IMA ADPCM in wav files");
wav->samplesPerBlock = rshort(ft);
- wav->bytesPerBlock = (wav->samplesPerBlock + 7)/2 * ft->info.channels;/* FIXME */
+ bytesPerBlock = ImaBytesPerBlock(ft->info.channels, wav->samplesPerBlock);
+ if (bytesPerBlock > wav->blockAlign || wav->samplesPerBlock%8 != 1)
+ fail("format[%s]: samplesPerBlock(%d) incompatible with blockAlign(%d)",
+ wav_format_str(wav->formatTag), wav->samplesPerBlock, wav->blockAlign);
+
wav->packet = (unsigned char *)malloc(wav->blockAlign);
len -= 2;
@@ -646,14 +659,15 @@
/* GSM formats have extended fmt chunk. Check for those cases. */
case WAVE_FORMAT_GSM610:
if (wExtSize < 2)
- fail("wave header error: format[%s] expects wExtSize >= %d",
+ fail("format[%s]: expects wExtSize >= %d",
wav_format_str(wav->formatTag), 2);
wav->samplesPerBlock = rshort(ft);
+ bytesPerBlock = 65;
if (wav->blockAlign != 65)
- fail("wave header error: format[%s] expects blockAlign(%d) = %d",
+ fail("format[%s]: expects blockAlign(%d) = %d",
wav_format_str(wav->formatTag), wav->blockAlign, 65);
if (wav->samplesPerBlock != 320)
- fail("wave header error: format[%s] expects samplesPerBlock(%d) = %d",
+ fail("format[%s]: expects samplesPerBlock(%d) = %d",
wav_format_str(wav->formatTag), wav->samplesPerBlock, 320);
bytespersample = WORD; /* AFTER de-compression */
len -= 2;
@@ -720,13 +734,8 @@
{
case WAVE_FORMAT_ADPCM:
- /* Compute easiest part of number of samples. For every block, there
- are samplesPerBlock samples to read. */
- wav->numSamples = (((wDataLength / wav->blockAlign) * wav->samplesPerBlock) * ft->info.channels);
- /* Next, for any partial blocks, subtract overhead from it and it
- will leave # of samples to read. */
- wav->numSamples +=
- ((wDataLength % wav->blockAlign) - (6 * ft->info.channels)) * ft->info.channels;
+ wav->numSamples =
+ AdpcmSamplesIn(wDataLength, ft->info.channels, wav->blockAlign, wav->samplesPerBlock);
/*report("datalen %d, numSamples %d",wDataLength, wav->numSamples);*/
wav->blockSamplesRemaining = 0; /* Samples left in buffer */
break;
@@ -734,11 +743,9 @@
case WAVE_FORMAT_IMA_ADPCM:
/* Compute easiest part of number of samples. For every block, there
are samplesPerBlock samples to read. */
- wav->numSamples = (((wDataLength / wav->blockAlign) * wav->samplesPerBlock) * ft->info.channels);
- /* Next, for any partial blocks, substract overhead from it and it
- will leave # of samples to read. */
- wav->numSamples +=
- ((wDataLength % wav->blockAlign) - (3 * ft->info.channels)) * ft->info.channels;
+ wav->numSamples =
+ ImaSamplesIn(wDataLength, ft->info.channels, wav->blockAlign, wav->samplesPerBlock);
+ /*report("datalen %d, numSamples %d",wDataLength, wav->numSamples);*/
wav->blockSamplesRemaining = 0; /* Samples left in buffer */
initImaTable();
break;
@@ -766,12 +773,12 @@
{
case WAVE_FORMAT_ADPCM:
report(" %d Extsize, %d Samps/block, %d bytes/block %d Num Coefs",
- wExtSize,wav->samplesPerBlock,wav->bytesPerBlock,wav->nCoefs);
+ wExtSize,wav->samplesPerBlock,bytesPerBlock,wav->nCoefs);
break;
case WAVE_FORMAT_IMA_ADPCM:
report(" %d Extsize, %d Samps/block, %d bytes/block",
- wExtSize,wav->samplesPerBlock,wav->bytesPerBlock);
+ wExtSize,wav->samplesPerBlock,bytesPerBlock);
break;
#ifdef HAVE_LIBGSM
@@ -904,6 +911,9 @@
int littlendian = 1;
char *endptr;
+ if (sizeof(struct wavstuff)> PRIVSIZE)
+ fail("struct wav_t too big (%d); increase PRIVSIZE in st.h and recompile sox",sizeof(struct wavstuff));
+
endptr = (char *) &littlendian;
if (!*endptr) ft->swap = ft->swap ? 0 : 1;
@@ -1103,7 +1113,7 @@
wBlockAlign = wChannels * 64; /* reasonable default */
wBitsPerSample = 4;
wExtSize = 2;
- wSamplesPerBlock = ((wBlockAlign - 4*wChannels)/(4*wChannels))*8 + 1;
+ wSamplesPerBlock = ImaSamplesIn(0, wChannels, wBlockAlign, 0);
break;
case ADPCM:
/* warn("Experimental support writing ADPCM style.\n"); */
@@ -1113,7 +1123,7 @@
wBlockAlign = wChannels * 128; /* reasonable default */
wBitsPerSample = 4;
wExtSize = 4+4*7; /* Ext fmt data length */
- wSamplesPerBlock = 2*(wBlockAlign - 7*wChannels)/wChannels + 2;
+ wSamplesPerBlock = AdpcmSamplesIn(0, wChannels, wBlockAlign, 0);
break;
case GSM:
#ifdef HAVE_LIBGSM
@@ -1169,9 +1179,8 @@
if (wFormatTag != WAVE_FORMAT_PCM) /* PCM omits the "fact" chunk */
wRiffLength += (8+wFactSize);
- /* wAvgBytesPerSec <-- this is BEFORE compression, isn't it? */
- /* if (wFormatTag != WAVE_FORMAT_GSM610) GSM set this above */
- wAvgBytesPerSec = ft->info.rate * wChannels * bytespersample;
+ /* wAvgBytesPerSec <-- this is BEFORE compression, isn't it? guess not. */
+ wAvgBytesPerSec = (double)wBlockAlign*ft->info.rate / (double)wSamplesPerBlock + 0.5;
/* figured out header info, so write it */
fputs("RIFF", ft->fp);