1159b3361Sopenharmony_ci/* 2159b3361Sopenharmony_ci * Get Audio routines source file 3159b3361Sopenharmony_ci * 4159b3361Sopenharmony_ci * Copyright (c) 1999 Albert L Faber 5159b3361Sopenharmony_ci * 2008-2017 Robert Hegemann 6159b3361Sopenharmony_ci * 7159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or 8159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public 9159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either 10159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version. 11159b3361Sopenharmony_ci * 12159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful, 13159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15159b3361Sopenharmony_ci * Library General Public License for more details. 16159b3361Sopenharmony_ci * 17159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public 18159b3361Sopenharmony_ci * License along with this library; if not, write to the 19159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA. 21159b3361Sopenharmony_ci */ 22159b3361Sopenharmony_ci 23159b3361Sopenharmony_ci/* $Id$ */ 24159b3361Sopenharmony_ci 25159b3361Sopenharmony_ci 26159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H 27159b3361Sopenharmony_ci# include <config.h> 28159b3361Sopenharmony_ci#endif 29159b3361Sopenharmony_ci 30159b3361Sopenharmony_ci#include <assert.h> 31159b3361Sopenharmony_ci 32159b3361Sopenharmony_ci#ifdef HAVE_LIMITS_H 33159b3361Sopenharmony_ci# include <limits.h> 34159b3361Sopenharmony_ci#endif 35159b3361Sopenharmony_ci 36159b3361Sopenharmony_ci#include <stdio.h> 37159b3361Sopenharmony_ci 38159b3361Sopenharmony_ci#ifdef STDC_HEADERS 39159b3361Sopenharmony_ci# include <stdlib.h> 40159b3361Sopenharmony_ci# include <string.h> 41159b3361Sopenharmony_ci#else 42159b3361Sopenharmony_ci# ifndef HAVE_STRCHR 43159b3361Sopenharmony_ci# define strchr index 44159b3361Sopenharmony_ci# define strrchr rindex 45159b3361Sopenharmony_ci# endif 46159b3361Sopenharmony_cichar *strchr(), *strrchr(); 47159b3361Sopenharmony_ci# ifndef HAVE_MEMCPY 48159b3361Sopenharmony_ci# define memcpy(d, s, n) bcopy ((s), (d), (n)) 49159b3361Sopenharmony_ci# define memmove(d, s, n) bcopy ((s), (d), (n)) 50159b3361Sopenharmony_ci# endif 51159b3361Sopenharmony_ci#endif 52159b3361Sopenharmony_ci 53159b3361Sopenharmony_ci#ifdef HAVE_INTTYPES_H 54159b3361Sopenharmony_ci# include <inttypes.h> 55159b3361Sopenharmony_ci#else 56159b3361Sopenharmony_ci# ifdef HAVE_STDINT_H 57159b3361Sopenharmony_ci# include <stdint.h> 58159b3361Sopenharmony_ci# endif 59159b3361Sopenharmony_ci#endif 60159b3361Sopenharmony_ci 61159b3361Sopenharmony_ci#if defined(HAVE_MPGLIB) || defined(HAVE_MPG123) 62159b3361Sopenharmony_ci#define hip_global_struct mpstr_tag 63159b3361Sopenharmony_ci#endif 64159b3361Sopenharmony_ci#ifdef HAVE_MPG123 65159b3361Sopenharmony_ci#include <mpg123.h> 66159b3361Sopenharmony_ci/* for mpstr_tag */ 67159b3361Sopenharmony_ci#include "mpglib/mpglib.h" 68159b3361Sopenharmony_ci 69159b3361Sopenharmony_ci#endif 70159b3361Sopenharmony_ci 71159b3361Sopenharmony_ci#define MAX_U_32_NUM 0xFFFFFFFF 72159b3361Sopenharmony_ci 73159b3361Sopenharmony_ci 74159b3361Sopenharmony_ci#include <math.h> 75159b3361Sopenharmony_ci 76159b3361Sopenharmony_ci#if defined(__riscos__) 77159b3361Sopenharmony_ci# include <kernel.h> 78159b3361Sopenharmony_ci# include <sys/swis.h> 79159b3361Sopenharmony_ci#elif defined(_WIN32) 80159b3361Sopenharmony_ci# include <sys/types.h> 81159b3361Sopenharmony_ci# include <sys/stat.h> 82159b3361Sopenharmony_ci#else 83159b3361Sopenharmony_ci# include <sys/stat.h> 84159b3361Sopenharmony_ci#endif 85159b3361Sopenharmony_ci 86159b3361Sopenharmony_ci#ifdef __sun__ 87159b3361Sopenharmony_ci/* woraround for SunOS 4.x, it has SEEK_* defined here */ 88159b3361Sopenharmony_ci#include <unistd.h> 89159b3361Sopenharmony_ci#endif 90159b3361Sopenharmony_ci 91159b3361Sopenharmony_ci#include "lame.h" 92159b3361Sopenharmony_ci#include "main.h" 93159b3361Sopenharmony_ci#include "get_audio.h" 94159b3361Sopenharmony_ci#include "lametime.h" 95159b3361Sopenharmony_ci#include "console.h" 96159b3361Sopenharmony_ci 97159b3361Sopenharmony_ci#ifdef WITH_DMALLOC 98159b3361Sopenharmony_ci#include <dmalloc.h> 99159b3361Sopenharmony_ci#endif 100159b3361Sopenharmony_ci 101159b3361Sopenharmony_ci#ifndef STR 102159b3361Sopenharmony_ci# define __STR(x) #x 103159b3361Sopenharmony_ci# define STR(x) __STR(x) 104159b3361Sopenharmony_ci#define __LOC__ __FILE__ "("STR(__LINE__)") : " 105159b3361Sopenharmony_ci#endif 106159b3361Sopenharmony_ci 107159b3361Sopenharmony_ci 108159b3361Sopenharmony_ci#define FLOAT_TO_UNSIGNED(f) ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1)) 109159b3361Sopenharmony_ci#define UNSIGNED_TO_FLOAT(u) (((double)((long)((u) - 2147483647L - 1))) + 2147483648.0) 110159b3361Sopenharmony_ci 111159b3361Sopenharmony_cistatic uint32_t uint32_high_low(unsigned char const *bytes) 112159b3361Sopenharmony_ci{ 113159b3361Sopenharmony_ci uint32_t const hh = bytes[0]; 114159b3361Sopenharmony_ci uint32_t const hl = bytes[1]; 115159b3361Sopenharmony_ci uint32_t const lh = bytes[2]; 116159b3361Sopenharmony_ci uint32_t const ll = bytes[3]; 117159b3361Sopenharmony_ci return (hh << 24) | (hl << 16) | (lh << 8) | ll; 118159b3361Sopenharmony_ci} 119159b3361Sopenharmony_ci 120159b3361Sopenharmony_cistatic double 121159b3361Sopenharmony_ciread_ieee_extended_high_low(FILE * fp) 122159b3361Sopenharmony_ci{ 123159b3361Sopenharmony_ci unsigned char bytes[10]; 124159b3361Sopenharmony_ci memset(bytes, 0, 10); 125159b3361Sopenharmony_ci fread(bytes, 1, 10, fp); 126159b3361Sopenharmony_ci { 127159b3361Sopenharmony_ci int32_t const s = (bytes[0] & 0x80); 128159b3361Sopenharmony_ci int32_t const e_h = (bytes[0] & 0x7F); 129159b3361Sopenharmony_ci int32_t const e_l = bytes[1]; 130159b3361Sopenharmony_ci int32_t e = (e_h << 8) | e_l; 131159b3361Sopenharmony_ci uint32_t const hm = uint32_high_low(bytes + 2); 132159b3361Sopenharmony_ci uint32_t const lm = uint32_high_low(bytes + 6); 133159b3361Sopenharmony_ci double result = 0; 134159b3361Sopenharmony_ci if (e != 0 || hm != 0 || lm != 0) { 135159b3361Sopenharmony_ci if (e == 0x7fff) { 136159b3361Sopenharmony_ci result = HUGE_VAL; 137159b3361Sopenharmony_ci } 138159b3361Sopenharmony_ci else { 139159b3361Sopenharmony_ci double mantissa_h = UNSIGNED_TO_FLOAT(hm); 140159b3361Sopenharmony_ci double mantissa_l = UNSIGNED_TO_FLOAT(lm); 141159b3361Sopenharmony_ci e -= 0x3fff; 142159b3361Sopenharmony_ci e -= 31; 143159b3361Sopenharmony_ci result = ldexp(mantissa_h, e); 144159b3361Sopenharmony_ci e -= 32; 145159b3361Sopenharmony_ci result += ldexp(mantissa_l, e); 146159b3361Sopenharmony_ci } 147159b3361Sopenharmony_ci } 148159b3361Sopenharmony_ci return s ? -result : result; 149159b3361Sopenharmony_ci } 150159b3361Sopenharmony_ci} 151159b3361Sopenharmony_ci 152159b3361Sopenharmony_ci 153159b3361Sopenharmony_cistatic uint16_t 154159b3361Sopenharmony_ciread_16_bits_low_high(FILE * fp) 155159b3361Sopenharmony_ci{ 156159b3361Sopenharmony_ci unsigned char bytes[2] = { 0, 0 }; 157159b3361Sopenharmony_ci fread(bytes, 1, 2, fp); 158159b3361Sopenharmony_ci { 159159b3361Sopenharmony_ci uint16_t const l = bytes[0]; 160159b3361Sopenharmony_ci uint16_t const h = bytes[1]; 161159b3361Sopenharmony_ci return (h << 8) | l; 162159b3361Sopenharmony_ci } 163159b3361Sopenharmony_ci} 164159b3361Sopenharmony_ci 165159b3361Sopenharmony_ci 166159b3361Sopenharmony_cistatic uint32_t 167159b3361Sopenharmony_ciread_32_bits_low_high(FILE * fp) 168159b3361Sopenharmony_ci{ 169159b3361Sopenharmony_ci unsigned char bytes[4] = { 0, 0, 0, 0 }; 170159b3361Sopenharmony_ci fread(bytes, 1, 4, fp); 171159b3361Sopenharmony_ci { 172159b3361Sopenharmony_ci uint32_t const ll = bytes[0]; 173159b3361Sopenharmony_ci uint32_t const lh = bytes[1]; 174159b3361Sopenharmony_ci uint32_t const hl = bytes[2]; 175159b3361Sopenharmony_ci uint32_t const hh = bytes[3]; 176159b3361Sopenharmony_ci return (hh << 24) | (hl << 16) | (lh << 8) | ll; 177159b3361Sopenharmony_ci } 178159b3361Sopenharmony_ci} 179159b3361Sopenharmony_ci 180159b3361Sopenharmony_cistatic uint16_t 181159b3361Sopenharmony_ciread_16_bits_high_low(FILE * fp) 182159b3361Sopenharmony_ci{ 183159b3361Sopenharmony_ci unsigned char bytes[2] = { 0, 0 }; 184159b3361Sopenharmony_ci fread(bytes, 1, 2, fp); 185159b3361Sopenharmony_ci { 186159b3361Sopenharmony_ci uint16_t const h = bytes[0]; 187159b3361Sopenharmony_ci uint16_t const l = bytes[1]; 188159b3361Sopenharmony_ci return (h << 8) | l; 189159b3361Sopenharmony_ci } 190159b3361Sopenharmony_ci} 191159b3361Sopenharmony_ci 192159b3361Sopenharmony_cistatic uint32_t 193159b3361Sopenharmony_ciread_32_bits_high_low(FILE * fp) 194159b3361Sopenharmony_ci{ 195159b3361Sopenharmony_ci unsigned char bytes[4] = { 0, 0, 0, 0 }; 196159b3361Sopenharmony_ci fread(bytes, 1, 4, fp); 197159b3361Sopenharmony_ci return uint32_high_low(bytes); 198159b3361Sopenharmony_ci} 199159b3361Sopenharmony_ci 200159b3361Sopenharmony_cistatic void 201159b3361Sopenharmony_ciwrite_16_bits_low_high(FILE * fp, int val) 202159b3361Sopenharmony_ci{ 203159b3361Sopenharmony_ci unsigned char bytes[2]; 204159b3361Sopenharmony_ci bytes[0] = (val & 0xff); 205159b3361Sopenharmony_ci bytes[1] = ((val >> 8) & 0xff); 206159b3361Sopenharmony_ci fwrite(bytes, 1, 2, fp); 207159b3361Sopenharmony_ci} 208159b3361Sopenharmony_ci 209159b3361Sopenharmony_cistatic void 210159b3361Sopenharmony_ciwrite_32_bits_low_high(FILE * fp, int val) 211159b3361Sopenharmony_ci{ 212159b3361Sopenharmony_ci unsigned char bytes[4]; 213159b3361Sopenharmony_ci bytes[0] = (val & 0xff); 214159b3361Sopenharmony_ci bytes[1] = ((val >> 8) & 0xff); 215159b3361Sopenharmony_ci bytes[2] = ((val >> 16) & 0xff); 216159b3361Sopenharmony_ci bytes[3] = ((val >> 24) & 0xff); 217159b3361Sopenharmony_ci fwrite(bytes, 1, 4, fp); 218159b3361Sopenharmony_ci} 219159b3361Sopenharmony_ci 220159b3361Sopenharmony_ci#ifdef LIBSNDFILE 221159b3361Sopenharmony_ci 222159b3361Sopenharmony_ci#include <sndfile.h> 223159b3361Sopenharmony_ci 224159b3361Sopenharmony_ci 225159b3361Sopenharmony_ci#else 226159b3361Sopenharmony_ci 227159b3361Sopenharmony_citypedef void SNDFILE; 228159b3361Sopenharmony_ci 229159b3361Sopenharmony_ci#endif /* ifdef LIBSNDFILE */ 230159b3361Sopenharmony_ci 231159b3361Sopenharmony_ci 232159b3361Sopenharmony_ci 233159b3361Sopenharmony_citypedef struct blockAlign_struct { 234159b3361Sopenharmony_ci uint32_t offset; 235159b3361Sopenharmony_ci uint32_t blockSize; 236159b3361Sopenharmony_ci} blockAlign; 237159b3361Sopenharmony_ci 238159b3361Sopenharmony_citypedef struct IFF_AIFF_struct { 239159b3361Sopenharmony_ci short numChannels; 240159b3361Sopenharmony_ci unsigned long numSampleFrames; 241159b3361Sopenharmony_ci short sampleSize; 242159b3361Sopenharmony_ci double sampleRate; 243159b3361Sopenharmony_ci uint32_t sampleType; 244159b3361Sopenharmony_ci uint32_t sampleFormat; 245159b3361Sopenharmony_ci blockAlign blkAlgn; 246159b3361Sopenharmony_ci} IFF_AIFF; 247159b3361Sopenharmony_ci 248159b3361Sopenharmony_ci 249159b3361Sopenharmony_ci 250159b3361Sopenharmony_cistruct PcmBuffer { 251159b3361Sopenharmony_ci void *ch[2]; /* buffer for each channel */ 252159b3361Sopenharmony_ci int w; /* sample width */ 253159b3361Sopenharmony_ci int n; /* number samples allocated */ 254159b3361Sopenharmony_ci int u; /* number samples used */ 255159b3361Sopenharmony_ci int skip_start; /* number samples to ignore at the beginning */ 256159b3361Sopenharmony_ci int skip_end; /* number samples to ignore at the end */ 257159b3361Sopenharmony_ci}; 258159b3361Sopenharmony_ci 259159b3361Sopenharmony_citypedef struct PcmBuffer PcmBuffer; 260159b3361Sopenharmony_ci 261159b3361Sopenharmony_cistatic void 262159b3361Sopenharmony_ciinitPcmBuffer(PcmBuffer * b, int w) 263159b3361Sopenharmony_ci{ 264159b3361Sopenharmony_ci b->ch[0] = 0; 265159b3361Sopenharmony_ci b->ch[1] = 0; 266159b3361Sopenharmony_ci b->w = w; 267159b3361Sopenharmony_ci b->n = 0; 268159b3361Sopenharmony_ci b->u = 0; 269159b3361Sopenharmony_ci b->skip_start = 0; 270159b3361Sopenharmony_ci b->skip_end = 0; 271159b3361Sopenharmony_ci} 272159b3361Sopenharmony_ci 273159b3361Sopenharmony_cistatic void 274159b3361Sopenharmony_cifreePcmBuffer(PcmBuffer * b) 275159b3361Sopenharmony_ci{ 276159b3361Sopenharmony_ci if (b != 0) { 277159b3361Sopenharmony_ci free(b->ch[0]); 278159b3361Sopenharmony_ci free(b->ch[1]); 279159b3361Sopenharmony_ci b->ch[0] = 0; 280159b3361Sopenharmony_ci b->ch[1] = 0; 281159b3361Sopenharmony_ci b->n = 0; 282159b3361Sopenharmony_ci b->u = 0; 283159b3361Sopenharmony_ci } 284159b3361Sopenharmony_ci} 285159b3361Sopenharmony_ci 286159b3361Sopenharmony_cistatic int 287159b3361Sopenharmony_ciaddPcmBuffer(PcmBuffer * b, void *a0, void *a1, int read) 288159b3361Sopenharmony_ci{ 289159b3361Sopenharmony_ci int a_n; 290159b3361Sopenharmony_ci 291159b3361Sopenharmony_ci if (b == 0) { 292159b3361Sopenharmony_ci return 0; 293159b3361Sopenharmony_ci } 294159b3361Sopenharmony_ci if (read < 0) { 295159b3361Sopenharmony_ci return b->u - b->skip_end; 296159b3361Sopenharmony_ci } 297159b3361Sopenharmony_ci if (b->skip_start >= read) { 298159b3361Sopenharmony_ci b->skip_start -= read; 299159b3361Sopenharmony_ci return b->u - b->skip_end; 300159b3361Sopenharmony_ci } 301159b3361Sopenharmony_ci a_n = read - b->skip_start; 302159b3361Sopenharmony_ci 303159b3361Sopenharmony_ci if (a_n > 0) { 304159b3361Sopenharmony_ci int const a_skip = b->w * b->skip_start; 305159b3361Sopenharmony_ci int const a_want = b->w * a_n; 306159b3361Sopenharmony_ci int const b_used = b->w * b->u; 307159b3361Sopenharmony_ci int const b_have = b->w * b->n; 308159b3361Sopenharmony_ci int const b_need = b->w * (b->u + a_n); 309159b3361Sopenharmony_ci if (b_have < b_need) { 310159b3361Sopenharmony_ci b->n = b->u + a_n; 311159b3361Sopenharmony_ci b->ch[0] = realloc(b->ch[0], b_need); 312159b3361Sopenharmony_ci b->ch[1] = realloc(b->ch[1], b_need); 313159b3361Sopenharmony_ci } 314159b3361Sopenharmony_ci b->u += a_n; 315159b3361Sopenharmony_ci if (b->ch[0] != 0 && a0 != 0) { 316159b3361Sopenharmony_ci char *src = a0; 317159b3361Sopenharmony_ci char *dst = b->ch[0]; 318159b3361Sopenharmony_ci memcpy(dst + b_used, src + a_skip, a_want); 319159b3361Sopenharmony_ci } 320159b3361Sopenharmony_ci if (b->ch[1] != 0 && a1 != 0) { 321159b3361Sopenharmony_ci char *src = a1; 322159b3361Sopenharmony_ci char *dst = b->ch[1]; 323159b3361Sopenharmony_ci memcpy(dst + b_used, src + a_skip, a_want); 324159b3361Sopenharmony_ci } 325159b3361Sopenharmony_ci } 326159b3361Sopenharmony_ci b->skip_start = 0; 327159b3361Sopenharmony_ci return b->u - b->skip_end; 328159b3361Sopenharmony_ci} 329159b3361Sopenharmony_ci 330159b3361Sopenharmony_cistatic int 331159b3361Sopenharmony_citakePcmBuffer(PcmBuffer * b, void *a0, void *a1, int a_n, int mm) 332159b3361Sopenharmony_ci{ 333159b3361Sopenharmony_ci if (a_n > mm) { 334159b3361Sopenharmony_ci a_n = mm; 335159b3361Sopenharmony_ci } 336159b3361Sopenharmony_ci if (b != 0 && a_n > 0) { 337159b3361Sopenharmony_ci int const a_take = b->w * a_n; 338159b3361Sopenharmony_ci if (a0 != 0 && b->ch[0] != 0) { 339159b3361Sopenharmony_ci memcpy(a0, b->ch[0], a_take); 340159b3361Sopenharmony_ci } 341159b3361Sopenharmony_ci if (a1 != 0 && b->ch[1] != 0) { 342159b3361Sopenharmony_ci memcpy(a1, b->ch[1], a_take); 343159b3361Sopenharmony_ci } 344159b3361Sopenharmony_ci b->u -= a_n; 345159b3361Sopenharmony_ci if (b->u < 0) { 346159b3361Sopenharmony_ci b->u = 0; 347159b3361Sopenharmony_ci return a_n; 348159b3361Sopenharmony_ci } 349159b3361Sopenharmony_ci if (b->ch[0] != 0) { 350159b3361Sopenharmony_ci memmove(b->ch[0], (char *) b->ch[0] + a_take, b->w * b->u); 351159b3361Sopenharmony_ci } 352159b3361Sopenharmony_ci if (b->ch[1] != 0) { 353159b3361Sopenharmony_ci memmove(b->ch[1], (char *) b->ch[1] + a_take, b->w * b->u); 354159b3361Sopenharmony_ci } 355159b3361Sopenharmony_ci } 356159b3361Sopenharmony_ci return a_n; 357159b3361Sopenharmony_ci} 358159b3361Sopenharmony_ci 359159b3361Sopenharmony_ci/* global data for get_audio.c. */ 360159b3361Sopenharmony_citypedef struct get_audio_global_data_struct { 361159b3361Sopenharmony_ci int count_samples_carefully; 362159b3361Sopenharmony_ci int pcmbitwidth; 363159b3361Sopenharmony_ci int pcmswapbytes; 364159b3361Sopenharmony_ci int pcm_is_unsigned_8bit; 365159b3361Sopenharmony_ci int pcm_is_ieee_float; 366159b3361Sopenharmony_ci unsigned int num_samples_read; 367159b3361Sopenharmony_ci FILE *music_in; 368159b3361Sopenharmony_ci SNDFILE *snd_file; 369159b3361Sopenharmony_ci#ifdef HAVE_MPG123 370159b3361Sopenharmony_ci mpg123_handle* mh; 371159b3361Sopenharmony_ci#endif 372159b3361Sopenharmony_ci hip_t hip; 373159b3361Sopenharmony_ci PcmBuffer pcm32; 374159b3361Sopenharmony_ci PcmBuffer pcm16; 375159b3361Sopenharmony_ci size_t in_id3v2_size; 376159b3361Sopenharmony_ci unsigned char* in_id3v2_tag; 377159b3361Sopenharmony_ci} get_audio_global_data; 378159b3361Sopenharmony_ci 379159b3361Sopenharmony_cistatic get_audio_global_data global; 380159b3361Sopenharmony_ci 381159b3361Sopenharmony_ci 382159b3361Sopenharmony_ci 383159b3361Sopenharmony_ci#ifdef AMIGA_MPEGA 384159b3361Sopenharmony_ciint lame_decode_initfile_amiga(const char *fullname, mp3data_struct * const mp3data); 385159b3361Sopenharmony_ci#else 386159b3361Sopenharmony_ciint lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding); 387159b3361Sopenharmony_ci#endif 388159b3361Sopenharmony_ci#ifdef HAVE_MPG123 389159b3361Sopenharmony_ciint lame123_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding); 390159b3361Sopenharmony_ci#endif 391159b3361Sopenharmony_ci 392159b3361Sopenharmony_ci/* read mp3 file until mpglib returns one frame of PCM data */ 393159b3361Sopenharmony_cistatic int lame_decode_fromfile(FILE * fd, short int pcm_l[], short int pcm_r[], 394159b3361Sopenharmony_ci mp3data_struct * mp3data); 395159b3361Sopenharmony_ci 396159b3361Sopenharmony_ci 397159b3361Sopenharmony_cistatic int read_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read); 398159b3361Sopenharmony_cistatic int read_samples_mp3(lame_t gfp, FILE * musicin, short int mpg123pcm[2][1152]); 399159b3361Sopenharmony_ci#ifdef LIBSNDFILE 400159b3361Sopenharmony_cistatic SNDFILE *open_snd_file(lame_t gfp, char const *inPath); 401159b3361Sopenharmony_ci#endif 402159b3361Sopenharmony_cistatic FILE *open_mpeg_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding); 403159b3361Sopenharmony_cistatic FILE *open_wave_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding); 404159b3361Sopenharmony_cistatic int close_input_file(FILE * musicin); 405159b3361Sopenharmony_ci 406159b3361Sopenharmony_ci 407159b3361Sopenharmony_cistatic size_t 408159b3361Sopenharmony_cimin_size_t(size_t a, size_t b) 409159b3361Sopenharmony_ci{ 410159b3361Sopenharmony_ci if (a < b) { 411159b3361Sopenharmony_ci return a; 412159b3361Sopenharmony_ci } 413159b3361Sopenharmony_ci return b; 414159b3361Sopenharmony_ci} 415159b3361Sopenharmony_ci 416159b3361Sopenharmony_cienum ByteOrder machine_byte_order(void); 417159b3361Sopenharmony_ci 418159b3361Sopenharmony_cienum ByteOrder 419159b3361Sopenharmony_cimachine_byte_order(void) 420159b3361Sopenharmony_ci{ 421159b3361Sopenharmony_ci long one = 1; 422159b3361Sopenharmony_ci return !(*((char *) (&one))) ? ByteOrderBigEndian : ByteOrderLittleEndian; 423159b3361Sopenharmony_ci} 424159b3361Sopenharmony_ci 425159b3361Sopenharmony_ci 426159b3361Sopenharmony_ci 427159b3361Sopenharmony_ci/* Replacement for forward fseek(,,SEEK_CUR), because fseek() fails on pipes */ 428159b3361Sopenharmony_ci 429159b3361Sopenharmony_ci 430159b3361Sopenharmony_cistatic int 431159b3361Sopenharmony_cifskip_long(FILE * fp, long offset, int whence) 432159b3361Sopenharmony_ci{ 433159b3361Sopenharmony_ci#ifndef PIPE_BUF 434159b3361Sopenharmony_ci char buffer[4096]; 435159b3361Sopenharmony_ci#else 436159b3361Sopenharmony_ci char buffer[PIPE_BUF]; 437159b3361Sopenharmony_ci#endif 438159b3361Sopenharmony_ci 439159b3361Sopenharmony_ci/* S_ISFIFO macro is defined on newer Linuxes */ 440159b3361Sopenharmony_ci#ifndef S_ISFIFO 441159b3361Sopenharmony_ci# ifdef _S_IFIFO 442159b3361Sopenharmony_ci /* _S_IFIFO is defined on Win32 and Cygwin */ 443159b3361Sopenharmony_ci# define S_ISFIFO(m) (((m)&_S_IFIFO) == _S_IFIFO) 444159b3361Sopenharmony_ci# endif 445159b3361Sopenharmony_ci#endif 446159b3361Sopenharmony_ci 447159b3361Sopenharmony_ci#ifdef S_ISFIFO 448159b3361Sopenharmony_ci /* fseek is known to fail on pipes with several C-Library implementations 449159b3361Sopenharmony_ci workaround: 1) test for pipe 450159b3361Sopenharmony_ci 2) for pipes, only relatvie seeking is possible 451159b3361Sopenharmony_ci 3) and only in forward direction! 452159b3361Sopenharmony_ci else fallback to old code 453159b3361Sopenharmony_ci */ 454159b3361Sopenharmony_ci { 455159b3361Sopenharmony_ci int const fd = fileno(fp); 456159b3361Sopenharmony_ci struct stat file_stat; 457159b3361Sopenharmony_ci 458159b3361Sopenharmony_ci if (fstat(fd, &file_stat) == 0) { 459159b3361Sopenharmony_ci if (S_ISFIFO(file_stat.st_mode)) { 460159b3361Sopenharmony_ci if (whence != SEEK_CUR || offset < 0) { 461159b3361Sopenharmony_ci return -1; 462159b3361Sopenharmony_ci } 463159b3361Sopenharmony_ci while (offset > 0) { 464159b3361Sopenharmony_ci size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset); 465159b3361Sopenharmony_ci size_t const read = fread(buffer, 1, bytes_to_skip, fp); 466159b3361Sopenharmony_ci if (read < 1) { 467159b3361Sopenharmony_ci return -1; 468159b3361Sopenharmony_ci } 469159b3361Sopenharmony_ci assert( read <= LONG_MAX ); 470159b3361Sopenharmony_ci offset -= (long) read; 471159b3361Sopenharmony_ci } 472159b3361Sopenharmony_ci return 0; 473159b3361Sopenharmony_ci } 474159b3361Sopenharmony_ci } 475159b3361Sopenharmony_ci } 476159b3361Sopenharmony_ci#endif 477159b3361Sopenharmony_ci if (0 == fseek(fp, offset, whence)) { 478159b3361Sopenharmony_ci return 0; 479159b3361Sopenharmony_ci } 480159b3361Sopenharmony_ci 481159b3361Sopenharmony_ci if (whence != SEEK_CUR || offset < 0) { 482159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 483159b3361Sopenharmony_ci error_printf 484159b3361Sopenharmony_ci ("fskip problem: Mostly the return status of functions is not evaluated, so it is more secure to pollute <stderr>.\n"); 485159b3361Sopenharmony_ci } 486159b3361Sopenharmony_ci return -1; 487159b3361Sopenharmony_ci } 488159b3361Sopenharmony_ci 489159b3361Sopenharmony_ci while (offset > 0) { 490159b3361Sopenharmony_ci size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset); 491159b3361Sopenharmony_ci size_t const read = fread(buffer, 1, bytes_to_skip, fp); 492159b3361Sopenharmony_ci if (read < 1) { 493159b3361Sopenharmony_ci return -1; 494159b3361Sopenharmony_ci } 495159b3361Sopenharmony_ci assert( read <= LONG_MAX ); 496159b3361Sopenharmony_ci offset -= (long) read; 497159b3361Sopenharmony_ci } 498159b3361Sopenharmony_ci 499159b3361Sopenharmony_ci return 0; 500159b3361Sopenharmony_ci} 501159b3361Sopenharmony_ci 502159b3361Sopenharmony_cistatic int 503159b3361Sopenharmony_cifskip_uint32(FILE * fp, uint32_t offset) 504159b3361Sopenharmony_ci{ 505159b3361Sopenharmony_ci int ret = 0; 506159b3361Sopenharmony_ci while (offset > INT_MAX && ret == 0) { 507159b3361Sopenharmony_ci offset -= INT_MAX; 508159b3361Sopenharmony_ci ret = fskip_long(fp, INT_MAX, SEEK_CUR); 509159b3361Sopenharmony_ci } 510159b3361Sopenharmony_ci if (offset > 0 && ret == 0) { 511159b3361Sopenharmony_ci ret = fskip_long(fp, offset, SEEK_CUR); 512159b3361Sopenharmony_ci } 513159b3361Sopenharmony_ci return ret; 514159b3361Sopenharmony_ci} 515159b3361Sopenharmony_ci 516159b3361Sopenharmony_cistatic off_t 517159b3361Sopenharmony_cilame_get_file_size(FILE * fp) 518159b3361Sopenharmony_ci{ 519159b3361Sopenharmony_ci struct stat sb; 520159b3361Sopenharmony_ci int fd = fileno(fp); 521159b3361Sopenharmony_ci 522159b3361Sopenharmony_ci if (0 == fstat(fd, &sb)) 523159b3361Sopenharmony_ci return sb.st_size; 524159b3361Sopenharmony_ci return (off_t) - 1; 525159b3361Sopenharmony_ci} 526159b3361Sopenharmony_ci 527159b3361Sopenharmony_ci 528159b3361Sopenharmony_ciFILE * 529159b3361Sopenharmony_ciinit_outfile(char const *outPath, int decode) 530159b3361Sopenharmony_ci{ 531159b3361Sopenharmony_ci FILE *outf; 532159b3361Sopenharmony_ci 533159b3361Sopenharmony_ci /* open the output file */ 534159b3361Sopenharmony_ci if (0 == strcmp(outPath, "-")) { 535159b3361Sopenharmony_ci outf = stdout; 536159b3361Sopenharmony_ci lame_set_stream_binary_mode(outf); 537159b3361Sopenharmony_ci } 538159b3361Sopenharmony_ci else { 539159b3361Sopenharmony_ci outf = lame_fopen(outPath, "w+b"); 540159b3361Sopenharmony_ci#ifdef __riscos__ 541159b3361Sopenharmony_ci /* Assign correct file type */ 542159b3361Sopenharmony_ci if (outf != NULL) { 543159b3361Sopenharmony_ci char *p, *out_path = strdup(outPath); 544159b3361Sopenharmony_ci for (p = out_path; *p; p++) { /* ugly, ugly to modify a string */ 545159b3361Sopenharmony_ci switch (*p) { 546159b3361Sopenharmony_ci case '.': 547159b3361Sopenharmony_ci *p = '/'; 548159b3361Sopenharmony_ci break; 549159b3361Sopenharmony_ci case '/': 550159b3361Sopenharmony_ci *p = '.'; 551159b3361Sopenharmony_ci break; 552159b3361Sopenharmony_ci } 553159b3361Sopenharmony_ci } 554159b3361Sopenharmony_ci SetFiletype(out_path, decode ? 0xFB1 /*WAV*/ : 0x1AD /*AMPEG*/); 555159b3361Sopenharmony_ci free(out_path); 556159b3361Sopenharmony_ci } 557159b3361Sopenharmony_ci#else 558159b3361Sopenharmony_ci (void) decode; 559159b3361Sopenharmony_ci#endif 560159b3361Sopenharmony_ci } 561159b3361Sopenharmony_ci return outf; 562159b3361Sopenharmony_ci} 563159b3361Sopenharmony_ci 564159b3361Sopenharmony_ci 565159b3361Sopenharmony_cistatic void 566159b3361Sopenharmony_cisetSkipStartAndEnd(lame_t gfp, int enc_delay, int enc_padding) 567159b3361Sopenharmony_ci{ 568159b3361Sopenharmony_ci int skip_start = 0, skip_end = 0; 569159b3361Sopenharmony_ci long dec_delay = -1; 570159b3361Sopenharmony_ci 571159b3361Sopenharmony_ci if (global_decoder.mp3_delay_set) 572159b3361Sopenharmony_ci skip_start = global_decoder.mp3_delay; 573159b3361Sopenharmony_ci 574159b3361Sopenharmony_ci#if 0 575159b3361Sopenharmony_ci /* We should ask mpg123 for the delay, but we know it is 529 samples and 576159b3361Sopenharmony_ci will not change unless we enable gapless mode. Also, global.hip is not 577159b3361Sopenharmony_ci always the correct handle, so avoid this for now. */ 578159b3361Sopenharmony_ci /* Will use it for layer III only, mpg123 does not deal with layer I and II 579159b3361Sopenharmony_ci gapless stuff (yet?) */ 580159b3361Sopenharmony_ci mpg123_getstate(global.hip->mh, MPG123_DEC_DELAY, &dec_delay, NULL); 581159b3361Sopenharmony_ci#else 582159b3361Sopenharmony_ci if(dec_delay < 0) 583159b3361Sopenharmony_ci dec_delay = 528 + 1; /* Same value as above, actually. */ 584159b3361Sopenharmony_ci#endif 585159b3361Sopenharmony_ci 586159b3361Sopenharmony_ci switch (global_reader.input_format) { 587159b3361Sopenharmony_ci case sf_mp123: 588159b3361Sopenharmony_ci break; 589159b3361Sopenharmony_ci 590159b3361Sopenharmony_ci case sf_mp3: 591159b3361Sopenharmony_ci if (skip_start == 0) { 592159b3361Sopenharmony_ci if (enc_delay > -1 || enc_padding > -1) { 593159b3361Sopenharmony_ci if (enc_delay > -1) 594159b3361Sopenharmony_ci skip_start = enc_delay + dec_delay; 595159b3361Sopenharmony_ci if (enc_padding > -1) 596159b3361Sopenharmony_ci skip_end = enc_padding - dec_delay; 597159b3361Sopenharmony_ci } 598159b3361Sopenharmony_ci else 599159b3361Sopenharmony_ci skip_start = lame_get_encoder_delay(gfp) + dec_delay; 600159b3361Sopenharmony_ci } 601159b3361Sopenharmony_ci else { 602159b3361Sopenharmony_ci /* user specified a value of skip. just add for decoder */ 603159b3361Sopenharmony_ci skip_start += dec_delay; /* mp3 decoder has a 528 sample delay, plus user supplied "skip" */ 604159b3361Sopenharmony_ci } 605159b3361Sopenharmony_ci break; 606159b3361Sopenharmony_ci case sf_mp2: 607159b3361Sopenharmony_ci skip_start += 240 + 1; 608159b3361Sopenharmony_ci break; 609159b3361Sopenharmony_ci case sf_mp1: 610159b3361Sopenharmony_ci skip_start += 240 + 1; 611159b3361Sopenharmony_ci break; 612159b3361Sopenharmony_ci case sf_raw: 613159b3361Sopenharmony_ci skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */ 614159b3361Sopenharmony_ci break; 615159b3361Sopenharmony_ci case sf_wave: 616159b3361Sopenharmony_ci skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */ 617159b3361Sopenharmony_ci break; 618159b3361Sopenharmony_ci case sf_aiff: 619159b3361Sopenharmony_ci skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */ 620159b3361Sopenharmony_ci break; 621159b3361Sopenharmony_ci default: 622159b3361Sopenharmony_ci skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */ 623159b3361Sopenharmony_ci break; 624159b3361Sopenharmony_ci } 625159b3361Sopenharmony_ci skip_start = skip_start < 0 ? 0 : skip_start; 626159b3361Sopenharmony_ci skip_end = skip_end < 0 ? 0 : skip_end; 627159b3361Sopenharmony_ci global. pcm16.skip_start = global.pcm32.skip_start = skip_start; 628159b3361Sopenharmony_ci global. pcm16.skip_end = global.pcm32.skip_end = skip_end; 629159b3361Sopenharmony_ci} 630159b3361Sopenharmony_ci 631159b3361Sopenharmony_ci 632159b3361Sopenharmony_ci 633159b3361Sopenharmony_ciint 634159b3361Sopenharmony_ciinit_infile(lame_t gfp, char const *inPath) 635159b3361Sopenharmony_ci{ 636159b3361Sopenharmony_ci int enc_delay = 0, enc_padding = 0; 637159b3361Sopenharmony_ci /* open the input file */ 638159b3361Sopenharmony_ci global. count_samples_carefully = 0; 639159b3361Sopenharmony_ci global. num_samples_read = 0; 640159b3361Sopenharmony_ci global. pcmbitwidth = global_raw_pcm.in_bitwidth; 641159b3361Sopenharmony_ci global. pcmswapbytes = global_reader.swapbytes; 642159b3361Sopenharmony_ci global. pcm_is_unsigned_8bit = global_raw_pcm.in_signed == 1 ? 0 : 1; 643159b3361Sopenharmony_ci global. pcm_is_ieee_float = 0; 644159b3361Sopenharmony_ci global. hip = 0; 645159b3361Sopenharmony_ci global. music_in = 0; 646159b3361Sopenharmony_ci global. snd_file = 0; 647159b3361Sopenharmony_ci global. in_id3v2_size = 0; 648159b3361Sopenharmony_ci global. in_id3v2_tag = 0; 649159b3361Sopenharmony_ci if (is_mpeg_file_format(global_reader.input_format)) { 650159b3361Sopenharmony_ci global. music_in = open_mpeg_file(gfp, inPath, &enc_delay, &enc_padding); 651159b3361Sopenharmony_ci } 652159b3361Sopenharmony_ci else { 653159b3361Sopenharmony_ci#ifdef LIBSNDFILE 654159b3361Sopenharmony_ci if (strcmp(inPath, "-") != 0) { /* not for stdin */ 655159b3361Sopenharmony_ci global. snd_file = open_snd_file(gfp, inPath); 656159b3361Sopenharmony_ci } 657159b3361Sopenharmony_ci#endif 658159b3361Sopenharmony_ci if (global.snd_file == 0) { 659159b3361Sopenharmony_ci global. music_in = open_wave_file(gfp, inPath, &enc_delay, &enc_padding); 660159b3361Sopenharmony_ci } 661159b3361Sopenharmony_ci } 662159b3361Sopenharmony_ci initPcmBuffer(&global.pcm32, sizeof(int)); 663159b3361Sopenharmony_ci initPcmBuffer(&global.pcm16, sizeof(short)); 664159b3361Sopenharmony_ci setSkipStartAndEnd(gfp, enc_delay, enc_padding); 665159b3361Sopenharmony_ci { 666159b3361Sopenharmony_ci unsigned long n = lame_get_num_samples(gfp); 667159b3361Sopenharmony_ci if (n != MAX_U_32_NUM) { 668159b3361Sopenharmony_ci unsigned long const discard = global.pcm32.skip_start + global.pcm32.skip_end; 669159b3361Sopenharmony_ci lame_set_num_samples(gfp, n > discard ? n - discard : 0); 670159b3361Sopenharmony_ci } 671159b3361Sopenharmony_ci } 672159b3361Sopenharmony_ci return (global.snd_file != NULL || global.music_in != NULL) ? 1 : -1; 673159b3361Sopenharmony_ci} 674159b3361Sopenharmony_ci 675159b3361Sopenharmony_ciint 676159b3361Sopenharmony_cisamples_to_skip_at_start(void) 677159b3361Sopenharmony_ci{ 678159b3361Sopenharmony_ci return global.pcm32.skip_start; 679159b3361Sopenharmony_ci} 680159b3361Sopenharmony_ci 681159b3361Sopenharmony_ciint 682159b3361Sopenharmony_cisamples_to_skip_at_end(void) 683159b3361Sopenharmony_ci{ 684159b3361Sopenharmony_ci return global.pcm32.skip_end; 685159b3361Sopenharmony_ci} 686159b3361Sopenharmony_ci 687159b3361Sopenharmony_civoid 688159b3361Sopenharmony_ciclose_infile(void) 689159b3361Sopenharmony_ci{ 690159b3361Sopenharmony_ci#if defined(HAVE_MPGLIB) || defined(HAVE_MPG123) 691159b3361Sopenharmony_ci if (global.hip != 0) { 692159b3361Sopenharmony_ci hip_decode_exit(global.hip); /* release mp3decoder memory */ 693159b3361Sopenharmony_ci global. hip = 0; 694159b3361Sopenharmony_ci } 695159b3361Sopenharmony_ci#endif 696159b3361Sopenharmony_ci close_input_file(global.music_in); 697159b3361Sopenharmony_ci#ifdef LIBSNDFILE 698159b3361Sopenharmony_ci if (global.snd_file) { 699159b3361Sopenharmony_ci if (sf_close(global.snd_file) != 0) { 700159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 701159b3361Sopenharmony_ci error_printf("Could not close sound file \n"); 702159b3361Sopenharmony_ci } 703159b3361Sopenharmony_ci } 704159b3361Sopenharmony_ci global. snd_file = 0; 705159b3361Sopenharmony_ci } 706159b3361Sopenharmony_ci#endif 707159b3361Sopenharmony_ci freePcmBuffer(&global.pcm32); 708159b3361Sopenharmony_ci freePcmBuffer(&global.pcm16); 709159b3361Sopenharmony_ci global. music_in = 0; 710159b3361Sopenharmony_ci free(global.in_id3v2_tag); 711159b3361Sopenharmony_ci global.in_id3v2_tag = 0; 712159b3361Sopenharmony_ci global.in_id3v2_size = 0; 713159b3361Sopenharmony_ci} 714159b3361Sopenharmony_ci 715159b3361Sopenharmony_ci 716159b3361Sopenharmony_cistatic int 717159b3361Sopenharmony_ci get_audio_common(lame_t gfp, int buffer[2][1152], short buffer16[2][1152]); 718159b3361Sopenharmony_ci 719159b3361Sopenharmony_ci/************************************************************************ 720159b3361Sopenharmony_ci* 721159b3361Sopenharmony_ci* get_audio() 722159b3361Sopenharmony_ci* 723159b3361Sopenharmony_ci* PURPOSE: reads a frame of audio data from a file to the buffer, 724159b3361Sopenharmony_ci* aligns the data for future processing, and separates the 725159b3361Sopenharmony_ci* left and right channels 726159b3361Sopenharmony_ci* 727159b3361Sopenharmony_ci************************************************************************/ 728159b3361Sopenharmony_ciint 729159b3361Sopenharmony_ciget_audio(lame_t gfp, int buffer[2][1152]) 730159b3361Sopenharmony_ci{ 731159b3361Sopenharmony_ci int used = 0, read = 0; 732159b3361Sopenharmony_ci do { 733159b3361Sopenharmony_ci read = get_audio_common(gfp, buffer, NULL); 734159b3361Sopenharmony_ci used = addPcmBuffer(&global.pcm32, buffer[0], buffer[1], read); 735159b3361Sopenharmony_ci } while (used <= 0 && read > 0); 736159b3361Sopenharmony_ci if (read < 0) { 737159b3361Sopenharmony_ci return read; 738159b3361Sopenharmony_ci } 739159b3361Sopenharmony_ci if (global_reader.swap_channel == 0) 740159b3361Sopenharmony_ci return takePcmBuffer(&global.pcm32, buffer[0], buffer[1], used, 1152); 741159b3361Sopenharmony_ci else 742159b3361Sopenharmony_ci return takePcmBuffer(&global.pcm32, buffer[1], buffer[0], used, 1152); 743159b3361Sopenharmony_ci} 744159b3361Sopenharmony_ci 745159b3361Sopenharmony_ci/* 746159b3361Sopenharmony_ci get_audio16 - behave as the original get_audio function, with a limited 747159b3361Sopenharmony_ci 16 bit per sample output 748159b3361Sopenharmony_ci*/ 749159b3361Sopenharmony_ciint 750159b3361Sopenharmony_ciget_audio16(lame_t gfp, short buffer[2][1152]) 751159b3361Sopenharmony_ci{ 752159b3361Sopenharmony_ci int used = 0, read = 0; 753159b3361Sopenharmony_ci do { 754159b3361Sopenharmony_ci read = get_audio_common(gfp, NULL, buffer); 755159b3361Sopenharmony_ci used = addPcmBuffer(&global.pcm16, buffer[0], buffer[1], read); 756159b3361Sopenharmony_ci } while (used <= 0 && read > 0); 757159b3361Sopenharmony_ci if (read < 0) { 758159b3361Sopenharmony_ci return read; 759159b3361Sopenharmony_ci } 760159b3361Sopenharmony_ci if (global_reader.swap_channel == 0) 761159b3361Sopenharmony_ci return takePcmBuffer(&global.pcm16, buffer[0], buffer[1], used, 1152); 762159b3361Sopenharmony_ci else 763159b3361Sopenharmony_ci return takePcmBuffer(&global.pcm16, buffer[1], buffer[0], used, 1152); 764159b3361Sopenharmony_ci} 765159b3361Sopenharmony_ci 766159b3361Sopenharmony_ci/************************************************************************ 767159b3361Sopenharmony_ci get_audio_common - central functionality of get_audio* 768159b3361Sopenharmony_ci in: gfp 769159b3361Sopenharmony_ci buffer output to the int buffer or 16-bit buffer 770159b3361Sopenharmony_ci out: buffer int output (if buffer != NULL) 771159b3361Sopenharmony_ci buffer16 16-bit output (if buffer == NULL) 772159b3361Sopenharmony_cireturns: samples read 773159b3361Sopenharmony_cinote: either buffer or buffer16 must be allocated upon call 774159b3361Sopenharmony_ci*/ 775159b3361Sopenharmony_cistatic int 776159b3361Sopenharmony_ciget_audio_common(lame_t gfp, int buffer[2][1152], short buffer16[2][1152]) 777159b3361Sopenharmony_ci{ 778159b3361Sopenharmony_ci const int num_channels = lame_get_num_channels(gfp); 779159b3361Sopenharmony_ci const int framesize = lame_get_framesize(gfp); 780159b3361Sopenharmony_ci int insamp[2 * 1152]; 781159b3361Sopenharmony_ci short buf_tmp16[2][1152]; 782159b3361Sopenharmony_ci int samples_read; 783159b3361Sopenharmony_ci int samples_to_read; 784159b3361Sopenharmony_ci int i; 785159b3361Sopenharmony_ci 786159b3361Sopenharmony_ci /* sanity checks, that's what we expect to be true */ 787159b3361Sopenharmony_ci if ((num_channels < 1 || 2 < num_channels) 788159b3361Sopenharmony_ci ||(framesize < 1 || 1152 < framesize)) { 789159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 790159b3361Sopenharmony_ci error_printf("Error: internal problem!\n"); 791159b3361Sopenharmony_ci } 792159b3361Sopenharmony_ci return -1; 793159b3361Sopenharmony_ci } 794159b3361Sopenharmony_ci 795159b3361Sopenharmony_ci /* 796159b3361Sopenharmony_ci * NOTE: LAME can now handle arbritray size input data packets, 797159b3361Sopenharmony_ci * so there is no reason to read the input data in chuncks of 798159b3361Sopenharmony_ci * size "framesize". EXCEPT: the LAME graphical frame analyzer 799159b3361Sopenharmony_ci * will get out of sync if we read more than framesize worth of data. 800159b3361Sopenharmony_ci */ 801159b3361Sopenharmony_ci 802159b3361Sopenharmony_ci samples_to_read = framesize; 803159b3361Sopenharmony_ci 804159b3361Sopenharmony_ci /* if this flag has been set, then we are carefull to read 805159b3361Sopenharmony_ci * exactly num_samples and no more. This is useful for .wav and .aiff 806159b3361Sopenharmony_ci * files which have id3 or other tags at the end. Note that if you 807159b3361Sopenharmony_ci * are using LIBSNDFILE, this is not necessary 808159b3361Sopenharmony_ci */ 809159b3361Sopenharmony_ci if (global.count_samples_carefully) { 810159b3361Sopenharmony_ci unsigned int tmp_num_samples, remaining; 811159b3361Sopenharmony_ci /* get num_samples */ 812159b3361Sopenharmony_ci if (is_mpeg_file_format(global_reader.input_format)) { 813159b3361Sopenharmony_ci tmp_num_samples = global_decoder.mp3input_data.nsamp; 814159b3361Sopenharmony_ci } 815159b3361Sopenharmony_ci else { 816159b3361Sopenharmony_ci tmp_num_samples = lame_get_num_samples(gfp); 817159b3361Sopenharmony_ci } 818159b3361Sopenharmony_ci if (global.num_samples_read < tmp_num_samples) { 819159b3361Sopenharmony_ci remaining = tmp_num_samples - global.num_samples_read; 820159b3361Sopenharmony_ci } 821159b3361Sopenharmony_ci else { 822159b3361Sopenharmony_ci remaining = 0; 823159b3361Sopenharmony_ci } 824159b3361Sopenharmony_ci if (remaining < (unsigned int) framesize && 0 != tmp_num_samples) 825159b3361Sopenharmony_ci /* in case the input is a FIFO (at least it's reproducible with 826159b3361Sopenharmony_ci a FIFO) tmp_num_samples may be 0 and therefore remaining 827159b3361Sopenharmony_ci would be 0, but we need to read some samples, so don't 828159b3361Sopenharmony_ci change samples_to_read to the wrong value in this case */ 829159b3361Sopenharmony_ci samples_to_read = remaining; 830159b3361Sopenharmony_ci } 831159b3361Sopenharmony_ci 832159b3361Sopenharmony_ci if (is_mpeg_file_format(global_reader.input_format)) { 833159b3361Sopenharmony_ci if (buffer != NULL) 834159b3361Sopenharmony_ci samples_read = read_samples_mp3(gfp, global.music_in, buf_tmp16); 835159b3361Sopenharmony_ci else 836159b3361Sopenharmony_ci samples_read = read_samples_mp3(gfp, global.music_in, buffer16); 837159b3361Sopenharmony_ci if (samples_read < 0) { 838159b3361Sopenharmony_ci return samples_read; 839159b3361Sopenharmony_ci } 840159b3361Sopenharmony_ci } 841159b3361Sopenharmony_ci else { 842159b3361Sopenharmony_ci int *p; 843159b3361Sopenharmony_ci if (global.snd_file) { 844159b3361Sopenharmony_ci#ifdef LIBSNDFILE 845159b3361Sopenharmony_ci samples_read = sf_read_int(global.snd_file, insamp, num_channels * samples_to_read); 846159b3361Sopenharmony_ci#else 847159b3361Sopenharmony_ci samples_read = 0; 848159b3361Sopenharmony_ci#endif 849159b3361Sopenharmony_ci } 850159b3361Sopenharmony_ci else { 851159b3361Sopenharmony_ci samples_read = 852159b3361Sopenharmony_ci read_samples_pcm(global.music_in, insamp, num_channels * samples_to_read); 853159b3361Sopenharmony_ci } 854159b3361Sopenharmony_ci if (samples_read < 0) { 855159b3361Sopenharmony_ci return samples_read; 856159b3361Sopenharmony_ci } 857159b3361Sopenharmony_ci p = insamp + samples_read; 858159b3361Sopenharmony_ci samples_read /= num_channels; 859159b3361Sopenharmony_ci if (buffer != NULL) { /* output to int buffer */ 860159b3361Sopenharmony_ci if (num_channels == 2) { 861159b3361Sopenharmony_ci for (i = samples_read; --i >= 0;) { 862159b3361Sopenharmony_ci buffer[1][i] = *--p; 863159b3361Sopenharmony_ci buffer[0][i] = *--p; 864159b3361Sopenharmony_ci } 865159b3361Sopenharmony_ci } 866159b3361Sopenharmony_ci else if (num_channels == 1) { 867159b3361Sopenharmony_ci memset(buffer[1], 0, samples_read * sizeof(int)); 868159b3361Sopenharmony_ci for (i = samples_read; --i >= 0;) { 869159b3361Sopenharmony_ci buffer[0][i] = *--p; 870159b3361Sopenharmony_ci } 871159b3361Sopenharmony_ci } 872159b3361Sopenharmony_ci else 873159b3361Sopenharmony_ci assert(0); 874159b3361Sopenharmony_ci } 875159b3361Sopenharmony_ci else { /* convert from int; output to 16-bit buffer */ 876159b3361Sopenharmony_ci if (num_channels == 2) { 877159b3361Sopenharmony_ci for (i = samples_read; --i >= 0;) { 878159b3361Sopenharmony_ci buffer16[1][i] = *--p >> (8 * sizeof(int) - 16); 879159b3361Sopenharmony_ci buffer16[0][i] = *--p >> (8 * sizeof(int) - 16); 880159b3361Sopenharmony_ci } 881159b3361Sopenharmony_ci } 882159b3361Sopenharmony_ci else if (num_channels == 1) { 883159b3361Sopenharmony_ci memset(buffer16[1], 0, samples_read * sizeof(short)); 884159b3361Sopenharmony_ci for (i = samples_read; --i >= 0;) { 885159b3361Sopenharmony_ci buffer16[0][i] = *--p >> (8 * sizeof(int) - 16); 886159b3361Sopenharmony_ci } 887159b3361Sopenharmony_ci } 888159b3361Sopenharmony_ci else 889159b3361Sopenharmony_ci assert(0); 890159b3361Sopenharmony_ci } 891159b3361Sopenharmony_ci } 892159b3361Sopenharmony_ci 893159b3361Sopenharmony_ci /* LAME mp3 output 16bit - convert to int, if necessary */ 894159b3361Sopenharmony_ci if (is_mpeg_file_format(global_reader.input_format)) { 895159b3361Sopenharmony_ci if (buffer != NULL) { 896159b3361Sopenharmony_ci for (i = samples_read; --i >= 0;) 897159b3361Sopenharmony_ci buffer[0][i] = buf_tmp16[0][i] << (8 * sizeof(int) - 16); 898159b3361Sopenharmony_ci if (num_channels == 2) { 899159b3361Sopenharmony_ci for (i = samples_read; --i >= 0;) 900159b3361Sopenharmony_ci buffer[1][i] = buf_tmp16[1][i] << (8 * sizeof(int) - 16); 901159b3361Sopenharmony_ci } 902159b3361Sopenharmony_ci else if (num_channels == 1) { 903159b3361Sopenharmony_ci memset(buffer[1], 0, samples_read * sizeof(int)); 904159b3361Sopenharmony_ci } 905159b3361Sopenharmony_ci else 906159b3361Sopenharmony_ci assert(0); 907159b3361Sopenharmony_ci } 908159b3361Sopenharmony_ci } 909159b3361Sopenharmony_ci 910159b3361Sopenharmony_ci 911159b3361Sopenharmony_ci /* if ... then it is considered infinitely long. 912159b3361Sopenharmony_ci Don't count the samples */ 913159b3361Sopenharmony_ci if (global.count_samples_carefully) 914159b3361Sopenharmony_ci global. num_samples_read += samples_read; 915159b3361Sopenharmony_ci 916159b3361Sopenharmony_ci return samples_read; 917159b3361Sopenharmony_ci} 918159b3361Sopenharmony_ci 919159b3361Sopenharmony_ci 920159b3361Sopenharmony_ci 921159b3361Sopenharmony_cistatic int 922159b3361Sopenharmony_ciread_samples_mp3(lame_t gfp, FILE * musicin, short int mpg123pcm[2][1152]) 923159b3361Sopenharmony_ci{ 924159b3361Sopenharmony_ci int out; 925159b3361Sopenharmony_ci#ifdef HAVE_MPG123 926159b3361Sopenharmony_ci short int *outbuf; 927159b3361Sopenharmony_ci size_t outbytes; 928159b3361Sopenharmony_ci#endif 929159b3361Sopenharmony_ci#if defined(AMIGA_MPEGA) || defined(HAVE_MPGLIB) || defined(HAVE_MPG123) 930159b3361Sopenharmony_ci int samplerate; 931159b3361Sopenharmony_ci static const char type_name[] = "MP3 file"; 932159b3361Sopenharmony_ci 933159b3361Sopenharmony_ci#ifdef HAVE_MPG123 934159b3361Sopenharmony_ci /* Need to deinterleave so rather use mpg123_decode_frame() to decode the 935159b3361Sopenharmony_ci current frame and deinterleave from the internal buffer. */ 936159b3361Sopenharmony_ci out = mpg123_decode_frame(global.hip->mh, NULL, (unsigned char**)&outbuf, &outbytes); 937159b3361Sopenharmony_ci if (out != MPG123_OK && out != MPG123_DONE) 938159b3361Sopenharmony_ci { 939159b3361Sopenharmony_ci if (out == MPG123_NEW_FORMAT) 940159b3361Sopenharmony_ci { 941159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 942159b3361Sopenharmony_ci error_printf("Error: format changed in %s - not supported\n", 943159b3361Sopenharmony_ci type_name); 944159b3361Sopenharmony_ci } 945159b3361Sopenharmony_ci } 946159b3361Sopenharmony_ci return -1; 947159b3361Sopenharmony_ci } 948159b3361Sopenharmony_ci out = outbytes/(sizeof(short)*global_decoder.mp3input_data.stereo); 949159b3361Sopenharmony_ci if (global_decoder.mp3input_data.stereo == 2) { 950159b3361Sopenharmony_ci int i; 951159b3361Sopenharmony_ci for (i=0; i<out; ++i) { 952159b3361Sopenharmony_ci mpg123pcm[0][i] = *outbuf++; 953159b3361Sopenharmony_ci mpg123pcm[1][i] = *outbuf++; 954159b3361Sopenharmony_ci } 955159b3361Sopenharmony_ci } 956159b3361Sopenharmony_ci else 957159b3361Sopenharmony_ci memcpy(mpg123pcm[0], outbuf, sizeof(short)*out); 958159b3361Sopenharmony_ci if(global.hip->pinfo) 959159b3361Sopenharmony_ci hip_finish_pinfo(global.hip); 960159b3361Sopenharmony_ci#else 961159b3361Sopenharmony_ci out = lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1], &global_decoder.mp3input_data); 962159b3361Sopenharmony_ci /* 963159b3361Sopenharmony_ci * out < 0: error, probably EOF 964159b3361Sopenharmony_ci * out = 0: not possible with lame_decode_fromfile() ??? 965159b3361Sopenharmony_ci * out > 0: number of output samples 966159b3361Sopenharmony_ci */ 967159b3361Sopenharmony_ci if (out < 0) { 968159b3361Sopenharmony_ci memset(mpg123pcm, 0, sizeof(**mpg123pcm) * 2 * 1152); 969159b3361Sopenharmony_ci return 0; 970159b3361Sopenharmony_ci } 971159b3361Sopenharmony_ci 972159b3361Sopenharmony_ci if (lame_get_num_channels(gfp) != global_decoder.mp3input_data.stereo) { 973159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 974159b3361Sopenharmony_ci error_printf("Error: number of channels has changed in %s - not supported\n", 975159b3361Sopenharmony_ci type_name); 976159b3361Sopenharmony_ci } 977159b3361Sopenharmony_ci out = -1; 978159b3361Sopenharmony_ci } 979159b3361Sopenharmony_ci samplerate = global_reader.input_samplerate; 980159b3361Sopenharmony_ci if (samplerate == 0) { 981159b3361Sopenharmony_ci samplerate = global_decoder.mp3input_data.samplerate; 982159b3361Sopenharmony_ci } 983159b3361Sopenharmony_ci if (lame_get_in_samplerate(gfp) != samplerate) { 984159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 985159b3361Sopenharmony_ci error_printf("Error: sample frequency has changed in %s - not supported\n", type_name); 986159b3361Sopenharmony_ci } 987159b3361Sopenharmony_ci out = -1; 988159b3361Sopenharmony_ci } 989159b3361Sopenharmony_ci#endif 990159b3361Sopenharmony_ci#else 991159b3361Sopenharmony_ci out = -1; 992159b3361Sopenharmony_ci#endif 993159b3361Sopenharmony_ci return out; 994159b3361Sopenharmony_ci} 995159b3361Sopenharmony_ci 996159b3361Sopenharmony_cistatic 997159b3361Sopenharmony_ciint set_input_num_channels(lame_t gfp, int num_channels) 998159b3361Sopenharmony_ci{ 999159b3361Sopenharmony_ci if (gfp) { 1000159b3361Sopenharmony_ci if (-1 == lame_set_num_channels(gfp, num_channels)) { 1001159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1002159b3361Sopenharmony_ci error_printf("Unsupported number of channels: %d\n", num_channels); 1003159b3361Sopenharmony_ci } 1004159b3361Sopenharmony_ci return 0; 1005159b3361Sopenharmony_ci } 1006159b3361Sopenharmony_ci } 1007159b3361Sopenharmony_ci return 1; 1008159b3361Sopenharmony_ci} 1009159b3361Sopenharmony_ci 1010159b3361Sopenharmony_cistatic 1011159b3361Sopenharmony_ciint set_input_samplerate(lame_t gfp, int input_samplerate) 1012159b3361Sopenharmony_ci{ 1013159b3361Sopenharmony_ci if (gfp) { 1014159b3361Sopenharmony_ci int sr = global_reader.input_samplerate; 1015159b3361Sopenharmony_ci if (sr == 0) sr = input_samplerate; 1016159b3361Sopenharmony_ci if (-1 == lame_set_in_samplerate(gfp, sr)) { 1017159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1018159b3361Sopenharmony_ci error_printf("Unsupported sample rate: %d\n", sr); 1019159b3361Sopenharmony_ci } 1020159b3361Sopenharmony_ci return 0; 1021159b3361Sopenharmony_ci } 1022159b3361Sopenharmony_ci } 1023159b3361Sopenharmony_ci return 1; 1024159b3361Sopenharmony_ci} 1025159b3361Sopenharmony_ci 1026159b3361Sopenharmony_ciint 1027159b3361Sopenharmony_ciWriteWaveHeader(FILE * const fp, int pcmbytes, int freq, int channels, int bits) 1028159b3361Sopenharmony_ci{ 1029159b3361Sopenharmony_ci int bytes = (bits + 7) / 8; 1030159b3361Sopenharmony_ci 1031159b3361Sopenharmony_ci /* quick and dirty, but documented */ 1032159b3361Sopenharmony_ci fwrite("RIFF", 1, 4, fp); /* label */ 1033159b3361Sopenharmony_ci write_32_bits_low_high(fp, pcmbytes + 44 - 8); /* length in bytes without header */ 1034159b3361Sopenharmony_ci fwrite("WAVEfmt ", 2, 4, fp); /* 2 labels */ 1035159b3361Sopenharmony_ci write_32_bits_low_high(fp, 2 + 2 + 4 + 4 + 2 + 2); /* length of PCM format declaration area */ 1036159b3361Sopenharmony_ci write_16_bits_low_high(fp, 1); /* is PCM? */ 1037159b3361Sopenharmony_ci write_16_bits_low_high(fp, channels); /* number of channels */ 1038159b3361Sopenharmony_ci write_32_bits_low_high(fp, freq); /* sample frequency in [Hz] */ 1039159b3361Sopenharmony_ci write_32_bits_low_high(fp, freq * channels * bytes); /* bytes per second */ 1040159b3361Sopenharmony_ci write_16_bits_low_high(fp, channels * bytes); /* bytes per sample time */ 1041159b3361Sopenharmony_ci write_16_bits_low_high(fp, bits); /* bits per sample */ 1042159b3361Sopenharmony_ci fwrite("data", 1, 4, fp); /* label */ 1043159b3361Sopenharmony_ci write_32_bits_low_high(fp, pcmbytes); /* length in bytes of raw PCM data */ 1044159b3361Sopenharmony_ci 1045159b3361Sopenharmony_ci return ferror(fp) ? -1 : 0; 1046159b3361Sopenharmony_ci} 1047159b3361Sopenharmony_ci 1048159b3361Sopenharmony_ci 1049159b3361Sopenharmony_ci 1050159b3361Sopenharmony_ci 1051159b3361Sopenharmony_ci#if defined(LIBSNDFILE) 1052159b3361Sopenharmony_ci 1053159b3361Sopenharmony_ciextern SNDFILE *sf_wchar_open(wchar_t const *wpath, int mode, SF_INFO * sfinfo); 1054159b3361Sopenharmony_ci 1055159b3361Sopenharmony_cistatic SNDFILE * 1056159b3361Sopenharmony_ciopen_snd_file(lame_t gfp, char const *inPath) 1057159b3361Sopenharmony_ci{ 1058159b3361Sopenharmony_ci char const *lpszFileName = inPath; 1059159b3361Sopenharmony_ci SNDFILE *gs_pSndFileIn = NULL; 1060159b3361Sopenharmony_ci SF_INFO gs_wfInfo; 1061159b3361Sopenharmony_ci 1062159b3361Sopenharmony_ci { 1063159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__) 1064159b3361Sopenharmony_ci wchar_t *file_name = utf8ToUnicode(lpszFileName); 1065159b3361Sopenharmony_ci#endif 1066159b3361Sopenharmony_ci /* Try to open the sound file */ 1067159b3361Sopenharmony_ci memset(&gs_wfInfo, 0, sizeof(gs_wfInfo)); 1068159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__) 1069159b3361Sopenharmony_ci gs_pSndFileIn = sf_wchar_open(file_name, SFM_READ, &gs_wfInfo); 1070159b3361Sopenharmony_ci#else 1071159b3361Sopenharmony_ci gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo); 1072159b3361Sopenharmony_ci#endif 1073159b3361Sopenharmony_ci 1074159b3361Sopenharmony_ci if (gs_pSndFileIn == NULL) { 1075159b3361Sopenharmony_ci if (global_raw_pcm.in_signed == 0 && global_raw_pcm.in_bitwidth != 8) { 1076159b3361Sopenharmony_ci error_printf("Unsigned input only supported with bitwidth 8\n"); 1077159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__) 1078159b3361Sopenharmony_ci free(file_name); 1079159b3361Sopenharmony_ci#endif 1080159b3361Sopenharmony_ci return 0; 1081159b3361Sopenharmony_ci } 1082159b3361Sopenharmony_ci /* set some defaults incase input is raw PCM */ 1083159b3361Sopenharmony_ci gs_wfInfo.seekable = (global_reader.input_format != sf_raw); /* if user specified -r, set to not seekable */ 1084159b3361Sopenharmony_ci gs_wfInfo.samplerate = lame_get_in_samplerate(gfp); 1085159b3361Sopenharmony_ci gs_wfInfo.channels = lame_get_num_channels(gfp); 1086159b3361Sopenharmony_ci gs_wfInfo.format = SF_FORMAT_RAW; 1087159b3361Sopenharmony_ci if ((global_raw_pcm.in_endian == ByteOrderLittleEndian) ^ (global_reader.swapbytes != 1088159b3361Sopenharmony_ci 0)) { 1089159b3361Sopenharmony_ci gs_wfInfo.format |= SF_ENDIAN_LITTLE; 1090159b3361Sopenharmony_ci } 1091159b3361Sopenharmony_ci else { 1092159b3361Sopenharmony_ci gs_wfInfo.format |= SF_ENDIAN_BIG; 1093159b3361Sopenharmony_ci } 1094159b3361Sopenharmony_ci switch (global_raw_pcm.in_bitwidth) { 1095159b3361Sopenharmony_ci case 8: 1096159b3361Sopenharmony_ci gs_wfInfo.format |= 1097159b3361Sopenharmony_ci global_raw_pcm.in_signed == 0 ? SF_FORMAT_PCM_U8 : SF_FORMAT_PCM_S8; 1098159b3361Sopenharmony_ci break; 1099159b3361Sopenharmony_ci case 16: 1100159b3361Sopenharmony_ci gs_wfInfo.format |= SF_FORMAT_PCM_16; 1101159b3361Sopenharmony_ci break; 1102159b3361Sopenharmony_ci case 24: 1103159b3361Sopenharmony_ci gs_wfInfo.format |= SF_FORMAT_PCM_24; 1104159b3361Sopenharmony_ci break; 1105159b3361Sopenharmony_ci case 32: 1106159b3361Sopenharmony_ci gs_wfInfo.format |= SF_FORMAT_PCM_32; 1107159b3361Sopenharmony_ci break; 1108159b3361Sopenharmony_ci default: 1109159b3361Sopenharmony_ci break; 1110159b3361Sopenharmony_ci } 1111159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__) 1112159b3361Sopenharmony_ci gs_pSndFileIn = sf_wchar_open(file_name, SFM_READ, &gs_wfInfo); 1113159b3361Sopenharmony_ci#else 1114159b3361Sopenharmony_ci gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo); 1115159b3361Sopenharmony_ci#endif 1116159b3361Sopenharmony_ci } 1117159b3361Sopenharmony_ci#if defined( _WIN32 ) && !defined(__MINGW32__) 1118159b3361Sopenharmony_ci free(file_name); 1119159b3361Sopenharmony_ci#endif 1120159b3361Sopenharmony_ci 1121159b3361Sopenharmony_ci /* Check result */ 1122159b3361Sopenharmony_ci if (gs_pSndFileIn == NULL) { 1123159b3361Sopenharmony_ci sf_perror(gs_pSndFileIn); 1124159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1125159b3361Sopenharmony_ci error_printf("Could not open sound file \"%s\".\n", lpszFileName); 1126159b3361Sopenharmony_ci } 1127159b3361Sopenharmony_ci return 0; 1128159b3361Sopenharmony_ci } 1129159b3361Sopenharmony_ci sf_command(gs_pSndFileIn, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE); 1130159b3361Sopenharmony_ci 1131159b3361Sopenharmony_ci if ((gs_wfInfo.format & SF_FORMAT_RAW) == SF_FORMAT_RAW) { 1132159b3361Sopenharmony_ci global_reader.input_format = sf_raw; 1133159b3361Sopenharmony_ci } 1134159b3361Sopenharmony_ci 1135159b3361Sopenharmony_ci#ifdef _DEBUG_SND_FILE 1136159b3361Sopenharmony_ci printf("\n\nSF_INFO structure\n"); 1137159b3361Sopenharmony_ci printf("samplerate :%d\n", gs_wfInfo.samplerate); 1138159b3361Sopenharmony_ci printf("samples :%d\n", gs_wfInfo.frames); 1139159b3361Sopenharmony_ci printf("channels :%d\n", gs_wfInfo.channels); 1140159b3361Sopenharmony_ci printf("format :"); 1141159b3361Sopenharmony_ci 1142159b3361Sopenharmony_ci /* new formats from sbellon@sbellon.de 1/2000 */ 1143159b3361Sopenharmony_ci 1144159b3361Sopenharmony_ci switch (gs_wfInfo.format & SF_FORMAT_TYPEMASK) { 1145159b3361Sopenharmony_ci case SF_FORMAT_WAV: 1146159b3361Sopenharmony_ci printf("Microsoft WAV format (big endian). "); 1147159b3361Sopenharmony_ci break; 1148159b3361Sopenharmony_ci case SF_FORMAT_AIFF: 1149159b3361Sopenharmony_ci printf("Apple/SGI AIFF format (little endian). "); 1150159b3361Sopenharmony_ci break; 1151159b3361Sopenharmony_ci case SF_FORMAT_AU: 1152159b3361Sopenharmony_ci printf("Sun/NeXT AU format (big endian). "); 1153159b3361Sopenharmony_ci break; 1154159b3361Sopenharmony_ci /* 1155159b3361Sopenharmony_ci case SF_FORMAT_AULE: 1156159b3361Sopenharmony_ci DEBUGF("DEC AU format (little endian). "); 1157159b3361Sopenharmony_ci break; 1158159b3361Sopenharmony_ci */ 1159159b3361Sopenharmony_ci case SF_FORMAT_RAW: 1160159b3361Sopenharmony_ci printf("RAW PCM data. "); 1161159b3361Sopenharmony_ci break; 1162159b3361Sopenharmony_ci case SF_FORMAT_PAF: 1163159b3361Sopenharmony_ci printf("Ensoniq PARIS file format. "); 1164159b3361Sopenharmony_ci break; 1165159b3361Sopenharmony_ci case SF_FORMAT_SVX: 1166159b3361Sopenharmony_ci printf("Amiga IFF / SVX8 / SV16 format. "); 1167159b3361Sopenharmony_ci break; 1168159b3361Sopenharmony_ci case SF_FORMAT_NIST: 1169159b3361Sopenharmony_ci printf("Sphere NIST format. "); 1170159b3361Sopenharmony_ci break; 1171159b3361Sopenharmony_ci default: 1172159b3361Sopenharmony_ci assert(0); 1173159b3361Sopenharmony_ci break; 1174159b3361Sopenharmony_ci } 1175159b3361Sopenharmony_ci 1176159b3361Sopenharmony_ci switch (gs_wfInfo.format & SF_FORMAT_SUBMASK) { 1177159b3361Sopenharmony_ci /* 1178159b3361Sopenharmony_ci case SF_FORMAT_PCM: 1179159b3361Sopenharmony_ci DEBUGF("PCM data in 8, 16, 24 or 32 bits."); 1180159b3361Sopenharmony_ci break; 1181159b3361Sopenharmony_ci */ 1182159b3361Sopenharmony_ci case SF_FORMAT_FLOAT: 1183159b3361Sopenharmony_ci printf("32 bit Intel x86 floats."); 1184159b3361Sopenharmony_ci break; 1185159b3361Sopenharmony_ci case SF_FORMAT_ULAW: 1186159b3361Sopenharmony_ci printf("U-Law encoded."); 1187159b3361Sopenharmony_ci break; 1188159b3361Sopenharmony_ci case SF_FORMAT_ALAW: 1189159b3361Sopenharmony_ci printf("A-Law encoded."); 1190159b3361Sopenharmony_ci break; 1191159b3361Sopenharmony_ci case SF_FORMAT_IMA_ADPCM: 1192159b3361Sopenharmony_ci printf("IMA ADPCM."); 1193159b3361Sopenharmony_ci break; 1194159b3361Sopenharmony_ci case SF_FORMAT_MS_ADPCM: 1195159b3361Sopenharmony_ci printf("Microsoft ADPCM."); 1196159b3361Sopenharmony_ci break; 1197159b3361Sopenharmony_ci /* 1198159b3361Sopenharmony_ci case SF_FORMAT_PCM_BE: 1199159b3361Sopenharmony_ci DEBUGF("Big endian PCM data."); 1200159b3361Sopenharmony_ci break; 1201159b3361Sopenharmony_ci case SF_FORMAT_PCM_LE: 1202159b3361Sopenharmony_ci DEBUGF("Little endian PCM data."); 1203159b3361Sopenharmony_ci break; 1204159b3361Sopenharmony_ci */ 1205159b3361Sopenharmony_ci case SF_FORMAT_PCM_S8: 1206159b3361Sopenharmony_ci printf("Signed 8 bit PCM."); 1207159b3361Sopenharmony_ci break; 1208159b3361Sopenharmony_ci case SF_FORMAT_PCM_U8: 1209159b3361Sopenharmony_ci printf("Unsigned 8 bit PCM."); 1210159b3361Sopenharmony_ci break; 1211159b3361Sopenharmony_ci case SF_FORMAT_PCM_16: 1212159b3361Sopenharmony_ci printf("Signed 16 bit PCM."); 1213159b3361Sopenharmony_ci break; 1214159b3361Sopenharmony_ci case SF_FORMAT_PCM_24: 1215159b3361Sopenharmony_ci printf("Signed 24 bit PCM."); 1216159b3361Sopenharmony_ci break; 1217159b3361Sopenharmony_ci case SF_FORMAT_PCM_32: 1218159b3361Sopenharmony_ci printf("Signed 32 bit PCM."); 1219159b3361Sopenharmony_ci break; 1220159b3361Sopenharmony_ci /* 1221159b3361Sopenharmony_ci case SF_FORMAT_SVX_FIB: 1222159b3361Sopenharmony_ci DEBUGF("SVX Fibonacci Delta encoding."); 1223159b3361Sopenharmony_ci break; 1224159b3361Sopenharmony_ci case SF_FORMAT_SVX_EXP: 1225159b3361Sopenharmony_ci DEBUGF("SVX Exponential Delta encoding."); 1226159b3361Sopenharmony_ci break; 1227159b3361Sopenharmony_ci */ 1228159b3361Sopenharmony_ci default: 1229159b3361Sopenharmony_ci assert(0); 1230159b3361Sopenharmony_ci break; 1231159b3361Sopenharmony_ci } 1232159b3361Sopenharmony_ci 1233159b3361Sopenharmony_ci printf("\n"); 1234159b3361Sopenharmony_ci printf("sections :%d\n", gs_wfInfo.sections); 1235159b3361Sopenharmony_ci printf("seekable :%d\n", gs_wfInfo.seekable); 1236159b3361Sopenharmony_ci#endif 1237159b3361Sopenharmony_ci /* Check result */ 1238159b3361Sopenharmony_ci if (gs_pSndFileIn == NULL) { 1239159b3361Sopenharmony_ci sf_perror(gs_pSndFileIn); 1240159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1241159b3361Sopenharmony_ci error_printf("Could not open sound file \"%s\".\n", lpszFileName); 1242159b3361Sopenharmony_ci } 1243159b3361Sopenharmony_ci return 0; 1244159b3361Sopenharmony_ci } 1245159b3361Sopenharmony_ci 1246159b3361Sopenharmony_ci 1247159b3361Sopenharmony_ci if(gs_wfInfo.frames >= 0 && gs_wfInfo.frames < (sf_count_t)(unsigned)MAX_U_32_NUM) 1248159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, gs_wfInfo.frames); 1249159b3361Sopenharmony_ci else 1250159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, MAX_U_32_NUM); 1251159b3361Sopenharmony_ci if (!set_input_num_channels(gfp, gs_wfInfo.channels)) { 1252159b3361Sopenharmony_ci sf_close(gs_pSndFileIn); 1253159b3361Sopenharmony_ci return 0; 1254159b3361Sopenharmony_ci } 1255159b3361Sopenharmony_ci if (!set_input_samplerate(gfp, gs_wfInfo.samplerate)) { 1256159b3361Sopenharmony_ci sf_close(gs_pSndFileIn); 1257159b3361Sopenharmony_ci return 0; 1258159b3361Sopenharmony_ci } 1259159b3361Sopenharmony_ci global. pcmbitwidth = 32; 1260159b3361Sopenharmony_ci } 1261159b3361Sopenharmony_ci#if 0 1262159b3361Sopenharmony_ci if (lame_get_num_samples(gfp) == MAX_U_32_NUM) { 1263159b3361Sopenharmony_ci /* try to figure out num_samples */ 1264159b3361Sopenharmony_ci double const flen = lame_get_file_size(lpszFileName); 1265159b3361Sopenharmony_ci if (flen >= 0) { 1266159b3361Sopenharmony_ci /* try file size, assume 2 bytes per sample */ 1267159b3361Sopenharmony_ci lame_set_num_samples(gfp, flen / (2 * lame_get_num_channels(gfp))); 1268159b3361Sopenharmony_ci } 1269159b3361Sopenharmony_ci } 1270159b3361Sopenharmony_ci#endif 1271159b3361Sopenharmony_ci return gs_pSndFileIn; 1272159b3361Sopenharmony_ci} 1273159b3361Sopenharmony_ci 1274159b3361Sopenharmony_ci#endif /* defined(LIBSNDFILE) */ 1275159b3361Sopenharmony_ci 1276159b3361Sopenharmony_ci 1277159b3361Sopenharmony_ci 1278159b3361Sopenharmony_ci/************************************************************************ 1279159b3361Sopenharmony_ciunpack_read_samples - read and unpack signed low-to-high byte or unsigned 1280159b3361Sopenharmony_ci single byte input. (used for read_samples function) 1281159b3361Sopenharmony_ci Output integers are stored in the native byte order 1282159b3361Sopenharmony_ci (little or big endian). -jd 1283159b3361Sopenharmony_ci in: samples_to_read 1284159b3361Sopenharmony_ci bytes_per_sample 1285159b3361Sopenharmony_ci swap_order - set for high-to-low byte order input stream 1286159b3361Sopenharmony_ci i/o: pcm_in 1287159b3361Sopenharmony_ci out: sample_buffer (must be allocated up to samples_to_read upon call) 1288159b3361Sopenharmony_cireturns: number of samples read 1289159b3361Sopenharmony_ci*/ 1290159b3361Sopenharmony_cistatic int 1291159b3361Sopenharmony_ciunpack_read_samples(const int samples_to_read, const int bytes_per_sample, 1292159b3361Sopenharmony_ci const int swap_order, int *sample_buffer, FILE * pcm_in) 1293159b3361Sopenharmony_ci{ 1294159b3361Sopenharmony_ci int samples_read; 1295159b3361Sopenharmony_ci int i; 1296159b3361Sopenharmony_ci int *op; /* output pointer */ 1297159b3361Sopenharmony_ci unsigned char *ip = (unsigned char *) sample_buffer; /* input pointer */ 1298159b3361Sopenharmony_ci const int b = sizeof(int) * 8; 1299159b3361Sopenharmony_ci 1300159b3361Sopenharmony_ci { 1301159b3361Sopenharmony_ci size_t samples_read_ = fread(sample_buffer, bytes_per_sample, samples_to_read, pcm_in); 1302159b3361Sopenharmony_ci assert( samples_read_ <= INT_MAX ); 1303159b3361Sopenharmony_ci samples_read = (int) samples_read_; 1304159b3361Sopenharmony_ci } 1305159b3361Sopenharmony_ci op = sample_buffer + samples_read; 1306159b3361Sopenharmony_ci 1307159b3361Sopenharmony_ci#define GA_URS_IFLOOP( ga_urs_bps ) \ 1308159b3361Sopenharmony_ci if( bytes_per_sample == ga_urs_bps ) \ 1309159b3361Sopenharmony_ci for( i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >=0;) 1310159b3361Sopenharmony_ci 1311159b3361Sopenharmony_ci if (swap_order == 0) { 1312159b3361Sopenharmony_ci GA_URS_IFLOOP(1) 1313159b3361Sopenharmony_ci * --op = ip[i] << (b - 8); 1314159b3361Sopenharmony_ci GA_URS_IFLOOP(2) 1315159b3361Sopenharmony_ci * --op = ip[i] << (b - 16) | ip[i + 1] << (b - 8); 1316159b3361Sopenharmony_ci GA_URS_IFLOOP(3) 1317159b3361Sopenharmony_ci * --op = ip[i] << (b - 24) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 8); 1318159b3361Sopenharmony_ci GA_URS_IFLOOP(4) 1319159b3361Sopenharmony_ci * --op = 1320159b3361Sopenharmony_ci ip[i] << (b - 32) | ip[i + 1] << (b - 24) | ip[i + 2] << (b - 16) | ip[i + 3] << (b - 1321159b3361Sopenharmony_ci 8); 1322159b3361Sopenharmony_ci } 1323159b3361Sopenharmony_ci else { 1324159b3361Sopenharmony_ci GA_URS_IFLOOP(1) 1325159b3361Sopenharmony_ci * --op = (ip[i] ^ 0x80) << (b - 8) | 0x7f << (b - 16); /* convert from unsigned */ 1326159b3361Sopenharmony_ci GA_URS_IFLOOP(2) 1327159b3361Sopenharmony_ci * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16); 1328159b3361Sopenharmony_ci GA_URS_IFLOOP(3) 1329159b3361Sopenharmony_ci * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24); 1330159b3361Sopenharmony_ci GA_URS_IFLOOP(4) 1331159b3361Sopenharmony_ci * --op = 1332159b3361Sopenharmony_ci ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24) | ip[i + 3] << (b - 1333159b3361Sopenharmony_ci 32); 1334159b3361Sopenharmony_ci } 1335159b3361Sopenharmony_ci#undef GA_URS_IFLOOP 1336159b3361Sopenharmony_ci if (global.pcm_is_ieee_float) { 1337159b3361Sopenharmony_ci ieee754_float32_t const m_max = INT_MAX; 1338159b3361Sopenharmony_ci ieee754_float32_t const m_min = -(ieee754_float32_t) INT_MIN; 1339159b3361Sopenharmony_ci ieee754_float32_t *x = (ieee754_float32_t *) sample_buffer; 1340159b3361Sopenharmony_ci assert(sizeof(ieee754_float32_t) == sizeof(int)); 1341159b3361Sopenharmony_ci for (i = 0; i < samples_to_read; ++i) { 1342159b3361Sopenharmony_ci ieee754_float32_t const u = x[i]; 1343159b3361Sopenharmony_ci int v; 1344159b3361Sopenharmony_ci if (u >= 1) { 1345159b3361Sopenharmony_ci v = INT_MAX; 1346159b3361Sopenharmony_ci } 1347159b3361Sopenharmony_ci else if (u <= -1) { 1348159b3361Sopenharmony_ci v = INT_MIN; 1349159b3361Sopenharmony_ci } 1350159b3361Sopenharmony_ci else if (u >= 0) { 1351159b3361Sopenharmony_ci v = (int) (u * m_max + 0.5f); 1352159b3361Sopenharmony_ci } 1353159b3361Sopenharmony_ci else { 1354159b3361Sopenharmony_ci v = (int) (u * m_min - 0.5f); 1355159b3361Sopenharmony_ci } 1356159b3361Sopenharmony_ci sample_buffer[i] = v; 1357159b3361Sopenharmony_ci } 1358159b3361Sopenharmony_ci } 1359159b3361Sopenharmony_ci return (samples_read); 1360159b3361Sopenharmony_ci} 1361159b3361Sopenharmony_ci 1362159b3361Sopenharmony_ci 1363159b3361Sopenharmony_ci 1364159b3361Sopenharmony_ci/************************************************************************ 1365159b3361Sopenharmony_ci* 1366159b3361Sopenharmony_ci* read_samples() 1367159b3361Sopenharmony_ci* 1368159b3361Sopenharmony_ci* PURPOSE: reads the PCM samples from a file to the buffer 1369159b3361Sopenharmony_ci* 1370159b3361Sopenharmony_ci* SEMANTICS: 1371159b3361Sopenharmony_ci* Reads #samples_read# number of shorts from #musicin# filepointer 1372159b3361Sopenharmony_ci* into #sample_buffer[]#. Returns the number of samples read. 1373159b3361Sopenharmony_ci* 1374159b3361Sopenharmony_ci************************************************************************/ 1375159b3361Sopenharmony_ci 1376159b3361Sopenharmony_cistatic int 1377159b3361Sopenharmony_ciread_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read) 1378159b3361Sopenharmony_ci{ 1379159b3361Sopenharmony_ci int samples_read; 1380159b3361Sopenharmony_ci int bytes_per_sample = global.pcmbitwidth / 8; 1381159b3361Sopenharmony_ci int swap_byte_order; /* byte order of input stream */ 1382159b3361Sopenharmony_ci 1383159b3361Sopenharmony_ci switch (global.pcmbitwidth) { 1384159b3361Sopenharmony_ci case 32: 1385159b3361Sopenharmony_ci case 24: 1386159b3361Sopenharmony_ci case 16: 1387159b3361Sopenharmony_ci if (global_raw_pcm.in_signed == 0) { 1388159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1389159b3361Sopenharmony_ci error_printf("Unsigned input only supported with bitwidth 8\n"); 1390159b3361Sopenharmony_ci } 1391159b3361Sopenharmony_ci return -1; 1392159b3361Sopenharmony_ci } 1393159b3361Sopenharmony_ci swap_byte_order = (global_raw_pcm.in_endian != ByteOrderLittleEndian) ? 1 : 0; 1394159b3361Sopenharmony_ci if (global.pcmswapbytes) { 1395159b3361Sopenharmony_ci swap_byte_order = !swap_byte_order; 1396159b3361Sopenharmony_ci } 1397159b3361Sopenharmony_ci break; 1398159b3361Sopenharmony_ci 1399159b3361Sopenharmony_ci case 8: 1400159b3361Sopenharmony_ci swap_byte_order = global.pcm_is_unsigned_8bit; 1401159b3361Sopenharmony_ci break; 1402159b3361Sopenharmony_ci 1403159b3361Sopenharmony_ci default: 1404159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1405159b3361Sopenharmony_ci error_printf("Only 8, 16, 24 and 32 bit input files supported \n"); 1406159b3361Sopenharmony_ci } 1407159b3361Sopenharmony_ci return -1; 1408159b3361Sopenharmony_ci } 1409159b3361Sopenharmony_ci if (samples_to_read < 0 || samples_to_read > 2304) { 1410159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1411159b3361Sopenharmony_ci error_printf("Error: unexpected number of samples to read: %d\n", samples_to_read); 1412159b3361Sopenharmony_ci } 1413159b3361Sopenharmony_ci return -1; 1414159b3361Sopenharmony_ci } 1415159b3361Sopenharmony_ci samples_read = unpack_read_samples(samples_to_read, bytes_per_sample, swap_byte_order, 1416159b3361Sopenharmony_ci sample_buffer, musicin); 1417159b3361Sopenharmony_ci if (ferror(musicin)) { 1418159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1419159b3361Sopenharmony_ci error_printf("Error reading input file\n"); 1420159b3361Sopenharmony_ci } 1421159b3361Sopenharmony_ci return -1; 1422159b3361Sopenharmony_ci } 1423159b3361Sopenharmony_ci 1424159b3361Sopenharmony_ci return samples_read; 1425159b3361Sopenharmony_ci} 1426159b3361Sopenharmony_ci 1427159b3361Sopenharmony_ci 1428159b3361Sopenharmony_ci 1429159b3361Sopenharmony_ci/* AIFF Definitions */ 1430159b3361Sopenharmony_ci 1431159b3361Sopenharmony_cistatic uint32_t const IFF_ID_FORM = 0x464f524d; /* "FORM" */ 1432159b3361Sopenharmony_cistatic uint32_t const IFF_ID_AIFF = 0x41494646; /* "AIFF" */ 1433159b3361Sopenharmony_cistatic uint32_t const IFF_ID_AIFC = 0x41494643; /* "AIFC" */ 1434159b3361Sopenharmony_cistatic uint32_t const IFF_ID_COMM = 0x434f4d4d; /* "COMM" */ 1435159b3361Sopenharmony_cistatic uint32_t const IFF_ID_SSND = 0x53534e44; /* "SSND" */ 1436159b3361Sopenharmony_cistatic uint32_t const IFF_ID_MPEG = 0x4d504547; /* "MPEG" */ 1437159b3361Sopenharmony_ci 1438159b3361Sopenharmony_cistatic uint32_t const IFF_ID_NONE = 0x4e4f4e45; /* "NONE" *//* AIFF-C data format */ 1439159b3361Sopenharmony_cistatic uint32_t const IFF_ID_2CBE = 0x74776f73; /* "twos" *//* AIFF-C data format */ 1440159b3361Sopenharmony_cistatic uint32_t const IFF_ID_2CLE = 0x736f7774; /* "sowt" *//* AIFF-C data format */ 1441159b3361Sopenharmony_cistatic uint32_t const IFF_ID_FL32 = 0x666C3332; /* "fl32" *//* AIFF-C data format */ 1442159b3361Sopenharmony_cistatic uint32_t const IFF_ID_FL64 = 0x666C3634; /* "fl64" *//* AIFF-C data format */ 1443159b3361Sopenharmony_ci 1444159b3361Sopenharmony_cistatic uint32_t const WAV_ID_RIFF = 0x52494646; /* "RIFF" */ 1445159b3361Sopenharmony_cistatic uint32_t const WAV_ID_WAVE = 0x57415645; /* "WAVE" */ 1446159b3361Sopenharmony_cistatic uint32_t const WAV_ID_FMT = 0x666d7420; /* "fmt " */ 1447159b3361Sopenharmony_cistatic uint32_t const WAV_ID_DATA = 0x64617461; /* "data" */ 1448159b3361Sopenharmony_ci 1449159b3361Sopenharmony_ci#ifndef WAVE_FORMAT_PCM 1450159b3361Sopenharmony_cistatic uint16_t const WAVE_FORMAT_PCM = 0x0001; 1451159b3361Sopenharmony_ci#endif 1452159b3361Sopenharmony_ci#ifndef WAVE_FORMAT_IEEE_FLOAT 1453159b3361Sopenharmony_cistatic uint16_t const WAVE_FORMAT_IEEE_FLOAT = 0x0003; 1454159b3361Sopenharmony_ci#endif 1455159b3361Sopenharmony_ci#ifndef WAVE_FORMAT_EXTENSIBLE 1456159b3361Sopenharmony_cistatic uint16_t const WAVE_FORMAT_EXTENSIBLE = 0xFFFE; 1457159b3361Sopenharmony_ci#endif 1458159b3361Sopenharmony_ci 1459159b3361Sopenharmony_ci 1460159b3361Sopenharmony_cistatic uint32_t 1461159b3361Sopenharmony_cimake_even_number_of_bytes_in_length(uint32_t x) 1462159b3361Sopenharmony_ci{ 1463159b3361Sopenharmony_ci return x + (x & 0x01); 1464159b3361Sopenharmony_ci} 1465159b3361Sopenharmony_ci 1466159b3361Sopenharmony_ci 1467159b3361Sopenharmony_ci/***************************************************************************** 1468159b3361Sopenharmony_ci * 1469159b3361Sopenharmony_ci * Read Microsoft Wave headers 1470159b3361Sopenharmony_ci * 1471159b3361Sopenharmony_ci * By the time we get here the first 32-bits of the file have already been 1472159b3361Sopenharmony_ci * read, and we're pretty sure that we're looking at a WAV file. 1473159b3361Sopenharmony_ci * 1474159b3361Sopenharmony_ci *****************************************************************************/ 1475159b3361Sopenharmony_ci 1476159b3361Sopenharmony_cistatic int 1477159b3361Sopenharmony_ciparse_wave_header(lame_global_flags * gfp, FILE * sf) 1478159b3361Sopenharmony_ci{ 1479159b3361Sopenharmony_ci uint32_t ui32_nSamplesPerSec = 0; 1480159b3361Sopenharmony_ci uint32_t ui32_DataChunkSize = 0; 1481159b3361Sopenharmony_ci uint16_t ui16_wFormatTag = 0; 1482159b3361Sopenharmony_ci uint16_t ui16_nChannels = 0; 1483159b3361Sopenharmony_ci uint16_t ui16_wBitsPerSample = 0; 1484159b3361Sopenharmony_ci 1485159b3361Sopenharmony_ci int is_wav = 0; 1486159b3361Sopenharmony_ci int loop_sanity = 0; 1487159b3361Sopenharmony_ci 1488159b3361Sopenharmony_ci uint32_t ui32_chunkSize = read_32_bits_high_low(sf); /* file_length */ 1489159b3361Sopenharmony_ci uint32_t ui32_WAVEID = read_32_bits_high_low(sf); 1490159b3361Sopenharmony_ci if (ui32_WAVEID != WAV_ID_WAVE || ui32_chunkSize < 1) 1491159b3361Sopenharmony_ci return -1; 1492159b3361Sopenharmony_ci 1493159b3361Sopenharmony_ci for (loop_sanity = 0; loop_sanity < 20; ++loop_sanity) { 1494159b3361Sopenharmony_ci uint32_t ui32_ckID = read_32_bits_high_low(sf); 1495159b3361Sopenharmony_ci if (ui32_ckID == WAV_ID_FMT) { 1496159b3361Sopenharmony_ci uint32_t ui32_nAvgBytesPerSec = 0; 1497159b3361Sopenharmony_ci uint32_t ui32_cksize = 0; 1498159b3361Sopenharmony_ci uint16_t ui16_nBlockAlign = 0; 1499159b3361Sopenharmony_ci 1500159b3361Sopenharmony_ci ui32_cksize = read_32_bits_low_high(sf); 1501159b3361Sopenharmony_ci ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize); 1502159b3361Sopenharmony_ci if (ui32_cksize < 16u) { 1503159b3361Sopenharmony_ci /*DEBUGF("'fmt' chunk too short (only %ld bytes)!", ui32_cksize);*/ 1504159b3361Sopenharmony_ci return -1; 1505159b3361Sopenharmony_ci } 1506159b3361Sopenharmony_ci ui16_wFormatTag = read_16_bits_low_high(sf); 1507159b3361Sopenharmony_ci ui16_nChannels = read_16_bits_low_high(sf); 1508159b3361Sopenharmony_ci ui32_nSamplesPerSec = read_32_bits_low_high(sf); 1509159b3361Sopenharmony_ci ui32_nAvgBytesPerSec = read_32_bits_low_high(sf); 1510159b3361Sopenharmony_ci ui16_nBlockAlign = read_16_bits_low_high(sf); 1511159b3361Sopenharmony_ci ui16_wBitsPerSample = read_16_bits_low_high(sf); 1512159b3361Sopenharmony_ci ui32_cksize -= 16u; 1513159b3361Sopenharmony_ci /* WAVE_FORMAT_EXTENSIBLE support */ 1514159b3361Sopenharmony_ci if ((ui32_cksize > 9u) && (ui16_wFormatTag == WAVE_FORMAT_EXTENSIBLE)) { 1515159b3361Sopenharmony_ci uint16_t ui16_cbSize = read_16_bits_low_high(sf); 1516159b3361Sopenharmony_ci uint16_t ui16_wValidBitsPerSample = read_16_bits_low_high(sf); 1517159b3361Sopenharmony_ci uint32_t ui32_dwChannelMask = read_32_bits_low_high(sf); 1518159b3361Sopenharmony_ci uint16_t ui16_SubFormat = read_16_bits_low_high(sf); 1519159b3361Sopenharmony_ci ui32_cksize -= 10u; 1520159b3361Sopenharmony_ci ui16_wFormatTag = ui16_SubFormat; /* SubType coincident with format_tag for PCM int or float */ 1521159b3361Sopenharmony_ci (void) (ui16_cbSize, ui16_wValidBitsPerSample, ui32_dwChannelMask); /* unused */ 1522159b3361Sopenharmony_ci } 1523159b3361Sopenharmony_ci /* DEBUGF(" skipping %d bytes\n", ui32_cksize); */ 1524159b3361Sopenharmony_ci if (ui32_cksize > 0) { 1525159b3361Sopenharmony_ci if (fskip_uint32(sf, ui32_cksize) != 0) 1526159b3361Sopenharmony_ci return -1; 1527159b3361Sopenharmony_ci }; 1528159b3361Sopenharmony_ci } 1529159b3361Sopenharmony_ci else if (ui32_ckID == WAV_ID_DATA) { 1530159b3361Sopenharmony_ci ui32_DataChunkSize = read_32_bits_low_high(sf); 1531159b3361Sopenharmony_ci is_wav = 1; 1532159b3361Sopenharmony_ci /* We've found the audio data. Read no further! */ 1533159b3361Sopenharmony_ci break; 1534159b3361Sopenharmony_ci } 1535159b3361Sopenharmony_ci else { 1536159b3361Sopenharmony_ci uint32_t ui32_cksize = read_32_bits_low_high(sf); 1537159b3361Sopenharmony_ci ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize); 1538159b3361Sopenharmony_ci if (fskip_uint32(sf, ui32_cksize) != 0) { 1539159b3361Sopenharmony_ci return -1; 1540159b3361Sopenharmony_ci } 1541159b3361Sopenharmony_ci } 1542159b3361Sopenharmony_ci } 1543159b3361Sopenharmony_ci if (is_wav) { 1544159b3361Sopenharmony_ci if (ui16_wFormatTag == 0x0050 || ui16_wFormatTag == 0x0055) { 1545159b3361Sopenharmony_ci return sf_mp123; 1546159b3361Sopenharmony_ci } 1547159b3361Sopenharmony_ci if (ui16_wFormatTag != WAVE_FORMAT_PCM && ui16_wFormatTag != WAVE_FORMAT_IEEE_FLOAT) { 1548159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1549159b3361Sopenharmony_ci error_printf("Unsupported data format: 0x%04X\n", ui16_wFormatTag); 1550159b3361Sopenharmony_ci } 1551159b3361Sopenharmony_ci return 0; /* oh no! non-supported format */ 1552159b3361Sopenharmony_ci } 1553159b3361Sopenharmony_ci 1554159b3361Sopenharmony_ci /* make sure the header is sane */ 1555159b3361Sopenharmony_ci if (!set_input_num_channels(gfp, ui16_nChannels)) 1556159b3361Sopenharmony_ci return 0; 1557159b3361Sopenharmony_ci if (!set_input_samplerate(gfp, ui32_nSamplesPerSec)) 1558159b3361Sopenharmony_ci return 0; 1559159b3361Sopenharmony_ci /* avoid division by zero */ 1560159b3361Sopenharmony_ci if (ui16_wBitsPerSample < 1) { 1561159b3361Sopenharmony_ci if (global_ui_config.silent < 10) 1562159b3361Sopenharmony_ci error_printf("Unsupported bits per sample: %d\n", ui16_wBitsPerSample); 1563159b3361Sopenharmony_ci return -1; 1564159b3361Sopenharmony_ci } 1565159b3361Sopenharmony_ci global. pcmbitwidth = ui16_wBitsPerSample; 1566159b3361Sopenharmony_ci global. pcm_is_unsigned_8bit = 1; 1567159b3361Sopenharmony_ci global. pcm_is_ieee_float = (ui16_wFormatTag == WAVE_FORMAT_IEEE_FLOAT ? 1 : 0); 1568159b3361Sopenharmony_ci if (ui32_DataChunkSize == MAX_U_32_NUM) 1569159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, MAX_U_32_NUM); 1570159b3361Sopenharmony_ci else 1571159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, ui32_DataChunkSize / (ui16_nChannels * ((ui16_wBitsPerSample + 7u) / 8u))); 1572159b3361Sopenharmony_ci return 1; 1573159b3361Sopenharmony_ci } 1574159b3361Sopenharmony_ci return -1; 1575159b3361Sopenharmony_ci} 1576159b3361Sopenharmony_ci 1577159b3361Sopenharmony_ci 1578159b3361Sopenharmony_ci 1579159b3361Sopenharmony_ci/************************************************************************ 1580159b3361Sopenharmony_ci* aiff_check2 1581159b3361Sopenharmony_ci* 1582159b3361Sopenharmony_ci* PURPOSE: Checks AIFF header information to make sure it is valid. 1583159b3361Sopenharmony_ci* returns 0 on success, 1 on errors 1584159b3361Sopenharmony_ci************************************************************************/ 1585159b3361Sopenharmony_ci 1586159b3361Sopenharmony_cistatic int 1587159b3361Sopenharmony_ciaiff_check2(IFF_AIFF * const pcm_aiff_data) 1588159b3361Sopenharmony_ci{ 1589159b3361Sopenharmony_ci if (pcm_aiff_data->sampleType != IFF_ID_SSND) { 1590159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1591159b3361Sopenharmony_ci error_printf("ERROR: input sound data is not PCM\n"); 1592159b3361Sopenharmony_ci } 1593159b3361Sopenharmony_ci return 1; 1594159b3361Sopenharmony_ci } 1595159b3361Sopenharmony_ci switch (pcm_aiff_data->sampleSize) { 1596159b3361Sopenharmony_ci case 32: 1597159b3361Sopenharmony_ci case 24: 1598159b3361Sopenharmony_ci case 16: 1599159b3361Sopenharmony_ci case 8: 1600159b3361Sopenharmony_ci break; 1601159b3361Sopenharmony_ci default: 1602159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1603159b3361Sopenharmony_ci error_printf("ERROR: input sound data is not 8, 16, 24 or 32 bits\n"); 1604159b3361Sopenharmony_ci } 1605159b3361Sopenharmony_ci return 1; 1606159b3361Sopenharmony_ci } 1607159b3361Sopenharmony_ci if (pcm_aiff_data->numChannels != 1 && pcm_aiff_data->numChannels != 2) { 1608159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1609159b3361Sopenharmony_ci error_printf("ERROR: input sound data is not mono or stereo\n"); 1610159b3361Sopenharmony_ci } 1611159b3361Sopenharmony_ci return 1; 1612159b3361Sopenharmony_ci } 1613159b3361Sopenharmony_ci if (pcm_aiff_data->blkAlgn.blockSize != 0) { 1614159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1615159b3361Sopenharmony_ci error_printf("ERROR: block size of input sound data is not 0 bytes\n"); 1616159b3361Sopenharmony_ci } 1617159b3361Sopenharmony_ci return 1; 1618159b3361Sopenharmony_ci } 1619159b3361Sopenharmony_ci /* A bug, since we correctly skip the offset earlier in the code. 1620159b3361Sopenharmony_ci if (pcm_aiff_data->blkAlgn.offset != 0) { 1621159b3361Sopenharmony_ci error_printf("Block offset is not 0 bytes in '%s'\n", file_name); 1622159b3361Sopenharmony_ci return 1; 1623159b3361Sopenharmony_ci } */ 1624159b3361Sopenharmony_ci 1625159b3361Sopenharmony_ci return 0; 1626159b3361Sopenharmony_ci} 1627159b3361Sopenharmony_ci 1628159b3361Sopenharmony_ci 1629159b3361Sopenharmony_ci/***************************************************************************** 1630159b3361Sopenharmony_ci * 1631159b3361Sopenharmony_ci * Read Audio Interchange File Format (AIFF) headers. 1632159b3361Sopenharmony_ci * 1633159b3361Sopenharmony_ci * By the time we get here the first 32 bits of the file have already been 1634159b3361Sopenharmony_ci * read, and we're pretty sure that we're looking at an AIFF file. 1635159b3361Sopenharmony_ci * 1636159b3361Sopenharmony_ci *****************************************************************************/ 1637159b3361Sopenharmony_ci 1638159b3361Sopenharmony_cistatic int 1639159b3361Sopenharmony_ciparse_aiff_header(lame_global_flags * gfp, FILE * sf) 1640159b3361Sopenharmony_ci{ 1641159b3361Sopenharmony_ci uint32_t ui32_ChunkSize = 0; 1642159b3361Sopenharmony_ci uint32_t ui32_TypeID = 0; 1643159b3361Sopenharmony_ci IFF_AIFF aiff_info; 1644159b3361Sopenharmony_ci int seen_comm_chunk = 0, seen_ssnd_chunk = 0; 1645159b3361Sopenharmony_ci long pcm_data_pos = -1; 1646159b3361Sopenharmony_ci 1647159b3361Sopenharmony_ci memset(&aiff_info, 0, sizeof(aiff_info)); 1648159b3361Sopenharmony_ci aiff_info.sampleFormat = IFF_ID_NONE; 1649159b3361Sopenharmony_ci ui32_ChunkSize = read_32_bits_high_low(sf); 1650159b3361Sopenharmony_ci 1651159b3361Sopenharmony_ci ui32_TypeID = read_32_bits_high_low(sf); 1652159b3361Sopenharmony_ci ui32_ChunkSize -= 4; 1653159b3361Sopenharmony_ci if ((ui32_TypeID != IFF_ID_AIFF) && (ui32_TypeID != IFF_ID_AIFC)) 1654159b3361Sopenharmony_ci return -1; 1655159b3361Sopenharmony_ci 1656159b3361Sopenharmony_ci while (ui32_ChunkSize >= 8) { 1657159b3361Sopenharmony_ci uint32_t ui32_type = read_32_bits_high_low(sf); 1658159b3361Sopenharmony_ci ui32_ChunkSize -= 4; 1659159b3361Sopenharmony_ci 1660159b3361Sopenharmony_ci /* DEBUGF( 1661159b3361Sopenharmony_ci "found chunk type %08x '%4.4s'\n", ui32_type, (char*)&ui32_type); */ 1662159b3361Sopenharmony_ci 1663159b3361Sopenharmony_ci /* don't use a switch here to make it easier to use 'break' for SSND */ 1664159b3361Sopenharmony_ci if (ui32_type == IFF_ID_COMM) { 1665159b3361Sopenharmony_ci uint32_t ui32_cksize = read_32_bits_high_low(sf); 1666159b3361Sopenharmony_ci ui32_ChunkSize -= 4; 1667159b3361Sopenharmony_ci ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize); 1668159b3361Sopenharmony_ci if (ui32_cksize < 18 || ui32_ChunkSize < ui32_cksize) 1669159b3361Sopenharmony_ci return -1; 1670159b3361Sopenharmony_ci ui32_ChunkSize -= ui32_cksize; 1671159b3361Sopenharmony_ci seen_comm_chunk = seen_ssnd_chunk + 1; 1672159b3361Sopenharmony_ci 1673159b3361Sopenharmony_ci aiff_info.numChannels = read_16_bits_high_low(sf); 1674159b3361Sopenharmony_ci aiff_info.numSampleFrames = read_32_bits_high_low(sf); 1675159b3361Sopenharmony_ci aiff_info.sampleSize = read_16_bits_high_low(sf); 1676159b3361Sopenharmony_ci aiff_info.sampleRate = read_ieee_extended_high_low(sf); 1677159b3361Sopenharmony_ci ui32_cksize -= 18; 1678159b3361Sopenharmony_ci if (ui32_TypeID == IFF_ID_AIFC) { 1679159b3361Sopenharmony_ci if (ui32_cksize < 4) 1680159b3361Sopenharmony_ci return -1; 1681159b3361Sopenharmony_ci aiff_info.sampleFormat = read_32_bits_high_low(sf); 1682159b3361Sopenharmony_ci ui32_cksize -= 4; 1683159b3361Sopenharmony_ci } 1684159b3361Sopenharmony_ci if (fskip_uint32(sf, ui32_cksize) != 0) 1685159b3361Sopenharmony_ci return -1; 1686159b3361Sopenharmony_ci } 1687159b3361Sopenharmony_ci else if (ui32_type == IFF_ID_SSND) { 1688159b3361Sopenharmony_ci uint32_t ui32_cksize = read_32_bits_high_low(sf); 1689159b3361Sopenharmony_ci ui32_ChunkSize -= 4; 1690159b3361Sopenharmony_ci ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize); 1691159b3361Sopenharmony_ci if (ui32_cksize < 8 || ui32_ChunkSize < ui32_cksize) 1692159b3361Sopenharmony_ci return -1; 1693159b3361Sopenharmony_ci ui32_ChunkSize -= ui32_cksize; 1694159b3361Sopenharmony_ci seen_ssnd_chunk = 1; 1695159b3361Sopenharmony_ci 1696159b3361Sopenharmony_ci aiff_info.sampleType = IFF_ID_SSND; 1697159b3361Sopenharmony_ci aiff_info.blkAlgn.offset = read_32_bits_high_low(sf); 1698159b3361Sopenharmony_ci aiff_info.blkAlgn.blockSize = read_32_bits_high_low(sf); 1699159b3361Sopenharmony_ci ui32_cksize -= 8; 1700159b3361Sopenharmony_ci if (seen_comm_chunk > 0) { 1701159b3361Sopenharmony_ci if (fskip_uint32(sf, aiff_info.blkAlgn.offset) != 0) 1702159b3361Sopenharmony_ci return -1; 1703159b3361Sopenharmony_ci /* We've found the audio data. Read no further! */ 1704159b3361Sopenharmony_ci break; 1705159b3361Sopenharmony_ci } 1706159b3361Sopenharmony_ci pcm_data_pos = ftell(sf); 1707159b3361Sopenharmony_ci if (pcm_data_pos >= 0) { 1708159b3361Sopenharmony_ci pcm_data_pos += aiff_info.blkAlgn.offset; 1709159b3361Sopenharmony_ci } 1710159b3361Sopenharmony_ci if (fskip_uint32(sf, ui32_cksize) != 0) 1711159b3361Sopenharmony_ci return -1; 1712159b3361Sopenharmony_ci } 1713159b3361Sopenharmony_ci else { 1714159b3361Sopenharmony_ci uint32_t ui32_cksize; 1715159b3361Sopenharmony_ci ui32_cksize = read_32_bits_high_low(sf); 1716159b3361Sopenharmony_ci ui32_ChunkSize -= 4; 1717159b3361Sopenharmony_ci ui32_cksize = make_even_number_of_bytes_in_length(ui32_cksize); 1718159b3361Sopenharmony_ci if (ui32_ChunkSize < ui32_cksize) 1719159b3361Sopenharmony_ci return -1; 1720159b3361Sopenharmony_ci ui32_ChunkSize -= ui32_cksize; 1721159b3361Sopenharmony_ci if (fskip_uint32(sf, ui32_cksize) != 0) 1722159b3361Sopenharmony_ci return -1; 1723159b3361Sopenharmony_ci } 1724159b3361Sopenharmony_ci } 1725159b3361Sopenharmony_ci if (aiff_info.sampleFormat == IFF_ID_2CLE) { 1726159b3361Sopenharmony_ci global. pcm_is_ieee_float = 0; 1727159b3361Sopenharmony_ci global. pcmswapbytes = global_reader.swapbytes; 1728159b3361Sopenharmony_ci } 1729159b3361Sopenharmony_ci else if (aiff_info.sampleFormat == IFF_ID_2CBE) { 1730159b3361Sopenharmony_ci global. pcm_is_ieee_float = 0; 1731159b3361Sopenharmony_ci global. pcmswapbytes = !global_reader.swapbytes; 1732159b3361Sopenharmony_ci } 1733159b3361Sopenharmony_ci else if (aiff_info.sampleFormat == IFF_ID_NONE) { 1734159b3361Sopenharmony_ci global. pcm_is_ieee_float = 0; 1735159b3361Sopenharmony_ci global. pcmswapbytes = !global_reader.swapbytes; 1736159b3361Sopenharmony_ci } 1737159b3361Sopenharmony_ci else if (aiff_info.sampleFormat == IFF_ID_FL32) { 1738159b3361Sopenharmony_ci global. pcm_is_ieee_float = 1; 1739159b3361Sopenharmony_ci global. pcmswapbytes = !global_reader.swapbytes; 1740159b3361Sopenharmony_ci } 1741159b3361Sopenharmony_ci /* 64 bit floating point reading is still missing 1742159b3361Sopenharmony_ci else if (aiff_info.sampleFormat == IFF_ID_FL64) { 1743159b3361Sopenharmony_ci global. pcm_is_ieee_float = 1; 1744159b3361Sopenharmony_ci global. pcmswapbytes = !global_reader.swapbytes; 1745159b3361Sopenharmony_ci } 1746159b3361Sopenharmony_ci */ 1747159b3361Sopenharmony_ci else { 1748159b3361Sopenharmony_ci return -1; 1749159b3361Sopenharmony_ci } 1750159b3361Sopenharmony_ci 1751159b3361Sopenharmony_ci /* DEBUGF("Parsed AIFF %d\n", is_aiff); */ 1752159b3361Sopenharmony_ci if (seen_comm_chunk && (seen_ssnd_chunk > 0 || aiff_info.numSampleFrames == 0)) { 1753159b3361Sopenharmony_ci /* make sure the header is sane */ 1754159b3361Sopenharmony_ci if (0 != aiff_check2(&aiff_info)) 1755159b3361Sopenharmony_ci return 0; 1756159b3361Sopenharmony_ci if (!set_input_num_channels(gfp, aiff_info.numChannels)) 1757159b3361Sopenharmony_ci return 0; 1758159b3361Sopenharmony_ci if (!set_input_samplerate(gfp, (int) aiff_info.sampleRate)) 1759159b3361Sopenharmony_ci return 0; 1760159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, aiff_info.numSampleFrames); 1761159b3361Sopenharmony_ci global. pcmbitwidth = aiff_info.sampleSize; 1762159b3361Sopenharmony_ci global. pcm_is_unsigned_8bit = 0; 1763159b3361Sopenharmony_ci if (pcm_data_pos >= 0) { 1764159b3361Sopenharmony_ci if (fseek(sf, pcm_data_pos, SEEK_SET) != 0) { 1765159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1766159b3361Sopenharmony_ci error_printf("Can't rewind stream to audio data position\n"); 1767159b3361Sopenharmony_ci } 1768159b3361Sopenharmony_ci return 0; 1769159b3361Sopenharmony_ci } 1770159b3361Sopenharmony_ci } 1771159b3361Sopenharmony_ci 1772159b3361Sopenharmony_ci return 1; 1773159b3361Sopenharmony_ci } 1774159b3361Sopenharmony_ci return -1; 1775159b3361Sopenharmony_ci} 1776159b3361Sopenharmony_ci 1777159b3361Sopenharmony_ci 1778159b3361Sopenharmony_ci 1779159b3361Sopenharmony_ci/************************************************************************ 1780159b3361Sopenharmony_ci* 1781159b3361Sopenharmony_ci* parse_file_header 1782159b3361Sopenharmony_ci* 1783159b3361Sopenharmony_ci* PURPOSE: Read the header from a bytestream. Try to determine whether 1784159b3361Sopenharmony_ci* it's a WAV file or AIFF without rewinding, since rewind 1785159b3361Sopenharmony_ci* doesn't work on pipes and there's a good chance we're reading 1786159b3361Sopenharmony_ci* from stdin (otherwise we'd probably be using libsndfile). 1787159b3361Sopenharmony_ci* 1788159b3361Sopenharmony_ci* When this function returns, the file offset will be positioned at the 1789159b3361Sopenharmony_ci* beginning of the sound data. 1790159b3361Sopenharmony_ci* 1791159b3361Sopenharmony_ci************************************************************************/ 1792159b3361Sopenharmony_ci 1793159b3361Sopenharmony_cistatic int 1794159b3361Sopenharmony_ciparse_file_header(lame_global_flags * gfp, FILE * sf) 1795159b3361Sopenharmony_ci{ 1796159b3361Sopenharmony_ci uint32_t ui32_type = read_32_bits_high_low(sf); 1797159b3361Sopenharmony_ci /* 1798159b3361Sopenharmony_ci DEBUGF( 1799159b3361Sopenharmony_ci "First word of input stream: %08x '%4.4s'\n", ui32_type, (char*) &type); 1800159b3361Sopenharmony_ci */ 1801159b3361Sopenharmony_ci global. count_samples_carefully = 0; 1802159b3361Sopenharmony_ci global. pcm_is_unsigned_8bit = global_raw_pcm.in_signed == 1 ? 0 : 1; 1803159b3361Sopenharmony_ci /*global_reader.input_format = sf_raw; commented out, because it is better to fail 1804159b3361Sopenharmony_ci here as to encode some hundreds of input files not supported by LAME 1805159b3361Sopenharmony_ci If you know you have RAW PCM data, use the -r switch 1806159b3361Sopenharmony_ci */ 1807159b3361Sopenharmony_ci 1808159b3361Sopenharmony_ci if (ui32_type == WAV_ID_RIFF) { 1809159b3361Sopenharmony_ci /* It's probably a WAV file */ 1810159b3361Sopenharmony_ci int const ret = parse_wave_header(gfp, sf); 1811159b3361Sopenharmony_ci if (ret == sf_mp123) { 1812159b3361Sopenharmony_ci global. count_samples_carefully = 1; 1813159b3361Sopenharmony_ci return sf_mp123; 1814159b3361Sopenharmony_ci } 1815159b3361Sopenharmony_ci if (ret > 0) { 1816159b3361Sopenharmony_ci if (lame_get_num_samples(gfp) == MAX_U_32_NUM || global_reader.ignorewavlength == 1) 1817159b3361Sopenharmony_ci { 1818159b3361Sopenharmony_ci global. count_samples_carefully = 0; 1819159b3361Sopenharmony_ci lame_set_num_samples(gfp, MAX_U_32_NUM); 1820159b3361Sopenharmony_ci } 1821159b3361Sopenharmony_ci else 1822159b3361Sopenharmony_ci global. count_samples_carefully = 1; 1823159b3361Sopenharmony_ci return sf_wave; 1824159b3361Sopenharmony_ci } 1825159b3361Sopenharmony_ci if (ret < 0) { 1826159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1827159b3361Sopenharmony_ci error_printf("Warning: corrupt or unsupported WAVE format\n"); 1828159b3361Sopenharmony_ci } 1829159b3361Sopenharmony_ci } 1830159b3361Sopenharmony_ci } 1831159b3361Sopenharmony_ci else if (ui32_type == IFF_ID_FORM) { 1832159b3361Sopenharmony_ci /* It's probably an AIFF file */ 1833159b3361Sopenharmony_ci int const ret = parse_aiff_header(gfp, sf); 1834159b3361Sopenharmony_ci if (ret > 0) { 1835159b3361Sopenharmony_ci global. count_samples_carefully = 1; 1836159b3361Sopenharmony_ci return sf_aiff; 1837159b3361Sopenharmony_ci } 1838159b3361Sopenharmony_ci if (ret < 0) { 1839159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1840159b3361Sopenharmony_ci error_printf("Warning: corrupt or unsupported AIFF format\n"); 1841159b3361Sopenharmony_ci } 1842159b3361Sopenharmony_ci } 1843159b3361Sopenharmony_ci } 1844159b3361Sopenharmony_ci else { 1845159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1846159b3361Sopenharmony_ci error_printf("Warning: unsupported audio format\n"); 1847159b3361Sopenharmony_ci } 1848159b3361Sopenharmony_ci } 1849159b3361Sopenharmony_ci return sf_unknown; 1850159b3361Sopenharmony_ci} 1851159b3361Sopenharmony_ci 1852159b3361Sopenharmony_ci 1853159b3361Sopenharmony_cistatic int 1854159b3361Sopenharmony_ciopen_mpeg_file_part2(lame_t gfp, FILE* musicin, char const *inPath, int *enc_delay, int *enc_padding) 1855159b3361Sopenharmony_ci{ 1856159b3361Sopenharmony_ci#ifdef HAVE_MPG123 1857159b3361Sopenharmony_ci if (-1 == lame123_decode_initfile(musicin, &global_decoder.mp3input_data, enc_delay, enc_padding)) { 1858159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1859159b3361Sopenharmony_ci error_printf("Error opening MPEG input file %s.\n", inPath); 1860159b3361Sopenharmony_ci } 1861159b3361Sopenharmony_ci return 0; 1862159b3361Sopenharmony_ci } 1863159b3361Sopenharmony_ci#else 1864159b3361Sopenharmony_ci#ifdef HAVE_MPGLIB 1865159b3361Sopenharmony_ci if (-1 == lame_decode_initfile(musicin, &global_decoder.mp3input_data, enc_delay, enc_padding)) { 1866159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1867159b3361Sopenharmony_ci error_printf("Error reading headers in mp3 input file %s.\n", inPath); 1868159b3361Sopenharmony_ci } 1869159b3361Sopenharmony_ci return 0; 1870159b3361Sopenharmony_ci } 1871159b3361Sopenharmony_ci#endif 1872159b3361Sopenharmony_ci#endif 1873159b3361Sopenharmony_ci if (!set_input_num_channels(gfp, global_decoder.mp3input_data.stereo)) { 1874159b3361Sopenharmony_ci return 0; 1875159b3361Sopenharmony_ci } 1876159b3361Sopenharmony_ci if (!set_input_samplerate(gfp, global_decoder.mp3input_data.samplerate)) { 1877159b3361Sopenharmony_ci return 0; 1878159b3361Sopenharmony_ci } 1879159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, global_decoder.mp3input_data.nsamp); 1880159b3361Sopenharmony_ci return 1; 1881159b3361Sopenharmony_ci} 1882159b3361Sopenharmony_ci 1883159b3361Sopenharmony_ci 1884159b3361Sopenharmony_cistatic FILE * 1885159b3361Sopenharmony_ciopen_wave_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding) 1886159b3361Sopenharmony_ci{ 1887159b3361Sopenharmony_ci FILE *musicin; 1888159b3361Sopenharmony_ci 1889159b3361Sopenharmony_ci /* set the defaults from info incase we cannot determine them from file */ 1890159b3361Sopenharmony_ci lame_set_num_samples(gfp, MAX_U_32_NUM); 1891159b3361Sopenharmony_ci 1892159b3361Sopenharmony_ci if (!strcmp(inPath, "-")) { 1893159b3361Sopenharmony_ci lame_set_stream_binary_mode(musicin = stdin); /* Read from standard input. */ 1894159b3361Sopenharmony_ci } 1895159b3361Sopenharmony_ci else { 1896159b3361Sopenharmony_ci if ((musicin = lame_fopen(inPath, "rb")) == NULL) { 1897159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1898159b3361Sopenharmony_ci error_printf("Could not find \"%s\".\n", inPath); 1899159b3361Sopenharmony_ci } 1900159b3361Sopenharmony_ci return 0; 1901159b3361Sopenharmony_ci } 1902159b3361Sopenharmony_ci } 1903159b3361Sopenharmony_ci 1904159b3361Sopenharmony_ci if (global_reader.input_format == sf_ogg) { 1905159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1906159b3361Sopenharmony_ci error_printf("sorry, vorbis support in LAME is deprecated.\n"); 1907159b3361Sopenharmony_ci } 1908159b3361Sopenharmony_ci close_input_file(musicin); 1909159b3361Sopenharmony_ci return 0; 1910159b3361Sopenharmony_ci } 1911159b3361Sopenharmony_ci else if (global_reader.input_format == sf_raw) { 1912159b3361Sopenharmony_ci /* assume raw PCM */ 1913159b3361Sopenharmony_ci if (global_ui_config.silent < 9) { 1914159b3361Sopenharmony_ci console_printf("Assuming raw pcm input file"); 1915159b3361Sopenharmony_ci if (global_reader.swapbytes) 1916159b3361Sopenharmony_ci console_printf(" : Forcing byte-swapping\n"); 1917159b3361Sopenharmony_ci else 1918159b3361Sopenharmony_ci console_printf("\n"); 1919159b3361Sopenharmony_ci } 1920159b3361Sopenharmony_ci global. pcmswapbytes = global_reader.swapbytes; 1921159b3361Sopenharmony_ci } 1922159b3361Sopenharmony_ci else { 1923159b3361Sopenharmony_ci global_reader.input_format = parse_file_header(gfp, musicin); 1924159b3361Sopenharmony_ci } 1925159b3361Sopenharmony_ci if (global_reader.input_format == sf_mp123) { 1926159b3361Sopenharmony_ci if (open_mpeg_file_part2(gfp, musicin, inPath, enc_delay, enc_padding)) 1927159b3361Sopenharmony_ci return musicin; 1928159b3361Sopenharmony_ci close_input_file(musicin); 1929159b3361Sopenharmony_ci return 0; 1930159b3361Sopenharmony_ci } 1931159b3361Sopenharmony_ci if (global_reader.input_format == sf_unknown) { 1932159b3361Sopenharmony_ci close_input_file(musicin); 1933159b3361Sopenharmony_ci return 0; 1934159b3361Sopenharmony_ci } 1935159b3361Sopenharmony_ci 1936159b3361Sopenharmony_ci if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) { 1937159b3361Sopenharmony_ci int const tmp_num_channels = lame_get_num_channels(gfp); 1938159b3361Sopenharmony_ci double const flen = lame_get_file_size(musicin); /* try to figure out num_samples */ 1939159b3361Sopenharmony_ci if (flen >= 0 && tmp_num_channels > 0 ) { 1940159b3361Sopenharmony_ci /* try file size, assume 2 bytes per sample */ 1941159b3361Sopenharmony_ci unsigned long fsize = (unsigned long) (flen / (2 * tmp_num_channels)); 1942159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, fsize); 1943159b3361Sopenharmony_ci global. count_samples_carefully = 0; 1944159b3361Sopenharmony_ci } 1945159b3361Sopenharmony_ci } 1946159b3361Sopenharmony_ci return musicin; 1947159b3361Sopenharmony_ci} 1948159b3361Sopenharmony_ci 1949159b3361Sopenharmony_ci 1950159b3361Sopenharmony_ci 1951159b3361Sopenharmony_cistatic FILE * 1952159b3361Sopenharmony_ciopen_mpeg_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding) 1953159b3361Sopenharmony_ci{ 1954159b3361Sopenharmony_ci FILE *musicin; 1955159b3361Sopenharmony_ci 1956159b3361Sopenharmony_ci /* set the defaults from info incase we cannot determine them from file */ 1957159b3361Sopenharmony_ci lame_set_num_samples(gfp, MAX_U_32_NUM); 1958159b3361Sopenharmony_ci 1959159b3361Sopenharmony_ci if (strcmp(inPath, "-") == 0) { 1960159b3361Sopenharmony_ci musicin = stdin; 1961159b3361Sopenharmony_ci lame_set_stream_binary_mode(musicin); /* Read from standard input. */ 1962159b3361Sopenharmony_ci } 1963159b3361Sopenharmony_ci else { 1964159b3361Sopenharmony_ci musicin = lame_fopen(inPath, "rb"); 1965159b3361Sopenharmony_ci if (musicin == NULL) { 1966159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1967159b3361Sopenharmony_ci error_printf("Could not find \"%s\".\n", inPath); 1968159b3361Sopenharmony_ci } 1969159b3361Sopenharmony_ci return 0; 1970159b3361Sopenharmony_ci } 1971159b3361Sopenharmony_ci } 1972159b3361Sopenharmony_ci#ifdef AMIGA_MPEGA 1973159b3361Sopenharmony_ci if (-1 == lame_decode_initfile_amiga(inPath, &global_decoder.mp3input_data)) { 1974159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 1975159b3361Sopenharmony_ci error_printf("Error reading headers in mp3 input file %s.\n", inPath); 1976159b3361Sopenharmony_ci } 1977159b3361Sopenharmony_ci close_input_file(musicin); 1978159b3361Sopenharmony_ci return 0; 1979159b3361Sopenharmony_ci } 1980159b3361Sopenharmony_ci#endif 1981159b3361Sopenharmony_ci if ( 0 == open_mpeg_file_part2(gfp, musicin, inPath, enc_delay, enc_padding) ) { 1982159b3361Sopenharmony_ci close_input_file(musicin); 1983159b3361Sopenharmony_ci return 0; 1984159b3361Sopenharmony_ci } 1985159b3361Sopenharmony_ci if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) { 1986159b3361Sopenharmony_ci double flen = lame_get_file_size(musicin); /* try to figure out num_samples */ 1987159b3361Sopenharmony_ci if (flen >= 0) { 1988159b3361Sopenharmony_ci /* try file size, assume 2 bytes per sample */ 1989159b3361Sopenharmony_ci if (global_decoder.mp3input_data.bitrate > 0) { 1990159b3361Sopenharmony_ci double totalseconds = 1991159b3361Sopenharmony_ci (flen * 8.0 / (1000.0 * global_decoder.mp3input_data.bitrate)); 1992159b3361Sopenharmony_ci unsigned long tmp_num_samples = 1993159b3361Sopenharmony_ci (unsigned long) (totalseconds * lame_get_in_samplerate(gfp)); 1994159b3361Sopenharmony_ci 1995159b3361Sopenharmony_ci (void) lame_set_num_samples(gfp, tmp_num_samples); 1996159b3361Sopenharmony_ci global_decoder.mp3input_data.nsamp = tmp_num_samples; 1997159b3361Sopenharmony_ci global. count_samples_carefully = 0; 1998159b3361Sopenharmony_ci } 1999159b3361Sopenharmony_ci } 2000159b3361Sopenharmony_ci } 2001159b3361Sopenharmony_ci return musicin; 2002159b3361Sopenharmony_ci} 2003159b3361Sopenharmony_ci 2004159b3361Sopenharmony_ci 2005159b3361Sopenharmony_cistatic int 2006159b3361Sopenharmony_ciclose_input_file(FILE * musicin) 2007159b3361Sopenharmony_ci{ 2008159b3361Sopenharmony_ci int ret = 0; 2009159b3361Sopenharmony_ci 2010159b3361Sopenharmony_ci if (musicin != stdin && musicin != 0) { 2011159b3361Sopenharmony_ci ret = fclose(musicin); 2012159b3361Sopenharmony_ci } 2013159b3361Sopenharmony_ci if (ret != 0) { 2014159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 2015159b3361Sopenharmony_ci error_printf("Could not close audio input file\n"); 2016159b3361Sopenharmony_ci } 2017159b3361Sopenharmony_ci } 2018159b3361Sopenharmony_ci return ret; 2019159b3361Sopenharmony_ci} 2020159b3361Sopenharmony_ci 2021159b3361Sopenharmony_ci 2022159b3361Sopenharmony_ci 2023159b3361Sopenharmony_ci#if defined(HAVE_MPGLIB) 2024159b3361Sopenharmony_cistatic int 2025159b3361Sopenharmony_cicheck_aid(const unsigned char *header) 2026159b3361Sopenharmony_ci{ 2027159b3361Sopenharmony_ci return 0 == memcmp(header, "AiD\1", 4); 2028159b3361Sopenharmony_ci} 2029159b3361Sopenharmony_ci 2030159b3361Sopenharmony_ci/* 2031159b3361Sopenharmony_ci * Please check this and don't kill me if there's a bug 2032159b3361Sopenharmony_ci * This is a (nearly?) complete header analysis for a MPEG-1/2/2.5 Layer I, II or III 2033159b3361Sopenharmony_ci * data stream 2034159b3361Sopenharmony_ci */ 2035159b3361Sopenharmony_ci 2036159b3361Sopenharmony_cistatic int 2037159b3361Sopenharmony_ciis_syncword_mp123(const void *const headerptr) 2038159b3361Sopenharmony_ci{ 2039159b3361Sopenharmony_ci const unsigned char *const p = headerptr; 2040159b3361Sopenharmony_ci static const char abl2[16] = { 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8 }; 2041159b3361Sopenharmony_ci 2042159b3361Sopenharmony_ci if ((p[0] & 0xFF) != 0xFF) 2043159b3361Sopenharmony_ci return 0; /* first 8 bits must be '1' */ 2044159b3361Sopenharmony_ci if ((p[1] & 0xE0) != 0xE0) 2045159b3361Sopenharmony_ci return 0; /* next 3 bits are also */ 2046159b3361Sopenharmony_ci if ((p[1] & 0x18) == 0x08) 2047159b3361Sopenharmony_ci return 0; /* no MPEG-1, -2 or -2.5 */ 2048159b3361Sopenharmony_ci switch (p[1] & 0x06) { 2049159b3361Sopenharmony_ci default: 2050159b3361Sopenharmony_ci case 0x00: /* illegal Layer */ 2051159b3361Sopenharmony_ci return 0; 2052159b3361Sopenharmony_ci 2053159b3361Sopenharmony_ci case 0x02: /* Layer3 */ 2054159b3361Sopenharmony_ci if (global_reader.input_format != sf_mp3 && global_reader.input_format != sf_mp123) { 2055159b3361Sopenharmony_ci return 0; 2056159b3361Sopenharmony_ci } 2057159b3361Sopenharmony_ci global_reader.input_format = sf_mp3; 2058159b3361Sopenharmony_ci break; 2059159b3361Sopenharmony_ci 2060159b3361Sopenharmony_ci case 0x04: /* Layer2 */ 2061159b3361Sopenharmony_ci if (global_reader.input_format != sf_mp2 && global_reader.input_format != sf_mp123) { 2062159b3361Sopenharmony_ci return 0; 2063159b3361Sopenharmony_ci } 2064159b3361Sopenharmony_ci global_reader.input_format = sf_mp2; 2065159b3361Sopenharmony_ci break; 2066159b3361Sopenharmony_ci 2067159b3361Sopenharmony_ci case 0x06: /* Layer1 */ 2068159b3361Sopenharmony_ci if (global_reader.input_format != sf_mp1 && global_reader.input_format != sf_mp123) { 2069159b3361Sopenharmony_ci return 0; 2070159b3361Sopenharmony_ci } 2071159b3361Sopenharmony_ci global_reader.input_format = sf_mp1; 2072159b3361Sopenharmony_ci break; 2073159b3361Sopenharmony_ci } 2074159b3361Sopenharmony_ci if ((p[1] & 0x06) == 0x00) 2075159b3361Sopenharmony_ci return 0; /* no Layer I, II and III */ 2076159b3361Sopenharmony_ci if ((p[2] & 0xF0) == 0xF0) 2077159b3361Sopenharmony_ci return 0; /* bad bitrate */ 2078159b3361Sopenharmony_ci if ((p[2] & 0x0C) == 0x0C) 2079159b3361Sopenharmony_ci return 0; /* no sample frequency with (32,44.1,48)/(1,2,4) */ 2080159b3361Sopenharmony_ci if ((p[1] & 0x18) == 0x18 && (p[1] & 0x06) == 0x04 && abl2[p[2] >> 4] & (1 << (p[3] >> 6))) 2081159b3361Sopenharmony_ci return 0; 2082159b3361Sopenharmony_ci if ((p[3] & 3) == 2) 2083159b3361Sopenharmony_ci return 0; /* reserved enphasis mode */ 2084159b3361Sopenharmony_ci return 1; 2085159b3361Sopenharmony_ci} 2086159b3361Sopenharmony_ci 2087159b3361Sopenharmony_cistatic size_t 2088159b3361Sopenharmony_cilenOfId3v2Tag(unsigned char const* buf) 2089159b3361Sopenharmony_ci{ 2090159b3361Sopenharmony_ci unsigned int b0 = buf[0] & 127; 2091159b3361Sopenharmony_ci unsigned int b1 = buf[1] & 127; 2092159b3361Sopenharmony_ci unsigned int b2 = buf[2] & 127; 2093159b3361Sopenharmony_ci unsigned int b3 = buf[3] & 127; 2094159b3361Sopenharmony_ci return (((((b0 << 7) + b1) << 7) + b2) << 7) + b3; 2095159b3361Sopenharmony_ci} 2096159b3361Sopenharmony_ci#endif 2097159b3361Sopenharmony_ci 2098159b3361Sopenharmony_ci#ifdef HAVE_MPG123 2099159b3361Sopenharmony_ci#define CHECK123(code) if(MPG123_OK != (code)) return -1 2100159b3361Sopenharmony_ci 2101159b3361Sopenharmony_ci#ifdef _WIN32 2102159b3361Sopenharmony_cistatic ssize_t lame123_read_from_file(void* handle, void* buffer, size_t size) 2103159b3361Sopenharmony_ci{ 2104159b3361Sopenharmony_ci return fread(buffer, 1, size, (FILE*)handle); 2105159b3361Sopenharmony_ci} 2106159b3361Sopenharmony_ci 2107159b3361Sopenharmony_cistatic off_t lame123_seek_in_file(void* handle, off_t offset, int direction) 2108159b3361Sopenharmony_ci{ 2109159b3361Sopenharmony_ci if (fseek((FILE*)handle, offset, direction) != 0) 2110159b3361Sopenharmony_ci return (off_t)-1; 2111159b3361Sopenharmony_ci return ftell((FILE*)handle); 2112159b3361Sopenharmony_ci} 2113159b3361Sopenharmony_ci 2114159b3361Sopenharmony_cistatic void lame123_cleanup_file(void* handle) 2115159b3361Sopenharmony_ci{ 2116159b3361Sopenharmony_ci /* don't call fclose(); close_input_file() will do that */ 2117159b3361Sopenharmony_ci} 2118159b3361Sopenharmony_ci#endif 2119159b3361Sopenharmony_ci 2120159b3361Sopenharmony_ciint lame123_decode_initfile(FILE *fd, mp3data_struct *mp3data, int *enc_delay, int *enc_padding) 2121159b3361Sopenharmony_ci{ 2122159b3361Sopenharmony_ci off_t len; 2123159b3361Sopenharmony_ci unsigned char *id3buf; 2124159b3361Sopenharmony_ci size_t id3size; 2125159b3361Sopenharmony_ci struct mpg123_frameinfo fi; 2126159b3361Sopenharmony_ci long rate, val; 2127159b3361Sopenharmony_ci int channels; 2128159b3361Sopenharmony_ci 2129159b3361Sopenharmony_ci mpg123_init(); 2130159b3361Sopenharmony_ci memset(mp3data, 0, sizeof(mp3data_struct)); 2131159b3361Sopenharmony_ci if (global.hip) { 2132159b3361Sopenharmony_ci hip_decode_exit(global.hip); 2133159b3361Sopenharmony_ci } 2134159b3361Sopenharmony_ci global. hip = hip_decode_init(); 2135159b3361Sopenharmony_ci if(!global.hip->mh) 2136159b3361Sopenharmony_ci return -1; 2137159b3361Sopenharmony_ci /* TODO: enforce float format ... optionally be careful for builds 2138159b3361Sopenharmony_ci that only know 16 bit output. */ 2139159b3361Sopenharmony_ci mpg123_param(global.hip->mh, MPG123_ADD_FLAGS, MPG123_STORE_RAW_ID3, 0.); 2140159b3361Sopenharmony_ci mpg123_param(global.hip->mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0.); 2141159b3361Sopenharmony_ci mpg123_format_none(global.hip->mh); 2142159b3361Sopenharmony_ci /* TODO: switch to MPG123_ENC_FLOAT_32, always! */ 2143159b3361Sopenharmony_ci CHECK123(mpg123_format2(global.hip->mh, 2144159b3361Sopenharmony_ci 0, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16)); 2145159b3361Sopenharmony_ci /* TODO: verboseness / silence set up */ 2146159b3361Sopenharmony_ci#ifdef _WIN32 2147159b3361Sopenharmony_ci /* On Win32 compiles it can happen that lame.exe and libmp3lame.dll use 2148159b3361Sopenharmony_ci different C++ runtimes, which maintail different FILE* lists, and 2149159b3361Sopenharmony_ci fileno() would produce invalid file numbers for those msvcrt instances. 2150159b3361Sopenharmony_ci So use mpg123_replace_reader_handle() / mpg123_open_handle() here 2151159b3361Sopenharmony_ci instead of mpg123_open_fd(). */ 2152159b3361Sopenharmony_ci CHECK123(mpg123_replace_reader_handle(global.hip->mh, lame123_read_from_file, lame123_seek_in_file, lame123_cleanup_file)); 2153159b3361Sopenharmony_ci CHECK123(mpg123_open_handle(global.hip->mh, fd)); 2154159b3361Sopenharmony_ci#else 2155159b3361Sopenharmony_ci CHECK123(mpg123_open_fd(global.hip->mh, fileno(fd))); 2156159b3361Sopenharmony_ci#endif 2157159b3361Sopenharmony_ci /* Seek to get past Info frame and ID3v2. */ 2158159b3361Sopenharmony_ci CHECK123(mpg123_seek(global.hip->mh, SEEK_SET, 0)); 2159159b3361Sopenharmony_ci /* TODO: Figure out if MPG123_GAPLESS is desired or not. */ 2160159b3361Sopenharmony_ci /* Guessing seems to be OK, so we do not have to insist on knowing 2161159b3361Sopenharmony_ci if libmpg123 got that info from Info tag or not. */ 2162159b3361Sopenharmony_ci /* I am paranoid about off_t being larger than long or int. */ 2163159b3361Sopenharmony_ci len = mpg123_framelength(global.hip->mh); 2164159b3361Sopenharmony_ci if(len <= (unsigned long)-1) 2165159b3361Sopenharmony_ci mp3data->totalframes = len; 2166159b3361Sopenharmony_ci else 2167159b3361Sopenharmony_ci return -1; 2168159b3361Sopenharmony_ci len = mpg123_length(global.hip->mh); 2169159b3361Sopenharmony_ci if(len <= ((unsigned int)-1)/2) 2170159b3361Sopenharmony_ci mp3data->nsamp = len; 2171159b3361Sopenharmony_ci else 2172159b3361Sopenharmony_ci return -1; 2173159b3361Sopenharmony_ci /* Encoder delay and padding are not needed when libmpg123 handles gapless 2174159b3361Sopenharmony_ci decoding itself. So let's see if we get away with that. */ 2175159b3361Sopenharmony_ci mpg123_getstate(global.hip->mh, MPG123_ENC_DELAY, &val, NULL); 2176159b3361Sopenharmony_ci *enc_delay = val; 2177159b3361Sopenharmony_ci mpg123_getstate(global.hip->mh, MPG123_ENC_PADDING, &val, NULL); 2178159b3361Sopenharmony_ci *enc_padding = val; 2179159b3361Sopenharmony_ci if(global.in_id3v2_tag) 2180159b3361Sopenharmony_ci free(global.in_id3v2_tag); 2181159b3361Sopenharmony_ci global.in_id3v2_size = 0; 2182159b3361Sopenharmony_ci if( MPG123_OK == mpg123_id3_raw(global.hip->mh, NULL, NULL, 2183159b3361Sopenharmony_ci &id3buf, &id3size) && id3buf && id3size ) { 2184159b3361Sopenharmony_ci global.in_id3v2_tag = malloc(id3size); 2185159b3361Sopenharmony_ci if(global.in_id3v2_tag) { 2186159b3361Sopenharmony_ci memcpy(global.in_id3v2_tag, id3buf, id3size); 2187159b3361Sopenharmony_ci global.in_id3v2_size = id3size; 2188159b3361Sopenharmony_ci } 2189159b3361Sopenharmony_ci } 2190159b3361Sopenharmony_ci CHECK123(mpg123_info(global.hip->mh, &fi)); 2191159b3361Sopenharmony_ci CHECK123(mpg123_getformat(global.hip->mh, &rate, &channels, NULL)); 2192159b3361Sopenharmony_ci /* How much of this is actually needed for the frontend? */ 2193159b3361Sopenharmony_ci mp3data->header_parsed = 1; 2194159b3361Sopenharmony_ci mp3data->stereo = channels; /* Channel count correct? Or is dual mono different? */ 2195159b3361Sopenharmony_ci mp3data->samplerate = rate; 2196159b3361Sopenharmony_ci mp3data->mode = fi.mode; 2197159b3361Sopenharmony_ci mp3data->mode_ext = fi.mode_ext; 2198159b3361Sopenharmony_ci mp3data->framesize = mpg123_spf(global.hip->mh); 2199159b3361Sopenharmony_ci mp3data->bitrate = fi.bitrate; 2200159b3361Sopenharmony_ci if(global_reader.input_format == sf_mp123) switch(fi.layer) { 2201159b3361Sopenharmony_ci case 1: 2202159b3361Sopenharmony_ci global_reader.input_format = sf_mp1; 2203159b3361Sopenharmony_ci break; 2204159b3361Sopenharmony_ci case 2: 2205159b3361Sopenharmony_ci global_reader.input_format = sf_mp2; 2206159b3361Sopenharmony_ci break; 2207159b3361Sopenharmony_ci case 3: 2208159b3361Sopenharmony_ci global_reader.input_format = sf_mp3; 2209159b3361Sopenharmony_ci break; 2210159b3361Sopenharmony_ci } 2211159b3361Sopenharmony_ci 2212159b3361Sopenharmony_ci return 0; 2213159b3361Sopenharmony_ci} 2214159b3361Sopenharmony_ci#endif 2215159b3361Sopenharmony_ci 2216159b3361Sopenharmony_ci#ifdef HAVE_MPGLIB 2217159b3361Sopenharmony_ciint 2218159b3361Sopenharmony_cilame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding) 2219159b3361Sopenharmony_ci{ 2220159b3361Sopenharmony_ci /* VBRTAGDATA pTagData; */ 2221159b3361Sopenharmony_ci /* int xing_header,len2,num_frames; */ 2222159b3361Sopenharmony_ci unsigned char buf[100]; 2223159b3361Sopenharmony_ci int ret; 2224159b3361Sopenharmony_ci size_t len; 2225159b3361Sopenharmony_ci int aid_header; 2226159b3361Sopenharmony_ci short int pcm_l[1152], pcm_r[1152]; 2227159b3361Sopenharmony_ci int freeformat = 0; 2228159b3361Sopenharmony_ci 2229159b3361Sopenharmony_ci memset(mp3data, 0, sizeof(mp3data_struct)); 2230159b3361Sopenharmony_ci if (global.hip) { 2231159b3361Sopenharmony_ci hip_decode_exit(global.hip); 2232159b3361Sopenharmony_ci } 2233159b3361Sopenharmony_ci global. hip = hip_decode_init(); 2234159b3361Sopenharmony_ci hip_set_msgf(global.hip, global_ui_config.silent < 10 ? &frontend_msgf : 0); 2235159b3361Sopenharmony_ci hip_set_errorf(global.hip, global_ui_config.silent < 10 ? &frontend_errorf : 0); 2236159b3361Sopenharmony_ci hip_set_debugf(global.hip, &frontend_debugf); 2237159b3361Sopenharmony_ci 2238159b3361Sopenharmony_ci len = 4; 2239159b3361Sopenharmony_ci if (fread(buf, 1, len, fd) != len) 2240159b3361Sopenharmony_ci return -1; /* failed */ 2241159b3361Sopenharmony_ci while (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') { 2242159b3361Sopenharmony_ci len = 6; 2243159b3361Sopenharmony_ci if (fread(&buf[4], 1, len, fd) != len) 2244159b3361Sopenharmony_ci return -1; /* failed */ 2245159b3361Sopenharmony_ci len = lenOfId3v2Tag(&buf[6]); 2246159b3361Sopenharmony_ci if (global.in_id3v2_size < 1) { 2247159b3361Sopenharmony_ci global.in_id3v2_size = 10 + len; 2248159b3361Sopenharmony_ci global.in_id3v2_tag = malloc(global.in_id3v2_size); 2249159b3361Sopenharmony_ci if (global.in_id3v2_tag) { 2250159b3361Sopenharmony_ci memcpy(global.in_id3v2_tag, buf, 10); 2251159b3361Sopenharmony_ci if (fread(&global.in_id3v2_tag[10], 1, len, fd) != len) 2252159b3361Sopenharmony_ci return -1; /* failed */ 2253159b3361Sopenharmony_ci len = 0; /* copied, nothing to skip */ 2254159b3361Sopenharmony_ci } 2255159b3361Sopenharmony_ci else { 2256159b3361Sopenharmony_ci global.in_id3v2_size = 0; 2257159b3361Sopenharmony_ci } 2258159b3361Sopenharmony_ci } 2259159b3361Sopenharmony_ci if (len > LONG_MAX) 2260159b3361Sopenharmony_ci return -1; 2261159b3361Sopenharmony_ci if (fskip_long(fd, (long) len, SEEK_CUR) != 0) 2262159b3361Sopenharmony_ci return -1; 2263159b3361Sopenharmony_ci len = 4; 2264159b3361Sopenharmony_ci if (fread(&buf, 1, len, fd) != len) 2265159b3361Sopenharmony_ci return -1; /* failed */ 2266159b3361Sopenharmony_ci } 2267159b3361Sopenharmony_ci aid_header = check_aid(buf); 2268159b3361Sopenharmony_ci if (aid_header) { 2269159b3361Sopenharmony_ci if (fread(&buf, 1, 2, fd) != 2) 2270159b3361Sopenharmony_ci return -1; /* failed */ 2271159b3361Sopenharmony_ci aid_header = (unsigned char) buf[0] + 256 * (unsigned char) buf[1]; 2272159b3361Sopenharmony_ci if (global_ui_config.silent < 9) { 2273159b3361Sopenharmony_ci console_printf("Album ID found. length=%i \n", aid_header); 2274159b3361Sopenharmony_ci } 2275159b3361Sopenharmony_ci /* skip rest of AID, except for 6 bytes we have already read */ 2276159b3361Sopenharmony_ci fskip_long(fd, aid_header - 6, SEEK_CUR); 2277159b3361Sopenharmony_ci 2278159b3361Sopenharmony_ci /* read 4 more bytes to set up buffer for MP3 header check */ 2279159b3361Sopenharmony_ci if (fread(&buf, 1, len, fd) != len) 2280159b3361Sopenharmony_ci return -1; /* failed */ 2281159b3361Sopenharmony_ci } 2282159b3361Sopenharmony_ci len = 4; 2283159b3361Sopenharmony_ci while (!is_syncword_mp123(buf)) { 2284159b3361Sopenharmony_ci unsigned int i; 2285159b3361Sopenharmony_ci for (i = 0; i < len - 1; i++) 2286159b3361Sopenharmony_ci buf[i] = buf[i + 1]; 2287159b3361Sopenharmony_ci if (fread(buf + len - 1, 1, 1, fd) != 1) 2288159b3361Sopenharmony_ci return -1; /* failed */ 2289159b3361Sopenharmony_ci } 2290159b3361Sopenharmony_ci 2291159b3361Sopenharmony_ci if ((buf[2] & 0xf0) == 0) { 2292159b3361Sopenharmony_ci if (global_ui_config.silent < 9) { 2293159b3361Sopenharmony_ci console_printf("Input file is freeformat.\n"); 2294159b3361Sopenharmony_ci } 2295159b3361Sopenharmony_ci freeformat = 1; 2296159b3361Sopenharmony_ci } 2297159b3361Sopenharmony_ci /* now parse the current buffer looking for MP3 headers. */ 2298159b3361Sopenharmony_ci /* (as of 11/00: mpglib modified so that for the first frame where */ 2299159b3361Sopenharmony_ci /* headers are parsed, no data will be decoded. */ 2300159b3361Sopenharmony_ci /* However, for freeformat, we need to decode an entire frame, */ 2301159b3361Sopenharmony_ci /* so mp3data->bitrate will be 0 until we have decoded the first */ 2302159b3361Sopenharmony_ci /* frame. Cannot decode first frame here because we are not */ 2303159b3361Sopenharmony_ci /* yet prepared to handle the output. */ 2304159b3361Sopenharmony_ci ret = hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, enc_padding); 2305159b3361Sopenharmony_ci if (-1 == ret) 2306159b3361Sopenharmony_ci return -1; 2307159b3361Sopenharmony_ci 2308159b3361Sopenharmony_ci /* repeat until we decode a valid mp3 header. */ 2309159b3361Sopenharmony_ci while (!mp3data->header_parsed) { 2310159b3361Sopenharmony_ci len = fread(buf, 1, sizeof(buf), fd); 2311159b3361Sopenharmony_ci if (len != sizeof(buf)) 2312159b3361Sopenharmony_ci return -1; 2313159b3361Sopenharmony_ci ret = 2314159b3361Sopenharmony_ci hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, 2315159b3361Sopenharmony_ci enc_padding); 2316159b3361Sopenharmony_ci if (-1 == ret) 2317159b3361Sopenharmony_ci return -1; 2318159b3361Sopenharmony_ci } 2319159b3361Sopenharmony_ci 2320159b3361Sopenharmony_ci if (mp3data->bitrate == 0 && !freeformat) { 2321159b3361Sopenharmony_ci if (global_ui_config.silent < 10) { 2322159b3361Sopenharmony_ci error_printf("fail to sync...\n"); 2323159b3361Sopenharmony_ci } 2324159b3361Sopenharmony_ci return lame_decode_initfile(fd, mp3data, enc_delay, enc_padding); 2325159b3361Sopenharmony_ci } 2326159b3361Sopenharmony_ci 2327159b3361Sopenharmony_ci if (mp3data->totalframes > 0) { 2328159b3361Sopenharmony_ci /* mpglib found a Xing VBR header and computed nsamp & totalframes */ 2329159b3361Sopenharmony_ci } 2330159b3361Sopenharmony_ci else { 2331159b3361Sopenharmony_ci /* set as unknown. Later, we will take a guess based on file size 2332159b3361Sopenharmony_ci * ant bitrate */ 2333159b3361Sopenharmony_ci mp3data->nsamp = MAX_U_32_NUM; 2334159b3361Sopenharmony_ci } 2335159b3361Sopenharmony_ci 2336159b3361Sopenharmony_ci 2337159b3361Sopenharmony_ci /* 2338159b3361Sopenharmony_ci report_printf("ret = %i NEED_MORE=%i \n",ret,MP3_NEED_MORE); 2339159b3361Sopenharmony_ci report_printf("stereo = %i \n",mp.fr.stereo); 2340159b3361Sopenharmony_ci report_printf("samp = %i \n",freqs[mp.fr.sampling_frequency]); 2341159b3361Sopenharmony_ci report_printf("framesize = %i \n",framesize); 2342159b3361Sopenharmony_ci report_printf("bitrate = %i \n",mp3data->bitrate); 2343159b3361Sopenharmony_ci report_printf("num frames = %ui \n",num_frames); 2344159b3361Sopenharmony_ci report_printf("num samp = %ui \n",mp3data->nsamp); 2345159b3361Sopenharmony_ci report_printf("mode = %i \n",mp.fr.mode); 2346159b3361Sopenharmony_ci */ 2347159b3361Sopenharmony_ci 2348159b3361Sopenharmony_ci return 0; 2349159b3361Sopenharmony_ci} 2350159b3361Sopenharmony_ci 2351159b3361Sopenharmony_ci/* 2352159b3361Sopenharmony_ciFor lame_decode_fromfile: return code 2353159b3361Sopenharmony_ci -1 error 2354159b3361Sopenharmony_ci n number of samples output. either 576 or 1152 depending on MP3 file. 2355159b3361Sopenharmony_ci 2356159b3361Sopenharmony_ci 2357159b3361Sopenharmony_ciFor lame_decode1_headers(): return code 2358159b3361Sopenharmony_ci -1 error 2359159b3361Sopenharmony_ci 0 ok, but need more data before outputing any samples 2360159b3361Sopenharmony_ci n number of samples output. either 576 or 1152 depending on MP3 file. 2361159b3361Sopenharmony_ci*/ 2362159b3361Sopenharmony_cistatic int 2363159b3361Sopenharmony_cilame_decode_fromfile(FILE * fd, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) 2364159b3361Sopenharmony_ci{ 2365159b3361Sopenharmony_ci int ret = 0; 2366159b3361Sopenharmony_ci size_t len = 0; 2367159b3361Sopenharmony_ci unsigned char buf[1024]; 2368159b3361Sopenharmony_ci 2369159b3361Sopenharmony_ci /* first see if we still have data buffered in the decoder: */ 2370159b3361Sopenharmony_ci ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data); 2371159b3361Sopenharmony_ci if (ret != 0) 2372159b3361Sopenharmony_ci return ret; 2373159b3361Sopenharmony_ci 2374159b3361Sopenharmony_ci 2375159b3361Sopenharmony_ci /* read until we get a valid output frame */ 2376159b3361Sopenharmony_ci for (;;) { 2377159b3361Sopenharmony_ci len = fread(buf, 1, 1024, fd); 2378159b3361Sopenharmony_ci if (len == 0) { 2379159b3361Sopenharmony_ci /* we are done reading the file, but check for buffered data */ 2380159b3361Sopenharmony_ci ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data); 2381159b3361Sopenharmony_ci if (ret <= 0) { 2382159b3361Sopenharmony_ci return -1; /* done with file */ 2383159b3361Sopenharmony_ci } 2384159b3361Sopenharmony_ci break; 2385159b3361Sopenharmony_ci } 2386159b3361Sopenharmony_ci 2387159b3361Sopenharmony_ci ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data); 2388159b3361Sopenharmony_ci if (ret == -1) { 2389159b3361Sopenharmony_ci return -1; 2390159b3361Sopenharmony_ci } 2391159b3361Sopenharmony_ci if (ret > 0) 2392159b3361Sopenharmony_ci break; 2393159b3361Sopenharmony_ci } 2394159b3361Sopenharmony_ci return ret; 2395159b3361Sopenharmony_ci} 2396159b3361Sopenharmony_ci#endif /* defined(HAVE_MPGLIB) */ 2397159b3361Sopenharmony_ci 2398159b3361Sopenharmony_ci 2399159b3361Sopenharmony_ciint 2400159b3361Sopenharmony_ciis_mpeg_file_format(int input_file_format) 2401159b3361Sopenharmony_ci{ 2402159b3361Sopenharmony_ci switch (input_file_format) { 2403159b3361Sopenharmony_ci case sf_mp1: 2404159b3361Sopenharmony_ci return 1; 2405159b3361Sopenharmony_ci case sf_mp2: 2406159b3361Sopenharmony_ci return 2; 2407159b3361Sopenharmony_ci case sf_mp3: 2408159b3361Sopenharmony_ci return 3; 2409159b3361Sopenharmony_ci case sf_mp123: 2410159b3361Sopenharmony_ci return -1; 2411159b3361Sopenharmony_ci default: 2412159b3361Sopenharmony_ci break; 2413159b3361Sopenharmony_ci } 2414159b3361Sopenharmony_ci return 0; 2415159b3361Sopenharmony_ci} 2416159b3361Sopenharmony_ci 2417159b3361Sopenharmony_ci 2418159b3361Sopenharmony_ci#define LOW__BYTE(x) (x & 0x00ff) 2419159b3361Sopenharmony_ci#define HIGH_BYTE(x) ((x >> 8) & 0x00ff) 2420159b3361Sopenharmony_ci 2421159b3361Sopenharmony_civoid 2422159b3361Sopenharmony_ciput_audio16(FILE * outf, short Buffer[2][1152], int iread, int nch) 2423159b3361Sopenharmony_ci{ 2424159b3361Sopenharmony_ci char data[2 * 1152 * 2]; 2425159b3361Sopenharmony_ci int i, m = 0; 2426159b3361Sopenharmony_ci 2427159b3361Sopenharmony_ci if (global_decoder.disable_wav_header && global_reader.swapbytes) { 2428159b3361Sopenharmony_ci if (nch == 1) { 2429159b3361Sopenharmony_ci for (i = 0; i < iread; i++) { 2430159b3361Sopenharmony_ci short x = Buffer[0][i]; 2431159b3361Sopenharmony_ci /* write 16 Bits High Low */ 2432159b3361Sopenharmony_ci data[m++] = HIGH_BYTE(x); 2433159b3361Sopenharmony_ci data[m++] = LOW__BYTE(x); 2434159b3361Sopenharmony_ci } 2435159b3361Sopenharmony_ci } 2436159b3361Sopenharmony_ci else { 2437159b3361Sopenharmony_ci for (i = 0; i < iread; i++) { 2438159b3361Sopenharmony_ci short x = Buffer[0][i], y = Buffer[1][i]; 2439159b3361Sopenharmony_ci /* write 16 Bits High Low */ 2440159b3361Sopenharmony_ci data[m++] = HIGH_BYTE(x); 2441159b3361Sopenharmony_ci data[m++] = LOW__BYTE(x); 2442159b3361Sopenharmony_ci /* write 16 Bits High Low */ 2443159b3361Sopenharmony_ci data[m++] = HIGH_BYTE(y); 2444159b3361Sopenharmony_ci data[m++] = LOW__BYTE(y); 2445159b3361Sopenharmony_ci } 2446159b3361Sopenharmony_ci } 2447159b3361Sopenharmony_ci } 2448159b3361Sopenharmony_ci else { 2449159b3361Sopenharmony_ci if (nch == 1) { 2450159b3361Sopenharmony_ci for (i = 0; i < iread; i++) { 2451159b3361Sopenharmony_ci short x = Buffer[0][i]; 2452159b3361Sopenharmony_ci /* write 16 Bits Low High */ 2453159b3361Sopenharmony_ci data[m++] = LOW__BYTE(x); 2454159b3361Sopenharmony_ci data[m++] = HIGH_BYTE(x); 2455159b3361Sopenharmony_ci } 2456159b3361Sopenharmony_ci } 2457159b3361Sopenharmony_ci else { 2458159b3361Sopenharmony_ci for (i = 0; i < iread; i++) { 2459159b3361Sopenharmony_ci short x = Buffer[0][i], y = Buffer[1][i]; 2460159b3361Sopenharmony_ci /* write 16 Bits Low High */ 2461159b3361Sopenharmony_ci data[m++] = LOW__BYTE(x); 2462159b3361Sopenharmony_ci data[m++] = HIGH_BYTE(x); 2463159b3361Sopenharmony_ci /* write 16 Bits Low High */ 2464159b3361Sopenharmony_ci data[m++] = LOW__BYTE(y); 2465159b3361Sopenharmony_ci data[m++] = HIGH_BYTE(y); 2466159b3361Sopenharmony_ci } 2467159b3361Sopenharmony_ci } 2468159b3361Sopenharmony_ci } 2469159b3361Sopenharmony_ci if (m > 0) { 2470159b3361Sopenharmony_ci fwrite(data, 1, m, outf); 2471159b3361Sopenharmony_ci } 2472159b3361Sopenharmony_ci if (global_writer.flush_write == 1) { 2473159b3361Sopenharmony_ci fflush(outf); 2474159b3361Sopenharmony_ci } 2475159b3361Sopenharmony_ci} 2476159b3361Sopenharmony_ci 2477159b3361Sopenharmony_cihip_t 2478159b3361Sopenharmony_ciget_hip(void) 2479159b3361Sopenharmony_ci{ 2480159b3361Sopenharmony_ci return global.hip; 2481159b3361Sopenharmony_ci} 2482159b3361Sopenharmony_ci 2483159b3361Sopenharmony_cisize_t 2484159b3361Sopenharmony_cisizeOfOldTag(lame_t gf) 2485159b3361Sopenharmony_ci{ 2486159b3361Sopenharmony_ci (void) gf; 2487159b3361Sopenharmony_ci return global.in_id3v2_size; 2488159b3361Sopenharmony_ci} 2489159b3361Sopenharmony_ci 2490159b3361Sopenharmony_ciunsigned char* 2491159b3361Sopenharmony_cigetOldTag(lame_t gf) 2492159b3361Sopenharmony_ci{ 2493159b3361Sopenharmony_ci (void) gf; 2494159b3361Sopenharmony_ci return global.in_id3v2_tag; 2495159b3361Sopenharmony_ci} 2496159b3361Sopenharmony_ci 2497159b3361Sopenharmony_ci/* end of get_audio.c */ 2498