LIBSOXFORMAT_NG(3)             Sound eXchange_ng            LIBSOXFORMAT_NG(3)

NAME
       libsoxformat_ng - libsox_ng format handlers' internals

SYNOPSIS
       #include "sox_i.h"

       typedef struct {
           ...
       } priv_t;

       static int startread(sox_format_t *ft);
       static size_t read(sox_format_t *ft, sox_sample_t *buf, size_t len);
       static int stopread(sox_format_t *ft);
       static int startwrite(sox_format_t *ft);
       static size_t write(sox_format_t *ft, sox_sample_t *buf, size_t len);
       static int stopwrite(sox_format_t *ft);
       static int seek(sox_format_t *ft, sox_uint64_t offset);

       sox_format_handler_t const *lsx_whatever_format_fn(void)
       {
         static char const description[] = "Whatever format";
         static char const * const names = { "wvr", NULL };
         static unsigned const write_encodings[] = {
           SOX_ENCODING_*, {bitwidth,} 0,
           ..., 0,
           0};
         static sox_format_handler_t const handler = { SOX_LIB_VERSION_CODE,
           description, names, {SOX_FILE_* |} 0,
           startread, read, stopread,
           startwrite, write, stopwrite,
           seek, write_encodings,
           sizeof(priv_t)
         };
         return &handler;
       }


DESCRIPTION
       How SoX format handlers work and how to write a new one.

       SoX's  formats  and  effects  operate with an internal sample format of
       signed 32-bit integers. The data processing routines  are  called  with
       buffers  of these samples and buffer sizes which refer to the number of
       samples processed, not the number of bytes. File readers translate  in-
       put  samples to signed 32-bit integers and return the number of samples
       read. For example, data in linear signed byte format is left-shifted 24
       bits.

       Stereo data is stored with the left and right channels' data in succes-
       sive samples and quadraphonic data is stored left front,  right  front,
       left rear, right rear.

       A  format  handler  is responsible for translating between sound sample
       files and an internal buffer in which sound data is  stored  as  signed
       32-bit integers with a fixed sampling rate.

       struct sox_format_handler {
         unsigned     sox_lib_version_code;        /* Checked on load           */
         char       * description;                 /* Description of the format */
         char     * * names;                       /* Filename extensions       */
         unsigned int flags;                       /* File flags (SOX_FILE_*)   */
         sox_format_handler_startread  startread;  /* Initialize decoder        */
         sox_format_handler_read       read;       /* Decode a block of samples */
         sox_format_handler_stopread   stopread;   /* Close decoder             */
         sox_format_handler_startwrite startwrite; /* Initialize encoder        */
         sox_format_handler_write      write;      /* Encode a block of samples */
         sox_format_handler_stopwrite  stopwrite;  /* Close encoder             */
         sox_format_handler_seek       seek;       /* Reposition reader         */
         unsigned   * write_formats;               /* Encodings and precision   */
         unsigned   * write_rates;                 /* Sample rates              */
         size_t       priv_size;                   /* sizeof(priv_t)            */
       };


       sox_uint32_t sox_lib_version_code
              Checked  when format plugins are loaded to ensure they were com-
              piled for the same version of libsox that is calling them.

       char *description
              A short description of the format, printed by sox_ng --help-for-
              mat.

       char **names
              A null-terminated array of filename extensions (without the dot)
              that are handled by this format.

       unsigned int flags
              The logical OR of:
              SOX_FILE_NOSTDIO   The handler does not use stdio routines
              SOX_FILE_DEVICE    The file is an audio device
              SOX_FILE_PHONY     Phony file/device (for example /dev/null)
              SOX_FILE_REWIND    File should be rewound to write header
              SOX_FILE_BIT_REV   Is the file bit-reversed?
              SOX_FILE_NIB_REV   Is the file nibble-reversed?
              SOX_FILE_ENDIAN    Is the file format endian?
              SOX_FILE_ENDBIG    For an endian file format, is it big endian?
              SOX_FILE_MONO      Do channel restrictions allow mono?
              SOX_FILE_STEREO    Do channel restrictions allow stereo?
              SOX_FILE_QUAD      Do channel restrictions allow quad?
              SOX_FILE_LIT_END   A mask to OR in if the file is little-endian
              SOX_FILE_BIG_END   A mask to OR in if the file is big-endian
              SOX_FILE_CHANS     A mask to interrogate channels restrictions.
                                 If flags & SOX_FILE_CHANS is 0, there are no
                                 restrictions

       int (*startread)(sox_format_t *fp)
              A function to set up the  format  parameters,  read  in  a  data
              header  and do anything else that needs to be done before decod-
              ing data.  It returns SOX_SUCCESS if all went well,  or  a  non-
              zero  value  if  there  was some problem with the file, in which
              case read and stopread will not be called.

              At exit from startread, sox_format_t.signal should be completely
              filled in, using either data from the file's headers (if  avail-
              able) or whatever the format is guessing/assuming if header data
              is not available.

       size_t (*read)(sox_format_t *ft, sox_sample_t *buf, size_t len)
              Given  a  buffer  and  a  length,  read up to that many samples,
              transform them into signed long integers and copy them into  the
              buffer.  It returns the number of samples actually read.

       int (*stopread)(sox_format_t *ft)
              Does what needs to be done when it has finished reading.

       int (*startwrite)(sox_format_t *ft)
              Set up the format parameters, maybe write out a data header, and
              any  other  preliminaries  for  encoding the format.  It returns
              SOX_SUCCESS if all went well, or a non-zero value if  there  was
              some  problem,  in  which  case  write and stopwrite will not be
              called.

              At exit from  startwrite,  sox_format_t.signal  should  be  com-
              pletely  filled in, using either the data that was specified, or
              values chosen by the format based on the  format's  defaults  or
              capabilities.

       size_t (*write)(sox_format_t *ft, sox_sample_t *buf, size_t len)
              Given  a  buffer and a length, copy that many samples out of the
              buffer, convert them from signed longs to the  appropriate  data
              types  and  write  them  to the file.  If it can't write all the
              samples out, it returns a lesser number of samples.

       int (*stopwrite)(sox_format_t *ft)
              Fix up the file header or whatever else needs to be done  before
              closing the file.

       unsigned *write_formats
              An  array of values indicating the encodings and precisions sup-
              ported for writing (encoding). Precisions are specified with de-
              fault precision first, and with 0 and repeat, and list ends with
              with one more 0.

              An example for a format that supports signed integers at  depths
              of 16 and 24 bits with a default of 16, and 8-bit unsigned:

                 unsigned const * formats = {
                   SOX_ENCODING_SIGN2, 16, 24, 0,
                   SOX_ENCODING_UNSIGNED, 8, 0,
                   0 };


       sox_rate_t *write_rates
              An  zero-terminated array of sample rates that are supported for
              writing, NULL if all rates are supported.

       size_t priv_size
              The size of the format's priv_t.  SoX automatically allocates  a
              buffer in which the handler can store its private data, of which
              the   size   is   specified   here.    Usually   this   will  be
              sizeof(priv_t).  The buffer is allocated and zeroed  before  the
              call  to  startread/startwrite,  is freed after the call to sto-
              pread/stopwrite and is provided via ft->priv in each call to the
              handler's functions.

EXAMPLES
       The SoX source code includes a skeleton C file to assist you in writing
       new formats (src/skelform.c).  New formats can often just deal with the
       header and then use raw.c's routines for reading and writing.

SEE ALSO
       sox_ng(1), libsox_ng(3), soxformat_ng(7)and src/skelform.c in  the  SoX
       source code.

SoX                             January 5, 2026             LIBSOXFORMAT_NG(3)
