• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (C) 2001-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
3 **
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.
8 **
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.
13 **
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.
17 */
18 
19 #include	"sfconfig.h"
20 
21 #include	<stdio.h>
22 #include	<string.h>
23 #include	<math.h>
24 
25 #include	"sndfile.h"
26 #include	"common.h"
27 
28 static SF_FORMAT_INFO const simple_formats [] =
29 {
30 	{	SF_FORMAT_AIFF | SF_FORMAT_PCM_16,
31 		"AIFF (Apple/SGI 16 bit PCM)", "aiff"
32 		},
33 
34 	{	SF_FORMAT_AIFF | SF_FORMAT_FLOAT,
35 		"AIFF (Apple/SGI 32 bit float)", "aifc"
36 		},
37 
38 	{	SF_FORMAT_AIFF | SF_FORMAT_PCM_S8,
39 		"AIFF (Apple/SGI 8 bit PCM)", "aiff"
40 		},
41 
42 	{	SF_FORMAT_AU | SF_FORMAT_PCM_16,
43 		"AU (Sun/Next 16 bit PCM)", "au"
44 		},
45 
46 	{	SF_FORMAT_AU | SF_FORMAT_ULAW,
47 		"AU (Sun/Next 8-bit u-law)", "au"
48 		},
49 
50 	{	SF_FORMAT_CAF | SF_FORMAT_ALAC_16,
51 		"CAF (Apple 16 bit ALAC)", "caf"
52 		},
53 
54 	{	SF_FORMAT_CAF | SF_FORMAT_PCM_16,
55 		"CAF (Apple 16 bit PCM)", "caf"
56 		},
57 
58 #if HAVE_EXTERNAL_XIPH_LIBS
59 	{	SF_FORMAT_FLAC | SF_FORMAT_PCM_16,
60 		"FLAC 16 bit", "flac"
61 		},
62 #endif
63 
64 #if HAVE_MPEG
65 	{	SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III,
66 		"MPEG Layer 3", "mp3"
67 		},
68 #endif
69 
70 	{	SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM,
71 		"OKI Dialogic VOX ADPCM", "vox"
72 		},
73 
74 #if HAVE_EXTERNAL_XIPH_LIBS
75 	{	SF_FORMAT_OGG | SF_FORMAT_OPUS,
76 		"Ogg Opus (Xiph Foundation)", "opus"
77 		},
78 
79 	{	SF_FORMAT_OGG | SF_FORMAT_VORBIS,
80 		"Ogg Vorbis (Xiph Foundation)", "ogg"
81 		},
82 #endif
83 
84 	{	SF_FORMAT_WAV | SF_FORMAT_PCM_16,
85 		"WAV (Microsoft 16 bit PCM)", "wav"
86 		},
87 
88 	{	SF_FORMAT_WAV | SF_FORMAT_FLOAT,
89 		"WAV (Microsoft 32 bit float)", "wav"
90 		},
91 
92 	{	SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM,
93 		"WAV (Microsoft 4 bit IMA ADPCM)", "wav"
94 		},
95 
96 	{	SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM,
97 		"WAV (Microsoft 4 bit MS ADPCM)", "wav"
98 		},
99 
100 	{	SF_FORMAT_WAV | SF_FORMAT_PCM_U8,
101 		"WAV (Microsoft 8 bit PCM)", "wav"
102 		},
103 
104 } ; /* simple_formats */
105 
106 int
psf_get_format_simple_count(void)107 psf_get_format_simple_count	(void)
108 {	return (sizeof (simple_formats) / sizeof (SF_FORMAT_INFO)) ;
109 } /* psf_get_format_simple_count */
110 
111 int
psf_get_format_simple(SF_FORMAT_INFO * data)112 psf_get_format_simple (SF_FORMAT_INFO *data)
113 {	int indx ;
114 
115 	if (data->format < 0 || data->format >= (SIGNED_SIZEOF (simple_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
116 		return SFE_BAD_COMMAND_PARAM ;
117 
118 	indx = data->format ;
119 	memcpy (data, &(simple_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
120 
121 	return 0 ;
122 } /* psf_get_format_simple */
123 
124 /*============================================================================
125 ** Major format info.
126 */
127 
128 static SF_FORMAT_INFO const major_formats [] =
129 {
130 	{	SF_FORMAT_AIFF,		"AIFF (Apple/SGI)",						"aiff" 	},
131 	{	SF_FORMAT_AU,		"AU (Sun/NeXT)", 						"au"	},
132 	{	SF_FORMAT_AVR,		"AVR (Audio Visual Research)",			"avr"	},
133 	{	SF_FORMAT_CAF,		"CAF (Apple Core Audio File)",			"caf"	},
134 #if HAVE_EXTERNAL_XIPH_LIBS
135 	{	SF_FORMAT_FLAC,		"FLAC (Free Lossless Audio Codec)",		"flac"	},
136 #endif
137 	{	SF_FORMAT_HTK,		"HTK (HMM Tool Kit)",					"htk"	},
138 	{	SF_FORMAT_SVX,		"IFF (Amiga IFF/SVX8/SV16)",			"iff"	},
139 	{	SF_FORMAT_MAT4,		"MAT4 (GNU Octave 2.0 / Matlab 4.2)",	"mat"	},
140 	{	SF_FORMAT_MAT5,		"MAT5 (GNU Octave 2.1 / Matlab 5.0)",	"mat"	},
141 	{	SF_FORMAT_MPC2K,	"MPC (Akai MPC 2k)",					"mpc"	},
142 #if HAVE_MPEG
143 	{	SF_FORMAT_MPEG,		"MPEG-1/2 Audio",						"m1a"	},
144 #endif
145 #if HAVE_EXTERNAL_XIPH_LIBS
146 	{	SF_FORMAT_OGG,		"OGG (OGG Container format)",			"oga"	},
147 #endif
148 	{	SF_FORMAT_PAF,		"PAF (Ensoniq PARIS)", 					"paf"	},
149 	{	SF_FORMAT_PVF,		"PVF (Portable Voice Format)",			"pvf"	},
150 	{	SF_FORMAT_RAW,		"RAW (header-less)",					"raw"	},
151 	{	SF_FORMAT_RF64,		"RF64 (RIFF 64)",						"rf64"	},
152 	{	SF_FORMAT_SD2,		"SD2 (Sound Designer II)", 				"sd2"	},
153 	{	SF_FORMAT_SDS,		"SDS (Midi Sample Dump Standard)", 		"sds"	},
154 	{	SF_FORMAT_IRCAM,	"SF (Berkeley/IRCAM/CARL)",				"sf"	},
155 	{	SF_FORMAT_VOC,		"VOC (Creative Labs)",					"voc"	},
156 	{	SF_FORMAT_W64,		"W64 (SoundFoundry WAVE 64)",			"w64"	},
157 	{	SF_FORMAT_WAV,		"WAV (Microsoft)",						"wav"	},
158 	{	SF_FORMAT_NIST,		"WAV (NIST Sphere)",					"wav"	},
159 	{	SF_FORMAT_WAVEX,	"WAVEX (Microsoft)",					"wav"	},
160 	{	SF_FORMAT_WVE,		"WVE (Psion Series 3)",					"wve"	},
161 	{	SF_FORMAT_XI,		"XI (FastTracker 2)",					"xi"	},
162 
163 } ; /* major_formats */
164 
165 int
psf_get_format_major_count(void)166 psf_get_format_major_count	(void)
167 {	return (sizeof (major_formats) / sizeof (SF_FORMAT_INFO)) ;
168 } /* psf_get_format_major_count */
169 
170 int
psf_get_format_major(SF_FORMAT_INFO * data)171 psf_get_format_major (SF_FORMAT_INFO *data)
172 {	int indx ;
173 
174 	if (data->format < 0 || data->format >= (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
175 		return SFE_BAD_COMMAND_PARAM ;
176 
177 	indx = data->format ;
178 	memcpy (data, &(major_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
179 
180 	return 0 ;
181 } /* psf_get_format_major */
182 
183 /*============================================================================
184 ** Subtype format info.
185 */
186 
187 static SF_FORMAT_INFO subtype_formats [] =
188 {
189 	{	SF_FORMAT_PCM_S8,		"Signed 8 bit PCM",		NULL 	},
190 	{	SF_FORMAT_PCM_16,		"Signed 16 bit PCM",	NULL 	},
191 	{	SF_FORMAT_PCM_24,		"Signed 24 bit PCM",	NULL 	},
192 	{	SF_FORMAT_PCM_32,		"Signed 32 bit PCM",	NULL 	},
193 
194 	{	SF_FORMAT_PCM_U8,		"Unsigned 8 bit PCM",	NULL 	},
195 
196 	{	SF_FORMAT_FLOAT,		"32 bit float",			NULL 	},
197 	{	SF_FORMAT_DOUBLE,		"64 bit float",			NULL 	},
198 
199 	{	SF_FORMAT_ULAW,			"U-Law",				NULL 	},
200 	{	SF_FORMAT_ALAW,			"A-Law",				NULL 	},
201 	{	SF_FORMAT_IMA_ADPCM,	"IMA ADPCM",			NULL 	},
202 	{	SF_FORMAT_MS_ADPCM,		"Microsoft ADPCM",		NULL 	},
203 
204 	{	SF_FORMAT_GSM610,		"GSM 6.10",				NULL 	},
205 
206 	{	SF_FORMAT_G721_32,		"32kbs G721 ADPCM",		NULL 	},
207 	{	SF_FORMAT_G723_24,		"24kbs G723 ADPCM",		NULL 	},
208 	{	SF_FORMAT_G723_40,		"40kbs G723 ADPCM",		NULL	},
209 
210 	{	SF_FORMAT_DWVW_12,		"12 bit DWVW",			NULL 	},
211 	{	SF_FORMAT_DWVW_16,		"16 bit DWVW",			NULL 	},
212 	{	SF_FORMAT_DWVW_24,		"24 bit DWVW",			NULL 	},
213 	{	SF_FORMAT_VOX_ADPCM,	"VOX ADPCM",			"vox" 	},
214 
215 	{	SF_FORMAT_NMS_ADPCM_16,	"16kbs NMS ADPCM",		NULL	},
216 	{	SF_FORMAT_NMS_ADPCM_24,	"24kbs NMS ADPCM",		NULL	},
217 	{	SF_FORMAT_NMS_ADPCM_32,	"32kbs NMS ADPCM",		NULL	},
218 
219 	{	SF_FORMAT_DPCM_16,		"16 bit DPCM",			NULL 	},
220 	{	SF_FORMAT_DPCM_8,		"8 bit DPCM",			NULL 	},
221 
222 #if HAVE_EXTERNAL_XIPH_LIBS
223 	{	SF_FORMAT_VORBIS,		"Vorbis",				NULL 	},
224 	{	SF_FORMAT_OPUS,			"Opus",					NULL 	},
225 #endif
226 
227 #if HAVE_MPEG
228 	{	SF_FORMAT_MPEG_LAYER_I,		"MPEG Layer I",		"mp1"	},
229 	{	SF_FORMAT_MPEG_LAYER_II,	"MPEG Layer II",	"mp2"	},
230 	{	SF_FORMAT_MPEG_LAYER_III,	"MPEG Layer III",	"mp3"	},
231 #endif
232 
233 	{	SF_FORMAT_ALAC_16,		"16 bit ALAC",			NULL	},
234 	{	SF_FORMAT_ALAC_20,		"20 bit ALAC",			NULL	},
235 	{	SF_FORMAT_ALAC_24,		"24 bit ALAC",			NULL	},
236 	{	SF_FORMAT_ALAC_32,		"32 bit ALAC",			NULL	},
237 } ; /* subtype_formats */
238 
239 int
psf_get_format_subtype_count(void)240 psf_get_format_subtype_count	(void)
241 {	return (sizeof (subtype_formats) / sizeof (SF_FORMAT_INFO)) ;
242 } /* psf_get_format_subtype_count */
243 
244 int
psf_get_format_subtype(SF_FORMAT_INFO * data)245 psf_get_format_subtype (SF_FORMAT_INFO *data)
246 {	int indx ;
247 
248 	if (data->format < 0 || data->format >= (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
249 	{	data->format = 0 ;
250 		return SFE_BAD_COMMAND_PARAM ;
251 		} ;
252 
253 	indx = data->format ;
254 	memcpy (data, &(subtype_formats [indx]), sizeof (SF_FORMAT_INFO)) ;
255 
256 	return 0 ;
257 } /* psf_get_format_subtype */
258 
259 /*==============================================================================
260 */
261 
262 int
psf_get_format_info(SF_FORMAT_INFO * data)263 psf_get_format_info (SF_FORMAT_INFO *data)
264 {	int k, format ;
265 
266 	if (SF_CONTAINER (data->format))
267 	{	format = SF_CONTAINER (data->format) ;
268 
269 		for (k = 0 ; k < (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
270 		{	if (format == major_formats [k].format)
271 			{	memcpy (data, &(major_formats [k]), sizeof (SF_FORMAT_INFO)) ;
272 				return 0 ;
273 				} ;
274 			} ;
275 		}
276 	else if (SF_CODEC (data->format))
277 	{	format = SF_CODEC (data->format) ;
278 
279 		for (k = 0 ; k < (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
280 		{	if (format == subtype_formats [k].format)
281 			{	memcpy (data, &(subtype_formats [k]), sizeof (SF_FORMAT_INFO)) ;
282 				return 0 ;
283 				} ;
284 			} ;
285 		} ;
286 
287 	memset (data, 0, sizeof (SF_FORMAT_INFO)) ;
288 
289 	return SFE_BAD_COMMAND_PARAM ;
290 } /* psf_get_format_info */
291 
292 /*==============================================================================
293 */
294 
295 double
psf_calc_signal_max(SF_PRIVATE * psf,int normalize)296 psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
297 {	BUF_UNION	ubuf ;
298 	sf_count_t	position ;
299 	double 		max_val, temp, *data ;
300 	int			k, len, readcount, save_state ;
301 
302 	/* If the file is not seekable, there is nothing we can do. */
303 	if (! psf->sf.seekable)
304 	{	psf->error = SFE_NOT_SEEKABLE ;
305 		return	0.0 ;
306 		} ;
307 
308 	if (! psf->read_double)
309 	{	psf->error = SFE_UNIMPLEMENTED ;
310 		return	0.0 ;
311 		} ;
312 
313 	save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
314 	sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
315 
316 	/* Brute force. Read the whole file and find the biggest sample. */
317 	/* Get current position in file */
318 	position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ;
319 	/* Go to start of file. */
320 	sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;
321 
322 	data = ubuf.dbuf ;
323 	/* Make sure len is an integer multiple of the channel count. */
324 	len = ARRAY_LEN (ubuf.dbuf) - (ARRAY_LEN (ubuf.dbuf) % psf->sf.channels) ;
325 
326 	for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */)
327 	{	readcount = (int) sf_read_double ((SNDFILE*) psf, data, len) ;
328 		for (k = 0 ; k < readcount ; k++)
329 		{	temp = fabs (data [k]) ;
330 			max_val = temp > max_val ? temp : max_val ;
331 			} ;
332 		} ;
333 
334 	/* Return to SNDFILE to original state. */
335 	sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;
336 	sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
337 
338 	return	max_val ;
339 } /* psf_calc_signal_max */
340 
341 int
psf_calc_max_all_channels(SF_PRIVATE * psf,double * peaks,int normalize)342 psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
343 {	BUF_UNION	ubuf ;
344 	sf_count_t	position ;
345 	double 		temp, *data ;
346 	int			k, len, readcount, save_state ;
347 	int			chan ;
348 
349 	/* If the file is not seekable, there is nothing we can do. */
350 	if (! psf->sf.seekable)
351 		return (psf->error = SFE_NOT_SEEKABLE) ;
352 
353 	if (! psf->read_double)
354 		return (psf->error = SFE_UNIMPLEMENTED) ;
355 
356 	save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
357 	sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
358 
359 	memset (peaks, 0, sizeof (double) * psf->sf.channels) ;
360 
361 	/* Brute force. Read the whole file and find the biggest sample for each channel. */
362 	position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Get current position in file */
363 	sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;			/* Go to start of file. */
364 
365 	len = ARRAY_LEN (ubuf.dbuf) - (ARRAY_LEN (ubuf.dbuf) % psf->sf.channels) ;
366 
367 	data = ubuf.dbuf ;
368 
369 	chan = 0 ;
370 	readcount = len ;
371 	while (readcount > 0)
372 	{	readcount = (int) sf_read_double ((SNDFILE*) psf, data, len) ;
373 		for (k = 0 ; k < readcount ; k++)
374 		{	temp = fabs (data [k]) ;
375 			peaks [chan] = temp > peaks [chan] ? temp : peaks [chan] ;
376 			chan = (chan + 1) % psf->sf.channels ;
377 			} ;
378 		} ;
379 
380 	sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;		/* Return to original position. */
381 
382 	sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
383 
384 	return	0 ;
385 } /* psf_calc_max_all_channels */
386 
387 int
psf_get_signal_max(SF_PRIVATE * psf,double * peak)388 psf_get_signal_max (SF_PRIVATE *psf, double *peak)
389 {	int k ;
390 
391 	if (psf->peak_info == NULL)
392 		return SF_FALSE ;
393 
394 	peak [0] = psf->peak_info->peaks [0].value ;
395 
396 	for (k = 1 ; k < psf->sf.channels ; k++)
397 		peak [0] = SF_MAX (peak [0], psf->peak_info->peaks [k].value) ;
398 
399 	return SF_TRUE ;
400 } /* psf_get_signal_max */
401 
402 int
psf_get_max_all_channels(SF_PRIVATE * psf,double * peaks)403 psf_get_max_all_channels (SF_PRIVATE *psf, double *peaks)
404 {	int k ;
405 
406 	if (psf->peak_info == NULL)
407 		return SF_FALSE ;
408 
409 	for (k = 0 ; k < psf->sf.channels ; k++)
410 		peaks [k] = psf->peak_info->peaks [k].value ;
411 
412 	return SF_TRUE ;
413 } /* psf_get_max_all_channels */
414 
415 
416