diff options
Diffstat (limited to 'libs/libsndfile/src/mat4.c')
-rw-r--r-- | libs/libsndfile/src/mat4.c | 394 |
1 files changed, 0 insertions, 394 deletions
diff --git a/libs/libsndfile/src/mat4.c b/libs/libsndfile/src/mat4.c deleted file mode 100644 index fcc6111506..0000000000 --- a/libs/libsndfile/src/mat4.c +++ /dev/null @@ -1,394 +0,0 @@ -/* -** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com> -** -** This program 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.1 of the License, or -** (at your option) any later version. -** -** This program 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 program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "sfconfig.h" - -#include <stdio.h> -#include <fcntl.h> -#include <string.h> -#include <ctype.h> - -#include "sndfile.h" -#include "sfendian.h" -#include "common.h" -#include "float_cast.h" - -/*------------------------------------------------------------------------------ -** Information on how to decode and encode this file was obtained in a PDF -** file which I found on http://www.wotsit.org/. -** Also did a lot of testing with GNU Octave but do not have access to -** Matlab (tm) and so could not test it there. -*/ - -/*------------------------------------------------------------------------------ -** Macros to handle big/little endian issues. -*/ - -#define MAT4_BE_DOUBLE (MAKE_MARKER (0, 0, 0x03, 0xE8)) -#define MAT4_LE_DOUBLE (MAKE_MARKER (0, 0, 0, 0)) - -#define MAT4_BE_FLOAT (MAKE_MARKER (0, 0, 0x03, 0xF2)) -#define MAT4_LE_FLOAT (MAKE_MARKER (0x0A, 0, 0, 0)) - -#define MAT4_BE_PCM_32 (MAKE_MARKER (0, 0, 0x03, 0xFC)) -#define MAT4_LE_PCM_32 (MAKE_MARKER (0x14, 0, 0, 0)) - -#define MAT4_BE_PCM_16 (MAKE_MARKER (0, 0, 0x04, 0x06)) -#define MAT4_LE_PCM_16 (MAKE_MARKER (0x1E, 0, 0, 0)) - -/* Can't see any reason to ever implement this. */ -#define MAT4_BE_PCM_U8 (MAKE_MARKER (0, 0, 0x04, 0x1A)) -#define MAT4_LE_PCM_U8 (MAKE_MARKER (0x32, 0, 0, 0)) - -/*------------------------------------------------------------------------------ -** Private static functions. -*/ - -static int mat4_close (SF_PRIVATE *psf) ; - -static int mat4_format_to_encoding (int format, int endian) ; - -static int mat4_write_header (SF_PRIVATE *psf, int calc_length) ; -static int mat4_read_header (SF_PRIVATE *psf) ; - -static const char * mat4_marker_to_str (int marker) ; - -/*------------------------------------------------------------------------------ -** Public function. -*/ - -int -mat4_open (SF_PRIVATE *psf) -{ int subformat, error = 0 ; - - if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0)) - { if ((error = mat4_read_header (psf))) - return error ; - } ; - - if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_MAT4) - return SFE_BAD_OPEN_FORMAT ; - - subformat = psf->sf.format & SF_FORMAT_SUBMASK ; - - if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) - { if (psf->is_pipe) - return SFE_NO_PIPE_WRITE ; - - psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ; - if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0)) - psf->endian = SF_ENDIAN_LITTLE ; - else if (CPU_IS_BIG_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0)) - psf->endian = SF_ENDIAN_BIG ; - - if ((error = mat4_write_header (psf, SF_FALSE))) - return error ; - - psf->write_header = mat4_write_header ; - } ; - - psf->container_close = mat4_close ; - - psf->blockwidth = psf->bytewidth * psf->sf.channels ; - - switch (subformat) - { case SF_FORMAT_PCM_16 : - case SF_FORMAT_PCM_32 : - error = pcm_init (psf) ; - break ; - - case SF_FORMAT_FLOAT : - error = float32_init (psf) ; - break ; - - case SF_FORMAT_DOUBLE : - error = double64_init (psf) ; - break ; - - default : break ; - } ; - - if (error) - return error ; - - return error ; -} /* mat4_open */ - -/*------------------------------------------------------------------------------ -*/ - -static int -mat4_close (SF_PRIVATE *psf) -{ - if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) - mat4_write_header (psf, SF_TRUE) ; - - return 0 ; -} /* mat4_close */ - -/*------------------------------------------------------------------------------ -*/ - -static int -mat4_write_header (SF_PRIVATE *psf, int calc_length) -{ sf_count_t current ; - int encoding ; - double samplerate ; - - current = psf_ftell (psf) ; - - if (calc_length) - { psf->filelength = psf_get_filelen (psf) ; - - psf->datalength = psf->filelength - psf->dataoffset ; - if (psf->dataend) - psf->datalength -= psf->filelength - psf->dataend ; - - psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; - } ; - - encoding = mat4_format_to_encoding (psf->sf.format & SF_FORMAT_SUBMASK, psf->endian) ; - - if (encoding == -1) - return SFE_BAD_OPEN_FORMAT ; - - /* Reset the current header length to zero. */ - psf->header [0] = 0 ; - psf->headindex = 0 ; - psf_fseek (psf, 0, SEEK_SET) ; - - /* Need sample rate as a double for writing to the header. */ - samplerate = psf->sf.samplerate ; - - if (psf->endian == SF_ENDIAN_BIG) - { psf_binheader_writef (psf, "Em444", MAT4_BE_DOUBLE, 1, 1, 0) ; - psf_binheader_writef (psf, "E4bd", 11, "samplerate", 11, samplerate) ; - psf_binheader_writef (psf, "tEm484", encoding, psf->sf.channels, psf->sf.frames, 0) ; - psf_binheader_writef (psf, "E4b", 9, "wavedata", 9) ; - } - else if (psf->endian == SF_ENDIAN_LITTLE) - { psf_binheader_writef (psf, "em444", MAT4_LE_DOUBLE, 1, 1, 0) ; - psf_binheader_writef (psf, "e4bd", 11, "samplerate", 11, samplerate) ; - psf_binheader_writef (psf, "tem484", encoding, psf->sf.channels, psf->sf.frames, 0) ; - psf_binheader_writef (psf, "e4b", 9, "wavedata", 9) ; - } - else - return SFE_BAD_OPEN_FORMAT ; - - /* Header construction complete so write it out. */ - psf_fwrite (psf->header, psf->headindex, 1, psf) ; - - if (psf->error) - return psf->error ; - - psf->dataoffset = psf->headindex ; - - if (current > 0) - psf_fseek (psf, current, SEEK_SET) ; - - return psf->error ; -} /* mat4_write_header */ - -static int -mat4_read_header (SF_PRIVATE *psf) -{ int marker, namesize, rows, cols, imag ; - double value ; - const char *marker_str ; - char name [64] ; - - psf_binheader_readf (psf, "pm", 0, &marker) ; - - /* MAT4 file must start with a double for the samplerate. */ - if (marker == MAT4_BE_DOUBLE) - { psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ; - marker_str = "big endian double" ; - } - else if (marker == MAT4_LE_DOUBLE) - { psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ; - marker_str = "little endian double" ; - } - else - return SFE_UNIMPLEMENTED ; - - psf_log_printf (psf, "GNU Octave 2.0 / MATLAB v4.2 format\nMarker : %s\n", marker_str) ; - - psf_binheader_readf (psf, "444", &rows, &cols, &imag) ; - - psf_log_printf (psf, " Rows : %d\n Cols : %d\n Imag : %s\n", rows, cols, imag ? "True" : "False") ; - - psf_binheader_readf (psf, "4", &namesize) ; - - if (namesize >= SIGNED_SIZEOF (name)) - return SFE_MAT4_BAD_NAME ; - - psf_binheader_readf (psf, "b", name, namesize) ; - name [namesize] = 0 ; - - psf_log_printf (psf, " Name : %s\n", name) ; - - psf_binheader_readf (psf, "d", &value) ; - - LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), " Value : %f\n", value) ; - psf_log_printf (psf, psf->u.cbuf) ; - - if ((rows != 1) || (cols != 1)) - return SFE_MAT4_NO_SAMPLERATE ; - - psf->sf.samplerate = lrint (value) ; - - /* Now write out the audio data. */ - - psf_binheader_readf (psf, "m", &marker) ; - - psf_log_printf (psf, "Marker : %s\n", mat4_marker_to_str (marker)) ; - - psf_binheader_readf (psf, "444", &rows, &cols, &imag) ; - - psf_log_printf (psf, " Rows : %d\n Cols : %d\n Imag : %s\n", rows, cols, imag ? "True" : "False") ; - - psf_binheader_readf (psf, "4", &namesize) ; - - if (namesize >= SIGNED_SIZEOF (name)) - return SFE_MAT4_BAD_NAME ; - - psf_binheader_readf (psf, "b", name, namesize) ; - name [namesize] = 0 ; - - psf_log_printf (psf, " Name : %s\n", name) ; - - psf->dataoffset = psf_ftell (psf) ; - - if (rows == 0 && cols == 0) - { psf_log_printf (psf, "*** Error : zero channel count.\n") ; - return SFE_MAT4_ZERO_CHANNELS ; - } ; - - psf->sf.channels = rows ; - psf->sf.frames = cols ; - - psf->sf.format = psf->endian | SF_FORMAT_MAT4 ; - switch (marker) - { case MAT4_BE_DOUBLE : - case MAT4_LE_DOUBLE : - psf->sf.format |= SF_FORMAT_DOUBLE ; - psf->bytewidth = 8 ; - break ; - - case MAT4_BE_FLOAT : - case MAT4_LE_FLOAT : - psf->sf.format |= SF_FORMAT_FLOAT ; - psf->bytewidth = 4 ; - break ; - - case MAT4_BE_PCM_32 : - case MAT4_LE_PCM_32 : - psf->sf.format |= SF_FORMAT_PCM_32 ; - psf->bytewidth = 4 ; - break ; - - case MAT4_BE_PCM_16 : - case MAT4_LE_PCM_16 : - psf->sf.format |= SF_FORMAT_PCM_16 ; - psf->bytewidth = 2 ; - break ; - - default : - psf_log_printf (psf, "*** Error : Bad marker %08X\n", marker) ; - return SFE_UNIMPLEMENTED ; - } ; - - if ((psf->filelength - psf->dataoffset) < psf->sf.channels * psf->sf.frames * psf->bytewidth) - { psf_log_printf (psf, "*** File seems to be truncated. %D <--> %D\n", - psf->filelength - psf->dataoffset, psf->sf.channels * psf->sf.frames * psf->bytewidth) ; - } - else if ((psf->filelength - psf->dataoffset) > psf->sf.channels * psf->sf.frames * psf->bytewidth) - psf->dataend = psf->dataoffset + rows * cols * psf->bytewidth ; - - psf->datalength = psf->filelength - psf->dataoffset - psf->dataend ; - - psf->sf.sections = 1 ; - - return 0 ; -} /* mat4_read_header */ - -static int -mat4_format_to_encoding (int format, int endian) -{ - switch (format | endian) - { case (SF_FORMAT_PCM_16 | SF_ENDIAN_BIG) : - return MAT4_BE_PCM_16 ; - - case (SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE) : - return MAT4_LE_PCM_16 ; - - case (SF_FORMAT_PCM_32 | SF_ENDIAN_BIG) : - return MAT4_BE_PCM_32 ; - - case (SF_FORMAT_PCM_32 | SF_ENDIAN_LITTLE) : - return MAT4_LE_PCM_32 ; - - case (SF_FORMAT_FLOAT | SF_ENDIAN_BIG) : - return MAT4_BE_FLOAT ; - - case (SF_FORMAT_FLOAT | SF_ENDIAN_LITTLE) : - return MAT4_LE_FLOAT ; - - case (SF_FORMAT_DOUBLE | SF_ENDIAN_BIG) : - return MAT4_BE_DOUBLE ; - - case (SF_FORMAT_DOUBLE | SF_ENDIAN_LITTLE) : - return MAT4_LE_DOUBLE ; - - default : break ; - } ; - - return -1 ; -} /* mat4_format_to_encoding */ - -static const char * -mat4_marker_to_str (int marker) -{ static char str [32] ; - - switch (marker) - { - case MAT4_BE_PCM_16 : return "big endian 16 bit PCM" ; - case MAT4_LE_PCM_16 : return "little endian 16 bit PCM" ; - - case MAT4_BE_PCM_32 : return "big endian 32 bit PCM" ; - case MAT4_LE_PCM_32 : return "little endian 32 bit PCM" ; - - - case MAT4_BE_FLOAT : return "big endian float" ; - case MAT4_LE_FLOAT : return "big endian float" ; - - case MAT4_BE_DOUBLE : return "big endian double" ; - case MAT4_LE_DOUBLE : return "little endian double" ; - } ; - - /* This is a little unsafe but is really only for debugging. */ - str [sizeof (str) - 1] = 0 ; - LSF_SNPRINTF (str, sizeof (str) - 1, "%08X", marker) ; - return str ; -} /* mat4_marker_to_str */ -/* -** Do not edit or modify anything in this comment block. -** The arch-tag line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: f7e5f5d6-fc39-452e-bc4a-59627116ff59 -*/ |