2
0

common.c 14 KB

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