1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665 |
- /* -*- mode: C; mode: fold -*- */
- /*
- * LAME MP3 encoding engine
- *
- * Copyright (c) 1999-2000 Mark Taylor
- * Copyright (c) 2000-2005 Takehiro Tominaga
- * Copyright (c) 2000-2017 Robert Hegemann
- * Copyright (c) 2000-2005 Gabriel Bouvigne
- * Copyright (c) 2000-2004 Alexander Leidinger
- *
- * 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: lame.c,v 1.377 2017/09/26 12:14:02 robert Exp $ */
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include "lame.h"
- #include "machine.h"
- #include "encoder.h"
- #include "util.h"
- #include "lame_global_flags.h"
- #include "gain_analysis.h"
- #include "bitstream.h"
- #include "quantize_pvt.h"
- #include "set_get.h"
- #include "quantize.h"
- #include "psymodel.h"
- #include "version.h"
- #include "VbrTag.h"
- #include "tables.h"
- #if defined(__FreeBSD__) && !defined(__alpha__)
- #include <floatingpoint.h>
- #endif
- #ifdef __riscos__
- #include "asmstuff.h"
- #endif
- #ifdef __sun__
- /* woraround for SunOS 4.x, it has SEEK_* defined here */
- #include <unistd.h>
- #endif
- #define LAME_DEFAULT_QUALITY 3
- int
- is_lame_global_flags_valid(const lame_global_flags * gfp)
- {
- if (gfp == NULL)
- return 0;
- if (gfp->class_id != LAME_ID)
- return 0;
- return 1;
- }
- int
- is_lame_internal_flags_valid(const lame_internal_flags * gfc)
- {
- if (gfc == NULL)
- return 0;
- if (gfc->class_id != LAME_ID)
- return 0;
- if (gfc->lame_init_params_successful <=0)
- return 0;
- return 1;
- }
- static FLOAT
- filter_coef(FLOAT x)
- {
- if (x > 1.0)
- return 0.0;
- if (x <= 0.0)
- return 1.0;
- return cos(PI / 2 * x);
- }
- static void
- lame_init_params_ppflt(lame_internal_flags * gfc)
- {
- SessionConfig_t *const cfg = &gfc->cfg;
-
- /***************************************************************/
- /* compute info needed for polyphase filter (filter type==0, default) */
- /***************************************************************/
- int band, maxband, minband;
- FLOAT freq;
- int lowpass_band = 32;
- int highpass_band = -1;
- if (cfg->lowpass1 > 0) {
- minband = 999;
- for (band = 0; band <= 31; band++) {
- freq = band / 31.0;
- /* this band and above will be zeroed: */
- if (freq >= cfg->lowpass2) {
- lowpass_band = Min(lowpass_band, band);
- }
- if (cfg->lowpass1 < freq && freq < cfg->lowpass2) {
- minband = Min(minband, band);
- }
- }
- /* compute the *actual* transition band implemented by
- * the polyphase filter */
- if (minband == 999) {
- cfg->lowpass1 = (lowpass_band - .75) / 31.0;
- }
- else {
- cfg->lowpass1 = (minband - .75) / 31.0;
- }
- cfg->lowpass2 = lowpass_band / 31.0;
- }
- /* make sure highpass filter is within 90% of what the effective
- * highpass frequency will be */
- if (cfg->highpass2 > 0) {
- if (cfg->highpass2 < .9 * (.75 / 31.0)) {
- cfg->highpass1 = 0;
- cfg->highpass2 = 0;
- MSGF(gfc, "Warning: highpass filter disabled. " "highpass frequency too small\n");
- }
- }
- if (cfg->highpass2 > 0) {
- maxband = -1;
- for (band = 0; band <= 31; band++) {
- freq = band / 31.0;
- /* this band and below will be zereod */
- if (freq <= cfg->highpass1) {
- highpass_band = Max(highpass_band, band);
- }
- if (cfg->highpass1 < freq && freq < cfg->highpass2) {
- maxband = Max(maxband, band);
- }
- }
- /* compute the *actual* transition band implemented by
- * the polyphase filter */
- cfg->highpass1 = highpass_band / 31.0;
- if (maxband == -1) {
- cfg->highpass2 = (highpass_band + .75) / 31.0;
- }
- else {
- cfg->highpass2 = (maxband + .75) / 31.0;
- }
- }
- for (band = 0; band < 32; band++) {
- FLOAT fc1, fc2;
- freq = band / 31.0f;
- if (cfg->highpass2 > cfg->highpass1) {
- fc1 = filter_coef((cfg->highpass2 - freq) / (cfg->highpass2 - cfg->highpass1 + 1e-20));
- }
- else {
- fc1 = 1.0f;
- }
- if (cfg->lowpass2 > cfg->lowpass1) {
- fc2 = filter_coef((freq - cfg->lowpass1) / (cfg->lowpass2 - cfg->lowpass1 + 1e-20));
- }
- else {
- fc2 = 1.0f;
- }
- gfc->sv_enc.amp_filter[band] = fc1 * fc2;
- }
- }
- static void
- optimum_bandwidth(double *const lowerlimit, double *const upperlimit, const unsigned bitrate)
- {
- /*
- * Input:
- * bitrate total bitrate in kbps
- *
- * Output:
- * lowerlimit: best lowpass frequency limit for input filter in Hz
- * upperlimit: best highpass frequency limit for input filter in Hz
- */
- int table_index;
- typedef struct {
- int bitrate; /* only indicative value */
- int lowpass;
- } band_pass_t;
- const band_pass_t freq_map[] = {
- {8, 2000},
- {16, 3700},
- {24, 3900},
- {32, 5500},
- {40, 7000},
- {48, 7500},
- {56, 10000},
- {64, 11000},
- {80, 13500},
- {96, 15100},
- {112, 15600},
- {128, 17000},
- {160, 17500},
- {192, 18600},
- {224, 19400},
- {256, 19700},
- {320, 20500}
- };
- table_index = nearestBitrateFullIndex(bitrate);
- (void) freq_map[table_index].bitrate;
- *lowerlimit = freq_map[table_index].lowpass;
- /*
- * Now we try to choose a good high pass filtering frequency.
- * This value is currently not used.
- * For fu < 16 kHz: sqrt(fu*fl) = 560 Hz
- * For fu = 18 kHz: no high pass filtering
- * This gives:
- *
- * 2 kHz => 160 Hz
- * 3 kHz => 107 Hz
- * 4 kHz => 80 Hz
- * 8 kHz => 40 Hz
- * 16 kHz => 20 Hz
- * 17 kHz => 10 Hz
- * 18 kHz => 0 Hz
- *
- * These are ad hoc values and these can be optimized if a high pass is available.
- */
- /* if (f_low <= 16000)
- f_high = 16000. * 20. / f_low;
- else if (f_low <= 18000)
- f_high = 180. - 0.01 * f_low;
- else
- f_high = 0.;*/
- /*
- * When we sometimes have a good highpass filter, we can add the highpass
- * frequency to the lowpass frequency
- */
- /*if (upperlimit != NULL)
- *upperlimit = f_high;*/
- (void) upperlimit;
- }
- static int
- optimum_samplefreq(int lowpassfreq, int input_samplefreq)
- {
- /*
- * Rules:
- * - if possible, sfb21 should NOT be used
- *
- */
- int suggested_samplefreq = 44100;
- if (input_samplefreq >= 48000)
- suggested_samplefreq = 48000;
- else if (input_samplefreq >= 44100)
- suggested_samplefreq = 44100;
- else if (input_samplefreq >= 32000)
- suggested_samplefreq = 32000;
- else if (input_samplefreq >= 24000)
- suggested_samplefreq = 24000;
- else if (input_samplefreq >= 22050)
- suggested_samplefreq = 22050;
- else if (input_samplefreq >= 16000)
- suggested_samplefreq = 16000;
- else if (input_samplefreq >= 12000)
- suggested_samplefreq = 12000;
- else if (input_samplefreq >= 11025)
- suggested_samplefreq = 11025;
- else if (input_samplefreq >= 8000)
- suggested_samplefreq = 8000;
- if (lowpassfreq == -1)
- return suggested_samplefreq;
- if (lowpassfreq <= 15960)
- suggested_samplefreq = 44100;
- if (lowpassfreq <= 15250)
- suggested_samplefreq = 32000;
- if (lowpassfreq <= 11220)
- suggested_samplefreq = 24000;
- if (lowpassfreq <= 9970)
- suggested_samplefreq = 22050;
- if (lowpassfreq <= 7230)
- suggested_samplefreq = 16000;
- if (lowpassfreq <= 5420)
- suggested_samplefreq = 12000;
- if (lowpassfreq <= 4510)
- suggested_samplefreq = 11025;
- if (lowpassfreq <= 3970)
- suggested_samplefreq = 8000;
- if (input_samplefreq < suggested_samplefreq) {
- /* choose a valid MPEG sample frequency above the input sample frequency
- to avoid SFB21/12 bitrate bloat
- rh 061115
- */
- if (input_samplefreq > 44100) {
- return 48000;
- }
- if (input_samplefreq > 32000) {
- return 44100;
- }
- if (input_samplefreq > 24000) {
- return 32000;
- }
- if (input_samplefreq > 22050) {
- return 24000;
- }
- if (input_samplefreq > 16000) {
- return 22050;
- }
- if (input_samplefreq > 12000) {
- return 16000;
- }
- if (input_samplefreq > 11025) {
- return 12000;
- }
- if (input_samplefreq > 8000) {
- return 11025;
- }
- return 8000;
- }
- return suggested_samplefreq;
- }
- /* set internal feature flags. USER should not access these since
- * some combinations will produce strange results */
- static void
- lame_init_qval(lame_global_flags * gfp)
- {
- lame_internal_flags *const gfc = gfp->internal_flags;
- SessionConfig_t *const cfg = &gfc->cfg;
- switch (gfp->quality) {
- default:
- case 9: /* no psymodel, no noise shaping */
- cfg->noise_shaping = 0;
- cfg->noise_shaping_amp = 0;
- cfg->noise_shaping_stop = 0;
- cfg->use_best_huffman = 0;
- cfg->full_outer_loop = 0;
- break;
- case 8:
- gfp->quality = 7;
- /*lint --fallthrough */
- case 7: /* use psymodel (for short block and m/s switching), but no noise shapping */
- cfg->noise_shaping = 0;
- cfg->noise_shaping_amp = 0;
- cfg->noise_shaping_stop = 0;
- cfg->use_best_huffman = 0;
- cfg->full_outer_loop = 0;
- if (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) {
- cfg->full_outer_loop = -1;
- }
- break;
- case 6:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- cfg->noise_shaping_amp = 0;
- cfg->noise_shaping_stop = 0;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 0;
- cfg->full_outer_loop = 0;
- break;
- case 5:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- cfg->noise_shaping_amp = 0;
- cfg->noise_shaping_stop = 0;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 0;
- cfg->full_outer_loop = 0;
- break;
- case 4:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- cfg->noise_shaping_amp = 0;
- cfg->noise_shaping_stop = 0;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 1;
- cfg->full_outer_loop = 0;
- break;
- case 3:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- cfg->noise_shaping_amp = 1;
- cfg->noise_shaping_stop = 1;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 1;
- cfg->full_outer_loop = 0;
- break;
- case 2:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- if (gfc->sv_qnt.substep_shaping == 0)
- gfc->sv_qnt.substep_shaping = 2;
- cfg->noise_shaping_amp = 1;
- cfg->noise_shaping_stop = 1;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 1; /* inner loop */
- cfg->full_outer_loop = 0;
- break;
- case 1:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- if (gfc->sv_qnt.substep_shaping == 0)
- gfc->sv_qnt.substep_shaping = 2;
- cfg->noise_shaping_amp = 2;
- cfg->noise_shaping_stop = 1;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 1;
- cfg->full_outer_loop = 0;
- break;
- case 0:
- if (cfg->noise_shaping == 0)
- cfg->noise_shaping = 1;
- if (gfc->sv_qnt.substep_shaping == 0)
- gfc->sv_qnt.substep_shaping = 2;
- cfg->noise_shaping_amp = 2;
- cfg->noise_shaping_stop = 1;
- if (cfg->subblock_gain == -1)
- cfg->subblock_gain = 1;
- cfg->use_best_huffman = 1; /*type 2 disabled because of it slowness,
- in favor of full outer loop search */
- cfg->full_outer_loop = 1;
- break;
- }
- }
- static double
- linear_int(double a, double b, double m)
- {
- return a + m * (b - a);
- }
- /********************************************************************
- * initialize internal params based on data in gf
- * (globalflags struct filled in by calling program)
- *
- * OUTLINE:
- *
- * We first have some complex code to determine bitrate,
- * output samplerate and mode. It is complicated by the fact
- * that we allow the user to set some or all of these parameters,
- * and need to determine best possible values for the rest of them:
- *
- * 1. set some CPU related flags
- * 2. check if we are mono->mono, stereo->mono or stereo->stereo
- * 3. compute bitrate and output samplerate:
- * user may have set compression ratio
- * user may have set a bitrate
- * user may have set a output samplerate
- * 4. set some options which depend on output samplerate
- * 5. compute the actual compression ratio
- * 6. set mode based on compression ratio
- *
- * The remaining code is much simpler - it just sets options
- * based on the mode & compression ratio:
- *
- * set allow_diff_short based on mode
- * select lowpass filter based on compression ratio & mode
- * set the bitrate index, and min/max bitrates for VBR modes
- * disable VBR tag if it is not appropriate
- * initialize the bitstream
- * initialize scalefac_band data
- * set sideinfo_len (based on channels, CRC, out_samplerate)
- * write an id3v2 tag into the bitstream
- * write VBR tag into the bitstream
- * set mpeg1/2 flag
- * estimate the number of frames (based on a lot of data)
- *
- * now we set more flags:
- * nspsytune:
- * see code
- * VBR modes
- * see code
- * CBR/ABR
- * see code
- *
- * Finally, we set the algorithm flags based on the gfp->quality value
- * lame_init_qval(gfp);
- *
- ********************************************************************/
- int
- lame_init_params(lame_global_flags * gfp)
- {
- int i;
- int j;
- lame_internal_flags *gfc;
- SessionConfig_t *cfg;
- if (!is_lame_global_flags_valid(gfp))
- return -1;
- gfc = gfp->internal_flags;
- if (gfc == 0)
- return -1;
- if (is_lame_internal_flags_valid(gfc))
- return -1; /* already initialized */
- /* start updating lame internal flags */
- gfc->class_id = LAME_ID;
- gfc->lame_init_params_successful = 0; /* will be set to one, when we get through until the end */
- if (gfp->samplerate_in < 1)
- return -1; /* input sample rate makes no sense */
- if (gfp->num_channels < 1 || 2 < gfp->num_channels)
- return -1; /* number of input channels makes no sense */
- if (gfp->samplerate_out != 0) {
- int v=0;
- if (SmpFrqIndex(gfp->samplerate_out, &v) < 0)
- return -1; /* output sample rate makes no sense */
- }
- cfg = &gfc->cfg;
- cfg->enforce_min_bitrate = gfp->VBR_hard_min;
- cfg->analysis = gfp->analysis;
- if (cfg->analysis)
- gfp->write_lame_tag = 0;
- /* some file options not allowed if output is: not specified or stdout */
- if (gfc->pinfo != NULL)
- gfp->write_lame_tag = 0; /* disable Xing VBR tag */
- /* report functions */
- gfc->report_msg = gfp->report.msgf;
- gfc->report_dbg = gfp->report.debugf;
- gfc->report_err = gfp->report.errorf;
- if (gfp->asm_optimizations.amd3dnow)
- gfc->CPU_features.AMD_3DNow = has_3DNow();
- else
- gfc->CPU_features.AMD_3DNow = 0;
- if (gfp->asm_optimizations.mmx)
- gfc->CPU_features.MMX = has_MMX();
- else
- gfc->CPU_features.MMX = 0;
- if (gfp->asm_optimizations.sse) {
- gfc->CPU_features.SSE = has_SSE();
- gfc->CPU_features.SSE2 = has_SSE2();
- }
- else {
- gfc->CPU_features.SSE = 0;
- gfc->CPU_features.SSE2 = 0;
- }
- cfg->vbr = gfp->VBR;
- cfg->error_protection = gfp->error_protection;
- cfg->copyright = gfp->copyright;
- cfg->original = gfp->original;
- cfg->extension = gfp->extension;
- cfg->emphasis = gfp->emphasis;
- cfg->channels_in = gfp->num_channels;
- if (cfg->channels_in == 1)
- gfp->mode = MONO;
- cfg->channels_out = (gfp->mode == MONO) ? 1 : 2;
- if (gfp->mode != JOINT_STEREO)
- gfp->force_ms = 0; /* forced mid/side stereo for j-stereo only */
- cfg->force_ms = gfp->force_ms;
- if (cfg->vbr == vbr_off && gfp->VBR_mean_bitrate_kbps != 128 && gfp->brate == 0)
- gfp->brate = gfp->VBR_mean_bitrate_kbps;
- switch (cfg->vbr) {
- case vbr_off:
- case vbr_mtrh:
- case vbr_mt:
- /* these modes can handle free format condition */
- break;
- default:
- gfp->free_format = 0; /* mode can't be mixed with free format */
- break;
- }
- cfg->free_format = gfp->free_format;
- if (cfg->vbr == vbr_off && gfp->brate == 0) {
- /* no bitrate or compression ratio specified, use 11.025 */
- if (EQ(gfp->compression_ratio, 0))
- gfp->compression_ratio = 11.025; /* rate to compress a CD down to exactly 128000 bps */
- }
- /* find bitrate if user specify a compression ratio */
- if (cfg->vbr == vbr_off && gfp->compression_ratio > 0) {
- if (gfp->samplerate_out == 0)
- gfp->samplerate_out = map2MP3Frequency((int) (0.97 * gfp->samplerate_in)); /* round up with a margin of 3% */
- /* choose a bitrate for the output samplerate which achieves
- * specified compression ratio
- */
- gfp->brate = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->compression_ratio);
- /* we need the version for the bitrate table look up */
- cfg->samplerate_index = SmpFrqIndex(gfp->samplerate_out, &cfg->version);
- assert(cfg->samplerate_index >=0);
- if (!cfg->free_format) /* for non Free Format find the nearest allowed bitrate */
- gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, gfp->samplerate_out);
- }
- if (gfp->samplerate_out) {
- if (gfp->samplerate_out < 16000) {
- gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8);
- gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 64);
- }
- else if (gfp->samplerate_out < 32000) {
- gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8);
- gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 160);
- }
- else {
- gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 32);
- gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 320);
- }
- }
- /* WORK IN PROGRESS */
- /* mapping VBR scale to internal VBR quality settings */
- if (gfp->samplerate_out == 0 && (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh)) {
- float const qval = gfp->VBR_q + gfp->VBR_q_frac;
- struct q_map { int sr_a; float qa, qb, ta, tb; int lp; };
- struct q_map const m[9]
- = { {48000, 0.0,6.5, 0.0,6.5, 23700}
- , {44100, 0.0,6.5, 0.0,6.5, 21780}
- , {32000, 6.5,8.0, 5.2,6.5, 15800}
- , {24000, 8.0,8.5, 5.2,6.0, 11850}
- , {22050, 8.5,9.01, 5.2,6.5, 10892}
- , {16000, 9.01,9.4, 4.9,6.5, 7903}
- , {12000, 9.4,9.6, 4.5,6.0, 5928}
- , {11025, 9.6,9.9, 5.1,6.5, 5446}
- , { 8000, 9.9,10., 4.9,6.5, 3952}
- };
- for (i = 2; i < 9; ++i) {
- if (gfp->samplerate_in == m[i].sr_a) {
- if (qval < m[i].qa) {
- double d = qval / m[i].qa;
- d = d * m[i].ta;
- gfp->VBR_q = (int)d;
- gfp->VBR_q_frac = d - gfp->VBR_q;
- }
- }
- if (gfp->samplerate_in >= m[i].sr_a) {
- if (m[i].qa <= qval && qval < m[i].qb) {
- float const q_ = m[i].qb-m[i].qa;
- float const t_ = m[i].tb-m[i].ta;
- double d = m[i].ta + t_ * (qval-m[i].qa) / q_;
- gfp->VBR_q = (int)d;
- gfp->VBR_q_frac = d - gfp->VBR_q;
- gfp->samplerate_out = m[i].sr_a;
- if (gfp->lowpassfreq == 0) {
- gfp->lowpassfreq = -1;
- }
- break;
- }
- }
- }
- }
- /****************************************************************/
- /* if a filter has not been enabled, see if we should add one: */
- /****************************************************************/
- if (gfp->lowpassfreq == 0) {
- double lowpass = 16000;
- double highpass;
- switch (cfg->vbr) {
- case vbr_off:{
- optimum_bandwidth(&lowpass, &highpass, gfp->brate);
- break;
- }
- case vbr_abr:{
- optimum_bandwidth(&lowpass, &highpass, gfp->VBR_mean_bitrate_kbps);
- break;
- }
- case vbr_rh:{
- int const x[11] = {
- 19500, 19000, 18600, 18000, 17500, 16000, 15600, 14900, 12500, 10000, 3950
- };
- if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {
- double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;
- lowpass = linear_int(a, b, m);
- }
- else {
- lowpass = 19500;
- }
- break;
- }
- case vbr_mtrh:
- case vbr_mt:{
- int const x[11] = {
- 24000, 19500, 18500, 18000, 17500, 17000, 16500, 15600, 15200, 7230, 3950
- };
- if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {
- double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;
- lowpass = linear_int(a, b, m);
- }
- else {
- lowpass = 21500;
- }
- break;
- }
- default:{
- int const x[11] = {
- 19500, 19000, 18500, 18000, 17500, 16500, 15500, 14500, 12500, 9500, 3950
- };
- if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {
- double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;
- lowpass = linear_int(a, b, m);
- }
- else {
- lowpass = 19500;
- }
- }
- }
- if (gfp->mode == MONO && (cfg->vbr == vbr_off || cfg->vbr == vbr_abr))
- lowpass *= 1.5;
- gfp->lowpassfreq = lowpass;
- }
- if (gfp->samplerate_out == 0) {
- if (2 * gfp->lowpassfreq > gfp->samplerate_in) {
- gfp->lowpassfreq = gfp->samplerate_in / 2;
- }
- gfp->samplerate_out = optimum_samplefreq((int) gfp->lowpassfreq, gfp->samplerate_in);
- }
- if (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) {
- gfp->lowpassfreq = Min(24000, gfp->lowpassfreq);
- }
- else {
- gfp->lowpassfreq = Min(20500, gfp->lowpassfreq);
- }
- gfp->lowpassfreq = Min(gfp->samplerate_out / 2, gfp->lowpassfreq);
- if (cfg->vbr == vbr_off) {
- gfp->compression_ratio = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate);
- }
- if (cfg->vbr == vbr_abr) {
- gfp->compression_ratio =
- gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps);
- }
- cfg->disable_reservoir = gfp->disable_reservoir;
- cfg->lowpassfreq = gfp->lowpassfreq;
- cfg->highpassfreq = gfp->highpassfreq;
- cfg->samplerate_in = gfp->samplerate_in;
- cfg->samplerate_out = gfp->samplerate_out;
- cfg->mode_gr = cfg->samplerate_out <= 24000 ? 1 : 2; /* Number of granules per frame */
- /*
- * sample freq bitrate compression ratio
- * [kHz] [kbps/channel] for 16 bit input
- * 44.1 56 12.6
- * 44.1 64 11.025
- * 44.1 80 8.82
- * 22.05 24 14.7
- * 22.05 32 11.025
- * 22.05 40 8.82
- * 16 16 16.0
- * 16 24 10.667
- *
- */
- /*
- * For VBR, take a guess at the compression_ratio.
- * For example:
- *
- * VBR_q compression like
- * - 4.4 320 kbps/44 kHz
- * 0...1 5.5 256 kbps/44 kHz
- * 2 7.3 192 kbps/44 kHz
- * 4 8.8 160 kbps/44 kHz
- * 6 11 128 kbps/44 kHz
- * 9 14.7 96 kbps
- *
- * for lower bitrates, downsample with --resample
- */
- switch (cfg->vbr) {
- case vbr_mt:
- case vbr_rh:
- case vbr_mtrh:
- {
- /*numbers are a bit strange, but they determine the lowpass value */
- FLOAT const cmp[] = { 5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, 15, 16.5 };
- gfp->compression_ratio = cmp[gfp->VBR_q];
- }
- break;
- case vbr_abr:
- gfp->compression_ratio =
- cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps);
- break;
- default:
- gfp->compression_ratio = cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate);
- break;
- }
- /* mode = -1 (not set by user) or
- * mode = MONO (because of only 1 input channel).
- * If mode has not been set, then select J-STEREO
- */
- if (gfp->mode == NOT_SET) {
- gfp->mode = JOINT_STEREO;
- }
- cfg->mode = gfp->mode;
- /* apply user driven high pass filter */
- if (cfg->highpassfreq > 0) {
- cfg->highpass1 = 2. * cfg->highpassfreq;
- if (gfp->highpasswidth >= 0)
- cfg->highpass2 = 2. * (cfg->highpassfreq + gfp->highpasswidth);
- else /* 0% above on default */
- cfg->highpass2 = (1 + 0.00) * 2. * cfg->highpassfreq;
- cfg->highpass1 /= cfg->samplerate_out;
- cfg->highpass2 /= cfg->samplerate_out;
- }
- else {
- cfg->highpass1 = 0;
- cfg->highpass2 = 0;
- }
- /* apply user driven low pass filter */
- cfg->lowpass1 = 0;
- cfg->lowpass2 = 0;
- if (cfg->lowpassfreq > 0 && cfg->lowpassfreq < (cfg->samplerate_out / 2) ) {
- cfg->lowpass2 = 2. * cfg->lowpassfreq;
- if (gfp->lowpasswidth >= 0) {
- cfg->lowpass1 = 2. * (cfg->lowpassfreq - gfp->lowpasswidth);
- if (cfg->lowpass1 < 0) /* has to be >= 0 */
- cfg->lowpass1 = 0;
- }
- else { /* 0% below on default */
- cfg->lowpass1 = (1 - 0.00) * 2. * cfg->lowpassfreq;
- }
- cfg->lowpass1 /= cfg->samplerate_out;
- cfg->lowpass2 /= cfg->samplerate_out;
- }
- /**********************************************************************/
- /* compute info needed for polyphase filter (filter type==0, default) */
- /**********************************************************************/
- lame_init_params_ppflt(gfc);
- /*******************************************************
- * samplerate and bitrate index
- *******************************************************/
- cfg->samplerate_index = SmpFrqIndex(cfg->samplerate_out, &cfg->version);
- assert(cfg->samplerate_index >= 0);
- if (cfg->vbr == vbr_off) {
- if (cfg->free_format) {
- gfc->ov_enc.bitrate_index = 0;
- }
- else {
- gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, cfg->samplerate_out);
- gfc->ov_enc.bitrate_index = BitrateIndex(gfp->brate, cfg->version, cfg->samplerate_out);
- if (gfc->ov_enc.bitrate_index <= 0) {
- /* This never happens, because of preceding FindNearestBitrate!
- * But, set a sane value, just in case
- */
- assert(0);
- gfc->ov_enc.bitrate_index = 8;
- }
- }
- }
- else {
- gfc->ov_enc.bitrate_index = 1;
- }
- init_bit_stream_w(gfc);
- j = cfg->samplerate_index + (3 * cfg->version) + 6 * (cfg->samplerate_out < 16000);
- for (i = 0; i < SBMAX_l + 1; i++)
- gfc->scalefac_band.l[i] = sfBandIndex[j].l[i];
- for (i = 0; i < PSFB21 + 1; i++) {
- int const size = (gfc->scalefac_band.l[22] - gfc->scalefac_band.l[21]) / PSFB21;
- int const start = gfc->scalefac_band.l[21] + i * size;
- gfc->scalefac_band.psfb21[i] = start;
- }
- gfc->scalefac_band.psfb21[PSFB21] = 576;
- for (i = 0; i < SBMAX_s + 1; i++)
- gfc->scalefac_band.s[i] = sfBandIndex[j].s[i];
- for (i = 0; i < PSFB12 + 1; i++) {
- int const size = (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) / PSFB12;
- int const start = gfc->scalefac_band.s[12] + i * size;
- gfc->scalefac_band.psfb12[i] = start;
- }
- gfc->scalefac_band.psfb12[PSFB12] = 192;
- /* determine the mean bitrate for main data */
- if (cfg->mode_gr == 2) /* MPEG 1 */
- cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 17 : 4 + 32;
- else /* MPEG 2 */
- cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 9 : 4 + 17;
- if (cfg->error_protection)
- cfg->sideinfo_len += 2;
- {
- int k;
- for (k = 0; k < 19; k++)
- gfc->sv_enc.pefirbuf[k] = 700 * cfg->mode_gr * cfg->channels_out;
- if (gfp->ATHtype == -1)
- gfp->ATHtype = 4;
- }
- assert(gfp->VBR_q <= 9);
- assert(gfp->VBR_q >= 0);
- switch (cfg->vbr) {
- case vbr_mt:
- case vbr_mtrh:{
- if (gfp->strict_ISO < 0) {
- gfp->strict_ISO = MDB_MAXIMUM;
- }
- if (gfp->useTemporal < 0) {
- gfp->useTemporal = 0; /* off by default for this VBR mode */
- }
- (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0);
- /* The newer VBR code supports only a limited
- subset of quality levels:
- 9-5=5 are the same, uses x^3/4 quantization
- 4-0=0 are the same 5 plus best huffman divide code
- */
- if (gfp->quality < 0)
- gfp->quality = LAME_DEFAULT_QUALITY;
- if (gfp->quality < 5)
- gfp->quality = 0;
- if (gfp->quality > 7)
- gfp->quality = 7;
- /* sfb21 extra only with MPEG-1 at higher sampling rates
- */
- if (gfp->experimentalY)
- gfc->sv_qnt.sfb21_extra = 0;
- else
- gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000);
- break;
- }
- case vbr_rh:{
- (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0);
- /* sfb21 extra only with MPEG-1 at higher sampling rates
- */
- if (gfp->experimentalY)
- gfc->sv_qnt.sfb21_extra = 0;
- else
- gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000);
- /* VBR needs at least the output of GPSYCHO,
- * so we have to garantee that by setting a minimum
- * quality level, actually level 6 does it.
- * down to level 6
- */
- if (gfp->quality > 6)
- gfp->quality = 6;
- if (gfp->quality < 0)
- gfp->quality = LAME_DEFAULT_QUALITY;
- break;
- }
- default: /* cbr/abr */ {
- /* no sfb21 extra with CBR code
- */
- gfc->sv_qnt.sfb21_extra = 0;
- if (gfp->quality < 0)
- gfp->quality = LAME_DEFAULT_QUALITY;
- if (cfg->vbr == vbr_off)
- (void) lame_set_VBR_mean_bitrate_kbps(gfp, gfp->brate);
- /* second, set parameters depending on bitrate */
- (void) apply_preset(gfp, gfp->VBR_mean_bitrate_kbps, 0);
- gfp->VBR = cfg->vbr;
- break;
- }
- }
- /*initialize default values common for all modes */
- gfc->sv_qnt.mask_adjust = gfp->maskingadjust;
- gfc->sv_qnt.mask_adjust_short = gfp->maskingadjust_short;
- /* just another daily changing developer switch */
- if (gfp->tune) {
- gfc->sv_qnt.mask_adjust += gfp->tune_value_a;
- gfc->sv_qnt.mask_adjust_short += gfp->tune_value_a;
- }
- if (cfg->vbr != vbr_off) { /* choose a min/max bitrate for VBR */
- /* if the user didn't specify VBR_max_bitrate: */
- cfg->vbr_min_bitrate_index = 1; /* default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1) */
- cfg->vbr_max_bitrate_index = 14; /* default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) */
- if (cfg->samplerate_out < 16000)
- cfg->vbr_max_bitrate_index = 8; /* default: allow 64 kbps (MPEG-2.5) */
- if (gfp->VBR_min_bitrate_kbps) {
- gfp->VBR_min_bitrate_kbps =
- FindNearestBitrate(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out);
- cfg->vbr_min_bitrate_index =
- BitrateIndex(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out);
- if (cfg->vbr_min_bitrate_index < 0) {
- /* This never happens, because of preceding FindNearestBitrate!
- * But, set a sane value, just in case
- */
- assert(0);
- cfg->vbr_min_bitrate_index = 1;
- }
- }
- if (gfp->VBR_max_bitrate_kbps) {
- gfp->VBR_max_bitrate_kbps =
- FindNearestBitrate(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out);
- cfg->vbr_max_bitrate_index =
- BitrateIndex(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out);
- if (cfg->vbr_max_bitrate_index < 0) {
- /* This never happens, because of preceding FindNearestBitrate!
- * But, set a sane value, just in case
- */
- assert(0);
- cfg->vbr_max_bitrate_index = cfg->samplerate_out < 16000 ? 8 : 14;
- }
- }
- gfp->VBR_min_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index];
- gfp->VBR_max_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_max_bitrate_index];
- gfp->VBR_mean_bitrate_kbps =
- Min(bitrate_table[cfg->version][cfg->vbr_max_bitrate_index],
- gfp->VBR_mean_bitrate_kbps);
- gfp->VBR_mean_bitrate_kbps =
- Max(bitrate_table[cfg->version][cfg->vbr_min_bitrate_index],
- gfp->VBR_mean_bitrate_kbps);
- }
- cfg->preset = gfp->preset;
- cfg->write_lame_tag = gfp->write_lame_tag;
- gfc->sv_qnt.substep_shaping = gfp->substep_shaping;
- cfg->noise_shaping = gfp->noise_shaping;
- cfg->subblock_gain = gfp->subblock_gain;
- cfg->use_best_huffman = gfp->use_best_huffman;
- cfg->avg_bitrate = gfp->brate;
- cfg->vbr_avg_bitrate_kbps = gfp->VBR_mean_bitrate_kbps;
- cfg->compression_ratio = gfp->compression_ratio;
- /* initialize internal qval settings */
- lame_init_qval(gfp);
- /* automatic ATH adjustment on
- */
- if (gfp->athaa_type < 0)
- gfc->ATH->use_adjust = 3;
- else
- gfc->ATH->use_adjust = gfp->athaa_type;
- /* initialize internal adaptive ATH settings -jd */
- gfc->ATH->aa_sensitivity_p = pow(10.0, gfp->athaa_sensitivity / -10.0);
- if (gfp->short_blocks == short_block_not_set) {
- gfp->short_blocks = short_block_allowed;
- }
- /*Note Jan/2003: Many hardware decoders cannot handle short blocks in regular
- stereo mode unless they are coupled (same type in both channels)
- it is a rare event (1 frame per min. or so) that LAME would use
- uncoupled short blocks, so lets turn them off until we decide
- how to handle this. No other encoders allow uncoupled short blocks,
- even though it is in the standard. */
- /* rh 20040217: coupling makes no sense for mono and dual-mono streams
- */
- if (gfp->short_blocks == short_block_allowed
- && (cfg->mode == JOINT_STEREO || cfg->mode == STEREO)) {
- gfp->short_blocks = short_block_coupled;
- }
- cfg->short_blocks = gfp->short_blocks;
- if (lame_get_quant_comp(gfp) < 0)
- (void) lame_set_quant_comp(gfp, 1);
- if (lame_get_quant_comp_short(gfp) < 0)
- (void) lame_set_quant_comp_short(gfp, 0);
- if (lame_get_msfix(gfp) < 0)
- lame_set_msfix(gfp, 0);
- /* select psychoacoustic model */
- (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1);
- if (gfp->ATHtype < 0)
- gfp->ATHtype = 4;
- if (gfp->ATHcurve < 0)
- gfp->ATHcurve = 4;
- if (gfp->interChRatio < 0)
- gfp->interChRatio = 0;
- if (gfp->useTemporal < 0)
- gfp->useTemporal = 1; /* on by default */
- cfg->interChRatio = gfp->interChRatio;
- cfg->msfix = gfp->msfix;
- cfg->ATH_offset_db = 0-gfp->ATH_lower_db;
- cfg->ATH_offset_factor = powf(10.f, cfg->ATH_offset_db * 0.1f);
- cfg->ATHcurve = gfp->ATHcurve;
- cfg->ATHtype = gfp->ATHtype;
- cfg->ATHonly = gfp->ATHonly;
- cfg->ATHshort = gfp->ATHshort;
- cfg->noATH = gfp->noATH;
- cfg->quant_comp = gfp->quant_comp;
- cfg->quant_comp_short = gfp->quant_comp_short;
- cfg->use_temporal_masking_effect = gfp->useTemporal;
- if (cfg->mode == JOINT_STEREO) {
- cfg->use_safe_joint_stereo = gfp->exp_nspsytune & 2;
- }
- else {
- cfg->use_safe_joint_stereo = 0;
- }
- {
- cfg->adjust_bass_db = (gfp->exp_nspsytune >> 2) & 63;
- if (cfg->adjust_bass_db >= 32.f)
- cfg->adjust_bass_db -= 64.f;
- cfg->adjust_bass_db *= 0.25f;
- cfg->adjust_alto_db = (gfp->exp_nspsytune >> 8) & 63;
- if (cfg->adjust_alto_db >= 32.f)
- cfg->adjust_alto_db -= 64.f;
- cfg->adjust_alto_db *= 0.25f;
- cfg->adjust_treble_db = (gfp->exp_nspsytune >> 14) & 63;
- if (cfg->adjust_treble_db >= 32.f)
- cfg->adjust_treble_db -= 64.f;
- cfg->adjust_treble_db *= 0.25f;
- /* to be compatible with Naoki's original code, the next 6 bits
- * define only the amount of changing treble for sfb21 */
- cfg->adjust_sfb21_db = (gfp->exp_nspsytune >> 20) & 63;
- if (cfg->adjust_sfb21_db >= 32.f)
- cfg->adjust_sfb21_db -= 64.f;
- cfg->adjust_sfb21_db *= 0.25f;
- cfg->adjust_sfb21_db += cfg->adjust_treble_db;
- }
- /* Setting up the PCM input data transform matrix, to apply
- * user defined re-scaling, and or two-to-one channel downmix.
- */
- {
- FLOAT m[2][2] = { {1.0f, 0.0f}, {0.0f, 1.0f} };
- /* user selected scaling of the samples */
- m[0][0] *= gfp->scale;
- m[0][1] *= gfp->scale;
- m[1][0] *= gfp->scale;
- m[1][1] *= gfp->scale;
- /* user selected scaling of the channel 0 (left) samples */
- m[0][0] *= gfp->scale_left;
- m[0][1] *= gfp->scale_left;
- /* user selected scaling of the channel 1 (right) samples */
- m[1][0] *= gfp->scale_right;
- m[1][1] *= gfp->scale_right;
- /* Downsample to Mono if 2 channels in and 1 channel out */
- if (cfg->channels_in == 2 && cfg->channels_out == 1) {
- m[0][0] = 0.5f * (m[0][0] + m[1][0]);
- m[0][1] = 0.5f * (m[0][1] + m[1][1]);
- m[1][0] = 0;
- m[1][1] = 0;
- }
- cfg->pcm_transform[0][0] = m[0][0];
- cfg->pcm_transform[0][1] = m[0][1];
- cfg->pcm_transform[1][0] = m[1][0];
- cfg->pcm_transform[1][1] = m[1][1];
- }
- /* padding method as described in
- * "MPEG-Layer3 / Bitstream Syntax and Decoding"
- * by Martin Sieler, Ralph Sperschneider
- *
- * note: there is no padding for the very first frame
- *
- * Robert Hegemann 2000-06-22
- */
- gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF = 0;
- if (cfg->vbr == vbr_off)
- gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF
- = ((cfg->version + 1) * 72000L * cfg->avg_bitrate) % cfg->samplerate_out;
- (void) lame_init_bitstream(gfp);
- iteration_init(gfc);
- (void) psymodel_init(gfp);
- cfg->buffer_constraint = get_max_frame_buffer_size_by_constraint(cfg, gfp->strict_ISO);
- cfg->findReplayGain = gfp->findReplayGain;
- cfg->decode_on_the_fly = gfp->decode_on_the_fly;
- if (cfg->decode_on_the_fly)
- cfg->findPeakSample = 1;
- if (cfg->findReplayGain) {
- if (InitGainAnalysis(gfc->sv_rpg.rgdata, cfg->samplerate_out) == INIT_GAIN_ANALYSIS_ERROR) {
- /* Actually this never happens, our samplerates are the ones RG accepts!
- * But just in case, turn RG off
- */
- assert(0);
- cfg->findReplayGain = 0;
- }
- }
- #ifdef DECODE_ON_THE_FLY
- if (cfg->decode_on_the_fly && !gfp->decode_only) {
- if (gfc->hip) {
- hip_decode_exit(gfc->hip);
- }
- gfc->hip = hip_decode_init();
- /* report functions */
- hip_set_errorf(gfc->hip, gfp->report.errorf);
- hip_set_debugf(gfc->hip, gfp->report.debugf);
- hip_set_msgf(gfc->hip, gfp->report.msgf);
- }
- #endif
- /* updating lame internal flags finished successful */
- gfc->lame_init_params_successful = 1;
- return 0;
- }
- static void
- concatSep(char* dest, char const* sep, char const* str)
- {
- if (*dest != 0) strcat(dest, sep);
- strcat(dest, str);
- }
- /*
- * print_config
- *
- * Prints some selected information about the coding parameters via
- * the macro command MSGF(), which is currently mapped to lame_errorf
- * (reports via a error function?), which is a printf-like function
- * for <stderr>.
- */
- void
- lame_print_config(const lame_global_flags * gfp)
- {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- SessionConfig_t const *const cfg = &gfc->cfg;
- double const out_samplerate = cfg->samplerate_out;
- double const in_samplerate = cfg->samplerate_in;
- MSGF(gfc, "LAME %s %s (%s)\n", get_lame_version(), get_lame_os_bitness(), get_lame_url());
- #if (LAME_ALPHA_VERSION)
- MSGF(gfc, "warning: alpha versions should be used for testing only\n");
- #endif
- if (gfc->CPU_features.MMX
- || gfc->CPU_features.AMD_3DNow || gfc->CPU_features.SSE || gfc->CPU_features.SSE2) {
- char text[256] = { 0 };
- int fft_asm_used = 0;
- #ifdef HAVE_NASM
- if (gfc->CPU_features.AMD_3DNow) {
- fft_asm_used = 1;
- }
- else if (gfc->CPU_features.SSE) {
- fft_asm_used = 2;
- }
- #else
- # if defined( HAVE_XMMINTRIN_H ) && defined( MIN_ARCH_SSE )
- {
- fft_asm_used = 3;
- }
- # endif
- #endif
- if (gfc->CPU_features.MMX) {
- #ifdef MMX_choose_table
- concatSep(text, ", ", "MMX (ASM used)");
- #else
- concatSep(text, ", ", "MMX");
- #endif
- }
- if (gfc->CPU_features.AMD_3DNow) {
- concatSep(text, ", ", (fft_asm_used == 1) ? "3DNow! (ASM used)" : "3DNow!");
- }
- if (gfc->CPU_features.SSE) {
- #if defined(HAVE_XMMINTRIN_H)
- concatSep(text, ", ", "SSE (ASM used)");
- #else
- concatSep(text, ", ", (fft_asm_used == 2) ? "SSE (ASM used)" : "SSE");
- #endif
- }
- if (gfc->CPU_features.SSE2) {
- concatSep(text, ", ", (fft_asm_used == 3) ? "SSE2 (ASM used)" : "SSE2");
- }
- MSGF(gfc, "CPU features: %s\n", text);
- }
- if (cfg->channels_in == 2 && cfg->channels_out == 1 /* mono */ ) {
- MSGF(gfc, "Autoconverting from stereo to mono. Setting encoding to mono mode.\n");
- }
- if (isResamplingNecessary(cfg)) {
- MSGF(gfc, "Resampling: input %g kHz output %g kHz\n",
- 1.e-3 * in_samplerate, 1.e-3 * out_samplerate);
- }
- if (cfg->highpass2 > 0.)
- MSGF(gfc,
- "Using polyphase highpass filter, transition band: %5.0f Hz - %5.0f Hz\n",
- 0.5 * cfg->highpass1 * out_samplerate, 0.5 * cfg->highpass2 * out_samplerate);
- if (0. < cfg->lowpass1 || 0. < cfg->lowpass2) {
- MSGF(gfc,
- "Using polyphase lowpass filter, transition band: %5.0f Hz - %5.0f Hz\n",
- 0.5 * cfg->lowpass1 * out_samplerate, 0.5 * cfg->lowpass2 * out_samplerate);
- }
- else {
- MSGF(gfc, "polyphase lowpass filter disabled\n");
- }
- if (cfg->free_format) {
- MSGF(gfc, "Warning: many decoders cannot handle free format bitstreams\n");
- if (cfg->avg_bitrate > 320) {
- MSGF(gfc,
- "Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)\n");
- }
- }
- }
- /** rh:
- * some pretty printing is very welcome at this point!
- * so, if someone is willing to do so, please do it!
- * add more, if you see more...
- */
- void
- lame_print_internals(const lame_global_flags * gfp)
- {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- SessionConfig_t const *const cfg = &gfc->cfg;
- const char *pc = "";
- /* compiler/processor optimizations, operational, etc.
- */
- MSGF(gfc, "\nmisc:\n\n");
- MSGF(gfc, "\tscaling: %g\n", gfp->scale);
- MSGF(gfc, "\tch0 (left) scaling: %g\n", gfp->scale_left);
- MSGF(gfc, "\tch1 (right) scaling: %g\n", gfp->scale_right);
- switch (cfg->use_best_huffman) {
- default:
- pc = "normal";
- break;
- case 1:
- pc = "best (outside loop)";
- break;
- case 2:
- pc = "best (inside loop, slow)";
- break;
- }
- MSGF(gfc, "\thuffman search: %s\n", pc);
- MSGF(gfc, "\texperimental Y=%d\n", gfp->experimentalY);
- MSGF(gfc, "\t...\n");
- /* everything controlling the stream format
- */
- MSGF(gfc, "\nstream format:\n\n");
- switch (cfg->version) {
- case 0:
- pc = "2.5";
- break;
- case 1:
- pc = "1";
- break;
- case 2:
- pc = "2";
- break;
- default:
- pc = "?";
- break;
- }
- MSGF(gfc, "\tMPEG-%s Layer 3\n", pc);
- switch (cfg->mode) {
- case JOINT_STEREO:
- pc = "joint stereo";
- break;
- case STEREO:
- pc = "stereo";
- break;
- case DUAL_CHANNEL:
- pc = "dual channel";
- break;
- case MONO:
- pc = "mono";
- break;
- case NOT_SET:
- pc = "not set (error)";
- break;
- default:
- pc = "unknown (error)";
- break;
- }
- MSGF(gfc, "\t%d channel - %s\n", cfg->channels_out, pc);
- switch (cfg->vbr) {
- case vbr_off:
- pc = "off";
- break;
- default:
- pc = "all";
- break;
- }
- MSGF(gfc, "\tpadding: %s\n", pc);
- if (vbr_default == cfg->vbr)
- pc = "(default)";
- else if (cfg->free_format)
- pc = "(free format)";
- else
- pc = "";
- switch (cfg->vbr) {
- case vbr_off:
- MSGF(gfc, "\tconstant bitrate - CBR %s\n", pc);
- break;
- case vbr_abr:
- MSGF(gfc, "\tvariable bitrate - ABR %s\n", pc);
- break;
- case vbr_rh:
- MSGF(gfc, "\tvariable bitrate - VBR rh %s\n", pc);
- break;
- case vbr_mt:
- MSGF(gfc, "\tvariable bitrate - VBR mt %s\n", pc);
- break;
- case vbr_mtrh:
- MSGF(gfc, "\tvariable bitrate - VBR mtrh %s\n", pc);
- break;
- default:
- MSGF(gfc, "\t ?? oops, some new one ?? \n");
- break;
- }
- if (cfg->write_lame_tag)
- MSGF(gfc, "\tusing LAME Tag\n");
- MSGF(gfc, "\t...\n");
- /* everything controlling psychoacoustic settings, like ATH, etc.
- */
- MSGF(gfc, "\npsychoacoustic:\n\n");
- switch (cfg->short_blocks) {
- default:
- case short_block_not_set:
- pc = "?";
- break;
- case short_block_allowed:
- pc = "allowed";
- break;
- case short_block_coupled:
- pc = "channel coupled";
- break;
- case short_block_dispensed:
- pc = "dispensed";
- break;
- case short_block_forced:
- pc = "forced";
- break;
- }
- MSGF(gfc, "\tusing short blocks: %s\n", pc);
- MSGF(gfc, "\tsubblock gain: %d\n", cfg->subblock_gain);
- MSGF(gfc, "\tadjust masking: %g dB\n", gfc->sv_qnt.mask_adjust);
- MSGF(gfc, "\tadjust masking short: %g dB\n", gfc->sv_qnt.mask_adjust_short);
- MSGF(gfc, "\tquantization comparison: %d\n", cfg->quant_comp);
- MSGF(gfc, "\t ^ comparison short blocks: %d\n", cfg->quant_comp_short);
- MSGF(gfc, "\tnoise shaping: %d\n", cfg->noise_shaping);
- MSGF(gfc, "\t ^ amplification: %d\n", cfg->noise_shaping_amp);
- MSGF(gfc, "\t ^ stopping: %d\n", cfg->noise_shaping_stop);
- pc = "using";
- if (cfg->ATHshort)
- pc = "the only masking for short blocks";
- if (cfg->ATHonly)
- pc = "the only masking";
- if (cfg->noATH)
- pc = "not used";
- MSGF(gfc, "\tATH: %s\n", pc);
- MSGF(gfc, "\t ^ type: %d\n", cfg->ATHtype);
- MSGF(gfc, "\t ^ shape: %g%s\n", cfg->ATHcurve, " (only for type 4)");
- MSGF(gfc, "\t ^ level adjustement: %g dB\n", cfg->ATH_offset_db);
- MSGF(gfc, "\t ^ adjust type: %d\n", gfc->ATH->use_adjust);
- MSGF(gfc, "\t ^ adjust sensitivity power: %f\n", gfc->ATH->aa_sensitivity_p);
- MSGF(gfc, "\texperimental psy tunings by Naoki Shibata\n");
- MSGF(gfc, "\t adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\n",
- 10 * log10(gfc->sv_qnt.longfact[0]),
- 10 * log10(gfc->sv_qnt.longfact[7]),
- 10 * log10(gfc->sv_qnt.longfact[14]), 10 * log10(gfc->sv_qnt.longfact[21]));
- pc = cfg->use_temporal_masking_effect ? "yes" : "no";
- MSGF(gfc, "\tusing temporal masking effect: %s\n", pc);
- MSGF(gfc, "\tinterchannel masking ratio: %g\n", cfg->interChRatio);
- MSGF(gfc, "\t...\n");
- /* that's all ?
- */
- MSGF(gfc, "\n");
- return;
- }
- static void
- save_gain_values(lame_internal_flags * gfc)
- {
- SessionConfig_t const *const cfg = &gfc->cfg;
- RpgStateVar_t const *const rsv = &gfc->sv_rpg;
- RpgResult_t *const rov = &gfc->ov_rpg;
- /* save the ReplayGain value */
- if (cfg->findReplayGain) {
- FLOAT const RadioGain = (FLOAT) GetTitleGain(rsv->rgdata);
- if (NEQ(RadioGain, GAIN_NOT_ENOUGH_SAMPLES)) {
- rov->RadioGain = (int) floor(RadioGain * 10.0 + 0.5); /* round to nearest */
- }
- else {
- rov->RadioGain = 0;
- }
- }
- /* find the gain and scale change required for no clipping */
- if (cfg->findPeakSample) {
- rov->noclipGainChange = (int) ceil(log10(rov->PeakSample / 32767.0) * 20.0 * 10.0); /* round up */
- if (rov->noclipGainChange > 0) { /* clipping occurs */
- rov->noclipScale = floor((32767.0f / rov->PeakSample) * 100.0f) / 100.0f; /* round down */
- }
- else /* no clipping */
- rov->noclipScale = -1.0f;
- }
- }
- static int
- update_inbuffer_size(lame_internal_flags * gfc, const int nsamples)
- {
- EncStateVar_t *const esv = &gfc->sv_enc;
- if (esv->in_buffer_0 == 0 || esv->in_buffer_nsamples < nsamples) {
- if (esv->in_buffer_0) {
- free(esv->in_buffer_0);
- }
- if (esv->in_buffer_1) {
- free(esv->in_buffer_1);
- }
- esv->in_buffer_0 = lame_calloc(sample_t, nsamples);
- esv->in_buffer_1 = lame_calloc(sample_t, nsamples);
- esv->in_buffer_nsamples = nsamples;
- }
- if (esv->in_buffer_0 == NULL || esv->in_buffer_1 == NULL) {
- if (esv->in_buffer_0) {
- free(esv->in_buffer_0);
- }
- if (esv->in_buffer_1) {
- free(esv->in_buffer_1);
- }
- esv->in_buffer_0 = 0;
- esv->in_buffer_1 = 0;
- esv->in_buffer_nsamples = 0;
- ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
- return -2;
- }
- return 0;
- }
- static int
- calcNeeded(SessionConfig_t const * cfg)
- {
- int mf_needed;
- int pcm_samples_per_frame = 576 * cfg->mode_gr;
- /* some sanity checks */
- #if ENCDELAY < MDCTDELAY
- # error ENCDELAY is less than MDCTDELAY, see encoder.h
- #endif
- #if FFTOFFSET > BLKSIZE
- # error FFTOFFSET is greater than BLKSIZE, see encoder.h
- #endif
- mf_needed = BLKSIZE + pcm_samples_per_frame - FFTOFFSET; /* amount needed for FFT */
- /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */
- mf_needed = Max(mf_needed, 512 + pcm_samples_per_frame - 32);
- assert(MFSIZE >= mf_needed);
-
- return mf_needed;
- }
- /*
- * THE MAIN LAME ENCODING INTERFACE
- * mt 3/00
- *
- * input pcm data, output (maybe) mp3 frames.
- * This routine handles all buffering, resampling and filtering for you.
- * The required mp3buffer_size can be computed from num_samples,
- * samplerate and encoding rate, but here is a worst case estimate:
- *
- * mp3buffer_size in bytes = 1.25*num_samples + 7200
- *
- * return code = number of bytes output in mp3buffer. can be 0
- *
- * NOTE: this routine uses LAME's internal PCM data representation,
- * 'sample_t'. It should not be used by any application.
- * applications should use lame_encode_buffer(),
- * lame_encode_buffer_float()
- * lame_encode_buffer_int()
- * etc... depending on what type of data they are working with.
- */
- static int
- lame_encode_buffer_sample_t(lame_internal_flags * gfc,
- int nsamples, unsigned char *mp3buf, const int mp3buf_size)
- {
- SessionConfig_t const *const cfg = &gfc->cfg;
- EncStateVar_t *const esv = &gfc->sv_enc;
- int pcm_samples_per_frame = 576 * cfg->mode_gr;
- int mp3size = 0, ret, i, ch, mf_needed;
- int mp3out;
- sample_t *mfbuf[2];
- sample_t *in_buffer[2];
- if (gfc->class_id != LAME_ID)
- return -3;
- if (nsamples == 0)
- return 0;
- /* copy out any tags that may have been written into bitstream */
- { /* if user specifed buffer size = 0, dont check size */
- int const buf_size = mp3buf_size == 0 ? INT_MAX : mp3buf_size;
- mp3out = copy_buffer(gfc, mp3buf, buf_size, 0);
- }
- if (mp3out < 0)
- return mp3out; /* not enough buffer space */
- mp3buf += mp3out;
- mp3size += mp3out;
- in_buffer[0] = esv->in_buffer_0;
- in_buffer[1] = esv->in_buffer_1;
- mf_needed = calcNeeded(cfg);
- mfbuf[0] = esv->mfbuf[0];
- mfbuf[1] = esv->mfbuf[1];
- while (nsamples > 0) {
- sample_t const *in_buffer_ptr[2];
- int n_in = 0; /* number of input samples processed with fill_buffer */
- int n_out = 0; /* number of samples output with fill_buffer */
- /* n_in <> n_out if we are resampling */
- in_buffer_ptr[0] = in_buffer[0];
- in_buffer_ptr[1] = in_buffer[1];
- /* copy in new samples into mfbuf, with resampling */
- fill_buffer(gfc, mfbuf, &in_buffer_ptr[0], nsamples, &n_in, &n_out);
- /* compute ReplayGain of resampled input if requested */
- if (cfg->findReplayGain && !cfg->decode_on_the_fly)
- if (AnalyzeSamples
- (gfc->sv_rpg.rgdata, &mfbuf[0][esv->mf_size], &mfbuf[1][esv->mf_size], n_out,
- cfg->channels_out) == GAIN_ANALYSIS_ERROR)
- return -6;
- /* update in_buffer counters */
- nsamples -= n_in;
- in_buffer[0] += n_in;
- if (cfg->channels_out == 2)
- in_buffer[1] += n_in;
- /* update mfbuf[] counters */
- esv->mf_size += n_out;
- assert(esv->mf_size <= MFSIZE);
-
- /* lame_encode_flush may have set gfc->mf_sample_to_encode to 0
- * so we have to reinitialize it here when that happened.
- */
- if (esv->mf_samples_to_encode < 1) {
- esv->mf_samples_to_encode = ENCDELAY + POSTDELAY;
- }
- esv->mf_samples_to_encode += n_out;
- if (esv->mf_size >= mf_needed) {
- /* encode the frame. */
- /* mp3buf = pointer to current location in buffer */
- /* mp3buf_size = size of original mp3 output buffer */
- /* = 0 if we should not worry about the */
- /* buffer size because calling program is */
- /* to lazy to compute it */
- /* mp3size = size of data written to buffer so far */
- /* mp3buf_size-mp3size = amount of space avalable */
- int buf_size = mp3buf_size - mp3size;
- if (mp3buf_size == 0)
- buf_size = INT_MAX;
- ret = lame_encode_mp3_frame(gfc, mfbuf[0], mfbuf[1], mp3buf, buf_size);
- if (ret < 0)
- return ret;
- mp3buf += ret;
- mp3size += ret;
- /* shift out old samples */
- esv->mf_size -= pcm_samples_per_frame;
- esv->mf_samples_to_encode -= pcm_samples_per_frame;
- for (ch = 0; ch < cfg->channels_out; ch++)
- for (i = 0; i < esv->mf_size; i++)
- mfbuf[ch][i] = mfbuf[ch][i + pcm_samples_per_frame];
- }
- }
- assert(nsamples == 0);
- return mp3size;
- }
- enum PCMSampleType
- { pcm_short_type
- , pcm_int_type
- , pcm_long_type
- , pcm_float_type
- , pcm_double_type
- };
- static void
- lame_copy_inbuffer(lame_internal_flags* gfc,
- void const* l, void const* r, int nsamples,
- enum PCMSampleType pcm_type, int jump, FLOAT s)
- {
- SessionConfig_t const *const cfg = &gfc->cfg;
- EncStateVar_t *const esv = &gfc->sv_enc;
- sample_t* ib0 = esv->in_buffer_0;
- sample_t* ib1 = esv->in_buffer_1;
- FLOAT m[2][2];
- /* Apply user defined re-scaling */
- m[0][0] = s * cfg->pcm_transform[0][0];
- m[0][1] = s * cfg->pcm_transform[0][1];
- m[1][0] = s * cfg->pcm_transform[1][0];
- m[1][1] = s * cfg->pcm_transform[1][1];
- /* make a copy of input buffer, changing type to sample_t */
- #define COPY_AND_TRANSFORM(T) \
- { \
- T const *bl = l, *br = r; \
- int i; \
- for (i = 0; i < nsamples; i++) { \
- sample_t const xl = *bl; \
- sample_t const xr = *br; \
- sample_t const u = xl * m[0][0] + xr * m[0][1]; \
- sample_t const v = xl * m[1][0] + xr * m[1][1]; \
- ib0[i] = u; \
- ib1[i] = v; \
- bl += jump; \
- br += jump; \
- } \
- }
- switch ( pcm_type ) {
- case pcm_short_type:
- COPY_AND_TRANSFORM(short int);
- break;
- case pcm_int_type:
- COPY_AND_TRANSFORM(int);
- break;
- case pcm_long_type:
- COPY_AND_TRANSFORM(long int);
- break;
- case pcm_float_type:
- COPY_AND_TRANSFORM(float);
- break;
- case pcm_double_type:
- COPY_AND_TRANSFORM(double);
- break;
- }
- }
- static int
- lame_encode_buffer_template(lame_global_flags * gfp,
- void const* buffer_l, void const* buffer_r, const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size, enum PCMSampleType pcm_type, int aa, FLOAT norm)
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- SessionConfig_t const *const cfg = &gfc->cfg;
- if (nsamples == 0)
- return 0;
- if (update_inbuffer_size(gfc, nsamples) != 0) {
- return -2;
- }
- /* make a copy of input buffer, changing type to sample_t */
- if (cfg->channels_in > 1) {
- if (buffer_l == 0 || buffer_r == 0) {
- return 0;
- }
- lame_copy_inbuffer(gfc, buffer_l, buffer_r, nsamples, pcm_type, aa, norm);
- }
- else {
- if (buffer_l == 0) {
- return 0;
- }
- lame_copy_inbuffer(gfc, buffer_l, buffer_l, nsamples, pcm_type, aa, norm);
- }
- return lame_encode_buffer_sample_t(gfc, nsamples, mp3buf, mp3buf_size);
- }
- }
- return -3;
- }
- int
- lame_encode_buffer(lame_global_flags * gfp,
- const short int pcm_l[], const short int pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_short_type, 1, 1.0);
- }
- int
- lame_encode_buffer_float(lame_global_flags * gfp,
- const float pcm_l[], const float pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- 32768 for full scale */
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 1.0);
- }
- int
- lame_encode_buffer_ieee_float(lame_t gfp,
- const float pcm_l[], const float pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- 1.0 for full scale */
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 32767.0);
- }
- int
- lame_encode_buffer_interleaved_ieee_float(lame_t gfp,
- const float pcm[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- 1.0 for full scale */
- return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_float_type, 2, 32767.0);
- }
- int
- lame_encode_buffer_ieee_double(lame_t gfp,
- const double pcm_l[], const double pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- 1.0 for full scale */
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_double_type, 1, 32767.0);
- }
- int
- lame_encode_buffer_interleaved_ieee_double(lame_t gfp,
- const double pcm[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- 1.0 for full scale */
- return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_double_type, 2, 32767.0);
- }
- int
- lame_encode_buffer_int(lame_global_flags * gfp,
- const int pcm_l[], const int pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- MAX_INT for full scale */
- FLOAT const norm = (1.0 / (1L << (8 * sizeof(int) - 16)));
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_int_type, 1, norm);
- }
- int
- lame_encode_buffer_long2(lame_global_flags * gfp,
- const long pcm_l[], const long pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- MAX_LONG for full scale */
- FLOAT const norm = (1.0 / (1L << (8 * sizeof(long) - 16)));
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, norm);
- }
- int
- lame_encode_buffer_long(lame_global_flags * gfp,
- const long pcm_l[], const long pcm_r[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- 32768 for full scale */
- return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, 1.0);
- }
- int
- lame_encode_buffer_interleaved(lame_global_flags * gfp,
- short int pcm[], int nsamples,
- unsigned char *mp3buf, int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- MAX_SHORT for full scale */
- return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_short_type, 2, 1.0);
- }
- int
- lame_encode_buffer_interleaved_int(lame_t gfp,
- const int pcm[], const int nsamples,
- unsigned char *mp3buf, const int mp3buf_size)
- {
- /* input is assumed to be normalized to +/- MAX(int) for full scale */
- FLOAT const norm = (1.0 / (1L << (8 * sizeof(int)-16)));
- return lame_encode_buffer_template(gfp, pcm, pcm + 1, nsamples, mp3buf, mp3buf_size, pcm_int_type, 2, norm);
- }
- /*****************************************************************
- Flush mp3 buffer, pad with ancillary data so last frame is complete.
- Reset reservoir size to 0
- but keep all PCM samples and MDCT data in memory
- This option is used to break a large file into several mp3 files
- that when concatenated together will decode with no gaps
- Because we set the reservoir=0, they will also decode seperately
- with no errors.
- *********************************************************************/
- int
- lame_encode_flush_nogap(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
- {
- int rc = -3;
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- flush_bitstream(gfc);
- /* if user specifed buffer size = 0, dont check size */
- if (mp3buffer_size == 0)
- mp3buffer_size = INT_MAX;
- rc = copy_buffer(gfc, mp3buffer, mp3buffer_size, 1);
- save_gain_values(gfc);
- }
- }
- return rc;
- }
- /* called by lame_init_params. You can also call this after flush_nogap
- if you want to write new id3v2 and Xing VBR tags into the bitstream */
- int
- lame_init_bitstream(lame_global_flags * gfp)
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags *const gfc = gfp->internal_flags;
- if (gfc != 0) {
- gfc->ov_enc.frame_number = 0;
- if (gfp->write_id3tag_automatic) {
- (void) id3tag_write_v2(gfp);
- }
- /* initialize histogram data optionally used by frontend */
- memset(gfc->ov_enc.bitrate_channelmode_hist, 0,
- sizeof(gfc->ov_enc.bitrate_channelmode_hist));
- memset(gfc->ov_enc.bitrate_blocktype_hist, 0,
- sizeof(gfc->ov_enc.bitrate_blocktype_hist));
- gfc->ov_rpg.PeakSample = 0.0;
- /* Write initial VBR Header to bitstream and init VBR data */
- if (gfc->cfg.write_lame_tag)
- (void) InitVbrTag(gfp);
- return 0;
- }
- }
- return -3;
- }
- /*****************************************************************/
- /* flush internal PCM sample buffers, then mp3 buffers */
- /* then write id3 v1 tags into bitstream. */
- /*****************************************************************/
- int
- lame_encode_flush(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
- {
- lame_internal_flags *gfc;
- SessionConfig_t const *cfg;
- EncStateVar_t *esv;
- short int buffer[2][1152];
- int imp3 = 0, mp3count, mp3buffer_size_remaining;
- /* we always add POSTDELAY=288 padding to make sure granule with real
- * data can be complety decoded (because of 50% overlap with next granule */
- int end_padding;
- int frames_left;
- int samples_to_encode;
- int pcm_samples_per_frame;
- int mf_needed;
- int is_resampling_necessary;
- double resample_ratio = 1;
- if (!is_lame_global_flags_valid(gfp)) {
- return -3;
- }
- gfc = gfp->internal_flags;
- if (!is_lame_internal_flags_valid(gfc)) {
- return -3;
- }
- cfg = &gfc->cfg;
- esv = &gfc->sv_enc;
-
- /* Was flush already called? */
- if (esv->mf_samples_to_encode < 1) {
- return 0;
- }
- pcm_samples_per_frame = 576 * cfg->mode_gr;
- mf_needed = calcNeeded(cfg);
- samples_to_encode = esv->mf_samples_to_encode - POSTDELAY;
- memset(buffer, 0, sizeof(buffer));
- mp3count = 0;
- is_resampling_necessary = isResamplingNecessary(cfg);
- if (is_resampling_necessary) {
- resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out;
- /* delay due to resampling; needs to be fixed, if resampling code gets changed */
- samples_to_encode += 16. / resample_ratio;
- }
- end_padding = pcm_samples_per_frame - (samples_to_encode % pcm_samples_per_frame);
- if (end_padding < 576)
- end_padding += pcm_samples_per_frame;
- gfc->ov_enc.encoder_padding = end_padding;
-
- frames_left = (samples_to_encode + end_padding) / pcm_samples_per_frame;
- while (frames_left > 0 && imp3 >= 0) {
- int const frame_num = gfc->ov_enc.frame_number;
- int bunch = mf_needed - esv->mf_size;
- bunch *= resample_ratio;
- if (bunch > 1152) bunch = 1152;
- if (bunch < 1) bunch = 1;
- mp3buffer_size_remaining = mp3buffer_size - mp3count;
- /* if user specifed buffer size = 0, dont check size */
- if (mp3buffer_size == 0)
- mp3buffer_size_remaining = 0;
- /* send in a frame of 0 padding until all internal sample buffers
- * are flushed
- */
- imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], bunch,
- mp3buffer, mp3buffer_size_remaining);
- mp3buffer += imp3;
- mp3count += imp3;
- { /* even a single pcm sample can produce several frames!
- * for example: 1 Hz input file resampled to 8 kHz mpeg2.5
- */
- int const new_frames = gfc->ov_enc.frame_number - frame_num;
- if (new_frames > 0)
- frames_left -= new_frames;
- }
- }
- /* Set esv->mf_samples_to_encode to 0, so we may detect
- * and break loops calling it more than once in a row.
- */
- esv->mf_samples_to_encode = 0;
- if (imp3 < 0) {
- /* some type of fatal error */
- return imp3;
- }
- mp3buffer_size_remaining = mp3buffer_size - mp3count;
- /* if user specifed buffer size = 0, dont check size */
- if (mp3buffer_size == 0)
- mp3buffer_size_remaining = INT_MAX;
- /* mp3 related stuff. bit buffer might still contain some mp3 data */
- flush_bitstream(gfc);
- imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 1);
- save_gain_values(gfc);
- if (imp3 < 0) {
- /* some type of fatal error */
- return imp3;
- }
- mp3buffer += imp3;
- mp3count += imp3;
- mp3buffer_size_remaining = mp3buffer_size - mp3count;
- /* if user specifed buffer size = 0, dont check size */
- if (mp3buffer_size == 0)
- mp3buffer_size_remaining = INT_MAX;
- if (gfp->write_id3tag_automatic) {
- /* write a id3 tag to the bitstream */
- (void) id3tag_write_v1(gfp);
- imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 0);
- if (imp3 < 0) {
- return imp3;
- }
- mp3count += imp3;
- }
- #if 0
- {
- int const ed = gfc->ov_enc.encoder_delay;
- int const ep = gfc->ov_enc.encoder_padding;
- int const ns = (gfc->ov_enc.frame_number * pcm_samples_per_frame) - (ed + ep);
- double duration = ns;
- duration /= cfg->samplerate_out;
- MSGF(gfc, "frames=%d\n", gfc->ov_enc.frame_number);
- MSGF(gfc, "pcm_samples_per_frame=%d\n", pcm_samples_per_frame);
- MSGF(gfc, "encoder delay=%d\n", ed);
- MSGF(gfc, "encoder padding=%d\n", ep);
- MSGF(gfc, "sample count=%d (%g)\n", ns, cfg->samplerate_in * duration);
- MSGF(gfc, "duration=%g sec\n", duration);
- }
- #endif
- return mp3count;
- }
- /***********************************************************************
- *
- * lame_close ()
- *
- * frees internal buffers
- *
- ***********************************************************************/
- int
- lame_close(lame_global_flags * gfp)
- {
- int ret = 0;
- if (gfp && gfp->class_id == LAME_ID) {
- lame_internal_flags *const gfc = gfp->internal_flags;
- gfp->class_id = 0;
- if (NULL == gfc || gfc->class_id != LAME_ID) {
- ret = -3;
- }
- if (NULL != gfc) {
- gfc->lame_init_params_successful = 0;
- gfc->class_id = 0;
- /* this routine will free all malloc'd data in gfc, and then free gfc: */
- freegfc(gfc);
- gfp->internal_flags = NULL;
- }
- if (gfp->lame_allocated_gfp) {
- gfp->lame_allocated_gfp = 0;
- free(gfp);
- }
- }
- return ret;
- }
- /*****************************************************************/
- /* flush internal mp3 buffers, and free internal buffers */
- /*****************************************************************/
- #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
- int CDECL
- lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size);
- #else
- #endif
- int
- lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
- {
- int const ret = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
- (void) lame_close(gfp);
- return ret;
- }
- /*****************************************************************/
- /* write VBR Xing header, and ID3 version 1 tag, if asked for */
- /*****************************************************************/
- void lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream);
- void
- lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream)
- {
- lame_internal_flags *gfc;
- SessionConfig_t const *cfg;
- if (!is_lame_global_flags_valid(gfp)) {
- return;
- }
- gfc = gfp->internal_flags;
- if (!is_lame_internal_flags_valid(gfc)) {
- return;
- }
- cfg = &gfc->cfg;
- if (!cfg->write_lame_tag) {
- return;
- }
- /* Write Xing header again */
- if (fpStream && !fseek(fpStream, 0, SEEK_SET)) {
- int rc = PutVbrTag(gfp, fpStream);
- switch (rc) {
- default:
- /* OK */
- break;
- case -1:
- ERRORF(gfc, "Error: could not update LAME tag.\n");
- break;
- case -2:
- ERRORF(gfc, "Error: could not update LAME tag, file not seekable.\n");
- break;
- case -3:
- ERRORF(gfc, "Error: could not update LAME tag, file not readable.\n");
- break;
- }
- }
- }
- static int
- lame_init_internal_flags(lame_internal_flags* gfc)
- {
- if (NULL == gfc)
- return -1;
- gfc->cfg.vbr_min_bitrate_index = 1; /* not 0 ????? */
- gfc->cfg.vbr_max_bitrate_index = 13; /* not 14 ????? */
- gfc->cfg.decode_on_the_fly = 0;
- gfc->cfg.findReplayGain = 0;
- gfc->cfg.findPeakSample = 0;
- gfc->sv_qnt.OldValue[0] = 180;
- gfc->sv_qnt.OldValue[1] = 180;
- gfc->sv_qnt.CurrentStep[0] = 4;
- gfc->sv_qnt.CurrentStep[1] = 4;
- gfc->sv_qnt.masking_lower = 1;
- /* The reason for
- * int mf_samples_to_encode = ENCDELAY + POSTDELAY;
- * ENCDELAY = internal encoder delay. And then we have to add POSTDELAY=288
- * because of the 50% MDCT overlap. A 576 MDCT granule decodes to
- * 1152 samples. To synthesize the 576 samples centered under this granule
- * we need the previous granule for the first 288 samples (no problem), and
- * the next granule for the next 288 samples (not possible if this is last
- * granule). So we need to pad with 288 samples to make sure we can
- * encode the 576 samples we are interested in.
- */
- gfc->sv_enc.mf_samples_to_encode = ENCDELAY + POSTDELAY;
- gfc->sv_enc.mf_size = ENCDELAY - MDCTDELAY; /* we pad input with this many 0's */
- gfc->ov_enc.encoder_padding = 0;
- gfc->ov_enc.encoder_delay = ENCDELAY;
- gfc->ov_rpg.RadioGain = 0;
- gfc->ov_rpg.noclipGainChange = 0;
- gfc->ov_rpg.noclipScale = -1.0;
- gfc->ATH = lame_calloc(ATH_t, 1);
- if (NULL == gfc->ATH)
- return -2; /* maybe error codes should be enumerated in lame.h ?? */
- gfc->sv_rpg.rgdata = lame_calloc(replaygain_t, 1);
- if (NULL == gfc->sv_rpg.rgdata) {
- return -2;
- }
- return 0;
- }
- /* initialize mp3 encoder */
- #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
- static
- #else
- #endif
- int
- lame_init_old(lame_global_flags * gfp)
- {
- disable_FPE(); /* disable floating point exceptions */
- memset(gfp, 0, sizeof(lame_global_flags));
- gfp->class_id = LAME_ID;
- /* Global flags. set defaults here for non-zero values */
- /* see lame.h for description */
- /* set integer values to -1 to mean that LAME will compute the
- * best value, UNLESS the calling program as set it
- * (and the value is no longer -1)
- */
- gfp->strict_ISO = MDB_MAXIMUM;
- gfp->mode = NOT_SET;
- gfp->original = 1;
- gfp->samplerate_in = 44100;
- gfp->num_channels = 2;
- gfp->num_samples = MAX_U_32_NUM;
- gfp->write_lame_tag = 1;
- gfp->quality = -1;
- gfp->short_blocks = short_block_not_set;
- gfp->subblock_gain = -1;
- gfp->lowpassfreq = 0;
- gfp->highpassfreq = 0;
- gfp->lowpasswidth = -1;
- gfp->highpasswidth = -1;
- gfp->VBR = vbr_off;
- gfp->VBR_q = 4;
- gfp->VBR_mean_bitrate_kbps = 128;
- gfp->VBR_min_bitrate_kbps = 0;
- gfp->VBR_max_bitrate_kbps = 0;
- gfp->VBR_hard_min = 0;
- gfp->quant_comp = -1;
- gfp->quant_comp_short = -1;
- gfp->msfix = -1;
- gfp->attackthre = -1;
- gfp->attackthre_s = -1;
- gfp->scale = 1;
- gfp->scale_left = 1;
- gfp->scale_right = 1;
- gfp->ATHcurve = -1;
- gfp->ATHtype = -1; /* default = -1 = set in lame_init_params */
- /* 2 = equal loudness curve */
- gfp->athaa_sensitivity = 0.0; /* no offset */
- gfp->athaa_type = -1;
- gfp->useTemporal = -1;
- gfp->interChRatio = -1;
- gfp->findReplayGain = 0;
- gfp->decode_on_the_fly = 0;
- gfp->asm_optimizations.mmx = 1;
- gfp->asm_optimizations.amd3dnow = 1;
- gfp->asm_optimizations.sse = 1;
- gfp->preset = 0;
- gfp->write_id3tag_automatic = 1;
- gfp->report.debugf = &lame_report_def;
- gfp->report.errorf = &lame_report_def;
- gfp->report.msgf = &lame_report_def;
- gfp->internal_flags = lame_calloc(lame_internal_flags, 1);
- if (lame_init_internal_flags(gfp->internal_flags) < 0) {
- freegfc(gfp->internal_flags);
- gfp->internal_flags = 0;
- return -1;
- }
- return 0;
- }
- lame_global_flags *
- lame_init(void)
- {
- lame_global_flags *gfp;
- int ret;
- init_log_table();
- gfp = lame_calloc(lame_global_flags, 1);
- if (gfp == NULL)
- return NULL;
- ret = lame_init_old(gfp);
- if (ret != 0) {
- free(gfp);
- return NULL;
- }
- gfp->lame_allocated_gfp = 1;
- return gfp;
- }
- /***********************************************************************
- *
- * some simple statistics
- *
- * Robert Hegemann 2000-10-11
- *
- ***********************************************************************/
- /* histogram of used bitrate indexes:
- * One has to weight them to calculate the average bitrate in kbps
- *
- * bitrate indices:
- * there are 14 possible bitrate indices, 0 has the special meaning
- * "free format" which is not possible to mix with VBR and 15 is forbidden
- * anyway.
- *
- * stereo modes:
- * 0: LR number of left-right encoded frames
- * 1: LR-I number of left-right and intensity encoded frames
- * 2: MS number of mid-side encoded frames
- * 3: MS-I number of mid-side and intensity encoded frames
- *
- * 4: number of encoded frames
- *
- */
- void
- lame_bitrate_kbps(const lame_global_flags * gfp, int bitrate_kbps[14])
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- SessionConfig_t const *const cfg = &gfc->cfg;
- int i;
- if (cfg->free_format) {
- for (i = 0; i < 14; i++)
- bitrate_kbps[i] = -1;
- bitrate_kbps[0] = cfg->avg_bitrate;
- }
- else {
- for (i = 0; i < 14; i++)
- bitrate_kbps[i] = bitrate_table[cfg->version][i + 1];
- }
- }
- }
- }
- void
- lame_bitrate_hist(const lame_global_flags * gfp, int bitrate_count[14])
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- SessionConfig_t const *const cfg = &gfc->cfg;
- EncResult_t const *const eov = &gfc->ov_enc;
- int i;
- if (cfg->free_format) {
- for (i = 0; i < 14; i++) {
- bitrate_count[i] = 0;
- }
- bitrate_count[0] = eov->bitrate_channelmode_hist[0][4];
- }
- else {
- for (i = 0; i < 14; i++) {
- bitrate_count[i] = eov->bitrate_channelmode_hist[i + 1][4];
- }
- }
- }
- }
- }
- void
- lame_stereo_mode_hist(const lame_global_flags * gfp, int stmode_count[4])
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- EncResult_t const *const eov = &gfc->ov_enc;
- int i;
- for (i = 0; i < 4; i++) {
- stmode_count[i] = eov->bitrate_channelmode_hist[15][i];
- }
- }
- }
- }
- void
- lame_bitrate_stereo_mode_hist(const lame_global_flags * gfp, int bitrate_stmode_count[14][4])
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- SessionConfig_t const *const cfg = &gfc->cfg;
- EncResult_t const *const eov = &gfc->ov_enc;
- int i;
- int j;
- if (cfg->free_format) {
- for (j = 0; j < 14; j++)
- for (i = 0; i < 4; i++) {
- bitrate_stmode_count[j][i] = 0;
- }
- for (i = 0; i < 4; i++) {
- bitrate_stmode_count[0][i] = eov->bitrate_channelmode_hist[0][i];
- }
- }
- else {
- for (j = 0; j < 14; j++) {
- for (i = 0; i < 4; i++) {
- bitrate_stmode_count[j][i] = eov->bitrate_channelmode_hist[j + 1][i];
- }
- }
- }
- }
- }
- }
- void
- lame_block_type_hist(const lame_global_flags * gfp, int btype_count[6])
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- EncResult_t const *const eov = &gfc->ov_enc;
- int i;
- for (i = 0; i < 6; ++i) {
- btype_count[i] = eov->bitrate_blocktype_hist[15][i];
- }
- }
- }
- }
- void
- lame_bitrate_block_type_hist(const lame_global_flags * gfp, int bitrate_btype_count[14][6])
- {
- if (is_lame_global_flags_valid(gfp)) {
- lame_internal_flags const *const gfc = gfp->internal_flags;
- if (is_lame_internal_flags_valid(gfc)) {
- SessionConfig_t const *const cfg = &gfc->cfg;
- EncResult_t const *const eov = &gfc->ov_enc;
- int i, j;
- if (cfg->free_format) {
- for (j = 0; j < 14; ++j) {
- for (i = 0; i < 6; ++i) {
- bitrate_btype_count[j][i] = 0;
- }
- }
- for (i = 0; i < 6; ++i) {
- bitrate_btype_count[0][i] = eov->bitrate_blocktype_hist[0][i];
- }
- }
- else {
- for (j = 0; j < 14; ++j) {
- for (i = 0; i < 6; ++i) {
- bitrate_btype_count[j][i] = eov->bitrate_blocktype_hist[j + 1][i];
- }
- }
- }
- }
- }
- }
- /* end of lame.c */
|