annotate src/libsndfile-1.0.25/src/pvf.c @ 138:eb184393b244

Rebuild with DW2 exception handling to match Qt
author Chris Cannam <cannam@all-day-breakfast.com>
date Thu, 27 Oct 2016 10:26:57 +0100
parents 545efbb81310
children
rev   line source
cannam@85 1 /*
cannam@85 2 ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
cannam@85 3 **
cannam@85 4 ** This program is free software; you can redistribute it and/or modify
cannam@85 5 ** it under the terms of the GNU Lesser General Public License as published by
cannam@85 6 ** the Free Software Foundation; either version 2.1 of the License, or
cannam@85 7 ** (at your option) any later version.
cannam@85 8 **
cannam@85 9 ** This program is distributed in the hope that it will be useful,
cannam@85 10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
cannam@85 11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cannam@85 12 ** GNU Lesser General Public License for more details.
cannam@85 13 **
cannam@85 14 ** You should have received a copy of the GNU Lesser General Public License
cannam@85 15 ** along with this program; if not, write to the Free Software
cannam@85 16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
cannam@85 17 */
cannam@85 18
cannam@85 19 #include "sfconfig.h"
cannam@85 20
cannam@85 21 #include <stdio.h>
cannam@85 22 #include <fcntl.h>
cannam@85 23 #include <string.h>
cannam@85 24 #include <ctype.h>
cannam@85 25
cannam@85 26 #include "sndfile.h"
cannam@85 27 #include "sfendian.h"
cannam@85 28 #include "common.h"
cannam@85 29
cannam@85 30 /*------------------------------------------------------------------------------
cannam@85 31 ** Macros to handle big/little endian issues.
cannam@85 32 */
cannam@85 33
cannam@85 34 #define PVF1_MARKER (MAKE_MARKER ('P', 'V', 'F', '1'))
cannam@85 35
cannam@85 36 /*------------------------------------------------------------------------------
cannam@85 37 ** Private static functions.
cannam@85 38 */
cannam@85 39
cannam@85 40 static int pvf_close (SF_PRIVATE *psf) ;
cannam@85 41
cannam@85 42 static int pvf_write_header (SF_PRIVATE *psf, int calc_length) ;
cannam@85 43 static int pvf_read_header (SF_PRIVATE *psf) ;
cannam@85 44
cannam@85 45 /*------------------------------------------------------------------------------
cannam@85 46 ** Public function.
cannam@85 47 */
cannam@85 48
cannam@85 49 int
cannam@85 50 pvf_open (SF_PRIVATE *psf)
cannam@85 51 { int subformat ;
cannam@85 52 int error = 0 ;
cannam@85 53
cannam@85 54 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
cannam@85 55 { if ((error = pvf_read_header (psf)))
cannam@85 56 return error ;
cannam@85 57 } ;
cannam@85 58
cannam@85 59 subformat = SF_CODEC (psf->sf.format) ;
cannam@85 60
cannam@85 61 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
cannam@85 62 { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PVF)
cannam@85 63 return SFE_BAD_OPEN_FORMAT ;
cannam@85 64
cannam@85 65 psf->endian = SF_ENDIAN_BIG ;
cannam@85 66
cannam@85 67 if (pvf_write_header (psf, SF_FALSE))
cannam@85 68 return psf->error ;
cannam@85 69
cannam@85 70 psf->write_header = pvf_write_header ;
cannam@85 71 } ;
cannam@85 72
cannam@85 73 psf->container_close = pvf_close ;
cannam@85 74
cannam@85 75 psf->blockwidth = psf->bytewidth * psf->sf.channels ;
cannam@85 76
cannam@85 77 switch (subformat)
cannam@85 78 { case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
cannam@85 79 case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
cannam@85 80 case SF_FORMAT_PCM_32 : /* 32-bit linear PCM. */
cannam@85 81 error = pcm_init (psf) ;
cannam@85 82 break ;
cannam@85 83
cannam@85 84 default : break ;
cannam@85 85 } ;
cannam@85 86
cannam@85 87 return error ;
cannam@85 88 } /* pvf_open */
cannam@85 89
cannam@85 90 /*------------------------------------------------------------------------------
cannam@85 91 */
cannam@85 92
cannam@85 93 static int
cannam@85 94 pvf_close (SF_PRIVATE * UNUSED (psf))
cannam@85 95 {
cannam@85 96 return 0 ;
cannam@85 97 } /* pvf_close */
cannam@85 98
cannam@85 99 static int
cannam@85 100 pvf_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
cannam@85 101 { sf_count_t current ;
cannam@85 102
cannam@85 103 if (psf->pipeoffset > 0)
cannam@85 104 return 0 ;
cannam@85 105
cannam@85 106 current = psf_ftell (psf) ;
cannam@85 107
cannam@85 108 /* Reset the current header length to zero. */
cannam@85 109 psf->header [0] = 0 ;
cannam@85 110 psf->headindex = 0 ;
cannam@85 111
cannam@85 112 if (psf->is_pipe == SF_FALSE)
cannam@85 113 psf_fseek (psf, 0, SEEK_SET) ;
cannam@85 114
cannam@85 115 snprintf ((char*) psf->header, sizeof (psf->header), "PVF1\n%d %d %d\n",
cannam@85 116 psf->sf.channels, psf->sf.samplerate, psf->bytewidth * 8) ;
cannam@85 117
cannam@85 118 psf->headindex = strlen ((char*) psf->header) ;
cannam@85 119
cannam@85 120 /* Header construction complete so write it out. */
cannam@85 121 psf_fwrite (psf->header, psf->headindex, 1, psf) ;
cannam@85 122
cannam@85 123 if (psf->error)
cannam@85 124 return psf->error ;
cannam@85 125
cannam@85 126 psf->dataoffset = psf->headindex ;
cannam@85 127
cannam@85 128 if (current > 0)
cannam@85 129 psf_fseek (psf, current, SEEK_SET) ;
cannam@85 130
cannam@85 131 return psf->error ;
cannam@85 132 } /* pvf_write_header */
cannam@85 133
cannam@85 134 static int
cannam@85 135 pvf_read_header (SF_PRIVATE *psf)
cannam@85 136 { char buffer [32] ;
cannam@85 137 int marker, channels, samplerate, bitwidth ;
cannam@85 138
cannam@85 139 psf_binheader_readf (psf, "pmj", 0, &marker, 1) ;
cannam@85 140 psf_log_printf (psf, "%M\n", marker) ;
cannam@85 141
cannam@85 142 if (marker != PVF1_MARKER)
cannam@85 143 return SFE_PVF_NO_PVF1 ;
cannam@85 144
cannam@85 145 /* Grab characters up until a newline which is replaced by an EOS. */
cannam@85 146 psf_binheader_readf (psf, "G", buffer, sizeof (buffer)) ;
cannam@85 147
cannam@85 148 if (sscanf (buffer, "%d %d %d", &channels, &samplerate, &bitwidth) != 3)
cannam@85 149 return SFE_PVF_BAD_HEADER ;
cannam@85 150
cannam@85 151 psf_log_printf (psf, " Channels : %d\n Sample rate : %d\n Bit width : %d\n",
cannam@85 152 channels, samplerate, bitwidth) ;
cannam@85 153
cannam@85 154 psf->sf.channels = channels ;
cannam@85 155 psf->sf.samplerate = samplerate ;
cannam@85 156
cannam@85 157 switch (bitwidth)
cannam@85 158 { case 8 :
cannam@85 159 psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_S8 ;
cannam@85 160 psf->bytewidth = 1 ;
cannam@85 161 break ;
cannam@85 162
cannam@85 163 case 16 :
cannam@85 164 psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_16 ;
cannam@85 165 psf->bytewidth = 2 ;
cannam@85 166 break ;
cannam@85 167 case 32 :
cannam@85 168 psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_32 ;
cannam@85 169 psf->bytewidth = 4 ;
cannam@85 170 break ;
cannam@85 171
cannam@85 172 default :
cannam@85 173 return SFE_PVF_BAD_BITWIDTH ;
cannam@85 174 } ;
cannam@85 175
cannam@85 176 psf->dataoffset = psf_ftell (psf) ;
cannam@85 177 psf_log_printf (psf, " Data Offset : %D\n", psf->dataoffset) ;
cannam@85 178
cannam@85 179 psf->endian = SF_ENDIAN_BIG ;
cannam@85 180
cannam@85 181 psf->datalength = psf->filelength - psf->dataoffset ;
cannam@85 182 psf->blockwidth = psf->sf.channels * psf->bytewidth ;
cannam@85 183
cannam@85 184 if (! psf->sf.frames && psf->blockwidth)
cannam@85 185 psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
cannam@85 186
cannam@85 187 return 0 ;
cannam@85 188 } /* pvf_read_header */