Coverage Report

Created: 2025-11-03 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libsndfile/src/command.c
Line
Count
Source
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
107
psf_get_format_simple_count (void)
108
0
{ return (sizeof (simple_formats) / sizeof (SF_FORMAT_INFO)) ;
109
0
} /* psf_get_format_simple_count */
110
111
int
112
psf_get_format_simple (SF_FORMAT_INFO *data)
113
0
{ int indx ;
114
115
0
  if (data->format < 0 || data->format >= (SIGNED_SIZEOF (simple_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
116
0
    return SFE_BAD_COMMAND_PARAM ;
117
118
0
  indx = data->format ;
119
0
  memcpy (data, &(simple_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
120
121
0
  return 0 ;
122
0
} /* 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
166
psf_get_format_major_count  (void)
167
0
{ return (sizeof (major_formats) / sizeof (SF_FORMAT_INFO)) ;
168
0
} /* psf_get_format_major_count */
169
170
int
171
psf_get_format_major (SF_FORMAT_INFO *data)
172
0
{ int indx ;
173
174
0
  if (data->format < 0 || data->format >= (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
175
0
    return SFE_BAD_COMMAND_PARAM ;
176
177
0
  indx = data->format ;
178
0
  memcpy (data, &(major_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
179
180
0
  return 0 ;
181
0
} /* 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
240
psf_get_format_subtype_count  (void)
241
0
{ return (sizeof (subtype_formats) / sizeof (SF_FORMAT_INFO)) ;
242
0
} /* psf_get_format_subtype_count */
243
244
int
245
psf_get_format_subtype (SF_FORMAT_INFO *data)
246
0
{ int indx ;
247
248
0
  if (data->format < 0 || data->format >= (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
249
0
  { data->format = 0 ;
250
0
    return SFE_BAD_COMMAND_PARAM ;
251
0
    } ;
252
253
0
  indx = data->format ;
254
0
  memcpy (data, &(subtype_formats [indx]), sizeof (SF_FORMAT_INFO)) ;
255
256
0
  return 0 ;
257
0
} /* psf_get_format_subtype */
258
259
/*==============================================================================
260
*/
261
262
int
263
psf_get_format_info (SF_FORMAT_INFO *data)
264
0
{ int k, format ;
265
266
0
  if (SF_CONTAINER (data->format))
267
0
  { format = SF_CONTAINER (data->format) ;
268
269
0
    for (k = 0 ; k < (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
270
0
    { if (format == major_formats [k].format)
271
0
      { memcpy (data, &(major_formats [k]), sizeof (SF_FORMAT_INFO)) ;
272
0
        return 0 ;
273
0
        } ;
274
0
      } ;
275
0
    }
276
0
  else if (SF_CODEC (data->format))
277
0
  { format = SF_CODEC (data->format) ;
278
279
0
    for (k = 0 ; k < (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
280
0
    { if (format == subtype_formats [k].format)
281
0
      { memcpy (data, &(subtype_formats [k]), sizeof (SF_FORMAT_INFO)) ;
282
0
        return 0 ;
283
0
        } ;
284
0
      } ;
285
0
    } ;
286
287
0
  memset (data, 0, sizeof (SF_FORMAT_INFO)) ;
288
289
0
  return SFE_BAD_COMMAND_PARAM ;
290
0
} /* psf_get_format_info */
291
292
/*==============================================================================
293
*/
294
295
double
296
psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
297
0
{ BUF_UNION ubuf ;
298
0
  sf_count_t  position ;
299
0
  double    max_val, temp, *data ;
300
0
  int     k, len, readcount, save_state ;
301
302
  /* If the file is not seekable, there is nothing we can do. */
303
0
  if (! psf->sf.seekable)
304
0
  { psf->error = SFE_NOT_SEEKABLE ;
305
0
    return  0.0 ;
306
0
    } ;
307
308
0
  if (! psf->read_double)
309
0
  { psf->error = SFE_UNIMPLEMENTED ;
310
0
    return  0.0 ;
311
0
    } ;
312
313
0
  save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
314
0
  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
0
  position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ;
319
  /* Go to start of file. */
320
0
  sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;
321
322
0
  data = ubuf.dbuf ;
323
  /* Make sure len is an integer multiple of the channel count. */
324
0
  len = ARRAY_LEN (ubuf.dbuf) - (ARRAY_LEN (ubuf.dbuf) % psf->sf.channels) ;
325
326
0
  for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */)
327
0
  { readcount = (int) sf_read_double ((SNDFILE*) psf, data, len) ;
328
0
    for (k = 0 ; k < readcount ; k++)
329
0
    { temp = fabs (data [k]) ;
330
0
      max_val = temp > max_val ? temp : max_val ;
331
0
      } ;
332
0
    } ;
333
334
  /* Return to SNDFILE to original state. */
335
0
  sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;
336
0
  sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
337
338
0
  return  max_val ;
339
0
} /* psf_calc_signal_max */
340
341
int
342
psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
343
0
{ BUF_UNION ubuf ;
344
0
  sf_count_t  position ;
345
0
  double    temp, *data ;
346
0
  int     k, len, readcount, save_state ;
347
0
  int     chan ;
348
349
  /* If the file is not seekable, there is nothing we can do. */
350
0
  if (! psf->sf.seekable)
351
0
    return (psf->error = SFE_NOT_SEEKABLE) ;
352
353
0
  if (! psf->read_double)
354
0
    return (psf->error = SFE_UNIMPLEMENTED) ;
355
356
0
  save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
357
0
  sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
358
359
0
  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
0
  position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Get current position in file */
363
0
  sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;     /* Go to start of file. */
364
365
0
  len = ARRAY_LEN (ubuf.dbuf) - (ARRAY_LEN (ubuf.dbuf) % psf->sf.channels) ;
366
367
0
  data = ubuf.dbuf ;
368
369
0
  chan = 0 ;
370
0
  readcount = len ;
371
0
  while (readcount > 0)
372
0
  { readcount = (int) sf_read_double ((SNDFILE*) psf, data, len) ;
373
0
    for (k = 0 ; k < readcount ; k++)
374
0
    { temp = fabs (data [k]) ;
375
0
      peaks [chan] = temp > peaks [chan] ? temp : peaks [chan] ;
376
0
      chan = (chan + 1) % psf->sf.channels ;
377
0
      } ;
378
0
    } ;
379
380
0
  sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;   /* Return to original position. */
381
382
0
  sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
383
384
0
  return  0 ;
385
0
} /* psf_calc_max_all_channels */
386
387
int
388
psf_get_signal_max (SF_PRIVATE *psf, double *peak)
389
0
{ int k ;
390
391
0
  if (psf->peak_info == NULL)
392
0
    return SF_FALSE ;
393
394
0
  peak [0] = psf->peak_info->peaks [0].value ;
395
396
0
  for (k = 1 ; k < psf->sf.channels ; k++)
397
0
    peak [0] = SF_MAX (peak [0], psf->peak_info->peaks [k].value) ;
398
399
0
  return SF_TRUE ;
400
0
} /* psf_get_signal_max */
401
402
int
403
psf_get_max_all_channels (SF_PRIVATE *psf, double *peaks)
404
0
{ int k ;
405
406
0
  if (psf->peak_info == NULL)
407
0
    return SF_FALSE ;
408
409
0
  for (k = 0 ; k < psf->sf.channels ; k++)
410
0
    peaks [k] = psf->peak_info->peaks [k].value ;
411
412
0
  return SF_TRUE ;
413
0
} /* psf_get_max_all_channels */
414
415