ref: 3d4cdf3d163b9d8c6a4241ff412b785178af4865
parent: cc62528640ac1659ebdde9437fdae61710a1362e
author: robs <robs>
date: Mon Mar 3 14:20:07 EST 2008
Restructuring some internals; let me know what I've broken...
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,7 +15,7 @@
format support, libao playback, Secret Rabbit Code
resampling; many fixes and much cleanup.
Rob Sykes [email protected]
- Formats: M3U, PLS, FLAC, AMR, 24bit support for popular
+ Formats: M3U, PLS, FLAC, AMR, HTK, 24bit support for popular
formats.
Effects: key, tempo, pad, bass, treble, new reverb, new
flanger, soft-knee companding, speed via resampling, filters
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,30 +24,41 @@
File formats:
- o None new.
+ o New htk format. (robs)
+ o Fix [1864216] comments mangled when writing ogg-vorbis. (robs)
+ o Fix short noise at end of alsa playback. (Morita Sho)
+ o Fix wve seek accuracy. (robs)
+ o Fix lpc10 not working. (robs)
+ o For wav & au, fix [548256] size in header wrong when piping out. (robs)
+ o Writing aiff, aifc & cvsd now repeatable with -R. (robs)
+ o Writing hcom no longer fails with unsupported rate--chooses
+ best match. (robs)
+ o Au/snd: added support for 32-bit integer and 64-bit float PCM
+ encoding/decoding; display name of unsupported encoding. (robs)
Effects:
- o Added effect to splice together audio sections. (robs)
- o Added remix effect (complements the mixer effect). (robs)
- o Added norm (normalise) effect. (robs)
+ o New `splice' effect; splice together audio sections. (robs)
+ o New `remix' effect; complements the mixer effect. (robs)
+ o New `norm' (normalise) effect. (robs)
+ o Fix crash on 64-bit arch. with tempo & key effects. (Sami Liedes)
+ o Fix synth max. level setting for some output encodings. (robs)
Other new features:
o Command line support for multiple file comments. (robs)
- o Added soxi utility to extract/display file header fields. (robs)
- o Added pkg-config support. (Pascal Giard)
- o Added basic VU meter. (robs)
- o Added simple heuristic to detect when playing an album and set
+ o Soxi utility to extract/display file header fields. (robs)
+ o Pkg-config support. (Pascal Giard)
+ o Basic VU meter. (robs)
+ o Simple heuristic to detect when playing an album and set
the default replay-gain mode to `album'. (robs)
+ o More intelligent choice of output file format parameters when
+ type is different to that of input file. (robs)
-Bug fixes:
+Other bug fixes:
- o Fix [1864216] comments mangled when writing ogg-vorbis. (robs)
- o Fix crash on 64-bit arch. with tempo & key effects. (Sami Liedes)
o Fix [1890983] rec shortcut should apply bit depth (8-bit,
16-bit, etc.) to input handler. (robs)
- o Fix short noise at end of alsa playback. (Morita Sho)
Internal improvements:
--- a/soxformat.7
+++ b/soxformat.7
@@ -295,6 +295,10 @@
Mac users will need their usual arsenal of file converters
to deal with an HCOM file on other systems.
.TP
+.B .htk
+Single channel 16-bit PCM format used by HTK,
+a toolkit for building Hidden Markov Model speech processing tools.
+.TP
.B .ircam (also with \-t sndfile)
Another name for
.BR .sf .
--- a/src/8svx.c
+++ b/src/8svx.c
@@ -26,7 +26,7 @@
/* 8SVXSTARTREAD */
/*======================================================================*/
-static int sox_svxstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
svx_t p = (svx_t ) ft->priv;
@@ -160,8 +160,8 @@
ft->length = p->nsamples;
ft->signal.channels = channels;
ft->signal.rate = rate;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.size = SOX_SIZE_BYTE;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 8;
/* open files to channels */
p->ch[0] = ft->fp;
@@ -193,7 +193,7 @@
/*======================================================================*/
/* 8SVXREAD */
/*======================================================================*/
-static sox_size_t sox_svxread(sox_format_t * ft, sox_sample_t *buf, sox_size_t nsamp)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t nsamp)
{
unsigned char datum;
size_t done = 0, i;
@@ -217,7 +217,7 @@
/*======================================================================*/
/* 8SVXSTOPREAD */
/*======================================================================*/
-static int sox_svxstopread(sox_format_t * ft)
+static int stopread(sox_format_t * ft)
{
size_t i;
@@ -233,7 +233,7 @@
/*======================================================================*/
/* 8SVXSTARTWRITE */
/*======================================================================*/
-static int sox_svxstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
svx_t p = (svx_t ) ft->priv;
size_t i;
@@ -249,9 +249,6 @@
}
/* write header (channel 0) */
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.size = SOX_SIZE_BYTE;
-
p->nsamples = 0;
svxwriteheader(ft, p->nsamples);
return(SOX_SUCCESS);
@@ -261,7 +258,7 @@
/* 8SVXWRITE */
/*======================================================================*/
-static sox_size_t sox_svxwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
svx_t p = (svx_t ) ft->priv;
@@ -285,7 +282,7 @@
/* 8SVXSTOPWRITE */
/*======================================================================*/
-static int sox_svxstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
svx_t p = (svx_t ) ft->priv;
@@ -362,27 +359,15 @@
sox_writedw(ft, nsamples); /* samples in file */
}
-/* Amiga 8SVX */
-static const char *svxnames[] = {
- "8svx",
- NULL
-};
-
-static sox_format_handler_t sox_svx_format = {
- svxnames,
- SOX_FILE_BIG_END,
- sox_svxstartread,
- sox_svxread,
- sox_svxstopread,
- sox_svxstartwrite,
- sox_svxwrite,
- sox_svxstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_svx_format_fn(void);
-
-const sox_format_handler_t *sox_svx_format_fn(void)
+SOX_FORMAT_HANDLER(svx)
{
- return &sox_svx_format;
+ static char const * const names[] = {"8svx", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 8, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_BIG_END|SOX_FILE_MONO|SOX_FILE_STEREO|SOX_FILE_QUAD,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,6 +4,7 @@
if(CMAKE_COMPILER_IS_GNUCC)
add_definitions(-Wconversion -Werror)
+ #add_definitions(-Wno-missing-field-initializers)
endif(CMAKE_COMPILER_IS_GNUCC)
if (NOT EXTERNAL_GSM)
@@ -29,17 +30,17 @@
echo mixer remix stat
)
set(formats_srcs
- 8svx cvsd hcom s1-fmt u2-fmt
- adpcm cvsd-fmt ima-fmt s2-fmt u3-fmt
- adpcms dat ima_rw s3-fmt u4-fmt
- aifc-fmt dvms-fmt la-fmt s4-fmt ul-fmt
- aiff formats lpc10.c sf voc
- aiff-fmt g711 lu-fmt skelform vox
- al-fmt g721 maud smp vox-fmt
- au g723_24 nulfile sndrtool wav
- auto g723_40 prc sphere wve
- avr g72x raw tx16w xa
- cdr gsm.c raw-fmt u1-fmt
+ 8svx cvsd hcom raw-fmt u1-fmt
+ adpcm cvsd-fmt htk s1-fmt u2-fmt
+ adpcms dat ima-fmt s2-fmt u3-fmt
+ aifc-fmt dvms-fmt ima_rw s3-fmt u4-fmt
+ aiff formats la-fmt s4-fmt ul-fmt
+ aiff-fmt g711 lpc10.c sf voc
+ al-fmt g721 lu-fmt skelform vox
+ au g723_24 maud smp vox-fmt
+ auto g723_40 nulfile sndrtool wav
+ avr g72x prc sphere wve
+ cdr gsm.c raw tx16w xa
)
add_library(lib${PROJECT_NAME}
${effects_srcs} misc util
--- a/src/FFT.c
+++ b/src/FFT.c
@@ -45,12 +45,12 @@
* Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
+#include "sox_i.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
-
-#include "sox_i.h"
#include "FFT.h"
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,8 @@
libsox_fmt_sf.la libsox_fmt_smp.la libsox_fmt_sndrtool.la \
libsox_fmt_sphere.la libsox_fmt_txw.la libsox_fmt_voc.la \
libsox_fmt_vox.la libsox_fmt_ima.la libsox_fmt_wav.la \
- libsox_fmt_wve.la libsox_fmt_xa.la libsox_fmt_nul.la
+ libsox_fmt_wve.la libsox_fmt_xa.la libsox_fmt_nul.la \
+ libsox_fmt_htk.la
# File format detection
libsox_fmt_auto_la_SOURCES = auto.c
@@ -98,6 +99,8 @@
libsox_fmt_gsm_la_LIBADD = libsox.la @GSM_LIBS@ @LIBGSM_LIBADD@
libsox_fmt_hcom_la_SOURCES = hcom.c
libsox_fmt_hcom_la_LIBADD = libsox.la
+libsox_fmt_htk_la_SOURCES = htk.c
+libsox_fmt_htk_la_LIBADD = libsox.la
libsox_fmt_lpc10_la_SOURCES = lpc10.c
libsox_fmt_lpc10_la_LIBADD = ../lpc10/liblpc10.la libsox.la
libsox_fmt_maud_la_SOURCES = maud.c
@@ -219,7 +222,7 @@
libsox_la_SOURCES += auto.c raw-fmt.c s1-fmt.c s2-fmt.c s3-fmt.c \
s4-fmt.c u1-fmt.c u2-fmt.c u3-fmt.c u4-fmt.c al-fmt.c la-fmt.c ul-fmt.c \
lu-fmt.c 8svx.c aiff-fmt.c aifc-fmt.c au.c avr.c cdr.c cvsd-fmt.c \
- dvms-fmt.c dat.c gsm.c hcom.c lpc10.c maud.c prc.c sf.c sfircam.h smp.c \
+ dvms-fmt.c dat.c gsm.c hcom.c htk.c lpc10.c maud.c prc.c sf.c sfircam.h smp.c \
sndrtool.c sphere.c tx16w.c voc.c vox-fmt.c ima-fmt.c adpcm.c adpcm.h \
ima_rw.c ima_rw.h wav.c wav.h wve.c xa.c nulfile.c
libsox_la_LIBADD = @GSM_LIBS@ @LIBGSM_LIBADD@
--- a/src/adpcm.c
+++ b/src/adpcm.c
@@ -32,11 +32,12 @@
*
*/
+#include "sox_i.h"
+#include "adpcm.h"
+
#include <sys/types.h>
#include <math.h>
#include <stdio.h>
-#include "sox_i.h"
-#include "adpcm.h"
typedef struct MsState {
sox_sample_t step; /* step size */
--- a/src/adpcms.c
+++ b/src/adpcms.c
@@ -140,7 +140,7 @@
sox_adpcm_reset(state, type);
- return sox_rawstart(ft, sox_true, sox_false, type, SOX_SIZE_16BIT);
+ return sox_rawstart(ft, sox_true, sox_false, sox_true, type, 4);
}
int sox_adpcm_oki_start(sox_format_t * ft, adpcm_io_t state)
@@ -155,14 +155,13 @@
/******************************************************************************
* Function : sox_adpcm_read
- * Description: Fills an internal buffer from the VOX file, converts the
- * OKI ADPCM 4-bit samples to 12-bit signed PCM and then scales
- * the samples to full range 16 bit PCM.
+ * Description: Converts the OKI ADPCM 4-bit samples to 16-bit signed PCM and
+ * then scales the samples to full sox_sample_t range.
* Parameters : ft - file info structure
* state - ADPCM state structure
* buffer - output buffer
- * length - size of output buffer
- * Returns : int - number of samples returned in buffer
+ * len - size of output buffer
+ * Returns : - number of samples returned in buffer
* Exceptions :
* Notes :
******************************************************************************/
--- a/src/aifc-fmt.c
+++ b/src/aifc-fmt.c
@@ -1,38 +1,34 @@
/*
- * Export module for AIFF-C format, implemented in aiff.c.
+ * File format: AIFF-C (see aiff.c) (c) 2007-8 SoX contributors
*
- * Copyright 1991-2007 Guido van Rossum And Sundry Contributors
- *
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Guido van Rossum And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "aiff.h"
-static const char *aifcnames[] = {
- "aifc",
- "aiffc",
- NULL
-};
-
-static sox_format_handler_t sox_aifc_format = {
- aifcnames,
- SOX_FILE_LOOPS | SOX_FILE_BIG_END,
- sox_aiffstartread,
- sox_aiffread,
- sox_aiffstopread,
- sox_aifcstartwrite,
- sox_aiffwrite,
- sox_aifcstopwrite,
- sox_aiffseek
-};
-
-const sox_format_handler_t *sox_aifc_format_fn(void);
-
-const sox_format_handler_t *sox_aifc_format_fn(void)
+SOX_FORMAT_HANDLER(aifc)
{
- return &sox_aifc_format;
+ static char const * const names[] = {"aifc", "aiffc", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 32, 24, 16, 8, 0, 0};
+ static sox_format_handler_t const sox_aifc_format = {
+ names, SOX_FILE_LOOPS | SOX_FILE_BIG_END,
+ sox_aiffstartread, sox_aiffread, sox_aiffstopread,
+ sox_aifcstartwrite, sox_aiffwrite, sox_aifcstopwrite,
+ sox_aiffseek, write_encodings, NULL
+ };
+ return &sox_aifc_format;
}
--- a/src/aiff-fmt.c
+++ b/src/aiff-fmt.c
@@ -1,38 +1,34 @@
/*
- * Export module for AIFF format, implemented in aiff.c.
+ * File format: AIFF (see aiff.c) (c) 2007-8 SoX contributors
*
- * Copyright 1991-2007 Guido van Rossum And Sundry Contributors
- *
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Guido van Rossum And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "aiff.h"
-static const char *aiffnames[] = {
- "aiff",
- "aif",
- NULL
-};
-
-static sox_format_handler_t sox_aiff_format = {
- aiffnames,
- SOX_FILE_LOOPS | SOX_FILE_BIG_END,
- sox_aiffstartread,
- sox_aiffread,
- sox_aiffstopread,
- sox_aiffstartwrite,
- sox_aiffwrite,
- sox_aiffstopwrite,
- sox_aiffseek
-};
-
-const sox_format_handler_t *sox_aiff_format_fn(void);
-
-const sox_format_handler_t *sox_aiff_format_fn(void)
+SOX_FORMAT_HANDLER(aiff)
{
- return &sox_aiff_format;
+ static char const * const names[] = {"aiff", "aif", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 32, 24, 16, 8, 0, 0};
+ static sox_format_handler_t const sox_aiff_format = {
+ names, SOX_FILE_LOOPS | SOX_FILE_BIG_END,
+ sox_aiffstartread, sox_aiffread, sox_aiffstopread,
+ sox_aiffstartwrite, sox_aiffwrite, sox_aiffstopwrite,
+ sox_aiffseek, write_encodings, NULL
+ };
+ return &sox_aiff_format;
}
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -51,10 +51,11 @@
{
aiff_t aiff = (aiff_t ) ft->priv;
sox_size_t new_offset, channel_block, alignment;
+ sox_size_t size = ft->encoding.bits_per_sample >> 3;
- new_offset = offset * ft->signal.size;
+ new_offset = offset * size;
/* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
+ channel_block = ft->signal.channels * size;
alignment = new_offset % channel_block;
/* Most common mistaken is to compute something like
* "skip everthing upto and including this sample" so
@@ -67,7 +68,7 @@
ft->sox_errno = sox_seeki(ft, (sox_ssize_t)new_offset, SEEK_SET);
if (ft->sox_errno == SOX_SUCCESS)
- aiff->nsamples = ft->length - (new_offset / ft->signal.size);
+ aiff->nsamples = ft->length - (new_offset / size);
return(ft->sox_errno);
}
@@ -386,33 +387,17 @@
if (foundcomm) {
ft->signal.channels = channels;
ft->signal.rate = rate;
- if (ft->signal.encoding != SOX_ENCODING_UNKNOWN && ft->signal.encoding != SOX_ENCODING_SIGN2)
+ if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN && ft->encoding.encoding != SOX_ENCODING_SIGN2)
sox_report("AIFF only supports signed data. Forcing to signed.");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
if (bits <= 8)
- {
- ft->signal.size = SOX_SIZE_BYTE;
- if (bits < 8)
- sox_report("Forcing data size from %d bits to 8 bits",bits);
- }
+ ft->encoding.bits_per_sample = 8;
else if (bits <= 16)
- {
- ft->signal.size = SOX_SIZE_16BIT;
- if (bits < 16)
- sox_report("Forcing data size from %d bits to 16 bits",bits);
- }
+ ft->encoding.bits_per_sample = 16;
else if (bits <= 24)
- {
- ft->signal.size = SOX_SIZE_24BIT;
- if (bits < 24)
- sox_report("Forcing data size from %d bits to 24 bits",bits);
- }
+ ft->encoding.bits_per_sample = 24;
else if (bits <= 32)
- {
- ft->signal.size = SOX_SIZE_32BIT;
- if (bits < 32)
- sox_report("Forcing data size from %d bits to 32 bits",bits);
- }
+ ft->encoding.bits_per_sample = 32;
else
{
sox_fail_errno(ft,SOX_EFMT,"unsupported sample size in AIFF header: %d", bits);
@@ -421,8 +406,8 @@
} else {
if ((ft->signal.channels == 0)
|| (ft->signal.rate == 0)
- || (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- || (ft->signal.size == 0)) {
+ || (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ || (ft->encoding.bits_per_sample == 0)) {
sox_report("You must specify # channels, sample rate, signed/unsigned,");
sox_report("and 8/16 on the command line.");
sox_fail_errno(ft,SOX_EFMT,"Bogus AIFF file: no COMM section.");
@@ -431,13 +416,13 @@
}
- aiff->nsamples = ssndsize / ft->signal.size;
+ aiff->nsamples = ssndsize / (ft->encoding.bits_per_sample >> 3);
/* Cope with 'sowt' CD tracks as read on Macs */
if (is_sowt)
{
aiff->nsamples -= 4;
- ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
+ ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
}
if (foundmark && !foundinstr)
@@ -680,23 +665,14 @@
return rc;
aiff->nsamples = 0;
- if (ft->signal.encoding < SOX_ENCODING_SIZE_IS_WORD &&
- ft->signal.size == SOX_SIZE_BYTE) {
- sox_report("expanding compressed bytes to signed 16 bits");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.size = SOX_SIZE_16BIT;
- }
- if (ft->signal.encoding != SOX_ENCODING_UNKNOWN && ft->signal.encoding != SOX_ENCODING_SIGN2)
- sox_report("AIFF only supports signed data. Forcing to signed.");
- ft->signal.encoding = SOX_ENCODING_SIGN2; /* We have a fixed encoding */
/* Compute the "very large number" so that a maximum number
of samples can be transmitted through a pipe without the
risk of causing overflow when calculating the number of bytes.
- At 48 kHz, 16 bits stereo, this gives ~3 hours of music.
- Sorry, the AIFF format does not provide for an "infinite"
+ At 48 kHz, 16 bits stereo, this gives ~3 hours of audio.
+ Sorry, the AIFF format does not provide for an indefinite
number of samples. */
- return(aiffwriteheader(ft, 0x7f000000 / (ft->signal.size*ft->signal.channels)));
+ return(aiffwriteheader(ft, 0x7f000000 / ((ft->encoding.bits_per_sample>>3)*ft->signal.channels)));
}
sox_size_t sox_aiffwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
@@ -713,7 +689,7 @@
/* If we've written an odd number of bytes, write a padding
NUL */
- if (aiff->nsamples % 2 == 1 && ft->signal.size == SOX_SIZE_8BIT && ft->signal.channels == 1)
+ if (aiff->nsamples % 2 == 1 && ft->encoding.bits_per_sample == 8 && ft->signal.channels == 1)
{
sox_sample_t buf = 0;
sox_rawwrite(ft, &buf, 1);
@@ -749,17 +725,17 @@
hsize += 8 /* INST hdr */ + 20; /* INST chunk */
}
- if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_BYTE)
+ if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 8)
bits = 8;
- else if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_16BIT)
+ else if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 16)
bits = 16;
- else if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_24BIT)
+ else if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 24)
bits = 24;
- else if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_32BIT)
+ else if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 32)
bits = 32;
else
{
@@ -784,7 +760,7 @@
sox_writes(ft, "FORM"); /* IFF header */
/* file size */
- sox_writedw(ft, hsize + nframes * ft->signal.size * ft->signal.channels);
+ sox_writedw(ft, hsize + nframes * (ft->encoding.bits_per_sample >> 3) * ft->signal.channels);
sox_writes(ft, "AIFF"); /* File type */
/* Now we write the COMT comment chunk using the precomputed sizes */
@@ -798,7 +774,7 @@
/* time stamp of comment, Unix knows of time from 1/1/1970,
Apple knows time from 1/1/1904 */
- sox_writedw(ft, (unsigned)(time(NULL) + 2082844800));
+ sox_writedw(ft, (unsigned)((sox_globals.repeatable? 0 : time(NULL)) + 2082844800));
/* A marker ID of 0 indicates the comment is not associated
with a marker */
@@ -869,7 +845,7 @@
/* SSND chunk -- describes data */
sox_writes(ft, "SSND");
/* chunk size */
- sox_writedw(ft, 8 + nframes * ft->signal.channels * ft->signal.size);
+ sox_writedw(ft, 8 + nframes * ft->signal.channels * (ft->encoding.bits_per_sample >> 3));
sox_writedw(ft, 0); /* offset */
sox_writedw(ft, 0); /* block size */
return(SOX_SUCCESS);
@@ -886,15 +862,6 @@
return rc;
aiff->nsamples = 0;
- if (ft->signal.encoding < SOX_ENCODING_SIZE_IS_WORD &&
- ft->signal.size == SOX_SIZE_BYTE) {
- sox_report("expanding compressed bytes to signed 16 bits");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.size = SOX_SIZE_16BIT;
- }
- if (ft->signal.encoding != SOX_ENCODING_UNKNOWN && ft->signal.encoding != SOX_ENCODING_SIGN2)
- sox_report("AIFC only supports signed data. Forcing to signed.");
- ft->signal.encoding = SOX_ENCODING_SIGN2; /* We have a fixed encoding */
/* Compute the "very large number" so that a maximum number
of samples can be transmitted through a pipe without the
@@ -902,7 +869,7 @@
At 48 kHz, 16 bits stereo, this gives ~3 hours of music.
Sorry, the AIFC format does not provide for an "infinite"
number of samples. */
- return(aifcwriteheader(ft, 0x7f000000 / (ft->signal.size*ft->signal.channels)));
+ return(aifcwriteheader(ft, 0x7f000000 / ((ft->encoding.bits_per_sample >> 3)*ft->signal.channels)));
}
int sox_aifcstopwrite(sox_format_t * ft)
@@ -911,7 +878,7 @@
/* If we've written an odd number of bytes, write a padding
NUL */
- if (aiff->nsamples % 2 == 1 && ft->signal.size == SOX_SIZE_8BIT && ft->signal.channels == 1)
+ if (aiff->nsamples % 2 == 1 && ft->encoding.bits_per_sample == 8 && ft->signal.channels == 1)
{
sox_sample_t buf = 0;
sox_rawwrite(ft, &buf, 1);
@@ -937,17 +904,17 @@
8 /*SSND hdr*/ + 12 /*SSND chunk*/;
unsigned bits = 0;
- if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_BYTE)
+ if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 8)
bits = 8;
- else if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_16BIT)
+ else if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 16)
bits = 16;
- else if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_24BIT)
+ else if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 24)
bits = 24;
- else if (ft->signal.encoding == SOX_ENCODING_SIGN2 &&
- ft->signal.size == SOX_SIZE_32BIT)
+ else if (ft->encoding.encoding == SOX_ENCODING_SIGN2 &&
+ ft->encoding.bits_per_sample == 32)
bits = 32;
else
{
@@ -957,7 +924,7 @@
sox_writes(ft, "FORM"); /* IFF header */
/* file size */
- sox_writedw(ft, hsize + nframes * ft->signal.size * ft->signal.channels);
+ sox_writedw(ft, hsize + nframes * (ft->encoding.bits_per_sample >> 3) * ft->signal.channels);
sox_writes(ft, "AIFC"); /* File type */
/* FVER chunk */
@@ -981,7 +948,7 @@
/* SSND chunk -- describes data */
sox_writes(ft, "SSND");
/* chunk size */
- sox_writedw(ft, 8 + nframes * ft->signal.channels * ft->signal.size);
+ sox_writedw(ft, 8 + nframes * ft->signal.channels * (ft->encoding.bits_per_sample >> 3));
sox_writedw(ft, 0); /* offset */
sox_writedw(ft, 0); /* block size */
--- a/src/al-fmt.c
+++ b/src/al-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX al raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(al, 8BIT, 0, ALAW)
+RAW_FORMAT(al, 8, 0, ALAW)
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -22,46 +22,46 @@
static int get_format(sox_format_t * ft, snd_pcm_format_mask_t *fmask, int *fmt)
{
- if (ft->signal.size != SOX_SIZE_16BIT)
+ if (ft->encoding.bits_per_sample != 16)
{
sox_report("trying for word samples.");
- ft->signal.size = SOX_SIZE_16BIT;
+ ft->encoding.bits_per_sample = 16;
}
- if (ft->signal.encoding != SOX_ENCODING_SIGN2 &&
- ft->signal.encoding != SOX_ENCODING_UNSIGNED)
+ if (ft->encoding.encoding != SOX_ENCODING_SIGN2 &&
+ ft->encoding.encoding != SOX_ENCODING_UNSIGNED)
{
- if (ft->signal.size == SOX_SIZE_16BIT)
+ if (ft->encoding.bits_per_sample == 16)
{
- if (ft->signal.encoding != SOX_ENCODING_UNKNOWN)
+ if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN)
sox_report("driver supports only signed and unsigned samples. Changing to signed.");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
else
{
- if (ft->signal.encoding != SOX_ENCODING_UNKNOWN)
+ if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN)
sox_report("driver supports only signed and unsigned samples. Changing to unsigned.");
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
}
}
/* Some hardware only wants to work with 8-bit or 16-bit data */
- if (ft->signal.size == SOX_SIZE_BYTE)
+ if (ft->encoding.bits_per_sample == 8)
{
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_U8)) &&
!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S8)))
{
sox_report("driver doesn't supported byte samples. Changing to words.");
- ft->signal.size = SOX_SIZE_16BIT;
+ ft->encoding.bits_per_sample = 16;
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT)
+ else if (ft->encoding.bits_per_sample == 16)
{
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_U16)) &&
!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S16)))
{
sox_report("driver doesn't supported word samples. Changing to bytes.");
- ft->signal.size = SOX_SIZE_BYTE;
+ ft->encoding.bits_per_sample = 8;
}
}
else
@@ -69,24 +69,24 @@
if ((snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_U16)) ||
(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S16)))
{
- sox_report("driver doesn't supported %s samples. Changing to words.", sox_sizes_str[ft->signal.size]);
- ft->signal.size = SOX_SIZE_16BIT;
+ sox_report("driver doesn't supported %u-bit samples. Changing to 16-bit.", ft->encoding.bits_per_sample);
+ ft->encoding.bits_per_sample = 16;
}
else
{
- sox_report("driver doesn't supported %s samples. Changing to bytes.", sox_sizes_str[ft->signal.size]);
- ft->signal.size = SOX_SIZE_BYTE;
+ sox_report("driver doesn't supported %u-bit samples. Changing to 8-bit.", ft->encoding.bits_per_sample);
+ ft->encoding.bits_per_sample = 8;
}
}
- if (ft->signal.size == SOX_SIZE_BYTE) {
- switch (ft->signal.encoding)
+ if (ft->encoding.bits_per_sample == 8) {
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_SIGN2:
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S8)))
{
sox_report("driver doesn't supported signed byte samples. Changing to unsigned bytes.");
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
}
break;
case SOX_ENCODING_UNSIGNED:
@@ -93,13 +93,13 @@
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_U8)))
{
sox_report("driver doesn't supported unsigned byte samples. Changing to signed bytes.");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
break;
default:
break;
}
- switch (ft->signal.encoding)
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_SIGN2:
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S8)))
@@ -121,14 +121,14 @@
break;
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT) {
- switch (ft->signal.encoding)
+ else if (ft->encoding.bits_per_sample == 16) {
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_SIGN2:
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S16)))
{
sox_report("driver does not support signed word samples. Changing to unsigned words.");
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
}
break;
case SOX_ENCODING_UNSIGNED:
@@ -135,13 +135,13 @@
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_U16)))
{
sox_report("driver does not support unsigned word samples. Changing to signed words.");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
break;
default:
break;
}
- switch (ft->signal.encoding)
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_SIGN2:
if (!(snd_pcm_format_mask_test(fmask, SND_PCM_FORMAT_S16)))
@@ -164,14 +164,14 @@
}
}
else {
- sox_fail_errno(ft,SOX_EFMT,"ALSA driver does not support %s %s output",
- sox_encodings_str[(unsigned char)ft->signal.encoding], sox_sizes_str[ft->signal.size]);
+ sox_fail_errno(ft,SOX_EFMT,"ALSA driver does not support %s %u-bit output",
+ sox_encodings_str[(unsigned char)ft->encoding.encoding], ft->encoding.bits_per_sample);
return SOX_EOF;
}
return 0;
}
-static int sox_alsasetup(sox_format_t * ft, snd_pcm_stream_t mode)
+static int setup(sox_format_t * ft, snd_pcm_stream_t mode)
{
int fmt = SND_PCM_FORMAT_S16;
int err;
@@ -293,7 +293,7 @@
}
/* Have a much larger buffer than sox_globals.bufsiz to avoid underruns */
- buffer_size = sox_globals.bufsiz * 8 / ft->signal.size / ft->signal.channels;
+ buffer_size = sox_globals.bufsiz * 8 / (ft->encoding.bits_per_sample >> 3) / ft->signal.channels;
if (snd_pcm_hw_params_get_buffer_size_min(hw_params, &buffer_size_min) < 0)
{
@@ -369,7 +369,7 @@
goto open_error;
}
- alsa->buf_size = buffer_size * ft->signal.size * ft->signal.channels;
+ alsa->buf_size = buffer_size * (ft->encoding.bits_per_sample >> 3) * ft->signal.channels;
alsa->period_size = period_size;
alsa->frames_this_period = 0;
alsa->buf = xmalloc(alsa->buf_size);
@@ -424,9 +424,9 @@
* size and encoding of samples,
* mono/stereo/quad.
*/
-static int sox_alsastartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
- return sox_alsasetup(ft, SND_PCM_STREAM_CAPTURE);
+ return setup(ft, SND_PCM_STREAM_CAPTURE);
}
static void ub_read_buf(sox_sample_t *buf1, char const * buf2, sox_size_t len, sox_bool swap UNUSED, sox_size_t * clips UNUSED)
@@ -467,15 +467,15 @@
}
}
-static sox_size_t sox_alsaread(sox_format_t * ft, sox_sample_t *buf, sox_size_t nsamp)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t nsamp)
{
alsa_priv_t alsa = (alsa_priv_t)ft->priv;
void (*read_buf)(sox_sample_t *, char const *, sox_size_t, sox_bool, sox_size_t *) = 0;
sox_size_t len;
- switch(ft->signal.size) {
- case SOX_SIZE_BYTE:
- switch(ft->signal.encoding) {
+ switch(ft->encoding.bits_per_sample) {
+ case 8:
+ switch(ft->encoding.encoding) {
case SOX_ENCODING_SIGN2: read_buf = sb_read_buf; break;
case SOX_ENCODING_UNSIGNED: read_buf = ub_read_buf; break;
default:
@@ -483,8 +483,8 @@
return 0;
}
break;
- case SOX_SIZE_16BIT:
- switch(ft->signal.encoding) {
+ case 16:
+ switch(ft->encoding.encoding) {
case SOX_ENCODING_SIGN2: read_buf = sw_read_buf; break;
case SOX_ENCODING_UNSIGNED: read_buf = uw_read_buf; break;
default:
@@ -498,8 +498,8 @@
}
/* Prevent overflow */
- if (nsamp > alsa->buf_size/ft->signal.size)
- nsamp = (alsa->buf_size/ft->signal.size);
+ if (nsamp > alsa->buf_size/(ft->encoding.bits_per_sample >> 3))
+ nsamp = (alsa->buf_size/(ft->encoding.bits_per_sample >> 3));
len = 0;
while (len < nsamp) {
@@ -512,7 +512,7 @@
}
} else {
n *= ft->signal.channels;
- read_buf(buf + len, alsa->buf, n, ft->signal.reverse_bytes, &ft->clips);
+ read_buf(buf + len, alsa->buf, n, ft->encoding.reverse_bytes, &ft->clips);
len += n;
}
}
@@ -519,7 +519,7 @@
return len;
}
-static int sox_alsastopread(sox_format_t * ft)
+static int stopread(sox_format_t * ft)
{
alsa_priv_t alsa = (alsa_priv_t)ft->priv;
@@ -530,9 +530,9 @@
return SOX_SUCCESS;
}
-static int sox_alsastartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
- return sox_alsasetup(ft, SND_PCM_STREAM_PLAYBACK);
+ return setup(ft, SND_PCM_STREAM_PLAYBACK);
}
static void sox_ub_write_buf(char* buf1, sox_sample_t const * buf2, sox_size_t len, sox_bool swap UNUSED, sox_size_t * clips)
@@ -571,15 +571,15 @@
}
}
-static sox_size_t sox_alsawrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t nsamp)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t nsamp)
{
sox_size_t osamp, done;
alsa_priv_t alsa = (alsa_priv_t)ft->priv;
void (*write_buf)(char *, const sox_sample_t *, sox_size_t, sox_bool, sox_size_t *) = 0;
- switch(ft->signal.size) {
- case SOX_SIZE_BYTE:
- switch (ft->signal.encoding)
+ switch(ft->encoding.bits_per_sample) {
+ case 8:
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_SIGN2:
write_buf = sox_sb_write_buf;
@@ -592,8 +592,8 @@
return 0;
}
break;
- case SOX_SIZE_16BIT:
- switch (ft->signal.encoding)
+ case 16:
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_SIGN2:
write_buf = sox_sw_write_buf;
@@ -615,13 +615,13 @@
int err;
sox_size_t len;
- osamp = min(nsamp - done, alsa->buf_size / ft->signal.size);
- write_buf(alsa->buf, buf, osamp, ft->signal.reverse_bytes, &ft->clips);
+ osamp = min(nsamp - done, alsa->buf_size / (ft->encoding.bits_per_sample >> 3));
+ write_buf(alsa->buf, buf, osamp, ft->encoding.reverse_bytes, &ft->clips);
buf += osamp;
for (len = 0; len < osamp;) {
err = snd_pcm_writei(alsa->pcm_handle,
- alsa->buf + (len * ft->signal.size),
+ alsa->buf + (len * (ft->encoding.bits_per_sample >> 3)),
(osamp - len) / ft->signal.channels);
if (errno == EAGAIN) /* Happens naturally; don't report it */
errno = 0;
@@ -642,7 +642,7 @@
}
-static int sox_alsastopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
alsa_priv_t alsa = (alsa_priv_t)ft->priv;
@@ -650,7 +650,7 @@
* whole periods to the hardware */
snd_pcm_uframes_t frames_of_silence = alsa->period_size - alsa->frames_this_period;
- memset(alsa->buf, 0, frames_of_silence * ft->signal.size * ft->signal.channels);
+ memset(alsa->buf, 0, frames_of_silence * (ft->encoding.bits_per_sample >> 3) * ft->signal.channels);
sox_debug("padding output with %u silent samples", (unsigned)frames_of_silence);
while (frames_of_silence > 0) {
@@ -676,26 +676,18 @@
return SOX_SUCCESS;
}
-static const char *alsanames[] = {
- "alsa",
- NULL
-};
-
-static sox_format_handler_t sox_alsa_format = {
- alsanames,
- SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
- sox_alsastartread,
- sox_alsaread,
- sox_alsastopread,
- sox_alsastartwrite,
- sox_alsawrite,
- sox_alsastopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_alsa_format_fn(void);
-
-const sox_format_handler_t *sox_alsa_format_fn(void)
+SOX_FORMAT_HANDLER(alsa)
{
- return &sox_alsa_format;
+ static char const * const names[] = { "alsa", NULL };
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 8, 0,
+ SOX_ENCODING_UNSIGNED, 16, 8, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/amr-nb.c
+++ b/src/amr-nb.c
@@ -21,6 +21,8 @@
* or install equivalent package(s) e.g. marillat.
*/
+#include "sox_i.h"
+
#include "amrnb/typedef.h"
#include "amrnb/interf_dec.h"
#include "amrnb/sp_dec.h"
--- a/src/amr-wb.c
+++ b/src/amr-wb.c
@@ -21,6 +21,8 @@
* or install equivalent package(s) e.g. marillat.
*/
+#include "sox_i.h"
+
#include "amrwb/typedef.h"
#include "amrwb/enc_if.h"
#include "amrwb/dec_if.h"
--- a/src/amr.h
+++ b/src/amr.h
@@ -16,7 +16,6 @@
* Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
-#include "sox_i.h"
#include <string.h>
#include <math.h>
@@ -56,14 +55,6 @@
return result;
}
-static void set_format(sox_format_t * ft)
-{
- ft->signal.rate = AMR_RATE;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = AMR_ENCODING;
- ft->signal.channels = 1;
-}
-
static int startread(sox_format_t * ft)
{
amr_t amr = (amr_t) ft->priv;
@@ -80,7 +71,9 @@
sox_fail_errno(ft, SOX_EHDR, "invalid magic number");
return SOX_EOF;
}
- set_format(ft);
+ ft->signal.rate = AMR_RATE;
+ ft->encoding.encoding = AMR_ENCODING;
+ ft->signal.channels = 1;
return SOX_SUCCESS;
}
@@ -110,9 +103,9 @@
{
amr_t amr = (amr_t) ft->priv;
- if (ft->signal.compression != HUGE_VAL) {
- amr->mode = ft->signal.compression;
- if (amr->mode != ft->signal.compression || amr->mode > AMR_MODE_MAX) {
+ if (ft->encoding.compression != HUGE_VAL) {
+ amr->mode = ft->encoding.compression;
+ if (amr->mode != ft->encoding.compression || amr->mode > AMR_MODE_MAX) {
sox_fail_errno(ft, SOX_EINVAL, "compression level must be a whole number from 0 to %i", AMR_MODE_MAX);
return SOX_EOF;
}
@@ -119,7 +112,6 @@
}
else amr->mode = 0;
- set_format(ft);
#include "amr2.h"
sox_writes(ft, magic);
amr->pcm_index = 0;
@@ -158,16 +150,17 @@
return result;
}
-const sox_format_handler_t *AMR_FORMAT_FN(void);
-
-const sox_format_handler_t *AMR_FORMAT_FN(void)
+sox_format_handler_t const * AMR_FORMAT_FN(void);
+sox_format_handler_t const * AMR_FORMAT_FN(void)
{
- static char const * names[] = {AMR_NAMES, NULL};
+ static char const * const names[] = {AMR_NAMES, NULL};
+ static sox_rate_t const write_rates[] = {AMR_RATE, 0};
+ static unsigned const write_encodings[] = {AMR_ENCODING, 0, 0};
static sox_format_handler_t handler = {
- names, 0,
+ names, SOX_FILE_MONO,
startread, read, stopread,
startwrite, write, stopwrite,
- NULL
+ NULL, write_encodings, write_rates
};
return &handler;
}
--- a/src/ao.c
+++ b/src/ao.c
@@ -38,16 +38,8 @@
ao_priv_t ao = (ao_priv_t)ft->priv;
set_signal_defaults(&ft->signal);
- if (ft->signal.size != SOX_SIZE_16BIT ||
- ft->signal.encoding != SOX_ENCODING_SIGN2)
- {
- sox_report("Forcing to signed 16 bit samples for ao driver");
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- }
-
- ao->buf_size = sox_globals.bufsiz - (sox_globals.bufsiz % ft->signal.size);
- ao->buf_size *= ft->signal.size;
+ ao->buf_size = sox_globals.bufsiz - (sox_globals.bufsiz % (ft->encoding.bits_per_sample >> 3));
+ ao->buf_size *= (ft->encoding.bits_per_sample >> 3);
ao->buf = xmalloc(ao->buf_size);
if (!ao->buf)
@@ -73,7 +65,7 @@
}
}
- ao->format.bits = ft->signal.size * 8;
+ ao->format.bits = ft->encoding.bits_per_sample;
ao->format.rate = ft->signal.rate;
ao->format.channels = ft->signal.channels;
ao->format.byte_format = AO_FMT_NATIVE;
@@ -97,17 +89,17 @@
}
}
-static sox_size_t write(sox_format_t *ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, sox_size_t len)
{
ao_priv_t ao = (ao_priv_t)ft->priv;
sox_size_t aobuf_size;
- if (len > ao->buf_size / ft->signal.size)
- len = ao->buf_size / ft->signal.size;
+ if (len > ao->buf_size / (ft->encoding.bits_per_sample >> 3))
+ len = ao->buf_size / (ft->encoding.bits_per_sample >> 3);
- aobuf_size = ft->signal.size * len;
+ aobuf_size = (ft->encoding.bits_per_sample >> 3) * len;
- sox_sw_write_buf((char *)ao->buf, buf, len, ft->signal.reverse_bytes,
+ sox_sw_write_buf((char *)ao->buf, buf, len, ft->encoding.reverse_bytes,
&(ft->clips));
if (ao_play(ao->device, (void *)ao->buf, aobuf_size) == 0)
return 0;
@@ -130,22 +122,15 @@
return SOX_SUCCESS;
}
-/* libao player */
-static const char *aonames[] = {
- "ao",
- NULL
-};
-
-static sox_format_handler_t sox_ao_format = {
- aonames, SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
- NULL, NULL, NULL,
- startwrite, write, stopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_ao_format_fn(void);
-
-const sox_format_handler_t *sox_ao_format_fn(void)
+SOX_FORMAT_HANDLER(ao)
{
- return &sox_ao_format;
+ static char const * const names[] = {"ao", NULL};
+ static unsigned const encodings[] = {SOX_ENCODING_SIGN2, 16, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
+ NULL, NULL, NULL,
+ startwrite, write_samples, stopwrite,
+ NULL, encodings, NULL
+ };
+ return &handler;
}
--- a/src/au.c
+++ b/src/au.c
@@ -1,313 +1,94 @@
/*
* Copyright 1991, 1992, 1993 Guido van Rossum And Sundry Contributors.
* This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Guido van Rossum And Sundry Contributors are not responsible for
+ * any purpose. This copyright notice must be maintained.
+ * Guido van Rossum And Sundry Contributors are not responsible for
* the consequences of using this software.
*
* October 7, 1998 - [email protected]
* G.723 was using incorrect # of bits. Corrected to 3 and 5 bits.
- */
-
-/*
+ *
* libSoX Sun format with header (SunOS 4.1; see /usr/demo/SOUND).
* NeXT uses this format also, but has more format codes defined.
* DEC uses a slight variation and swaps bytes.
- * We only support the common formats.
- * CCITT G.721 (32 kbit/s) and G.723 (24/40 kbit/s) are also supported,
- * courtesy Sun's public domain implementation.
+ * We support only the common formats, plus
+ * CCITT G.721 (32 kbit/s) and G.723 (24/40 kbit/s),
+ * courtesy of Sun's public domain implementation.
* Output is always in big-endian (Sun/NeXT) order.
*/
#include "sox_i.h"
#include "g72x.h"
-#include <stdlib.h>
#include <string.h>
-#include <errno.h>
/* Magic numbers used in Sun and NeXT audio files */
-#define SUN_MAGIC 0x2e736e64 /* Really '.snd' */
-#define SUN_INV_MAGIC 0x646e732e /* '.snd' upside-down */
-#define DEC_MAGIC 0x2e736400 /* Really '\0ds.' (for DEC) */
-#define DEC_INV_MAGIC 0x0064732e /* '\0ds.' upside-down */
-#define SUN_HDRSIZE 24 /* Size of minimal header */
-#define SUN_UNSPEC ((unsigned)(~0)) /* Unspecified data size */
-#define SUN_ENCODING_UNKNOWN 0
-#define SUN_ULAW 1 /* u-law encoding */
-#define SUN_LIN_8 2 /* Linear 8 bits */
-#define SUN_LIN_16 3 /* Linear 16 bits */
-#define SUN_LIN_24 4 /* Linear 24 bits */
-#define SUN_LIN_32 5 /* Linear 32 bits */
-#define SUN_FLOAT 6 /* IEEE FP 32 bits */
-#define SUN_DOUBLE 7 /* IEEE FP 64 bits */
-#define SUN_G721 23 /* CCITT G.721 4-bits ADPCM */
-#define SUN_G723_3 25 /* CCITT G.723 3-bits ADPCM */
-#define SUN_G723_5 26 /* CCITT G.723 5-bits ADPCM */
-#define SUN_ALAW 27 /* a-law encoding */
-/* The other formats are not supported by sox at the moment */
+#define SUN_MAGIC 0x2e736e64 /* Really '.snd' */
+#define SUN_INV_MAGIC 0x646e732e /* '.snd' reversed bytes */
+#define DEC_MAGIC 0x2e736400 /* Really '\0ds.' (for DEC) */
+#define DEC_INV_MAGIC 0x0064732e /* '\0ds.' reversed bytes */
+#define SUN_HDRSIZE 24 /* Size of minimal header */
+#define SUN_UNSPEC ~0u /* Unspecified data size (this is legal) */
-/* Private data */
-typedef struct aupriv {
- /* For writer: size in bytes */
- sox_size_t data_size;
- /* For seeking */
- sox_size_t dataStart;
- /* For G72x decoding: */
- struct g72x_state state;
- int (*dec_routine)(int i, int out_coding, struct g72x_state *state_ptr);
- int dec_bits;
- unsigned int in_buffer;
- int in_bits;
-} *au_t;
+typedef enum {
+ Unspecified, Mulaw_8, Linear_8, Linear_16, Linear_24, Linear_32, Float,
+ Double, Indirect, Nested, Dsp_core, Dsp_data_8, Dsp_data_16, Dsp_data_24,
+ Dsp_data_32, Unknown, Display, Mulaw_squelch, Emphasized, Compressed,
+ Compressed_emphasized, Dsp_commands, Dsp_commands_samples, Adpcm_g721,
+ Adpcm_g722, Adpcm_g723_3, Adpcm_g723_5, Alaw_8, Unknown_other} sun_encoding_t;
+static char const * const str[] = {
+ "Unspecified", "8-bit mu-law", "8-bit signed linear", "16-bit signed linear",
+ "24-bit signed linear", "32-bit signed linear", "Floating-point",
+ "Double precision float", "Fragmented sampled data", "Unknown", "DSP program",
+ "8-bit fixed-point", "16-bit fixed-point", "24-bit fixed-point",
+ "32-bit fixed-point", "Unknown", "Non-audio data", "Mu-law squelch",
+ "16-bit linear with emphasis", "16-bit linear with compression",
+ "16-bit linear with emphasis and compression", "Music Kit DSP commands",
+ "Music Kit DSP samples", "4-bit G.721 ADPCM", "G.722 ADPCM",
+ "3-bit G.723 ADPCM", "5-bit G.723 ADPCM", "8-bit a-law", "Unknown"};
-static void auwriteheader(sox_format_t * ft, sox_size_t data_size);
-
-static int sox_auencodingandsize(uint32_t sun_encoding, sox_encoding_t * encoding, unsigned * size)
+static sun_encoding_t sun_enc(unsigned size, sox_encoding_t sox_enc)
{
- switch (sun_encoding) {
- case SUN_ULAW:
- *encoding = SOX_ENCODING_ULAW;
- *size = SOX_SIZE_BYTE;
- break;
- case SUN_ALAW:
- *encoding = SOX_ENCODING_ALAW;
- *size = SOX_SIZE_BYTE;
- break;
- case SUN_LIN_8:
- *encoding = SOX_ENCODING_SIGN2;
- *size = SOX_SIZE_BYTE;
- break;
- case SUN_LIN_16:
- *encoding = SOX_ENCODING_SIGN2;
- *size = SOX_SIZE_16BIT;
- break;
- case SUN_LIN_24:
- *encoding = SOX_ENCODING_SIGN2;
- *size = SOX_SIZE_24BIT;
- break;
- case SUN_G721:
- *encoding = SOX_ENCODING_SIGN2;
- *size = SOX_SIZE_16BIT;
- break;
- case SUN_G723_3:
- *encoding = SOX_ENCODING_SIGN2;
- *size = SOX_SIZE_16BIT;
- break;
- case SUN_G723_5:
- *encoding = SOX_ENCODING_SIGN2;
- *size = SOX_SIZE_16BIT;
- break;
- case SUN_FLOAT:
- *encoding = SOX_ENCODING_FLOAT;
- *size = SOX_SIZE_32BIT;
- break;
- default:
- sox_debug("encoding: 0x%x", sun_encoding);
- return(SOX_EOF);
- }
- return(SOX_SUCCESS);
+ sun_encoding_t result = Unspecified;
+ if (sox_enc == SOX_ENCODING_ULAW && size == 8) result = Mulaw_8;
+ else if (sox_enc == SOX_ENCODING_ALAW && size == 8) result = Alaw_8;
+ else if (sox_enc == SOX_ENCODING_SIGN2 && size == 8) result = Linear_8;
+ else if (sox_enc == SOX_ENCODING_SIGN2 && size == 16) result = Linear_16;
+ else if (sox_enc == SOX_ENCODING_SIGN2 && size == 24) result = Linear_24;
+ else if (sox_enc == SOX_ENCODING_SIGN2 && size == 32) result = Linear_32;
+ else if (sox_enc == SOX_ENCODING_FLOAT && size == 32) result = Float;
+ else if (sox_enc == SOX_ENCODING_FLOAT && size == 64) result = Double;
+ return result;
}
-static int sox_auseek(sox_format_t * ft, sox_size_t offset)
+static int sox_enc(
+ uint32_t sun_encoding, sox_encoding_t * encoding, unsigned * size)
{
- au_t au = (au_t ) ft->priv;
-
- if (au->dec_routine != NULL)
- {
- sox_fail_errno(ft,SOX_ENOTSUP,"Sorry, DEC unsupported");
- }
- else
- {
- sox_size_t new_offset, channel_block, alignment;
-
- new_offset = offset * ft->signal.size;
- /* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
- alignment = new_offset % channel_block;
- /* Most common mistaken is to compute something like
- * "skip everthing upto and including this sample" so
- * advance to next sample block in this case.
- */
- if (alignment != 0)
- new_offset += (channel_block - alignment);
- new_offset += au->dataStart;
-
- ft->sox_errno = sox_seeki(ft, (sox_ssize_t)new_offset, SEEK_SET);
- }
-
- return(ft->sox_errno);
-}
-
-static int sox_austartread(sox_format_t * ft)
-{
- /* The following 6 variables represent a Sun sound header on disk.
- The numbers are written as big-endians.
- Any extra bytes (totalling hdr_size - 24) are an
- "info" field of unspecified nature, usually a string.
- By convention the header size is a multiple of 4. */
- uint32_t magic;
- uint32_t hdr_size;
- uint32_t data_size;
- uint32_t encoding;
- uint32_t sample_rate;
- uint32_t channels;
-
- unsigned int i;
- char *buf;
- au_t p = (au_t ) ft->priv;
-
- int rc;
-
- /* Check the magic word */
- sox_readdw(ft, &magic);
- if (magic == DEC_INV_MAGIC) {
- sox_debug("Found inverted DEC magic word.");
- /* Inverted headers are not standard. Code was probably
- * left over from pre-standardize period of testing for
- * endianess. Its not hurting though.
- */
- ft->signal.reverse_bytes = SOX_IS_BIGENDIAN;
- }
- else if (magic == SUN_INV_MAGIC) {
- sox_debug("Found inverted Sun/NeXT magic word.");
- ft->signal.reverse_bytes = SOX_IS_BIGENDIAN;
- }
- else if (magic == SUN_MAGIC) {
- sox_debug("Found Sun/NeXT magic word");
- ft->signal.reverse_bytes = SOX_IS_LITTLEENDIAN;
- }
- else if (magic == DEC_MAGIC) {
- sox_debug("Found DEC magic word");
- ft->signal.reverse_bytes = SOX_IS_LITTLEENDIAN;
- }
- else
- {
- sox_fail_errno(ft,SOX_EHDR,"Did not detect valid Sun/NeXT/DEC magic number in header.");
- return(SOX_EOF);
- }
-
- /* Read the header size */
- sox_readdw(ft, &hdr_size);
- if (hdr_size < SUN_HDRSIZE)
- {
- sox_fail_errno(ft,SOX_EHDR,"Sun/NeXT header size too small.");
- return(SOX_EOF);
- }
-
- /* Read the data size; may be ~0 meaning unspecified */
- sox_readdw(ft, &data_size);
-
- /* Read the encoding; there are some more possibilities */
- sox_readdw(ft, &encoding);
-
-
- /* Translate the encoding into encoding and size parameters */
- /* (Or, for G.72x, set the decoding routine and parameters) */
- p->dec_routine = NULL;
- p->in_buffer = 0;
- p->in_bits = 0;
- if(sox_auencodingandsize(encoding, &(ft->signal.encoding),
- &(ft->signal.size)) == SOX_EOF)
- {
- sox_fail_errno(ft,SOX_EFMT,"Unsupported encoding in Sun/NeXT header.\nOnly U-law, signed bytes, signed words, ADPCM, and 32-bit floats are supported.");
- return(SOX_EOF);
- }
- switch (encoding) {
- case SUN_G721:
- g72x_init_state(&p->state);
- p->dec_routine = g721_decoder;
- p->dec_bits = 4;
- break;
- case SUN_G723_3:
- g72x_init_state(&p->state);
- p->dec_routine = g723_24_decoder;
- p->dec_bits = 3;
- break;
- case SUN_G723_5:
- g72x_init_state(&p->state);
- p->dec_routine = g723_40_decoder;
- p->dec_bits = 5;
- break;
- }
-
-
- /* Read the sampling rate */
- sox_readdw(ft, &sample_rate);
- if (ft->signal.rate == 0 || ft->signal.rate == sample_rate)
- ft->signal.rate = sample_rate;
- else
- sox_report("User options overriding rate read in .au header");
+ switch (sun_encoding) {
+ case Mulaw_8 : *encoding = SOX_ENCODING_ULAW ; *size = 8; break;
+ case Alaw_8 : *encoding = SOX_ENCODING_ALAW ; *size = 8; break;
+ case Linear_8 : *encoding = SOX_ENCODING_SIGN2; *size = 8; break;
+ case Linear_16 : *encoding = SOX_ENCODING_SIGN2; *size = 16; break;
+ case Linear_24 : *encoding = SOX_ENCODING_SIGN2; *size = 24; break;
+ case Linear_32 : *encoding = SOX_ENCODING_SIGN2; *size = 32; break;
+ case Float : *encoding = SOX_ENCODING_FLOAT; *size = 32; break;
+ case Double : *encoding = SOX_ENCODING_FLOAT; *size = 64; break;
+ /* Sun encodings that SoX can read, but not write: */
+ case Adpcm_g721 : *encoding = SOX_ENCODING_G721 ; *size = 4; break;
+ case Adpcm_g723_3: *encoding = SOX_ENCODING_G723 ; *size = 3; break;
+ case Adpcm_g723_5: *encoding = SOX_ENCODING_G723 ; *size = 5; break;
- /* Read the number of channels */
- sox_readdw(ft, &channels);
- if (ft->signal.channels == 0 || ft->signal.channels == channels)
- ft->signal.channels = channels;
- else
- sox_report("User options overriding channels read in .au header");
-
-
- /* Skip the info string in header; print it if verbose */
- hdr_size -= SUN_HDRSIZE; /* #bytes already read */
- if (hdr_size > 0) {
- /* Allocate comment buffer */
- buf = (char *) xmalloc(hdr_size+1);
-
- for(i = 0; i < hdr_size; i++) {
- sox_readb(ft, (unsigned char *)&(buf[i]));
- if (sox_eof(ft))
- {
- sox_fail_errno(ft,SOX_EOF,"Unexpected EOF in Sun/NeXT header info.");
- return(SOX_EOF);
- }
- }
- /* Buffer should already be null terminated but
- * just in case we xmalloced an extra byte and
- * force the last byte to be 0 anyways.
- * This should help work with a greater array of
- * software.
- */
- buf[hdr_size] = '\0';
+ default: sox_debug("encoding: 0x%x", sun_encoding); return SOX_EOF;
+ }
+ return SOX_SUCCESS;
+}
- append_comments(&ft->comments, buf);
- free(buf);
- }
- /* Needed for seeking */
- ft->length = data_size/ft->signal.size;
- if(ft->seekable)
- p->dataStart = sox_tell(ft);
+typedef struct { /* For G72x decoding: */
+ struct g72x_state state;
+ int (*dec_routine)(int i, int out_coding, struct g72x_state *state_ptr);
+ unsigned int in_buffer;
+ int in_bits;
+} priv_t;
- /* Needed for rawread() */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
- return(SOX_SUCCESS);
-}
-
-/* When writing, the header is supposed to contain the number of
- data bytes written, unless it is written to a pipe.
- Since we don't know how many bytes will follow until we're done,
- we first write the header with an unspecified number of bytes,
- and at the end we rewind the file and write the header again
- with the right size. This only works if the file is seekable;
- if it is not, the unspecified size remains in the header
- (this is legal). */
-
-static int sox_austartwrite(sox_format_t * ft)
-{
- au_t p = (au_t ) ft->priv;
- int rc;
-
- /* Needed because of rawwrite(); */
- rc = sox_rawstartwrite(ft);
- if (rc)
- return rc;
-
- p->data_size = 0;
- auwriteheader(ft, SUN_UNSPEC);
- return(SOX_SUCCESS);
-}
-
/*
* Unpack input codes and pass them back as bytes.
* Returns 1 if there is residual input, returns -1 if eof, else returns 0.
@@ -315,181 +96,149 @@
*/
static int unpack_input(sox_format_t * ft, unsigned char *code)
{
- au_t p = (au_t ) ft->priv;
- unsigned char in_byte;
+ priv_t * p = (priv_t * ) ft->priv;
+ unsigned char in_byte;
- if (p->in_bits < p->dec_bits) {
- if (sox_readb(ft, &in_byte) == SOX_EOF) {
- *code = 0;
- return (-1);
- }
- p->in_buffer |= (in_byte << p->in_bits);
- p->in_bits += 8;
- }
- *code = p->in_buffer & ((1 << p->dec_bits) - 1);
- p->in_buffer >>= p->dec_bits;
- p->in_bits -= p->dec_bits;
- return (p->in_bits > 0);
-}
+ if (p->in_bits < (int)ft->encoding.bits_per_sample) {
+ if (sox_readb(ft, &in_byte) == SOX_EOF) {
+ *code = 0;
+ return -1;
+ }
+ p->in_buffer |= (in_byte << p->in_bits);
+ p->in_bits += 8;
+ }
+ *code = p->in_buffer & ((1 << ft->encoding.bits_per_sample) - 1);
+ p->in_buffer >>= ft->encoding.bits_per_sample;
+ p->in_bits -= ft->encoding.bits_per_sample;
+ return p->in_bits > 0;
+}
-static sox_size_t sox_auread(sox_format_t * ft, sox_sample_t *buf, sox_size_t samp)
+static sox_size_t dec_read(sox_format_t *ft, sox_sample_t *buf, sox_size_t samp)
{
- au_t p = (au_t ) ft->priv;
- unsigned char code;
- int done;
- if (p->dec_routine == NULL)
- return sox_rawread(ft, buf, samp);
- done = 0;
- while (samp > 0 && unpack_input(ft, &code) >= 0) {
- *buf++ = SOX_SIGNED_16BIT_TO_SAMPLE(
- (*p->dec_routine)(code, AUDIO_ENCODING_LINEAR,
- &p->state),);
- samp--;
- done++;
- }
- return done;
-}
+ priv_t * p = (priv_t *)ft->priv;
+ unsigned char code;
+ sox_size_t done;
-static sox_size_t sox_auwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t samp)
-{
- au_t p = (au_t ) ft->priv;
- p->data_size += samp * ft->signal.size;
- return(sox_rawwrite(ft, buf, samp));
+ for (done = 0; samp > 0 && unpack_input(ft, &code) >= 0; ++done, --samp)
+ *buf++ = SOX_SIGNED_16BIT_TO_SAMPLE(
+ (*p->dec_routine)(code, AUDIO_ENCODING_LINEAR, &p->state),);
+ return done;
}
-static int sox_austopwrite(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
- au_t p = (au_t ) ft->priv;
+ priv_t * p = (priv_t * ) ft->priv;
+ uint32_t magic; /* These 6 uint32_t variables represent a Sun sound */
+ uint32_t hdr_size; /* header on disk. The numbers are written as */
+ uint32_t data_size; /* big-endians. Any extra bytes (totalling */
+ uint32_t sun_encoding; /* hdr_size - 24) are an "info" field of */
+ uint32_t sample_rate; /* unspecified nature, usually a string. By */
+ uint32_t channels; /* convention the header size is a multiple of 4. */
+ unsigned bits_per_sample;
+ sox_encoding_t sox_encoding;
- /* Attempt to update header */
- if (ft->seekable)
- {
- if (sox_seeki(ft, 0, 0) != 0)
- {
- sox_fail_errno(ft,errno,"Can't rewind output file to rewrite Sun header.");
- return(SOX_EOF);
- }
- auwriteheader(ft, p->data_size);
- }
- return(SOX_SUCCESS);
-}
+ sox_readdw(ft, &magic);
+ if (magic == DEC_INV_MAGIC) {
+ sox_debug("Found inverted DEC magic word.");
+ /* Inverted headers are not standard. Code was probably
+ * left over from pre-standardize period of testing for
+ * endianess. Its not hurting though.
+ */
+ ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN;
+ }
+ else if (magic == SUN_INV_MAGIC) {
+ sox_debug("Found inverted Sun/NeXT magic word.");
+ ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN;
+ }
+ else if (magic == SUN_MAGIC) {
+ sox_debug("Found Sun/NeXT magic word");
+ ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN;
+ }
+ else if (magic == DEC_MAGIC) {
+ sox_debug("Found DEC magic word");
+ ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN;
+ }
+ else {
+ sox_fail_errno(ft,SOX_EHDR,"Did not detect valid Sun/NeXT/DEC magic number in header.");
+ return SOX_EOF;
+ }
-static unsigned sox_ausunencoding(unsigned size, sox_encoding_t encoding)
-{
- unsigned sun_encoding;
+ sox_readdw(ft, &hdr_size);
+ if (hdr_size < SUN_HDRSIZE) {
+ sox_fail_errno(ft, SOX_EHDR, "Sun/NeXT header size too small.");
+ return SOX_EOF;
+ }
+ sox_readdw(ft, &data_size); /* Can be SUN_UNSPEC */
+ sox_readdw(ft, &sun_encoding);
+ sox_readdw(ft, &sample_rate);
+ sox_readdw(ft, &channels);
- if (encoding == SOX_ENCODING_ULAW && size == SOX_SIZE_BYTE)
- sun_encoding = SUN_ULAW;
- else if (encoding == SOX_ENCODING_ALAW && size == SOX_SIZE_BYTE)
- sun_encoding = SUN_ALAW;
- else if (encoding == SOX_ENCODING_SIGN2 && size == SOX_SIZE_BYTE)
- sun_encoding = SUN_LIN_8;
- else if (encoding == SOX_ENCODING_SIGN2 && size == SOX_SIZE_16BIT)
- sun_encoding = SUN_LIN_16;
- else if (encoding == SOX_ENCODING_SIGN2 && size == SOX_SIZE_24BIT)
- sun_encoding = SUN_LIN_24;
- else if (encoding == SOX_ENCODING_FLOAT && size == SOX_SIZE_32BIT)
- sun_encoding = SUN_FLOAT;
- else sun_encoding = SUN_ENCODING_UNKNOWN;
- return sun_encoding;
-}
-
-static void auwriteheader(sox_format_t * ft, sox_size_t data_size)
-{
- uint32_t magic;
- uint32_t hdr_size;
- uint32_t encoding;
- uint32_t sample_rate;
- uint32_t channels;
- int x;
- int comment_size;
- char * comment = cat_comments(ft->comments);
-
- encoding = sox_ausunencoding(ft->signal.size, ft->signal.encoding);
- if (encoding == SUN_ENCODING_UNKNOWN) {
- sox_report("Unsupported output encoding/size for Sun/NeXT header or .AU format not specified.");
- sox_report("Only u-law, A-law, and signed 8/16/24 bits are supported.");
- if (ft->signal.size > SOX_SIZE_16BIT) {
- sox_report("Defaulting to signed 24 bit");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.size = SOX_SIZE_24BIT;
- encoding = SUN_LIN_24;
- }
- else if (ft->signal.size == SOX_SIZE_16BIT) {
- sox_report("Defaulting to signed 16 bit");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- encoding = SUN_LIN_16;
- }
- else {
- sox_report("Defaulting to 8khz u-law");
- encoding = SUN_ULAW;
- ft->signal.encoding = SOX_ENCODING_ULAW;
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.rate = 8000; /* strange but true */
- }
- }
+ if (sox_enc(sun_encoding, &sox_encoding, &bits_per_sample) == SOX_EOF) {
+ int n = min(sun_encoding, Unknown_other);
+ sox_fail_errno(ft, SOX_EFMT, "unsupported encoding `%s' (%u)", str[n], sun_encoding);
+ return SOX_EOF;
+ }
+ switch (sun_encoding) {
+ case Adpcm_g721 : p->dec_routine = g721_decoder ; break;
+ case Adpcm_g723_3: p->dec_routine = g723_24_decoder; break;
+ case Adpcm_g723_5: p->dec_routine = g723_40_decoder; break;
+ }
+ if (p->dec_routine) {
+ g72x_init_state(&p->state);
+ ft->handler.seek = NULL;
+ ft->handler.read = dec_read;
+ }
- magic = SUN_MAGIC;
- sox_writedw(ft, magic);
+ hdr_size -= SUN_HDRSIZE; /* # bytes already read */
+ if (hdr_size > 0) {
+ char * buf = xcalloc(1, hdr_size + 1); /* +1 ensures null-terminated */
+ if (sox_readbuf(ft, buf, hdr_size) != hdr_size) {
+ sox_fail_errno(ft, SOX_EOF, "Unexpected EOF in Sun/NeXT header info.");
+ free(buf);
+ return SOX_EOF;
+ }
+ append_comments(&ft->comments, buf);
+ free(buf);
+ }
+ if (data_size == SUN_UNSPEC)
+ data_size = 0; /* SoX uses 0 for unspecified */
+ return sox_check_read_params( ft, channels, (sox_rate_t)sample_rate,
+ sox_encoding, bits_per_sample, div_bits(data_size, bits_per_sample));
+}
- hdr_size = SUN_HDRSIZE;
-
- comment_size = strlen(comment) + 1; /*+1 = null-term. */
- if (comment_size < 4)
- comment_size = 4; /* minimum size */
-
- hdr_size += comment_size;
-
- sox_writedw(ft, hdr_size);
-
- sox_writedw(ft, data_size);
-
- sox_writedw(ft, encoding);
-
- sample_rate = ft->signal.rate;
- sox_writedw(ft, sample_rate);
-
- channels = ft->signal.channels;
- sox_writedw(ft, channels);
-
- sox_writes(ft, comment);
-
- /* Info must be 4 bytes at least and null terminated. */
- x = strlen(comment);
- free(comment);
- for (;x < 3; x++)
- sox_writeb(ft, 0);
-
- sox_writeb(ft, 0);
+static int write_header(sox_format_t * ft)
+{
+ char *comment = cat_comments(ft->comments);
+ size_t len = strlen(comment) + 1; /* Write out null-terminated */
+ size_t info_len = max(4, (len + 3) & ~3u); /* Minimum & multiple of 4 bytes */
+ size_t size = ft->olength? ft->olength : ft->length;
+ sox_bool error = sox_false
+ ||sox_writedw(ft, SUN_MAGIC)
+ ||sox_writedw(ft, SUN_HDRSIZE + info_len)
+ ||sox_writedw(ft, size? size*(ft->encoding.bits_per_sample >> 3) : SUN_UNSPEC)
+ ||sox_writedw(ft, sun_enc(ft->encoding.bits_per_sample,ft->encoding.encoding))
+ ||sox_writedw(ft, (unsigned)(ft->signal.rate + .5))
+ ||sox_writedw(ft, ft->signal.channels)
+ ||sox_writebuf(ft, comment, len) != len
+ ||sox_padbytes(ft, info_len - len);
+ free(comment);
+ return error? SOX_EOF: SOX_SUCCESS;
}
-/* SPARC .au w/header */
-static const char *aunames[] = {
- "au",
- "snd",
- NULL
-};
-
-/* Purposely did not specify format as big endian because
- * it can handle both. This means we must set our own
- * default values for reverse_bytes when not specified
- * since we didn't give the hint to soxio.
- */
-static sox_format_handler_t sox_au_format = {
- aunames,
- SOX_FILE_BIG_END,
- sox_austartread,
- sox_auread,
- sox_rawstopread,
- sox_austartwrite,
- sox_auwrite,
- sox_austopwrite,
- sox_auseek
-};
-
-const sox_format_handler_t *sox_au_format_fn(void);
-
-const sox_format_handler_t *sox_au_format_fn(void)
+SOX_FORMAT_HANDLER(au)
{
- return &sox_au_format;
+ static char const * const names[] = {"au", "snd", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_ULAW, 8, 0,
+ SOX_ENCODING_ALAW, 8, 0,
+ SOX_ENCODING_SIGN2, 8, 16, 24, 32, 0,
+ SOX_ENCODING_FLOAT, 32, 64, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_BIG_END | SOX_FILE_REWIND,
+ startread, sox_rawread, NULL,
+ write_header, sox_rawwrite, NULL,
+ sox_rawseek, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/auto.c
+++ b/src/auto.c
@@ -158,17 +158,15 @@
sox_debug("Detected file format type: %s", type);
set_endianness_if_not_already_set(ft);
- return ft->handler->startread? (* ft->handler->startread)(ft) : SOX_SUCCESS;
+ return ft->handler.startread? (*ft->handler.startread)(ft) : SOX_SUCCESS;
}
-const sox_format_handler_t *sox_auto_format_fn(void);
-const sox_format_handler_t *sox_auto_format_fn(void)
+SOX_FORMAT_HANDLER(auto)
{
static const char *autonames[] = {"magic", NULL};
-
static sox_format_handler_t sox_auto_format = {
autonames, SOX_FILE_DEVICE | SOX_FILE_PHONY,
- sox_autostartread, NULL, NULL, NULL, NULL, NULL, NULL
+ sox_autostartread, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
return &sox_auto_format;
}
--- a/src/avr.c
+++ b/src/avr.c
@@ -19,11 +19,11 @@
*/
+#include "sox_i.h"
+
#include <stdio.h>
#include <string.h>
-#include "sox_i.h"
-
#define AVR_MAGIC "2BIT"
/* Taken from the Audio File Formats FAQ */
@@ -63,7 +63,7 @@
*/
-static int sox_avrstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
avr_t avr = (avr_t)ft->priv;
int rc;
@@ -87,10 +87,10 @@
sox_readw (ft, &(avr->rez));
if (avr->rez == 8) {
- ft->signal.size = SOX_SIZE_BYTE;
+ ft->encoding.bits_per_sample = 8;
}
else if (avr->rez == 16) {
- ft->signal.size = SOX_SIZE_16BIT;
+ ft->encoding.bits_per_sample = 16;
}
else {
sox_fail_errno(ft,SOX_EFMT,"AVR: unsupported sample resolution");
@@ -99,10 +99,10 @@
sox_readw (ft, &(avr->sign));
if (avr->sign) {
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
else {
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
}
sox_readw (ft, &(avr->loop));
@@ -141,7 +141,7 @@
return(SOX_SUCCESS);
}
-static int sox_avrstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
avr_t avr = (avr_t)ft->priv;
int rc;
@@ -181,10 +181,10 @@
}
/* rez */
- if (ft->signal.size == SOX_SIZE_BYTE) {
+ if (ft->encoding.bits_per_sample == 8) {
sox_writew (ft, 8);
}
- else if (ft->signal.size == SOX_SIZE_16BIT) {
+ else if (ft->encoding.bits_per_sample == 16) {
sox_writew (ft, 16);
}
else {
@@ -193,10 +193,10 @@
}
/* sign */
- if (ft->signal.encoding == SOX_ENCODING_SIGN2) {
+ if (ft->encoding.encoding == SOX_ENCODING_SIGN2) {
sox_writew (ft, 0xffff);
}
- else if (ft->signal.encoding == SOX_ENCODING_UNSIGNED) {
+ else if (ft->encoding.encoding == SOX_ENCODING_UNSIGNED) {
sox_writew (ft, 0);
}
else {
@@ -246,7 +246,7 @@
return(SOX_SUCCESS);
}
-static sox_size_t sox_avrwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t nsamp)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t nsamp)
{
avr_t avr = (avr_t)ft->priv;
@@ -255,7 +255,7 @@
return (sox_rawwrite (ft, buf, nsamp));
}
-static int sox_avrstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
avr_t avr = (avr_t)ft->priv;
@@ -272,26 +272,19 @@
return(SOX_SUCCESS);
}
-static const char *avrnames[] = {
- "avr",
- NULL
-};
-
-static sox_format_handler_t sox_avr_format = {
- avrnames,
- SOX_FILE_BIG_END,
- sox_avrstartread,
- sox_rawread,
- NULL,
- sox_avrstartwrite,
- sox_avrwrite,
- sox_avrstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_avr_format_fn(void);
-
-const sox_format_handler_t *sox_avr_format_fn(void)
+SOX_FORMAT_HANDLER(avr)
{
- return &sox_avr_format;
+ static char const * const names[] = { "avr", NULL };
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 8, 0,
+ SOX_ENCODING_UNSIGNED, 16, 8, 0,
+ 0};
+ static sox_format_handler_t handler = {
+ names,
+ SOX_FILE_BIG_END|SOX_FILE_MONO|SOX_FILE_STEREO,
+ startread, sox_rawread, NULL,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/band.h
+++ b/src/band.h
@@ -42,8 +42,8 @@
* Reference from the SPKit manual.
*/
- p->a2 = exp(-2 * M_PI * bw_Hz / effp->ininfo.rate);
- p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->ininfo.rate);
+ p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
+ p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate);
if (p->filter_type == filter_BPF_SPK_N)
p->b0 = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2));
else
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -79,7 +79,7 @@
"disp('Hit return to continue')\n"
"pause\n"
, effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
- , effp->ininfo.rate, effp->ininfo.rate
+ , effp->in_signal.rate, effp->in_signal.rate
, p->b0, p->b1, p->b2, p->a1, p->a2
);
return SOX_EOF;
@@ -100,7 +100,7 @@
"plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"
"pause -1 'Hit return to continue'\n"
, effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
- , effp->ininfo.rate, effp->ininfo.rate
+ , effp->in_signal.rate, effp->in_signal.rate
, p->b0, p->b1, p->b2, p->a1, p->a2
);
return SOX_EOF;
--- a/src/biquads.c
+++ b/src/biquads.c
@@ -141,7 +141,7 @@
static int start(sox_effect_t * effp)
{
biquad_t p = (biquad_t) effp->priv;
- double w0 = 2 * M_PI * p->fc / effp->ininfo.rate;
+ double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
double A = exp(p->gain / 40 * log(10.));
double alpha = 0;
@@ -172,7 +172,7 @@
break;
case width_bw_old:
- alpha = tan(M_PI * p->width / effp->ininfo.rate);
+ alpha = tan(M_PI * p->width / effp->in_signal.rate);
break;
}
switch (p->filter_type) {
@@ -253,7 +253,7 @@
break;
case filter_deemph: /* See deemph.plt for documentation */
- if (effp->ininfo.rate != 44100) {
+ if (effp->in_signal.rate != 44100) {
sox_fail("Sample rate must be 44100 (audio-CD)");
return SOX_EOF;
}
--- a/src/cdr.c
+++ b/src/cdr.c
@@ -1,61 +1,49 @@
/*
- * CD Digital Audio format handler: pads to integer number of CDDA sectors
+ * File format: cdda (c) 2006-8 SoX contributors
+ * Based on an original idea by David Elliott
*
- * David Elliott, Sony Microsystems - July 5, 1991
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
*
- * Copyright 1991 David Elliott And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * David Elliott And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
-#define SECTOR_SIZE (2352 / 2)
-#define samples (*(sox_size_t *)ft->priv)
-
static int start(sox_format_t * ft)
{
- ft->signal.rate = 44100;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.channels = 2;
-
- if (ft->mode == 'r' && ft->seekable) /* Need length for seeking */
- ft->length = sox_filelength(ft)/SOX_SIZE_16BIT;
-
- return SOX_SUCCESS;
+ return sox_check_read_params(ft, 2, 44100., SOX_ENCODING_SIGN2, 16, (off_t)0);
}
-static sox_size_t write(
- sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
-{
- samples += len;
- return sox_rawwrite(ft, buf, len);
-}
-
static int stopwrite(sox_format_t * ft)
{
- sox_size_t i = samples % SECTOR_SIZE;
+ sox_size_t const sector_num_samples = 588 * ft->signal.channels;
+ sox_size_t i = ft->olength % sector_num_samples;
- if (i) while (i++ < SECTOR_SIZE) /* Pad with silence to multiple */
- sox_writew(ft, 0); /* of SECTOR_SIZE samples. */
-
+ if (i) while (i++ < sector_num_samples) /* Pad with silence to multiple */
+ sox_writew(ft, 0); /* of 1/75th of a second. */
return SOX_SUCCESS;
}
-const sox_format_handler_t *sox_cdr_format_fn(void);
-const sox_format_handler_t *sox_cdr_format_fn(void)
+SOX_FORMAT_HANDLER(cdr)
{
- static const char * names[] = {"cdda", "cdr", NULL};
-
+ static char const * const names[] = {"cdda", "cdr", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 16, 0, 0};
+ static sox_rate_t const write_rates[] = {44100, 0};
static sox_format_handler_t handler = {
- names, SOX_FILE_BIG_END,
+ names, SOX_FILE_BIG_END|SOX_FILE_STEREO,
start, sox_rawread, NULL,
- start, write, stopwrite,
- sox_rawseek
+ NULL, sox_rawwrite, stopwrite,
+ sox_rawseek, write_encodings, write_rates
};
-
return &handler;
}
--- a/src/chorus.c
+++ b/src/chorus.c
@@ -62,10 +62,11 @@
* libSoX chorus effect file.
*/
+#include "sox_i.h"
+
#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
#include <math.h>
#include <string.h>
-#include "sox_i.h"
#define MOD_SINE 0
#define MOD_TRIANGLE 1
@@ -153,9 +154,9 @@
}
for ( i = 0; i < chorus->num_chorus; i++ ) {
chorus->samples[i] = (int) ( ( chorus->delay[i] +
- chorus->depth[i] ) * effp->ininfo.rate / 1000.0);
+ chorus->depth[i] ) * effp->in_signal.rate / 1000.0);
chorus->depth_samples[i] = (int) (chorus->depth[i] *
- effp->ininfo.rate / 1000.0);
+ effp->in_signal.rate / 1000.0);
if ( chorus->delay[i] < 20.0 )
{
@@ -197,7 +198,7 @@
sox_fail("chorus: decay must be less that 1.0!" );
return (SOX_EOF);
}
- chorus->length[i] = effp->ininfo.rate / chorus->speed[i];
+ chorus->length[i] = effp->in_signal.rate / chorus->speed[i];
chorus->lookup_tab[i] = (int *) xmalloc(sizeof (int) * chorus->length[i]);
if (chorus->modulation[i] == MOD_SINE)
--- a/src/compand.c
+++ b/src/compand.c
@@ -11,6 +11,8 @@
* the consequences of using this software.
*/
+#include "sox_i.h"
+
#include <string.h>
#include <stdlib.h>
#include "compandt.h"
@@ -130,7 +132,7 @@
unsigned i, j;
sox_debug("%i input channel(s) expected: actually %i",
- l->expectedChannels, effp->outinfo.channels);
+ l->expectedChannels, effp->out_signal.channels);
for (i = 0; i < l->expectedChannels; ++i)
sox_debug("Channel %i: attack = %g decay = %g", i,
l->channels[i].attack_times[0], l->channels[i].attack_times[1]);
@@ -140,14 +142,14 @@
/* Convert attack and decay rates using number of samples */
for (i = 0; i < l->expectedChannels; ++i)
for (j = 0; j < 2; ++j)
- if (l->channels[i].attack_times[j] > 1.0/effp->outinfo.rate)
+ if (l->channels[i].attack_times[j] > 1.0/effp->out_signal.rate)
l->channels[i].attack_times[j] = 1.0 -
- exp(-1.0/(effp->outinfo.rate * l->channels[i].attack_times[j]));
+ exp(-1.0/(effp->out_signal.rate * l->channels[i].attack_times[j]));
else
l->channels[i].attack_times[j] = 1.0;
/* Allocate the delay buffer */
- l->delay_buf_size = l->delay * effp->outinfo.rate * effp->outinfo.channels;
+ l->delay_buf_size = l->delay * effp->out_signal.rate * effp->out_signal.channels;
if (l->delay_buf_size > 0)
l->delay_buf = xcalloc((sox_size_t)l->delay_buf_size, sizeof(*l->delay_buf));
l->delay_buf_index = 0;
@@ -177,7 +179,7 @@
{
compand_t l = (compand_t) effp->priv;
int len = (*isamp > *osamp) ? *osamp : *isamp;
- int filechans = effp->outinfo.channels;
+ int filechans = effp->out_signal.channels;
int idone,odone;
for (idone = 0,odone = 0; idone < len; ibuf += filechans) {
@@ -241,7 +243,7 @@
if (l->delay_buf_full == 0)
l->delay_buf_index = 0;
while (done < *osamp && l->delay_buf_cnt > 0)
- for (chan = 0; chan < effp->outinfo.channels; ++chan) {
+ for (chan = 0; chan < effp->out_signal.channels; ++chan) {
int c = l->expectedChannels > 1 ? chan : 0;
double level_in_lin = l->channels[c].volume;
double level_out_lin = sox_compandt(&l->transfer_fn, level_in_lin);
--- a/src/compandt.c
+++ b/src/compandt.c
@@ -16,6 +16,8 @@
* Compander Transfer Function: (c) 2007 [email protected]
*/
+#include "sox_i.h"
+
#include "compandt.h"
#include <string.h>
--- a/src/compandt.h
+++ b/src/compandt.h
@@ -16,7 +16,6 @@
* Compander Transfer Function: (c) 2007 [email protected]
*/
-#include "sox_i.h"
#include <math.h>
typedef struct {
--- a/src/cvsd-fmt.c
+++ b/src/cvsd-fmt.c
@@ -1,51 +1,32 @@
/*
- * CVSD format module (implementation in cvsd.c)
+ * File format: CVSD (see cvsd.c) (c) 2007-8 SoX contributors
*
- * Copyright (C) 1996-2007 Thomas Sailer and SoX Contributors
- * Thomas Sailer ([email protected]) (HB9JNX/AE4WA)
- * Swiss Federal Institute of Technology, Electronics Lab
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
-#include "sox_i.h"
#include "cvsd.h"
-
- /* Cont. Variable Slope Delta */
-static const char *cvsdnames[] = {
- "cvs",
- "cvsd",
- NULL
-};
-static sox_format_handler_t sox_cvsd_format = {
- cvsdnames,
- 0,
- sox_cvsdstartread,
- sox_cvsdread,
- sox_cvsdstopread,
- sox_cvsdstartwrite,
- sox_cvsdwrite,
- sox_cvsdstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_cvsd_format_fn(void);
-
-const sox_format_handler_t *sox_cvsd_format_fn(void)
+SOX_FORMAT_HANDLER(cvsd)
{
- return &sox_cvsd_format;
+ static char const * const names[] = {"cvsd", "cvs", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_MONO,
+ sox_cvsdstartread, sox_cvsdread, sox_cvsdstopread,
+ sox_cvsdstartwrite, sox_cvsdwrite, sox_cvsdstopwrite,
+ sox_rawseek, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/cvsd.c
+++ b/src/cvsd.c
@@ -118,8 +118,7 @@
p->cvsd_rate = (ft->signal.rate <= 24000) ? 16000 : 32000;
ft->signal.rate = 8000;
ft->signal.channels = 1;
- ft->signal.size = SOX_SIZE_16BIT; /* make output format default to words */
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ sox_rawstart(ft, sox_true, sox_false, sox_true, SOX_ENCODING_CVSD, 1);
/*
* initialize the decoder
*/
@@ -146,7 +145,7 @@
p->com.v_min = 1;
p->com.v_max = -1;
sox_report("cvsd: bit rate %dbit/s, bits from %s", p->cvsd_rate,
- ft->signal.reverse_bits ? "msb to lsb" : "lsb to msb");
+ ft->encoding.reverse_bits ? "msb to lsb" : "lsb to msb");
}
/* ---------------------------------------------------------------------- */
@@ -465,7 +464,7 @@
len = sizeof(hdr->Filename)-1;
memcpy(hdr->Filename, ft->filename, len);
hdr->Id = hdr->State = 0;
- hdr->Unixtime = time(NULL);
+ hdr->Unixtime = sox_globals.repeatable? 0 : time(NULL);
hdr->Usender = hdr->Ureceiver = 0;
hdr->Length = p->bytes_written;
hdr->Srate = p->cvsd_rate/100;
--- a/src/cvsd.h
+++ b/src/cvsd.h
@@ -20,6 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
+#include "sox_i.h"
int sox_cvsdstartread(sox_format_t * ft);
int sox_cvsdstartwrite(sox_format_t * ft);
--- a/src/dat.c
+++ b/src/dat.c
@@ -52,8 +52,7 @@
if (ft->signal.channels == 0)
ft->signal.channels = 1;
- ft->signal.size = SOX_SIZE_64BIT;
- ft->signal.encoding = SOX_ENCODING_FLOAT;
+ ft->encoding.encoding = SOX_ENCODING_FLOAT_TEXT;
return (SOX_SUCCESS);
}
@@ -63,8 +62,6 @@
dat_t dat = (dat_t) ft->priv;
char s[LINEWIDTH];
- ft->signal.size = SOX_SIZE_64BIT;
- ft->signal.encoding = SOX_ENCODING_FLOAT;
dat->timevalue = 0.0;
dat->deltat = 1.0 / (double)ft->signal.rate;
/* Write format comments to start of file */
@@ -144,7 +141,7 @@
sox_writes(ft, s);
done++;
}
- sprintf(s," \015\n");
+ sprintf(s," \r\n");
sox_writes(ft, s);
dat->timevalue += dat->deltat;
}
@@ -151,27 +148,15 @@
return done;
}
-/* Text data samples */
-static const char *datnames[] = {
- "dat",
- NULL
-};
-
-static sox_format_handler_t sox_dat_format = {
- datnames,
- 0,
- sox_datstartread,
- sox_datread,
- NULL,
- sox_datstartwrite,
- sox_datwrite,
- NULL,
- NULL
-};
-
-const sox_format_handler_t *sox_dat_format_fn(void);
-
-const sox_format_handler_t *sox_dat_format_fn(void)
+SOX_FORMAT_HANDLER(dat)
{
- return &sox_dat_format;
+ static char const * const names[] = {"dat", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_FLOAT_TEXT, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, 0,
+ sox_datstartread, sox_datread, NULL,
+ sox_datstartwrite, sox_datwrite, NULL,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/dither.c
+++ b/src/dither.c
@@ -12,9 +12,10 @@
*
*/
+#include "sox_i.h"
+
#include <stdlib.h>
#include <math.h>
-#include "sox_i.h"
typedef struct dither {
double amount;
@@ -48,17 +49,10 @@
{
dither_t dither = (dither_t) effp->priv;
- if (effp->outinfo.encoding == SOX_ENCODING_ULAW ||
- effp->outinfo.encoding == SOX_ENCODING_ALAW) {
- dither->amount *= 16;
- return SOX_SUCCESS;
- } else if (effp->outinfo.size == SOX_SIZE_BYTE) {
- dither->amount *= 256;
- return SOX_SUCCESS;
- } else if (effp->outinfo.size == SOX_SIZE_16BIT)
- return SOX_SUCCESS;
-
- return SOX_EFF_NULL; /* Dithering not needed at >= 24 bits */
+ if (effp->out_signal.precision > 16)
+ return SOX_EFF_NULL; /* Dithering not needed at >= 24 bits */
+ dither->amount *= 1 << (16 - effp->out_signal.precision);
+ return SOX_SUCCESS;
}
static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
--- a/src/dvms-fmt.c
+++ b/src/dvms-fmt.c
@@ -1,51 +1,32 @@
/*
- * DVMS format module (implementation in cvsd.c)
+ * File format: DVMS (see cvsd.c) (c) 2007-8 SoX contributors
*
- * Copyright (C) 1996-2007 Thomas Sailer and SoX Contributors
- * Thomas Sailer ([email protected]) (HB9JNX/AE4WA)
- * Swiss Federal Institute of Technology, Electronics Lab
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
-#include "sox_i.h"
#include "cvsd.h"
-
-/* Cont. Variable Solot Delta */
-static const char *dvmsnames[] = {
- "vms",
- "dvms",
- NULL
-};
-static sox_format_handler_t sox_dvms_format = {
- dvmsnames,
- 0,
- sox_dvmsstartread,
- sox_cvsdread,
- sox_cvsdstopread,
- sox_dvmsstartwrite,
- sox_cvsdwrite,
- sox_dvmsstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_dvms_format_fn(void);
-
-const sox_format_handler_t *sox_dvms_format_fn(void)
+SOX_FORMAT_HANDLER(dvms)
{
- return &sox_dvms_format;
+ static char const * const names[] = {"dvms", "vms", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_MONO,
+ sox_dvmsstartread, sox_cvsdread, sox_cvsdstopread,
+ sox_dvmsstartwrite, sox_cvsdwrite, sox_dvmsstopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/earwax.c
+++ b/src/earwax.c
@@ -67,7 +67,7 @@
{
assert_static(EARWAX_NUMTAPS * sizeof(*taps) <= SOX_MAX_EFFECT_PRIVSIZE,
/* else */ earwax_PRIVSIZE_too_big);
- if (effp->ininfo.rate != 44100 || effp->ininfo.channels != 2) {
+ if (effp->in_signal.rate != 44100 || effp->in_signal.channels != 2) {
sox_fail("works only with stereo audio sampled at 44100Hz (i.e. CDDA)");
return SOX_EOF;
}
--- a/src/echo.c
+++ b/src/echo.c
@@ -55,9 +55,10 @@
* libSoX reverb effect file.
*/
+#include "sox_i.h"
+
#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
#include <math.h>
-#include "sox_i.h"
#define DELAY_BUFSIZ ( 50 * 50U * 1024 )
#define MAX_ECHOS 7 /* 24 bit x ( 1 + MAX_ECHOS ) = */
@@ -132,7 +133,7 @@
return (SOX_EOF);
}
for ( i = 0; i < echo->num_delays; i++ ) {
- echo->samples[i] = echo->delay[i] * effp->ininfo.rate / 1000.0;
+ echo->samples[i] = echo->delay[i] * effp->in_signal.rate / 1000.0;
if ( echo->samples[i] < 1 )
{
sox_fail("echo: delay must be positive!");
@@ -141,7 +142,7 @@
if ( echo->samples[i] > (sox_ssize_t)DELAY_BUFSIZ )
{
sox_fail("echo: delay must be less than %g seconds!",
- DELAY_BUFSIZ / effp->ininfo.rate );
+ DELAY_BUFSIZ / effp->in_signal.rate );
return (SOX_EOF);
}
if ( echo->decay[i] < 0.0 )
--- a/src/echos.c
+++ b/src/echos.c
@@ -46,9 +46,10 @@
* libSoX reverb effect file.
*/
+#include "sox_i.h"
+
#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
#include <math.h>
-#include "sox_i.h"
#define DELAY_BUFSIZ ( 50 * 50U * 1024 )
#define MAX_ECHOS 7 /* 24 bit x ( 1 + MAX_ECHOS ) = */
@@ -125,7 +126,7 @@
return (SOX_EOF);
}
for ( i = 0; i < echos->num_delays; i++ ) {
- echos->samples[i] = echos->delay[i] * effp->ininfo.rate / 1000.0;
+ echos->samples[i] = echos->delay[i] * effp->in_signal.rate / 1000.0;
if ( echos->samples[i] < 1 )
{
sox_fail("echos: delay must be positive!");
@@ -134,7 +135,7 @@
if ( echos->samples[i] > (sox_ssize_t)DELAY_BUFSIZ )
{
sox_fail("echos: delay must be less than %g seconds!",
- DELAY_BUFSIZ / effp->ininfo.rate );
+ DELAY_BUFSIZ / effp->in_signal.rate );
return (SOX_EOF);
}
if ( echos->decay[i] < 0.0 )
--- a/src/effects.c
+++ b/src/effects.c
@@ -92,10 +92,14 @@
/* Effects chain: */
-sox_effects_chain_t * sox_create_effects_chain(void)
+sox_effects_chain_t * sox_create_effects_chain(
+ sox_encodinginfo_t const * in_enc,
+ sox_encodinginfo_t const * out_enc)
{
sox_effects_chain_t * result = xcalloc(1, sizeof(sox_effects_chain_t));
result->global_info = sox_effects_globals;
+ result->in_enc = in_enc;
+ result->out_enc = out_enc;
return result;
}
@@ -117,8 +121,7 @@
* output rate and channels the effect does produce are written back to *in,
* ready for the next effect in the chain.
*/
-int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t
- const * out)
+int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out)
{
int ret, (*start)(sox_effect_t * effp) = effp->handler.start;
unsigned f;
@@ -129,17 +132,19 @@
return SOX_SUCCESS;
}
effp->global_info = &chain->global_info;
- effp->ininfo = *in;
- effp->outinfo = *out;
+ effp->in_signal = *in;
+ effp->out_signal = *out;
+ effp->in_encoding = chain->in_enc;
+ effp->out_encoding = chain->out_enc;
if (!(effp->handler.flags & SOX_EFF_CHAN))
- effp->outinfo.channels = in->channels;
+ effp->out_signal.channels = in->channels;
if (!(effp->handler.flags & SOX_EFF_RATE))
- effp->outinfo.rate = in->rate;
+ effp->out_signal.rate = in->rate;
if (!(effp->handler.flags & SOX_EFF_PREC))
- effp->outinfo.size = in->size;
+ effp->out_signal.precision = in->precision;
effp->flows =
- (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->ininfo.channels;
+ (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
effp->clips = 0;
effp->imin = 0;
eff0 = *effp;
@@ -151,7 +156,7 @@
if (ret != SOX_SUCCESS)
return SOX_EOF;
- *in = effp->outinfo;
+ *in = effp->out_signal;
if (chain->length == SOX_MAX_EFFECTS) {
sox_fail("Too many effects!");
--- a/src/example1.c
+++ b/src/example1.c
@@ -29,9 +29,9 @@
static int input_drain(sox_effect_t *effp, sox_sample_t * obuf, sox_size_t * osamp)
{
- *osamp -= *osamp % effp->outinfo.channels;
+ *osamp -= *osamp % effp->out_signal.channels;
*osamp = sox_read(in, obuf, *osamp);
- *osamp -= *osamp % effp->outinfo.channels;
+ *osamp -= *osamp % effp->out_signal.channels;
if (!*osamp && in->sox_errno)
fprintf(stderr, "%s: %s\n", in->filename, in->sox_errstr);
return *osamp? SOX_SUCCESS : SOX_EOF;
@@ -73,7 +73,7 @@
*/
int main(int argc, char * argv[])
{
- sox_effects_chain_t * chain = sox_create_effects_chain();
+ sox_effects_chain_t * chain;
sox_effect_t e;
char * vol[] = {"3dB"};
@@ -80,7 +80,11 @@
assert(argc == 3);
assert(sox_format_init() == SOX_SUCCESS);
- assert(in = sox_open_read(argv[1], NULL, NULL));
+ assert(in = sox_open_read(argv[1], NULL, NULL, NULL));
+ assert(out = sox_open_write(NULL, argv[2], &in->signal, NULL, NULL, NULL, 0, NULL, 0));
+
+ chain = sox_create_effects_chain(&in->encoding, &out->encoding);
+
sox_create_effect(&e, input_handler());
assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
@@ -92,14 +96,13 @@
assert(e.handler.getopts(&e, 0, NULL) == SOX_SUCCESS);
assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
- assert(out = sox_open_write(NULL, argv[2], &in->signal, NULL, NULL, 0, NULL, 0));
sox_create_effect(&e, output_handler());
assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
- assert(sox_flow_effects(chain, NULL) == SOX_SUCCESS);
+ sox_flow_effects(chain, NULL);
- sox_close(out);
sox_delete_effects(chain);
+ sox_close(out);
sox_close(in);
sox_format_quit();
free(chain);
--- a/src/fade.c
+++ b/src/fade.c
@@ -9,6 +9,8 @@
* the consequences of using this software.
*/
+#include "sox_i.h"
+
/* Fade curves */
#define FADE_QUARTER 'q' /* Quarter of sine wave, 0 to pi/2 */
#define FADE_HALF 'h' /* Half of sine wave, pi/2 to 1.5 * pi
@@ -21,7 +23,6 @@
#include <math.h>
#include <string.h>
-#include "sox_i.h"
/* Private data for fade file */
typedef struct fadestuff
@@ -118,7 +119,7 @@
/* converting time values to samples */
fade->in_start = 0;
- if (sox_parsesamples(effp->ininfo.rate, fade->in_stop_str,
+ if (sox_parsesamples(effp->in_signal.rate, fade->in_stop_str,
&fade->in_stop, 't') == NULL)
return sox_usage(effp);
@@ -127,7 +128,7 @@
if (fade->out_stop_str)
{
fade->do_out = 1;
- if (sox_parsesamples(effp->ininfo.rate, fade->out_stop_str,
+ if (sox_parsesamples(effp->in_signal.rate, fade->out_stop_str,
&fade->out_stop, 't') == NULL)
return sox_usage(effp);
@@ -134,7 +135,7 @@
/* See if user wants to fade out. */
if (fade->out_start_str)
{
- if (sox_parsesamples(effp->ininfo.rate, fade->out_start_str,
+ if (sox_parsesamples(effp->in_signal.rate, fade->out_start_str,
&fade->out_start, 't') == NULL)
return sox_usage(effp);
/* Fade time is relative to stop time. */
@@ -238,7 +239,7 @@
/* Process next channel */
chcnt++;
- if (chcnt >= effp->ininfo.channels)
+ if (chcnt >= effp->in_signal.channels)
{ /* all channels of this sample processed */
chcnt = 0;
fade->samplesdone += 1;
@@ -281,7 +282,7 @@
*osamp += 1;
t_chan++;
- if (t_chan >= effp->ininfo.channels)
+ if (t_chan >= effp->in_signal.channels)
{
fade->samplesdone += 1;
t_chan = 0;
--- a/src/ffmpeg.c
+++ b/src/ffmpeg.c
@@ -153,7 +153,7 @@
ffmpeg_t ffmpeg = (ffmpeg_t)ft->priv;
AVFormatParameters params;
int ret;
- unsigned i;
+ int i;
ffmpeg->audio_buf = xcalloc(1, AVCODEC_MAX_AUDIO_FRAME_SIZE);
@@ -198,8 +198,8 @@
/* Copy format info */
ft->signal.rate = ffmpeg->audio_st->codec->sample_rate;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
ft->signal.channels = ffmpeg->audio_st->codec->channels;
ft->length = 0; /* Currently we can't seek; no idea how to get this
info from ffmpeg anyway (in time, yes, but not in
@@ -212,7 +212,7 @@
* Read up to len samples of type sox_sample_t from file into buf[].
* Return number of samples read.
*/
-static sox_size_t read(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
ffmpeg_t ffmpeg = (ffmpeg_t)ft->priv;
AVPacket *pkt = &ffmpeg->audio_pkt;
@@ -397,7 +397,7 @@
* Write up to len samples of type sox_sample_t from buf[] into file.
* Return number of samples written.
*/
-static sox_size_t write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
ffmpeg_t ffmpeg = (ffmpeg_t)ft->priv;
sox_size_t nread = 0, nwritten = 0;
@@ -443,7 +443,7 @@
static int stopwrite(sox_format_t * ft)
{
ffmpeg_t ffmpeg = (ffmpeg_t)ft->priv;
- unsigned i;
+ int i;
/* Close CODEC */
if (ffmpeg->audio_st) {
@@ -472,35 +472,29 @@
return SOX_SUCCESS;
}
+SOX_FORMAT_HANDLER(ffmpeg)
+{
+ /* Format file suffixes */
+ /* For now, comment out formats built in to SoX */
+ static char const * const names[] = {
+ "ffmpeg", /* special type to force use of ffmpeg */
+ "mp4",
+ "m4a",
+ "avi",
+ "wmv",
+ "mpg",
+ NULL
+ };
-/* Format file suffixes */
-/* For now, comment out formats built in to SoX */
-static const char *names[] = {
- "ffmpeg", /* special type to force use of ffmpeg */
- "mp4",
- "m4a",
- "avi",
- "wmv",
- "mpg",
- NULL
-};
+ static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 16, 0, 0};
-/* Format descriptor */
-static sox_format_handler_t sox_ffmpeg_format = {
- names,
- SOX_FILE_NOSTDIO,
- startread,
- read,
- stopread,
- startwrite,
- write,
- stopwrite,
- NULL
-};
+ static sox_format_handler_t handler = {
+ names,
+ SOX_FILE_NOSTDIO,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
-const sox_format_handler_t *sox_ffmpeg_format_fn(void);
-
-const sox_format_handler_t *sox_ffmpeg_format_fn(void)
-{
- return &sox_ffmpeg_format;
+ return &handler;
}
--- a/src/filter.c
+++ b/src/filter.c
@@ -21,12 +21,12 @@
*
*/
+#include "sox_i.h"
+
#include <math.h>
#include <string.h>
#include <stdlib.h>
-#include "sox_i.h"
-
#define ISCALE 0x10000
#define BUFFSIZE 8192
@@ -100,7 +100,7 @@
long Xh0, Xh1, Xh;
int i;
- f->rate = effp->ininfo.rate;
+ f->rate = effp->in_signal.rate;
/* adjust upper frequency to Nyquist if necessary */
if (f->freq1 > (sox_sample_t)f->rate/2 || f->freq1 <= 0)
--- a/src/flac.c
+++ b/src/flac.c
@@ -179,9 +179,9 @@
return SOX_EOF;
}
- ft->signal.encoding = SOX_ENCODING_FLAC;
+ ft->encoding.encoding = SOX_ENCODING_FLAC;
ft->signal.rate = decoder->sample_rate;
- ft->signal.size = decoder->bits_per_sample >> 3;
+ ft->encoding.bits_per_sample = decoder->bits_per_sample;
ft->signal.channels = decoder->channels;
ft->length = decoder->total_samples * decoder->channels;
return SOX_SUCCESS;
@@ -188,7 +188,7 @@
}
-static sox_size_t read(sox_format_t * const ft, sox_sample_t * sampleBuffer, sox_size_t const requested)
+static sox_size_t read_samples(sox_format_t * const ft, sox_sample_t * sampleBuffer, sox_size_t const requested)
{
Decoder * decoder = (Decoder *) ft->priv;
size_t actual = 0;
@@ -305,9 +305,9 @@
FLAC__StreamEncoderState status;
unsigned compression_level = MAX_COMPRESSION; /* Default to "best" */
- if (ft->signal.compression != HUGE_VAL) {
- compression_level = ft->signal.compression;
- if (compression_level != ft->signal.compression ||
+ if (ft->encoding.compression != HUGE_VAL) {
+ compression_level = ft->encoding.compression;
+ if (compression_level != ft->encoding.compression ||
compression_level > MAX_COMPRESSION) {
sox_fail_errno(ft, SOX_EINVAL,
"FLAC compression level must be a whole number from 0 to %i",
@@ -324,13 +324,8 @@
}
encoder->decoded_samples = xmalloc(sox_globals.bufsiz * sizeof(FLAC__int32));
- /* FIXME: FLAC should not need to know about this oddity */
- if (ft->signal.encoding < SOX_ENCODING_SIZE_IS_WORD)
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_FLAC;
+ encoder->bits_per_sample = ft->encoding.bits_per_sample;
- encoder->bits_per_sample = (ft->signal.size > 4 ? 4 : ft->signal.size) << 3;
-
sox_report("encoding at %i bits per sample", encoder->bits_per_sample);
FLAC__stream_encoder_set_channels(encoder->flac, ft->signal.channels);
@@ -455,7 +450,7 @@
-static sox_size_t write(sox_format_t * const ft, sox_sample_t const * const sampleBuffer, sox_size_t const len)
+static sox_size_t write_samples(sox_format_t * const ft, sox_sample_t const * const sampleBuffer, sox_size_t const len)
{
Encoder * encoder = (Encoder *) ft->priv;
unsigned i;
@@ -519,16 +514,15 @@
}
-const sox_format_handler_t *sox_flac_format_fn(void);
-
-const sox_format_handler_t *sox_flac_format_fn(void)
+SOX_FORMAT_HANDLER(flac)
{
static char const * const names[] = {"flac", NULL};
- static sox_format_handler_t handler = {
+ static unsigned const encodings[] = {SOX_ENCODING_FLAC, 8, 16, 24, 0, 0};
+ static sox_format_handler_t const handler = {
names, 0,
- start_read, read, stop_read,
- start_write, write, stop_write,
- seek
+ start_read, read_samples, stop_read,
+ start_write, write_samples, stop_write,
+ seek, encodings, NULL
};
return &handler;
}
--- a/src/flanger.c
+++ b/src/flanger.c
@@ -153,7 +153,7 @@
static int sox_flanger_start(sox_effect_t * effp)
{
flanger_t f = (flanger_t) effp->priv;
- int c, channels = effp->ininfo.channels;
+ int c, channels = effp->in_signal.channels;
if (channels > MAX_CHANNELS) {
sox_fail("Can not operate with more than %i channels", MAX_CHANNELS);
@@ -177,7 +177,7 @@
/* Create the delay buffers, one for each channel: */
f->delay_buf_length =
- (f->delay_min + f->delay_depth) / 1000 * effp->ininfo.rate + 0.5;
+ (f->delay_min + f->delay_depth) / 1000 * effp->in_signal.rate + 0.5;
++f->delay_buf_length; /* Need 0 to n, i.e. n + 1. */
++f->delay_buf_length; /* Quadratic interpolator needs one more. */
for (c = 0; c < channels; ++c)
@@ -184,7 +184,7 @@
f->delay_bufs[c] = xcalloc(f->delay_buf_length, sizeof(*f->delay_bufs[0]));
/* Create the LFO lookup table: */
- f->lfo_length = effp->ininfo.rate / f->speed;
+ f->lfo_length = effp->in_signal.rate / f->speed;
f->lfo = xcalloc(f->lfo_length, sizeof(*f->lfo));
sox_generate_wave_table(
f->wave_shape,
@@ -191,7 +191,7 @@
SOX_FLOAT,
f->lfo,
f->lfo_length,
- (double)(sox_size_t)(f->delay_min / 1000 * effp->ininfo.rate + .5),
+ (double)(sox_size_t)(f->delay_min / 1000 * effp->in_signal.rate + .5),
(double)(f->delay_buf_length - 2),
3 * M_PI_2); /* Start the sweep at minimum delay (for mono at least) */
@@ -207,7 +207,7 @@
sox_sample_t * obuf, sox_size_t * isamp, sox_size_t * osamp)
{
flanger_t f = (flanger_t) effp->priv;
- int c, channels = effp->ininfo.channels;
+ int c, channels = effp->in_signal.channels;
sox_size_t len = (*isamp > *osamp ? *osamp : *isamp) / channels;
*isamp = *osamp = len * channels;
@@ -261,7 +261,7 @@
static int sox_flanger_stop(sox_effect_t * effp)
{
flanger_t f = (flanger_t) effp->priv;
- int c, channels = effp->ininfo.channels;
+ int c, channels = effp->in_signal.channels;
for (c = 0; c < channels; ++c)
free(f->delay_bufs[c]);
--- a/src/formats.h
+++ b/src/formats.h
@@ -12,6 +12,7 @@
FORMAT(dvms)
FORMAT(gsm)
FORMAT(hcom)
+ FORMAT(htk)
FORMAT(ima)
FORMAT(la)
FORMAT(lpc10)
--- a/src/gsm.c
+++ b/src/gsm.c
@@ -58,8 +58,7 @@
struct gsmpriv *p = (struct gsmpriv *) ft->priv;
unsigned ch;
- ft->signal.encoding = SOX_ENCODING_GSM;
- ft->signal.size = SOX_SIZE_BYTE;
+ ft->encoding.encoding = SOX_ENCODING_GSM;
if (!ft->signal.rate)
ft->signal.rate = 8000;
@@ -235,27 +234,15 @@
return sox_gsmstopread(ft); /* destroy handles and free buffers */
}
-/* GSM 06.10 */
-static const char *gsmnames[] = {
- "gsm",
- NULL
-};
-
-static sox_format_handler_t sox_gsm_format = {
- gsmnames,
- 0,
- sox_gsmstartread,
- sox_gsmread,
- sox_gsmstopread,
- sox_gsmstartwrite,
- sox_gsmwrite,
- sox_gsmstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_gsm_format_fn(void);
-
-const sox_format_handler_t *sox_gsm_format_fn(void)
+SOX_FORMAT_HANDLER(gsm)
{
- return &sox_gsm_format;
+ static char const * const names[] = {"gsm", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_GSM, 0, 0};
+ static sox_format_handler_t handler = {
+ names, 0,
+ sox_gsmstartread, sox_gsmread, sox_gsmstopread,
+ sox_gsmstartwrite, sox_gsmwrite, sox_gsmstopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/hcom.c
+++ b/src/hcom.c
@@ -2,7 +2,7 @@
* libSoX Macintosh HCOM format.
* These are really FSSD type files with Huffman compression,
* in MacBinary format.
- * To do: make the MacBinary format optional (so that .data files
+ * TODO: make the MacBinary format optional (so that .data files
* are also acceptable). (How to do this on output?)
*
* September 25, 1991
@@ -54,7 +54,7 @@
int32_t curword;
};
-static int sox_hcomstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
struct readpriv *p = (struct readpriv *) ft->priv;
int i;
@@ -116,8 +116,8 @@
sox_readw(ft, &dictsize);
/* Translate to sox parameters */
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- ft->signal.size = SOX_SIZE_BYTE;
+ ft->encoding.encoding = SOX_ENCODING_HCOM;
+ ft->encoding.bits_per_sample = 8;
ft->signal.rate = 22050 / divisor;
ft->signal.channels = 1;
@@ -149,7 +149,7 @@
return (SOX_SUCCESS);
}
-static sox_size_t sox_hcomread(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
register struct readpriv *p = (struct readpriv *) ft->priv;
int done = 0;
@@ -213,7 +213,7 @@
return done;
}
-static int sox_hcomstopread(sox_format_t * ft)
+static int stopread(sox_format_t * ft)
{
register struct readpriv *p = (struct readpriv *) ft->priv;
@@ -240,31 +240,17 @@
#define BUFINCR (10*BUFSIZ)
-static int sox_hcomstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
- register struct writepriv *p = (struct writepriv *) ft->priv;
+ struct writepriv * p = (struct writepriv *) ft->priv;
- switch ((int)ft->signal.rate) {
- case 22050:
- case 22050/2:
- case 22050/3:
- case 22050/4:
- break;
- default:
- sox_fail_errno(ft,SOX_EFMT,"unacceptable output rate for HCOM: try 5512, 7350, 11025 or 22050 hertz");
- return (SOX_EOF);
- }
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- ft->signal.channels = 1;
-
- p->size = BUFINCR;
- p->pos = 0;
- p->data = (unsigned char *) xmalloc(p->size);
- return (SOX_SUCCESS);
+ p->size = BUFINCR;
+ p->pos = 0;
+ p->data = xmalloc(p->size);
+ return SOX_SUCCESS;
}
-static sox_size_t sox_hcomwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
struct writepriv *p = (struct writepriv *) ft->priv;
sox_sample_t datum;
@@ -321,10 +307,10 @@
}
}
-static void compress(sox_format_t * ft, unsigned char **df, int32_t *dl, sox_rate_t fr)
+static void compress(sox_format_t * ft, unsigned char **df, int32_t *dl)
{
struct readpriv *p = (struct readpriv *) ft->priv;
- int32_t samplerate;
+ int samplerate;
unsigned char *datafork = *df;
unsigned char *ddf, *dfp;
short dictsize;
@@ -416,7 +402,7 @@
put32_be(&dfp, *dl);
put32_be(&dfp, p->new_checksum);
put32_be(&dfp, 1);
- samplerate = 22050 / fr;
+ samplerate = 22050 / ft->signal.rate + .5;
put32_be(&dfp, samplerate);
put16_be(&dfp, dictsize);
*df = datafork; /* reassign passed pointer to new datafork */
@@ -425,7 +411,7 @@
/* End of hcom utility routines */
-static int sox_hcomstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
struct writepriv *p = (struct writepriv *) ft->priv;
unsigned char *compressed_data = p->data;
@@ -434,7 +420,7 @@
/* Compress it all at once */
if (compressed_len)
- compress(ft, &compressed_data, (int32_t *)&compressed_len, ft->signal.rate);
+ compress(ft, &compressed_data, (int32_t *)&compressed_len);
free((char *)p->data);
/* Write the header */
@@ -462,27 +448,17 @@
return rc;
}
-/* Mac FSSD/HCOM */
-static const char *hcomnames[] = {
- "hcom",
- NULL
-};
-
-static sox_format_handler_t sox_hcom_format = {
- hcomnames,
- SOX_FILE_BIG_END,
- sox_hcomstartread,
- sox_hcomread,
- sox_hcomstopread,
- sox_hcomstartwrite,
- sox_hcomwrite,
- sox_hcomstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_hcom_format_fn(void);
-
-const sox_format_handler_t *sox_hcom_format_fn(void)
+SOX_FORMAT_HANDLER(hcom)
{
- return &sox_hcom_format;
+ static char const * const names[] = {"hcom", NULL};
+ static sox_rate_t const write_rates[] = {22050,22050/2,22050/3,22050/4, 0};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_HCOM, 8, 0, 0};
+ static sox_format_handler_t handler = {
+ names, SOX_FILE_BIG_END|SOX_FILE_MONO,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, write_rates
+ };
+ return &handler;
}
--- /dev/null
+++ b/src/htk.c
@@ -1,0 +1,74 @@
+/*
+ * File format: HTK (c) 2008 [email protected]
+ *
+ * See http://labrosa.ee.columbia.edu/doc/HTKBook21/HTKBook.html
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
+ */
+
+#include "sox_i.h"
+#include <math.h>
+
+typedef enum {
+ Waveform, Lpc, Lprefc, Lpcepstra, Lpdelcep, Irefc,
+ Mfcc, Fbank, Melspec, User, Discrete, Unknown} kind_t;
+static char const * const str[] = {
+ "Sampled waveform", "Linear prediction filter", "Linear prediction",
+ "LPC cepstral", "LPC cepstra plus delta", "LPC reflection coef in",
+ "Mel-frequency cepstral", "Log mel-filter bank", "Linear mel-filter bank",
+ "User defined sample", "Vector quantised data", "Unknown"};
+
+static int start_read(sox_format_t * ft)
+{
+ uint32_t period_100ns, num_samples;
+ uint16_t bytes_per_sample, parmKind;
+
+ if (sox_readdw(ft, &num_samples ) ||
+ sox_readdw(ft, &period_100ns ) ||
+ sox_readw (ft, &bytes_per_sample) ||
+ sox_readw (ft, &parmKind )) return SOX_EOF;
+ if (parmKind != Waveform) {
+ int n = min(parmKind & 077, Unknown);
+ sox_fail_errno(ft, SOX_EFMT, "unsupported HTK type `%s' (0%o)", str[n], parmKind);
+ return SOX_EOF;
+ }
+ return sox_check_read_params(ft, 1, 1e7 / period_100ns,
+ SOX_ENCODING_SIGN2, (unsigned)bytes_per_sample << 3, (off_t)num_samples);
+}
+
+static int write_header(sox_format_t * ft)
+{
+ double period_100ns = 1e7 / ft->signal.rate;
+
+ if (!ft->olength && floor(period_100ns) != period_100ns)
+ sox_warn("rounding sample period %f (x 100ns) to nearest integer", period_100ns);
+ return sox_writedw(ft, ft->olength? ft->olength:ft->length)
+ || sox_writedw(ft, (uint32_t)(period_100ns + .5))
+ || sox_writew(ft, ft->encoding.bits_per_sample >> 3)
+ || sox_writew(ft, Waveform) ? SOX_EOF : SOX_SUCCESS;
+}
+
+SOX_FORMAT_HANDLER(htk)
+{
+ static char const * const names[] = {"htk", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 16, 0, 0};
+ static sox_format_handler_t handler = {
+ names, SOX_FILE_BIG_END | SOX_FILE_MONO | SOX_FILE_REWIND,
+ start_read, sox_rawread, NULL,
+ write_header, sox_rawwrite, NULL,
+ sox_rawseek, write_encodings, NULL
+ };
+ return &handler;
+}
--- a/src/ima-fmt.c
+++ b/src/ima-fmt.c
@@ -1,32 +1,33 @@
/*
- * SOX file format handler for Dialogic/Oki ADPCM VOX files.
+ * File format: raw IMA ADPCM (c) 2007-8 SoX contributors
*
- * Copyright 1991-2007 Tony Seebregts And Sundry Contributors
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
*
- * This source code is freely redistributable and may be used for any
- * purpose. This copyright notice must be maintained.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
*
- * Tony Seebregts And Sundry Contributors are not responsible for the
- * consequences of using this software.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "vox.h"
-const sox_format_handler_t *sox_ima_format_fn(void);
-
-const sox_format_handler_t *sox_ima_format_fn(void)
+SOX_FORMAT_HANDLER(ima)
{
- static char const * names[] = {"ima", NULL};
+ static char const * const names[] = {"ima", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_IMA_ADPCM, 4, 0, 0};
static sox_format_handler_t handler = {
- names, 0,
- sox_ima_start,
- sox_vox_read,
- sox_vox_stopread,
- sox_ima_start,
- sox_vox_write,
- sox_vox_stopwrite,
- NULL
+ names, SOX_FILE_MONO,
+ sox_ima_start, sox_vox_read, sox_vox_stopread,
+ sox_ima_start, sox_vox_write, sox_vox_stopwrite,
+ sox_rawseek, write_encodings, NULL
};
return &handler;
}
--- a/src/ima_rw.c
+++ b/src/ima_rw.c
@@ -19,12 +19,13 @@
*/
+#include "sox_i.h"
+#include "ima_rw.h"
+
#include <sys/types.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
-#include "sox_i.h"
-#include "ima_rw.h"
/*
*
* Lookup tables for IMA ADPCM format
--- a/src/la-fmt.c
+++ b/src/la-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX la raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(la, 8BIT, SOX_FILE_BIT_REV, ALAW)
+RAW_FORMAT(la, 8, SOX_FILE_BIT_REV, ALAW)
--- a/src/ladspa.c
+++ b/src/ladspa.c
@@ -198,8 +198,8 @@
unsigned long i;
/* Instantiate the plugin */
- sox_debug("rate for plugin is %g", effp->ininfo.rate);
- l_st->handle = l_st->desc->instantiate(l_st->desc, (unsigned long)effp->ininfo.rate);
+ sox_debug("rate for plugin is %g", effp->in_signal.rate);
+ l_st->handle = l_st->desc->instantiate(l_st->desc, (unsigned long)effp->in_signal.rate);
if (l_st->handle == NULL) {
sox_fail("could not instantiate plugin");
return SOX_EOF;
--- a/src/lpc10.c
+++ b/src/lpc10.c
@@ -127,10 +127,7 @@
return SOX_EOF;
}
lpc->samples = LPC10_SAMPLES_PER_FRAME;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
-
- return SOX_SUCCESS;
+ return sox_check_read_params(ft, 1, 8000., SOX_ENCODING_LPC10, 0, (off_t)0);
}
static int startwrite(sox_format_t * ft)
@@ -146,7 +143,7 @@
return SOX_SUCCESS;
}
-static sox_size_t read(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
lpcpriv_t lpc = (lpcpriv_t)ft->priv;
sox_size_t nread = 0;
@@ -170,7 +167,7 @@
return nread;
}
-static sox_size_t write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
lpcpriv_t lpc = (lpcpriv_t)ft->priv;
sox_size_t nwritten = 0;
@@ -211,28 +208,16 @@
return SOX_SUCCESS;
}
-/* LPC-10 */
-static const char *lpc10names[] = {
- "lpc",
- "lpc10",
- NULL
-};
-
-static sox_format_handler_t sox_lpc10_format = {
- lpc10names,
- 0,
- startread,
- read,
- stopread,
- startwrite,
- write,
- stopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_lpc10_format_fn(void);
-
-const sox_format_handler_t *sox_lpc10_format_fn(void)
+SOX_FORMAT_HANDLER(lpc10)
{
- return &sox_lpc10_format;
+ static char const * const names[] = {"lpc10", "lpc", NULL};
+ static sox_rate_t const write_rates[] = {8000, 0};
+ static unsigned const write_encodings[] = {SOX_ENCODING_LPC10, 0, 0};
+ static sox_format_handler_t handler = {
+ names, SOX_FILE_MONO,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, write_rates
+ };
+ return &handler;
}
--- a/src/lu-fmt.c
+++ b/src/lu-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX lu raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(lu, 8BIT, SOX_FILE_BIT_REV, ULAW)
+RAW_FORMAT(lu, 8, SOX_FILE_BIT_REV, ULAW)
--- a/src/maud.c
+++ b/src/maud.c
@@ -15,9 +15,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* For SEEK_* defines if not found in stdio */
-#endif
/* Private data for MAUD file */
struct maudstuff { /* max. 100 bytes!!!! */
@@ -33,7 +30,7 @@
* size and encoding of samples,
* mono/stereo/quad.
*/
-static int sox_maudstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
struct maudstuff * p = (struct maudstuff *) ft->priv;
@@ -136,20 +133,20 @@
sox_readdw(ft, &trash32);
if (bitpersam == 8 && chaninf == 0) {
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.bits_per_sample = 8;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
}
else if (bitpersam == 8 && chaninf == 2) {
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_ALAW;
+ ft->encoding.bits_per_sample = 8;
+ ft->encoding.encoding = SOX_ENCODING_ALAW;
}
else if (bitpersam == 8 && chaninf == 3) {
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.bits_per_sample = 8;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
else if (bitpersam == 16 && chaninf == 0) {
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
else
{
@@ -196,7 +193,7 @@
return(SOX_SUCCESS);
}
-static int sox_maudstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
struct maudstuff * p = (struct maudstuff *) ft->priv;
int rc;
@@ -212,18 +209,6 @@
sox_fail_errno(ft,SOX_EOF,"Output .maud file must be a file, not a pipe");
return (SOX_EOF);
}
-
- if (ft->signal.channels != 1 && ft->signal.channels != 2) {
- sox_fail_errno(ft,SOX_EFMT,"MAUD: unsupported number of channels, unable to store");
- return(SOX_EOF);
- }
- if (ft->signal.size == SOX_SIZE_16BIT) ft->signal.encoding = SOX_ENCODING_SIGN2;
- if (ft->signal.encoding == SOX_ENCODING_ULAW ||
- ft->signal.encoding == SOX_ENCODING_ALAW) ft->signal.size = SOX_SIZE_BYTE;
- if (ft->signal.size == SOX_SIZE_BYTE &&
- ft->signal.encoding == SOX_ENCODING_SIGN2)
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
-
p->nsamples = 0x7f000000;
maudwriteheader(ft);
p->nsamples = 0;
@@ -230,7 +215,7 @@
return (SOX_SUCCESS);
}
-static sox_size_t sox_maudwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
struct maudstuff * p = (struct maudstuff *) ft->priv;
@@ -239,7 +224,7 @@
return sox_rawwrite(ft, buf, len);
}
-static int sox_maudstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
/* All samples are already written out. */
@@ -259,7 +244,7 @@
struct maudstuff * p = (struct maudstuff *) ft->priv;
sox_writes(ft, "FORM");
- sox_writedw(ft, (p->nsamples*ft->signal.size) + MAUDHEADERSIZE); /* size of file */
+ sox_writedw(ft, (p->nsamples* (ft->encoding.bits_per_sample >> 3)) + MAUDHEADERSIZE); /* size of file */
sox_writes(ft, "MAUD"); /* File type */
sox_writes(ft, "MHDR");
@@ -266,7 +251,7 @@
sox_writedw(ft, 8*4); /* number of bytes to follow */
sox_writedw(ft, p->nsamples); /* number of samples stored in MDAT */
- switch (ft->signal.encoding) {
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_UNSIGNED:
sox_writew(ft, 8); /* number of bits per sample as stored in MDAT */
@@ -300,7 +285,7 @@
sox_writew(ft, 2);
}
- switch (ft->signal.encoding) {
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_UNSIGNED:
case SOX_ENCODING_SIGN2:
@@ -328,30 +313,23 @@
sox_writes(ft, "file create by Sound eXchange ");
sox_writes(ft, "MDAT");
- sox_writedw(ft, p->nsamples * ft->signal.size ); /* samples in file */
+ sox_writedw(ft, p->nsamples * (ft->encoding.bits_per_sample >> 3)); /* samples in file */
}
-/* Amiga MAUD */
-static const char *maudnames[] = {
- "maud",
- NULL,
-};
-
-static sox_format_handler_t sox_maud_format = {
- maudnames,
- SOX_FILE_BIG_END,
- sox_maudstartread,
- sox_rawread,
- sox_rawstopread,
- sox_maudstartwrite,
- sox_maudwrite,
- sox_maudstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_maud_format_fn(void);
-
-const sox_format_handler_t *sox_maud_format_fn(void)
+SOX_FORMAT_HANDLER(maud)
{
- return &sox_maud_format;
+ static char const * const names[] = {"maud", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 0,
+ SOX_ENCODING_UNSIGNED, 8, 0,
+ SOX_ENCODING_ULAW, 8, 0,
+ SOX_ENCODING_ALAW, 8, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_BIG_END | SOX_FILE_MONO | SOX_FILE_STEREO,
+ startread, sox_rawread, sox_rawstopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/mcompand.c
+++ b/src/mcompand.c
@@ -14,6 +14,8 @@
* the consequences of using this software.
*/
+#include "sox_i.h"
+
#include <string.h>
#include <stdlib.h>
#include "compandt.h"
@@ -357,7 +359,7 @@
for (band=0;band<c->nBands;++band) {
l = &c->bands[band];
- l->delay_size = c->bands[band].delay * effp->outinfo.rate * effp->outinfo.channels;
+ l->delay_size = c->bands[band].delay * effp->out_signal.rate * effp->out_signal.channels;
if (l->delay_size > c->delay_buf_size)
c->delay_buf_size = l->delay_size;
}
@@ -367,14 +369,14 @@
/* Convert attack and decay rates using number of samples */
for (i = 0; i < l->expectedChannels; ++i) {
- if (l->attackRate[i] > 1.0/effp->outinfo.rate)
+ if (l->attackRate[i] > 1.0/effp->out_signal.rate)
l->attackRate[i] = 1.0 -
- exp(-1.0/(effp->outinfo.rate * l->attackRate[i]));
+ exp(-1.0/(effp->out_signal.rate * l->attackRate[i]));
else
l->attackRate[i] = 1.0;
- if (l->decayRate[i] > 1.0/effp->outinfo.rate)
+ if (l->decayRate[i] > 1.0/effp->out_signal.rate)
l->decayRate[i] = 1.0 -
- exp(-1.0/(effp->outinfo.rate * l->decayRate[i]));
+ exp(-1.0/(effp->out_signal.rate * l->decayRate[i]));
else
l->decayRate[i] = 1.0;
}
@@ -386,7 +388,7 @@
l->delay_buf_cnt = 0;
if (l->topfreq != 0)
- lowpass_setup(&l->filter, l->topfreq, effp->outinfo.rate, effp->outinfo.channels);
+ lowpass_setup(&l->filter, l->topfreq, effp->out_signal.rate, effp->out_signal.channels);
}
return (SOX_SUCCESS);
}
@@ -503,7 +505,7 @@
l = &c->bands[band];
if (l->topfreq)
- lowpass_flow(effp, &l->filter, effp->outinfo.channels, abuf, bbuf, cbuf, len);
+ lowpass_flow(effp, &l->filter, effp->out_signal.channels, abuf, bbuf, cbuf, len);
else {
bbuf = abuf;
abuf = cbuf;
@@ -510,7 +512,7 @@
}
if (abuf == ibuf_copy)
abuf = c->band_buf3;
- (void)sox_mcompand_flow_1(effp, c,l,bbuf,abuf,len,effp->outinfo.channels);
+ (void)sox_mcompand_flow_1(effp, c,l,bbuf,abuf,len,effp->out_signal.channels);
for (i=0;i<len;++i)
{
out = obuf[i] + abuf[i];
--- a/src/misc.c
+++ b/src/misc.c
@@ -29,56 +29,119 @@
#include <byteswap.h>
#endif
-const char * const sox_sizes_str[] = {
- "NONSENSE!",
- "1 byte",
- "2 bytes",
- "3 bytes",
- "4 bytes",
- "NONSENSE",
- "NONSENSE",
- "NONSENSE",
- "8 bytes"
+const char * const sox_encodings_str[] = {
+ "?",
+ "Signed Integer PCM",
+ "Unsigned Integer PCM",
+ "Floating Point PCM",
+ "Floating Point (text) PCM",
+ "FLAC",
+ "HCOM",
+ "", /* Lossless above, lossy below */
+ "u-law",
+ "A-law",
+ "G.721 ADPCM",
+ "G.723 ADPCM",
+ "MS ADPCM",
+ "IMA ADPCM",
+ "OKI ADPCM",
+ "GSM",
+ "MPEG audio (layer I, II or III)",
+ "Vorbis",
+ "AMR-WB",
+ "AMR-NB",
+ "CVSD",
+ "LPC10",
};
-const char * const sox_size_bits_str[] = {
- "NONSENSE!",
- "8-bit",
- "16-bit",
- "24-bit",
- "32-bit",
- "NONSENSE",
- "NONSENSE",
- "NONSENSE",
- "64-bit"
-};
+assert_static(array_length(sox_encodings_str) == SOX_ENCODINGS,
+ SIZE_MISMATCH_BETWEEN_sox_encodings_t_AND_sox_encodings_str);
-const char * const sox_encodings_str[] = {
- "NONSENSE!",
+void sox_init_encodinginfo(sox_encodinginfo_t * e)
+{
+ e->reverse_bytes = SOX_OPTION_DEFAULT;
+ e->reverse_nibbles = SOX_OPTION_DEFAULT;
+ e->reverse_bits = SOX_OPTION_DEFAULT;
+ e->compression = HUGE_VAL;
+}
- "u-law",
- "A-law",
- "G72x-ADPCM",
- "MS-ADPCM",
- "IMA-ADPCM",
- "OKI-ADPCM",
+unsigned sox_precision(sox_encoding_t encoding, unsigned bits_per_sample)
+{
+ switch (encoding) {
+ case SOX_ENCODING_HCOM: return !(bits_per_sample & 7) && (bits_per_sample >> 3) - 1 < 1? bits_per_sample: 0;
+ case SOX_ENCODING_FLAC: return !(bits_per_sample & 7) && (bits_per_sample >> 3) - 1 < 3? bits_per_sample: 0;
+ case SOX_ENCODING_SIGN2:
+ case SOX_ENCODING_UNSIGNED: return !(bits_per_sample & 7) && (bits_per_sample >> 3) - 1 < 4? bits_per_sample: 0;
- "", /* FIXME, see sox.h */
+ case SOX_ENCODING_ALAW: return bits_per_sample == 8? 13: 0;
+ case SOX_ENCODING_ULAW: return bits_per_sample == 8? 14: 0;
- "unsigned",
- "signed (2's complement)",
- "floating point",
- "GSM",
- "MPEG audio (layer I, II or III)",
- "Vorbis",
- "FLAC",
- "AMR-WB",
- "AMR-NB",
-};
+ case SOX_ENCODING_MS_ADPCM: return bits_per_sample == 4? 14: 0;
+ case SOX_ENCODING_IMA_ADPCM: return bits_per_sample == 4? 13: 0;
+ case SOX_ENCODING_OKI_ADPCM: return bits_per_sample == 4? 12: 0;
+ case SOX_ENCODING_G721: return bits_per_sample == 4? 12: 0;
+ case SOX_ENCODING_G723: return bits_per_sample == 3? 8:
+ bits_per_sample == 5? 14: 0;
+ case SOX_ENCODING_CVSD: return bits_per_sample == 1? 16: 0;
-assert_static(array_length(sox_encodings_str) == SOX_ENCODINGS,
- SIZE_MISMATCH_BETWEEN_sox_encodings_t_AND_sox_encodings_str);
+ case SOX_ENCODING_GSM:
+ case SOX_ENCODING_MP3:
+ case SOX_ENCODING_VORBIS:
+ case SOX_ENCODING_AMR_WB:
+ case SOX_ENCODING_AMR_NB:
+ case SOX_ENCODING_LPC10: return !bits_per_sample? 16: 0;
+ case SOX_ENCODING_FLOAT: return bits_per_sample == 32 ? 24: bits_per_sample == 64 ? 53: 0;
+ case SOX_ENCODING_FLOAT_TEXT: return !bits_per_sample? 53: 0;
+
+ case SOX_ENCODINGS:
+ case SOX_ENCODING_LOSSLESS:
+ case SOX_ENCODING_UNKNOWN: break;
+ }
+ return 0;
+}
+
+int sox_check_read_params(sox_format_t * ft, unsigned channels,
+ sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample, off_t length)
+{
+ ft->length = length;
+
+ if (ft->seekable)
+ ft->data_start = sox_tell(ft);
+
+ if (channels && ft->signal.channels && ft->signal.channels != channels)
+ sox_warn("'%s': overriding number of channels", ft->filename);
+ else ft->signal.channels = channels;
+
+ if (rate && ft->signal.rate && ft->signal.rate != rate)
+ sox_warn("'%s': overriding sample rate", ft->filename);
+ else ft->signal.rate = rate;
+
+ if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding)
+ sox_warn("'%s': overriding encoding type", ft->filename);
+ else ft->encoding.encoding = encoding;
+
+ if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample)
+ sox_warn("'%s': overriding encoding size", ft->filename);
+ ft->encoding.bits_per_sample = bits_per_sample;
+
+ if (!ft->length && ft->encoding.bits_per_sample && sox_filelength(ft))
+ ft->length = div_bits(sox_filelength(ft) - ft->data_start, ft->encoding.bits_per_sample);
+
+ if ( sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
+ return SOX_SUCCESS;
+ sox_fail_errno(ft, EINVAL, "invalid format for this file type");
+ return SOX_EOF;
+}
+
+sox_sample_t sox_sample_max(sox_encodinginfo_t const * encoding)
+{
+ unsigned precision = encoding->encoding == SOX_ENCODING_FLOAT?
+ SOX_SAMPLE_PRECISION : sox_precision(encoding->encoding, encoding->bits_per_sample);
+ unsigned shift = SOX_SAMPLE_PRECISION - min(precision, SOX_SAMPLE_PRECISION);
+ return (SOX_SAMPLE_MAX >> shift) << shift;
+}
+
const char sox_readerr[] = "Premature EOF while reading sample file.";
const char sox_writerr[] = "Error writing sample file. You are probably out of disk space.";
@@ -154,10 +217,9 @@
sox_size_t sox_filelength(sox_format_t * ft)
{
struct stat st;
+ int ret = fstat(fileno(ft->fp), &st);
- fstat(fileno(ft->fp), &st);
-
- return (sox_size_t)st.st_size;
+ return ret? 0 : (sox_size_t)st.st_size;
}
int sox_flush(sox_format_t * ft)
@@ -500,6 +562,14 @@
ft->sox_errno = SOX_SUCCESS;
}
return ft->sox_errno;
+}
+
+int sox_offset_seek(sox_format_t * ft, off_t byte_offset, sox_size_t to_sample)
+{
+ double wide_sample = to_sample - (to_sample % ft->signal.channels);
+ double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
+ off_t to = to_d;
+ return (to != to_d)? SOX_EOF : sox_seeki(ft, byte_offset + to, SEEK_SET);
}
enum_item const * find_enum_text(char const * text, enum_item const * enum_items)
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -167,8 +167,8 @@
for (i = 0; i < 16; i++)
pans[i] = ((double*)&mixer->sources[0][0])[i];
- ichan = effp->ininfo.channels;
- ochan = effp->outinfo.channels;
+ ichan = effp->in_signal.channels;
+ ochan = effp->out_signal.channels;
if (ochan == -1) {
sox_fail("Output must have known number of channels");
return(SOX_EOF);
@@ -485,11 +485,11 @@
}
}
- if (effp->ininfo.channels != effp->outinfo.channels)
+ if (effp->in_signal.channels != effp->out_signal.channels)
return SOX_SUCCESS;
- for (i = 0; i < (int)effp->ininfo.channels; ++i)
- for (j = 0; j < (int)effp->outinfo.channels; ++j)
+ for (i = 0; i < (int)effp->in_signal.channels; ++i)
+ for (j = 0; j < (int)effp->out_signal.channels; ++j)
if (mixer->sources[i][j] != (i == j))
return SOX_SUCCESS;
@@ -509,8 +509,8 @@
int i, j;
double samp;
- ichan = effp->ininfo.channels;
- ochan = effp->outinfo.channels;
+ ichan = effp->in_signal.channels;
+ ochan = effp->out_signal.channels;
len = *isamp / ichan;
if (len > *osamp / ochan)
len = *osamp / ochan;
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -158,7 +158,7 @@
return rc;
}
-static int sox_mp3startread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
struct mp3priv *p = (struct mp3priv *) ft->priv;
size_t ReadSize;
@@ -183,8 +183,7 @@
mad_synth_init(p->Synth);
mad_timer_reset(p->Timer);
- ft->signal.encoding = SOX_ENCODING_MP3;
- ft->signal.size = SOX_SIZE_16BIT;
+ ft->encoding.encoding = SOX_ENCODING_MP3;
/* Decode at least one valid frame to find out the input
* format. The decoded frame will be saved off so that it
@@ -330,7 +329,7 @@
return done;
}
-static int sox_mp3stopread(sox_format_t * ft)
+static int stopread(sox_format_t * ft)
{
struct mp3priv *p=(struct mp3priv*) ft->priv;
@@ -347,13 +346,13 @@
return SOX_SUCCESS;
}
#else /*HAVE_MAD_H*/
-static int sox_mp3startread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
sox_fail_errno(ft,SOX_EOF,"SoX was compiled without MP3 decoding support");
return SOX_EOF;
}
#define sox_mp3read NULL
-#define sox_mp3stopread NULL
+#define stopread NULL
#endif /*HAVE_MAD_H*/
#ifdef HAVE_LAME_LAME_H
@@ -362,14 +361,14 @@
return;
}
-static int sox_mp3startwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
struct mp3priv *p = (struct mp3priv *) ft->priv;
- if (ft->signal.encoding != SOX_ENCODING_MP3) {
- if(ft->signal.encoding != SOX_ENCODING_UNKNOWN)
+ if (ft->encoding.encoding != SOX_ENCODING_MP3) {
+ if(ft->encoding.encoding != SOX_ENCODING_UNKNOWN)
sox_report("Encoding forced to MP3");
- ft->signal.encoding = SOX_ENCODING_MP3;
+ ft->encoding.encoding = SOX_ENCODING_MP3;
}
p->gfp = lame_init();
@@ -397,7 +396,7 @@
/* FIXME: Someone who knows about lame could implement adjustable compression
here. E.g. by using the -C value as an index into a table of params or
as a compressed bit-rate. */
- if (ft->signal.compression != HUGE_VAL)
+ if (ft->encoding.compression != HUGE_VAL)
sox_warn("-C option not supported for mp3; using default compression rate");
if (lame_init_params(p->gfp) < 0){
sox_fail_errno(ft,SOX_EOF,"LAME initialization failed");
@@ -501,7 +500,7 @@
return done;
}
-static int sox_mp3stopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
struct mp3priv *p = (struct mp3priv *) ft->priv;
char mp3buffer[7200];
@@ -508,7 +507,7 @@
int written;
size_t written2;
- if ( (written=lame_encode_flush(p->gfp, (unsigned char *)mp3buffer, 7200)) <0){
+ if ((written=lame_encode_flush(p->gfp, (unsigned char *)mp3buffer, 7200)) <0){
sox_fail_errno(ft,SOX_EOF,"Encoding failed");
}
else if (sox_writebuf(ft, mp3buffer, written2 = written) < written2){
@@ -520,37 +519,25 @@
}
#else /* HAVE_LAME_LAME_H */
-static int sox_mp3startwrite(sox_format_t * ft UNUSED)
+static int startwrite(sox_format_t * ft UNUSED)
{
sox_fail_errno(ft,SOX_EOF,"SoX was compiled without MP3 encoding support");
return SOX_EOF;
}
#define sox_mp3write NULL
-#define sox_mp3stopwrite NULL
+#define stopwrite NULL
#endif /* HAVE_LAME_LAME_H */
-/* MP3 */
-static const char *mp3names[] = {
- "mp3",
- "mp2",
- NULL,
-};
-
-static sox_format_handler_t sox_mp3_format = {
- mp3names,
- 0,
- sox_mp3startread,
- sox_mp3read,
- sox_mp3stopread,
- sox_mp3startwrite,
- sox_mp3write,
- sox_mp3stopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_mp3_format_fn(void);
-
-const sox_format_handler_t *sox_mp3_format_fn(void)
+SOX_FORMAT_HANDLER(mp3)
{
- return &sox_mp3_format;
+ static char const * const names[] = {"mp3", "mp2", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_GSM, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, 0,
+ startread, sox_mp3read, stopread,
+ startwrite, sox_mp3write, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/noiseprof.c
+++ b/src/noiseprof.c
@@ -56,7 +56,7 @@
static int sox_noiseprof_start(sox_effect_t * effp)
{
profdata_t data = (profdata_t) effp->priv;
- unsigned channels = effp->ininfo.channels;
+ unsigned channels = effp->in_signal.channels;
unsigned i;
/* Note: don't fall back to stderr if stdout is unavailable
@@ -111,13 +111,13 @@
{
profdata_t data = (profdata_t) effp->priv;
sox_size_t samp = min(*isamp, *osamp);
- sox_size_t tracks = effp->ininfo.channels;
+ sox_size_t tracks = effp->in_signal.channels;
sox_size_t track_samples = samp / tracks;
int ncopy = 0;
sox_size_t i;
/* FIXME: Make this automatic for all effects */
- assert(effp->ininfo.channels == effp->outinfo.channels);
+ assert(effp->in_signal.channels == effp->out_signal.channels);
/* How many samples per track to analyze? */
ncopy = min(track_samples, WINDOWSIZE-data->bufdata);
@@ -152,7 +152,7 @@
static int sox_noiseprof_drain(sox_effect_t * effp, sox_sample_t *obuf UNUSED, sox_size_t *osamp)
{
profdata_t data = (profdata_t) effp->priv;
- int tracks = effp->ininfo.channels;
+ int tracks = effp->in_signal.channels;
int i;
*osamp = 0;
@@ -183,7 +183,7 @@
profdata_t data = (profdata_t) effp->priv;
sox_size_t i;
- for (i = 0; i < effp->ininfo.channels; i ++) {
+ for (i = 0; i < effp->in_signal.channels; i ++) {
int j;
chandata_t* chan = &(data->chandata[i]);
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -62,7 +62,7 @@
{
reddata_t data = (reddata_t) effp->priv;
sox_size_t fchannels = 0;
- sox_size_t channels = effp->ininfo.channels;
+ sox_size_t channels = effp->in_signal.channels;
sox_size_t i;
FILE* ifp;
@@ -243,7 +243,7 @@
{
reddata_t data = (reddata_t) effp->priv;
sox_size_t samp = min(*isamp, *osamp);
- sox_size_t tracks = effp->ininfo.channels;
+ sox_size_t tracks = effp->in_signal.channels;
sox_size_t track_samples = samp / tracks;
sox_size_t ncopy = min(track_samples, WINDOWSIZE-data->bufdata);
sox_size_t whole_window = (ncopy + data->bufdata == WINDOWSIZE);
@@ -251,7 +251,7 @@
sox_size_t i;
/* FIXME: Make this automatic for all effects */
- assert(effp->ininfo.channels == effp->outinfo.channels);
+ assert(effp->in_signal.channels == effp->out_signal.channels);
if (whole_window)
data->bufdata = WINDOWSIZE/2;
@@ -293,7 +293,7 @@
{
reddata_t data = (reddata_t)effp->priv;
unsigned i;
- unsigned tracks = effp->ininfo.channels;
+ unsigned tracks = effp->in_signal.channels;
for (i = 0; i < tracks; i ++)
*osamp = process_window(effp, data, i, tracks, obuf, data->bufdata);
@@ -311,7 +311,7 @@
reddata_t data = (reddata_t) effp->priv;
sox_size_t i;
- for (i = 0; i < effp->ininfo.channels; i ++) {
+ for (i = 0; i < effp->in_signal.channels; i ++) {
chandata_t* chan = &(data->chandata[i]);
free(chan->lastwindow);
free(chan->window);
--- a/src/normalise.c
+++ b/src/normalise.c
@@ -84,8 +84,7 @@
int result = SOX_SUCCESS;
if (!p->norm0) {
- int shift_for_max = (4 - min(effp->outinfo.size, 4)) << 3;
- double max = (SOX_SAMPLE_MAX >> shift_for_max) << shift_for_max;
+ double max = sox_sample_max(effp->out_encoding);
p->norm0 = p->level * min(max / p->max, (double)SOX_SAMPLE_MIN / p->min);
rewind(p->tmp_file);
}
--- a/src/nulfile.c
+++ b/src/nulfile.c
@@ -26,39 +26,34 @@
ft->signal.rate = SOX_DEFAULT_RATE;
sox_report("sample rate not specified; using %g", ft->signal.rate);
}
- if (!ft->signal.size) {
- ft->signal.size = SOX_DEFAULT_SIZE;
- sox_report("precision not specified; using %s", sox_size_bits_str[ft->signal.size]);
- }
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN) {
- ft->signal.encoding = SOX_DEFAULT_ENCODING;
- sox_report("encoding not specified; using %s", sox_encodings_str[ft->signal.encoding]);
- }
+ ft->signal.precision =
+ ft->encoding.bits_per_sample? ft->encoding.bits_per_sample: SOX_SAMPLE_PRECISION;
/* Default number of channels is application-dependent */
return SOX_SUCCESS;
}
-static sox_size_t read(sox_format_t * ft UNUSED, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t * buf, sox_size_t len)
{
/* Reading from null generates silence i.e. (sox_sample_t)0. */
+ (void)ft;
memset(buf, 0, sizeof(sox_sample_t) * len);
return len; /* Return number of samples "read". */
}
-static sox_size_t write(sox_format_t * ft UNUSED, const sox_sample_t *buf UNUSED, sox_size_t len)
+static sox_size_t write_samples(
+ sox_format_t * ft, sox_sample_t const * buf, sox_size_t len)
{
/* Writing to null just discards the samples */
+ (void)ft, (void)buf;
return len; /* Return number of samples "written". */
}
-const sox_format_handler_t *sox_nul_format_fn(void);
-
-const sox_format_handler_t *sox_nul_format_fn(void)
+SOX_FORMAT_HANDLER(nul)
{
- static const char *names[] = {"null", NULL};
- static sox_format_handler_t handler = {
+ static const char * const names[] = {"null", NULL};
+ static sox_format_handler_t const handler = {
names, SOX_FILE_DEVICE | SOX_FILE_PHONY | SOX_FILE_NOSTDIO,
- startread, read, 0, 0, write, 0, 0
+ startread, read_samples, NULL, NULL, write_samples, NULL, NULL, NULL, NULL
};
return &handler;
}
--- a/src/oss.c
+++ b/src/oss.c
@@ -49,41 +49,41 @@
sox_signalinfo_t client_signal = ft->signal;
set_signal_defaults(&ft->signal);
- if (ft->signal.size == SOX_SIZE_BYTE) {
+ if (ft->encoding.bits_per_sample == 8) {
sampletype = AFMT_U8;
samplesize = 8;
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- if (ft->signal.encoding != SOX_ENCODING_UNSIGNED) {
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
+ if (ft->encoding.encoding != SOX_ENCODING_UNSIGNED) {
sox_report("OSS driver only supports unsigned with bytes");
sox_report("Forcing to unsigned");
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT) {
+ else if (ft->encoding.bits_per_sample == 16) {
/* Attempt to use endian that user specified */
- if (ft->signal.reverse_bytes)
+ if (ft->encoding.reverse_bytes)
sampletype = (SOX_IS_BIGENDIAN) ? AFMT_S16_LE : AFMT_S16_BE;
else
sampletype = (SOX_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
samplesize = 16;
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- if (ft->signal.encoding != SOX_ENCODING_SIGN2) {
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
+ if (ft->encoding.encoding != SOX_ENCODING_SIGN2) {
sox_report("OSS driver only supports signed with words");
sox_report("Forcing to signed linear");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
}
else {
/* Attempt to use endian that user specified */
- if (ft->signal.reverse_bytes)
+ if (ft->encoding.reverse_bytes)
sampletype = (SOX_IS_BIGENDIAN) ? AFMT_S16_LE : AFMT_S16_BE;
else
sampletype = (SOX_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
samplesize = 16;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
sox_report("OSS driver only supports bytes and words");
sox_report("Forcing to signed linear word");
}
@@ -106,8 +106,8 @@
if (samplesize == 16 && (tmp & (AFMT_S16_LE|AFMT_S16_BE)) == 0)
{
/* Must not like 16-bits, try 8-bits */
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.bits_per_sample = 8;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
sox_report("OSS driver doesn't like signed words");
sox_report("Forcing to unsigned bytes");
tmp = sampletype = AFMT_U8;
@@ -116,8 +116,8 @@
/* is 8-bit supported */
else if (samplesize == 8 && (tmp & AFMT_U8) == 0)
{
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
sox_report("OSS driver doesn't like unsigned bytes");
sox_report("Forcing to signed words");
sampletype = (SOX_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
@@ -132,7 +132,7 @@
* it supports at least one of the two endians.
*/
sampletype = (sampletype == AFMT_S16_BE) ? AFMT_S16_LE : AFMT_S16_BE;
- ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
+ ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
}
}
@@ -159,7 +159,7 @@
if (tmp != dsp_stereo)
{
if (client_signal.channels != 0)
- sox_warn("Sound card appears to only support %d channels. Overriding format", tmp+1);
+ sox_warn("Sound card appears to support only %d channels. Overriding format", tmp+1);
ft->signal.channels = tmp + 1;
}
@@ -206,47 +206,18 @@
return(SOX_SUCCESS);
}
-/*
- * Do anything required before you start reading samples.
- * Read file header.
- * Find out sampling rate,
- * size and encoding of samples,
- * mono/stereo/quad.
- */
-static int sox_ossstartread(sox_format_t * ft)
+SOX_FORMAT_HANDLER(oss)
{
- int rc;
- rc = ossinit(ft);
- return rc;
-}
-
-static int sox_ossstartwrite(sox_format_t * ft)
-{
- return ossinit(ft);
-}
-
-/* OSS /dev/dsp player */
-static const char *ossnames[] = {
- "ossdsp",
- "oss",
- NULL
-};
-
-static sox_format_handler_t sox_oss_format = {
- ossnames,
- SOX_FILE_DEVICE,
- sox_ossstartread,
- sox_rawread,
- sox_rawstopread,
- sox_ossstartwrite,
- sox_rawwrite,
- sox_rawstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_oss_format_fn(void);
-
-const sox_format_handler_t *sox_oss_format_fn(void)
-{
- return &sox_oss_format;
+ static char const * const names[] = {"ossdsp", "oss", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 0,
+ SOX_ENCODING_UNSIGNED, 8, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_DEVICE,
+ ossinit, sox_rawread, sox_rawstopread,
+ ossinit, sox_rawwrite, sox_rawstopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/pad.c
+++ b/src/pad.c
@@ -72,7 +72,7 @@
pad_t p = (pad_t) effp->priv;
unsigned i;
- parse(effp, 0, effp->ininfo.rate); /* Re-parse now rate is known */
+ parse(effp, 0, effp->in_signal.rate); /* Re-parse now rate is known */
p->in_pos = p->pad_pos = p->pads_pos = 0;
for (i = 0; i < p->npads; ++i)
if (p->pads[i].pad)
@@ -85,18 +85,18 @@
{
pad_t p = (pad_t) effp->priv;
sox_size_t c, idone = 0, odone = 0;
- *isamp /= effp->ininfo.channels;
- *osamp /= effp->ininfo.channels;
+ *isamp /= effp->in_signal.channels;
+ *osamp /= effp->in_signal.channels;
do {
/* Copying: */
for (; idone < *isamp && odone < *osamp && !(p->pads_pos != p->npads && p->in_pos == p->pads[p->pads_pos].start); ++idone, ++odone, ++p->in_pos)
- for (c = 0; c < effp->ininfo.channels; ++c) *obuf++ = *ibuf++;
+ for (c = 0; c < effp->in_signal.channels; ++c) *obuf++ = *ibuf++;
/* Padding: */
if (p->pads_pos != p->npads && p->in_pos == p->pads[p->pads_pos].start) {
for (; odone < *osamp && p->pad_pos < p->pads[p->pads_pos].pad; ++odone, ++p->pad_pos)
- for (c = 0; c < effp->ininfo.channels; ++c) *obuf++ = 0;
+ for (c = 0; c < effp->in_signal.channels; ++c) *obuf++ = 0;
if (p->pad_pos == p->pads[p->pads_pos].pad) { /* Move to next pad? */
++p->pads_pos;
p->pad_pos = 0;
@@ -104,8 +104,8 @@
}
} while (idone < *isamp && odone < *osamp);
- *isamp = idone * effp->ininfo.channels;
- *osamp = odone * effp->ininfo.channels;
+ *isamp = idone * effp->in_signal.channels;
+ *osamp = odone * effp->in_signal.channels;
return SOX_SUCCESS;
}
--- a/src/pan.c
+++ b/src/pan.c
@@ -46,7 +46,7 @@
*/
static int sox_pan_start(sox_effect_t * effp)
{
- if (effp->outinfo.channels==1)
+ if (effp->out_signal.channels==1)
sox_warn("PAN onto a mono channel...");
return SOX_SUCCESS;
}
@@ -77,8 +77,8 @@
left = 0.5 - hdir; /* 0 <= left <= 1 */
right = 0.5 + hdir; /* 0 <= right <= 1 */
- ich = effp->ininfo.channels;
- och = effp->outinfo.channels;
+ ich = effp->in_signal.channels;
+ och = effp->out_signal.channels;
len = min(*osamp/och,*isamp/ich);
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -54,10 +54,11 @@
* libSoX phaser effect file.
*/
+#include "sox_i.h"
+
#include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
#include <math.h>
#include <string.h>
-#include "sox_i.h"
#define MOD_SINE 0
#define MOD_TRIANGLE 1
@@ -111,7 +112,7 @@
phaser_t phaser = (phaser_t) effp->priv;
unsigned int i;
- phaser->maxsamples = phaser->delay * effp->ininfo.rate / 1000.0;
+ phaser->maxsamples = phaser->delay * effp->in_signal.rate / 1000.0;
if ( phaser->delay < 0.0 )
{
@@ -149,7 +150,7 @@
if ( phaser->in_gain / ( 1.0 - phaser->decay ) > 1.0 / phaser->out_gain )
sox_warn("phaser: warning >>> gain-out can cause saturation or clipping of output <<<");
- phaser->length = effp->ininfo.rate / phaser->speed;
+ phaser->length = effp->in_signal.rate / phaser->speed;
phaser->phaserbuf = (double *) xmalloc(sizeof (double) * phaser->maxsamples);
for ( i = 0; i < phaser->maxsamples; i++ )
phaser->phaserbuf[i] = 0.0;
--- a/src/pitch.c
+++ b/src/pitch.c
@@ -319,7 +319,7 @@
static int sox_pitch_start(sox_effect_t * effp)
{
pitch_t pitch = (pitch_t) effp->priv;
- register int sample_rate = effp->outinfo.rate;
+ register int sample_rate = effp->out_signal.rate;
unsigned int i;
/* computer inner stuff... */
--- a/src/polyphas.c
+++ b/src/polyphas.c
@@ -23,11 +23,12 @@
*
*/
+#include "sox_i.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "sox_i.h"
#define Float float/*double*/
#define ISCALE 0x10000
@@ -348,13 +349,13 @@
int total, size, uprate;
int k;
- if (effp->ininfo.rate == effp->outinfo.rate)
+ if (effp->in_signal.rate == effp->out_signal.rate)
return SOX_EFF_NULL;
- effp->outinfo.channels = effp->ininfo.channels;
+ effp->out_signal.channels = effp->in_signal.channels;
- rate->lcmrate = sox_lcm((sox_sample_t)effp->ininfo.rate,
- (sox_sample_t)effp->outinfo.rate);
+ rate->lcmrate = sox_lcm((sox_sample_t)effp->in_signal.rate,
+ (sox_sample_t)effp->out_signal.rate);
/* Cursory check for LCM overflow.
* If both rates are below 65k, there should be no problem.
@@ -361,8 +362,8 @@
* 16 bits x 16 bits = 32 bits, which we can handle.
*/
- rate->inskip = rate->lcmrate / (sox_sample_t)effp->ininfo.rate;
- rate->outskip = rate->lcmrate / (sox_sample_t)effp->outinfo.rate;
+ rate->inskip = rate->lcmrate / (sox_sample_t)effp->in_signal.rate;
+ rate->outskip = rate->lcmrate / (sox_sample_t)effp->out_signal.rate;
rate->Factor = (double)rate->inskip / (double)rate->outskip;
rate->inpipe = 0;
{
@@ -377,12 +378,12 @@
/* l1 and l2 are now lists of the up/down factors for conversion */
sox_debug("Poly: input rate %g, output rate %g. %d stages.",
- effp->ininfo.rate, effp->outinfo.rate,total);
+ effp->in_signal.rate, effp->out_signal.rate,total);
sox_debug("Poly: window: %s size: %d cutoff: %f.",
(rate->win_type == 0) ? ("nut") : ("ham"), rate->win_width, rate->cutoff);
/* Create an array of filters and past history */
- uprate = effp->ininfo.rate;
+ uprate = effp->in_signal.rate;
for (k = 0; k < total; k++) {
int j, prod, f_cutoff, f_len;
polystage *s;
--- a/src/prc.c
+++ b/src/prc.c
@@ -63,7 +63,7 @@
uint32_t nsamp, nbytes;
short padding;
short repeats;
- sox_size_t data_start; /* for seeking */
+ off_t data_start; /* for seeking */
struct adpcm_io adpcm;
unsigned frame_samp; /* samples left to read in current frame */
} *prc_t;
@@ -72,22 +72,8 @@
static int seek(sox_format_t * ft, sox_size_t offset)
{
- prc_t prc = (prc_t)ft->priv;
- sox_size_t new_offset, channel_block, alignment;
-
- new_offset = offset * ft->signal.size;
- /* Make sure request aligns to a channel block (i.e. left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
- alignment = new_offset % channel_block;
- /* Most common mistake is to compute something like
- * "skip everthing up to and including this sample" so
- * advance to next sample block in this case.
- */
- if (alignment != 0)
- new_offset += (channel_block - alignment);
- new_offset += prc->data_start;
-
- return sox_seeki(ft, (sox_ssize_t)new_offset, SEEK_SET);
+ prc_t p = (prc_t)ft->priv;
+ return sox_offset_seek(ft, p->data_start, offset);
}
static int startread(sox_format_t * ft)
@@ -129,9 +115,9 @@
sox_readdw(ft, &encoding);
sox_debug("Encoding of samples: %x", encoding);
if (encoding == 0)
- ft->signal.encoding = SOX_ENCODING_ALAW;
+ ft->encoding.encoding = SOX_ENCODING_ALAW;
else if (encoding == 0x100001a1)
- ft->signal.encoding = SOX_ENCODING_IMA_ADPCM;
+ ft->encoding.encoding = SOX_ENCODING_IMA_ADPCM;
else {
sox_fail_errno(ft, SOX_EHDR, "Unrecognised encoding");
return SOX_EOF;
@@ -164,11 +150,11 @@
p->data_start = sox_tell(ft);
ft->length = p->nsamp / ft->signal.channels;
- if (ft->signal.encoding == SOX_ENCODING_ALAW) {
- ft->signal.size = SOX_SIZE_BYTE;
+ if (ft->encoding.encoding == SOX_ENCODING_ALAW) {
+ ft->encoding.bits_per_sample = 8;
if (sox_rawstartread(ft))
return SOX_EOF;
- } else if (ft->signal.encoding == SOX_ENCODING_IMA_ADPCM) {
+ } else if (ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM) {
p->frame_samp = 0;
if (sox_adpcm_ima_start(ft, &p->adpcm))
return SOX_EOF;
@@ -214,13 +200,13 @@
return a;
}
-static sox_size_t read(sox_format_t * ft, sox_sample_t *buf, sox_size_t samp)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t samp)
{
prc_t p = (prc_t)ft->priv;
sox_debug_more("length now = %d", p->nsamp);
- if (ft->signal.encoding == SOX_ENCODING_IMA_ADPCM) {
+ if (ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM) {
sox_size_t nsamp, read;
if (p->frame_samp == 0) {
@@ -240,7 +226,7 @@
sox_debug_more("list length %d", trash);
/* Reset CODEC for start of frame */
- sox_adpcm_reset(&p->adpcm, ft->signal.encoding);
+ sox_adpcm_reset(&p->adpcm, ft->encoding.encoding);
}
nsamp = min(p->frame_samp, samp);
p->nsamp += nsamp;
@@ -258,7 +244,7 @@
{
prc_t p = (prc_t)ft->priv;
- if (ft->signal.encoding == SOX_ENCODING_IMA_ADPCM)
+ if (ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM)
return sox_adpcm_stopread(ft, &p->adpcm);
else
return SOX_SUCCESS;
@@ -277,16 +263,10 @@
{
prc_t p = (prc_t)ft->priv;
- if (ft->signal.encoding != SOX_ENCODING_ALAW &&
- ft->signal.encoding != SOX_ENCODING_IMA_ADPCM) {
- sox_report("PRC only supports A-law and ADPCM encoding; choosing A-law");
- ft->signal.encoding = SOX_ENCODING_ALAW;
- }
-
- if (ft->signal.encoding == SOX_ENCODING_ALAW) {
+ if (ft->encoding.encoding == SOX_ENCODING_ALAW) {
if (sox_rawstartwrite(ft))
return SOX_EOF;
- } else if (ft->signal.encoding == SOX_ENCODING_IMA_ADPCM) {
+ } else if (ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM) {
if (sox_adpcm_ima_start(ft, &p->adpcm))
return SOX_EOF;
}
@@ -296,16 +276,6 @@
if (p->repeats == 0)
p->repeats = 1;
- if (ft->signal.rate != 0 && ft->signal.rate != 8000)
- sox_report("PRC only supports 8 kHz sample rate; overriding.");
- ft->signal.rate = 8000;
-
- if (ft->signal.channels != 1 && ft->signal.channels != 0)
- sox_report("PRC only supports 1 channel; overriding.");
- ft->signal.channels = 1;
-
- ft->signal.size = SOX_SIZE_BYTE;
-
prcwriteheader(ft);
p->data_start = sox_tell(ft);
@@ -344,7 +314,7 @@
}
}
-static sox_size_t write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t samp)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t samp)
{
prc_t p = (prc_t)ft->priv;
/* Psion Record seems not to be able to handle frames > 800 samples */
@@ -351,7 +321,7 @@
samp = min(samp, 800);
p->nsamp += samp;
sox_debug_more("length now = %d", p->nsamp);
- if (ft->signal.encoding == SOX_ENCODING_IMA_ADPCM) {
+ if (ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM) {
sox_size_t written;
write_cardinal(ft, samp);
@@ -360,7 +330,7 @@
/* Write length again (seems to be a BListL) */
sox_debug_more("list length %d", samp);
sox_writedw(ft, samp);
- sox_adpcm_reset(&p->adpcm, ft->signal.encoding);
+ sox_adpcm_reset(&p->adpcm, ft->encoding.encoding);
written = sox_adpcm_write(ft, &p->adpcm, buf, samp);
sox_adpcm_flush(ft, &p->adpcm);
return written;
@@ -397,7 +367,7 @@
sox_debug("Number of samples: %d",p->nsamp);
sox_writedw(ft, p->nsamp);
- if (ft->signal.encoding == SOX_ENCODING_ALAW)
+ if (ft->encoding.encoding == SOX_ENCODING_ALAW)
sox_writedw(ft, 0);
else
sox_writedw(ft, 0x100001a1); /* ADPCM */
@@ -411,27 +381,19 @@
sox_writedw(ft, p->nbytes); /* Number of bytes of data */
}
-/* Psion .prc */
-static const char *prcnames[] = {
- "prc",
- NULL
-};
-
-static sox_format_handler_t sox_prc_format = {
- prcnames,
- SOX_FILE_LIT_END,
- startread,
- read,
- stopread,
- startwrite,
- write,
- stopwrite,
- seek
-};
-
-const sox_format_handler_t *sox_prc_format_fn(void);
-
-const sox_format_handler_t *sox_prc_format_fn(void)
+SOX_FORMAT_HANDLER(prc)
{
- return &sox_prc_format;
+ static char const * const names[] = {"prc", NULL};
+ static sox_rate_t const write_rates[] = {8000, 0};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_ALAW, 8, 0,
+ SOX_ENCODING_IMA_ADPCM, 4, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_LIT_END | SOX_FILE_MONO,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ seek, write_encodings, write_rates
+ };
+ return &handler;
}
--- a/src/rabbit.c
+++ b/src/rabbit.c
@@ -82,18 +82,18 @@
{
rabbit_t r = (rabbit_t) effp->priv;
int err = 0;
- double out_rate = r->out_rate != HUGE_VAL? r->out_rate : effp->outinfo.rate;
+ double out_rate = r->out_rate != HUGE_VAL? r->out_rate : effp->out_signal.rate;
- if (effp->ininfo.rate == out_rate)
+ if (effp->in_signal.rate == out_rate)
return SOX_EFF_NULL;
- effp->outinfo.channels = effp->ininfo.channels;
- effp->outinfo.rate = out_rate;
+ effp->out_signal.channels = effp->in_signal.channels;
+ effp->out_signal.rate = out_rate;
r->data = (SRC_DATA *)xcalloc(1, sizeof(SRC_DATA));
- r->data->src_ratio = out_rate / effp->ininfo.rate;
+ r->data->src_ratio = out_rate / effp->in_signal.rate;
r->i_alloc = r->o_alloc = 0;
- r->state = src_new(r->converter_type, (int)effp->ininfo.channels, &err);
+ r->state = src_new(r->converter_type, (int)effp->in_signal.channels, &err);
if (err) {
free(r->data);
sox_fail("cannot initialise rabbit: %s", src_strerror(err));
@@ -111,7 +111,7 @@
{
rabbit_t r = (rabbit_t) effp->priv;
SRC_DATA *d = r->data;
- unsigned int channels = effp->ininfo.channels;
+ unsigned int channels = effp->in_signal.channels;
sox_size_t i;
sox_size_t isamples0 = d->input_frames * channels;
sox_size_t isamples = isamples0 + *isamp;
--- a/src/raw-fmt.c
+++ b/src/raw-fmt.c
@@ -1,29 +1,42 @@
/*
- * libSoX raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 1991-2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
static int raw_start(sox_format_t * ft) {
- return sox_rawstart(ft, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0);
+ return sox_rawstart(ft, sox_false, sox_false, sox_true, SOX_ENCODING_UNKNOWN, 0);
}
-const sox_format_handler_t *sox_raw_format_fn(void);
-
-const sox_format_handler_t *sox_raw_format_fn(void)
+SOX_FORMAT_HANDLER(raw)
{
- static char const * names[] = {"raw", NULL};
- static sox_format_handler_t handler = {
+ static char const * const names[] = {"raw", NULL};
+ static unsigned const encodings[] = {
+ SOX_ENCODING_SIGN2, 32, 24, 16, 8, 0,
+ SOX_ENCODING_UNSIGNED, 32, 24, 16, 8, 0,
+ SOX_ENCODING_ULAW, 8, 0,
+ SOX_ENCODING_ALAW, 8, 0,
+ SOX_ENCODING_FLOAT, 64, 32, 0,
+ 0};
+ static sox_format_handler_t const handler = {
names, 0,
raw_start, sox_rawread , NULL,
raw_start, sox_rawwrite, NULL,
- sox_rawseek
+ sox_rawseek, encodings, NULL
};
return &handler;
}
--- a/src/raw.c
+++ b/src/raw.c
@@ -22,39 +22,12 @@
int sox_rawseek(sox_format_t * ft, sox_size_t offset)
{
- sox_size_t new_offset, channel_block, alignment;
-
- switch(ft->signal.size) {
- case SOX_SIZE_BYTE:
- case SOX_SIZE_16BIT:
- case SOX_SIZE_24BIT:
- case SOX_SIZE_32BIT:
- case SOX_SIZE_64BIT:
- break;
- default:
- sox_fail_errno(ft,SOX_ENOTSUP,"Can't seek this data size");
- return ft->sox_errno;
- }
-
- new_offset = offset * ft->signal.size;
- /* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
- alignment = new_offset % channel_block;
- /* Most common mistaken is to compute something like
- * "skip everthing upto and including this sample" so
- * advance to next sample block in this case.
- */
- if (alignment != 0)
- new_offset += (channel_block - alignment);
-
- ft->sox_errno = sox_seeki(ft, (sox_ssize_t)new_offset, SEEK_SET);
-
- return ft->sox_errno;
+ return sox_offset_seek(ft, ft->data_start, offset);
}
/* Works nicely for starting read and write; sox_rawstart{read,write}
are #defined in sox_i.h */
-int sox_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_encoding_t encoding, unsigned size)
+int sox_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned size)
{
if (default_rate && ft->signal.rate == 0) {
sox_warn("'%s': sample rate not specified; trying 8kHz", ft->filename);
@@ -68,18 +41,21 @@
if (encoding != SOX_ENCODING_UNKNOWN) {
if (ft->mode == 'r' &&
- ft->signal.encoding != SOX_ENCODING_UNKNOWN &&
- ft->signal.encoding != encoding)
+ ft->encoding.encoding != SOX_ENCODING_UNKNOWN &&
+ ft->encoding.encoding != encoding)
sox_report("'%s': Format options overriding file-type encoding", ft->filename);
- else ft->signal.encoding = encoding;
+ else ft->encoding.encoding = encoding;
}
if (size != 0) {
- if (ft->mode == 'r' && ft->signal.size != 0 && ft->signal.size != size)
+ if (ft->mode == 'r' && ft->encoding.bits_per_sample != 0 && ft->encoding.bits_per_sample != size)
sox_report("'%s': Format options overriding file-type sample-size", ft->filename);
- else ft->signal.size = size;
+ else ft->encoding.bits_per_sample = size;
}
+ if (ft->mode == 'r' && default_length && ft->encoding.bits_per_sample)
+ ft->length = div_bits(sox_filelength(ft), ft->encoding.bits_per_sample);
+
return SOX_SUCCESS;
}
@@ -141,9 +117,9 @@
static ft_io_fun *check_format(sox_format_t * ft, sox_bool write)
{
- switch (ft->signal.size) {
- case SOX_SIZE_BYTE:
- switch (ft->signal.encoding) {
+ switch (ft->encoding.bits_per_sample) {
+ case 8:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_SIGN2:
return write ? sox_write_sb_samples : sox_read_sb_samples;
case SOX_ENCODING_UNSIGNED:
@@ -157,8 +133,8 @@
}
break;
- case SOX_SIZE_16BIT:
- switch (ft->signal.encoding) {
+ case 16:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_SIGN2:
return write ? sox_write_sw_samples : sox_read_sw_samples;
case SOX_ENCODING_UNSIGNED:
@@ -168,8 +144,8 @@
}
break;
- case SOX_SIZE_24BIT:
- switch (ft->signal.encoding) {
+ case 24:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_SIGN2:
return write ? sox_write_s3_samples : sox_read_s3_samples;
case SOX_ENCODING_UNSIGNED:
@@ -179,8 +155,8 @@
}
break;
- case SOX_SIZE_32BIT:
- switch (ft->signal.encoding) {
+ case 32:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_SIGN2:
return write ? sox_write_sdw_samples : sox_read_sdw_samples;
case SOX_ENCODING_UNSIGNED:
@@ -192,8 +168,8 @@
}
break;
- case SOX_SIZE_64BIT:
- switch (ft->signal.encoding) {
+ case 64:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_FLOAT:
return write ? sox_write_sudf_samples : sox_read_sudf_samples;
default:
--- a/src/raw.h
+++ b/src/raw.h
@@ -1,25 +1,34 @@
/*
- * libSoX raw file formats
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * July 5, 1991
- * Copyright 1991 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#define RAW_FORMAT0(id, size, flags, encoding) \
static int id ## _start(sox_format_t * ft) { \
- return sox_rawstart(ft, sox_true, sox_true, SOX_ENCODING_ ## encoding, SOX_SIZE_ ## size); \
+ return sox_rawstart(ft, sox_true, sox_true, sox_true, SOX_ENCODING_ ## encoding, size); \
} \
const sox_format_handler_t *sox_ ## id ## _format_fn(void); \
const sox_format_handler_t *sox_ ## id ## _format_fn(void) { \
+ static unsigned const write_encodings[] = { \
+ SOX_ENCODING_ ## encoding, size, 0, 0}; \
static sox_format_handler_t handler = { \
names, flags, \
id ## _start, sox_rawread , NULL, \
id ## _start, sox_rawwrite, NULL, \
- NULL \
+ NULL, write_encodings, NULL \
}; \
return &handler; \
}
--- a/src/remix.c
+++ b/src/remix.c
@@ -98,7 +98,7 @@
if (p->out_specs[i].in_specs[j].multiplier == HUGE_VAL)
p->out_specs[i].in_specs[j].multiplier = (p->mode == automatic || (p->mode == semi && !mul_spec)) ? 1. / p->out_specs[i].num_in_channels : 1;
}
- effp->outinfo.channels = p->num_out_channels;
+ effp->out_signal.channels = p->num_out_channels;
return SOX_SUCCESS;
}
@@ -114,8 +114,8 @@
static int start(sox_effect_t * effp)
{
remix_t p = (remix_t) effp->priv;
- parse(effp, NULL, effp->ininfo.channels);
- if (effp->ininfo.channels < p->min_in_channels) {
+ parse(effp, NULL, effp->in_signal.channels);
+ if (effp->in_signal.channels < p->min_in_channels) {
sox_fail("too few input channels");
return SOX_EOF;
}
@@ -127,11 +127,11 @@
{
remix_t p = (remix_t) effp->priv;
unsigned i, j, len;
- len = min(*isamp / effp->ininfo.channels, *osamp / effp->outinfo.channels);
- *isamp = len * effp->ininfo.channels;
- *osamp = len * effp->outinfo.channels;
+ len = min(*isamp / effp->in_signal.channels, *osamp / effp->out_signal.channels);
+ *isamp = len * effp->in_signal.channels;
+ *osamp = len * effp->out_signal.channels;
- for (; len--; ibuf += effp->ininfo.channels) for (j = 0; j < effp->outinfo.channels; j++) {
+ for (; len--; ibuf += effp->in_signal.channels) for (j = 0; j < effp->out_signal.channels; j++) {
double out = 0;
for (i = 0; i < p->out_specs[j].num_in_channels; i++)
out += ibuf[p->out_specs[j].in_specs[i].channel_num] * p->out_specs[j].in_specs[i].multiplier;
--- a/src/resample.c
+++ b/src/resample.c
@@ -37,12 +37,12 @@
* Various changes, bugfixes(?), increased precision, by Stan Brooks.
*/
+#include "sox_i.h"
+
#include <math.h>
#include <stdlib.h>
#include <string.h>
-#include "sox_i.h"
-
/* Conversion constants */
#define Lc 7
#define Nc (1<<Lc)
@@ -195,16 +195,16 @@
long Xoff, gcdrate;
int i;
- if (effp->ininfo.rate == effp->outinfo.rate)
+ if (effp->in_signal.rate == effp->out_signal.rate)
return SOX_EFF_NULL;
- effp->outinfo.channels = effp->ininfo.channels;
+ effp->out_signal.channels = effp->in_signal.channels;
- r->Factor = effp->outinfo.rate / effp->ininfo.rate;
+ r->Factor = effp->out_signal.rate / effp->in_signal.rate;
- gcdrate = sox_gcd((long) effp->ininfo.rate, (long) effp->outinfo.rate);
- r->a = effp->ininfo.rate / gcdrate;
- r->b = effp->outinfo.rate / gcdrate;
+ gcdrate = sox_gcd((long) effp->in_signal.rate, (long) effp->out_signal.rate);
+ r->a = effp->in_signal.rate / gcdrate;
+ r->b = effp->out_signal.rate / gcdrate;
if (r->a <= r->b && r->b <= NQMAX) {
r->quadr = -1; /* exact coeffs */
--- a/src/reverb.c
+++ b/src/reverb.c
@@ -202,19 +202,19 @@
size_t i;
p->ichannels = p->ochannels = 1;
- effp->outinfo.rate = effp->ininfo.rate;
- if (effp->ininfo.channels > 2 && p->stereo_depth) {
+ effp->out_signal.rate = effp->in_signal.rate;
+ if (effp->in_signal.channels > 2 && p->stereo_depth) {
sox_warn("stereo-depth not applicable with >2 channels");
p->stereo_depth = 0;
}
- if (effp->ininfo.channels == 1 && p->stereo_depth)
- effp->outinfo.channels = p->ochannels = 2;
- else effp->outinfo.channels = effp->ininfo.channels;
- if (effp->ininfo.channels == 2 && p->stereo_depth)
+ if (effp->in_signal.channels == 1 && p->stereo_depth)
+ effp->out_signal.channels = p->ochannels = 2;
+ else effp->out_signal.channels = effp->in_signal.channels;
+ if (effp->in_signal.channels == 2 && p->stereo_depth)
p->ichannels = p->ochannels = 2;
- else effp->flows = effp->ininfo.channels;
+ else effp->flows = effp->in_signal.channels;
for (i = 0; i < p->ichannels; ++i) reverb_create(
- &p->chan[i].reverb, effp->ininfo.rate, p->wet_gain_dB, p->room_scale,
+ &p->chan[i].reverb, effp->in_signal.rate, p->wet_gain_dB, p->room_scale,
p->reverberance, p->hf_damping, p->pre_delay_ms, p->stereo_depth,
effp->global_info->global_info->bufsiz / p->ochannels, p->chan[i].wet);
return SOX_SUCCESS;
--- a/src/s1-fmt.c
+++ b/src/s1-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX s1 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT1(s1, "sb", 8BIT, 0, SIGN2)
+RAW_FORMAT1(s1, "sb", 8, 0, SIGN2)
--- a/src/s2-fmt.c
+++ b/src/s2-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX s2 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT1(s2, "sw", 16BIT, 0, SIGN2)
+RAW_FORMAT1(s2, "sw", 16, 0, SIGN2)
--- a/src/s3-fmt.c
+++ b/src/s3-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX s3 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(s3, 24BIT, 0, SIGN2)
+RAW_FORMAT(s3, 24, 0, SIGN2)
--- a/src/s4-fmt.c
+++ b/src/s4-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX s4 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT1(s4, "sl", 32BIT, 0, SIGN2)
+RAW_FORMAT1(s4, "sl", 32, 0, SIGN2)
--- a/src/sf.c
+++ b/src/sf.c
@@ -40,7 +40,7 @@
sfcodep = (SFCODE *) (&sfhead->sfinfo + 1);
do {
sfcharp = (char *) sfcodep + sizeof(SFCODE);
- if (ft->signal.reverse_bytes) {
+ if (ft->encoding.reverse_bytes) {
sfcodep->bsize = sox_swapdw(sfcodep->bsize);
sfcodep->code = sox_swapdw(sfcodep->code);
}
@@ -61,14 +61,14 @@
free(commentbuf);
}
-static int sox_sfseek(sox_format_t * ft, sox_size_t offset)
+static int seek(sox_format_t * ft, sox_size_t offset)
{
sox_size_t new_offset, channel_block, alignment;
sf_t sf = (sf_t ) ft->priv;
- new_offset = offset * ft->signal.size;
+ new_offset = offset * (ft->encoding.bits_per_sample >> 3);
/* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
+ channel_block = ft->signal.channels * (ft->encoding.bits_per_sample >> 3);
alignment = new_offset % channel_block;
/* Most common mistaken is to compute something like
* "skip everthing upto and including this sample" so
@@ -88,7 +88,7 @@
* size and encoding of samples,
* mono/stereo/quad.
*/
-static int sox_sfstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
sf_t sf = (sf_t) ft->priv;
SFHEADER sfhead;
@@ -101,7 +101,7 @@
return(SOX_EOF);
}
memcpy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
- if (ft->signal.reverse_bytes) {
+ if (ft->encoding.reverse_bytes) {
sox_swapf(&sf->info.sf_srate);
sf->info.sf_packmode = sox_swapdw(sf->info.sf_packmode);
sf->info.sf_chans = sox_swapdw(sf->info.sf_chans);
@@ -120,13 +120,13 @@
ft->signal.rate = sf->info.sf_srate;
switch(sf->info.sf_packmode) {
case SF_SHORT:
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- samplesize = ft->signal.size;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
+ samplesize = 2;
break;
case SF_FLOAT:
- ft->signal.size = SOX_SIZE_32BIT;
- ft->signal.encoding = SOX_ENCODING_FLOAT;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_FLOAT;
samplesize = sizeof(float);
break;
default:
@@ -156,7 +156,7 @@
return(rc);
}
-static int sox_sfstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
sf_t sf = (sf_t) ft->priv;
SFHEADER sfhead;
@@ -181,14 +181,14 @@
sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
sf->info.sf_srate = ft->signal.rate;
- if (ft->signal.size == SOX_SIZE_32BIT &&
- ft->signal.encoding == SOX_ENCODING_FLOAT) {
+ if (ft->encoding.bits_per_sample == 32 &&
+ ft->encoding.encoding == SOX_ENCODING_FLOAT) {
sf->info.sf_packmode = SF_FLOAT;
} else {
sf->info.sf_packmode = SF_SHORT;
/* Default to signed words */
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
sf->info.sf_chans = ft->signal.channels;
@@ -216,29 +216,18 @@
return(SOX_SUCCESS);
}
-/* Read and write are supplied by raw.c */
-/* IRCAM Sound File */
-static const char *sfnames[] = {
- "sf",
- "ircam",
- NULL
-};
-
-static sox_format_handler_t sox_sf_format = {
- sfnames,
- 0,
- sox_sfstartread,
- sox_rawread,
- sox_rawstopread,
- sox_sfstartwrite,
- sox_rawwrite,
- sox_rawstopwrite,
- sox_sfseek
-};
-
-const sox_format_handler_t *sox_sf_format_fn(void);
-
-const sox_format_handler_t *sox_sf_format_fn(void)
+SOX_FORMAT_HANDLER(sf)
{
- return &sox_sf_format;
+ static char const * const names[] = {"sf", "ircam", NULL};
+ static unsigned const encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 0,
+ SOX_ENCODING_FLOAT, 32, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, 0,
+ startread, sox_rawread, sox_rawstopread,
+ startwrite, sox_rawwrite, sox_rawstopwrite,
+ seek, encodings, NULL
+ };
+ return &handler;
}
--- a/src/silence.c
+++ b/src/silence.c
@@ -13,10 +13,10 @@
* Thesholds can be given as either a percentage or in decibels.
*/
+#include "sox_i.h"
#include <string.h>
#include <math.h>
-#include "sox_i.h"
/* Private data for silence effect. */
@@ -228,8 +228,8 @@
* better or else RMS will look like non-silence at
* aburpt changes from load to silence.
*/
- silence->window_size = (effp->ininfo.rate / 50) *
- effp->ininfo.channels;
+ silence->window_size = (effp->in_signal.rate / 50) *
+ effp->in_signal.channels;
silence->window = (double *)xmalloc(silence->window_size *
sizeof(double));
@@ -238,13 +238,13 @@
/* Now that we know sample rate, reparse duration. */
if (silence->start)
{
- if (sox_parsesamples(effp->ininfo.rate, silence->start_duration_str,
+ if (sox_parsesamples(effp->in_signal.rate, silence->start_duration_str,
&silence->start_duration, 's') == NULL)
return sox_usage(effp);
}
if (silence->stop)
{
- if (sox_parsesamples(effp->ininfo.rate,silence->stop_duration_str,
+ if (sox_parsesamples(effp->in_signal.rate,silence->stop_duration_str,
&silence->stop_duration,'s') == NULL)
return sox_usage(effp);
}
@@ -275,21 +275,21 @@
/* When scaling low bit data, noise values got scaled way up */
/* Only consider the original bits when looking for silence */
- switch(effp->ininfo.size)
+ switch(effp->in_signal.precision)
{
- case SOX_SIZE_BYTE:
+ case 8:
value = SOX_SAMPLE_TO_SIGNED_8BIT(value, dummy_clipped_count);
ratio = (double)abs(value) / (double)SOX_INT8_MAX;
break;
- case SOX_SIZE_16BIT:
+ case 16:
value = SOX_SAMPLE_TO_SIGNED_16BIT(value, dummy_clipped_count);
ratio = (double)abs(value) / (double)SOX_INT16_MAX;
break;
- case SOX_SIZE_24BIT:
+ case 24:
value = SOX_SAMPLE_TO_SIGNED_24BIT(value, dummy_clipped_count);
ratio = (double)abs(value) / (double)SOX_INT24_MAX;
break;
- case SOX_SIZE_32BIT:
+ case 32:
value = SOX_SAMPLE_TO_SIGNED_32BIT(value,);
ratio = (double)labs(value) / (double)SOX_INT32_MAX;
break;
@@ -359,11 +359,11 @@
silence_trim:
nrOfTicks = min((*isamp-nrOfInSamplesRead),
(*osamp-nrOfOutSamplesWritten)) /
- effp->ininfo.channels;
+ effp->in_signal.channels;
for(i = 0; i < nrOfTicks; i++)
{
threshold = 0;
- for (j = 0; j < effp->ininfo.channels; j++)
+ for (j = 0; j < effp->in_signal.channels; j++)
{
threshold |= aboveThreshold(effp,
compute_rms(effp, ibuf[j]),
@@ -374,7 +374,7 @@
if (threshold)
{
/* Add to holdoff buffer */
- for (j = 0; j < effp->ininfo.channels; j++)
+ for (j = 0; j < effp->in_signal.channels; j++)
{
update_rms(effp, *ibuf);
silence->start_holdoff[
@@ -401,12 +401,12 @@
else /* !above Threshold */
{
silence->start_holdoff_end = 0;
- for (j = 0; j < effp->ininfo.channels; j++)
+ for (j = 0; j < effp->in_signal.channels; j++)
{
update_rms(effp, ibuf[j]);
}
- ibuf += effp->ininfo.channels;
- nrOfInSamplesRead += effp->ininfo.channels;
+ ibuf += effp->in_signal.channels;
+ nrOfInSamplesRead += effp->in_signal.channels;
}
} /* for nrOfTicks */
break;
@@ -474,7 +474,7 @@
silence_copy:
nrOfTicks = min((*isamp-nrOfInSamplesRead),
(*osamp-nrOfOutSamplesWritten)) /
- effp->ininfo.channels;
+ effp->in_signal.channels;
if (silence->stop)
{
/* Case A */
@@ -481,7 +481,7 @@
for(i = 0; i < nrOfTicks; i++)
{
threshold = 1;
- for (j = 0; j < effp->ininfo.channels; j++)
+ for (j = 0; j < effp->in_signal.channels; j++)
{
threshold &= aboveThreshold(effp,
compute_rms(effp, ibuf[j]),
@@ -510,7 +510,7 @@
else if (threshold)
{
/* Not holding off so copy into output buffer */
- for (j = 0; j < effp->ininfo.channels; j++)
+ for (j = 0; j < effp->in_signal.channels; j++)
{
update_rms(effp, *ibuf);
*obuf++ = *ibuf++;
@@ -522,7 +522,7 @@
else if (!threshold)
{
/* Add to holdoff buffer */
- for (j = 0; j < effp->ininfo.channels; j++)
+ for (j = 0; j < effp->in_signal.channels; j++)
{
update_rms(effp, *ibuf);
if (silence->leave_silence) {
@@ -584,9 +584,9 @@
{
/* Case B */
memcpy(obuf, ibuf, sizeof(sox_sample_t)*nrOfTicks*
- effp->ininfo.channels);
- nrOfInSamplesRead += (nrOfTicks*effp->ininfo.channels);
- nrOfOutSamplesWritten += (nrOfTicks*effp->ininfo.channels);
+ effp->in_signal.channels);
+ nrOfInSamplesRead += (nrOfTicks*effp->in_signal.channels);
+ nrOfOutSamplesWritten += (nrOfTicks*effp->in_signal.channels);
}
break;
--- a/src/skeleff.c
+++ b/src/skeleff.c
@@ -30,7 +30,7 @@
/*
* Process command-line options but don't do other
- * initialization now: effp->ininfo & effp->outinfo are not
+ * initialization now: effp->in_signal & effp->out_signal are not
* yet filled in.
*/
static int getopts(sox_effect_t * effp, int n, char UNUSED **argv)
@@ -49,7 +49,7 @@
*/
static int start(sox_effect_t * effp)
{
- if (effp->outinfo.channels == 1) {
+ if (effp->out_signal.channels == 1) {
sox_fail("Can't run on mono data.");
return SOX_EOF;
}
@@ -67,7 +67,7 @@
skeleff_t UNUSED skeleff = (skeleff_t)effp->priv;
sox_size_t len, done;
- switch (effp->outinfo.channels) {
+ switch (effp->out_signal.channels) {
case 2:
/* Length to process will be buffer length / 2 since we
* work with two samples at a time.
--- a/src/skelform.c
+++ b/src/skelform.c
@@ -59,15 +59,15 @@
* then you should set it here.
*/
ft->signal.rate = 44100; /* or 8000, 16000, 32000, 48000, ... */
- ft->signal.size = SOX_SIZE_8BIT; /* or 16BIT ... */
- ft->signal.encoding = SOX_ENCODING_UNSIGNED; /* or SIGN2 ... */
- ft->signal.channels = 1; /* or 2 or 4 */
+ ft->signal.channels = 1; /* or 2 or 3 ... */
+ ft->encoding.bits_per_sample = 8; /* or 16 ... */
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED; /* or SIGN2 ... */
append_comment(&ft->comments, "any comment in file header.");
/* If your format doesn't have a header then samples_in_file
* can be determined by the file size.
*/
- samples_in_file = sox_filelength(ft) / ft->signal.size;
+ samples_in_file = sox_filelength(ft) / (ft->encoding.bits_per_sample >> 3);
/* If you can detect the length of your file, record it here. */
ft->length = samples_in_file;
@@ -80,7 +80,7 @@
* Read up to len samples of type sox_sample_t from file into buf[].
* Return number of samples read, or 0 if at end of file.
*/
-static sox_size_t read(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
skelform_t UNUSED sk = (skelform_t)ft->priv;
sox_size_t done;
@@ -90,9 +90,9 @@
if (feof(ft->fp)) /* no more samples */
break;
sample = fgetc(ft->fp);
- switch (ft->signal.size) {
- case SOX_SIZE_8BIT:
- switch (ft->signal.encoding) {
+ switch (ft->encoding.bits_per_sample) {
+ case 8:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_UNSIGNED:
*buf++ = SOX_UNSIGNED_8BIT_TO_SAMPLE(sample,);
break;
@@ -136,12 +136,12 @@
if (ft->signal.rate != 44100)
sox_fail("Output .skel file must have a sample rate of 44100Hz");
- if (ft->signal.size == 0) {
+ if (ft->encoding.bits_per_sample == 0) {
sox_fail("Did not specify a size for .skel output file");
return SOX_EOF;
}
- /* error check ft->signal.encoding */
+ /* error check ft->encoding.encoding */
/* error check ft->signal.channels */
/* Write file header, if any */
@@ -155,13 +155,13 @@
* Write len samples of type sox_sample_t from buf[] to file.
* Return number of samples written.
*/
-static sox_size_t write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
skelform_t UNUSED sk = (skelform_t)ft->priv;
- switch (ft->signal.size) {
- case SOX_SIZE_8BIT:
- switch (ft->signal.encoding) {
+ switch (ft->encoding.bits_per_sample) {
+ case 8:
+ switch (ft->encoding.encoding) {
case SOX_ENCODING_UNSIGNED:
while (len--) {
len = sox_writeb(ft, SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips));
@@ -196,32 +196,28 @@
return SOX_SUCCESS;
}
-/* Format file suffixes */
-static const char *names[] = {
- "skel",
- NULL
-};
+SOX_FORMAT_HANDLER(skel)
+{
+ /* Format file suffixes */
+ static const char *names[] = {"skel",NULL };
-/* Format descriptor
- * If no specific processing is needed for any of
- * the 7 functions, then the function above can be deleted
- * and 0 used in place of the its name below.
- */
-static sox_format_handler_t sox_skel_format = {
- names,
- 0,
- startread,
- read,
- stopread,
- startwrite,
- write,
- stopwrite,
- seek
-};
+ /* Encoding types and sizes that this handler can write */
+ static unsigned encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 0,
+ SOX_ENCODING_UNSIGNED, 8, 0,
+ 0};
-const sox_format_handler_t *sox_skel_format_fn(void);
+ /* Format descriptor
+ * If no specific processing is needed for any of
+ * the 7 functions, then the function above can be deleted
+ * and NULL used in place of the its name below.
+ */
+ static sox_format_handler_t handler = {
+ names, 0,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ seek, encodings, NULL
+ };
-const sox_format_handler_t *sox_skel_format_fn(void)
-{
- return &sox_skel_format;
+ return &handler;
}
--- a/src/smp.c
+++ b/src/smp.c
@@ -174,9 +174,9 @@
sox_size_t new_offset, channel_block, alignment;
smp_t smp = (smp_t) ft->priv;
- new_offset = offset * ft->signal.size;
+ new_offset = offset * (ft->encoding.bits_per_sample >> 3);
/* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
+ channel_block = ft->signal.channels * (ft->encoding.bits_per_sample >> 3);
alignment = new_offset % channel_block;
/* Most common mistaken is to compute something like
* "skip everthing upto and including this sample" so
@@ -189,7 +189,7 @@
ft->sox_errno = sox_seeki(ft, (sox_ssize_t)new_offset, SEEK_SET);
if( ft->sox_errno == SOX_SUCCESS )
- smp->NoOfSamps = ft->length - (new_offset / ft->signal.size);
+ smp->NoOfSamps = ft->length - (new_offset / (ft->encoding.bits_per_sample >> 3));
return(ft->sox_errno);
}
@@ -271,8 +271,8 @@
}
ft->signal.rate = (int) trailer.rate;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
ft->signal.channels = 1;
smp->dataStart = samplestart;
ft->length = smp->NoOfSamps;
@@ -344,11 +344,6 @@
return(SOX_EOF);
}
- /* If your format specifies any of the following info. */
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.channels = 1;
-
memcpy(header.Id, SVmagic, sizeof(header.Id));
memcpy(header.version, SVvers, sizeof(header.version));
sprintf(header.comments, "%-*s", COMMENTLEN - 1, "Converted using Sox.");
@@ -401,27 +396,15 @@
return(SOX_SUCCESS);
}
-/* SampleVision sound */
-static const char *smpnames[] = {
- "smp",
- NULL,
-};
-
-static sox_format_handler_t sox_smp_format = {
- smpnames,
- SOX_FILE_LOOPS | SOX_FILE_LIT_END,
- sox_smpstartread,
- sox_smpread,
- NULL,
- sox_smpstartwrite,
- sox_smpwrite,
- sox_smpstopwrite,
- sox_smpseek
-};
-
-const sox_format_handler_t *sox_smp_format_fn(void);
-
-const sox_format_handler_t *sox_smp_format_fn(void)
+SOX_FORMAT_HANDLER(smp)
{
- return &sox_smp_format;
+ static char const * const names[] = {"smp", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 16, 0, 0};
+ static sox_format_handler_t handler = {
+ names, SOX_FILE_LOOPS | SOX_FILE_LIT_END | SOX_FILE_MONO,
+ sox_smpstartread, sox_smpread, NULL,
+ sox_smpstartwrite, sox_smpwrite, sox_smpstopwrite,
+ sox_smpseek, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/sndfile.c
+++ b/src/sndfile.c
@@ -84,43 +84,43 @@
switch (format) {
case SF_FORMAT_PCM_S8:
- *size = SOX_SIZE_8BIT;
+ *size = 8;
return SOX_ENCODING_SIGN2;
case SF_FORMAT_PCM_16:
- *size = SOX_SIZE_16BIT;
+ *size = 16;
return SOX_ENCODING_SIGN2;
case SF_FORMAT_PCM_24:
- *size = SOX_SIZE_24BIT;
+ *size = 24;
return SOX_ENCODING_SIGN2;
case SF_FORMAT_PCM_32:
- *size = SOX_SIZE_32BIT;
+ *size = 32;
return SOX_ENCODING_SIGN2;
case SF_FORMAT_PCM_U8:
- *size = SOX_SIZE_8BIT;
+ *size = 8;
return SOX_ENCODING_UNSIGNED;
case SF_FORMAT_FLOAT:
- *size = SOX_SIZE_32BIT;
+ *size = 32;
return SOX_ENCODING_FLOAT;
case SF_FORMAT_DOUBLE:
- *size = SOX_SIZE_64BIT;
+ *size = 64;
return SOX_ENCODING_FLOAT;
case SF_FORMAT_ULAW:
- *size = SOX_SIZE_8BIT;
+ *size = 8;
return SOX_ENCODING_ULAW;
case SF_FORMAT_ALAW:
- *size = SOX_SIZE_8BIT;
+ *size = 8;
return SOX_ENCODING_ALAW;
case SF_FORMAT_IMA_ADPCM:
- *size = SOX_SIZE_16BIT;
+ *size = 16;
return SOX_ENCODING_IMA_ADPCM;
case SF_FORMAT_MS_ADPCM:
- *size = SOX_SIZE_16BIT;
+ *size = 16;
return SOX_ENCODING_MS_ADPCM;
case SF_FORMAT_GSM610:
- *size = SOX_SIZE_16BIT;
+ *size = 16;
return SOX_ENCODING_GSM;
case SF_FORMAT_VOX_ADPCM:
- *size = SOX_SIZE_16BIT;
+ *size = 16;
return SOX_ENCODING_OKI_ADPCM;
/* For encodings we can't represent, have a sensible default */
@@ -210,13 +210,12 @@
/* Make libsndfile subtype from sample encoding and size */
static int sndfile_format(sox_encoding_t encoding, unsigned size)
{
- if (encoding < SOX_ENCODING_SIZE_IS_WORD) {
- switch (encoding) {
+ size = (size + 7) & ~7u;
+ switch (encoding) {
case SOX_ENCODING_ULAW:
return SF_FORMAT_ULAW;
case SOX_ENCODING_ALAW:
return SF_FORMAT_ALAW;
- case SOX_ENCODING_ADPCM:
case SOX_ENCODING_MS_ADPCM:
return SF_FORMAT_MS_ADPCM;
case SOX_ENCODING_IMA_ADPCM:
@@ -223,13 +222,8 @@
return SF_FORMAT_IMA_ADPCM;
case SOX_ENCODING_OKI_ADPCM:
return SF_FORMAT_VOX_ADPCM;
- default: /* Should be impossible */
- return 0;
- }
- } else {
- switch (encoding) {
case SOX_ENCODING_UNSIGNED:
- if (size == SOX_SIZE_8BIT)
+ if (size == 8)
return SF_FORMAT_PCM_U8;
else
return 0;
@@ -239,13 +233,13 @@
#ifdef HAVE_SNDFILE_1_0_12
case SOX_ENCODING_FLAC:
switch (size) {
- case SOX_SIZE_8BIT:
+ case 8:
return SF_FORMAT_PCM_S8;
- case SOX_SIZE_16BIT:
+ case 16:
return SF_FORMAT_PCM_16;
- case SOX_SIZE_24BIT:
+ case 24:
return SF_FORMAT_PCM_24;
- case SOX_SIZE_32BIT:
+ case 32:
return SF_FORMAT_PCM_32;
default: /* invalid size */
return 0;
@@ -258,7 +252,6 @@
return SF_FORMAT_GSM610;
default: /* Bad encoding */
return 0;
- }
}
}
@@ -265,7 +258,7 @@
static void start(sox_format_t * ft)
{
sndfile_t sf = (sndfile_t)ft->priv;
- int subtype = sndfile_format(ft->signal.encoding, ft->signal.size);
+ int subtype = sndfile_format(ft->encoding.encoding, ft->encoding.bits_per_sample? ft->encoding.bits_per_sample : ft->signal.precision);
sf->log_buffer_ptr = sf->log_buffer = xmalloc(LOG_MAX);
sf->sf_info = (SF_INFO *)xcalloc(1, sizeof(SF_INFO));
@@ -304,7 +297,7 @@
}
/* Copy format info */
- ft->signal.encoding = sox_encoding_and_size((unsigned)sf->sf_info->format, &ft->signal.size);
+ ft->encoding.encoding = sox_encoding_and_size((unsigned)sf->sf_info->format, &ft->encoding.bits_per_sample);
ft->signal.channels = sf->sf_info->channels;
ft->length = sf->sf_info->frames * sf->sf_info->channels;
@@ -324,7 +317,7 @@
* Read up to len samples of type sox_sample_t from file into buf[].
* Return number of samples read.
*/
-static sox_size_t read(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
sndfile_t sf = (sndfile_t)ft->priv;
@@ -391,7 +384,7 @@
* Write len samples of type sox_sample_t from buf[] to file.
* Return number of samples written.
*/
-static sox_size_t write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
sndfile_t sf = (sndfile_t)ft->priv;
@@ -418,56 +411,60 @@
return SOX_SUCCESS;
}
-/* Format file suffixes */
-/* For now, comment out formats built in to SoX */
-static const char *names[] = {
- "sndfile", /* special type to force use of sndfile */
- /* "aif", */
- /* "wav", */
- /* "au", */
+SOX_FORMAT_HANDLER(sndfile)
+{
+ /* Format file suffixes */
+ /* For now, comment out formats built in to SoX */
+ static char const * const names[] = {
+ "sndfile", /* special type to force use of sndfile */
+ /* "aif", */
+ /* "wav", */
+ /* "au", */
#ifdef HAVE_SNDFILE_1_0_12
- "caf",
+ "caf",
#endif
- /* "flac", */
- /* "snd", */
- /* "svx", */
- "paf",
- "fap",
- /* "gsm", */
- /* "nist", */
- /* "ircam", */
- /* "sf", */
- /* "voc", */
- "w64",
- /* "raw", */
- "mat4",
- "mat5",
- "mat",
- "pvf",
- "sds",
- "sd2",
- /* "vox", */
- "xi",
- NULL
-};
+ /* "flac", */
+ /* "snd", */
+ /* "svx", */
+ "paf",
+ "fap",
+ /* "gsm", */
+ /* "nist", */
+ /* "ircam", */
+ /* "sf", */
+ /* "voc", */
+ "w64",
+ /* "raw", */
+ "mat4",
+ "mat5",
+ "mat",
+ "pvf",
+ "sds",
+ "sd2",
+ /* "vox", */
+ "xi",
+ NULL
+ };
-/* Format descriptor */
-static sox_format_handler_t format = {
- names,
- SOX_FILE_NOSTDIO,
- startread,
- read,
- stopread,
- startwrite,
- write,
- stopwrite,
- seek
-};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 24, 32, 8, 0,
+ SOX_ENCODING_UNSIGNED, 8, 0,
+ SOX_ENCODING_FLOAT, 32, 64, 0,
+ SOX_ENCODING_ALAW, 8, 0,
+ SOX_ENCODING_ULAW, 8, 0,
+ SOX_ENCODING_IMA_ADPCM, 4, 0,
+ SOX_ENCODING_MS_ADPCM, 4, 0,
+ SOX_ENCODING_OKI_ADPCM, 4, 0,
+ SOX_ENCODING_GSM, 0,
+ 0};
-const sox_format_handler_t *sox_sndfile_format_fn(void);
+ static sox_format_handler_t const format = {
+ names, SOX_FILE_NOSTDIO,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ seek, write_encodings, NULL
+ };
-const sox_format_handler_t *sox_sndfile_format_fn(void)
-{
return &format;
}
--- a/src/sndrtool.c
+++ b/src/sndrtool.c
@@ -40,14 +40,14 @@
sox_writebuf(ft, name_buf, 96);
}
-static int sox_sndseek(sox_format_t * ft, sox_size_t offset)
+static int seek(sox_format_t * ft, sox_size_t offset)
{
sox_size_t new_offset, channel_block, alignment;
snd_t snd = (snd_t) ft->priv;
- new_offset = offset * ft->signal.size;
+ new_offset = offset * (ft->encoding.bits_per_sample >> 3);
/* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
+ channel_block = ft->signal.channels * (ft->encoding.bits_per_sample >> 3);
alignment = new_offset % channel_block;
/* Most common mistaken is to compute something like
* "skip everthing upto and including this sample" so
@@ -60,7 +60,7 @@
return sox_seeki(ft, (sox_ssize_t) new_offset, SEEK_SET);
}
-static int sox_sndtstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
snd_t snd = (snd_t) ft->priv;
@@ -113,8 +113,8 @@
ft->signal.channels = 1;
ft->signal.rate = rate;
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- ft->signal.size = SOX_SIZE_BYTE;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.bits_per_sample = 8;
snd->dataStart = sox_tell(ft);
ft->length = sox_filelength(ft) - snd->dataStart;
@@ -122,7 +122,7 @@
return (SOX_SUCCESS);
}
-static int sox_sndtstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
snd_t p = (snd_t) ft->priv;
int rc;
@@ -133,9 +133,6 @@
return rc;
/* write header */
- ft->signal.channels = 1;
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- ft->signal.size = SOX_SIZE_BYTE;
p->nsamples = 0;
sndtwriteheader(ft, 0);
@@ -142,7 +139,7 @@
return (SOX_SUCCESS);
}
-static sox_size_t sox_sndtwrite(sox_format_t * ft, const sox_sample_t * buf,
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t * buf,
sox_size_t len)
{
snd_t p = (snd_t) ft->priv;
@@ -151,7 +148,7 @@
return sox_rawwrite(ft, buf, len);
}
-static int sox_sndtstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
snd_t p = (snd_t) ft->priv;
@@ -161,34 +158,19 @@
"can't rewind output file to rewrite SND header");
return SOX_EOF;
}
-
sndtwriteheader(ft, p->nsamples);
-
-
return (SOX_SUCCESS);
}
-/* Sndtool Sound File */
-static const char *sndtnames[] = {
- "sndt",
- NULL
-};
-
-static const sox_format_handler_t sox_snd_format = {
- sndtnames,
- SOX_FILE_LIT_END,
- sox_sndtstartread,
- sox_rawread,
- sox_rawstopread,
- sox_sndtstartwrite,
- sox_sndtwrite,
- sox_sndtstopwrite,
- sox_sndseek
-};
-
-const sox_format_handler_t *sox_sndrtool_format_fn(void);
-
-const sox_format_handler_t *sox_sndrtool_format_fn(void)
+SOX_FORMAT_HANDLER(sndrtool)
{
- return &sox_snd_format;
+ static char const * const names[] = {"sndt", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_UNSIGNED, 8, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_LIT_END | SOX_FILE_MONO,
+ startread, sox_rawread, sox_rawstopread,
+ startwrite, write_samples, stopwrite,
+ seek, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/sox.c
+++ b/src/sox.c
@@ -72,7 +72,6 @@
static enum {sox_sequence, sox_concatenate, sox_mix, sox_merge}
combine_method = sox_concatenate;
-static sox_bool repeatable_random = sox_false; /* Whether to invoke srand. */
static sox_bool interactive = sox_false;
static sox_bool uservolume = sox_false;
typedef enum {RG_off, RG_track, RG_album} rg_mode;
@@ -94,6 +93,7 @@
/* fopts */
char const * filetype;
sox_signalinfo_t signal;
+ sox_encodinginfo_t encoding;
double volume;
double replay_gain;
rg_mode replay_gain_mode;
@@ -131,7 +131,8 @@
/* Flowing */
-static sox_signalinfo_t combiner, ofile_signal;
+static sox_signalinfo_t combiner_signal, ofile_signal;
+static sox_encodinginfo_t combiner_encoding, ofile_encoding;
static sox_size_t mixing_clips = 0;
static size_t current_input = 0;
static unsigned long input_wide_samples = 0;
@@ -158,7 +159,7 @@
if (file_count) {
if (ofile->ft) {
- if (!(ofile->ft->handler->flags & SOX_FILE_NOSTDIO)) {
+ if (!(ofile->ft->handler.flags & SOX_FILE_NOSTDIO)) {
struct stat st;
fstat(fileno(ofile->ft->fp), &st);
@@ -193,24 +194,17 @@
fprintf(output, "\n%s: '%s'",
ft->mode == 'r'? "Input File " : "Output File ", ft->filename);
- if (strcmp(ft->filename, "-") == 0 || (ft->handler->flags & SOX_FILE_DEVICE))
- fprintf(output, " (%s)", ft->handler->names[0]);
+ if (strcmp(ft->filename, "-") == 0 || (ft->handler.flags & SOX_FILE_DEVICE))
+ fprintf(output, " (%s)", ft->handler.names[0]);
fprintf(output, "\n");
- if (ft->signal.size)
- fprintf(output, "Sample Size : %s (%s)\n",
- sox_size_bits_str[ft->signal.size],
- sox_sizes_str[ft->signal.size]);
-
- if (ft->signal.encoding)
- fprintf(output, "Sample Encoding: %s\n",
- sox_encodings_str[ft->signal.encoding]);
-
fprintf(output,
"Channels : %u\n"
- "Sample Rate : %g\n",
+ "Sample Rate : %g\n"
+ "Precision : %u-bit\n",
ft->signal.channels,
- ft->signal.rate);
+ ft->signal.rate,
+ ft->signal.precision);
if (ft->length && ft->signal.channels && ft->signal.rate) {
sox_size_t ws = ft->length / ft->signal.channels;
@@ -220,16 +214,25 @@
ws, "~="[ft->signal.rate == 44100],
(double)ws/ ft->signal.rate * 44100 / 588);
}
+ if (ft->encoding.encoding) {
+ char buffer[20] = {'\0'};
+ if (ft->encoding.bits_per_sample)
+ sprintf(buffer, "%u-bit ", ft->encoding.bits_per_sample);
+
+ fprintf(output, "Sample Encoding: %s%s\n", buffer,
+ sox_encodings_str[ft->encoding.encoding]);
+ }
+
if (full) {
- if (ft->signal.size > 1)
+ if (ft->encoding.bits_per_sample > 8)
fprintf(output, "Endian Type : %s\n",
- ft->signal.reverse_bytes != SOX_IS_BIGENDIAN ? "big" : "little");
- if (ft->signal.size)
+ ft->encoding.reverse_bytes != SOX_IS_BIGENDIAN ? "big" : "little");
+ if (ft->encoding.bits_per_sample)
fprintf(output,
"Reverse Nibbles: %s\n"
"Reverse Bits : %s\n",
- no_yes[ft->signal.reverse_nibbles],
- no_yes[ft->signal.reverse_bits]);
+ no_yes[ft->encoding.reverse_nibbles],
+ no_yes[ft->encoding.reverse_bits]);
}
if (f && f->replay_gain != HUGE_VAL)
@@ -238,7 +241,7 @@
if (f && f->volume != HUGE_VAL)
fprintf(output, "Level adjust : %g (linear gain)\n" , f->volume);
- if (!(ft->handler->flags & SOX_FILE_DEVICE) && ft->comments) {
+ if (!(ft->handler.flags & SOX_FILE_DEVICE) && ft->comments) {
if (num_comments(ft->comments) > 1) {
comments_t p = ft->comments;
fprintf(output, "Comments : \n");
@@ -293,7 +296,7 @@
static sox_size_t sox_read_wide(sox_format_t * ft, sox_sample_t * buf, sox_size_t max)
{
- sox_size_t len = max / combiner.channels;
+ sox_size_t len = max / combiner_signal.channels;
len = sox_read(ft, buf, len * ft->signal.channels) / ft->signal.channels;
if (!len && ft->sox_errno)
display_error(ft);
@@ -374,7 +377,7 @@
}
for (ws = 0; ws < olen; ++ws) /* wide samples */
if (combine_method == sox_mix) { /* sum samples together */
- for (s = 0; s < effp->ininfo.channels; ++s, ++p) {
+ for (s = 0; s < effp->in_signal.channels; ++s, ++p) {
*p = 0;
for (i = 0; i < input_count; ++i)
if (ws < ilen[i] && s < files[i]->ft->signal.channels) {
@@ -390,7 +393,7 @@
}
}
read_wide_samples += olen;
- olen *= effp->ininfo.channels;
+ olen *= effp->in_signal.channels;
*osamp = olen;
return olen? SOX_SUCCESS : SOX_EOF;
}
@@ -422,10 +425,10 @@
{
size_t len;
- if (show_progress) for (len = 0; len < *isamp; len += effp->ininfo.channels) {
+ if (show_progress) for (len = 0; len < *isamp; len += effp->in_signal.channels) {
omax[0] = max(omax[0], ibuf[len]);
omin[0] = min(omin[0], ibuf[len]);
- if (effp->ininfo.channels > 1) {
+ if (effp->in_signal.channels > 1) {
omax[1] = max(omax[1], ibuf[len + 1]);
omin[1] = min(omin[1], ibuf[len + 1]);
}
@@ -471,7 +474,7 @@
/* If needed effects are not given, auto-add at (performance) optimal point. */
static void add_effects(sox_effects_chain_t * chain)
{
- sox_signalinfo_t signal = combiner;
+ sox_signalinfo_t signal = combiner_signal;
unsigned i, min_chan = 0, min_rate = 0;
sox_effect_t eff;
@@ -482,7 +485,7 @@
if (user_efftab[i].handler.flags & SOX_EFF_RATE)
min_rate = i + 1;
}
- /* 1st `effect' in the chain is the input combiner */
+ /* 1st `effect' in the chain is the input combiner_signal */
sox_create_effect(&eff, input_combiner_effect_fn());
sox_add_effect(chain, &eff, &signal, &ofile->ft->signal);
@@ -515,7 +518,7 @@
for (i = 0; i < chain->length; ++i) {
sox_effect_t const * effp = &chain->effects[i][0];
sox_report("effects chain: %-10s %gHz %u channels %u bits %s",
- effp->handler.name, effp->ininfo.rate, effp->ininfo.channels, effp->ininfo.size * 8,
+ effp->handler.name, effp->in_signal.rate, effp->in_signal.channels, effp->in_signal.precision,
(effp->handler.flags & SOX_EFF_MCHAN)? "(multi)" : "");
}
}
@@ -617,11 +620,11 @@
if (!show_progress)
return;
if (all_done || since(&then, .1, sox_false)) {
- double read_time = (double)read_wide_samples / combiner.rate;
+ double read_time = (double)read_wide_samples / combiner_signal.rate;
double left_time = 0, in_time = 0, percentage = 0;
if (input_wide_samples) {
- in_time = (double)input_wide_samples / combiner.rate;
+ in_time = (double)input_wide_samples / combiner_signal.rate;
left_time = max(in_time - read_time, 0);
percentage = max(100. * read_wide_samples / input_wide_samples, 0);
}
@@ -653,7 +656,7 @@
* gigs of audio data into managable chunks
*/
if (input_count == 1 && ofile_effects_chain.length > 1 && strcmp(ofile_effects_chain.effects[1][0].handler.name, "trim") == 0) {
- if (files[0]->ft->handler->seek && files[0]->ft->seekable){
+ if (files[0]->ft->handler.seek && files[0]->ft->seekable){
sox_size_t offset = sox_trim_get_start(&ofile_effects_chain.effects[1][0]);
if (offset && sox_seek(files[0]->ft, offset, SOX_SEEK_SET) == SOX_SUCCESS) {
read_wide_samples = offset / files[0]->ft->signal.channels;
@@ -662,6 +665,7 @@
* trim so that it thinks user didn't request a skip.
*/
sox_trim_clear_start(&ofile_effects_chain.effects[1][0]);
+ sox_debug("optimize_trim successful");
}
}
}
@@ -708,7 +712,7 @@
* FIXME: This doesn't work for multi-file processing or
* effects that change file length.
*/
- factor = (double) ofile->signal.rate / combiner.rate;
+ factor = (double) ofile->signal.rate / combiner_signal.rate;
for (i = 0; i < SOX_MAX_NLOOPS; i++) {
loops[i].start = files[0]->ft->loops[i].start * factor;
loops[i].length = files[0]->ft->loops[i].length * factor;
@@ -719,6 +723,7 @@
ofile->ft = sox_open_write(overwrite_permitted,
ofile->filename,
&ofile->signal,
+ &ofile->encoding,
ofile->filetype,
comments,
olen,
@@ -735,8 +740,8 @@
* progress display to match behavior of ogg123,
* unless the user requested us not to display anything. */
if (show_progress == SOX_OPTION_DEFAULT)
- show_progress = (ofile->ft->handler->flags & SOX_FILE_DEVICE) != 0 &&
- (ofile->ft->handler->flags & SOX_FILE_PHONY) == 0;
+ show_progress = (ofile->ft->handler.flags & SOX_FILE_DEVICE) != 0 &&
+ (ofile->ft->handler.flags & SOX_FILE_PHONY) == 0;
report_file_info(ofile);
}
@@ -760,7 +765,8 @@
sox_bool known_length = combine_method != sox_sequence;
sox_size_t olen = 0;
- combiner = files[current_input]->ft->signal;
+ combiner_signal = files[current_input]->ft->signal;
+ combiner_encoding = files[current_input]->ft->encoding;
if (combine_method == sox_sequence) {
if (!current_input) for (i = 0; i < input_count; i++)
report_file_info(files[i]);
@@ -796,27 +802,34 @@
if (min_rate != max_rate)
exit(1);
- combiner.channels =
+ combiner_signal.channels =
combine_method == sox_merge? total_channels : max_channels;
}
ofile->signal = ofile_signal;
if (ofile->signal.rate == 0)
- ofile->signal.rate = combiner.rate;
- if (ofile->signal.size == 0)
- ofile->signal.size = combiner.size;
- if (ofile->signal.encoding == SOX_ENCODING_UNKNOWN)
- ofile->signal.encoding = combiner.encoding;
+ ofile->signal.rate = combiner_signal.rate;
if (ofile->signal.channels == 0) {
unsigned j;
for (j = 0; j < nuser_effects && !ofile->signal.channels; ++j)
- ofile->signal.channels = user_efftab[nuser_effects - 1 - j].outinfo.channels;
+ ofile->signal.channels = user_efftab[nuser_effects - 1 - j].out_signal.channels;
if (ofile->signal.channels == 0)
- ofile->signal.channels = combiner.channels;
+ ofile->signal.channels = combiner_signal.channels;
}
+ ofile->signal.precision = combiner_signal.precision;
- combiner.rate *= sox_effects_globals.speed;
+ combiner_signal.rate *= sox_effects_globals.speed;
+ ofile->encoding = ofile_encoding; {
+ sox_encodinginfo_t t = ofile->encoding;
+ if (!t.encoding)
+ t.encoding = combiner_encoding.encoding;
+ if (!t.bits_per_sample)
+ t.bits_per_sample = combiner_encoding.bits_per_sample;
+ if (sox_format_supports_encoding(ofile->filename, ofile->filetype, &t))
+ ofile->encoding = t;
+ }
+
for (i = 0; i < nuser_effects; i++)
known_length = known_length && !(user_efftab[i].handler.flags & SOX_EFF_LENGTH);
@@ -823,9 +836,11 @@
if (!known_length)
olen = 0;
- open_output_file((sox_size_t)(olen * ofile->signal.channels * ofile->signal.rate / combiner.rate + .5));
+ open_output_file((sox_size_t)(olen * ofile->signal.channels * ofile->signal.rate / combiner_signal.rate + .5));
ofile_effects_chain.global_info = sox_effects_globals;
+ ofile_effects_chain.in_enc = &combiner_encoding;
+ ofile_effects_chain.out_enc = &ofile->ft->encoding;
add_effects(&ofile_effects_chain);
optimize_trim();
@@ -1028,7 +1043,7 @@
free(text);
}
-static char *getoptstr = "+ac:fghimnoqr:st:uv:xABC:DLMNRSUV::X12348";
+static char *getoptstr = "+ac:fghimnoqr:st:uv:xABC:LMNRSUV::X12348";
static struct option long_options[] =
{
@@ -1141,9 +1156,9 @@
case 5:
switch (enum_option(option_index, endian_options)) {
- case ENDIAN_little: f->signal.reverse_bytes = SOX_IS_BIGENDIAN; break;
- case ENDIAN_big: f->signal.reverse_bytes = SOX_IS_LITTLEENDIAN; break;
- case ENDIAN_swap: f->signal.reverse_bytes = sox_true; break;
+ case ENDIAN_little: f->encoding.reverse_bytes = SOX_IS_BIGENDIAN; break;
+ case ENDIAN_big: f->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN; break;
+ case ENDIAN_swap: f->encoding.reverse_bytes = sox_true; break;
}
break;
@@ -1179,7 +1194,7 @@
break;
case 'R': /* Useful for regression testing. */
- repeatable_random = sox_true;
+ sox_globals.repeatable = sox_true;
break;
case 'n':
@@ -1223,42 +1238,41 @@
break;
case 'C':
- if (sscanf(optarg, "%lf %c", &f->signal.compression, &dummy) != 1) {
+ if (sscanf(optarg, "%lf %c", &f->encoding.compression, &dummy) != 1) {
sox_fail("Compression value `%s' is not a number", optarg);
exit(1);
}
break;
- case '1': f->signal.size = SOX_SIZE_BYTE; break;
- case '2': f->signal.size = SOX_SIZE_16BIT; break;
- case '3': f->signal.size = SOX_SIZE_24BIT; break;
- case '4': f->signal.size = SOX_SIZE_32BIT; break;
- case '8': f->signal.size = SOX_SIZE_64BIT; break;
+ case '1': f->encoding.bits_per_sample = 8; break;
+ case '2': f->encoding.bits_per_sample = 16; break;
+ case '3': f->encoding.bits_per_sample = 24; break;
+ case '4': f->encoding.bits_per_sample = 32; break;
+ case '8': f->encoding.bits_per_sample = 64; break;
- case 's': f->signal.encoding = SOX_ENCODING_SIGN2; break;
- case 'u': f->signal.encoding = SOX_ENCODING_UNSIGNED; break;
- case 'f': f->signal.encoding = SOX_ENCODING_FLOAT; break;
- case 'a': f->signal.encoding = SOX_ENCODING_ADPCM; break;
- case 'D': f->signal.encoding = SOX_ENCODING_MS_ADPCM; break;
- case 'i': f->signal.encoding = SOX_ENCODING_IMA_ADPCM; break;
- case 'o': f->signal.encoding = SOX_ENCODING_OKI_ADPCM; break;
- case 'g': f->signal.encoding = SOX_ENCODING_GSM; break;
+ case 's': f->encoding.encoding = SOX_ENCODING_SIGN2; break;
+ case 'u': f->encoding.encoding = SOX_ENCODING_UNSIGNED; break;
+ case 'f': f->encoding.encoding = SOX_ENCODING_FLOAT; break;
+ case 'a': f->encoding.encoding = SOX_ENCODING_MS_ADPCM; break;
+ case 'i': f->encoding.encoding = SOX_ENCODING_IMA_ADPCM; break;
+ case 'o': f->encoding.encoding = SOX_ENCODING_OKI_ADPCM; break;
+ case 'g': f->encoding.encoding = SOX_ENCODING_GSM; break;
- case 'U': f->signal.encoding = SOX_ENCODING_ULAW;
- if (f->signal.size == 0)
- f->signal.size = SOX_SIZE_BYTE;
+ case 'U': f->encoding.encoding = SOX_ENCODING_ULAW;
+ if (f->encoding.bits_per_sample == 0)
+ f->encoding.bits_per_sample = 8;
break;
- case 'A': f->signal.encoding = SOX_ENCODING_ALAW;
- if (f->signal.size == 0)
- f->signal.size = SOX_SIZE_BYTE;
+ case 'A': f->encoding.encoding = SOX_ENCODING_ALAW;
+ if (f->encoding.bits_per_sample == 0)
+ f->encoding.bits_per_sample = 8;
break;
- case 'L': f->signal.reverse_bytes = SOX_IS_BIGENDIAN; break;
- case 'B': f->signal.reverse_bytes = SOX_IS_LITTLEENDIAN; break;
- case 'x': f->signal.reverse_bytes = SOX_OPTION_YES; break;
- case 'X': f->signal.reverse_bits = SOX_OPTION_YES; break;
- case 'N': f->signal.reverse_nibbles = SOX_OPTION_YES; break;
+ case 'L': f->encoding.reverse_bytes = SOX_IS_BIGENDIAN; break;
+ case 'B': f->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN; break;
+ case 'x': f->encoding.reverse_bytes = SOX_OPTION_YES; break;
+ case 'X': f->encoding.reverse_bits = SOX_OPTION_YES; break;
+ case 'N': f->encoding.reverse_nibbles = SOX_OPTION_YES; break;
case 'S': show_progress = SOX_OPTION_YES; break;
case 'q': show_progress = SOX_OPTION_NO; break;
@@ -1327,10 +1341,7 @@
static void init_file(file_t f)
{
memset(f, 0, sizeof(*f));
- f->signal.reverse_bytes = SOX_OPTION_DEFAULT;
- f->signal.reverse_nibbles = SOX_OPTION_DEFAULT;
- f->signal.reverse_bits = SOX_OPTION_DEFAULT;
- f->signal.compression = HUGE_VAL;
+ sox_init_encodinginfo(&f->encoding);
f->volume = HUGE_VAL;
f->replay_gain = HUGE_VAL;
}
@@ -1394,7 +1405,7 @@
static int soxi1(soxi_t * type, char * filename)
{
sox_size_t ws;
- sox_format_t * ft = sox_open_read(filename, NULL, NULL);
+ sox_format_t * ft = sox_open_read(filename, NULL, NULL, NULL);
if (!ft)
return 1;
@@ -1404,8 +1415,8 @@
case channels: printf("%u\n", ft->signal.channels); break;
case samples: printf("%u\n", ws); break;
case duration: printf("%s\n", str_time((double)ws / max(ft->signal.rate, 1))); break;
- case bits: printf("%s\n", sox_size_bits_str[ft->signal.size]); break;
- case encoding: printf("%s\n", sox_encodings_str[ft->signal.encoding]); break;
+ case bits: printf("%u\n", ft->encoding.bits_per_sample); break;
+ case encoding: printf("%s\n", sox_encodings_str[ft->encoding.encoding]); break;
case annotation: if (ft->comments) {
comments_t p = ft->comments;
do printf("%s\n", *p); while (*++p);
@@ -1504,7 +1515,7 @@
/* Check for misplaced input/output-specific options */
for (i = 0; i < input_count; ++i) {
- if (files[i]->signal.compression != HUGE_VAL)
+ if (files[i]->encoding.compression != HUGE_VAL)
usage("A compression factor can be given only for an output file");
if (files[i]->comments != NULL)
usage("Comments can be given only for an output file");
@@ -1529,14 +1540,14 @@
f->signal = files[1]->ft->signal; /* input file, or from the output */
else f->signal = files[1]->signal; /* file (which is not open yet). */
}
- files[j]->ft = sox_open_read(f->filename, &f->signal, f->filetype);
+ files[j]->ft = sox_open_read(f->filename, &f->signal, &f->encoding, f->filetype);
if (!files[j]->ft)
/* sox_open_read() will call sox_warn for most errors.
* Rely on that printing something. */
exit(2);
if (show_progress == SOX_OPTION_DEFAULT &&
- (files[j]->ft->handler->flags & SOX_FILE_DEVICE) != 0 &&
- (files[j]->ft->handler->flags & SOX_FILE_PHONY) == 0)
+ (files[j]->ft->handler.flags & SOX_FILE_DEVICE) != 0 &&
+ (files[j]->ft->handler.flags & SOX_FILE_PHONY) == 0)
show_progress = SOX_OPTION_YES;
}
/* Simple heuristic to determine if replay-gain should be in album mode */
@@ -1567,12 +1578,12 @@
for (i = 0; i < input_count; i++) {
unsigned j;
for (j =0; j < nuser_effects && !files[i]->ft->signal.channels; ++j)
- files[i]->ft->signal.channels = user_efftab[j].ininfo.channels;
+ files[i]->ft->signal.channels = user_efftab[j].in_signal.channels;
if (!files[i]->ft->signal.channels)
++files[i]->ft->signal.channels;
}
- if (repeatable_random)
+ if (sox_globals.repeatable)
sox_debug("Not reseeding PRNG; randomness is repeatable");
else {
time_t t;
@@ -1582,6 +1593,7 @@
}
ofile_signal = ofile->signal;
+ ofile_encoding = ofile->encoding;
if (combine_method == sox_sequence) do {
if (ofile->ft)
sox_close(ofile->ft);
@@ -1592,8 +1604,8 @@
if (files[i]->ft->clips != 0)
sox_warn(i < input_count?"%s: input clipped %u samples" :
"%s: output clipped %u samples; decrease volume?",
- (files[i]->ft->handler->flags & SOX_FILE_DEVICE)?
- files[i]->ft->handler->names[0] : files[i]->ft->filename,
+ (files[i]->ft->handler.flags & SOX_FILE_DEVICE)?
+ files[i]->ft->handler.names[0] : files[i]->ft->filename,
files[i]->ft->clips);
if (mixing_clips > 0)
--- a/src/sox.h
+++ b/src/sox.h
@@ -68,6 +68,7 @@
typedef int32_t sox_sample_t;
/* Minimum and maximum values a sample can hold. */
+#define SOX_SAMPLE_PRECISION 32
#define SOX_SAMPLE_MAX (sox_sample_t)SOX_INT_MAX(32)
#define SOX_SAMPLE_MIN (sox_sample_t)SOX_INT_MIN(32)
@@ -173,26 +174,30 @@
typedef enum {
SOX_ENCODING_UNKNOWN ,
+
+ SOX_ENCODING_SIGN2 , /* signed linear 2's comp: Mac */
+ SOX_ENCODING_UNSIGNED , /* unsigned linear: Sound Blaster */
+ SOX_ENCODING_FLOAT , /* floating point (binary format) */
+ SOX_ENCODING_FLOAT_TEXT, /* floating point (text format) */
+ SOX_ENCODING_FLAC , /* FLAC compression */
+ SOX_ENCODING_HCOM , /* */
+ SOX_ENCODING_LOSSLESS , /* Lossless above, lossy below */
+
SOX_ENCODING_ULAW , /* u-law signed logs: US telephony, SPARC */
SOX_ENCODING_ALAW , /* A-law signed logs: non-US telephony */
- SOX_ENCODING_ADPCM , /* G72x Compressed PCM */
+ SOX_ENCODING_G721 , /* G.721 4-bit ADPCM */
+ SOX_ENCODING_G723 , /* G.723 3 or 5 bit ADPCM */
SOX_ENCODING_MS_ADPCM , /* Microsoft Compressed PCM */
SOX_ENCODING_IMA_ADPCM , /* IMA Compressed PCM */
SOX_ENCODING_OKI_ADPCM , /* Dialogic/OKI Compressed PCM */
-
- SOX_ENCODING_SIZE_IS_WORD, /* FIXME: marks raw types (above) that mis-report size. sox_signalinfo_t really needs a precision_in_bits item */
-
- SOX_ENCODING_UNSIGNED , /* unsigned linear: Sound Blaster */
- SOX_ENCODING_SIGN2 , /* signed linear 2's comp: Mac */
- SOX_ENCODING_FLOAT , /* 32-bit float */
SOX_ENCODING_GSM , /* GSM 6.10 33byte frame lossy compression */
SOX_ENCODING_MP3 , /* MP3 compression */
SOX_ENCODING_VORBIS , /* Vorbis compression */
- SOX_ENCODING_FLAC , /* FLAC compression */
SOX_ENCODING_AMR_WB , /* AMR-WB compression */
SOX_ENCODING_AMR_NB , /* AMR-NB compression */
-
+ SOX_ENCODING_CVSD , /* */
+ SOX_ENCODING_LPC10 , /* */
SOX_ENCODINGS /* End of list marker */
} sox_encoding_t;
@@ -199,38 +204,41 @@
typedef enum {sox_plot_off, sox_plot_octave, sox_plot_gnuplot} sox_plot_t;
typedef enum {SOX_OPTION_NO, SOX_OPTION_YES, SOX_OPTION_DEFAULT} sox_option_t;
-/* Signal parameters */
-typedef struct sox_signalinfo
-{
- sox_rate_t rate; /* sampling rate */
- unsigned channels; /* number of sound channels */
- unsigned size; /* compressed or uncompressed datum size */
- sox_encoding_t encoding; /* format of sample numbers */
- double compression; /* compression factor (where applicable) */
-
- /* There is a delineation between these vars being tri-state and
- * effectively boolean. Logically the line falls between setting
- * them up (could be done in libSoX, or by the libSoX client) and
- * using them (in libSoX). libSoX's logic to set them up includes
- * knowledge of the machine default and the format default. (The
- * sox client logic adds to this a layer of overridability via user
- * options.) The physical delineation is in the somewhat
- * snappily-named libSoX function `set_endianness_if_not_already_set'
- * which is called at the right times (as files are openned) by the
- * libSoX core, not by the file handlers themselves. The file handlers
- * indicate to the libSoX core if they have a preference using
- * SOX_FILE_xxx flags.
- */
- sox_option_t reverse_bytes; /* endiannesses... */
- sox_option_t reverse_nibbles;
- sox_option_t reverse_bits;
+typedef struct { /* Signal parameters; 0 if unknown */
+ sox_rate_t rate; /* sampling rate */
+ unsigned channels; /* number of sound channels */
+ unsigned precision; /* in bits */
} sox_signalinfo_t;
+
+typedef struct { /* Encoding parameters */
+ sox_encoding_t encoding; /* format of sample numbers */
+ unsigned bits_per_sample; /* 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
+ double compression; /* compression factor (where applicable) */
+
+ /* There is a delineation between these vars being tri-state and
+ * effectively boolean. Logically the line falls between setting
+ * them up (could be done in libSoX, or by the libSoX client) and
+ * using them (in libSoX). libSoX's logic to set them up includes
+ * knowledge of the machine default and the format default. (The
+ * sox client logic adds to this a layer of overridability via user
+ * options.) The physical delineation is in the somewhat
+ * snappily-named libSoX function `set_endianness_if_not_already_set'
+ * which is called at the right times (as files are openned) by the
+ * libSoX core, not by the file handlers themselves. The file handlers
+ * indicate to the libSoX core if they have a preference using
+ * SOX_FILE_xxx flags.
+ */
+ sox_option_t reverse_bytes; /* endiannesses... */
+ sox_option_t reverse_nibbles;
+ sox_option_t reverse_bits;
+} sox_encodinginfo_t;
+
/* Defaults for common hardware */
#define SOX_DEFAULT_CHANNELS 2
#define SOX_DEFAULT_RATE 48000
-#define SOX_DEFAULT_SIZE SOX_SIZE_16BIT
+#define SOX_DEFAULT_PRECISION 16
#define SOX_DEFAULT_ENCODING SOX_ENCODING_SIGN2
/* Loop parameters */
@@ -290,6 +298,8 @@
sox_size_t (*write)(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len);
int (*stopwrite)(sox_format_t * ft);
int (*seek)(sox_format_t * ft, sox_size_t offset);
+ unsigned const * write_formats;
+ sox_rate_t const * write_rates;
} sox_format_handler_t;
/*
@@ -307,11 +317,13 @@
char priv[SOX_MAX_FILE_PRIVSIZE]; /* format's private data area */
sox_signalinfo_t signal; /* signal specifications */
+ sox_encodinginfo_t encoding; /* encoding specifications */
sox_instrinfo_t instr; /* instrument specification */
sox_loopinfo_t loops[SOX_MAX_NLOOPS];/* Looping specification */
sox_bool seekable; /* can seek on this file */
char mode; /* read or write mode */
- sox_size_t length; /* frames in file, or 0 if unknown. */
+ sox_size_t length; /* samples * channels in file; 0 if unknown */
+ sox_size_t olength; /* samples * channels in file; 0 if unknown */
sox_size_t clips; /* increment if clipping occurs */
char *filename; /* file name */
char *filetype; /* type of file */
@@ -319,7 +331,8 @@
FILE *fp; /* File stream pointer */
int sox_errno; /* Failure error codes */
char sox_errstr[256]; /* Extend Failure text */
- const sox_format_handler_t * handler; /* format struct for this file */
+ off_t data_start;
+ sox_format_handler_t handler; /* format struct for this file */
};
/* file flags field */
@@ -334,35 +347,37 @@
/* These two for use by libSoX handlers: */
#define SOX_FILE_LIT_END (0 + 64)
#define SOX_FILE_BIG_END (128 + 64)
-#define SOX_FILE_BIT_REV 256
-#define SOX_FILE_NIB_REV 512
+#define SOX_FILE_BIT_REV 0x0100
+#define SOX_FILE_NIB_REV 0x0200
+#define SOX_FILE_CHANS 0x1C00
+#define SOX_FILE_MONO 0x0400
+#define SOX_FILE_STEREO 0x0800
+#define SOX_FILE_QUAD 0x1000
+#define SOX_FILE_REWIND 0x2000
-/* Size field */
-#define SOX_SIZE_BYTE 1
-#define SOX_SIZE_8BIT 1
-#define SOX_SIZE_16BIT 2
-#define SOX_SIZE_24BIT 3
-#define SOX_SIZE_32BIT 4
-#define SOX_SIZE_64BIT 8
-#define SOX_INFO_SIZE_MAX 8
-
/* declared in misc.c */
-extern const char * const sox_sizes_str[];
-extern const char * const sox_size_bits_str[];
extern const char * const sox_encodings_str[];
int sox_format_init(void);
-sox_format_t * sox_open_read(const char *path, const sox_signalinfo_t *info,
- const char *filetype);
+sox_format_t * sox_open_read(
+ char const * path,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype);
+sox_bool sox_format_supports_encoding(
+ char const * path,
+ char const * filetype,
+ sox_encodinginfo_t const * encoding);
sox_format_t * sox_open_write(
sox_bool (*overwrite_permitted)(const char *filename),
- const char *path,
- const sox_signalinfo_t *info,
- const char *filetype,
- comments_t comments,
- sox_size_t length,
- const sox_instrinfo_t *instr,
- const sox_loopinfo_t *loops);
+ char const * path,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ comments_t comments,
+ sox_size_t length,
+ sox_instrinfo_t const * instr,
+ sox_loopinfo_t const * loops);
sox_size_t sox_read(sox_format_t * ft, sox_sample_t *buf, sox_size_t len);
sox_size_t sox_write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len);
int sox_close(sox_format_t * ft);
@@ -410,16 +425,18 @@
* in memory in the optimal way for any structure to be cast over it. */
char priv[SOX_MAX_EFFECT_PRIVSIZE]; /* private area for effect */
- sox_effects_globals_t *global_info; /* global parameters */
- struct sox_signalinfo ininfo; /* input signal specifications */
- struct sox_signalinfo outinfo; /* output signal specifications */
+ sox_effects_globals_t * global_info; /* global parameters */
+ sox_signalinfo_t in_signal;
+ sox_signalinfo_t out_signal;
+ sox_encodinginfo_t const * in_encoding;
+ sox_encodinginfo_t const * out_encoding;
sox_effect_handler_t handler;
- sox_sample_t *obuf; /* output buffer */
- sox_size_t obeg, oend; /* consumed, total length */
- sox_size_t imin; /* minimum input buffer size */
- sox_size_t clips; /* increment if clipping occurs */
- sox_size_t flows; /* 1 if MCHAN, # chans otherwise */
- sox_size_t flow; /* flow # */
+ sox_sample_t * obuf; /* output buffer */
+ sox_size_t obeg, oend; /* consumed, total length */
+ sox_size_t imin; /* minimum input buffer size */
+ sox_size_t clips; /* increment if clipping occurs */
+ sox_size_t flows; /* 1 if MCHAN, # chans otherwise */
+ sox_size_t flow; /* flow # */
};
sox_effect_handler_t const *sox_find_effect(char const * name);
@@ -431,9 +448,10 @@
struct sox_effects_chain;
typedef struct sox_effects_chain sox_effects_chain_t;
-sox_effects_chain_t * sox_create_effects_chain(void);
-
-int sox_add_effect(sox_effects_chain_t *, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out);
+sox_effects_chain_t * sox_create_effects_chain(
+ sox_encodinginfo_t const * in_enc,
+ sox_encodinginfo_t const * out_enc);
+int sox_add_effect( sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out);
int sox_flow_effects(sox_effects_chain_t *, int (* callback)(sox_bool all_done));
sox_size_t sox_effects_clips(sox_effects_chain_t *);
sox_size_t sox_stop_effect(sox_effects_chain_t *, sox_size_t e);
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -104,6 +104,7 @@
#define ftello ftell
#define off_t long
#endif
+assert_static(sizeof(off_t) == _FILE_OFFSET_BITS >> 3, OFF_T_BUILD_PROBLEM);
/* Digitise one cycle of a wave and store it as
* a table of samples of a specified data-type.
@@ -176,7 +177,8 @@
int sox_writef(sox_format_t * ft, float f);
#define sox_readdf(ft, d) (sox_read_df_buf(ft, d, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
int sox_writedf(sox_format_t * ft, double d);
-int sox_seeki(sox_format_t * ft, sox_ssize_t offset, int whence);
+int sox_seeki(sox_format_t * ft, sox_ssize_t to_sample, int whence);
+int sox_offset_seek(sox_format_t * ft, off_t byte_offset, sox_size_t to_sample);
sox_size_t sox_filelength(sox_format_t * ft);
int sox_flush(sox_format_t * ft);
sox_ssize_t sox_tell(sox_format_t * ft);
@@ -275,7 +277,7 @@
char const * stdout_in_use_by;
sox_output_message_handler_t output_message_handler;
char const * subsystem;
-
+ sox_bool repeatable;
} sox_globals_t;
struct sox_effects_globals /* Global parameters (for effects) */
@@ -302,6 +304,17 @@
/*------------------------------ File Handlers -------------------------------*/
+void sox_init_encodinginfo(sox_encodinginfo_t * e);
+unsigned sox_precision(sox_encoding_t encoding, unsigned pcm_size);
+int sox_check_read_params(sox_format_t * ft, unsigned channels,
+ sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+ off_t num_samples);
+sox_sample_t sox_sample_max(sox_encodinginfo_t const * encoding);
+#define SOX_FORMAT_HANDLER(name) \
+sox_format_handler_t const * sox_##name##_format_fn(void); \
+sox_format_handler_t const * sox_##name##_format_fn(void)
+#define div_bits(size, bits) (off_t)((double)(size) * 8 / bits)
+
/* Psion record header check, defined in misc.c and used in prc.c and auto.c */
extern const char prc_header[41];
int prc_checkheader(sox_format_t * ft, char *head);
@@ -323,8 +336,8 @@
int sox_rawstartwrite(sox_format_t * ft);
sox_size_t sox_rawwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t nsamp);
int sox_rawseek(sox_format_t * ft, sox_size_t offset);
-int sox_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_encoding_t encoding, unsigned size);
-#define sox_rawstartread(ft) sox_rawstart(ft, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
+int sox_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned size);
+#define sox_rawstartread(ft) sox_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
#define sox_rawstartwrite sox_rawstartread
#define sox_rawstopread NULL
#define sox_rawstopwrite NULL
@@ -371,6 +384,8 @@
unsigned length;
sox_sample_t **ibufc, **obufc; /* Channel interleave buffers */
sox_effects_globals_t global_info;
+ sox_encodinginfo_t const * in_enc;
+ sox_encodinginfo_t const * out_enc;
};
#endif
--- a/src/soxconfig.h.cmake
+++ b/src/soxconfig.h.cmake
@@ -36,3 +36,4 @@
#cmakedefine HAVE_UNISTD_H 1
#cmakedefine HAVE_VSNPRINTF 1
#cmakedefine WORDS_BIGENDIAN 1
+#define _FILE_OFFSET_BITS 32
--- a/src/soxio.c
+++ b/src/soxio.c
@@ -1,5 +1,6 @@
#include "sox_i.h"
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -19,7 +20,7 @@
static void output_message(unsigned level, const char *filename, const char *fmt, va_list ap);
-sox_globals_t sox_globals = {2, 8192, NULL, NULL, output_message, NULL};
+sox_globals_t sox_globals = {2, 8192, NULL, NULL, output_message, NULL, sox_false};
static void output_message(unsigned level, const char *filename, const char *fmt, va_list ap)
{
@@ -87,20 +88,23 @@
*/
int sox_gettype(sox_format_t * ft, sox_bool is_file_extension)
{
+ sox_format_handler_t const * handler;
+
if (!ft->filetype) {
sox_fail_errno(ft, SOX_EFMT, "unknown file type");
return SOX_EFMT;
}
- ft->handler = sox_find_format(ft->filetype, is_file_extension);
- if (!ft->handler) {
+ handler = sox_find_format(ft->filetype, is_file_extension);
+ if (!handler) {
sox_fail_errno(ft, SOX_EFMT, "unknown file type `%s'", ft->filetype);
return SOX_EFMT;
}
- if (ft->mode == 'r' && !ft->handler->startread && !ft->handler->read) {
+ ft->handler = *handler;
+ if (ft->mode == 'r' && !ft->handler.startread && !ft->handler.read) {
sox_fail_errno(ft, SOX_EFMT, "file type `%s' isn't readable", ft->filetype);
return SOX_EFMT;
}
- if (ft->mode == 'w' && !ft->handler->startwrite && !ft->handler->write) {
+ if (ft->mode == 'w' && !ft->handler.startwrite && !ft->handler.write) {
sox_fail_errno(ft, SOX_EFMT, "file type `%s' isn't writable", ft->filetype);
return SOX_EFMT;
}
@@ -125,34 +129,34 @@
void set_signal_defaults(sox_signalinfo_t * signal)
{
if (!signal->rate ) signal->rate = SOX_DEFAULT_RATE;
- if (!signal->size ) signal->size = SOX_DEFAULT_SIZE;
+ if (!signal->precision ) signal->precision = SOX_DEFAULT_PRECISION;
if (!signal->channels) signal->channels = SOX_DEFAULT_CHANNELS;
}
void set_endianness_if_not_already_set(sox_format_t * ft)
{
- if (ft->signal.reverse_bytes == SOX_OPTION_DEFAULT) {
- if (ft->handler->flags & SOX_FILE_ENDIAN)
+ if (ft->encoding.reverse_bytes == SOX_OPTION_DEFAULT) {
+ if (ft->handler.flags & SOX_FILE_ENDIAN)
{
/* Set revere_bytes if we are running on opposite endian
* machine compared to file format.
*/
- if (ft->handler->flags & SOX_FILE_ENDBIG)
- ft->signal.reverse_bytes = SOX_IS_LITTLEENDIAN;
+ if (ft->handler.flags & SOX_FILE_ENDBIG)
+ ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN;
else
- ft->signal.reverse_bytes = SOX_IS_BIGENDIAN;
+ ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN;
}
else
- ft->signal.reverse_bytes = SOX_OPTION_NO;
+ ft->encoding.reverse_bytes = SOX_OPTION_NO;
}
- if (ft->signal.reverse_bits == SOX_OPTION_DEFAULT)
- ft->signal.reverse_bits = !!(ft->handler->flags & SOX_FILE_BIT_REV);
- else if (ft->signal.reverse_bits != !!(ft->handler->flags & SOX_FILE_BIT_REV))
+ if (ft->encoding.reverse_bits == SOX_OPTION_DEFAULT)
+ ft->encoding.reverse_bits = !!(ft->handler.flags & SOX_FILE_BIT_REV);
+ else if (ft->encoding.reverse_bits != !!(ft->handler.flags & SOX_FILE_BIT_REV))
sox_report("'%s': Format options overriding file-type bit-order", ft->filename);
- if (ft->signal.reverse_nibbles == SOX_OPTION_DEFAULT)
- ft->signal.reverse_nibbles = !!(ft->handler->flags & SOX_FILE_NIB_REV);
- else if (ft->signal.reverse_nibbles != !!(ft->handler->flags & SOX_FILE_NIB_REV))
+ if (ft->encoding.reverse_nibbles == SOX_OPTION_DEFAULT)
+ ft->encoding.reverse_nibbles = !!(ft->handler.flags & SOX_FILE_NIB_REV);
+ else if (ft->encoding.reverse_nibbles != !!(ft->handler.flags & SOX_FILE_NIB_REV))
sox_report("'%s': Format options overriding file-type nibble-order", ft->filename);
}
@@ -168,51 +172,27 @@
/* check that all settings have been given */
static int sox_checkformat(sox_format_t * ft)
{
+ ft->sox_errno = SOX_SUCCESS;
- ft->sox_errno = SOX_SUCCESS;
-
- if (ft->signal.rate == 0)
- {
- sox_fail_errno(ft,SOX_EFMT,"sampling rate was not specified");
- return SOX_EOF;
- }
-
- if (!ft->signal.size)
- {
- sox_fail_errno(ft,SOX_EFMT,"data size was not specified");
- return SOX_EOF;
- }
-
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- {
- sox_fail_errno(ft,SOX_EFMT,"data encoding was not specified");
- return SOX_EOF;
- }
-
- if (ft->signal.size > SOX_INFO_SIZE_MAX)
- {
- sox_fail_errno(ft,SOX_EFMT,"data size %u is invalid", ft->signal.size);
- return SOX_EOF;
- }
-
- if (ft->signal.encoding <= 0 || ft->signal.encoding >= SOX_ENCODINGS)
- {
- sox_fail_errno(ft,SOX_EFMT,"data encoding %d is invalid", ft->signal.encoding);
- return SOX_EOF;
- }
-
- return SOX_SUCCESS;
+ if (!ft->signal.rate) {
+ sox_fail_errno(ft,SOX_EFMT,"sampling rate was not specified");
+ return SOX_EOF;
+ }
+ if (!ft->signal.precision) {
+ sox_fail_errno(ft,SOX_EFMT,"data encoding was not specified");
+ return SOX_EOF;
+ }
+ return SOX_SUCCESS;
}
-sox_format_t * sox_open_read(const char *path, const sox_signalinfo_t *info,
- const char *filetype)
+sox_format_t * sox_open_read(
+ char const * path,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype)
{
sox_format_t * ft = xcalloc(sizeof(*ft), 1);
- ft->signal.reverse_bytes =
- ft->signal.reverse_nibbles =
- ft->signal.reverse_bits = SOX_OPTION_DEFAULT;
-
ft->filename = xstrdup(path);
/* Let auto type do the work if user is not overriding. */
@@ -226,14 +206,13 @@
sox_fail("Can't open input file `%s': %s", ft->filename, ft->sox_errstr);
goto input_error;
}
- ft->signal.size = 0;
- ft->signal.encoding = SOX_ENCODING_UNKNOWN;
- ft->signal.channels = 0;
- ft->signal.compression = HUGE_VAL;
- if (info)
- ft->signal = *info;
+ if (signal)
+ ft->signal = *signal;
+ if (encoding)
+ ft->encoding = *encoding;
+ else sox_init_encodinginfo(&ft->encoding);
- if (!(ft->handler->flags & SOX_FILE_NOSTDIO))
+ if (!(ft->handler.flags & SOX_FILE_NOSTDIO))
{
/* Open file handler based on input name. Used stdin file handler
* if the filename is "-"
@@ -262,17 +241,20 @@
set_endianness_if_not_already_set(ft);
/* Read and write starters can change their formats. */
- if (ft->handler->startread && (*ft->handler->startread)(ft) != SOX_SUCCESS)
+ if (ft->handler.startread && (*ft->handler.startread)(ft) != SOX_SUCCESS)
{
sox_fail("Can't open input file `%s': %s", ft->filename, ft->sox_errstr);
goto input_error;
}
+ if (!ft->signal.precision)
+ ft->signal.precision = sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample);
+
/* Go ahead and assume 1 channel audio if nothing is detected.
* This is because libsox usually doesn't set this for mono file
* formats (for historical reasons).
*/
- if (!(ft->handler->flags & SOX_FILE_PHONY) && !ft->signal.channels)
+ if (!(ft->handler.flags & SOX_FILE_PHONY) && !ft->signal.channels)
ft->signal.channels = 1;
if (sox_checkformat(ft) )
@@ -291,150 +273,330 @@
return NULL;
}
-sox_format_t * sox_open_write(
- sox_bool (*overwrite_permitted)(const char *filename),
- const char *path,
- const sox_signalinfo_t *info,
- const char *filetype,
- comments_t comments,
- sox_size_t length,
- const sox_instrinfo_t *instr,
- const sox_loopinfo_t *loops)
+static void set_output_format(sox_format_t * ft)
{
- sox_format_t * ft = xcalloc(sizeof(*ft), 1);
- int i;
- sox_bool no_filetype_given = filetype == NULL;
+ sox_encoding_t e;
+ unsigned i, s;
+ unsigned const * encodings = ft->handler.write_formats;
+#define enc_arg(T) (T)encodings[i++]
- ft->filename = xstrdup(path);
+ if (ft->handler.write_rates){
+ if (!ft->signal.rate)
+ ft->signal.rate = ft->handler.write_rates[0];
+ else {
+ sox_rate_t r;
+ i = 0;
+ while ((r = ft->handler.write_rates[i++])) {
+ if (r == ft->signal.rate)
+ break;
+ }
+ if (r != ft->signal.rate) {
+ sox_rate_t given = ft->signal.rate, max = 0;
+ ft->signal.rate = HUGE_VAL;
+ i = 0;
+ while ((r = ft->handler.write_rates[i++])) {
+ if (r > given && r < ft->signal.rate)
+ ft->signal.rate = r;
+ else max = max(r, max);
+ }
+ if (ft->signal.rate == HUGE_VAL)
+ ft->signal.rate = max;
+ sox_warn("%s can't encode at %gHz; using %gHz", ft->handler.names[0], given, ft->signal.rate);
+ }
+ }
+ }
+ else if (!ft->signal.rate)
+ ft->signal.rate = SOX_DEFAULT_RATE;
- if (!filetype) {
- char const * extension = find_file_extension(ft->filename);
- if (extension)
- ft->filetype = xstrdup(extension);
+ if (ft->handler.flags & SOX_FILE_CHANS) {
+ if (ft->signal.channels == 1 && !(ft->handler.flags & SOX_FILE_MONO)) {
+ ft->signal.channels = (ft->handler.flags & SOX_FILE_STEREO)? 2 : 4;
+ sox_warn("%s can't encode mono; setting channels to %u", ft->handler.names[0], ft->signal.channels);
} else
- ft->filetype = xstrdup(filetype);
+ if (ft->signal.channels == 2 && !(ft->handler.flags & SOX_FILE_STEREO)) {
+ ft->signal.channels = (ft->handler.flags & SOX_FILE_QUAD)? 4 : 1;
+ sox_warn("%s can't encode stereo; setting channels to %u", ft->handler.names[0], ft->signal.channels);
+ } else
+ if (ft->signal.channels == 4 && !(ft->handler.flags & SOX_FILE_QUAD)) {
+ ft->signal.channels = (ft->handler.flags & SOX_FILE_STEREO)? 2 : 1;
+ sox_warn("%s can't encode quad; setting channels to %u", ft->handler.names[0], ft->signal.channels);
+ }
+ } else ft->signal.channels = max(ft->signal.channels, 1);
- ft->mode = 'w';
- if (sox_gettype(ft, no_filetype_given) != SOX_SUCCESS) {
- sox_fail("Can't open output file `%s': %s", ft->filename, ft->sox_errstr);
- goto output_error;
+ if (!encodings)
+ return;
+ /* If an encoding has been given, check if it supported by this handler */
+ if (ft->encoding.encoding) {
+ i = 0;
+ while ((e = enc_arg(sox_encoding_t))) {
+ if (e == ft->encoding.encoding)
+ break;
+ while (enc_arg(unsigned));
}
- ft->signal.size = 0;
- ft->signal.encoding = SOX_ENCODING_UNKNOWN;
- ft->signal.channels = 0;
- ft->signal.compression = HUGE_VAL;
- if (info)
- ft->signal = *info;
+ if (e != ft->encoding.encoding) {
+ sox_warn("%s can't encode %s", ft->handler.names[0], sox_encodings_str[ft->encoding.encoding]);
+ ft->encoding.encoding = 0;
+ }
+ else {
+ unsigned max_p = 0;
+ unsigned max_p_s = 0;
+ unsigned given_size = 0;
+ sox_bool found = sox_false;
+ if (ft->encoding.bits_per_sample)
+ given_size = ft->encoding.bits_per_sample;
+ ft->encoding.bits_per_sample = 65;
+ while ((s = enc_arg(unsigned))) {
+ if (s == given_size)
+ found = sox_true;
+ if (sox_precision(e, s) >= ft->signal.precision) {
+ if (s < ft->encoding.bits_per_sample)
+ ft->encoding.bits_per_sample = s;
+ }
+ else if (sox_precision(e, s) > max_p) {
+ max_p = sox_precision(e, s);
+ max_p_s = s;
+ }
+ }
+ if (ft->encoding.bits_per_sample == 65)
+ ft->encoding.bits_per_sample = max_p_s;
+ if (given_size) {
+ if (found)
+ ft->encoding.bits_per_sample = given_size;
+ else sox_warn("%s can't encode %s to %u-bit", ft->handler.names[0], sox_encodings_str[ft->encoding.encoding], given_size);
+ }
+ }
+ }
- if (!(ft->handler->flags & SOX_FILE_NOSTDIO))
- {
- /* Open file handler based on output name. Used stdout file handler
- * if the filename is "-"
- */
- if (!strcmp(ft->filename, "-")) {
- if (sox_globals.stdout_in_use_by) {
- sox_fail("'-' (stdout) already in use by '%s'", sox_globals.stdout_in_use_by);
- goto output_error;
- }
- sox_globals.stdout_in_use_by = "audio output";
- SET_BINARY_MODE(stdout);
- ft->fp = stdout;
+ /* If a size has been given, check if it supported by this handler */
+ if (!ft->encoding.encoding && ft->encoding.bits_per_sample) {
+ i = 0;
+ s= 0;
+ while (s != ft->encoding.bits_per_sample && (e = enc_arg(sox_encoding_t)))
+ while ((s = enc_arg(unsigned)) && s != ft->encoding.bits_per_sample);
+ if (s != ft->encoding.bits_per_sample) {
+ sox_warn("%s can't encode to %u-bit", ft->handler.names[0], ft->encoding.bits_per_sample);
+ ft->encoding.bits_per_sample = 0;
+ }
+ else ft->encoding.encoding = e;
+ }
+
+ /* Find the smallest lossless encoding with precision >= signal.precision */
+ if (!ft->encoding.encoding) {
+ ft->encoding.bits_per_sample = 65;
+ i = 0;
+ while ((e = enc_arg(sox_encoding_t)))
+ while ((s = enc_arg(unsigned)))
+ if (e < SOX_ENCODING_LOSSLESS &&
+ sox_precision(e, s) >= ft->signal.precision && s < ft->encoding.bits_per_sample) {
+ ft->encoding.encoding = e;
+ ft->encoding.bits_per_sample = s;
}
- else {
- struct stat st;
- if (!stat(ft->filename, &st) && (st.st_mode & S_IFMT) == S_IFREG &&
- (overwrite_permitted && !overwrite_permitted(ft->filename))) {
- sox_fail("Permission to overwrite '%s' denied", ft->filename);
- goto output_error;
+ }
+
+ /* Find the smallest lossy encoding with precision >= signal precision,
+ * or, if none such, the highest precision encoding */
+ if (!ft->encoding.encoding) {
+ unsigned max_p = 0;
+ sox_encoding_t max_p_e = 0;
+ unsigned max_p_s = 0;
+ i = 0;
+ while ((e = enc_arg(sox_encoding_t)))
+ do {
+ s = enc_arg(unsigned);
+ if (sox_precision(e, s) >= ft->signal.precision) {
+ if (s < ft->encoding.bits_per_sample) {
+ ft->encoding.encoding = e;
+ ft->encoding.bits_per_sample = s;
}
- if ((ft->fp = fopen(ft->filename, "wb")) == NULL) {
- sox_fail("Can't open output file `%s': %s", ft->filename,
- strerror(errno));
- goto output_error;
- }
}
-
- /* stdout tends to be line-buffered. Override this */
- /* to be Full Buffering. */
- if (setvbuf (ft->fp, NULL, _IOFBF, sizeof(char) * sox_globals.bufsiz))
- {
- sox_fail("Can't set write buffer");
- goto output_error;
+ else if (sox_precision(e, s) > max_p) {
+ max_p = sox_precision(e, s);
+ max_p_e = e;
+ max_p_s = s;
}
+ } while (s);
+ if (!ft->encoding.encoding) {
+ ft->encoding.encoding = max_p_e;
+ ft->encoding.bits_per_sample = max_p_s;
+ }
+ }
+ ft->signal.precision = min(ft->signal.precision, sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample));
+ #undef enc_arg
+}
- /* See if this file is seekable or not */
- ft->seekable = is_seekable(ft);
+sox_bool sox_format_supports_encoding(
+ char const * path,
+ char const * filetype,
+ sox_encodinginfo_t const * encoding)
+{
+ #define enc_arg(T) (T)ft.handler.write_formats[i++]
+ sox_encoding_t e;
+ unsigned i = 0, s;
+ sox_format_t ft;
+ sox_bool no_filetype_given = filetype == NULL;
+
+ assert(path);
+ assert(encoding);
+ ft.filetype = (char *)(filetype? filetype : find_file_extension(path));
+ if (sox_gettype(&ft, no_filetype_given) != SOX_SUCCESS ||
+ !ft.handler.write_formats)
+ return sox_false;
+ while ((e = enc_arg(sox_encoding_t))) {
+ if (e == encoding->encoding) {
+ while ((s = enc_arg(unsigned)))
+ if (s == encoding->bits_per_sample)
+ return sox_true;
+ break;
}
+ while (enc_arg(unsigned));
+ }
+ return sox_false;
+ #undef enc_arg
+}
- ft->comments = copy_comments(comments);
+sox_format_t * sox_open_write(
+ sox_bool (*overwrite_permitted)(const char *filename),
+ char const * path,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ comments_t comments,
+ sox_size_t length,
+ sox_instrinfo_t const * instr,
+ sox_loopinfo_t const * loops)
+{
+ sox_bool no_filetype_given = filetype == NULL;
+ sox_format_t * ft = xcalloc(sizeof(*ft), 1);
+ int i;
- if (loops)
- for (i = 0; i < SOX_MAX_NLOOPS; i++)
- ft->loops[i] = loops[i];
+ if (!path || !signal) {
+ free(ft);
+ return NULL;
+ }
- /* leave SMPTE # alone since it's absolute */
- if (instr)
- ft->instr = *instr;
+ ft->filename = xstrdup(path);
- ft->length = length;
- set_endianness_if_not_already_set(ft);
+ if (!filetype) {
+ char const * extension = find_file_extension(ft->filename);
+ if (extension)
+ ft->filetype = xstrdup(extension);
+ } else ft->filetype = xstrdup(filetype);
- /* Read and write starters can change their formats. */
- if (ft->handler->startwrite && (*ft->handler->startwrite)(ft) != SOX_SUCCESS)
- {
- sox_fail("Can't open output file `%s': %s", ft->filename, ft->sox_errstr);
- goto output_error;
- }
+ ft->mode = 'w';
+ if (sox_gettype(ft, no_filetype_given) != SOX_SUCCESS) {
+ sox_fail("Can't open output file `%s': %s", ft->filename, ft->sox_errstr);
+ goto output_error;
+ }
+ ft->signal = *signal;
+ if (encoding)
+ ft->encoding = *encoding;
+ else sox_init_encodinginfo(&ft->encoding);
- if (sox_checkformat(ft) )
- {
- sox_fail("bad output format for file %s: %s", ft->filename,
- ft->sox_errstr);
- goto output_error;
- }
+ if (!(ft->handler.flags & SOX_FILE_NOSTDIO))
+ {
+ /* Open file handler based on output name. Used stdout file handler
+ * if the filename is "-"
+ */
+ if (!strcmp(ft->filename, "-")) {
+ if (sox_globals.stdout_in_use_by) {
+ sox_fail("'-' (stdout) already in use by '%s'", sox_globals.stdout_in_use_by);
+ goto output_error;
+ }
+ sox_globals.stdout_in_use_by = "audio output";
+ SET_BINARY_MODE(stdout);
+ ft->fp = stdout;
+ }
+ else {
+ struct stat st;
+ if (!stat(ft->filename, &st) && (st.st_mode & S_IFMT) == S_IFREG &&
+ (overwrite_permitted && !overwrite_permitted(ft->filename))) {
+ sox_fail("Permission to overwrite '%s' denied", ft->filename);
+ goto output_error;
+ }
+ if ((ft->fp = fopen(ft->filename, "wb")) == NULL) {
+ sox_fail("Can't open output file `%s': %s", ft->filename,
+ strerror(errno));
+ goto output_error;
+ }
+ }
- /*
- * Bit of a hack; doesn't cover the situation where
- * codec changes audio length (e.g. 8svx, gsm):
- */
- if (info)
- ft->length = ft->length * ft->signal.rate / info->rate * ft->signal.channels / info->channels + .5;
+ /* stdout tends to be line-buffered. Override this */
+ /* to be Full Buffering. */
+ if (setvbuf (ft->fp, NULL, _IOFBF, sizeof(char) * sox_globals.bufsiz))
+ {
+ sox_fail("Can't set write buffer");
+ goto output_error;
+ }
+ /* See if this file is seekable or not */
+ ft->seekable = is_seekable(ft);
+ }
+
+ ft->comments = copy_comments(comments);
+
+ if (loops) for (i = 0; i < SOX_MAX_NLOOPS; i++)
+ ft->loops[i] = loops[i];
+
+ /* leave SMPTE # alone since it's absolute */
+ if (instr)
+ ft->instr = *instr;
+
+ ft->length = length;
+ set_endianness_if_not_already_set(ft);
+ set_output_format(ft);
+
+ /* FIXME: doesn't cover the situation where
+ * codec changes audio length (e.g. 8svx, gsm): */
+ if (signal->rate && signal->channels)
+ ft->length = ft->length * ft->signal.rate / signal->rate *
+ ft->signal.channels / signal->channels + .5;
+
+ if ((ft->handler.flags & SOX_FILE_REWIND) && !ft->length && !ft->seekable)
+ sox_warn("can't seek in output file `%s'; length in file header will be unspecified", ft->filename);
+
+ /* Read and write starters can change their formats. */
+ if (ft->handler.startwrite && (ft->handler.startwrite)(ft) != SOX_SUCCESS){
+ sox_fail("can't open output file `%s': %s", ft->filename, ft->sox_errstr);
+ goto output_error;
+ }
+
+ if (sox_checkformat(ft) == SOX_SUCCESS)
return ft;
+ sox_fail("bad format for output file `%s': %s", ft->filename, ft->sox_errstr);
output_error:
-
- free(ft->filename);
- free(ft->filetype);
- free(ft);
- return NULL;
+ free(ft->filename);
+ free(ft->filetype);
+ free(ft);
+ return NULL;
}
sox_size_t sox_read(sox_format_t * ft, sox_sample_t * buf, sox_size_t len)
{
- sox_size_t actual = ft->handler->read? (*ft->handler->read)(ft, buf, len) : 0;
+ sox_size_t actual = ft->handler.read? (*ft->handler.read)(ft, buf, len) : 0;
return (actual > len? 0 : actual);
}
sox_size_t sox_write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
- return ft->handler->write? (*ft->handler->write)(ft, buf, len) : 0;
+ ft->olength += len;
+ return ft->handler.write? (*ft->handler.write)(ft, buf, len) : 0;
}
#define TWIDDLE_BYTE(ub, type) \
do { \
- if (ft->signal.reverse_bits) \
+ if (ft->encoding.reverse_bits) \
ub = cswap[ub]; \
- if (ft->signal.reverse_nibbles) \
+ if (ft->encoding.reverse_nibbles) \
ub = ((ub & 15) << 4) | (ub >> 4); \
} while (0);
#define TWIDDLE_WORD(uw, type) \
- if (ft->signal.reverse_bytes) \
+ if (ft->encoding.reverse_bytes) \
uw = sox_swap ## type(uw);
#define TWIDDLE_FLOAT(f, type) \
- if (ft->signal.reverse_bytes) \
+ if (ft->encoding.reverse_bytes) \
sox_swapf(&f);
/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
@@ -558,21 +720,30 @@
/* N.B. The file (if any) may already have been deleted. */
int sox_close(sox_format_t * ft)
{
- int rc;
+ int rc = SOX_SUCCESS;
- if (ft->mode == 'r')
- rc = ft->handler->stopread? (*ft->handler->stopread)(ft) : SOX_SUCCESS;
- else
- rc = ft->handler->stopwrite? (*ft->handler->stopwrite)(ft) : SOX_SUCCESS;
+ if (ft->mode == 'r')
+ rc = ft->handler.stopread? (*ft->handler.stopread)(ft) : SOX_SUCCESS;
+ else {
+ if (ft->handler.flags & SOX_FILE_REWIND) {
+ if (ft->olength != ft->length && ft->seekable) {
+ rc = sox_seeki(ft, 0, 0);
+ if (rc == SOX_SUCCESS)
+ rc = ft->handler.stopwrite? (*ft->handler.stopwrite)(ft)
+ : ft->handler.startwrite?(*ft->handler.startwrite)(ft) : SOX_SUCCESS;
+ }
+ }
+ else rc = ft->handler.stopwrite? (*ft->handler.stopwrite)(ft) : SOX_SUCCESS;
+ }
- if (!(ft->handler->flags & SOX_FILE_NOSTDIO))
- fclose(ft->fp);
- free(ft->filename);
- free(ft->filetype);
- delete_comments(&ft->comments);
+ if (!(ft->handler.flags & SOX_FILE_NOSTDIO))
+ fclose(ft->fp);
+ free(ft->filename);
+ free(ft->filetype);
+ delete_comments(&ft->comments);
- free(ft);
- return rc;
+ free(ft);
+ return rc;
}
int sox_seek(sox_format_t * ft, sox_size_t offset, int whence)
@@ -584,8 +755,8 @@
/* If file is a seekable file and this handler supports seeking,
* then invoke handler's function.
*/
- if (ft->seekable && ft->handler->seek)
- return (*ft->handler->seek)(ft, offset);
+ if (ft->seekable && ft->handler.seek)
+ return (*ft->handler.seek)(ft, offset);
return SOX_EOF; /* FIXME: return SOX_EBADF */
}
--- a/src/sphere.c
+++ b/src/sphere.c
@@ -26,10 +26,9 @@
* size and encoding of samples,
* mono/stereo/quad.
*/
-static int sox_spherestartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
sphere_t sphere = (sphere_t) ft->priv;
- int rc;
char *buf;
char fldname[64], fldtype[16], fldsval[128];
int i;
@@ -36,11 +35,6 @@
sox_size_t header_size, bytes_read;
long rate;
- /* Needed for rawread() */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
/* Magic header */
if (sox_reads(ft, fldname, 8) == SOX_EOF || strncmp(fldname, "NIST_1A", 7) != 0)
{
@@ -72,10 +66,10 @@
while (strncmp(buf, "end_head", 8) != 0)
{
- if (strncmp(buf, "sample_n_bytes", 14) == 0 && !ft->signal.size)
+ if (strncmp(buf, "sample_n_bytes", 14) == 0 && !ft->encoding.bits_per_sample)
{
sscanf(buf, "%63s %15s %d", fldname, fldtype, &i);
- ft->signal.size = i;
+ ft->encoding.bits_per_sample = i << 3;
}
if (strncmp(buf, "channel_count", 13) == 0 &&
ft->signal.channels == 0)
@@ -89,10 +83,10 @@
/* Only bother looking for ulaw flag. All others
* should be caught below by default PCM check
*/
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN &&
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN &&
strncmp(fldsval,"ulaw",4) == 0)
{
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
}
if (strncmp(buf, "sample_rate ", 12) == 0 &&
@@ -105,9 +99,9 @@
{
sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval);
if (strncmp(fldsval,"01",2) == 0)
- ft->signal.reverse_bytes = SOX_IS_BIGENDIAN; /* Data is little endian. */
+ ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN; /* Data is little endian. */
else if (strncmp(fldsval,"10",2) == 0)
- ft->signal.reverse_bytes = SOX_IS_LITTLEENDIAN; /* Data is big endian. */
+ ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN; /* Data is big endian. */
}
if (sox_reads(ft, buf, header_size) == SOX_EOF)
@@ -120,19 +114,19 @@
header_size -= (strlen(buf) + 1);
}
- if (!ft->signal.size)
- ft->signal.size = SOX_SIZE_BYTE;
+ if (!ft->encoding.bits_per_sample)
+ ft->encoding.bits_per_sample = 8;
/* sample_coding is optional and is PCM if missing.
* This means encoding is signed if size = word or
* unsigned if size = byte.
*/
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
{
- if (ft->signal.size == SOX_SIZE_8BIT)
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ if (ft->encoding.bits_per_sample == 8)
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
else
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
while (header_size)
@@ -164,10 +158,10 @@
}
free(buf);
- return (SOX_SUCCESS);
+ return sox_rawstartread(ft);
}
-static int sox_spherestartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
int rc;
int x;
@@ -179,17 +173,6 @@
return (SOX_EOF);
}
- switch (ft->signal.encoding)
- {
- case SOX_ENCODING_ULAW:
- case SOX_ENCODING_SIGN2:
- case SOX_ENCODING_UNSIGNED:
- break;
- default:
- sox_fail_errno(ft,SOX_EFMT,"SPHERE format only supports ulaw and PCM data.");
- return(SOX_EOF);
- }
-
sphere->numSamples = 0;
/* Needed for rawwrite */
@@ -206,7 +189,7 @@
}
-static sox_size_t sox_spherewrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
sphere_t sphere = (sphere_t) ft->priv;
@@ -214,7 +197,7 @@
return sox_rawwrite(ft, buf, len);
}
-static int sox_spherestopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
char buf[128];
sphere_t sphere = (sphere_t) ft->priv;
@@ -222,7 +205,7 @@
if (sox_seeki(ft, 0, 0) != 0)
{
- sox_fail_errno(ft,errno,"Could not rewird output file to rewrite sphere header.");
+ sox_fail_errno(ft,errno,"Could not rewind output file to rewrite sphere header.");
return (SOX_EOF);
}
@@ -233,7 +216,7 @@
sprintf(buf, "sample_count -i %ld\n", samples);
sox_writes(ft, buf);
- sprintf(buf, "sample_n_bytes -i %d\n", ft->signal.size);
+ sprintf(buf, "sample_n_bytes -i %d\n", ft->encoding.bits_per_sample >> 3);
sox_writes(ft, buf);
sprintf(buf, "channel_count -i %d\n", ft->signal.channels);
@@ -240,7 +223,7 @@
sox_writes(ft, buf);
sprintf(buf, "sample_byte_format -s2 %s\n",
- ft->signal.reverse_bytes != SOX_IS_BIGENDIAN ? "10" : "01");
+ ft->encoding.reverse_bytes != SOX_IS_BIGENDIAN ? "10" : "01");
sox_writes(ft, buf);
rate = ft->signal.rate;
@@ -247,7 +230,7 @@
sprintf(buf, "sample_rate -i %ld\n", rate);
sox_writes(ft, buf);
- if (ft->signal.encoding == SOX_ENCODING_ULAW)
+ if (ft->encoding.encoding == SOX_ENCODING_ULAW)
sox_writes(ft, "sample_coding -s4 ulaw\n");
else
sox_writes(ft, "sample_coding -s3 pcm\n");
@@ -257,28 +240,19 @@
return (SOX_SUCCESS);
}
-/* NIST Sphere File */
-static const char *spherenames[] = {
- "sph",
- "nist",
- NULL
-};
-
-static sox_format_handler_t sox_sphere_format = {
- spherenames,
- 0,
- sox_spherestartread,
- sox_rawread,
- sox_rawstopread,
- sox_spherestartwrite,
- sox_spherewrite,
- sox_spherestopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_sphere_format_fn(void);
-
-const sox_format_handler_t *sox_sphere_format_fn(void)
+SOX_FORMAT_HANDLER(sphere)
{
- return &sox_sphere_format;
+ static char const * const names[] = {"sph", "nist", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 8, 16, 24, 32, 0,
+ SOX_ENCODING_UNSIGNED, 8, 16, 24, 32, 0,
+ SOX_ENCODING_ULAW, 8, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, 0,
+ startread, sox_rawread, sox_rawstopread,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/splice.c
+++ b/src/splice.c
@@ -142,8 +142,8 @@
splice_t p = (splice_t) effp->priv;
unsigned i;
- parse(effp, 0, effp->ininfo.rate); /* Re-parse now rate is known */
- p->buffer = xcalloc(p->max_buffer_size * effp->ininfo.channels, sizeof(*p->buffer));
+ parse(effp, 0, effp->in_signal.rate); /* Re-parse now rate is known */
+ p->buffer = xcalloc(p->max_buffer_size * effp->in_signal.channels, sizeof(*p->buffer));
p->in_pos = p->buffer_pos = p->splices_pos = 0;
p->state = p->splices_pos != p->nsplices && p->in_pos == p->splices[p->splices_pos].start;
for (i = 0; i < p->nsplices; ++i)
@@ -157,8 +157,8 @@
{
splice_t p = (splice_t) effp->priv;
sox_size_t c, idone = 0, odone = 0;
- *isamp /= effp->ininfo.channels;
- *osamp /= effp->ininfo.channels;
+ *isamp /= effp->in_signal.channels;
+ *osamp /= effp->in_signal.channels;
while (sox_true) {
copying:
@@ -168,7 +168,7 @@
p->state = 1;
goto buffering;
}
- for (c = 0; c < effp->ininfo.channels; ++c)
+ for (c = 0; c < effp->in_signal.channels; ++c)
*obuf++ = *ibuf++;
}
break;
@@ -176,18 +176,18 @@
buffering:
if (p->state == 1) {
- sox_size_t buffer_size = (2 * p->splices[p->splices_pos].overlap + p->splices[p->splices_pos].search) * effp->ininfo.channels;
+ sox_size_t buffer_size = (2 * p->splices[p->splices_pos].overlap + p->splices[p->splices_pos].search) * effp->in_signal.channels;
for (; idone < *isamp; ++idone, ++p->in_pos) {
if (p->buffer_pos == buffer_size) {
p->buffer_pos = do_splice(p->buffer,
p->splices[p->splices_pos].overlap,
p->splices[p->splices_pos].search,
- effp->ininfo.channels) * effp->ininfo.channels;
+ effp->in_signal.channels) * effp->in_signal.channels;
p->state = 2;
goto flushing;
break;
}
- for (c = 0; c < effp->ininfo.channels; ++c)
+ for (c = 0; c < effp->in_signal.channels; ++c)
p->buffer[p->buffer_pos++] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
}
break;
@@ -195,7 +195,7 @@
flushing:
if (p->state == 2) {
- sox_size_t buffer_size = (2 * p->splices[p->splices_pos].overlap + p->splices[p->splices_pos].search) * effp->ininfo.channels;
+ sox_size_t buffer_size = (2 * p->splices[p->splices_pos].overlap + p->splices[p->splices_pos].search) * effp->in_signal.channels;
for (; odone < *osamp; ++odone) {
if (p->buffer_pos == buffer_size) {
p->buffer_pos = 0;
@@ -203,7 +203,7 @@
p->state = p->splices_pos != p->nsplices && p->in_pos == p->splices[p->splices_pos].start;
goto copying;
}
- for (c = 0; c < effp->ininfo.channels; ++c)
+ for (c = 0; c < effp->in_signal.channels; ++c)
*obuf++ = SOX_FLOAT_32BIT_TO_SAMPLE(p->buffer[p->buffer_pos++], effp->clips);
}
break;
@@ -210,8 +210,8 @@
}
}
- *isamp = idone * effp->ininfo.channels;
- *osamp = odone * effp->ininfo.channels;
+ *isamp = idone * effp->in_signal.channels;
+ *osamp = odone * effp->in_signal.channels;
return SOX_SUCCESS;
}
--- a/src/stat.c
+++ b/src/stat.c
@@ -13,9 +13,10 @@
* the consequences of using this software.
*/
+#include "sox_i.h"
+
#include <math.h>
#include <string.h>
-#include "sox_i.h"
#include "FFT.h"
/* Private data for stat effect */
@@ -146,7 +147,7 @@
if (stat->fft_offset >= stat->fft_size) {
stat->fft_offset = 0;
- print_power_spectrum(stat->fft_size, effp->ininfo.rate, stat->re_in, stat->re_out);
+ print_power_spectrum(stat->fft_size, effp->in_signal.rate, stat->re_in, stat->re_out);
}
}
@@ -215,7 +216,7 @@
for (x = stat->fft_offset; x < stat->fft_size; x++)
stat->re_in[x] = 0;
- print_power_spectrum(stat->fft_size, effp->ininfo.rate, stat->re_in, stat->re_out);
+ print_power_spectrum(stat->fft_size, effp->in_signal.rate, stat->re_in, stat->re_out);
}
*osamp = 0;
@@ -266,7 +267,7 @@
fprintf(stderr, "\n\n");
/* print out the info */
fprintf(stderr, "Samples read: %12u\n", stat->read);
- fprintf(stderr, "Length (seconds): %12.6f\n", (double)stat->read/effp->ininfo.rate/effp->ininfo.channels);
+ fprintf(stderr, "Length (seconds): %12.6f\n", (double)stat->read/effp->in_signal.rate/effp->in_signal.channels);
if (stat->srms)
fprintf(stderr, "Scaled by rms: %12.6f\n", rms);
else
@@ -282,7 +283,7 @@
fprintf(stderr, "Minimum delta: %12.6f\n", stat->dmin);
fprintf(stderr, "Mean delta: %12.6f\n", stat->dsum1/(ct-1));
fprintf(stderr, "RMS delta: %12.6f\n", sqrt(stat->dsum2/(ct-1)));
- freq = sqrt(stat->dsum2/stat->sum2)*effp->ininfo.rate/(M_PI*2);
+ freq = sqrt(stat->dsum2/stat->sum2)*effp->in_signal.rate/(M_PI*2);
fprintf(stderr, "Rough frequency: %12d\n", (int)freq);
if (amp>0)
@@ -295,17 +296,17 @@
x = (float)(stat->bin[0] + stat->bin[3]) / (float)(stat->bin[1] + stat->bin[2]);
if (x >= 3.0) { /* use opposite encoding */
- if (effp->ininfo.encoding == SOX_ENCODING_UNSIGNED)
- fprintf(stderr,"\nTry: -t raw -b -s \n");
+ if (effp->in_encoding->encoding == SOX_ENCODING_UNSIGNED)
+ fprintf(stderr,"\nTry: -t raw -s -1 \n");
else
- fprintf(stderr,"\nTry: -t raw -b -u \n");
+ fprintf(stderr,"\nTry: -t raw -u -1 \n");
} else if (x <= 1.0 / 3.0)
; /* correctly decoded */
else if (x >= 0.5 && x <= 2.0) { /* use ULAW */
- if (effp->ininfo.encoding == SOX_ENCODING_ULAW)
- fprintf(stderr,"\nTry: -t raw -b -u \n");
+ if (effp->in_encoding->encoding == SOX_ENCODING_ULAW)
+ fprintf(stderr,"\nTry: -t raw -u -1 \n");
else
- fprintf(stderr,"\nTry: -t raw -b -U \n");
+ fprintf(stderr,"\nTry: -t raw -U -1 \n");
} else
fprintf(stderr, "\nCan't guess the type\n");
}
--- a/src/stretch.c
+++ b/src/stretch.c
@@ -150,7 +150,7 @@
stretch->state = input_state;
- stretch->size = (int)(effp->outinfo.rate * 0.001 * stretch->window);
+ stretch->size = (int)(effp->out_signal.rate * 0.001 * stretch->window);
/* start in the middle of an input to avoid initial fading... */
stretch->index = stretch->size / 2;
stretch->ibuf = (sox_sample_t *)xmalloc(stretch->size * sizeof(sox_sample_t));
--- a/src/sunaudio.c
+++ b/src/sunaudio.c
@@ -60,7 +60,7 @@
file->size = 1024;
file->buf = xmalloc (file->size);
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN) ft->signal.encoding = SOX_ENCODING_ULAW;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN) ft->encoding.encoding = SOX_ENCODING_ULAW;
#ifdef __SVR4
/* Read in old values, change to what we need and then send back */
@@ -78,33 +78,33 @@
/* If simple hardware detected in force data to ulaw. */
if (simple_hw)
{
- if (ft->signal.size == SOX_SIZE_BYTE)
+ if (ft->encoding.bits_per_sample == 8)
{
- if (ft->signal.encoding != SOX_ENCODING_ULAW &&
- ft->signal.encoding != SOX_ENCODING_ALAW)
+ if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
+ ft->encoding.encoding != SOX_ENCODING_ALAW)
{
sox_report("Warning: Detected simple hardware. Forcing output to ULAW");
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT)
+ else if (ft->encoding.bits_per_sample == 16)
{
sox_report("Warning: Detected simple hardware. Forcing output to ULAW");
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.bits_per_sample = 8;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
}
- if (ft->signal.size == SOX_SIZE_BYTE) {
+ if (ft->encoding.bits_per_sample == 8) {
samplesize = 8;
- if (ft->signal.encoding != SOX_ENCODING_ULAW &&
- ft->signal.encoding != SOX_ENCODING_ALAW &&
- ft->signal.encoding != SOX_ENCODING_SIGN2) {
+ if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
+ ft->encoding.encoding != SOX_ENCODING_ALAW &&
+ ft->encoding.encoding != SOX_ENCODING_SIGN2) {
sox_fail_errno(ft,SOX_EFMT,"Sun audio driver only supports ULAW, ALAW, and signed linear for bytes.");
return (SOX_EOF);
}
- if ((ft->signal.encoding == SOX_ENCODING_ULAW ||
- ft->signal.encoding == SOX_ENCODING_ALAW) &&
+ if ((ft->encoding.encoding == SOX_ENCODING_ULAW ||
+ ft->encoding.encoding == SOX_ENCODING_ALAW) &&
ft->signal.channels == 2)
{
sox_report("Warning: only support mono for ULAW and ALAW data. Forcing to mono.");
@@ -111,9 +111,9 @@
ft->signal.channels = 1;
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT) {
+ else if (ft->encoding.bits_per_sample == 16) {
samplesize = 16;
- if (ft->signal.encoding != SOX_ENCODING_SIGN2) {
+ if (ft->encoding.encoding != SOX_ENCODING_SIGN2) {
sox_fail_errno(ft,SOX_EFMT,"Sun audio driver only supports signed linear for words.");
return(SOX_EOF);
}
@@ -141,9 +141,9 @@
audio_if.record.precision = samplesize;
audio_if.record.channels = ft->signal.channels;
audio_if.record.sample_rate = ft->signal.rate;
- if (ft->signal.encoding == SOX_ENCODING_ULAW)
+ if (ft->encoding.encoding == SOX_ENCODING_ULAW)
encoding = AUDIO_ENCODING_ULAW;
- else if (ft->signal.encoding == SOX_ENCODING_ALAW)
+ else if (ft->encoding.encoding == SOX_ENCODING_ALAW)
encoding = AUDIO_ENCODING_ALAW;
else
encoding = AUDIO_ENCODING_LINEAR;
@@ -211,37 +211,37 @@
if (simple_hw)
{
- if (ft->signal.size == SOX_SIZE_BYTE)
+ if (ft->encoding.bits_per_sample == 8)
{
- if (ft->signal.encoding != SOX_ENCODING_ULAW &&
- ft->signal.encoding != SOX_ENCODING_ALAW)
+ if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
+ ft->encoding.encoding != SOX_ENCODING_ALAW)
{
sox_report("Warning: Detected simple hardware. Forcing output to ULAW");
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT)
+ else if (ft->encoding.bits_per_sample == 16)
{
sox_report("Warning: Detected simple hardware. Forcing output to ULAW");
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.bits_per_sample = 8;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
}
- if (ft->signal.size == SOX_SIZE_BYTE)
+ if (ft->encoding.bits_per_sample == 8)
{
samplesize = 8;
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_ULAW;
- else if (ft->signal.encoding != SOX_ENCODING_ULAW &&
- ft->signal.encoding != SOX_ENCODING_ALAW &&
- ft->signal.encoding != SOX_ENCODING_SIGN2) {
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
+ else if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
+ ft->encoding.encoding != SOX_ENCODING_ALAW &&
+ ft->encoding.encoding != SOX_ENCODING_SIGN2) {
sox_report("Sun Audio driver only supports ULAW, ALAW, and Signed Linear for bytes.");
sox_report("Forcing to ULAW");
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
}
- if ((ft->signal.encoding == SOX_ENCODING_ULAW ||
- ft->signal.encoding == SOX_ENCODING_ALAW) &&
+ if ((ft->encoding.encoding == SOX_ENCODING_ULAW ||
+ ft->encoding.encoding == SOX_ENCODING_ALAW) &&
ft->signal.channels == 2)
{
sox_report("Warning: only support mono for ULAW and ALAW data. Forcing to mono.");
@@ -249,20 +249,20 @@
}
}
- else if (ft->signal.size == SOX_SIZE_16BIT) {
+ else if (ft->encoding.bits_per_sample == 16) {
samplesize = 16;
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- else if (ft->signal.encoding != SOX_ENCODING_SIGN2) {
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
+ else if (ft->encoding.encoding != SOX_ENCODING_SIGN2) {
sox_report("Sun Audio driver only supports Signed Linear for words.");
sox_report("Forcing to Signed Linear");
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
}
}
else {
sox_report("Sun Audio driver only supports bytes and words");
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
samplesize = 16;
}
@@ -276,9 +276,9 @@
audio_if.play.precision = samplesize;
audio_if.play.channels = ft->signal.channels;
audio_if.play.sample_rate = ft->signal.rate;
- if (ft->signal.encoding == SOX_ENCODING_ULAW)
+ if (ft->encoding.encoding == SOX_ENCODING_ULAW)
encoding = AUDIO_ENCODING_ULAW;
- else if (ft->signal.encoding == SOX_ENCODING_ALAW)
+ else if (ft->encoding.encoding == SOX_ENCODING_ALAW)
encoding = AUDIO_ENCODING_ALAW;
else
encoding = AUDIO_ENCODING_LINEAR;
@@ -307,27 +307,19 @@
return (SOX_SUCCESS);
}
-/* Sun /dev/audio player */
-static const char *names[] = {
- "sunau",
- NULL
-};
-
-static sox_format_handler_t sox_sunau_format = {
- names,
- SOX_FILE_DEVICE,
- sox_sunstartread,
- sox_rawread,
- sox_rawstopread,
- sox_sunstartwrite,
- sox_rawwrite,
- sox_rawstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_sunau_format_fn(void);
-
-const sox_format_handler_t *sox_sunau_format_fn(void)
+SOX_FORMAT_HANDLER(sunau)
{
- return &sox_sunau_format;
+ static char const * const names[] = {"sunau", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_ULAW, 8, 0,
+ SOX_ENCODING_ALAW, 8, 0,
+ SOX_ENCODING_SIGN2, 8, 16, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_DEVICE,
+ sox_sunstartread, sox_rawread, sox_rawstopread,
+ sox_sunstartwrite, sox_rawwrite, sox_rawstopwrite,
+ NULL, write_encodings
+ };
+ return &handler;
}
--- a/src/swap.c
+++ b/src/swap.c
@@ -62,13 +62,13 @@
swap_t swap = (swap_t) effp->priv;
int i;
- if (effp->outinfo.channels == 1)
+ if (effp->out_signal.channels == 1)
{
sox_fail("Can't swap channels on mono data.");
return (SOX_EOF);
}
- if (effp->outinfo.channels == 2)
+ if (effp->out_signal.channels == 2)
{
if (swap->def_opts)
{
@@ -90,7 +90,7 @@
swap->order[1]--;
}
- if (effp->outinfo.channels == 4)
+ if (effp->out_signal.channels == 4)
{
if (swap->def_opts)
{
@@ -117,7 +117,7 @@
}
- for (i = 0; i < (int)effp->outinfo.channels; ++i)
+ for (i = 0; i < (int)effp->out_signal.channels; ++i)
if (swap->order[i] != i)
return SOX_SUCCESS;
@@ -134,7 +134,7 @@
swap_t swap = (swap_t) effp->priv;
int len, done;
- switch (effp->outinfo.channels)
+ switch (effp->out_signal.channels)
{
case 2:
/* Length to process will be buffer length / 2 since we
--- a/src/synth.c
+++ b/src/synth.c
@@ -9,10 +9,11 @@
* for the consequences of using this software.
*/
+#include "sox_i.h"
+
#include <string.h>
#include <math.h>
#include <ctype.h>
-#include "sox_i.h"
typedef enum {
synth_sine,
@@ -373,8 +374,8 @@
create_channel(&synth->getopts_channels[synth->getopts_nchannels++]);
}
- if (!effp->ininfo.channels)
- effp->ininfo.channels = synth->getopts_nchannels;
+ if (!effp->in_signal.channels)
+ effp->in_signal.channels = synth->getopts_nchannels;
return SOX_SUCCESS;
}
@@ -385,16 +386,15 @@
{
synth_t synth = (synth_t) effp->priv;
size_t i;
- int shift_for_max = (4 - min(effp->outinfo.size, 4)) << 3;
- synth->max = (SOX_SAMPLE_MAX >> shift_for_max) << shift_for_max;
+ synth->max = sox_sample_max(effp->out_encoding);
synth->samples_done = 0;
if (synth->length_str)
- if (sox_parsesamples(effp->ininfo.rate, synth->length_str, &synth->samples_to_do, 't') == NULL)
+ if (sox_parsesamples(effp->in_signal.rate, synth->length_str, &synth->samples_to_do, 't') == NULL)
return sox_usage(effp);
- synth->number_of_channels = effp->ininfo.channels;
+ synth->number_of_channels = effp->in_signal.channels;
synth->channels = xcalloc(synth->number_of_channels, sizeof(*synth->channels));
for (i = 0; i < synth->number_of_channels; ++i) {
channel_t chan = &synth->channels[i];
@@ -558,17 +558,17 @@
sox_size_t * isamp, sox_size_t * osamp)
{
synth_t synth = (synth_t) effp->priv;
- unsigned len = min(*isamp, *osamp) / effp->ininfo.channels;
+ unsigned len = min(*isamp, *osamp) / effp->in_signal.channels;
unsigned c, done;
int result = SOX_SUCCESS;
for (done = 0; done < len && result == SOX_SUCCESS; ++done) {
- for (c = 0; c < effp->ininfo.channels; c++)
- *obuf++ = do_synth(*ibuf++, synth, c, effp->ininfo.rate);
+ for (c = 0; c < effp->in_signal.channels; c++)
+ *obuf++ = do_synth(*ibuf++, synth, c, effp->in_signal.rate);
if (++synth->samples_done == synth->samples_to_do)
result = SOX_EOF;
}
- *isamp = *osamp = done * effp->ininfo.channels;
+ *isamp = *osamp = done * effp->in_signal.channels;
return result;
}
@@ -596,9 +596,9 @@
const sox_effect_handler_t *sox_synth_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "synth",
- "[len] {type [combine] [freq[-freq2] [off [ph [p1 [p2 [p3]]]]]]}",
- SOX_EFF_MCHAN | SOX_EFF_PREC, getopts, start, flow, 0, stop, kill
+ "synth", "[len] {type [combine] [freq[-freq2] [off [ph [p1 [p2 [p3]]]]]]}",
+ SOX_EFF_MCHAN | SOX_EFF_PREC |SOX_EFF_LENGTH,
+ getopts, start, flow, 0, stop, kill
};
return &handler;
}
--- a/src/tempo.c
+++ b/src/tempo.c
@@ -237,8 +237,8 @@
if (p->factor == 1)
return SOX_EFF_NULL;
- p->tempo = tempo_create(effp->ininfo.channels);
- tempo_setup(p->tempo, effp->ininfo.rate, p->quick_search, p->factor,
+ p->tempo = tempo_create(effp->in_signal.channels);
+ tempo_setup(p->tempo, effp->in_signal.rate, p->quick_search, p->factor,
p->segment_ms, p->search_ms, p->overlap_ms);
return SOX_SUCCESS;
}
@@ -249,14 +249,14 @@
priv_t * p = (priv_t *) effp->priv;
sox_size_t i;
/* odone must be size_t 'cos tempo_output arg. is. (!= sox_size_t on amd64) */
- size_t odone = *osamp /= effp->ininfo.channels;
+ size_t odone = *osamp /= effp->in_signal.channels;
float const * s = tempo_output(p->tempo, NULL, &odone);
- for (i = 0; i < odone * effp->ininfo.channels; ++i)
+ for (i = 0; i < odone * effp->in_signal.channels; ++i)
*obuf++ = SOX_FLOAT_32BIT_TO_SAMPLE(*s++, effp->clips);
if (*isamp && odone < *osamp) {
- float * t = tempo_input(p->tempo, NULL, *isamp / effp->ininfo.channels);
+ float * t = tempo_input(p->tempo, NULL, *isamp / effp->in_signal.channels);
for (i = *isamp; i; --i)
*t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
tempo_process(p->tempo);
@@ -263,7 +263,7 @@
}
else *isamp = 0;
- *osamp = odone * effp->ininfo.channels;
+ *osamp = odone * effp->in_signal.channels;
return SOX_SUCCESS;
}
--- a/src/tests.sh
+++ b/src/tests.sh
@@ -2,18 +2,22 @@
#
# SoX Regression Test script: Lossless file conversion
-# Options:
-#verbose=-V
-#all=all
-
bindir="."
builddir="."
srcdir="."
-# Allow user to override paths. Useful for testing an installed
-# sox.
+# Set options & allow user to override paths. Useful for testing an
+# installed sox.
while [ $# -ne 0 ]; do
case "$1" in
+ -V)
+ verbose=$1
+ ;;
+
+ -a) # Perform each test up to 3 times with different #s of
+ all=all # channels; probably enough coverage without this though.
+ ;;
+
--bindir=*)
bindir=`echo $1 | sed 's/.*=//'`
;;
@@ -60,8 +64,7 @@
u2 ) formatText="unsigned word" ;;
raw) formatText="float"; formatFlags="-f -4" ;;
Raw) formatText="double"; formatFlags="-f -8" ;;
- au ) formatFlags="-s" ;;
- Wav) formatFlags="-u -1" ;;
+ wav1u) formatFlags="-1 -u"; formatExt="wav" ;;
s1X ) formatText="signed byte (swap bits)"; formatExt="s1"; formatFlags="-X" ;;
s1N ) formatText="signed byte (swap nibbles)"; formatExt="s1"; formatFlags="-N" ;;
s1XN ) formatText="signed byte (swap nibbles and bits)"; formatExt="s1"; formatFlags="-X -N" ;;
@@ -68,6 +71,15 @@
esac
}
+execute() {
+ if [ "${verbose}x" != "x" ] ; then
+ echo $*
+ fi
+ cmd=$1
+ shift
+ echo $* | xargs $cmd
+}
+
convertToAndFrom () {
while [ $# != 0 ]; do
if [ "${skip}x" != "x" ] ; then
@@ -77,12 +89,9 @@
if [ "${format1_skip}x" = "x" -a "${from_skip}x" = "x" ] ; then
getFormat ${format1}; format1Ext=$formatExt; format1Text=$formatText; format1Flags=$formatFlags
getFormat $1; format2Ext=$formatExt; format2Text=$formatText; format2Flags=$formatFlags
- echo ${bindir}/sox -c $channels -r $rate -n $format1Flags input.$format1Ext synth $samples's' sin 300-3300 noise trapezium
- echo ${bindir}/sox $verbose -r $rate -c $channels $format1Flags input.$format1Ext $format2Flags intermediate.$format2Ext
- echo ${bindir}/sox $verbose -r $rate -c $channels $format2Flags intermediate.$format2Ext $format1Flags output.$format1Ext
- ${bindir}/sox -R -c $channels -r $rate -n $format1Flags input.$format1Ext synth $samples's' sin 300-3300 noise trapezium
- ${bindir}/sox $verbose -r $rate -c $channels $format1Flags input.$format1Ext $format2Flags intermediate.$format2Ext
- ${bindir}/sox $verbose -r $rate -c $channels $format2Flags intermediate.$format2Ext $format1Flags output.$format1Ext
+ execute ${bindir}/sox $verbose -R -r $rate -c $channels -n $format1Flags input.$format1Ext synth $samples's' sin 300-3300 noise trapezium
+ execute ${bindir}/sox $verbose -R -r $rate -c $channels $format1Flags input.$format1Ext $format2Flags intermediate.$format2Ext
+ execute ${bindir}/sox $verbose -R -r $rate -c $channels $format2Flags intermediate.$format2Ext $format1Flags output.$format1Ext
intermediateReference=intermediate`echo "$channels $rate $format1Flags $format1Ext $format2Flags"|tr " " "_"`.$format2Ext
# Uncomment to generate new reference files
@@ -91,7 +100,7 @@
if test -f $intermediateReference
then
- if ! cmp -s $intermediateReference intermediate.$format2Ext
+ if ! execute cmp -s $intermediateReference intermediate.$format2Ext
then
echo "*FAIL* channels=$channels \"$format1Text\" ---> \"$format2Text\"."
exit 1 # This allows failure inspection.
@@ -98,7 +107,7 @@
fi
fi
- if cmp -s input.$format1Ext output.$format1Ext
+ if execute cmp -s input.$format1Ext output.$format1Ext
then
echo "ok channels=$channels \"$format1Text\" <--> \"$format2Text\"."
else
@@ -130,12 +139,12 @@
format1=ul
convertToAndFrom ul s2 u2 s4 raw Raw dat aiff aifc flac caf sph
- format1=Wav
- convertToAndFrom Wav aiff aifc au dat sf flac caf sph
+ format1=wav1u
+ convertToAndFrom wav1u aiff aifc au dat sf flac caf sph
}
do_twochannel_formats () {
- format1=Wav
+ format1=wav1u
convertToAndFrom avr maud
(rate=8000; convertToAndFrom voc) || exit 1 # Fixed rate
(samples=23492; convertToAndFrom 8svx) || exit 1 # Even number of samples only
@@ -148,7 +157,7 @@
format1=ima
convertToAndFrom ima s2 u2 s3 u3 s4 u4 raw Raw dat au aiff aifc flac caf # FIXME: vox wav
- format1=Wav
+ format1=wav1u
convertToAndFrom smp s1 s1X s1N s1XN sndt
(rate=5512; convertToAndFrom hcom) || exit 1 # Fixed rate
@@ -183,9 +192,9 @@
${builddir}/sox_sample_test || exit 1
-# Don't test unsupported stuff
-${bindir}/sox --help | grep -q "^AUDIO FILE.*\<flac\>" || skip="flac $skip"
-${bindir}/sox --help | grep -q "^AUDIO FILE.*\<caf\>" || skip="caf $skip"
+# Don't try to test unsupported stuff
+${bindir}/sox --help|grep "^AUDIO FILE.*\<flac\>">/dev/null || skip="flac $skip"
+${bindir}/sox --help|grep "^AUDIO FILE.*\<caf\>" >/dev/null || skip="caf $skip"
rate=44100
samples=23493
--- a/src/trim.c
+++ b/src/trim.c
@@ -62,15 +62,15 @@
{
trim_t trim = (trim_t) effp->priv;
- if (sox_parsesamples(effp->ininfo.rate, trim->start_str,
+ if (sox_parsesamples(effp->in_signal.rate, trim->start_str,
&trim->start, 't') == NULL)
return sox_usage(effp);
/* Account for # of channels */
- trim->start *= effp->ininfo.channels;
+ trim->start *= effp->in_signal.channels;
if (trim->length_str)
{
- if (sox_parsesamples(effp->ininfo.rate, trim->length_str,
+ if (sox_parsesamples(effp->in_signal.rate, trim->length_str,
&trim->length, 't') == NULL)
return sox_usage(effp);
}
@@ -78,7 +78,7 @@
trim->length = 0;
/* Account for # of channels */
- trim->length *= effp->ininfo.channels;
+ trim->length *= effp->in_signal.channels;
trim->index = 0;
trim->trimmed = 0;
--- a/src/tx16w.c
+++ b/src/tx16w.c
@@ -33,12 +33,12 @@
*
*/
-#define TXMAXLEN 0x3FF80
-
+#include "sox_i.h"
#include <stdio.h>
#include <string.h>
-#include "sox_i.h"
+#define TXMAXLEN 0x3FF80
+
/* Private data for TX16 file */
typedef struct txwstuff {
sox_size_t rest; /* bytes remaining in sample file */
@@ -59,7 +59,7 @@
static const unsigned char magic1[4] = {0, 0x06, 0x10, 0xF6};
static const unsigned char magic2[4] = {0, 0x52, 0x00, 0x52};
-/* SJB: dangerous static variables */
+/* FIXME SJB: dangerous static variables */
static sox_size_t tx16w_len=0;
static sox_size_t writedone=0;
@@ -70,7 +70,7 @@
* size and encoding of samples,
* mono/stereo/quad.
*/
-static int sox_txwstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
int c;
char filetype[7];
@@ -169,8 +169,8 @@
sox_debug("Sample rate = %g", ft->signal.rate);
ft->signal.channels = 1 ; /* not sure about stereo sample data yet ??? */
- ft->signal.size = SOX_SIZE_16BIT; /* this is close enough */
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.bits_per_sample = 16; /* this is close enough */
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
return(SOX_SUCCESS);
}
@@ -182,7 +182,7 @@
* Return number of samples read.
*/
-static sox_size_t sox_txwread(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
txw_t sk = (txw_t) ft->priv;
sox_size_t done = 0;
@@ -232,7 +232,7 @@
return done;
}
-static int sox_txwstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
struct WaveHeader_ WH;
@@ -243,10 +243,6 @@
if (ft->signal.channels != 1)
sox_report("tx16w is overriding output format to 1 channel.");
ft->signal.channels = 1 ; /* not sure about stereo sample data yet ??? */
- if (ft->signal.size != SOX_SIZE_16BIT || ft->signal.encoding != SOX_ENCODING_SIGN2)
- sox_report("tx16w is overriding output format to size Signed Word format.");
- ft->signal.size = SOX_SIZE_16BIT; /* this is close enough */
- ft->signal.encoding = SOX_ENCODING_SIGN2;
/* If you have to seek around the output file */
if (! ft->seekable)
@@ -263,30 +259,32 @@
return(SOX_SUCCESS);
}
-static sox_size_t sox_txwwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
- sox_size_t i;
- sox_sample_t w1,w2;
+ sox_size_t i;
+ sox_sample_t w1,w2;
- tx16w_len += len;
- if (tx16w_len > TXMAXLEN) return 0;
-
- for (i=0;i<len;i+=2) {
- w1 = *buf++ >> 20;
- if (i+1==len)
- w2 = 0;
- else {
- w2 = *buf++ >> 20;
- }
- sox_writesb(ft, (w1 >> 4) & 0xFF);
- sox_writesb(ft, (((w1 & 0x0F) << 4) | (w2 & 0x0F)) & 0xFF);
- sox_writesb(ft, (w2 >> 4) & 0xFF);
- writedone += 3;
- }
- return(len);
+ tx16w_len += len;
+ if (tx16w_len > TXMAXLEN) {
+ sox_fail_errno(ft, SOX_EOF, "Audio too long for TX16W file");
+ return 0;
+ }
+ for (i=0;i<len;i+=2) {
+ w1 = *buf++ >> 20;
+ if (i+1==len)
+ w2 = 0;
+ else {
+ w2 = *buf++ >> 20;
+ }
+ sox_writesb(ft, (w1 >> 4) & 0xFF);
+ sox_writesb(ft, (((w1 & 0x0F) << 4) | (w2 & 0x0F)) & 0xFF);
+ sox_writesb(ft, (w2 >> 4) & 0xFF);
+ writedone += 3;
+ }
+ return(len);
}
-static int sox_txwstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
struct WaveHeader_ WH;
int AttackLength, LoopLength, i;
@@ -363,27 +361,15 @@
return(SOX_SUCCESS);
}
-/* Yamaha TX16W and SY99 waves */
-static const char *txwnames[] = {
- "txw",
- NULL
-};
-
-static sox_format_handler_t sox_txw_format = {
- txwnames,
- 0,
- sox_txwstartread,
- sox_txwread,
- NULL,
- sox_txwstartwrite,
- sox_txwwrite,
- sox_txwstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_txw_format_fn(void);
-
-const sox_format_handler_t *sox_txw_format_fn(void)
+SOX_FORMAT_HANDLER(txw)
{
- return &sox_txw_format;
+ static char const * const names[] = {"txw", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 16, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, 0,
+ startread, read_samples, NULL,
+ startwrite, write_samples, stopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/u1-fmt.c
+++ b/src/u1-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX u1 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT3(u1, "ub", "sou", "fssd", 8BIT, 0, UNSIGNED)
+RAW_FORMAT3(u1, "ub", "sou", "fssd", 8, 0, UNSIGNED)
--- a/src/u2-fmt.c
+++ b/src/u2-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX u2 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT1(u2, "uw", 16BIT, 0, UNSIGNED)
+RAW_FORMAT1(u2, "uw", 16, 0, UNSIGNED)
--- a/src/u3-fmt.c
+++ b/src/u3-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX u3 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(u3, 24BIT, 0, UNSIGNED)
+RAW_FORMAT(u3, 24, 0, UNSIGNED)
--- a/src/u4-fmt.c
+++ b/src/u4-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX u4 raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(u4, 32BIT, 0, UNSIGNED)
+RAW_FORMAT(u4, 32, 0, UNSIGNED)
--- a/src/ul-fmt.c
+++ b/src/ul-fmt.c
@@ -1,14 +1,22 @@
/*
- * libSoX ul raw file format
+ * File formats: raw (c) 2007-8 SoX contributors
*
- * Copyright 2007 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "raw.h"
-RAW_FORMAT(ul, 8BIT, 0, ULAW)
+RAW_FORMAT(ul, 8, 0, ULAW)
--- a/src/voc.c
+++ b/src/voc.c
@@ -258,12 +258,12 @@
}
/* setup word length of data */
- ft->signal.size = v->size;
+ ft->encoding.bits_per_sample = v->size;
/* ANN: Check VOC format and map to the proper libSoX format value */
switch (v->format) {
case VOC_FMT_LIN8U: /* 0 8 bit unsigned linear PCM */
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
break;
case VOC_FMT_CRLADPCM4: /* 1 Creative 8-bit to 4-bit ADPCM */
sox_fail ("Unsupported VOC format CRLADPCM4 %d", v->format);
@@ -278,13 +278,13 @@
rtn=SOX_EOF;
break;
case VOC_FMT_LIN16: /* 4 16-bit signed PCM */
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
break;
case VOC_FMT_ALAW: /* 6 CCITT a-Law 8-bit PCM */
- ft->signal.encoding = SOX_ENCODING_ALAW;
+ ft->encoding.encoding = SOX_ENCODING_ALAW;
break;
case VOC_FMT_MU255: /* 7 CCITT u-Law 8-bit PCM */
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
break;
case VOC_FMT_CRLADPCM4A: /*0x200 Creative 16-bit to 4-bit ADPCM */
sox_fail ("Unsupported VOC format CRLADPCM4A %d", v->format);
@@ -360,7 +360,7 @@
/* Read the data in the file */
switch(v->size) {
- case SOX_SIZE_BYTE:
+ case 8:
if (sox_readb(ft, &uc) == SOX_EOF) {
sox_warn("VOC input: short file");
v->rest = 0;
@@ -376,7 +376,7 @@
*buf++ = SOX_UNSIGNED_8BIT_TO_SAMPLE(uc,);
}
break;
- case SOX_SIZE_16BIT:
+ case 16:
sox_readw(ft, (unsigned short *)&sw);
if (sox_eof(ft))
{
@@ -428,10 +428,6 @@
sox_writew(ft, 0x10a); /* major/minor version number */
sox_writew(ft, 0x1129); /* checksum of version number */
- if (ft->signal.size == SOX_SIZE_BYTE)
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- else
- ft->signal.encoding = SOX_ENCODING_SIGN2;
if (ft->signal.channels == 0)
ft->signal.channels = 1;
@@ -455,7 +451,7 @@
}
v->samples += len;
while(done < len) {
- if (ft->signal.size == SOX_SIZE_BYTE) {
+ if (ft->encoding.bits_per_sample == 8) {
uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips);
sox_writeb(ft, uc);
} else {
@@ -482,17 +478,17 @@
if (v->silent) {
sox_writesw(ft, v->samples);
} else {
- if (ft->signal.size == SOX_SIZE_BYTE) {
+ if (ft->encoding.bits_per_sample == 8) {
if (ft->signal.channels > 1) {
sox_seeki(ft, 8, 1); /* forward 7 + 1 for new block header */
}
}
v->samples += 2; /* adjustment: SBDK pp. 3-5 */
- datum = (v->samples * ft->signal.size) & 0xff;
+ datum = (v->samples * (ft->encoding.bits_per_sample >> 3)) & 0xff;
sox_writesb(ft, datum); /* low byte of length */
- datum = ((v->samples * ft->signal.size) >> 8) & 0xff;
+ datum = ((v->samples * (ft->encoding.bits_per_sample >> 3)) >> 8) & 0xff;
sox_writesb(ft, datum); /* middle byte of length */
- datum = ((v->samples * ft->signal.size)>> 16) & 0xff;
+ datum = ((v->samples * (ft->encoding.bits_per_sample >> 3))>> 16) & 0xff;
sox_writesb(ft, datum); /* high byte of length */
}
}
@@ -587,7 +583,7 @@
}
v->extended = 0;
v->rest = sblen - 2;
- v->size = SOX_SIZE_BYTE;
+ v->size = 8;
return (SOX_SUCCESS);
case VOC_DATA_16:
sox_readdw(ft, &new_rate_32);
@@ -609,8 +605,8 @@
sox_readb(ft, &uc);
switch (uc)
{
- case 8: v->size = SOX_SIZE_BYTE; break;
- case 16: v->size = SOX_SIZE_16BIT; break;
+ case 8: v->size = 8; break;
+ case 16: v->size = 16; break;
default:
sox_fail_errno(ft,SOX_EFMT,
"Don't understand size %d", uc);
@@ -751,7 +747,7 @@
sox_writeb(ft, 0); /* Period length */
sox_writesb(ft, v->rate); /* Rate code */
} else {
- if (ft->signal.size == SOX_SIZE_BYTE) {
+ if (ft->encoding.bits_per_sample == 8) {
/* 8-bit sample section. By always setting the correct */
/* rate value in the DATA block (even when its preceeded */
/* by an EXTENDED block) old software can still play stereo */
@@ -793,27 +789,18 @@
}
}
-/* Sound Blaster .VOC */
-static const char *vocnames[] = {
- "voc",
- NULL
-};
-
-static sox_format_handler_t sox_voc_format = {
- vocnames,
- SOX_FILE_LIT_END,
- sox_vocstartread,
- sox_vocread,
- NULL,
- sox_vocstartwrite,
- sox_vocwrite,
- sox_vocstopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_voc_format_fn(void);
-
-const sox_format_handler_t *sox_voc_format_fn(void)
+SOX_FORMAT_HANDLER(voc)
{
- return &sox_voc_format;
+ static char const * const names[] = {"voc", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 0,
+ SOX_ENCODING_UNSIGNED, 8, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_LIT_END|SOX_FILE_MONO|SOX_FILE_STEREO,
+ sox_vocstartread, sox_vocread, NULL,
+ sox_vocstartwrite, sox_vocwrite, sox_vocstopwrite,
+ NULL, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/vorbis.c
+++ b/src/vorbis.c
@@ -117,8 +117,7 @@
/* Record audio info */
ft->signal.rate = vi->rate;
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_VORBIS;
+ ft->encoding.encoding = SOX_ENCODING_VORBIS;
ft->signal.channels = vi->channels;
/* ov_pcm_total doesn't work on non-seekable files so
@@ -178,7 +177,7 @@
* Return number of samples read.
*/
-static sox_size_t read(sox_format_t * ft, sox_sample_t * buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t * buf, sox_size_t len)
{
vorbis_t vb = (vorbis_t) ft->priv;
sox_size_t i;
@@ -281,8 +280,7 @@
long rate;
double quality = 3; /* Default compression quality gives ~112kbps */
- ft->signal.size = SOX_SIZE_16BIT;
- ft->signal.encoding = SOX_ENCODING_VORBIS;
+ ft->encoding.encoding = SOX_ENCODING_VORBIS;
/* Allocate memory for all of the structures */
ve = vb->vorbis_enc_data = (vorbis_enc_t *) xmalloc(sizeof(vorbis_enc_t));
@@ -296,13 +294,13 @@
"Error setting-up Ogg Vorbis encoder; check sample-rate & # of channels");
/* Use encoding to average bit rate of VBR as specified by the -C option */
- if (ft->signal.compression != HUGE_VAL) {
- if (ft->signal.compression < -1 || ft->signal.compression > 10) {
+ if (ft->encoding.compression != HUGE_VAL) {
+ if (ft->encoding.compression < -1 || ft->encoding.compression > 10) {
sox_fail_errno(ft, SOX_EINVAL,
"Vorbis compression quality nust be between -1 and 10");
return SOX_EOF;
}
- quality = ft->signal.compression;
+ quality = ft->encoding.compression;
}
#include "vorbis1.h"
@@ -320,7 +318,7 @@
return (SOX_SUCCESS);
}
-static sox_size_t write(sox_format_t * ft, const sox_sample_t * buf,
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t * buf,
sox_size_t len)
{
vorbis_t vb = (vorbis_t) ft->priv;
@@ -377,7 +375,7 @@
vorbis_enc_t *ve = vb->vorbis_enc_data;
/* Close out the remaining data */
- write(ft, NULL, 0);
+ write_samples(ft, NULL, 0);
ogg_stream_clear(&ve->os);
vorbis_block_clear(&ve->vb);
@@ -394,16 +392,15 @@
return ov_pcm_seek(vb->vf, (ogg_int64_t)(offset / ft->signal.channels))? SOX_EOF:SOX_SUCCESS;
}
-const sox_format_handler_t *sox_vorbis_format_fn(void);
-
-const sox_format_handler_t *sox_vorbis_format_fn(void)
+SOX_FORMAT_HANDLER(vorbis)
{
static const char *names[] = {"vorbis", "ogg", NULL};
+ static unsigned encodings[] = {SOX_ENCODING_VORBIS, 0, 0};
static sox_format_handler_t handler = {
names, 0,
- startread, read, stopread,
- startwrite, write, stopwrite,
- seek
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ seek, encodings, NULL
};
return &handler;
}
--- a/src/vox-fmt.c
+++ b/src/vox-fmt.c
@@ -1,32 +1,33 @@
/*
- * SOX file format handler for Dialogic/Oki ADPCM VOX files.
+ * File format: raw Dialogic/OKI ADPCM (c) 2007-8 SoX contributors
*
- * Copyright 1991-2007 Tony Seebregts And Sundry Contributors
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
*
- * This source code is freely redistributable and may be used for any
- * purpose. This copyright notice must be maintained.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
*
- * Tony Seebregts And Sundry Contributors are not responsible for the
- * consequences of using this software.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include "vox.h"
-
-const sox_format_handler_t *sox_vox_format_fn(void);
-const sox_format_handler_t *sox_vox_format_fn(void)
+SOX_FORMAT_HANDLER(vox)
{
- static char const * names[] = {"vox", NULL};
+ static char const * const names[] = {"vox", NULL};
+ static unsigned const write_encodings[] = {SOX_ENCODING_OKI_ADPCM, 4, 0, 0};
static sox_format_handler_t handler = {
- names, 0,
- sox_vox_start,
- sox_vox_read,
- sox_vox_stopread,
- sox_vox_start,
- sox_vox_write,
- sox_vox_stopwrite,
- NULL
+ names, SOX_FILE_MONO,
+ sox_vox_start, sox_vox_read, sox_vox_stopread,
+ sox_vox_start, sox_vox_write, sox_vox_stopwrite,
+ sox_rawseek, write_encodings, NULL
};
return &handler;
}
--- a/src/vox.c
+++ b/src/vox.c
@@ -1,5 +1,5 @@
/*
- * SOX file format handler for Dialogic/Oki ADPCM VOX files.
+ * SoX file format handler for Dialogic/Oki ADPCM VOX files.
*
* Copyright 1991-2007 Tony Seebregts And Sundry Contributors
*
--- a/src/vox.h
+++ b/src/vox.h
@@ -1,13 +1,19 @@
/*
- * SOX file format handler for Dialogic/Oki ADPCM VOX files.
+ * (c) 2007-8 SoX contributors
*
- * Copyright 1991-2007 Tony Seebregts And Sundry Contributors
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
*
- * This source code is freely redistributable and may be used for any
- * purpose. This copyright notice must be maintained.
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
*
- * Tony Seebregts And Sundry Contributors are not responsible for the
- * consequences of using this software.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
int sox_vox_start(sox_format_t * ft);
--- a/src/wav.c
+++ b/src/wav.c
@@ -11,6 +11,8 @@
*
*/
+#include "sox_i.h"
+
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -19,7 +21,6 @@
#include <unistd.h> /* For SEEK_* defines if not found in stdio */
#endif
-#include "sox_i.h"
#include "wav.h"
#include "ima_rw.h"
#include "adpcm.h"
@@ -384,12 +385,11 @@
* size and encoding of samples,
* mono/stereo/quad.
*/
-static int sox_wavstartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
wav_t wav = (wav_t) ft->priv;
char magic[5];
uint32_t len;
- int rc;
/* wave file characteristics */
uint32_t dwRiffLength;
@@ -420,11 +420,11 @@
if (strncmp("RIFX", magic, 4) == 0)
{
sox_debug("Found RIFX header");
- ft->signal.reverse_bytes = SOX_IS_LITTLEENDIAN;
+ ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN;
}
else
{
- ft->signal.reverse_bytes = SOX_IS_BIGENDIAN;
+ ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN;
}
sox_readdw(ft, &dwRiffLength);
@@ -499,68 +499,44 @@
case WAVE_FORMAT_PCM:
/* Default (-1) depends on sample size. Set that later on. */
- if (ft->signal.encoding != SOX_ENCODING_UNKNOWN && ft->signal.encoding != SOX_ENCODING_UNSIGNED &&
- ft->signal.encoding != SOX_ENCODING_SIGN2)
+ if (ft->encoding.encoding != SOX_ENCODING_UNKNOWN && ft->encoding.encoding != SOX_ENCODING_UNSIGNED &&
+ ft->encoding.encoding != SOX_ENCODING_SIGN2)
sox_report("User options overriding encoding read in .wav header");
-
- /* Needed by rawread() functions */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
break;
case WAVE_FORMAT_IMA_ADPCM:
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN || ft->signal.encoding == SOX_ENCODING_IMA_ADPCM)
- ft->signal.encoding = SOX_ENCODING_IMA_ADPCM;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_IMA_ADPCM)
+ ft->encoding.encoding = SOX_ENCODING_IMA_ADPCM;
else
sox_report("User options overriding encoding read in .wav header");
break;
case WAVE_FORMAT_ADPCM:
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN || ft->signal.encoding == SOX_ENCODING_ADPCM)
- ft->signal.encoding = SOX_ENCODING_ADPCM;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_MS_ADPCM)
+ ft->encoding.encoding = SOX_ENCODING_MS_ADPCM;
else
sox_report("User options overriding encoding read in .wav header");
break;
case WAVE_FORMAT_IEEE_FLOAT:
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN || ft->signal.encoding == SOX_ENCODING_FLOAT)
- ft->signal.encoding = SOX_ENCODING_FLOAT;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_FLOAT)
+ ft->encoding.encoding = SOX_ENCODING_FLOAT;
else
sox_report("User options overriding encoding read in .wav header");
-
- /* Needed by rawread() functions */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
break;
case WAVE_FORMAT_ALAW:
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN || ft->signal.encoding == SOX_ENCODING_ALAW)
- ft->signal.encoding = SOX_ENCODING_ALAW;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_ALAW)
+ ft->encoding.encoding = SOX_ENCODING_ALAW;
else
sox_report("User options overriding encoding read in .wav header");
-
- /* Needed by rawread() functions */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
break;
case WAVE_FORMAT_MULAW:
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN || ft->signal.encoding == SOX_ENCODING_ULAW)
- ft->signal.encoding = SOX_ENCODING_ULAW;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_ULAW)
+ ft->encoding.encoding = SOX_ENCODING_ULAW;
else
sox_report("User options overriding encoding read in .wav header");
-
- /* Needed by rawread() functions */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
break;
case WAVE_FORMAT_OKI_ADPCM:
@@ -572,8 +548,8 @@
case WAVE_FORMAT_DOLBY_AC2:
return wavfail(ft, "Dolby AC2");
case WAVE_FORMAT_GSM610:
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN || ft->signal.encoding == SOX_ENCODING_GSM )
- ft->signal.encoding = SOX_ENCODING_GSM;
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN || ft->encoding.encoding == SOX_ENCODING_GSM )
+ ft->encoding.encoding = SOX_ENCODING_GSM;
else
sox_report("User options overriding encoding read in .wav header");
break;
@@ -689,7 +665,7 @@
if (errct) sox_warn("base iCoefs differ in %d/14 positions",errct);
}
- bytespersample = SOX_SIZE_16BIT; /* AFTER de-compression */
+ bytespersample = 2; /* AFTER de-compression */
break;
case WAVE_FORMAT_IMA_ADPCM:
@@ -720,7 +696,7 @@
wav->samples = (short *)xmalloc(wChannels*wav->samplesPerBlock*sizeof(short));
- bytespersample = SOX_SIZE_16BIT; /* AFTER de-compression */
+ bytespersample = 2; /* AFTER de-compression */
break;
/* GSM formats have extended fmt chunk. Check for those cases. */
@@ -745,7 +721,7 @@
wav_format_str(wav->formatTag), wav->samplesPerBlock, 320);
return SOX_EOF;
}
- bytespersample = SOX_SIZE_16BIT; /* AFTER de-compression */
+ bytespersample = 2; /* AFTER de-compression */
len -= 2;
break;
@@ -754,57 +730,28 @@
}
+ /* User options take precedence */
+ if (!ft->encoding.bits_per_sample || ft->encoding.bits_per_sample == wBitsPerSample)
+ ft->encoding.bits_per_sample = wBitsPerSample;
+ else
+ sox_warn("User options overriding size read in .wav header");
+
+ /* Now we have enough information to set default encodings. */
switch (bytespersample)
{
+ case 1:
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
+ break;
- case SOX_SIZE_BYTE:
- /* User options take precedence */
- if (!ft->signal.size || ft->signal.size == SOX_SIZE_BYTE)
- ft->signal.size = SOX_SIZE_BYTE;
- else
- sox_warn("User options overriding size read in .wav header");
-
- /* Now we have enough information to set default encodings. */
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- break;
+ case 2: case 3: case 4:
+ if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
+ break;
- case SOX_SIZE_16BIT:
- if (!ft->signal.size || ft->signal.size == SOX_SIZE_16BIT)
- ft->signal.size = SOX_SIZE_16BIT;
- else
- sox_warn("User options overriding size read in .wav header");
-
- /* Now we have enough information to set default encodings. */
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- break;
-
- case SOX_SIZE_24BIT:
- if (!ft->signal.size || ft->signal.size == SOX_SIZE_24BIT)
- ft->signal.size = SOX_SIZE_24BIT;
- else
- sox_warn("User options overriding size read in .wav header");
-
- /* Now we have enough information to set default encodings. */
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- break;
-
- case SOX_SIZE_32BIT:
- if (!ft->signal.size || ft->signal.size == SOX_SIZE_32BIT)
- ft->signal.size = SOX_SIZE_32BIT;
- else
- sox_warn("User options overriding size read in .wav header");
-
- /* Now we have enough information to set default encodings. */
- if (ft->signal.encoding == SOX_ENCODING_UNKNOWN)
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- break;
-
default:
- sox_fail_errno(ft,SOX_EOF,"Sorry, don't understand .wav size");
- return SOX_EOF;
+ sox_fail_errno(ft,SOX_EFMT,"Sorry, don't understand .wav size");
+ return SOX_EOF;
}
/* Skip anything left over from fmt chunk */
@@ -855,8 +802,8 @@
break;
default:
- wav->numSamples = dwDataLength/ft->signal.size/ft->signal.channels;
- ft->length = wav->numSamples*ft->signal.channels;
+ wav->numSamples = div_bits(dwDataLength, ft->encoding.bits_per_sample) / ft->signal.channels;
+ ft->length = wav->numSamples * ft->signal.channels;
}
sox_debug("Reading Wave file: %s format, %d channel%s, %d samp/sec",
@@ -991,7 +938,7 @@
sox_clearerr(ft);
sox_seeki(ft,(sox_ssize_t)wav->dataStart,SEEK_SET);
}
- return SOX_SUCCESS;
+ return sox_rawstartread(ft);
}
@@ -1002,7 +949,7 @@
* Return number of samples read.
*/
-static sox_size_t sox_wavread(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
wav_t wav = (wav_t) ft->priv;
sox_size_t done;
@@ -1011,10 +958,10 @@
/* If file is in ADPCM encoding then read in multiple blocks else */
/* read as much as possible and return quickly. */
- switch (ft->signal.encoding)
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_IMA_ADPCM:
- case SOX_ENCODING_ADPCM:
+ case SOX_ENCODING_MS_ADPCM:
if (!wav->ignoreSize && len > (wav->numSamples*ft->signal.channels))
len = (wav->numSamples*ft->signal.channels);
@@ -1098,7 +1045,7 @@
* Do anything required when you stop reading samples.
* Don't close input file!
*/
-static int sox_wavstopread(sox_format_t * ft)
+static int stopread(sox_format_t * ft)
{
wav_t wav = (wav_t) ft->priv;
@@ -1110,13 +1057,13 @@
free(wav->comment);
wav->comment = NULL;
- switch (ft->signal.encoding)
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_GSM:
wavgsmdestroy(ft);
break;
case SOX_ENCODING_IMA_ADPCM:
- case SOX_ENCODING_ADPCM:
+ case SOX_ENCODING_MS_ADPCM:
break;
default:
break;
@@ -1124,7 +1071,7 @@
return SOX_SUCCESS;
}
-static int sox_wavstartwrite(sox_format_t * ft)
+static int startwrite(sox_format_t * ft)
{
wav_t wav = (wav_t) ft->priv;
int rc;
@@ -1131,9 +1078,9 @@
ft->sox_errno = SOX_SUCCESS;
- if (ft->signal.encoding != SOX_ENCODING_ADPCM &&
- ft->signal.encoding != SOX_ENCODING_IMA_ADPCM &&
- ft->signal.encoding != SOX_ENCODING_GSM)
+ if (ft->encoding.encoding != SOX_ENCODING_MS_ADPCM &&
+ ft->encoding.encoding != SOX_ENCODING_IMA_ADPCM &&
+ ft->encoding.encoding != SOX_ENCODING_GSM)
{
rc = sox_rawstartwrite(ft);
if (rc)
@@ -1142,8 +1089,9 @@
wav->numSamples = 0;
wav->dataLength = 0;
- if (!ft->seekable)
+ if (!ft->length && !ft->seekable)
sox_warn("Length in output .wav header will be wrong since can't seek to fix it");
+
rc = wavwritehdr(ft, 0); /* also calculates various wav->* info */
if (rc != 0)
return rc;
@@ -1235,6 +1183,8 @@
*/
+#define MS_UNSPEC 0x7ffff000 /* Unspecified data size (this is a kludge) */
+
static int wavwritehdr(sox_format_t * ft, int second_header)
{
wav_t wav = (wav_t) ft->priv;
@@ -1260,7 +1210,7 @@
uint32_t dwSamplesWritten=0; /* windows doesnt seem to use this*/
/* data chunk */
- uint32_t dwDataLength=0x7ffff000; /* length of sound data in bytes */
+ uint32_t dwDataLength = MS_UNSPEC; /* length of sound data in bytes */
/* end of variables written to header */
/* internal variables, intermediate values etc */
@@ -1270,74 +1220,10 @@
dwSamplesPerSecond = ft->signal.rate;
wChannels = ft->signal.channels;
-
- /* Check to see if encoding is ADPCM or not. If ADPCM
- * possibly override the size to be bytes. It isn't needed
- * by this routine will look nicer (and more correct)
- * on verbose output.
- */
- if ((ft->signal.encoding == SOX_ENCODING_ADPCM ||
- ft->signal.encoding == SOX_ENCODING_IMA_ADPCM ||
- ft->signal.encoding == SOX_ENCODING_GSM) &&
- ft->signal.size != SOX_SIZE_BYTE)
- {
- sox_report("Overriding output size to bytes for compressed data.");
- ft->signal.size = SOX_SIZE_BYTE;
- }
-
- switch (ft->signal.size)
- {
- case SOX_SIZE_BYTE:
- wBitsPerSample = 8;
- if (ft->signal.encoding != SOX_ENCODING_UNSIGNED &&
- ft->signal.encoding != SOX_ENCODING_ULAW &&
- ft->signal.encoding != SOX_ENCODING_ALAW &&
- ft->signal.encoding != SOX_ENCODING_GSM &&
- ft->signal.encoding != SOX_ENCODING_ADPCM &&
- ft->signal.encoding != SOX_ENCODING_IMA_ADPCM)
- {
- sox_report("Do not support %s with 8-bit data. Forcing to unsigned",sox_encodings_str[(unsigned char)ft->signal.encoding]);
- ft->signal.encoding = SOX_ENCODING_UNSIGNED;
- }
- break;
- case SOX_SIZE_16BIT:
- wBitsPerSample = 16;
- if (ft->signal.encoding != SOX_ENCODING_SIGN2)
- {
- sox_report("Do not support %s with 16-bit data. Forcing to Signed.",sox_encodings_str[(unsigned char)ft->signal.encoding]);
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- }
- break;
- case SOX_SIZE_24BIT:
- wBitsPerSample = 24;
- if (ft->signal.encoding != SOX_ENCODING_SIGN2)
- {
- sox_report("Do not support %s with 24-bit data. Forcing to Signed.",sox_encodings_str[(unsigned char)ft->signal.encoding]);
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- }
- break;
-
- case SOX_SIZE_32BIT:
- wBitsPerSample = 32;
- if (ft->signal.encoding != SOX_ENCODING_SIGN2 &&
- ft->signal.encoding != SOX_ENCODING_FLOAT)
- {
- sox_report("Do not support %s with 32-bit data. Forcing to Signed.",sox_encodings_str[(unsigned char)ft->signal.encoding]);
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- }
-
- break;
- default:
- sox_report("Do not support %s data in WAV files. Forcing to Signed 16-bit.",sox_sizes_str[(unsigned char)ft->signal.size]);
- ft->signal.encoding = SOX_ENCODING_SIGN2;
- ft->signal.size = SOX_SIZE_16BIT;
- wBitsPerSample = 16;
- break;
- }
-
+ wBitsPerSample = ft->encoding.bits_per_sample;
wSamplesPerBlock = 1; /* common default for PCM data */
- switch (ft->signal.encoding)
+ switch (ft->encoding.encoding)
{
case SOX_ENCODING_UNSIGNED:
case SOX_ENCODING_SIGN2:
@@ -1370,7 +1256,7 @@
wExtSize = 2;
wSamplesPerBlock = ImaSamplesIn(0, wChannels, wBlockAlign, 0);
break;
- case SOX_ENCODING_ADPCM:
+ case SOX_ENCODING_MS_ADPCM:
if (wChannels>16)
{
sox_fail_errno(ft,SOX_EOF,"Channels(%d) must be <= 16",wChannels);
@@ -1386,6 +1272,8 @@
if (wChannels!=1)
{
sox_report("Overriding GSM audio from %d channel to 1",wChannels);
+ if (!second_header)
+ ft->length /= max(1, ft->signal.channels);
wChannels = ft->signal.channels = 1;
}
wFormatTag = WAVE_FORMAT_GSM610;
@@ -1402,12 +1290,12 @@
wav->blockAlign = wBlockAlign;
wav->samplesPerBlock = wSamplesPerBlock;
- if (!second_header) { /* adjust for blockAlign */
+ if (!second_header && !ft->length) { /* adjust for blockAlign */
blocksWritten = dwDataLength/wBlockAlign;
dwDataLength = blocksWritten * wBlockAlign;
dwSamplesWritten = blocksWritten * wSamplesPerBlock;
} else { /* fixup with real length */
- dwSamplesWritten = wav->numSamples;
+ dwSamplesWritten = second_header? wav->numSamples : ft->length;
switch(wFormatTag)
{
case WAVE_FORMAT_ADPCM:
@@ -1445,7 +1333,7 @@
/* If user specified opposite swap than we think, assume they are
* asking to write a RIFX file.
*/
- if (ft->signal.reverse_bytes && SOX_IS_LITTLEENDIAN)
+ if (ft->encoding.reverse_bytes && SOX_IS_LITTLEENDIAN)
{
if (!second_header)
sox_report("Requested to swap bytes so writing RIFX header");
@@ -1534,7 +1422,7 @@
return SOX_SUCCESS;
}
-static sox_size_t sox_wavwrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
wav_t wav = (wav_t) ft->priv;
sox_ssize_t total_len = len;
@@ -1575,7 +1463,7 @@
}
}
-static int sox_wavstopwrite(sox_format_t * ft)
+static int stopwrite(sox_format_t * ft)
{
wav_t wav = (wav_t) ft->priv;
@@ -1600,8 +1488,10 @@
/* All samples are already written out. */
/* If file header needs fixing up, for example it needs the */
/* the number of samples in a field, seek back and write them here. */
+ if (ft->length && wav->numSamples == ft->length)
+ return SOX_SUCCESS;
if (!ft->seekable)
- return SOX_EOF;
+ return SOX_EOF;
if (sox_seeki(ft, 0, SEEK_SET) != 0)
{
@@ -1664,7 +1554,7 @@
}
}
-static int sox_wavseek(sox_format_t * ft, sox_size_t offset)
+static int seek(sox_format_t * ft, sox_size_t offset)
{
wav_t wav = (wav_t) ft->priv;
int new_offset, channel_block, alignment;
@@ -1700,9 +1590,9 @@
break;
default:
- new_offset = offset * ft->signal.size;
+ new_offset = offset * (ft->encoding.bits_per_sample >> 3);
/* Make sure request aligns to a channel block (ie left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
+ channel_block = ft->signal.channels * (ft->encoding.bits_per_sample >> 3);
alignment = new_offset % channel_block;
/* Most common mistaken is to compute something like
* "skip everthing upto and including this sample" so
@@ -1716,34 +1606,30 @@
if( ft->sox_errno == SOX_SUCCESS )
wav->numSamples = (ft->length / ft->signal.channels) -
- (new_offset / ft->signal.size / ft->signal.channels);
+ (new_offset / (ft->encoding.bits_per_sample >> 3) / ft->signal.channels);
}
return(ft->sox_errno);
}
-/* Microsoft RIFF */
-static const char *wavnames[] = {
- "wav",
- "wavpcm",
- NULL
-};
-
-static sox_format_handler_t sox_wav_format = {
- wavnames,
- SOX_FILE_LIT_END,
- sox_wavstartread,
- sox_wavread,
- sox_wavstopread,
- sox_wavstartwrite,
- sox_wavwrite,
- sox_wavstopwrite,
- sox_wavseek
-};
-
-const sox_format_handler_t *sox_wav_format_fn(void);
-
-const sox_format_handler_t *sox_wav_format_fn()
+SOX_FORMAT_HANDLER(wav)
{
- return &sox_wav_format;
+ static char const * const names[] = {"wav", "wavpcm", NULL};
+ static unsigned const write_encodings[] = {
+ SOX_ENCODING_SIGN2, 16, 24, 32, 0,
+ SOX_ENCODING_UNSIGNED, 8, 0,
+ SOX_ENCODING_ULAW, 8, 0,
+ SOX_ENCODING_ALAW, 8, 0,
+ SOX_ENCODING_GSM, 0,
+ SOX_ENCODING_MS_ADPCM, 4, 0,
+ SOX_ENCODING_IMA_ADPCM, 4, 0,
+ SOX_ENCODING_FLOAT, 32, 0,
+ 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_LIT_END,
+ startread, read_samples, stopread,
+ startwrite, write_samples, stopwrite,
+ seek, write_encodings, NULL
+ };
+ return &handler;
}
--- a/src/wve.c
+++ b/src/wve.c
@@ -1,216 +1,61 @@
/*
- * Psion wve format, based on the au format file. Hacked by
- * Richard Caley ([email protected])
+ * File format: Psion wve (c) 2008 [email protected]
+ *
+ * See http://filext.com/file-extension/WVE
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sox_i.h"
#include <string.h>
-#include <errno.h>
-/* Magic numbers used in Psion audio files */
-#define PSION_MAGIC "ALawSoundFile**"
-#define PSION_VERSION ((short)3856)
-#define PSION_HDRSIZE 32
+static char const ID1[18] = "ALawSoundFile**\0\017\020";
+static char const ID2[] = {0,0,0,1,0,0,0,0,0,0}; /* pad & repeat info: ignore */
-typedef struct wvepriv
- {
- uint32_t length;
- short padding;
- short repeats;
-/* For seeking */
- sox_size_t dataStart;
- } *wve_t;
-
-static void wvewriteheader(sox_format_t * ft);
-
-static int sox_wveseek(sox_format_t * ft, sox_size_t offset)
+static int start_read(sox_format_t * ft)
{
- int new_offset, channel_block, alignment;
- wve_t wve = (wve_t)ft->priv;
+ char buf[sizeof(ID1)];
+ uint32_t num_samples;
- new_offset = offset * ft->signal.size;
- /* Make sure request aligns to a channel block (i.e. left+right) */
- channel_block = ft->signal.channels * ft->signal.size;
- alignment = new_offset % channel_block;
- /* Most common mistake is to compute something like
- * "skip everthing up to and including this sample" so
- * advance to next sample block in this case.
- */
- if (alignment != 0)
- new_offset += (channel_block - alignment);
- new_offset += wve->dataStart;
-
- return sox_seeki(ft, (sox_ssize_t)offset, SEEK_SET);
+ if (sox_readbuf(ft, buf, sizeof(buf)) != sizeof(buf) ||
+ sox_readdw(ft, &num_samples) || sox_skipbytes(ft, sizeof(ID2)))
+ return SOX_EOF;
+ if (memcmp(ID1, buf, sizeof(buf))) {
+ sox_fail_errno(ft,SOX_EHDR,"wve: can't find Psion identifier");
+ return SOX_EOF;
+ }
+ return sox_check_read_params(ft, 1, 8000., SOX_ENCODING_ALAW, 8, (off_t)num_samples);
}
-static int sox_wvestartread(sox_format_t * ft)
+static int write_header(sox_format_t * ft)
{
- wve_t p = (wve_t)ft->priv;
- char magic[16];
- short version;
- int rc;
-
- uint16_t trash16;
-
- /* Needed for rawread() */
- rc = sox_rawstartread(ft);
- if (rc)
- return rc;
-
- /* Check the magic word (null-terminated) */
- sox_reads(ft, magic, 16);
- if (strncmp(magic, PSION_MAGIC, 15)==0) {
- sox_debug("Found Psion magic word");
- }
- else
- {
- sox_fail_errno(ft,SOX_EHDR,"Psion header doesn't start with magic word\nTry the '.al' file type with '-t al -r 8000 filename'");
- return (SOX_EOF);
- }
-
- sox_readw(ft, (unsigned short *)&version);
-
- /* Check magic version */
- if (version == PSION_VERSION)
- sox_debug("Found Psion magic word");
- else
- {
- sox_fail_errno(ft,SOX_EHDR,"Wrong version in Psion header");
- return(SOX_EOF);
- }
-
- sox_readdw(ft, &(p->length));
-
- sox_readw(ft, (unsigned short *)&(p->padding));
-
- sox_readw(ft, (unsigned short *)&(p->repeats));
-
- sox_readw(ft, (unsigned short *)&trash16);
- sox_readw(ft, (unsigned short *)&trash16);
- sox_readw(ft, (unsigned short *)&trash16);
-
- ft->signal.encoding = SOX_ENCODING_ALAW;
- ft->signal.size = SOX_SIZE_BYTE;
-
- if (ft->signal.rate != 0)
- sox_report("WVE must use 8000 sample rate. Overriding");
- ft->signal.rate = 8000;
-
- if (ft->signal.channels != SOX_ENCODING_UNKNOWN && ft->signal.channels != 1)
- sox_report("WVE must only supports 1 channel. Overriding");
- ft->signal.channels = 1;
-
- p->dataStart = sox_tell(ft);
- ft->length = p->length/ft->signal.size;
-
- return (SOX_SUCCESS);
+ return sox_writebuf(ft, ID1, sizeof(ID1)) != sizeof(ID1)
+ || sox_writedw(ft, ft->olength? ft->olength:ft->length)
+ || sox_writebuf(ft, ID2, sizeof(ID2)) != sizeof(ID2)? SOX_EOF:SOX_SUCCESS;
}
-/* When writing, the header is supposed to contain the number of
- data bytes written, unless it is written to a pipe.
- Since we don't know how many bytes will follow until we're done,
- we first write the header with an unspecified number of bytes,
- and at the end we rewind the file and write the header again
- with the right size. This only works if the file is seekable;
- if it is not, the unspecified size remains in the header
- (this is illegal). */
-
-static int sox_wvestartwrite(sox_format_t * ft)
+SOX_FORMAT_HANDLER(wve)
{
- wve_t p = (wve_t)ft->priv;
-
- p->length = 0;
- if (p->repeats == 0)
- p->repeats = 1;
-
- if (ft->signal.rate != 0)
- sox_report("WVE must use 8000 sample rate. Overriding");
-
- if (ft->signal.channels != 0 && ft->signal.channels != 1)
- sox_report("WVE must only supports 1 channel. Overriding");
-
- ft->signal.encoding = SOX_ENCODING_ALAW;
- ft->signal.size = SOX_SIZE_BYTE;
- ft->signal.rate = 8000;
- ft->signal.channels = 1;
-
- wvewriteheader(ft);
- return SOX_SUCCESS;
-}
-
-static sox_size_t sox_wvewrite(sox_format_t * ft, const sox_sample_t *buf, sox_size_t samp)
-{
- wve_t p = (wve_t)ft->priv;
- p->length += samp * ft->signal.size;
- return sox_rawwrite(ft, buf, samp);
-}
-
-static int sox_wvestopwrite(sox_format_t * ft)
-{
-
- if (!ft->seekable)
- {
- sox_warn("Header will be have invalid file length since file is not seekable");
- return SOX_SUCCESS;
- }
-
- if (sox_seeki(ft, 0, 0) != 0)
- {
- sox_fail_errno(ft,errno,"Can't rewind output file to rewrite Psion header.");
- return(SOX_EOF);
- }
- wvewriteheader(ft);
- return SOX_SUCCESS;
-}
-
-static void wvewriteheader(sox_format_t * ft)
-{
-
- char magic[16];
- short version;
- short zero;
- wve_t p = (wve_t)ft->priv;
-
- strcpy(magic,PSION_MAGIC);
- version=PSION_VERSION;
- zero=0;
-
- sox_writes(ft, magic);
- /* Null terminate string */
- sox_writeb(ft, 0);
-
- sox_writesw(ft, version);
-
- sox_writedw(ft, p->length);
- sox_writesw(ft, p->padding);
- sox_writesw(ft, p->repeats);
-
- sox_writesw(ft, zero);
- sox_writesw(ft, zero);
- sox_writesw(ft, zero);
-}
-
-/* Psion .wve */
-static const char *wvenames[] = {
- "wve",
- NULL
-};
-
-static sox_format_handler_t sox_wve_format = {
- wvenames,
- SOX_FILE_BIG_END,
- sox_wvestartread,
- sox_rawread,
- sox_rawstopread,
- sox_wvestartwrite,
- sox_wvewrite,
- sox_wvestopwrite,
- sox_wveseek
-};
-
-const sox_format_handler_t *sox_wve_format_fn(void);
-
-const sox_format_handler_t *sox_wve_format_fn(void)
-{
- return &sox_wve_format;
+ static char const * const names[] = {"wve", NULL};
+ static sox_rate_t const write_rates[] = {8000, 0};
+ static unsigned const write_encodings[] = {SOX_ENCODING_ALAW, 8, 0, 0};
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_BIG_END | SOX_FILE_MONO | SOX_FILE_REWIND,
+ start_read, sox_rawread, NULL,
+ write_header, sox_rawwrite, NULL,
+ sox_rawseek, write_encodings, write_rates
+ };
+ return &handler;
}
--- a/src/xa.c
+++ b/src/xa.c
@@ -23,16 +23,12 @@
/* Thanks to Valery V. Anisimovsky <[email protected]> for the
* "Maxis XA Audio File Format Description", dated 5-01-2002. */
+#include "sox_i.h"
+
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* For SEEK_* defines if not found in stdio */
-#endif
-
-#include "sox_i.h"
-
#define HNIBBLE(byte) (((byte) >> 4) & 0xf)
#define LNIBBLE(byte) ((byte) & 0xf)
@@ -89,7 +85,7 @@
}
}
-static int sox_xastartread(sox_format_t * ft)
+static int startread(sox_format_t * ft)
{
xa_t xa = (xa_t) ft->priv;
char *magic = xa->header.magic;
@@ -130,10 +126,10 @@
sox_debug(" wBits: %u", xa->header.bits);
/* Populate the sox_soundstream structure */
- ft->signal.encoding = SOX_ENCODING_SIGN2;
+ ft->encoding.encoding = SOX_ENCODING_SIGN2;
- if (!ft->signal.size || ft->signal.size == (xa->header.bits >> 3)) {
- ft->signal.size = xa->header.bits >> 3;
+ if (!ft->encoding.bits_per_sample || ft->encoding.bits_per_sample == xa->header.bits) {
+ ft->encoding.bits_per_sample = xa->header.bits;
} else {
sox_report("User options overriding size read in .xa header");
}
@@ -151,22 +147,22 @@
}
/* Check for supported formats */
- if (ft->signal.size != 2) {
+ if (ft->encoding.bits_per_sample != 16) {
sox_fail_errno(ft, SOX_EFMT, "%d-bit sample resolution not supported.",
- ft->signal.size << 3);
+ ft->encoding.bits_per_sample);
return SOX_EOF;
}
/* Validate the header */
- if (xa->header.bits != ft->signal.size << 3) {
+ if (xa->header.bits != ft->encoding.bits_per_sample) {
sox_report("Invalid sample resolution %d bits. Assuming %d bits.",
- xa->header.bits, ft->signal.size << 3);
- xa->header.bits = ft->signal.size << 3;
+ xa->header.bits, ft->encoding.bits_per_sample);
+ xa->header.bits = ft->encoding.bits_per_sample;
}
- if (xa->header.align != ft->signal.size * xa->header.channels) {
+ if (xa->header.align != (ft->encoding.bits_per_sample >> 3) * xa->header.channels) {
sox_report("Invalid sample alignment value %d. Assuming %d.",
- xa->header.align, ft->signal.size * xa->header.channels);
- xa->header.align = ft->signal.size * xa->header.channels;
+ xa->header.align, (ft->encoding.bits_per_sample >> 3) * xa->header.channels);
+ xa->header.align = (ft->encoding.bits_per_sample >> 3) * xa->header.channels;
}
if (xa->header.avgByteRate != (xa->header.align * xa->header.sampleRate)) {
sox_report("Invalid dwAvgByteRate value %d. Assuming %d.",
@@ -194,7 +190,7 @@
* Read up to len samples from a file, converted to signed longs.
* Return the number of samples read.
*/
-static sox_size_t sox_xaread(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
+static sox_size_t read_samples(sox_format_t * ft, sox_sample_t *buf, sox_size_t len)
{
xa_t xa = (xa_t) ft->priv;
int32_t sample;
@@ -243,7 +239,7 @@
xa->state[i].curSample = sample;
buf[done++] = SOX_SIGNED_16BIT_TO_SAMPLE(sample,);
- xa->bytesDecoded += ft->signal.size;
+ xa->bytesDecoded += (ft->encoding.bits_per_sample >> 3);
}
for (i = 0; i < ft->signal.channels && done < len; i++) {
/* low nibble */
@@ -257,7 +253,7 @@
xa->state[i].curSample = sample;
buf[done++] = SOX_SIGNED_16BIT_TO_SAMPLE(sample,);
- xa->bytesDecoded += ft->signal.size;
+ xa->bytesDecoded += (ft->encoding.bits_per_sample >> 3);
}
xa->bufPos += ft->signal.channels;
@@ -269,7 +265,7 @@
return done;
}
-static int sox_xastopread(sox_format_t * ft)
+static int stopread(sox_format_t * ft)
{
xa_t xa = (xa_t) ft->priv;
@@ -284,45 +280,14 @@
return SOX_SUCCESS;
}
-static int sox_xastartwrite(sox_format_t * ft)
+SOX_FORMAT_HANDLER(xa)
{
- sox_fail_errno(ft, SOX_ENOTSUP, ".XA writing not supported");
- return SOX_EOF;
-}
-
-static sox_size_t sox_xawrite(sox_format_t * ft, const sox_sample_t *buf UNUSED, sox_size_t len UNUSED)
-{
- sox_fail_errno(ft, SOX_ENOTSUP, ".XA writing not supported");
- return 0;
-}
-
-static int sox_xastopwrite(sox_format_t * ft)
-{
- sox_fail_errno(ft, SOX_ENOTSUP, ".XA writing not supported");
- return SOX_EOF;
-}
-
-/* Maxis .xa */
-static const char *xanames[] = {
- "xa",
- NULL
-};
-
-sox_format_handler_t sox_xa_format = {
- xanames,
- SOX_FILE_LIT_END,
- sox_xastartread,
- sox_xaread,
- sox_xastopread,
- sox_xastartwrite,
- sox_xawrite,
- sox_xastopwrite,
- NULL
-};
-
-const sox_format_handler_t *sox_xa_format_fn(void);
-
-const sox_format_handler_t *sox_xa_format_fn(void)
-{
- return &sox_xa_format;
+ static char const * const names[] = {"xa", NULL };
+ static sox_format_handler_t const handler = {
+ names, SOX_FILE_LIT_END,
+ startread, read_samples, stopread,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL
+ };
+ return &handler;
}