| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290 |
- /*
- * Get Audio routines source file
- *
- * Copyright (c) 1999 Albert L Faber
- * 2008-2017 Robert Hegemann
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
- /* $Id$ */
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include <assert.h>
- #ifdef HAVE_LIMITS_H
- # include <limits.h>
- #endif
- #include <stdio.h>
- #ifdef STDC_HEADERS
- # include <stdlib.h>
- # include <string.h>
- #else
- # ifndef HAVE_STRCHR
- # define strchr index
- # define strrchr rindex
- # endif
- char *strchr(), *strrchr();
- # ifndef HAVE_MEMCPY
- # define memcpy(d, s, n) bcopy ((s), (d), (n))
- # define memmove(d, s, n) bcopy ((s), (d), (n))
- # endif
- #endif
- #ifdef HAVE_INTTYPES_H
- # include <inttypes.h>
- #else
- # ifdef HAVE_STDINT_H
- # include <stdint.h>
- # endif
- #endif
- #define MAX_U_32_NUM 0xFFFFFFFF
- #include <math.h>
- #if defined(__riscos__)
- # include <kernel.h>
- # include <sys/swis.h>
- #elif defined(_WIN32)
- # include <sys/types.h>
- # include <sys/stat.h>
- #else
- # include <sys/stat.h>
- #endif
- #ifdef __sun__
- /* woraround for SunOS 4.x, it has SEEK_* defined here */
- #include <unistd.h>
- #endif
- #include "lame.h"
- #include "main.h"
- #include "get_audio.h"
- #include "lametime.h"
- #include "console.h"
- #ifdef WITH_DMALLOC
- #include <dmalloc.h>
- #endif
- #ifndef STR
- # define __STR(x) #x
- # define STR(x) __STR(x)
- #define __LOC__ __FILE__ "("STR(__LINE__)") : "
- #endif
- #define FLOAT_TO_UNSIGNED(f) ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))
- #define UNSIGNED_TO_FLOAT(u) (((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)
- static unsigned int uint32_high_low(unsigned char *bytes)
- {
- uint32_t const hh = bytes[0];
- uint32_t const hl = bytes[1];
- uint32_t const lh = bytes[2];
- uint32_t const ll = bytes[3];
- return (hh << 24) | (hl << 16) | (lh << 8) | ll;
- }
- static double
- read_ieee_extended_high_low(FILE * fp)
- {
- unsigned char bytes[10];
- memset(bytes, 0, 10);
- fread(bytes, 1, 10, fp);
- {
- int32_t const s = (bytes[0] & 0x80);
- int32_t const e_h = (bytes[0] & 0x7F);
- int32_t const e_l = bytes[1];
- int32_t e = (e_h << 8) | e_l;
- uint32_t const hm = uint32_high_low(bytes + 2);
- uint32_t const lm = uint32_high_low(bytes + 6);
- double result = 0;
- if (e != 0 || hm != 0 || lm != 0) {
- if (e == 0x7fff) {
- result = HUGE_VAL;
- }
- else {
- double mantissa_h = UNSIGNED_TO_FLOAT(hm);
- double mantissa_l = UNSIGNED_TO_FLOAT(lm);
- e -= 0x3fff;
- e -= 31;
- result = ldexp(mantissa_h, e);
- e -= 32;
- result += ldexp(mantissa_l, e);
- }
- }
- return s ? -result : result;
- }
- }
- static int
- read_16_bits_low_high(FILE * fp)
- {
- unsigned char bytes[2] = { 0, 0 };
- fread(bytes, 1, 2, fp);
- {
- int32_t const low = bytes[0];
- int32_t const high = (signed char) (bytes[1]);
- return (high << 8) | low;
- }
- }
- static int
- read_32_bits_low_high(FILE * fp)
- {
- unsigned char bytes[4] = { 0, 0, 0, 0 };
- fread(bytes, 1, 4, fp);
- {
- int32_t const low = bytes[0];
- int32_t const medl = bytes[1];
- int32_t const medh = bytes[2];
- int32_t const high = (signed char) (bytes[3]);
- return (high << 24) | (medh << 16) | (medl << 8) | low;
- }
- }
- static int
- read_16_bits_high_low(FILE * fp)
- {
- unsigned char bytes[2] = { 0, 0 };
- fread(bytes, 1, 2, fp);
- {
- int32_t const low = bytes[1];
- int32_t const high = (signed char) (bytes[0]);
- return (high << 8) | low;
- }
- }
- static int
- read_32_bits_high_low(FILE * fp)
- {
- unsigned char bytes[4] = { 0, 0, 0, 0 };
- fread(bytes, 1, 4, fp);
- {
- int32_t const low = bytes[3];
- int32_t const medl = bytes[2];
- int32_t const medh = bytes[1];
- int32_t const high = (signed char) (bytes[0]);
- return (high << 24) | (medh << 16) | (medl << 8) | low;
- }
- }
- static void
- write_16_bits_low_high(FILE * fp, int val)
- {
- unsigned char bytes[2];
- bytes[0] = (val & 0xff);
- bytes[1] = ((val >> 8) & 0xff);
- fwrite(bytes, 1, 2, fp);
- }
- static void
- write_32_bits_low_high(FILE * fp, int val)
- {
- unsigned char bytes[4];
- bytes[0] = (val & 0xff);
- bytes[1] = ((val >> 8) & 0xff);
- bytes[2] = ((val >> 16) & 0xff);
- bytes[3] = ((val >> 24) & 0xff);
- fwrite(bytes, 1, 4, fp);
- }
- #ifdef LIBSNDFILE
- #include <sndfile.h>
- #else
- typedef void SNDFILE;
- #endif /* ifdef LIBSNDFILE */
- typedef struct blockAlign_struct {
- unsigned long offset;
- unsigned long blockSize;
- } blockAlign;
- typedef struct IFF_AIFF_struct {
- short numChannels;
- unsigned long numSampleFrames;
- short sampleSize;
- double sampleRate;
- unsigned long sampleType;
- blockAlign blkAlgn;
- } IFF_AIFF;
- struct PcmBuffer {
- void *ch[2]; /* buffer for each channel */
- int w; /* sample width */
- int n; /* number samples allocated */
- int u; /* number samples used */
- int skip_start; /* number samples to ignore at the beginning */
- int skip_end; /* number samples to ignore at the end */
- };
- typedef struct PcmBuffer PcmBuffer;
- static void
- initPcmBuffer(PcmBuffer * b, int w)
- {
- b->ch[0] = 0;
- b->ch[1] = 0;
- b->w = w;
- b->n = 0;
- b->u = 0;
- b->skip_start = 0;
- b->skip_end = 0;
- }
- static void
- freePcmBuffer(PcmBuffer * b)
- {
- if (b != 0) {
- free(b->ch[0]);
- free(b->ch[1]);
- b->ch[0] = 0;
- b->ch[1] = 0;
- b->n = 0;
- b->u = 0;
- }
- }
- static int
- addPcmBuffer(PcmBuffer * b, void *a0, void *a1, int read)
- {
- int a_n;
- if (b == 0) {
- return 0;
- }
- if (read < 0) {
- return b->u - b->skip_end;
- }
- if (b->skip_start >= read) {
- b->skip_start -= read;
- return b->u - b->skip_end;
- }
- a_n = read - b->skip_start;
- if (b != 0 && a_n > 0) {
- int const a_skip = b->w * b->skip_start;
- int const a_want = b->w * a_n;
- int const b_used = b->w * b->u;
- int const b_have = b->w * b->n;
- int const b_need = b->w * (b->u + a_n);
- if (b_have < b_need) {
- b->n = b->u + a_n;
- b->ch[0] = realloc(b->ch[0], b_need);
- b->ch[1] = realloc(b->ch[1], b_need);
- }
- b->u += a_n;
- if (b->ch[0] != 0 && a0 != 0) {
- char *src = a0;
- char *dst = b->ch[0];
- memcpy(dst + b_used, src + a_skip, a_want);
- }
- if (b->ch[1] != 0 && a1 != 0) {
- char *src = a1;
- char *dst = b->ch[1];
- memcpy(dst + b_used, src + a_skip, a_want);
- }
- }
- b->skip_start = 0;
- return b->u - b->skip_end;
- }
- static int
- takePcmBuffer(PcmBuffer * b, void *a0, void *a1, int a_n, int mm)
- {
- if (a_n > mm) {
- a_n = mm;
- }
- if (b != 0 && a_n > 0) {
- int const a_take = b->w * a_n;
- if (a0 != 0 && b->ch[0] != 0) {
- memcpy(a0, b->ch[0], a_take);
- }
- if (a1 != 0 && b->ch[1] != 0) {
- memcpy(a1, b->ch[1], a_take);
- }
- b->u -= a_n;
- if (b->u < 0) {
- b->u = 0;
- return a_n;
- }
- if (b->ch[0] != 0) {
- memmove(b->ch[0], (char *) b->ch[0] + a_take, b->w * b->u);
- }
- if (b->ch[1] != 0) {
- memmove(b->ch[1], (char *) b->ch[1] + a_take, b->w * b->u);
- }
- }
- return a_n;
- }
- /* global data for get_audio.c. */
- typedef struct get_audio_global_data_struct {
- int count_samples_carefully;
- int pcmbitwidth;
- int pcmswapbytes;
- int pcm_is_unsigned_8bit;
- int pcm_is_ieee_float;
- unsigned int num_samples_read;
- FILE *music_in;
- SNDFILE *snd_file;
- hip_t hip;
- PcmBuffer pcm32;
- PcmBuffer pcm16;
- size_t in_id3v2_size;
- unsigned char* in_id3v2_tag;
- } get_audio_global_data;
- static get_audio_global_data global;
- #ifdef AMIGA_MPEGA
- int lame_decode_initfile(const char *fullname, mp3data_struct * const mp3data);
- #else
- int lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding);
- #endif
- /* read mp3 file until mpglib returns one frame of PCM data */
- static int lame_decode_fromfile(FILE * fd, short int pcm_l[], short int pcm_r[],
- mp3data_struct * mp3data);
- static int read_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read);
- static int read_samples_mp3(lame_t gfp, FILE * musicin, short int mpg123pcm[2][1152]);
- #ifdef LIBSNDFILE
- static SNDFILE *open_snd_file(lame_t gfp, char const *inPath);
- #endif
- static FILE *open_mpeg_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding);
- static FILE *open_wave_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding);
- static int close_input_file(FILE * musicin);
- static size_t
- min_size_t(size_t a, size_t b)
- {
- if (a < b) {
- return a;
- }
- return b;
- }
- enum ByteOrder machine_byte_order(void);
- enum ByteOrder
- machine_byte_order(void)
- {
- long one = 1;
- return !(*((char *) (&one))) ? ByteOrderBigEndian : ByteOrderLittleEndian;
- }
- /* Replacement for forward fseek(,,SEEK_CUR), because fseek() fails on pipes */
- static int
- fskip(FILE * fp, long offset, int whence)
- {
- #ifndef PIPE_BUF
- char buffer[4096];
- #else
- char buffer[PIPE_BUF];
- #endif
- /* S_ISFIFO macro is defined on newer Linuxes */
- #ifndef S_ISFIFO
- # ifdef _S_IFIFO
- /* _S_IFIFO is defined on Win32 and Cygwin */
- # define S_ISFIFO(m) (((m)&_S_IFIFO) == _S_IFIFO)
- # endif
- #endif
- #ifdef S_ISFIFO
- /* fseek is known to fail on pipes with several C-Library implementations
- workaround: 1) test for pipe
- 2) for pipes, only relatvie seeking is possible
- 3) and only in forward direction!
- else fallback to old code
- */
- {
- int const fd = fileno(fp);
- struct stat file_stat;
- if (fstat(fd, &file_stat) == 0) {
- if (S_ISFIFO(file_stat.st_mode)) {
- if (whence != SEEK_CUR || offset < 0) {
- return -1;
- }
- while (offset > 0) {
- size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset);
- size_t const read = fread(buffer, 1, bytes_to_skip, fp);
- if (read < 1) {
- return -1;
- }
- assert( read <= LONG_MAX );
- offset -= (long) read;
- }
- return 0;
- }
- }
- }
- #endif
- if (0 == fseek(fp, offset, whence)) {
- return 0;
- }
- if (whence != SEEK_CUR || offset < 0) {
- if (global_ui_config.silent < 10) {
- error_printf
- ("fskip problem: Mostly the return status of functions is not evaluate so it is more secure to polute <stderr>.\n");
- }
- return -1;
- }
- while (offset > 0) {
- size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset);
- size_t const read = fread(buffer, 1, bytes_to_skip, fp);
- if (read < 1) {
- return -1;
- }
- assert( read <= LONG_MAX );
- offset -= (long) read;
- }
- return 0;
- }
- static off_t
- lame_get_file_size(FILE * fp)
- {
- struct stat sb;
- int fd = fileno(fp);
- if (0 == fstat(fd, &sb))
- return sb.st_size;
- return (off_t) - 1;
- }
- FILE *
- init_outfile(char const *outPath, int decode)
- {
- FILE *outf;
- /* open the output file */
- if (0 == strcmp(outPath, "-")) {
- outf = stdout;
- lame_set_stream_binary_mode(outf);
- }
- else {
- outf = lame_fopen(outPath, "w+b");
- #ifdef __riscos__
- /* Assign correct file type */
- if (outf != NULL) {
- char *p, *out_path = strdup(outPath);
- for (p = out_path; *p; p++) { /* ugly, ugly to modify a string */
- switch (*p) {
- case '.':
- *p = '/';
- break;
- case '/':
- *p = '.';
- break;
- }
- }
- SetFiletype(out_path, decode ? 0xFB1 /*WAV*/ : 0x1AD /*AMPEG*/);
- free(out_path);
- }
- #else
- (void) decode;
- #endif
- }
- return outf;
- }
- static void
- setSkipStartAndEnd(lame_t gfp, int enc_delay, int enc_padding)
- {
- int skip_start = 0, skip_end = 0;
- if (global_decoder.mp3_delay_set)
- skip_start = global_decoder.mp3_delay;
- switch (global_reader.input_format) {
- case sf_mp123:
- break;
- case sf_mp3:
- if (skip_start == 0) {
- if (enc_delay > -1 || enc_padding > -1) {
- if (enc_delay > -1)
- skip_start = enc_delay + 528 + 1;
- if (enc_padding > -1)
- skip_end = enc_padding - (528 + 1);
- }
- else
- skip_start = lame_get_encoder_delay(gfp) + 528 + 1;
- }
- else {
- /* user specified a value of skip. just add for decoder */
- skip_start += 528 + 1; /* mp3 decoder has a 528 sample delay, plus user supplied "skip" */
- }
- break;
- case sf_mp2:
- skip_start += 240 + 1;
- break;
- case sf_mp1:
- skip_start += 240 + 1;
- break;
- case sf_raw:
- skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
- break;
- case sf_wave:
- skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
- break;
- case sf_aiff:
- skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
- break;
- default:
- skip_start += 0; /* other formats have no delay *//* is += 0 not better ??? */
- break;
- }
- skip_start = skip_start < 0 ? 0 : skip_start;
- skip_end = skip_end < 0 ? 0 : skip_end;
- global. pcm16.skip_start = global.pcm32.skip_start = skip_start;
- global. pcm16.skip_end = global.pcm32.skip_end = skip_end;
- }
- int
- init_infile(lame_t gfp, char const *inPath)
- {
- int enc_delay = 0, enc_padding = 0;
- /* open the input file */
- global. count_samples_carefully = 0;
- global. num_samples_read = 0;
- global. pcmbitwidth = global_raw_pcm.in_bitwidth;
- global. pcmswapbytes = global_reader.swapbytes;
- global. pcm_is_unsigned_8bit = global_raw_pcm.in_signed == 1 ? 0 : 1;
- global. pcm_is_ieee_float = 0;
- global. hip = 0;
- global. music_in = 0;
- global. snd_file = 0;
- global. in_id3v2_size = 0;
- global. in_id3v2_tag = 0;
- if (is_mpeg_file_format(global_reader.input_format)) {
- global. music_in = open_mpeg_file(gfp, inPath, &enc_delay, &enc_padding);
- }
- else {
- #ifdef LIBSNDFILE
- if (strcmp(inPath, "-") != 0) { /* not for stdin */
- global. snd_file = open_snd_file(gfp, inPath);
- }
- #endif
- if (global.snd_file == 0) {
- global. music_in = open_wave_file(gfp, inPath, &enc_delay, &enc_padding);
- }
- }
- initPcmBuffer(&global.pcm32, sizeof(int));
- initPcmBuffer(&global.pcm16, sizeof(short));
- setSkipStartAndEnd(gfp, enc_delay, enc_padding);
- {
- unsigned long n = lame_get_num_samples(gfp);
- if (n != MAX_U_32_NUM) {
- unsigned long const discard = global.pcm32.skip_start + global.pcm32.skip_end;
- lame_set_num_samples(gfp, n > discard ? n - discard : 0);
- }
- }
- return (global.snd_file != NULL || global.music_in != NULL) ? 1 : -1;
- }
- int
- samples_to_skip_at_start(void)
- {
- return global.pcm32.skip_start;
- }
- int
- samples_to_skip_at_end(void)
- {
- return global.pcm32.skip_end;
- }
- void
- close_infile(void)
- {
- #if defined(HAVE_MPGLIB)
- if (global.hip != 0) {
- hip_decode_exit(global.hip); /* release mp3decoder memory */
- global. hip = 0;
- }
- #endif
- close_input_file(global.music_in);
- #ifdef LIBSNDFILE
- if (global.snd_file) {
- if (sf_close(global.snd_file) != 0) {
- if (global_ui_config.silent < 10) {
- error_printf("Could not close sound file \n");
- }
- }
- global. snd_file = 0;
- }
- #endif
- freePcmBuffer(&global.pcm32);
- freePcmBuffer(&global.pcm16);
- global. music_in = 0;
- free(global.in_id3v2_tag);
- global.in_id3v2_tag = 0;
- global.in_id3v2_size = 0;
- }
- static int
- get_audio_common(lame_t gfp, int buffer[2][1152], short buffer16[2][1152]);
- /************************************************************************
- *
- * get_audio()
- *
- * PURPOSE: reads a frame of audio data from a file to the buffer,
- * aligns the data for future processing, and separates the
- * left and right channels
- *
- ************************************************************************/
- int
- get_audio(lame_t gfp, int buffer[2][1152])
- {
- int used = 0, read = 0;
- do {
- read = get_audio_common(gfp, buffer, NULL);
- used = addPcmBuffer(&global.pcm32, buffer[0], buffer[1], read);
- } while (used <= 0 && read > 0);
- if (read < 0) {
- return read;
- }
- if (global_reader.swap_channel == 0)
- return takePcmBuffer(&global.pcm32, buffer[0], buffer[1], used, 1152);
- else
- return takePcmBuffer(&global.pcm32, buffer[1], buffer[0], used, 1152);
- }
- /*
- get_audio16 - behave as the original get_audio function, with a limited
- 16 bit per sample output
- */
- int
- get_audio16(lame_t gfp, short buffer[2][1152])
- {
- int used = 0, read = 0;
- do {
- read = get_audio_common(gfp, NULL, buffer);
- used = addPcmBuffer(&global.pcm16, buffer[0], buffer[1], read);
- } while (used <= 0 && read > 0);
- if (read < 0) {
- return read;
- }
- if (global_reader.swap_channel == 0)
- return takePcmBuffer(&global.pcm16, buffer[0], buffer[1], used, 1152);
- else
- return takePcmBuffer(&global.pcm16, buffer[1], buffer[0], used, 1152);
- }
- /************************************************************************
- get_audio_common - central functionality of get_audio*
- in: gfp
- buffer output to the int buffer or 16-bit buffer
- out: buffer int output (if buffer != NULL)
- buffer16 16-bit output (if buffer == NULL)
- returns: samples read
- note: either buffer or buffer16 must be allocated upon call
- */
- static int
- get_audio_common(lame_t gfp, int buffer[2][1152], short buffer16[2][1152])
- {
- const int num_channels = lame_get_num_channels(gfp);
- const int framesize = lame_get_framesize(gfp);
- int insamp[2 * 1152];
- short buf_tmp16[2][1152];
- int samples_read;
- int samples_to_read;
- unsigned int remaining;
- int i;
- int *p;
- /* sanity checks, that's what we expect to be true */
- if ((num_channels < 1 || 2 < num_channels)
- ||(framesize < 1 || 1152 < framesize)) {
- if (global_ui_config.silent < 10) {
- error_printf("Error: internal problem!\n");
- }
- return -1;
- }
- /*
- * NOTE: LAME can now handle arbritray size input data packets,
- * so there is no reason to read the input data in chuncks of
- * size "framesize". EXCEPT: the LAME graphical frame analyzer
- * will get out of sync if we read more than framesize worth of data.
- */
- samples_to_read = framesize;
- /* if this flag has been set, then we are carefull to read
- * exactly num_samples and no more. This is useful for .wav and .aiff
- * files which have id3 or other tags at the end. Note that if you
- * are using LIBSNDFILE, this is not necessary
- */
- if (global.count_samples_carefully) {
- unsigned int tmp_num_samples;
- /* get num_samples */
- if (is_mpeg_file_format(global_reader.input_format)) {
- tmp_num_samples = global_decoder.mp3input_data.nsamp;
- }
- else {
- tmp_num_samples = lame_get_num_samples(gfp);
- }
- if (global.num_samples_read < tmp_num_samples) {
- remaining = tmp_num_samples - global.num_samples_read;
- }
- else {
- remaining = 0;
- }
- if (remaining < (unsigned int) framesize && 0 != tmp_num_samples)
- /* in case the input is a FIFO (at least it's reproducible with
- a FIFO) tmp_num_samples may be 0 and therefore remaining
- would be 0, but we need to read some samples, so don't
- change samples_to_read to the wrong value in this case */
- samples_to_read = remaining;
- }
- if (is_mpeg_file_format(global_reader.input_format)) {
- if (buffer != NULL)
- samples_read = read_samples_mp3(gfp, global.music_in, buf_tmp16);
- else
- samples_read = read_samples_mp3(gfp, global.music_in, buffer16);
- if (samples_read < 0) {
- return samples_read;
- }
- }
- else {
- if (global.snd_file) {
- #ifdef LIBSNDFILE
- samples_read = sf_read_int(global.snd_file, insamp, num_channels * samples_to_read);
- #else
- samples_read = 0;
- #endif
- }
- else {
- samples_read =
- read_samples_pcm(global.music_in, insamp, num_channels * samples_to_read);
- }
- if (samples_read < 0) {
- return samples_read;
- }
- p = insamp + samples_read;
- samples_read /= num_channels;
- if (buffer != NULL) { /* output to int buffer */
- if (num_channels == 2) {
- for (i = samples_read; --i >= 0;) {
- buffer[1][i] = *--p;
- buffer[0][i] = *--p;
- }
- }
- else if (num_channels == 1) {
- memset(buffer[1], 0, samples_read * sizeof(int));
- for (i = samples_read; --i >= 0;) {
- buffer[0][i] = *--p;
- }
- }
- else
- assert(0);
- }
- else { /* convert from int; output to 16-bit buffer */
- if (num_channels == 2) {
- for (i = samples_read; --i >= 0;) {
- buffer16[1][i] = *--p >> (8 * sizeof(int) - 16);
- buffer16[0][i] = *--p >> (8 * sizeof(int) - 16);
- }
- }
- else if (num_channels == 1) {
- memset(buffer16[1], 0, samples_read * sizeof(short));
- for (i = samples_read; --i >= 0;) {
- buffer16[0][i] = *--p >> (8 * sizeof(int) - 16);
- }
- }
- else
- assert(0);
- }
- }
- /* LAME mp3 output 16bit - convert to int, if necessary */
- if (is_mpeg_file_format(global_reader.input_format)) {
- if (buffer != NULL) {
- for (i = samples_read; --i >= 0;)
- buffer[0][i] = buf_tmp16[0][i] << (8 * sizeof(int) - 16);
- if (num_channels == 2) {
- for (i = samples_read; --i >= 0;)
- buffer[1][i] = buf_tmp16[1][i] << (8 * sizeof(int) - 16);
- }
- else if (num_channels == 1) {
- memset(buffer[1], 0, samples_read * sizeof(int));
- }
- else
- assert(0);
- }
- }
- /* if ... then it is considered infinitely long.
- Don't count the samples */
- if (global.count_samples_carefully)
- global. num_samples_read += samples_read;
- return samples_read;
- }
- static int
- read_samples_mp3(lame_t gfp, FILE * musicin, short int mpg123pcm[2][1152])
- {
- int out;
- #if defined(AMIGA_MPEGA) || defined(HAVE_MPGLIB)
- int samplerate;
- static const char type_name[] = "MP3 file";
- out = lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1], &global_decoder.mp3input_data);
- /*
- * out < 0: error, probably EOF
- * out = 0: not possible with lame_decode_fromfile() ???
- * out > 0: number of output samples
- */
- if (out < 0) {
- memset(mpg123pcm, 0, sizeof(**mpg123pcm) * 2 * 1152);
- return 0;
- }
- if (lame_get_num_channels(gfp) != global_decoder.mp3input_data.stereo) {
- if (global_ui_config.silent < 10) {
- error_printf("Error: number of channels has changed in %s - not supported\n",
- type_name);
- }
- out = -1;
- }
- samplerate = global_reader.input_samplerate;
- if (samplerate == 0) {
- samplerate = global_decoder.mp3input_data.samplerate;
- }
- if (lame_get_in_samplerate(gfp) != samplerate) {
- if (global_ui_config.silent < 10) {
- error_printf("Error: sample frequency has changed in %s - not supported\n", type_name);
- }
- out = -1;
- }
- #else
- out = -1;
- #endif
- return out;
- }
- static
- int set_input_num_channels(lame_t gfp, int num_channels)
- {
- if (gfp) {
- if (-1 == lame_set_num_channels(gfp, num_channels)) {
- if (global_ui_config.silent < 10) {
- error_printf("Unsupported number of channels: %d\n", num_channels);
- }
- return 0;
- }
- }
- return 1;
- }
- static
- int set_input_samplerate(lame_t gfp, int input_samplerate)
- {
- if (gfp) {
- int sr = global_reader.input_samplerate;
- if (sr == 0) sr = input_samplerate;
- if (-1 == lame_set_in_samplerate(gfp, sr)) {
- if (global_ui_config.silent < 10) {
- error_printf("Unsupported sample rate: %d\n", sr);
- }
- return 0;
- }
- }
- return 1;
- }
- int
- WriteWaveHeader(FILE * const fp, int pcmbytes, int freq, int channels, int bits)
- {
- int bytes = (bits + 7) / 8;
- /* quick and dirty, but documented */
- fwrite("RIFF", 1, 4, fp); /* label */
- write_32_bits_low_high(fp, pcmbytes + 44 - 8); /* length in bytes without header */
- fwrite("WAVEfmt ", 2, 4, fp); /* 2 labels */
- write_32_bits_low_high(fp, 2 + 2 + 4 + 4 + 2 + 2); /* length of PCM format declaration area */
- write_16_bits_low_high(fp, 1); /* is PCM? */
- write_16_bits_low_high(fp, channels); /* number of channels */
- write_32_bits_low_high(fp, freq); /* sample frequency in [Hz] */
- write_32_bits_low_high(fp, freq * channels * bytes); /* bytes per second */
- write_16_bits_low_high(fp, channels * bytes); /* bytes per sample time */
- write_16_bits_low_high(fp, bits); /* bits per sample */
- fwrite("data", 1, 4, fp); /* label */
- write_32_bits_low_high(fp, pcmbytes); /* length in bytes of raw PCM data */
- return ferror(fp) ? -1 : 0;
- }
- #if defined(LIBSNDFILE)
- extern SNDFILE *sf_wchar_open(wchar_t const *wpath, int mode, SF_INFO * sfinfo);
- static SNDFILE *
- open_snd_file(lame_t gfp, char const *inPath)
- {
- char const *lpszFileName = inPath;
- SNDFILE *gs_pSndFileIn = NULL;
- SF_INFO gs_wfInfo;
- {
- #if defined( _WIN32 ) && !defined(__MINGW32__)
- wchar_t *file_name = utf8ToUnicode(lpszFileName);
- #endif
- /* Try to open the sound file */
- memset(&gs_wfInfo, 0, sizeof(gs_wfInfo));
- #if defined( _WIN32 ) && !defined(__MINGW32__)
- gs_pSndFileIn = sf_wchar_open(file_name, SFM_READ, &gs_wfInfo);
- #else
- gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo);
- #endif
- if (gs_pSndFileIn == NULL) {
- if (global_raw_pcm.in_signed == 0 && global_raw_pcm.in_bitwidth != 8) {
- error_printf("Unsigned input only supported with bitwidth 8\n");
- #if defined( _WIN32 ) && !defined(__MINGW32__)
- free(file_name);
- #endif
- return 0;
- }
- /* set some defaults incase input is raw PCM */
- gs_wfInfo.seekable = (global_reader.input_format != sf_raw); /* if user specified -r, set to not seekable */
- gs_wfInfo.samplerate = lame_get_in_samplerate(gfp);
- gs_wfInfo.channels = lame_get_num_channels(gfp);
- gs_wfInfo.format = SF_FORMAT_RAW;
- if ((global_raw_pcm.in_endian == ByteOrderLittleEndian) ^ (global_reader.swapbytes !=
- 0)) {
- gs_wfInfo.format |= SF_ENDIAN_LITTLE;
- }
- else {
- gs_wfInfo.format |= SF_ENDIAN_BIG;
- }
- switch (global_raw_pcm.in_bitwidth) {
- case 8:
- gs_wfInfo.format |=
- global_raw_pcm.in_signed == 0 ? SF_FORMAT_PCM_U8 : SF_FORMAT_PCM_S8;
- break;
- case 16:
- gs_wfInfo.format |= SF_FORMAT_PCM_16;
- break;
- case 24:
- gs_wfInfo.format |= SF_FORMAT_PCM_24;
- break;
- case 32:
- gs_wfInfo.format |= SF_FORMAT_PCM_32;
- break;
- default:
- break;
- }
- #if defined( _WIN32 ) && !defined(__MINGW32__)
- gs_pSndFileIn = sf_wchar_open(file_name, SFM_READ, &gs_wfInfo);
- #else
- gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo);
- #endif
- }
- #if defined( _WIN32 ) && !defined(__MINGW32__)
- free(file_name);
- #endif
- /* Check result */
- if (gs_pSndFileIn == NULL) {
- sf_perror(gs_pSndFileIn);
- if (global_ui_config.silent < 10) {
- error_printf("Could not open sound file \"%s\".\n", lpszFileName);
- }
- return 0;
- }
- sf_command(gs_pSndFileIn, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
- if ((gs_wfInfo.format & SF_FORMAT_RAW) == SF_FORMAT_RAW) {
- global_reader.input_format = sf_raw;
- }
- #ifdef _DEBUG_SND_FILE
- printf("\n\nSF_INFO structure\n");
- printf("samplerate :%d\n", gs_wfInfo.samplerate);
- printf("samples :%d\n", gs_wfInfo.frames);
- printf("channels :%d\n", gs_wfInfo.channels);
- printf("format :");
- /* new formats from sbellon@sbellon.de 1/2000 */
- switch (gs_wfInfo.format & SF_FORMAT_TYPEMASK) {
- case SF_FORMAT_WAV:
- printf("Microsoft WAV format (big endian). ");
- break;
- case SF_FORMAT_AIFF:
- printf("Apple/SGI AIFF format (little endian). ");
- break;
- case SF_FORMAT_AU:
- printf("Sun/NeXT AU format (big endian). ");
- break;
- /*
- case SF_FORMAT_AULE:
- DEBUGF("DEC AU format (little endian). ");
- break;
- */
- case SF_FORMAT_RAW:
- printf("RAW PCM data. ");
- break;
- case SF_FORMAT_PAF:
- printf("Ensoniq PARIS file format. ");
- break;
- case SF_FORMAT_SVX:
- printf("Amiga IFF / SVX8 / SV16 format. ");
- break;
- case SF_FORMAT_NIST:
- printf("Sphere NIST format. ");
- break;
- default:
- assert(0);
- break;
- }
- switch (gs_wfInfo.format & SF_FORMAT_SUBMASK) {
- /*
- case SF_FORMAT_PCM:
- DEBUGF("PCM data in 8, 16, 24 or 32 bits.");
- break;
- */
- case SF_FORMAT_FLOAT:
- printf("32 bit Intel x86 floats.");
- break;
- case SF_FORMAT_ULAW:
- printf("U-Law encoded.");
- break;
- case SF_FORMAT_ALAW:
- printf("A-Law encoded.");
- break;
- case SF_FORMAT_IMA_ADPCM:
- printf("IMA ADPCM.");
- break;
- case SF_FORMAT_MS_ADPCM:
- printf("Microsoft ADPCM.");
- break;
- /*
- case SF_FORMAT_PCM_BE:
- DEBUGF("Big endian PCM data.");
- break;
- case SF_FORMAT_PCM_LE:
- DEBUGF("Little endian PCM data.");
- break;
- */
- case SF_FORMAT_PCM_S8:
- printf("Signed 8 bit PCM.");
- break;
- case SF_FORMAT_PCM_U8:
- printf("Unsigned 8 bit PCM.");
- break;
- case SF_FORMAT_PCM_16:
- printf("Signed 16 bit PCM.");
- break;
- case SF_FORMAT_PCM_24:
- printf("Signed 24 bit PCM.");
- break;
- case SF_FORMAT_PCM_32:
- printf("Signed 32 bit PCM.");
- break;
- /*
- case SF_FORMAT_SVX_FIB:
- DEBUGF("SVX Fibonacci Delta encoding.");
- break;
- case SF_FORMAT_SVX_EXP:
- DEBUGF("SVX Exponential Delta encoding.");
- break;
- */
- default:
- assert(0);
- break;
- }
- printf("\n");
- printf("sections :%d\n", gs_wfInfo.sections);
- printf("seekable :%d\n", gs_wfInfo.seekable);
- #endif
- /* Check result */
- if (gs_pSndFileIn == NULL) {
- sf_perror(gs_pSndFileIn);
- if (global_ui_config.silent < 10) {
- error_printf("Could not open sound file \"%s\".\n", lpszFileName);
- }
- return 0;
- }
- if(gs_wfInfo.frames >= 0 && gs_wfInfo.frames < (sf_count_t)(unsigned)MAX_U_32_NUM)
- (void) lame_set_num_samples(gfp, gs_wfInfo.frames);
- else
- (void) lame_set_num_samples(gfp, MAX_U_32_NUM);
- if (!set_input_num_channels(gfp, gs_wfInfo.channels)) {
- sf_close(gs_pSndFileIn);
- return 0;
- }
- if (!set_input_samplerate(gfp, gs_wfInfo.samplerate)) {
- sf_close(gs_pSndFileIn);
- return 0;
- }
- global. pcmbitwidth = 32;
- }
- #if 0
- if (lame_get_num_samples(gfp) == MAX_U_32_NUM) {
- /* try to figure out num_samples */
- double const flen = lame_get_file_size(lpszFileName);
- if (flen >= 0) {
- /* try file size, assume 2 bytes per sample */
- lame_set_num_samples(gfp, flen / (2 * lame_get_num_channels(gfp)));
- }
- }
- #endif
- return gs_pSndFileIn;
- }
- #endif /* defined(LIBSNDFILE) */
- /************************************************************************
- unpack_read_samples - read and unpack signed low-to-high byte or unsigned
- single byte input. (used for read_samples function)
- Output integers are stored in the native byte order
- (little or big endian). -jd
- in: samples_to_read
- bytes_per_sample
- swap_order - set for high-to-low byte order input stream
- i/o: pcm_in
- out: sample_buffer (must be allocated up to samples_to_read upon call)
- returns: number of samples read
- */
- static int
- unpack_read_samples(const int samples_to_read, const int bytes_per_sample,
- const int swap_order, int *sample_buffer, FILE * pcm_in)
- {
- int samples_read;
- int i;
- int *op; /* output pointer */
- unsigned char *ip = (unsigned char *) sample_buffer; /* input pointer */
- const int b = sizeof(int) * 8;
- {
- size_t samples_read_ = fread(sample_buffer, bytes_per_sample, samples_to_read, pcm_in);
- assert( samples_read_ <= INT_MAX );
- samples_read = (int) samples_read_;
- }
- op = sample_buffer + samples_read;
- #define GA_URS_IFLOOP( ga_urs_bps ) \
- if( bytes_per_sample == ga_urs_bps ) \
- for( i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >=0;)
- if (swap_order == 0) {
- GA_URS_IFLOOP(1)
- * --op = ip[i] << (b - 8);
- GA_URS_IFLOOP(2)
- * --op = ip[i] << (b - 16) | ip[i + 1] << (b - 8);
- GA_URS_IFLOOP(3)
- * --op = ip[i] << (b - 24) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 8);
- GA_URS_IFLOOP(4)
- * --op =
- ip[i] << (b - 32) | ip[i + 1] << (b - 24) | ip[i + 2] << (b - 16) | ip[i + 3] << (b -
- 8);
- }
- else {
- GA_URS_IFLOOP(1)
- * --op = (ip[i] ^ 0x80) << (b - 8) | 0x7f << (b - 16); /* convert from unsigned */
- GA_URS_IFLOOP(2)
- * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16);
- GA_URS_IFLOOP(3)
- * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24);
- GA_URS_IFLOOP(4)
- * --op =
- ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24) | ip[i + 3] << (b -
- 32);
- }
- #undef GA_URS_IFLOOP
- if (global.pcm_is_ieee_float) {
- ieee754_float32_t const m_max = INT_MAX;
- ieee754_float32_t const m_min = -(ieee754_float32_t) INT_MIN;
- ieee754_float32_t *x = (ieee754_float32_t *) sample_buffer;
- assert(sizeof(ieee754_float32_t) == sizeof(int));
- for (i = 0; i < samples_to_read; ++i) {
- ieee754_float32_t const u = x[i];
- int v;
- if (u >= 1) {
- v = INT_MAX;
- }
- else if (u <= -1) {
- v = INT_MIN;
- }
- else if (u >= 0) {
- v = (int) (u * m_max + 0.5f);
- }
- else {
- v = (int) (u * m_min - 0.5f);
- }
- sample_buffer[i] = v;
- }
- }
- return (samples_read);
- }
- /************************************************************************
- *
- * read_samples()
- *
- * PURPOSE: reads the PCM samples from a file to the buffer
- *
- * SEMANTICS:
- * Reads #samples_read# number of shorts from #musicin# filepointer
- * into #sample_buffer[]#. Returns the number of samples read.
- *
- ************************************************************************/
- static int
- read_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read)
- {
- int samples_read;
- int bytes_per_sample = global.pcmbitwidth / 8;
- int swap_byte_order; /* byte order of input stream */
- switch (global.pcmbitwidth) {
- case 32:
- case 24:
- case 16:
- if (global_raw_pcm.in_signed == 0) {
- if (global_ui_config.silent < 10) {
- error_printf("Unsigned input only supported with bitwidth 8\n");
- }
- return -1;
- }
- swap_byte_order = (global_raw_pcm.in_endian != ByteOrderLittleEndian) ? 1 : 0;
- if (global.pcmswapbytes) {
- swap_byte_order = !swap_byte_order;
- }
- break;
- case 8:
- swap_byte_order = global.pcm_is_unsigned_8bit;
- break;
- default:
- if (global_ui_config.silent < 10) {
- error_printf("Only 8, 16, 24 and 32 bit input files supported \n");
- }
- return -1;
- }
- if (samples_to_read < 0 || samples_to_read > 2304) {
- if (global_ui_config.silent < 10) {
- error_printf("Error: unexpected number of samples to read: %d\n", samples_to_read);
- }
- return -1;
- }
- samples_read = unpack_read_samples(samples_to_read, bytes_per_sample, swap_byte_order,
- sample_buffer, musicin);
- if (ferror(musicin)) {
- if (global_ui_config.silent < 10) {
- error_printf("Error reading input file\n");
- }
- return -1;
- }
- return samples_read;
- }
- /* AIFF Definitions */
- static int const IFF_ID_FORM = 0x464f524d; /* "FORM" */
- static int const IFF_ID_AIFF = 0x41494646; /* "AIFF" */
- static int const IFF_ID_AIFC = 0x41494643; /* "AIFC" */
- static int const IFF_ID_COMM = 0x434f4d4d; /* "COMM" */
- static int const IFF_ID_SSND = 0x53534e44; /* "SSND" */
- static int const IFF_ID_MPEG = 0x4d504547; /* "MPEG" */
- static int const IFF_ID_NONE = 0x4e4f4e45; /* "NONE" *//* AIFF-C data format */
- static int const IFF_ID_2CBE = 0x74776f73; /* "twos" *//* AIFF-C data format */
- static int const IFF_ID_2CLE = 0x736f7774; /* "sowt" *//* AIFF-C data format */
- static int const WAV_ID_RIFF = 0x52494646; /* "RIFF" */
- static int const WAV_ID_WAVE = 0x57415645; /* "WAVE" */
- static int const WAV_ID_FMT = 0x666d7420; /* "fmt " */
- static int const WAV_ID_DATA = 0x64617461; /* "data" */
- #ifndef WAVE_FORMAT_PCM
- static short const WAVE_FORMAT_PCM = 0x0001;
- #endif
- #ifndef WAVE_FORMAT_IEEE_FLOAT
- static short const WAVE_FORMAT_IEEE_FLOAT = 0x0003;
- #endif
- #ifndef WAVE_FORMAT_EXTENSIBLE
- static short const WAVE_FORMAT_EXTENSIBLE = 0xFFFE;
- #endif
- static long
- make_even_number_of_bytes_in_length(long x)
- {
- if ((x & 0x01) != 0) {
- return x + 1;
- }
- return x;
- }
- /*****************************************************************************
- *
- * Read Microsoft Wave headers
- *
- * By the time we get here the first 32-bits of the file have already been
- * read, and we're pretty sure that we're looking at a WAV file.
- *
- *****************************************************************************/
- static int
- parse_wave_header(lame_global_flags * gfp, FILE * sf)
- {
- int format_tag = 0;
- int channels = 0;
- int bits_per_sample = 0;
- int samples_per_sec = 0;
- int is_wav = 0;
- unsigned long data_length = 0, subSize = 0;
- int loop_sanity = 0;
- (void) read_32_bits_high_low(sf); /* file_length */
- if (read_32_bits_high_low(sf) != WAV_ID_WAVE)
- return -1;
- for (loop_sanity = 0; loop_sanity < 20; ++loop_sanity) {
- int type = read_32_bits_high_low(sf);
- if (type == WAV_ID_FMT) {
- subSize = read_32_bits_low_high(sf);
- subSize = make_even_number_of_bytes_in_length(subSize);
- if (subSize < 16) {
- /*DEBUGF(
- "'fmt' chunk too short (only %ld bytes)!", subSize); */
- return -1;
- }
- format_tag = read_16_bits_low_high(sf);
- subSize -= 2;
- channels = read_16_bits_low_high(sf);
- subSize -= 2;
- samples_per_sec = read_32_bits_low_high(sf);
- subSize -= 4;
- (void) read_32_bits_low_high(sf); /* avg_bytes_per_sec */
- subSize -= 4;
- (void) read_16_bits_low_high(sf); /* block_align */
- subSize -= 2;
- bits_per_sample = read_16_bits_low_high(sf);
- subSize -= 2;
- /* WAVE_FORMAT_EXTENSIBLE support */
- if ((subSize > 9) && (format_tag == WAVE_FORMAT_EXTENSIBLE)) {
- read_16_bits_low_high(sf); /* cbSize */
- read_16_bits_low_high(sf); /* ValidBitsPerSample */
- read_32_bits_low_high(sf); /* ChannelMask */
- /* SubType coincident with format_tag for PCM int or float */
- format_tag = read_16_bits_low_high(sf);
- subSize -= 10;
- }
- /* DEBUGF(" skipping %d bytes\n", subSize); */
- if (subSize > 0) {
- if (fskip(sf, (long) subSize, SEEK_CUR) != 0)
- return -1;
- };
- }
- else if (type == WAV_ID_DATA) {
- subSize = read_32_bits_low_high(sf);
- data_length = subSize;
- is_wav = 1;
- /* We've found the audio data. Read no further! */
- break;
- }
- else {
- subSize = read_32_bits_low_high(sf);
- subSize = make_even_number_of_bytes_in_length(subSize);
- if (fskip(sf, (long) subSize, SEEK_CUR) != 0) {
- return -1;
- }
- }
- }
- if (is_wav) {
- if (format_tag == 0x0050 || format_tag == 0x0055) {
- return sf_mp123;
- }
- if (format_tag != WAVE_FORMAT_PCM && format_tag != WAVE_FORMAT_IEEE_FLOAT) {
- if (global_ui_config.silent < 10) {
- error_printf("Unsupported data format: 0x%04X\n", format_tag);
- }
- return 0; /* oh no! non-supported format */
- }
- /* make sure the header is sane */
- if (!set_input_num_channels(gfp, channels))
- return 0;
- if (!set_input_samplerate(gfp, samples_per_sec))
- return 0;
- /* avoid division by zero */
- if (bits_per_sample < 1) {
- if (global_ui_config.silent < 10)
- error_printf("Unsupported bits per sample: %d\n", bits_per_sample);
- return -1;
- }
- global. pcmbitwidth = bits_per_sample;
- global. pcm_is_unsigned_8bit = 1;
- global. pcm_is_ieee_float = (format_tag == WAVE_FORMAT_IEEE_FLOAT ? 1 : 0);
- if (data_length == MAX_U_32_NUM)
- (void) lame_set_num_samples(gfp, MAX_U_32_NUM);
- else
- (void) lame_set_num_samples(gfp, data_length / (channels * ((bits_per_sample + 7) / 8)));
- return 1;
- }
- return -1;
- }
- /************************************************************************
- * aiff_check2
- *
- * PURPOSE: Checks AIFF header information to make sure it is valid.
- * returns 0 on success, 1 on errors
- ************************************************************************/
- static int
- aiff_check2(IFF_AIFF * const pcm_aiff_data)
- {
- if (pcm_aiff_data->sampleType != (unsigned long) IFF_ID_SSND) {
- if (global_ui_config.silent < 10) {
- error_printf("ERROR: input sound data is not PCM\n");
- }
- return 1;
- }
- switch (pcm_aiff_data->sampleSize) {
- case 32:
- case 24:
- case 16:
- case 8:
- break;
- default:
- if (global_ui_config.silent < 10) {
- error_printf("ERROR: input sound data is not 8, 16, 24 or 32 bits\n");
- }
- return 1;
- }
- if (pcm_aiff_data->numChannels != 1 && pcm_aiff_data->numChannels != 2) {
- if (global_ui_config.silent < 10) {
- error_printf("ERROR: input sound data is not mono or stereo\n");
- }
- return 1;
- }
- if (pcm_aiff_data->blkAlgn.blockSize != 0) {
- if (global_ui_config.silent < 10) {
- error_printf("ERROR: block size of input sound data is not 0 bytes\n");
- }
- return 1;
- }
- /* A bug, since we correctly skip the offset earlier in the code.
- if (pcm_aiff_data->blkAlgn.offset != 0) {
- error_printf("Block offset is not 0 bytes in '%s'\n", file_name);
- return 1;
- } */
- return 0;
- }
- /*****************************************************************************
- *
- * Read Audio Interchange File Format (AIFF) headers.
- *
- * By the time we get here the first 32 bits of the file have already been
- * read, and we're pretty sure that we're looking at an AIFF file.
- *
- *****************************************************************************/
- static int
- parse_aiff_header(lame_global_flags * gfp, FILE * sf)
- {
- long chunkSize = 0, subSize = 0, typeID = 0, dataType = IFF_ID_NONE;
- IFF_AIFF aiff_info;
- int seen_comm_chunk = 0, seen_ssnd_chunk = 0;
- long pcm_data_pos = -1;
- memset(&aiff_info, 0, sizeof(aiff_info));
- chunkSize = read_32_bits_high_low(sf);
- typeID = read_32_bits_high_low(sf);
- if ((typeID != IFF_ID_AIFF) && (typeID != IFF_ID_AIFC))
- return -1;
- while (chunkSize > 0) {
- long ckSize;
- int type = read_32_bits_high_low(sf);
- chunkSize -= 4;
- /* DEBUGF(
- "found chunk type %08x '%4.4s'\n", type, (char*)&type); */
- /* don't use a switch here to make it easier to use 'break' for SSND */
- if (type == IFF_ID_COMM) {
- seen_comm_chunk = seen_ssnd_chunk + 1;
- subSize = read_32_bits_high_low(sf);
- ckSize = make_even_number_of_bytes_in_length(subSize);
- chunkSize -= ckSize;
- aiff_info.numChannels = (short) read_16_bits_high_low(sf);
- ckSize -= 2;
- aiff_info.numSampleFrames = read_32_bits_high_low(sf);
- ckSize -= 4;
- aiff_info.sampleSize = (short) read_16_bits_high_low(sf);
- ckSize -= 2;
- aiff_info.sampleRate = read_ieee_extended_high_low(sf);
- ckSize -= 10;
- if (typeID == IFF_ID_AIFC) {
- dataType = read_32_bits_high_low(sf);
- ckSize -= 4;
- }
- if (fskip(sf, ckSize, SEEK_CUR) != 0)
- return -1;
- }
- else if (type == IFF_ID_SSND) {
- seen_ssnd_chunk = 1;
- subSize = read_32_bits_high_low(sf);
- ckSize = make_even_number_of_bytes_in_length(subSize);
- chunkSize -= ckSize;
- aiff_info.blkAlgn.offset = read_32_bits_high_low(sf);
- ckSize -= 4;
- aiff_info.blkAlgn.blockSize = read_32_bits_high_low(sf);
- ckSize -= 4;
- aiff_info.sampleType = IFF_ID_SSND;
- if (seen_comm_chunk > 0) {
- if (fskip(sf, (long) aiff_info.blkAlgn.offset, SEEK_CUR) != 0)
- return -1;
- /* We've found the audio data. Read no further! */
- break;
- }
- pcm_data_pos = ftell(sf);
- if (pcm_data_pos >= 0) {
- pcm_data_pos += aiff_info.blkAlgn.offset;
- }
- if (fskip(sf, ckSize, SEEK_CUR) != 0)
- return -1;
- }
- else {
- subSize = read_32_bits_high_low(sf);
- ckSize = make_even_number_of_bytes_in_length(subSize);
- chunkSize -= ckSize;
- if (fskip(sf, ckSize, SEEK_CUR) != 0)
- return -1;
- }
- }
- if (dataType == IFF_ID_2CLE) {
- global. pcmswapbytes = global_reader.swapbytes;
- }
- else if (dataType == IFF_ID_2CBE) {
- global. pcmswapbytes = !global_reader.swapbytes;
- }
- else if (dataType == IFF_ID_NONE) {
- global. pcmswapbytes = !global_reader.swapbytes;
- }
- else {
- return -1;
- }
- /* DEBUGF("Parsed AIFF %d\n", is_aiff); */
- if (seen_comm_chunk && (seen_ssnd_chunk > 0 || aiff_info.numSampleFrames == 0)) {
- /* make sure the header is sane */
- if (0 != aiff_check2(&aiff_info))
- return 0;
- if (!set_input_num_channels(gfp, aiff_info.numChannels))
- return 0;
- if (!set_input_samplerate(gfp, (int) aiff_info.sampleRate))
- return 0;
- (void) lame_set_num_samples(gfp, aiff_info.numSampleFrames);
- global. pcmbitwidth = aiff_info.sampleSize;
- global. pcm_is_unsigned_8bit = 0;
- global. pcm_is_ieee_float = 0; /* FIXME: possible ??? */
- if (pcm_data_pos >= 0) {
- if (fseek(sf, pcm_data_pos, SEEK_SET) != 0) {
- if (global_ui_config.silent < 10) {
- error_printf("Can't rewind stream to audio data position\n");
- }
- return 0;
- }
- }
- return 1;
- }
- return -1;
- }
- /************************************************************************
- *
- * parse_file_header
- *
- * PURPOSE: Read the header from a bytestream. Try to determine whether
- * it's a WAV file or AIFF without rewinding, since rewind
- * doesn't work on pipes and there's a good chance we're reading
- * from stdin (otherwise we'd probably be using libsndfile).
- *
- * When this function returns, the file offset will be positioned at the
- * beginning of the sound data.
- *
- ************************************************************************/
- static int
- parse_file_header(lame_global_flags * gfp, FILE * sf)
- {
- int type = read_32_bits_high_low(sf);
- /*
- DEBUGF(
- "First word of input stream: %08x '%4.4s'\n", type, (char*) &type);
- */
- global. count_samples_carefully = 0;
- global. pcm_is_unsigned_8bit = global_raw_pcm.in_signed == 1 ? 0 : 1;
- /*global_reader.input_format = sf_raw; commented out, because it is better to fail
- here as to encode some hundreds of input files not supported by LAME
- If you know you have RAW PCM data, use the -r switch
- */
- if (type == WAV_ID_RIFF) {
- /* It's probably a WAV file */
- int const ret = parse_wave_header(gfp, sf);
- if (ret == sf_mp123) {
- global. count_samples_carefully = 1;
- return sf_mp123;
- }
- if (ret > 0) {
- if (lame_get_num_samples(gfp) == MAX_U_32_NUM || global_reader.ignorewavlength == 1)
- {
- global. count_samples_carefully = 0;
- lame_set_num_samples(gfp, MAX_U_32_NUM);
- }
- else
- global. count_samples_carefully = 1;
- return sf_wave;
- }
- if (ret < 0) {
- if (global_ui_config.silent < 10) {
- error_printf("Warning: corrupt or unsupported WAVE format\n");
- }
- }
- }
- else if (type == IFF_ID_FORM) {
- /* It's probably an AIFF file */
- int const ret = parse_aiff_header(gfp, sf);
- if (ret > 0) {
- global. count_samples_carefully = 1;
- return sf_aiff;
- }
- if (ret < 0) {
- if (global_ui_config.silent < 10) {
- error_printf("Warning: corrupt or unsupported AIFF format\n");
- }
- }
- }
- else {
- if (global_ui_config.silent < 10) {
- error_printf("Warning: unsupported audio format\n");
- }
- }
- return sf_unknown;
- }
- static int
- open_mpeg_file_part2(lame_t gfp, FILE* musicin, char const *inPath, int *enc_delay, int *enc_padding)
- {
- #ifdef HAVE_MPGLIB
- if (-1 == lame_decode_initfile(musicin, &global_decoder.mp3input_data, enc_delay, enc_padding)) {
- if (global_ui_config.silent < 10) {
- error_printf("Error reading headers in mp3 input file %s.\n", inPath);
- }
- return 0;
- }
- #endif
- if (!set_input_num_channels(gfp, global_decoder.mp3input_data.stereo)) {
- return 0;
- }
- if (!set_input_samplerate(gfp, global_decoder.mp3input_data.samplerate)) {
- return 0;
- }
- (void) lame_set_num_samples(gfp, global_decoder.mp3input_data.nsamp);
- return 1;
- }
- static FILE *
- open_wave_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding)
- {
- FILE *musicin;
- /* set the defaults from info incase we cannot determine them from file */
- lame_set_num_samples(gfp, MAX_U_32_NUM);
- if (!strcmp(inPath, "-")) {
- lame_set_stream_binary_mode(musicin = stdin); /* Read from standard input. */
- }
- else {
- if ((musicin = lame_fopen(inPath, "rb")) == NULL) {
- if (global_ui_config.silent < 10) {
- error_printf("Could not find \"%s\".\n", inPath);
- }
- return 0;
- }
- }
- if (global_reader.input_format == sf_ogg) {
- if (global_ui_config.silent < 10) {
- error_printf("sorry, vorbis support in LAME is deprecated.\n");
- }
- close_input_file(musicin);
- return 0;
- }
- else if (global_reader.input_format == sf_raw) {
- /* assume raw PCM */
- if (global_ui_config.silent < 9) {
- console_printf("Assuming raw pcm input file");
- if (global_reader.swapbytes)
- console_printf(" : Forcing byte-swapping\n");
- else
- console_printf("\n");
- }
- global. pcmswapbytes = global_reader.swapbytes;
- }
- else {
- global_reader.input_format = parse_file_header(gfp, musicin);
- }
- if (global_reader.input_format == sf_mp123) {
- if (open_mpeg_file_part2(gfp, musicin, inPath, enc_delay, enc_padding))
- return musicin;
- close_input_file(musicin);
- return 0;
- }
- if (global_reader.input_format == sf_unknown) {
- close_input_file(musicin);
- return 0;
- }
- if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) {
- int const tmp_num_channels = lame_get_num_channels(gfp);
- double const flen = lame_get_file_size(musicin); /* try to figure out num_samples */
- if (flen >= 0 && tmp_num_channels > 0 ) {
- /* try file size, assume 2 bytes per sample */
- unsigned long fsize = (unsigned long) (flen / (2 * tmp_num_channels));
- (void) lame_set_num_samples(gfp, fsize);
- global. count_samples_carefully = 0;
- }
- }
- return musicin;
- }
- static FILE *
- open_mpeg_file(lame_t gfp, char const *inPath, int *enc_delay, int *enc_padding)
- {
- FILE *musicin;
- /* set the defaults from info incase we cannot determine them from file */
- lame_set_num_samples(gfp, MAX_U_32_NUM);
- if (strcmp(inPath, "-") == 0) {
- musicin = stdin;
- lame_set_stream_binary_mode(musicin); /* Read from standard input. */
- }
- else {
- musicin = lame_fopen(inPath, "rb");
- if (musicin == NULL) {
- if (global_ui_config.silent < 10) {
- error_printf("Could not find \"%s\".\n", inPath);
- }
- return 0;
- }
- }
- #ifdef AMIGA_MPEGA
- if (-1 == lame_decode_initfile(inPath, &global_decoder.mp3input_data)) {
- if (global_ui_config.silent < 10) {
- error_printf("Error reading headers in mp3 input file %s.\n", inPath);
- }
- close_input_file(musicin);
- return 0;
- }
- #endif
- if ( 0 == open_mpeg_file_part2(gfp, musicin, inPath, enc_delay, enc_padding) ) {
- close_input_file(musicin);
- return 0;
- }
- if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) {
- double flen = lame_get_file_size(musicin); /* try to figure out num_samples */
- if (flen >= 0) {
- /* try file size, assume 2 bytes per sample */
- if (global_decoder.mp3input_data.bitrate > 0) {
- double totalseconds =
- (flen * 8.0 / (1000.0 * global_decoder.mp3input_data.bitrate));
- unsigned long tmp_num_samples =
- (unsigned long) (totalseconds * lame_get_in_samplerate(gfp));
- (void) lame_set_num_samples(gfp, tmp_num_samples);
- global_decoder.mp3input_data.nsamp = tmp_num_samples;
- global. count_samples_carefully = 0;
- }
- }
- }
- return musicin;
- }
- static int
- close_input_file(FILE * musicin)
- {
- int ret = 0;
- if (musicin != stdin && musicin != 0) {
- ret = fclose(musicin);
- }
- if (ret != 0) {
- if (global_ui_config.silent < 10) {
- error_printf("Could not close audio input file\n");
- }
- }
- return ret;
- }
- #if defined(HAVE_MPGLIB)
- static int
- check_aid(const unsigned char *header)
- {
- return 0 == memcmp(header, "AiD\1", 4);
- }
- /*
- * Please check this and don't kill me if there's a bug
- * This is a (nearly?) complete header analysis for a MPEG-1/2/2.5 Layer I, II or III
- * data stream
- */
- static int
- is_syncword_mp123(const void *const headerptr)
- {
- const unsigned char *const p = headerptr;
- static const char abl2[16] = { 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8 };
- if ((p[0] & 0xFF) != 0xFF)
- return 0; /* first 8 bits must be '1' */
- if ((p[1] & 0xE0) != 0xE0)
- return 0; /* next 3 bits are also */
- if ((p[1] & 0x18) == 0x08)
- return 0; /* no MPEG-1, -2 or -2.5 */
- switch (p[1] & 0x06) {
- default:
- case 0x00: /* illegal Layer */
- return 0;
- case 0x02: /* Layer3 */
- if (global_reader.input_format != sf_mp3 && global_reader.input_format != sf_mp123) {
- return 0;
- }
- global_reader.input_format = sf_mp3;
- break;
- case 0x04: /* Layer2 */
- if (global_reader.input_format != sf_mp2 && global_reader.input_format != sf_mp123) {
- return 0;
- }
- global_reader.input_format = sf_mp2;
- break;
- case 0x06: /* Layer1 */
- if (global_reader.input_format != sf_mp1 && global_reader.input_format != sf_mp123) {
- return 0;
- }
- global_reader.input_format = sf_mp1;
- break;
- }
- if ((p[1] & 0x06) == 0x00)
- return 0; /* no Layer I, II and III */
- if ((p[2] & 0xF0) == 0xF0)
- return 0; /* bad bitrate */
- if ((p[2] & 0x0C) == 0x0C)
- return 0; /* no sample frequency with (32,44.1,48)/(1,2,4) */
- if ((p[1] & 0x18) == 0x18 && (p[1] & 0x06) == 0x04 && abl2[p[2] >> 4] & (1 << (p[3] >> 6)))
- return 0;
- if ((p[3] & 3) == 2)
- return 0; /* reserved enphasis mode */
- return 1;
- }
- static size_t
- lenOfId3v2Tag(unsigned char const* buf)
- {
- unsigned int b0 = buf[0] & 127;
- unsigned int b1 = buf[1] & 127;
- unsigned int b2 = buf[2] & 127;
- unsigned int b3 = buf[3] & 127;
- return (((((b0 << 7) + b1) << 7) + b2) << 7) + b3;
- }
- int
- lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding)
- {
- /* VBRTAGDATA pTagData; */
- /* int xing_header,len2,num_frames; */
- unsigned char buf[100];
- int ret;
- size_t len;
- int aid_header;
- short int pcm_l[1152], pcm_r[1152];
- int freeformat = 0;
- memset(mp3data, 0, sizeof(mp3data_struct));
- if (global.hip) {
- hip_decode_exit(global.hip);
- }
- global. hip = hip_decode_init();
- hip_set_msgf(global.hip, global_ui_config.silent < 10 ? &frontend_msgf : 0);
- hip_set_errorf(global.hip, global_ui_config.silent < 10 ? &frontend_errorf : 0);
- hip_set_debugf(global.hip, &frontend_debugf);
- len = 4;
- if (fread(buf, 1, len, fd) != len)
- return -1; /* failed */
- while (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {
- len = 6;
- if (fread(&buf[4], 1, len, fd) != len)
- return -1; /* failed */
- len = lenOfId3v2Tag(&buf[6]);
- if (global.in_id3v2_size < 1) {
- global.in_id3v2_size = 10 + len;
- global.in_id3v2_tag = malloc(global.in_id3v2_size);
- if (global.in_id3v2_tag) {
- memcpy(global.in_id3v2_tag, buf, 10);
- if (fread(&global.in_id3v2_tag[10], 1, len, fd) != len)
- return -1; /* failed */
- len = 0; /* copied, nothing to skip */
- }
- else {
- global.in_id3v2_size = 0;
- }
- }
- assert( len <= LONG_MAX );
- fskip(fd, (long) len, SEEK_CUR);
- len = 4;
- if (fread(&buf, 1, len, fd) != len)
- return -1; /* failed */
- }
- aid_header = check_aid(buf);
- if (aid_header) {
- if (fread(&buf, 1, 2, fd) != 2)
- return -1; /* failed */
- aid_header = (unsigned char) buf[0] + 256 * (unsigned char) buf[1];
- if (global_ui_config.silent < 9) {
- console_printf("Album ID found. length=%i \n", aid_header);
- }
- /* skip rest of AID, except for 6 bytes we have already read */
- fskip(fd, aid_header - 6, SEEK_CUR);
- /* read 4 more bytes to set up buffer for MP3 header check */
- if (fread(&buf, 1, len, fd) != len)
- return -1; /* failed */
- }
- len = 4;
- while (!is_syncword_mp123(buf)) {
- unsigned int i;
- for (i = 0; i < len - 1; i++)
- buf[i] = buf[i + 1];
- if (fread(buf + len - 1, 1, 1, fd) != 1)
- return -1; /* failed */
- }
- if ((buf[2] & 0xf0) == 0) {
- if (global_ui_config.silent < 9) {
- console_printf("Input file is freeformat.\n");
- }
- freeformat = 1;
- }
- /* now parse the current buffer looking for MP3 headers. */
- /* (as of 11/00: mpglib modified so that for the first frame where */
- /* headers are parsed, no data will be decoded. */
- /* However, for freeformat, we need to decode an entire frame, */
- /* so mp3data->bitrate will be 0 until we have decoded the first */
- /* frame. Cannot decode first frame here because we are not */
- /* yet prepared to handle the output. */
- ret = hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, enc_padding);
- if (-1 == ret)
- return -1;
- /* repeat until we decode a valid mp3 header. */
- while (!mp3data->header_parsed) {
- len = fread(buf, 1, sizeof(buf), fd);
- if (len != sizeof(buf))
- return -1;
- ret =
- hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay,
- enc_padding);
- if (-1 == ret)
- return -1;
- }
- if (mp3data->bitrate == 0 && !freeformat) {
- if (global_ui_config.silent < 10) {
- error_printf("fail to sync...\n");
- }
- return lame_decode_initfile(fd, mp3data, enc_delay, enc_padding);
- }
- if (mp3data->totalframes > 0) {
- /* mpglib found a Xing VBR header and computed nsamp & totalframes */
- }
- else {
- /* set as unknown. Later, we will take a guess based on file size
- * ant bitrate */
- mp3data->nsamp = MAX_U_32_NUM;
- }
- /*
- report_printf("ret = %i NEED_MORE=%i \n",ret,MP3_NEED_MORE);
- report_printf("stereo = %i \n",mp.fr.stereo);
- report_printf("samp = %i \n",freqs[mp.fr.sampling_frequency]);
- report_printf("framesize = %i \n",framesize);
- report_printf("bitrate = %i \n",mp3data->bitrate);
- report_printf("num frames = %ui \n",num_frames);
- report_printf("num samp = %ui \n",mp3data->nsamp);
- report_printf("mode = %i \n",mp.fr.mode);
- */
- return 0;
- }
- /*
- For lame_decode_fromfile: return code
- -1 error
- n number of samples output. either 576 or 1152 depending on MP3 file.
- For lame_decode1_headers(): return code
- -1 error
- 0 ok, but need more data before outputing any samples
- n number of samples output. either 576 or 1152 depending on MP3 file.
- */
- static int
- lame_decode_fromfile(FILE * fd, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
- {
- int ret = 0;
- size_t len = 0;
- unsigned char buf[1024];
- /* first see if we still have data buffered in the decoder: */
- ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
- if (ret != 0)
- return ret;
- /* read until we get a valid output frame */
- for (;;) {
- len = fread(buf, 1, 1024, fd);
- if (len == 0) {
- /* we are done reading the file, but check for buffered data */
- ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
- if (ret <= 0) {
- return -1; /* done with file */
- }
- break;
- }
- ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
- if (ret == -1) {
- return -1;
- }
- if (ret > 0)
- break;
- }
- return ret;
- }
- #endif /* defined(HAVE_MPGLIB) */
- int
- is_mpeg_file_format(int input_file_format)
- {
- switch (input_file_format) {
- case sf_mp1:
- return 1;
- case sf_mp2:
- return 2;
- case sf_mp3:
- return 3;
- case sf_mp123:
- return -1;
- default:
- break;
- }
- return 0;
- }
- #define LOW__BYTE(x) (x & 0x00ff)
- #define HIGH_BYTE(x) ((x >> 8) & 0x00ff)
- void
- put_audio16(FILE * outf, short Buffer[2][1152], int iread, int nch)
- {
- char data[2 * 1152 * 2];
- int i, m = 0;
- if (global_decoder.disable_wav_header && global_reader.swapbytes) {
- if (nch == 1) {
- for (i = 0; i < iread; i++) {
- short x = Buffer[0][i];
- /* write 16 Bits High Low */
- data[m++] = HIGH_BYTE(x);
- data[m++] = LOW__BYTE(x);
- }
- }
- else {
- for (i = 0; i < iread; i++) {
- short x = Buffer[0][i], y = Buffer[1][i];
- /* write 16 Bits High Low */
- data[m++] = HIGH_BYTE(x);
- data[m++] = LOW__BYTE(x);
- /* write 16 Bits High Low */
- data[m++] = HIGH_BYTE(y);
- data[m++] = LOW__BYTE(y);
- }
- }
- }
- else {
- if (nch == 1) {
- for (i = 0; i < iread; i++) {
- short x = Buffer[0][i];
- /* write 16 Bits Low High */
- data[m++] = LOW__BYTE(x);
- data[m++] = HIGH_BYTE(x);
- }
- }
- else {
- for (i = 0; i < iread; i++) {
- short x = Buffer[0][i], y = Buffer[1][i];
- /* write 16 Bits Low High */
- data[m++] = LOW__BYTE(x);
- data[m++] = HIGH_BYTE(x);
- /* write 16 Bits Low High */
- data[m++] = LOW__BYTE(y);
- data[m++] = HIGH_BYTE(y);
- }
- }
- }
- if (m > 0) {
- fwrite(data, 1, m, outf);
- }
- if (global_writer.flush_write == 1) {
- fflush(outf);
- }
- }
- hip_t
- get_hip(void)
- {
- return global.hip;
- }
- size_t
- sizeOfOldTag(lame_t gf)
- {
- (void) gf;
- return global.in_id3v2_size;
- }
- unsigned char*
- getOldTag(lame_t gf)
- {
- (void) gf;
- return global.in_id3v2_tag;
- }
- /* end of get_audio.c */
|