2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU Lesser General Public License as published by
6 ** the Free Software Foundation; either version 2.1 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU Lesser General Public License for more details.
14 ** You should have received a copy of the GNU Lesser General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 static SF_FORMAT_INFO
const simple_formats
[] =
30 { SF_FORMAT_AIFF
| SF_FORMAT_PCM_16
,
31 "AIFF (Apple/SGI 16 bit PCM)", "aiff"
34 { SF_FORMAT_AIFF
| SF_FORMAT_FLOAT
,
35 "AIFF (Apple/SGI 32 bit float)", "aifc"
38 { SF_FORMAT_AIFF
| SF_FORMAT_PCM_S8
,
39 "AIFF (Apple/SGI 8 bit PCM)", "aiff"
42 { SF_FORMAT_AU
| SF_FORMAT_PCM_16
,
43 "AU (Sun/Next 16 bit PCM)", "au"
46 { SF_FORMAT_AU
| SF_FORMAT_ULAW
,
47 "AU (Sun/Next 8-bit u-law)", "au"
50 { SF_FORMAT_CAF
| SF_FORMAT_PCM_16
,
51 "CAF (Apple 16 bit PCM)", "caf"
54 #if HAVE_EXTERNAL_LIBS
55 { SF_FORMAT_FLAC
| SF_FORMAT_PCM_16
,
60 { SF_FORMAT_RAW
| SF_FORMAT_VOX_ADPCM
,
61 "OKI Dialogic VOX ADPCM", "vox"
64 #if HAVE_EXTERNAL_LIBS
65 { SF_FORMAT_OGG
| SF_FORMAT_VORBIS
,
66 "Ogg Vorbis (Xiph Foundation)", "oga"
70 { SF_FORMAT_WAV
| SF_FORMAT_PCM_16
,
71 "WAV (Microsoft 16 bit PCM)", "wav"
74 { SF_FORMAT_WAV
| SF_FORMAT_FLOAT
,
75 "WAV (Microsoft 32 bit float)", "wav"
78 { SF_FORMAT_WAV
| SF_FORMAT_IMA_ADPCM
,
79 "WAV (Microsoft 4 bit IMA ADPCM)", "wav"
82 { SF_FORMAT_WAV
| SF_FORMAT_MS_ADPCM
,
83 "WAV (Microsoft 4 bit MS ADPCM)", "wav"
86 { SF_FORMAT_WAV
| SF_FORMAT_PCM_U8
,
87 "WAV (Microsoft 8 bit PCM)", "wav"
90 } ; /* simple_formats */
93 psf_get_format_simple_count (void)
94 { return (sizeof (simple_formats
) / sizeof (SF_FORMAT_INFO
)) ;
95 } /* psf_get_format_simple_count */
98 psf_get_format_simple (SF_FORMAT_INFO
*data
)
101 if (data
->format
< 0 || data
->format
>= (SIGNED_SIZEOF (simple_formats
) / SIGNED_SIZEOF (SF_FORMAT_INFO
)))
102 return SFE_BAD_COMMAND_PARAM
;
104 indx
= data
->format
;
105 memcpy (data
, &(simple_formats
[indx
]), SIGNED_SIZEOF (SF_FORMAT_INFO
)) ;
108 } /* psf_get_format_simple */
110 /*============================================================================
111 ** Major format info.
114 static SF_FORMAT_INFO
const major_formats
[] =
116 { SF_FORMAT_AIFF
, "AIFF (Apple/SGI)", "aiff" },
117 { SF_FORMAT_AU
, "AU (Sun/NeXT)", "au" },
118 { SF_FORMAT_AVR
, "AVR (Audio Visual Research)", "avr" },
119 { SF_FORMAT_CAF
, "CAF (Apple Core Audio File)", "caf" },
120 #if HAVE_EXTERNAL_LIBS
121 { SF_FORMAT_FLAC
, "FLAC (FLAC Lossless Audio Codec)", "flac" },
123 { SF_FORMAT_HTK
, "HTK (HMM Tool Kit)", "htk" },
124 { SF_FORMAT_SVX
, "IFF (Amiga IFF/SVX8/SV16)", "iff" },
125 { SF_FORMAT_MAT4
, "MAT4 (GNU Octave 2.0 / Matlab 4.2)", "mat" },
126 { SF_FORMAT_MAT5
, "MAT5 (GNU Octave 2.1 / Matlab 5.0)", "mat" },
127 { SF_FORMAT_MPC2K
, "MPC (Akai MPC 2k)", "mpc" },
128 #if HAVE_EXTERNAL_LIBS
129 { SF_FORMAT_OGG
, "OGG (OGG Container format)", "oga" },
131 { SF_FORMAT_PAF
, "PAF (Ensoniq PARIS)", "paf" },
132 { SF_FORMAT_PVF
, "PVF (Portable Voice Format)", "pvf" },
133 { SF_FORMAT_RAW
, "RAW (header-less)", "raw" },
134 { SF_FORMAT_RF64
, "RF64 (RIFF 64)", "rf64" },
135 { SF_FORMAT_SD2
, "SD2 (Sound Designer II)", "sd2" },
136 { SF_FORMAT_SDS
, "SDS (Midi Sample Dump Standard)", "sds" },
137 { SF_FORMAT_IRCAM
, "SF (Berkeley/IRCAM/CARL)", "sf" },
138 { SF_FORMAT_VOC
, "VOC (Creative Labs)", "voc" },
139 { SF_FORMAT_W64
, "W64 (SoundFoundry WAVE 64)", "w64" },
140 { SF_FORMAT_WAV
, "WAV (Microsoft)", "wav" },
141 { SF_FORMAT_NIST
, "WAV (NIST Sphere)", "wav" },
142 { SF_FORMAT_WAVEX
, "WAVEX (Microsoft)", "wav" },
143 { SF_FORMAT_WVE
, "WVE (Psion Series 3)", "wve" },
144 { SF_FORMAT_XI
, "XI (FastTracker 2)", "xi" },
146 } ; /* major_formats */
149 psf_get_format_major_count (void)
150 { return (sizeof (major_formats
) / sizeof (SF_FORMAT_INFO
)) ;
151 } /* psf_get_format_major_count */
154 psf_get_format_major (SF_FORMAT_INFO
*data
)
157 if (data
->format
< 0 || data
->format
>= (SIGNED_SIZEOF (major_formats
) / SIGNED_SIZEOF (SF_FORMAT_INFO
)))
158 return SFE_BAD_COMMAND_PARAM
;
160 indx
= data
->format
;
161 memcpy (data
, &(major_formats
[indx
]), SIGNED_SIZEOF (SF_FORMAT_INFO
)) ;
164 } /* psf_get_format_major */
166 /*============================================================================
167 ** Subtype format info.
170 static SF_FORMAT_INFO subtype_formats
[] =
172 { SF_FORMAT_PCM_S8
, "Signed 8 bit PCM", NULL
},
173 { SF_FORMAT_PCM_16
, "Signed 16 bit PCM", NULL
},
174 { SF_FORMAT_PCM_24
, "Signed 24 bit PCM", NULL
},
175 { SF_FORMAT_PCM_32
, "Signed 32 bit PCM", NULL
},
177 { SF_FORMAT_PCM_U8
, "Unsigned 8 bit PCM", NULL
},
179 { SF_FORMAT_FLOAT
, "32 bit float", NULL
},
180 { SF_FORMAT_DOUBLE
, "64 bit float", NULL
},
182 { SF_FORMAT_ULAW
, "U-Law", NULL
},
183 { SF_FORMAT_ALAW
, "A-Law", NULL
},
184 { SF_FORMAT_IMA_ADPCM
, "IMA ADPCM", NULL
},
185 { SF_FORMAT_MS_ADPCM
, "Microsoft ADPCM", NULL
},
187 { SF_FORMAT_GSM610
, "GSM 6.10", NULL
},
189 { SF_FORMAT_G721_32
, "32kbs G721 ADPCM", NULL
},
190 { SF_FORMAT_G723_24
, "24kbs G723 ADPCM", NULL
},
192 { SF_FORMAT_DWVW_12
, "12 bit DWVW", NULL
},
193 { SF_FORMAT_DWVW_16
, "16 bit DWVW", NULL
},
194 { SF_FORMAT_DWVW_24
, "24 bit DWVW", NULL
},
195 { SF_FORMAT_VOX_ADPCM
, "VOX ADPCM", "vox" },
197 { SF_FORMAT_DPCM_16
, "16 bit DPCM", NULL
},
198 { SF_FORMAT_DPCM_8
, "8 bit DPCM", NULL
},
200 #if HAVE_EXTERNAL_LIBS
201 { SF_FORMAT_VORBIS
, "Vorbis", NULL
},
203 } ; /* subtype_formats */
206 psf_get_format_subtype_count (void)
207 { return (sizeof (subtype_formats
) / sizeof (SF_FORMAT_INFO
)) ;
208 } /* psf_get_format_subtype_count */
211 psf_get_format_subtype (SF_FORMAT_INFO
*data
)
214 if (data
->format
< 0 || data
->format
>= (SIGNED_SIZEOF (subtype_formats
) / SIGNED_SIZEOF (SF_FORMAT_INFO
)))
215 return SFE_BAD_COMMAND_PARAM
;
217 indx
= data
->format
;
218 memcpy (data
, &(subtype_formats
[indx
]), sizeof (SF_FORMAT_INFO
)) ;
221 } /* psf_get_format_subtype */
223 /*==============================================================================
227 psf_get_format_info (SF_FORMAT_INFO
*data
)
230 if (SF_CONTAINER (data
->format
))
231 { format
= SF_CONTAINER (data
->format
) ;
233 for (k
= 0 ; k
< (SIGNED_SIZEOF (major_formats
) / SIGNED_SIZEOF (SF_FORMAT_INFO
)) ; k
++)
234 { if (format
== major_formats
[k
].format
)
235 { memcpy (data
, &(major_formats
[k
]), sizeof (SF_FORMAT_INFO
)) ;
240 else if (SF_CODEC (data
->format
))
241 { format
= SF_CODEC (data
->format
) ;
243 for (k
= 0 ; k
< (SIGNED_SIZEOF (subtype_formats
) / SIGNED_SIZEOF (SF_FORMAT_INFO
)) ; k
++)
244 { if (format
== subtype_formats
[k
].format
)
245 { memcpy (data
, &(subtype_formats
[k
]), sizeof (SF_FORMAT_INFO
)) ;
251 memset (data
, 0, sizeof (SF_FORMAT_INFO
)) ;
253 return SFE_BAD_COMMAND_PARAM
;
254 } /* psf_get_format_info */
256 /*==============================================================================
260 psf_calc_signal_max (SF_PRIVATE
*psf
, int normalize
)
261 { sf_count_t position
;
262 double max_val
, temp
, *data
;
263 int k
, len
, readcount
, save_state
;
265 /* If the file is not seekable, there is nothing we can do. */
266 if (! psf
->sf
.seekable
)
267 { psf
->error
= SFE_NOT_SEEKABLE
;
271 if (! psf
->read_double
)
272 { psf
->error
= SFE_UNIMPLEMENTED
;
276 save_state
= sf_command ((SNDFILE
*) psf
, SFC_GET_NORM_DOUBLE
, NULL
, 0) ;
277 sf_command ((SNDFILE
*) psf
, SFC_SET_NORM_DOUBLE
, NULL
, normalize
) ;
279 /* Brute force. Read the whole file and find the biggest sample. */
280 /* Get current position in file */
281 position
= sf_seek ((SNDFILE
*) psf
, 0, SEEK_CUR
) ;
282 /* Go to start of file. */
283 sf_seek ((SNDFILE
*) psf
, 0, SEEK_SET
) ;
286 len
= ARRAY_LEN (psf
->u
.dbuf
) ;
288 for (readcount
= 1, max_val
= 0.0 ; readcount
> 0 ; /* nothing */)
289 { readcount
= sf_read_double ((SNDFILE
*) psf
, data
, len
) ;
290 for (k
= 0 ; k
< readcount
; k
++)
291 { temp
= fabs (data
[k
]) ;
292 max_val
= temp
> max_val
? temp
: max_val
;
296 /* Return to SNDFILE to original state. */
297 sf_seek ((SNDFILE
*) psf
, position
, SEEK_SET
) ;
298 sf_command ((SNDFILE
*) psf
, SFC_SET_NORM_DOUBLE
, NULL
, save_state
) ;
301 } /* psf_calc_signal_max */
304 psf_calc_max_all_channels (SF_PRIVATE
*psf
, double *peaks
, int normalize
)
305 { sf_count_t position
;
307 int k
, len
, readcount
, save_state
;
310 /* If the file is not seekable, there is nothing we can do. */
311 if (! psf
->sf
.seekable
)
312 return (psf
->error
= SFE_NOT_SEEKABLE
) ;
314 if (! psf
->read_double
)
315 return (psf
->error
= SFE_UNIMPLEMENTED
) ;
317 save_state
= sf_command ((SNDFILE
*) psf
, SFC_GET_NORM_DOUBLE
, NULL
, 0) ;
318 sf_command ((SNDFILE
*) psf
, SFC_SET_NORM_DOUBLE
, NULL
, normalize
) ;
320 memset (peaks
, 0, sizeof (double) * psf
->sf
.channels
) ;
322 /* Brute force. Read the whole file and find the biggest sample for each channel. */
323 position
= sf_seek ((SNDFILE
*) psf
, 0, SEEK_CUR
) ; /* Get current position in file */
324 sf_seek ((SNDFILE
*) psf
, 0, SEEK_SET
) ; /* Go to start of file. */
326 len
= ARRAY_LEN (psf
->u
.dbuf
) ;
332 while (readcount
> 0)
333 { readcount
= sf_read_double ((SNDFILE
*) psf
, data
, len
) ;
334 for (k
= 0 ; k
< readcount
; k
++)
335 { temp
= fabs (data
[k
]) ;
336 peaks
[chan
] = temp
> peaks
[chan
] ? temp
: peaks
[chan
] ;
337 chan
= (chan
+ 1) % psf
->sf
.channels
;
341 sf_seek ((SNDFILE
*) psf
, position
, SEEK_SET
) ; /* Return to original position. */
343 sf_command ((SNDFILE
*) psf
, SFC_SET_NORM_DOUBLE
, NULL
, save_state
) ;
346 } /* psf_calc_max_all_channels */
349 psf_get_signal_max (SF_PRIVATE
*psf
, double *peak
)
352 if (psf
->peak_info
== NULL
)
355 peak
[0] = psf
->peak_info
->peaks
[0].value
;
357 for (k
= 1 ; k
< psf
->sf
.channels
; k
++)
358 peak
[0] = SF_MAX (peak
[0], psf
->peak_info
->peaks
[k
].value
) ;
361 } /* psf_get_signal_max */
364 psf_get_max_all_channels (SF_PRIVATE
*psf
, double *peaks
)
367 if (psf
->peak_info
== NULL
)
370 for (k
= 0 ; k
< psf
->sf
.channels
; k
++)
371 peaks
[k
] = psf
->peak_info
->peaks
[k
].value
;
374 } /* psf_get_max_all_channels */