Path: blob/master/libs/mpg123/src/libmpg123/synth_real.c
4394 views
/*1synth_real.c: The functions for synthesizing real (float) samples, at the end of decoding.23copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.14see COPYING and AUTHORS files in distribution or http://mpg123.org5initially written by Michael Hipp, heavily dissected and rearranged by Thomas Orgis6*/78#include "mpg123lib_intern.h"9#include "../common/sample.h"10#include "../common/debug.h"1112#ifdef REAL_IS_FIXED13#error "Do not build this file with fixed point math!"14#else15/*16Part 3: All synth functions that produce float output.17What we need is just a special WRITE_SAMPLE. For the generic and i386 functions, that is.18The optimized synths would need to be changed internally to support float output.19*/2021#define SAMPLE_T real22#define WRITE_SAMPLE(samples,sum,clip) WRITE_REAL_SAMPLE(samples,sum,clip)2324/* Part 3a: All straight 1to1 decoding functions */25#define BLOCK 0x40 /* One decoding block is 64 samples. */2627#define SYNTH_NAME INT123_synth_1to1_real28#include "synth.h"29#undef SYNTH_NAME3031/* Mono-related synths; they wrap over _some_ INT123_synth_1to1_real (could be generic, could be i386). */32#define SYNTH_NAME fr->synths.plain[r_1to1][f_real]33#define MONO_NAME INT123_synth_1to1_real_mono34#define MONO2STEREO_NAME INT123_synth_1to1_real_m2s35#include "synth_mono.h"36#undef SYNTH_NAME37#undef MONO_NAME38#undef MONO2STEREO_NAME3940#ifdef OPT_X8641#define NO_AUTOINCREMENT42#define SYNTH_NAME INT123_synth_1to1_real_i38643#include "synth.h"44#undef SYNTH_NAME45/* i386 uses the normal mono functions. */46#undef NO_AUTOINCREMENT47#endif4849#undef BLOCK5051/* At least one optimized real decoder... */52#ifdef OPT_X86_6453/* Assembler routines. */54int INT123_synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1);55int INT123_synth_1to1_real_s_x86_64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);56void INT123_dct64_real_x86_64(real *out0, real *out1, real *samples);57/* Hull for C mpg123 API */58int INT123_synth_1to1_real_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)59{60real *samples = (real *) (fr->buffer.data+fr->buffer.fill);6162real *b0, **buf;63int bo1;64#ifndef NO_EQUALIZER65if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);66#endif67if(!channel)68{69fr->bo--;70fr->bo &= 0xf;71buf = fr->real_buffs[0];72}73else74{75samples++;76buf = fr->real_buffs[1];77}7879if(fr->bo & 0x1)80{81b0 = buf[0];82bo1 = fr->bo;83INT123_dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);84}85else86{87b0 = buf[1];88bo1 = fr->bo+1;89INT123_dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);90}9192INT123_synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1);9394if(final) fr->buffer.fill += 256;9596return 0;97}9899int INT123_synth_1to1_real_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)100{101real *samples = (real *) (fr->buffer.data+fr->buffer.fill);102103real *b0l, *b0r, **bufl, **bufr;104int bo1;105#ifndef NO_EQUALIZER106if(fr->have_eq_settings)107{108INT123_do_equalizer(bandPtr_l,0,fr->equalizer);109INT123_do_equalizer(bandPtr_r,1,fr->equalizer);110}111#endif112fr->bo--;113fr->bo &= 0xf;114bufl = fr->real_buffs[0];115bufr = fr->real_buffs[1];116117if(fr->bo & 0x1)118{119b0l = bufl[0];120b0r = bufr[0];121bo1 = fr->bo;122INT123_dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);123INT123_dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);124}125else126{127b0l = bufl[1];128b0r = bufr[1];129bo1 = fr->bo+1;130INT123_dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);131INT123_dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);132}133134INT123_synth_1to1_real_s_x86_64_asm(fr->decwin, b0l, b0r, samples, bo1);135136fr->buffer.fill += 256;137138return 0;139}140#endif141142#ifdef OPT_AVX143/* Assembler routines. */144#ifndef OPT_X86_64145int INT123_synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1);146#endif147int INT123_synth_1to1_real_s_avx_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);148void INT123_dct64_real_avx(real *out0, real *out1, real *samples);149/* Hull for C mpg123 API */150int INT123_synth_1to1_real_avx(real *bandPtr,int channel, mpg123_handle *fr, int final)151{152real *samples = (real *) (fr->buffer.data+fr->buffer.fill);153154real *b0, **buf;155int bo1;156#ifndef NO_EQUALIZER157if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);158#endif159if(!channel)160{161fr->bo--;162fr->bo &= 0xf;163buf = fr->real_buffs[0];164}165else166{167samples++;168buf = fr->real_buffs[1];169}170171if(fr->bo & 0x1)172{173b0 = buf[0];174bo1 = fr->bo;175INT123_dct64_real_avx(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);176}177else178{179b0 = buf[1];180bo1 = fr->bo+1;181INT123_dct64_real_avx(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);182}183184INT123_synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1);185186if(final) fr->buffer.fill += 256;187188return 0;189}190191int INT123_synth_1to1_fltst_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)192{193real *samples = (real *) (fr->buffer.data+fr->buffer.fill);194195real *b0l, *b0r, **bufl, **bufr;196int bo1;197#ifndef NO_EQUALIZER198if(fr->have_eq_settings)199{200INT123_do_equalizer(bandPtr_l,0,fr->equalizer);201INT123_do_equalizer(bandPtr_r,1,fr->equalizer);202}203#endif204fr->bo--;205fr->bo &= 0xf;206bufl = fr->real_buffs[0];207bufr = fr->real_buffs[1];208209if(fr->bo & 0x1)210{211b0l = bufl[0];212b0r = bufr[0];213bo1 = fr->bo;214INT123_dct64_real_avx(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);215INT123_dct64_real_avx(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);216}217else218{219b0l = bufl[1];220b0r = bufr[1];221bo1 = fr->bo+1;222INT123_dct64_real_avx(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);223INT123_dct64_real_avx(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);224}225226INT123_synth_1to1_real_s_avx_asm(fr->decwin, b0l, b0r, samples, bo1);227228fr->buffer.fill += 256;229230return 0;231}232#endif233234#if defined(OPT_SSE) || defined(OPT_SSE_VINTAGE)235/* Assembler routines. */236int INT123_synth_1to1_real_sse_asm(real *window, real *b0, real *samples, int bo1);237int INT123_synth_1to1_real_s_sse_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);238void INT123_dct64_real_sse(real *out0, real *out1, real *samples);239/* Hull for C mpg123 API */240int INT123_synth_1to1_real_sse(real *bandPtr,int channel, mpg123_handle *fr, int final)241{242real *samples = (real *) (fr->buffer.data+fr->buffer.fill);243244real *b0, **buf;245int bo1;246#ifndef NO_EQUALIZER247if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);248#endif249if(!channel)250{251fr->bo--;252fr->bo &= 0xf;253buf = fr->real_buffs[0];254}255else256{257samples++;258buf = fr->real_buffs[1];259}260261if(fr->bo & 0x1)262{263b0 = buf[0];264bo1 = fr->bo;265INT123_dct64_real_sse(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);266}267else268{269b0 = buf[1];270bo1 = fr->bo+1;271INT123_dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);272}273274INT123_synth_1to1_real_sse_asm(fr->decwin, b0, samples, bo1);275276if(final) fr->buffer.fill += 256;277278return 0;279}280281int INT123_synth_1to1_real_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)282{283real *samples = (real *) (fr->buffer.data+fr->buffer.fill);284285real *b0l, *b0r, **bufl, **bufr;286int bo1;287#ifndef NO_EQUALIZER288if(fr->have_eq_settings)289{290INT123_do_equalizer(bandPtr_l,0,fr->equalizer);291INT123_do_equalizer(bandPtr_r,1,fr->equalizer);292}293#endif294fr->bo--;295fr->bo &= 0xf;296bufl = fr->real_buffs[0];297bufr = fr->real_buffs[1];298299if(fr->bo & 0x1)300{301b0l = bufl[0];302b0r = bufr[0];303bo1 = fr->bo;304INT123_dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);305INT123_dct64_real_sse(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);306}307else308{309b0l = bufl[1];310b0r = bufr[1];311bo1 = fr->bo+1;312INT123_dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);313INT123_dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);314}315316INT123_synth_1to1_real_s_sse_asm(fr->decwin, b0l, b0r, samples, bo1);317318fr->buffer.fill += 256;319320return 0;321}322#endif323324#ifdef OPT_NEON325/* Assembler routines. */326int INT123_synth_1to1_real_neon_asm(real *window, real *b0, real *samples, int bo1);327int INT123_synth_1to1_real_s_neon_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);328void INT123_dct64_real_neon(real *out0, real *out1, real *samples);329/* Hull for C mpg123 API */330int INT123_synth_1to1_real_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)331{332real *samples = (real *) (fr->buffer.data+fr->buffer.fill);333334real *b0, **buf;335int bo1;336#ifndef NO_EQUALIZER337if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);338#endif339if(!channel)340{341fr->bo--;342fr->bo &= 0xf;343buf = fr->real_buffs[0];344}345else346{347samples++;348buf = fr->real_buffs[1];349}350351if(fr->bo & 0x1)352{353b0 = buf[0];354bo1 = fr->bo;355INT123_dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);356}357else358{359b0 = buf[1];360bo1 = fr->bo+1;361INT123_dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);362}363364INT123_synth_1to1_real_neon_asm(fr->decwin, b0, samples, bo1);365366if(final) fr->buffer.fill += 256;367368return 0;369}370int INT123_synth_1to1_real_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)371{372real *samples = (real *) (fr->buffer.data+fr->buffer.fill);373374real *b0l, *b0r, **bufl, **bufr;375int bo1;376#ifndef NO_EQUALIZER377if(fr->have_eq_settings)378{379INT123_do_equalizer(bandPtr_l,0,fr->equalizer);380INT123_do_equalizer(bandPtr_r,1,fr->equalizer);381}382#endif383fr->bo--;384fr->bo &= 0xf;385bufl = fr->real_buffs[0];386bufr = fr->real_buffs[1];387388if(fr->bo & 0x1)389{390b0l = bufl[0];391b0r = bufr[0];392bo1 = fr->bo;393INT123_dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);394INT123_dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);395}396else397{398b0l = bufl[1];399b0r = bufr[1];400bo1 = fr->bo+1;401INT123_dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);402INT123_dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);403}404405INT123_synth_1to1_real_s_neon_asm(fr->decwin, b0l, b0r, samples, bo1);406407fr->buffer.fill += 256;408409return 0;410}411#endif412413#ifdef OPT_NEON64414/* Assembler routines. */415int INT123_synth_1to1_real_neon64_asm(real *window, real *b0, real *samples, int bo1);416int INT123_synth_1to1_real_s_neon64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);417void INT123_dct64_real_neon64(real *out0, real *out1, real *samples);418/* Hull for C mpg123 API */419int INT123_synth_1to1_real_neon64(real *bandPtr,int channel, mpg123_handle *fr, int final)420{421real *samples = (real *) (fr->buffer.data+fr->buffer.fill);422423real *b0, **buf;424int bo1;425#ifndef NO_EQUALIZER426if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);427#endif428if(!channel)429{430fr->bo--;431fr->bo &= 0xf;432buf = fr->real_buffs[0];433}434else435{436samples++;437buf = fr->real_buffs[1];438}439440if(fr->bo & 0x1)441{442b0 = buf[0];443bo1 = fr->bo;444INT123_dct64_real_neon64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);445}446else447{448b0 = buf[1];449bo1 = fr->bo+1;450INT123_dct64_real_neon64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);451}452453INT123_synth_1to1_real_neon64_asm(fr->decwin, b0, samples, bo1);454455if(final) fr->buffer.fill += 256;456457return 0;458}459int INT123_synth_1to1_fltst_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)460{461real *samples = (real *) (fr->buffer.data+fr->buffer.fill);462463real *b0l, *b0r, **bufl, **bufr;464int bo1;465#ifndef NO_EQUALIZER466if(fr->have_eq_settings)467{468INT123_do_equalizer(bandPtr_l,0,fr->equalizer);469INT123_do_equalizer(bandPtr_r,1,fr->equalizer);470}471#endif472fr->bo--;473fr->bo &= 0xf;474bufl = fr->real_buffs[0];475bufr = fr->real_buffs[1];476477if(fr->bo & 0x1)478{479b0l = bufl[0];480b0r = bufr[0];481bo1 = fr->bo;482INT123_dct64_real_neon64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);483INT123_dct64_real_neon64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);484}485else486{487b0l = bufl[1];488b0r = bufr[1];489bo1 = fr->bo+1;490INT123_dct64_real_neon64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);491INT123_dct64_real_neon64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);492}493494INT123_synth_1to1_real_s_neon64_asm(fr->decwin, b0l, b0r, samples, bo1);495496fr->buffer.fill += 256;497498return 0;499}500#endif501502#ifndef NO_DOWNSAMPLE503504/*505Part 3b: 2to1 synth. Only generic and i386.506*/507#define BLOCK 0x20 /* One decoding block is 32 samples. */508509#define SYNTH_NAME INT123_synth_2to1_real510#include "synth.h"511#undef SYNTH_NAME512513/* Mono-related synths; they wrap over _some_ INT123_synth_2to1_real (could be generic, could be i386). */514#define SYNTH_NAME fr->synths.plain[r_2to1][f_real]515#define MONO_NAME INT123_synth_2to1_real_mono516#define MONO2STEREO_NAME INT123_synth_2to1_real_m2s517#include "synth_mono.h"518#undef SYNTH_NAME519#undef MONO_NAME520#undef MONO2STEREO_NAME521522#ifdef OPT_X86523#define NO_AUTOINCREMENT524#define SYNTH_NAME INT123_synth_2to1_real_i386525#include "synth.h"526#undef SYNTH_NAME527/* i386 uses the normal mono functions. */528#undef NO_AUTOINCREMENT529#endif530531#undef BLOCK532533/*534Part 3c: 4to1 synth. Only generic and i386.535*/536#define BLOCK 0x10 /* One decoding block is 16 samples. */537538#define SYNTH_NAME INT123_synth_4to1_real539#include "synth.h"540#undef SYNTH_NAME541542/* Mono-related synths; they wrap over _some_ INT123_synth_4to1_real (could be generic, could be i386). */543#define SYNTH_NAME fr->synths.plain[r_4to1][f_real]544#define MONO_NAME INT123_synth_4to1_real_mono545#define MONO2STEREO_NAME INT123_synth_4to1_real_m2s546#include "synth_mono.h"547#undef SYNTH_NAME548#undef MONO_NAME549#undef MONO2STEREO_NAME550551#ifdef OPT_X86552#define NO_AUTOINCREMENT553#define SYNTH_NAME INT123_synth_4to1_real_i386554#include "synth.h"555#undef SYNTH_NAME556/* i386 uses the normal mono functions. */557#undef NO_AUTOINCREMENT558#endif559560#undef BLOCK561562#endif /* NO_DOWNSAMPLE */563564#ifndef NO_NTOM565/*566Part 3d: ntom synth.567Same procedure as above... Just no extra play anymore, straight synth that may use an optimized INT123_dct64.568*/569570/* These are all in one header, there's no flexibility to gain. */571#define SYNTH_NAME INT123_synth_ntom_real572#define MONO_NAME INT123_synth_ntom_real_mono573#define MONO2STEREO_NAME INT123_synth_ntom_real_m2s574#include "synth_ntom.h"575#undef SYNTH_NAME576#undef MONO_NAME577#undef MONO2STEREO_NAME578579#endif580581#undef SAMPLE_T582#undef WRITE_SAMPLE583584#endif /* non-fixed type */585586587