1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci** Copyright (C) 1999-2019 Erik de Castro Lopo <erikd@mega-nerd.com> 3b815c7f3Sopenharmony_ci** Copyright (C) 2008 George Blood Audio 4b815c7f3Sopenharmony_ci** 5b815c7f3Sopenharmony_ci** All rights reserved. 6b815c7f3Sopenharmony_ci** 7b815c7f3Sopenharmony_ci** Redistribution and use in source and binary forms, with or without 8b815c7f3Sopenharmony_ci** modification, are permitted provided that the following conditions are 9b815c7f3Sopenharmony_ci** met: 10b815c7f3Sopenharmony_ci** 11b815c7f3Sopenharmony_ci** * Redistributions of source code must retain the above copyright 12b815c7f3Sopenharmony_ci** notice, this list of conditions and the following disclaimer. 13b815c7f3Sopenharmony_ci** * Redistributions in binary form must reproduce the above copyright 14b815c7f3Sopenharmony_ci** notice, this list of conditions and the following disclaimer in 15b815c7f3Sopenharmony_ci** the documentation and/or other materials provided with the 16b815c7f3Sopenharmony_ci** distribution. 17b815c7f3Sopenharmony_ci** * Neither the author nor the names of any contributors may be used 18b815c7f3Sopenharmony_ci** to endorse or promote products derived from this software without 19b815c7f3Sopenharmony_ci** specific prior written permission. 20b815c7f3Sopenharmony_ci** 21b815c7f3Sopenharmony_ci** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22b815c7f3Sopenharmony_ci** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23b815c7f3Sopenharmony_ci** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24b815c7f3Sopenharmony_ci** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 25b815c7f3Sopenharmony_ci** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26b815c7f3Sopenharmony_ci** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27b815c7f3Sopenharmony_ci** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28b815c7f3Sopenharmony_ci** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29b815c7f3Sopenharmony_ci** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30b815c7f3Sopenharmony_ci** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31b815c7f3Sopenharmony_ci** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32b815c7f3Sopenharmony_ci*/ 33b815c7f3Sopenharmony_ci 34b815c7f3Sopenharmony_ci#include <stdio.h> 35b815c7f3Sopenharmony_ci#include <stdlib.h> 36b815c7f3Sopenharmony_ci#include <string.h> 37b815c7f3Sopenharmony_ci#include <ctype.h> 38b815c7f3Sopenharmony_ci#include <stdint.h> 39b815c7f3Sopenharmony_ci#include <math.h> 40b815c7f3Sopenharmony_ci 41b815c7f3Sopenharmony_ci#include <sndfile.h> 42b815c7f3Sopenharmony_ci 43b815c7f3Sopenharmony_ci#include "common.h" 44b815c7f3Sopenharmony_ci 45b815c7f3Sopenharmony_ci#define BUFFER_LEN 4096 46b815c7f3Sopenharmony_ci 47b815c7f3Sopenharmony_ci#define MIN(x, y) ((x) < (y) ? (x) : (y)) 48b815c7f3Sopenharmony_ci 49b815c7f3Sopenharmony_ciint 50b815c7f3Sopenharmony_cisfe_copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels, int normalize) 51b815c7f3Sopenharmony_ci{ static double data [BUFFER_LEN], max ; 52b815c7f3Sopenharmony_ci sf_count_t frames, readcount, k ; 53b815c7f3Sopenharmony_ci 54b815c7f3Sopenharmony_ci frames = BUFFER_LEN / channels ; 55b815c7f3Sopenharmony_ci readcount = frames ; 56b815c7f3Sopenharmony_ci 57b815c7f3Sopenharmony_ci sf_command (infile, SFC_CALC_SIGNAL_MAX, &max, sizeof (max)) ; 58b815c7f3Sopenharmony_ci if (!isnormal (max)) /* neither zero, subnormal, infinite, nor NaN */ 59b815c7f3Sopenharmony_ci return 1 ; 60b815c7f3Sopenharmony_ci 61b815c7f3Sopenharmony_ci if (!normalize && max < 1.0) 62b815c7f3Sopenharmony_ci { while (readcount > 0) 63b815c7f3Sopenharmony_ci { readcount = sf_readf_double (infile, data, frames) ; 64b815c7f3Sopenharmony_ci sf_writef_double (outfile, data, readcount) ; 65b815c7f3Sopenharmony_ci } ; 66b815c7f3Sopenharmony_ci } 67b815c7f3Sopenharmony_ci else 68b815c7f3Sopenharmony_ci { sf_command (infile, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 69b815c7f3Sopenharmony_ci 70b815c7f3Sopenharmony_ci while (readcount > 0) 71b815c7f3Sopenharmony_ci { readcount = sf_readf_double (infile, data, frames) ; 72b815c7f3Sopenharmony_ci for (k = 0 ; k < readcount * channels ; k++) 73b815c7f3Sopenharmony_ci { data [k] /= max ; 74b815c7f3Sopenharmony_ci 75b815c7f3Sopenharmony_ci if (!isfinite (data [k])) /* infinite or NaN */ 76b815c7f3Sopenharmony_ci return 1 ; 77b815c7f3Sopenharmony_ci } 78b815c7f3Sopenharmony_ci sf_writef_double (outfile, data, readcount) ; 79b815c7f3Sopenharmony_ci } ; 80b815c7f3Sopenharmony_ci } ; 81b815c7f3Sopenharmony_ci 82b815c7f3Sopenharmony_ci return 0 ; 83b815c7f3Sopenharmony_ci} /* sfe_copy_data_fp */ 84b815c7f3Sopenharmony_ci 85b815c7f3Sopenharmony_civoid 86b815c7f3Sopenharmony_cisfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) 87b815c7f3Sopenharmony_ci{ static int data [BUFFER_LEN] ; 88b815c7f3Sopenharmony_ci int frames, readcount ; 89b815c7f3Sopenharmony_ci 90b815c7f3Sopenharmony_ci frames = BUFFER_LEN / channels ; 91b815c7f3Sopenharmony_ci readcount = frames ; 92b815c7f3Sopenharmony_ci 93b815c7f3Sopenharmony_ci while (readcount > 0) 94b815c7f3Sopenharmony_ci { readcount = (int) sf_readf_int (infile, data, frames) ; 95b815c7f3Sopenharmony_ci sf_writef_int (outfile, data, readcount) ; 96b815c7f3Sopenharmony_ci } ; 97b815c7f3Sopenharmony_ci 98b815c7f3Sopenharmony_ci return ; 99b815c7f3Sopenharmony_ci} /* sfe_copy_data_int */ 100b815c7f3Sopenharmony_ci 101b815c7f3Sopenharmony_ci/*============================================================================== 102b815c7f3Sopenharmony_ci*/ 103b815c7f3Sopenharmony_ci 104b815c7f3Sopenharmony_cistatic int 105b815c7f3Sopenharmony_cimerge_broadcast_info (SNDFILE * infile, SNDFILE * outfile, int format, const METADATA_INFO * info) 106b815c7f3Sopenharmony_ci{ SF_BROADCAST_INFO_2K binfo ; 107b815c7f3Sopenharmony_ci int infileminor ; 108b815c7f3Sopenharmony_ci 109b815c7f3Sopenharmony_ci memset (&binfo, 0, sizeof (binfo)) ; 110b815c7f3Sopenharmony_ci 111b815c7f3Sopenharmony_ci if ((SF_FORMAT_TYPEMASK & format) != SF_FORMAT_WAV) 112b815c7f3Sopenharmony_ci { printf ("Error : This is not a WAV file and hence broadcast info cannot be added to it.\n\n") ; 113b815c7f3Sopenharmony_ci return 1 ; 114b815c7f3Sopenharmony_ci } ; 115b815c7f3Sopenharmony_ci 116b815c7f3Sopenharmony_ci infileminor = SF_FORMAT_SUBMASK & format ; 117b815c7f3Sopenharmony_ci 118b815c7f3Sopenharmony_ci switch (infileminor) 119b815c7f3Sopenharmony_ci { case SF_FORMAT_PCM_16 : 120b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_24 : 121b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_32 : 122b815c7f3Sopenharmony_ci case SF_FORMAT_MPEG_LAYER_III : 123b815c7f3Sopenharmony_ci break ; 124b815c7f3Sopenharmony_ci 125b815c7f3Sopenharmony_ci default : 126b815c7f3Sopenharmony_ci printf ( 127b815c7f3Sopenharmony_ci "Warning : The EBU Technical Recommendation R68-2000 states that the only\n" 128b815c7f3Sopenharmony_ci " allowed encodings are Linear PCM and MPEG3. This file is not in\n" 129b815c7f3Sopenharmony_ci " the right format.\n\n" 130b815c7f3Sopenharmony_ci ) ; 131b815c7f3Sopenharmony_ci break ; 132b815c7f3Sopenharmony_ci } ; 133b815c7f3Sopenharmony_ci 134b815c7f3Sopenharmony_ci if (sf_command (infile, SFC_GET_BROADCAST_INFO, &binfo, sizeof (binfo)) == 0) 135b815c7f3Sopenharmony_ci { if (infile == outfile) 136b815c7f3Sopenharmony_ci { printf ( 137b815c7f3Sopenharmony_ci "Error : Attempting in-place broadcast info update, but file does not\n" 138b815c7f3Sopenharmony_ci " have a 'bext' chunk to modify. The solution is to specify both\n" 139b815c7f3Sopenharmony_ci " input and output files on the command line.\n\n" 140b815c7f3Sopenharmony_ci ) ; 141b815c7f3Sopenharmony_ci return 1 ; 142b815c7f3Sopenharmony_ci } ; 143b815c7f3Sopenharmony_ci } ; 144b815c7f3Sopenharmony_ci 145b815c7f3Sopenharmony_ci#define REPLACE_IF_NEW(x) \ 146b815c7f3Sopenharmony_ci if (info->x != NULL) \ 147b815c7f3Sopenharmony_ci { memset (binfo.x, 0, sizeof (binfo.x)) ; \ 148b815c7f3Sopenharmony_ci memcpy (binfo.x, info->x, MIN (strlen (info->x), sizeof (binfo.x))) ; \ 149b815c7f3Sopenharmony_ci } ; 150b815c7f3Sopenharmony_ci 151b815c7f3Sopenharmony_ci REPLACE_IF_NEW (description) ; 152b815c7f3Sopenharmony_ci REPLACE_IF_NEW (originator) ; 153b815c7f3Sopenharmony_ci REPLACE_IF_NEW (originator_reference) ; 154b815c7f3Sopenharmony_ci REPLACE_IF_NEW (origination_date) ; 155b815c7f3Sopenharmony_ci REPLACE_IF_NEW (origination_time) ; 156b815c7f3Sopenharmony_ci REPLACE_IF_NEW (umid) ; 157b815c7f3Sopenharmony_ci 158b815c7f3Sopenharmony_ci /* Special case loudness values */ 159b815c7f3Sopenharmony_ci#define REPLACE_IF_NEW_INT(x) \ 160b815c7f3Sopenharmony_ci if (info->x != NULL) \ 161b815c7f3Sopenharmony_ci { binfo.x = round (atof (info->x) * 100.0) ; \ 162b815c7f3Sopenharmony_ci } ; 163b815c7f3Sopenharmony_ci 164b815c7f3Sopenharmony_ci REPLACE_IF_NEW_INT (loudness_value) ; 165b815c7f3Sopenharmony_ci REPLACE_IF_NEW_INT (loudness_range) ; 166b815c7f3Sopenharmony_ci REPLACE_IF_NEW_INT (max_true_peak_level) ; 167b815c7f3Sopenharmony_ci REPLACE_IF_NEW_INT (max_momentary_loudness) ; 168b815c7f3Sopenharmony_ci REPLACE_IF_NEW_INT (max_shortterm_loudness) ; 169b815c7f3Sopenharmony_ci 170b815c7f3Sopenharmony_ci /* Special case for Time Ref. */ 171b815c7f3Sopenharmony_ci if (info->time_ref != NULL) 172b815c7f3Sopenharmony_ci { uint64_t ts = atoll (info->time_ref) ; 173b815c7f3Sopenharmony_ci 174b815c7f3Sopenharmony_ci binfo.time_reference_high = (ts >> 32) ; 175b815c7f3Sopenharmony_ci binfo.time_reference_low = (ts & 0xffffffff) ; 176b815c7f3Sopenharmony_ci } ; 177b815c7f3Sopenharmony_ci 178b815c7f3Sopenharmony_ci /* Special case for coding_history because we may want to append. */ 179b815c7f3Sopenharmony_ci if (info->coding_history != NULL) 180b815c7f3Sopenharmony_ci { if (info->coding_hist_append) 181b815c7f3Sopenharmony_ci { int slen = (int) strlen (binfo.coding_history) ; 182b815c7f3Sopenharmony_ci 183b815c7f3Sopenharmony_ci while (slen > 1 && isspace (binfo.coding_history [slen - 1])) 184b815c7f3Sopenharmony_ci slen -- ; 185b815c7f3Sopenharmony_ci 186b815c7f3Sopenharmony_ci memcpy (binfo.coding_history + slen, info->coding_history, sizeof (binfo.coding_history) - slen) ; 187b815c7f3Sopenharmony_ci } 188b815c7f3Sopenharmony_ci else 189b815c7f3Sopenharmony_ci { size_t slen = MIN (strlen (info->coding_history), sizeof (binfo.coding_history)) ; 190b815c7f3Sopenharmony_ci 191b815c7f3Sopenharmony_ci memset (binfo.coding_history, 0, sizeof (binfo.coding_history)) ; 192b815c7f3Sopenharmony_ci memcpy (binfo.coding_history, info->coding_history, slen) ; 193b815c7f3Sopenharmony_ci binfo.coding_history_size = (uint32_t) slen ; 194b815c7f3Sopenharmony_ci } ; 195b815c7f3Sopenharmony_ci } ; 196b815c7f3Sopenharmony_ci 197b815c7f3Sopenharmony_ci if (sf_command (outfile, SFC_SET_BROADCAST_INFO, &binfo, sizeof (binfo)) == 0) 198b815c7f3Sopenharmony_ci { printf ("Error : Setting of broadcast info chunks failed.\n\n") ; 199b815c7f3Sopenharmony_ci return 1 ; 200b815c7f3Sopenharmony_ci } ; 201b815c7f3Sopenharmony_ci 202b815c7f3Sopenharmony_ci return 0 ; 203b815c7f3Sopenharmony_ci} /* merge_broadcast_info*/ 204b815c7f3Sopenharmony_ci 205b815c7f3Sopenharmony_cistatic void 206b815c7f3Sopenharmony_ciupdate_strings (SNDFILE * outfile, const METADATA_INFO * info) 207b815c7f3Sopenharmony_ci{ 208b815c7f3Sopenharmony_ci if (info->title != NULL) 209b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_TITLE, info->title) ; 210b815c7f3Sopenharmony_ci 211b815c7f3Sopenharmony_ci if (info->copyright != NULL) 212b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_COPYRIGHT, info->copyright) ; 213b815c7f3Sopenharmony_ci 214b815c7f3Sopenharmony_ci if (info->artist != NULL) 215b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_ARTIST, info->artist) ; 216b815c7f3Sopenharmony_ci 217b815c7f3Sopenharmony_ci if (info->comment != NULL) 218b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_COMMENT, info->comment) ; 219b815c7f3Sopenharmony_ci 220b815c7f3Sopenharmony_ci if (info->date != NULL) 221b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_DATE, info->date) ; 222b815c7f3Sopenharmony_ci 223b815c7f3Sopenharmony_ci if (info->album != NULL) 224b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_ALBUM, info->album) ; 225b815c7f3Sopenharmony_ci 226b815c7f3Sopenharmony_ci if (info->license != NULL) 227b815c7f3Sopenharmony_ci sf_set_string (outfile, SF_STR_LICENSE, info->license) ; 228b815c7f3Sopenharmony_ci 229b815c7f3Sopenharmony_ci} /* update_strings */ 230b815c7f3Sopenharmony_ci 231b815c7f3Sopenharmony_ci 232b815c7f3Sopenharmony_ci 233b815c7f3Sopenharmony_civoid 234b815c7f3Sopenharmony_cisfe_apply_metadata_changes (const char * filenames [2], const METADATA_INFO * info) 235b815c7f3Sopenharmony_ci{ SNDFILE *infile = NULL, *outfile = NULL ; 236b815c7f3Sopenharmony_ci SF_INFO sfinfo ; 237b815c7f3Sopenharmony_ci METADATA_INFO tmpinfo ; 238b815c7f3Sopenharmony_ci int error_code = 0 ; 239b815c7f3Sopenharmony_ci 240b815c7f3Sopenharmony_ci memset (&sfinfo, 0, sizeof (sfinfo)) ; 241b815c7f3Sopenharmony_ci memset (&tmpinfo, 0, sizeof (tmpinfo)) ; 242b815c7f3Sopenharmony_ci 243b815c7f3Sopenharmony_ci if (filenames [1] == NULL) 244b815c7f3Sopenharmony_ci infile = outfile = sf_open (filenames [0], SFM_RDWR, &sfinfo) ; 245b815c7f3Sopenharmony_ci else 246b815c7f3Sopenharmony_ci { infile = sf_open (filenames [0], SFM_READ, &sfinfo) ; 247b815c7f3Sopenharmony_ci 248b815c7f3Sopenharmony_ci /* Output must be WAV. */ 249b815c7f3Sopenharmony_ci sfinfo.format = SF_FORMAT_WAV | (SF_FORMAT_SUBMASK & sfinfo.format) ; 250b815c7f3Sopenharmony_ci outfile = sf_open (filenames [1], SFM_WRITE, &sfinfo) ; 251b815c7f3Sopenharmony_ci } ; 252b815c7f3Sopenharmony_ci 253b815c7f3Sopenharmony_ci if (infile == NULL) 254b815c7f3Sopenharmony_ci { printf ("Error : Not able to open input file '%s' : %s\n", filenames [0], sf_strerror (infile)) ; 255b815c7f3Sopenharmony_ci error_code = 1 ; 256b815c7f3Sopenharmony_ci goto cleanup_exit ; 257b815c7f3Sopenharmony_ci } ; 258b815c7f3Sopenharmony_ci 259b815c7f3Sopenharmony_ci if (outfile == NULL) 260b815c7f3Sopenharmony_ci { printf ("Error : Not able to open output file '%s' : %s\n", filenames [1], sf_strerror (outfile)) ; 261b815c7f3Sopenharmony_ci error_code = 1 ; 262b815c7f3Sopenharmony_ci goto cleanup_exit ; 263b815c7f3Sopenharmony_ci } ; 264b815c7f3Sopenharmony_ci 265b815c7f3Sopenharmony_ci if (info->has_bext_fields && merge_broadcast_info (infile, outfile, sfinfo.format, info)) 266b815c7f3Sopenharmony_ci { error_code = 1 ; 267b815c7f3Sopenharmony_ci goto cleanup_exit ; 268b815c7f3Sopenharmony_ci } ; 269b815c7f3Sopenharmony_ci 270b815c7f3Sopenharmony_ci if (infile != outfile) 271b815c7f3Sopenharmony_ci { int infileminor = SF_FORMAT_SUBMASK & sfinfo.format ; 272b815c7f3Sopenharmony_ci 273b815c7f3Sopenharmony_ci /* If the input file is not the same as the output file, copy the data. */ 274b815c7f3Sopenharmony_ci if ((infileminor == SF_FORMAT_DOUBLE) || (infileminor == SF_FORMAT_FLOAT)) 275b815c7f3Sopenharmony_ci { if (sfe_copy_data_fp (outfile, infile, sfinfo.channels, SF_FALSE) != 0) 276b815c7f3Sopenharmony_ci { printf ("Error : Not able to decode input file '%s'\n", filenames [0]) ; 277b815c7f3Sopenharmony_ci error_code = 1 ; 278b815c7f3Sopenharmony_ci goto cleanup_exit ; 279b815c7f3Sopenharmony_ci } ; 280b815c7f3Sopenharmony_ci } 281b815c7f3Sopenharmony_ci else 282b815c7f3Sopenharmony_ci sfe_copy_data_int (outfile, infile, sfinfo.channels) ; 283b815c7f3Sopenharmony_ci } ; 284b815c7f3Sopenharmony_ci 285b815c7f3Sopenharmony_ci update_strings (outfile, info) ; 286b815c7f3Sopenharmony_ci 287b815c7f3Sopenharmony_cicleanup_exit : 288b815c7f3Sopenharmony_ci 289b815c7f3Sopenharmony_ci if (outfile != NULL && outfile != infile) 290b815c7f3Sopenharmony_ci sf_close (outfile) ; 291b815c7f3Sopenharmony_ci 292b815c7f3Sopenharmony_ci if (infile != NULL) 293b815c7f3Sopenharmony_ci sf_close (infile) ; 294b815c7f3Sopenharmony_ci 295b815c7f3Sopenharmony_ci if (error_code) 296b815c7f3Sopenharmony_ci exit (error_code) ; 297b815c7f3Sopenharmony_ci 298b815c7f3Sopenharmony_ci return ; 299b815c7f3Sopenharmony_ci} /* sfe_apply_metadata_changes */ 300b815c7f3Sopenharmony_ci 301b815c7f3Sopenharmony_ci/*============================================================================== 302b815c7f3Sopenharmony_ci*/ 303b815c7f3Sopenharmony_ci 304b815c7f3Sopenharmony_citypedef struct 305b815c7f3Sopenharmony_ci{ const char *ext ; 306b815c7f3Sopenharmony_ci int len ; 307b815c7f3Sopenharmony_ci int format ; 308b815c7f3Sopenharmony_ci} OUTPUT_FORMAT_MAP ; 309b815c7f3Sopenharmony_ci 310b815c7f3Sopenharmony_ci/* Map a file name extension to a container format. */ 311b815c7f3Sopenharmony_cistatic OUTPUT_FORMAT_MAP format_map [] = 312b815c7f3Sopenharmony_ci{ 313b815c7f3Sopenharmony_ci { "wav", 0, SF_FORMAT_WAV }, 314b815c7f3Sopenharmony_ci { "aif", 3, SF_FORMAT_AIFF }, 315b815c7f3Sopenharmony_ci { "au", 0, SF_FORMAT_AU }, 316b815c7f3Sopenharmony_ci { "snd", 0, SF_FORMAT_AU }, 317b815c7f3Sopenharmony_ci { "raw", 0, SF_FORMAT_RAW }, 318b815c7f3Sopenharmony_ci { "gsm", 0, SF_FORMAT_RAW | SF_FORMAT_GSM610 }, 319b815c7f3Sopenharmony_ci { "vox", 0, SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM }, 320b815c7f3Sopenharmony_ci { "paf", 0, SF_FORMAT_PAF | SF_ENDIAN_BIG }, 321b815c7f3Sopenharmony_ci { "fap", 0, SF_FORMAT_PAF | SF_ENDIAN_LITTLE }, 322b815c7f3Sopenharmony_ci { "svx", 0, SF_FORMAT_SVX }, 323b815c7f3Sopenharmony_ci { "nist", 0, SF_FORMAT_NIST }, 324b815c7f3Sopenharmony_ci { "sph", 0, SF_FORMAT_NIST }, 325b815c7f3Sopenharmony_ci { "voc", 0, SF_FORMAT_VOC }, 326b815c7f3Sopenharmony_ci { "ircam", 0, SF_FORMAT_IRCAM }, 327b815c7f3Sopenharmony_ci { "sf", 0, SF_FORMAT_IRCAM }, 328b815c7f3Sopenharmony_ci { "w64", 0, SF_FORMAT_W64 }, 329b815c7f3Sopenharmony_ci { "mat", 0, SF_FORMAT_MAT4 }, 330b815c7f3Sopenharmony_ci { "mat4", 0, SF_FORMAT_MAT4 }, 331b815c7f3Sopenharmony_ci { "mat5", 0, SF_FORMAT_MAT5 }, 332b815c7f3Sopenharmony_ci { "pvf", 0, SF_FORMAT_PVF }, 333b815c7f3Sopenharmony_ci { "xi", 0, SF_FORMAT_XI }, 334b815c7f3Sopenharmony_ci { "htk", 0, SF_FORMAT_HTK }, 335b815c7f3Sopenharmony_ci { "sds", 0, SF_FORMAT_SDS }, 336b815c7f3Sopenharmony_ci { "avr", 0, SF_FORMAT_AVR }, 337b815c7f3Sopenharmony_ci { "wavex", 0, SF_FORMAT_WAVEX }, 338b815c7f3Sopenharmony_ci { "sd2", 0, SF_FORMAT_SD2 }, 339b815c7f3Sopenharmony_ci { "flac", 0, SF_FORMAT_FLAC }, 340b815c7f3Sopenharmony_ci { "caf", 0, SF_FORMAT_CAF }, 341b815c7f3Sopenharmony_ci { "wve", 0, SF_FORMAT_WVE }, 342b815c7f3Sopenharmony_ci { "prc", 0, SF_FORMAT_WVE }, 343b815c7f3Sopenharmony_ci { "oga", 0, SF_FORMAT_OGG }, 344b815c7f3Sopenharmony_ci { "ogg", 0, SF_FORMAT_OGG | SF_FORMAT_VORBIS }, 345b815c7f3Sopenharmony_ci { "opus", 0, SF_FORMAT_OGG | SF_FORMAT_OPUS }, 346b815c7f3Sopenharmony_ci { "mpc", 0, SF_FORMAT_MPC2K }, 347b815c7f3Sopenharmony_ci { "rf64", 0, SF_FORMAT_RF64 }, 348b815c7f3Sopenharmony_ci { "mp3", 0, SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III }, 349b815c7f3Sopenharmony_ci} ; /* format_map */ 350b815c7f3Sopenharmony_ci 351b815c7f3Sopenharmony_ciint 352b815c7f3Sopenharmony_cisfe_file_type_of_ext (const char *str, int format) 353b815c7f3Sopenharmony_ci{ char buffer [16], *cptr ; 354b815c7f3Sopenharmony_ci int k ; 355b815c7f3Sopenharmony_ci 356b815c7f3Sopenharmony_ci format &= SF_FORMAT_SUBMASK ; 357b815c7f3Sopenharmony_ci 358b815c7f3Sopenharmony_ci if ((cptr = strrchr (str, '.')) == NULL) 359b815c7f3Sopenharmony_ci return 0 ; 360b815c7f3Sopenharmony_ci 361b815c7f3Sopenharmony_ci strncpy (buffer, cptr + 1, 15) ; 362b815c7f3Sopenharmony_ci buffer [15] = 0 ; 363b815c7f3Sopenharmony_ci 364b815c7f3Sopenharmony_ci for (k = 0 ; buffer [k] ; k++) 365b815c7f3Sopenharmony_ci buffer [k] = tolower ((buffer [k])) ; 366b815c7f3Sopenharmony_ci 367b815c7f3Sopenharmony_ci for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++) 368b815c7f3Sopenharmony_ci { if ((format_map [k].len > 0 && strncmp (buffer, format_map [k].ext, format_map [k].len) == 0) || 369b815c7f3Sopenharmony_ci (strcmp (buffer, format_map [k].ext) == 0)) 370b815c7f3Sopenharmony_ci { if (format_map [k].format & SF_FORMAT_SUBMASK) 371b815c7f3Sopenharmony_ci return format_map [k].format ; 372b815c7f3Sopenharmony_ci else 373b815c7f3Sopenharmony_ci return format_map [k].format | format ; 374b815c7f3Sopenharmony_ci } ; 375b815c7f3Sopenharmony_ci } ; 376b815c7f3Sopenharmony_ci 377b815c7f3Sopenharmony_ci /* Default if all the above fails. */ 378b815c7f3Sopenharmony_ci return (SF_FORMAT_WAV | SF_FORMAT_PCM_24) ; 379b815c7f3Sopenharmony_ci} /* sfe_file_type_of_ext */ 380b815c7f3Sopenharmony_ci 381b815c7f3Sopenharmony_civoid 382b815c7f3Sopenharmony_cisfe_dump_format_map (void) 383b815c7f3Sopenharmony_ci{ SF_FORMAT_INFO info ; 384b815c7f3Sopenharmony_ci int k ; 385b815c7f3Sopenharmony_ci 386b815c7f3Sopenharmony_ci for (k = 0 ; k < ARRAY_LEN (format_map) ; k++) 387b815c7f3Sopenharmony_ci { info.format = format_map [k].format ; 388b815c7f3Sopenharmony_ci sf_command (NULL, SFC_GET_FORMAT_INFO, &info, sizeof (info)) ; 389b815c7f3Sopenharmony_ci printf (" %-10s : %s", format_map [k].ext, info.name == NULL ? "????" : info.name) ; 390b815c7f3Sopenharmony_ci if (format_map [k].format & SF_FORMAT_SUBMASK) 391b815c7f3Sopenharmony_ci { info.format = format_map [k].format & SF_FORMAT_SUBMASK ; 392b815c7f3Sopenharmony_ci sf_command (NULL, SFC_GET_FORMAT_INFO, &info, sizeof (info)) ; 393b815c7f3Sopenharmony_ci printf (" %s", info.name == NULL ? "????" : info.name) ; 394b815c7f3Sopenharmony_ci } ; 395b815c7f3Sopenharmony_ci putchar ('\n') ; 396b815c7f3Sopenharmony_ci 397b815c7f3Sopenharmony_ci } ; 398b815c7f3Sopenharmony_ci 399b815c7f3Sopenharmony_ci} /* sfe_dump_format_map */ 400b815c7f3Sopenharmony_ci 401b815c7f3Sopenharmony_ciconst char * 402b815c7f3Sopenharmony_ciprogram_name (const char * argv0) 403b815c7f3Sopenharmony_ci{ const char * tmp ; 404b815c7f3Sopenharmony_ci 405b815c7f3Sopenharmony_ci tmp = strrchr (argv0, '/') ; 406b815c7f3Sopenharmony_ci argv0 = tmp ? tmp + 1 : argv0 ; 407b815c7f3Sopenharmony_ci 408b815c7f3Sopenharmony_ci /* Remove leading libtool name mangling. */ 409b815c7f3Sopenharmony_ci if (strstr (argv0, "lt-") == argv0) 410b815c7f3Sopenharmony_ci return argv0 + 3 ; 411b815c7f3Sopenharmony_ci 412b815c7f3Sopenharmony_ci return argv0 ; 413b815c7f3Sopenharmony_ci} /* program_name */ 414b815c7f3Sopenharmony_ci 415b815c7f3Sopenharmony_ciconst char * 416b815c7f3Sopenharmony_cisfe_endian_name (int format) 417b815c7f3Sopenharmony_ci{ 418b815c7f3Sopenharmony_ci switch (format & SF_FORMAT_ENDMASK) 419b815c7f3Sopenharmony_ci { case SF_ENDIAN_FILE : return "file" ; 420b815c7f3Sopenharmony_ci case SF_ENDIAN_LITTLE : return "little" ; 421b815c7f3Sopenharmony_ci case SF_ENDIAN_BIG : return "big" ; 422b815c7f3Sopenharmony_ci case SF_ENDIAN_CPU : return "cpu" ; 423b815c7f3Sopenharmony_ci default : break ; 424b815c7f3Sopenharmony_ci } ; 425b815c7f3Sopenharmony_ci 426b815c7f3Sopenharmony_ci return "unknown" ; 427b815c7f3Sopenharmony_ci} /* sfe_endian_name */ 428b815c7f3Sopenharmony_ci 429b815c7f3Sopenharmony_ciconst char * 430b815c7f3Sopenharmony_cisfe_container_name (int format) 431b815c7f3Sopenharmony_ci{ 432b815c7f3Sopenharmony_ci switch (format & SF_FORMAT_TYPEMASK) 433b815c7f3Sopenharmony_ci { case SF_FORMAT_WAV : return "WAV" ; 434b815c7f3Sopenharmony_ci case SF_FORMAT_AIFF : return "AIFF" ; 435b815c7f3Sopenharmony_ci case SF_FORMAT_AU : return "AU" ; 436b815c7f3Sopenharmony_ci case SF_FORMAT_RAW : return "RAW" ; 437b815c7f3Sopenharmony_ci case SF_FORMAT_PAF : return "PAF" ; 438b815c7f3Sopenharmony_ci case SF_FORMAT_SVX : return "SVX" ; 439b815c7f3Sopenharmony_ci case SF_FORMAT_NIST : return "NIST" ; 440b815c7f3Sopenharmony_ci case SF_FORMAT_VOC : return "VOC" ; 441b815c7f3Sopenharmony_ci case SF_FORMAT_IRCAM : return "IRCAM" ; 442b815c7f3Sopenharmony_ci case SF_FORMAT_W64 : return "W64" ; 443b815c7f3Sopenharmony_ci case SF_FORMAT_MAT4 : return "MAT4" ; 444b815c7f3Sopenharmony_ci case SF_FORMAT_MAT5 : return "MAT5" ; 445b815c7f3Sopenharmony_ci case SF_FORMAT_PVF : return "PVF" ; 446b815c7f3Sopenharmony_ci case SF_FORMAT_XI : return "XI" ; 447b815c7f3Sopenharmony_ci case SF_FORMAT_HTK : return "HTK" ; 448b815c7f3Sopenharmony_ci case SF_FORMAT_SDS : return "SDS" ; 449b815c7f3Sopenharmony_ci case SF_FORMAT_AVR : return "AVR" ; 450b815c7f3Sopenharmony_ci case SF_FORMAT_WAVEX : return "WAVEX" ; 451b815c7f3Sopenharmony_ci case SF_FORMAT_SD2 : return "SD2" ; 452b815c7f3Sopenharmony_ci case SF_FORMAT_FLAC : return "FLAC" ; 453b815c7f3Sopenharmony_ci case SF_FORMAT_CAF : return "CAF" ; 454b815c7f3Sopenharmony_ci case SF_FORMAT_WVE : return "WVE" ; 455b815c7f3Sopenharmony_ci case SF_FORMAT_OGG : return "OGG" ; 456b815c7f3Sopenharmony_ci case SF_FORMAT_MPC2K : return "MPC2K" ; 457b815c7f3Sopenharmony_ci case SF_FORMAT_RF64 : return "RF64" ; 458b815c7f3Sopenharmony_ci case SF_FORMAT_MPEG : return "MPEG" ; 459b815c7f3Sopenharmony_ci default : break ; 460b815c7f3Sopenharmony_ci } ; 461b815c7f3Sopenharmony_ci 462b815c7f3Sopenharmony_ci return "unknown" ; 463b815c7f3Sopenharmony_ci} /* sfe_container_name */ 464b815c7f3Sopenharmony_ci 465b815c7f3Sopenharmony_ciconst char * 466b815c7f3Sopenharmony_cisfe_codec_name (int format) 467b815c7f3Sopenharmony_ci{ 468b815c7f3Sopenharmony_ci switch (format & SF_FORMAT_SUBMASK) 469b815c7f3Sopenharmony_ci { case SF_FORMAT_PCM_S8 : return "signed 8 bit PCM" ; 470b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_16 : return "16 bit PCM" ; 471b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_24 : return "24 bit PCM" ; 472b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_32 : return "32 bit PCM" ; 473b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_U8 : return "unsigned 8 bit PCM" ; 474b815c7f3Sopenharmony_ci case SF_FORMAT_FLOAT : return "32 bit float" ; 475b815c7f3Sopenharmony_ci case SF_FORMAT_DOUBLE : return "64 bit double" ; 476b815c7f3Sopenharmony_ci case SF_FORMAT_ULAW : return "u-law" ; 477b815c7f3Sopenharmony_ci case SF_FORMAT_ALAW : return "a-law" ; 478b815c7f3Sopenharmony_ci case SF_FORMAT_IMA_ADPCM : return "IMA ADPCM" ; 479b815c7f3Sopenharmony_ci case SF_FORMAT_MS_ADPCM : return "MS ADPCM" ; 480b815c7f3Sopenharmony_ci case SF_FORMAT_GSM610 : return "gsm610" ; 481b815c7f3Sopenharmony_ci case SF_FORMAT_VOX_ADPCM : return "Vox ADPCM" ; 482b815c7f3Sopenharmony_ci case SF_FORMAT_G721_32 : return "g721 32kbps" ; 483b815c7f3Sopenharmony_ci case SF_FORMAT_G723_24 : return "g723 24kbps" ; 484b815c7f3Sopenharmony_ci case SF_FORMAT_G723_40 : return "g723 40kbps" ; 485b815c7f3Sopenharmony_ci case SF_FORMAT_DWVW_12 : return "12 bit DWVW" ; 486b815c7f3Sopenharmony_ci case SF_FORMAT_DWVW_16 : return "16 bit DWVW" ; 487b815c7f3Sopenharmony_ci case SF_FORMAT_DWVW_24 : return "14 bit DWVW" ; 488b815c7f3Sopenharmony_ci case SF_FORMAT_DWVW_N : return "DWVW" ; 489b815c7f3Sopenharmony_ci case SF_FORMAT_DPCM_8 : return "8 bit DPCM" ; 490b815c7f3Sopenharmony_ci case SF_FORMAT_DPCM_16 : return "16 bit DPCM" ; 491b815c7f3Sopenharmony_ci case SF_FORMAT_VORBIS : return "Vorbis" ; 492b815c7f3Sopenharmony_ci case SF_FORMAT_ALAC_16 : return "16 bit ALAC" ; 493b815c7f3Sopenharmony_ci case SF_FORMAT_ALAC_20 : return "20 bit ALAC" ; 494b815c7f3Sopenharmony_ci case SF_FORMAT_ALAC_24 : return "24 bit ALAC" ; 495b815c7f3Sopenharmony_ci case SF_FORMAT_ALAC_32 : return "32 bit ALAC" ; 496b815c7f3Sopenharmony_ci case SF_FORMAT_OPUS : return "Opus" ; 497b815c7f3Sopenharmony_ci case SF_FORMAT_MPEG_LAYER_I : return "MPEG layer 1" ; 498b815c7f3Sopenharmony_ci case SF_FORMAT_MPEG_LAYER_II : return "MPEG layer 2" ; 499b815c7f3Sopenharmony_ci case SF_FORMAT_MPEG_LAYER_III : return "MPEG layer 3" ; 500b815c7f3Sopenharmony_ci default : break ; 501b815c7f3Sopenharmony_ci } ; 502b815c7f3Sopenharmony_ci return "unknown" ; 503b815c7f3Sopenharmony_ci} /* sfe_codec_name */ 504