1 /* 2 synth_real.c: The functions for synthesizing real (float) samples, at the end of decoding. 3 4 copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1 5 see COPYING and AUTHORS files in distribution or http://mpg123.org 6 initially written by Michael Hipp, heavily dissected and rearranged by Thomas Orgis 7 */ 8 9 #include "mpg123lib_intern.h" 10 #include "sample.h" 11 #include "debug.h" 12 13 #ifdef REAL_IS_FIXED 14 #error "Do not build this file with fixed point math!" 15 #else 16 /* 17 Part 3: All synth functions that produce float output. 18 What we need is just a special WRITE_SAMPLE. For the generic and i386 functions, that is. 19 The optimized synths would need to be changed internally to support float output. 20 */ 21 22 #define SAMPLE_T real 23 #define WRITE_SAMPLE(samples,sum,clip) WRITE_REAL_SAMPLE(samples,sum,clip) 24 25 /* Part 3a: All straight 1to1 decoding functions */ 26 #define BLOCK 0x40 /* One decoding block is 64 samples. */ 27 28 #define SYNTH_NAME synth_1to1_real 29 #include "synth.h" 30 #undef SYNTH_NAME 31 32 /* Mono-related synths; they wrap over _some_ synth_1to1_real (could be generic, could be i386). */ 33 #define SYNTH_NAME fr->synths.plain[r_1to1][f_real] 34 #define MONO_NAME synth_1to1_real_mono 35 #define MONO2STEREO_NAME synth_1to1_real_m2s 36 #include "synth_mono.h" 37 #undef SYNTH_NAME 38 #undef MONO_NAME 39 #undef MONO2STEREO_NAME 40 41 #ifdef OPT_X86 42 #define NO_AUTOINCREMENT 43 #define SYNTH_NAME synth_1to1_real_i386 44 #include "synth.h" 45 #undef SYNTH_NAME 46 /* i386 uses the normal mono functions. */ 47 #undef NO_AUTOINCREMENT 48 #endif 49 50 #undef BLOCK 51 52 /* At least one optimized real decoder... */ 53 #ifdef OPT_X86_64 54 /* Assembler routines. */ 55 int synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1); 56 int synth_1to1_real_s_x86_64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1); 57 void dct64_real_x86_64(real *out0, real *out1, real *samples); 58 /* Hull for C mpg123 API */ 59 int synth_1to1_real_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final) 60 { 61 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 62 63 real *b0, **buf; 64 int bo1; 65 #ifndef NO_EQUALIZER 66 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer); 67 #endif 68 if(!channel) 69 { 70 fr->bo--; 71 fr->bo &= 0xf; 72 buf = fr->real_buffs[0]; 73 } 74 else 75 { 76 samples++; 77 buf = fr->real_buffs[1]; 78 } 79 80 if(fr->bo & 0x1) 81 { 82 b0 = buf[0]; 83 bo1 = fr->bo; 84 dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr); 85 } 86 else 87 { 88 b0 = buf[1]; 89 bo1 = fr->bo+1; 90 dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr); 91 } 92 93 synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1); 94 95 if(final) fr->buffer.fill += 256; 96 97 return 0; 98 } 99 100 int synth_1to1_real_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr) 101 { 102 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 103 104 real *b0l, *b0r, **bufl, **bufr; 105 int bo1; 106 #ifndef NO_EQUALIZER 107 if(fr->have_eq_settings) 108 { 109 do_equalizer(bandPtr_l,0,fr->equalizer); 110 do_equalizer(bandPtr_r,1,fr->equalizer); 111 } 112 #endif 113 fr->bo--; 114 fr->bo &= 0xf; 115 bufl = fr->real_buffs[0]; 116 bufr = fr->real_buffs[1]; 117 118 if(fr->bo & 0x1) 119 { 120 b0l = bufl[0]; 121 b0r = bufr[0]; 122 bo1 = fr->bo; 123 dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l); 124 dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r); 125 } 126 else 127 { 128 b0l = bufl[1]; 129 b0r = bufr[1]; 130 bo1 = fr->bo+1; 131 dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l); 132 dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r); 133 } 134 135 synth_1to1_real_s_x86_64_asm(fr->decwin, b0l, b0r, samples, bo1); 136 137 fr->buffer.fill += 256; 138 139 return 0; 140 } 141 #endif 142 143 #ifdef OPT_AVX 144 /* Assembler routines. */ 145 #ifndef OPT_X86_64 146 int synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1); 147 #endif 148 int synth_1to1_real_s_avx_asm(real *window, real *b0l, real *b0r, real *samples, int bo1); 149 void dct64_real_avx(real *out0, real *out1, real *samples); 150 /* Hull for C mpg123 API */ 151 int synth_1to1_real_avx(real *bandPtr,int channel, mpg123_handle *fr, int final) 152 { 153 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 154 155 real *b0, **buf; 156 int bo1; 157 #ifndef NO_EQUALIZER 158 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer); 159 #endif 160 if(!channel) 161 { 162 fr->bo--; 163 fr->bo &= 0xf; 164 buf = fr->real_buffs[0]; 165 } 166 else 167 { 168 samples++; 169 buf = fr->real_buffs[1]; 170 } 171 172 if(fr->bo & 0x1) 173 { 174 b0 = buf[0]; 175 bo1 = fr->bo; 176 dct64_real_avx(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr); 177 } 178 else 179 { 180 b0 = buf[1]; 181 bo1 = fr->bo+1; 182 dct64_real_avx(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr); 183 } 184 185 synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1); 186 187 if(final) fr->buffer.fill += 256; 188 189 return 0; 190 } 191 192 int synth_1to1_fltst_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr) 193 { 194 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 195 196 real *b0l, *b0r, **bufl, **bufr; 197 int bo1; 198 #ifndef NO_EQUALIZER 199 if(fr->have_eq_settings) 200 { 201 do_equalizer(bandPtr_l,0,fr->equalizer); 202 do_equalizer(bandPtr_r,1,fr->equalizer); 203 } 204 #endif 205 fr->bo--; 206 fr->bo &= 0xf; 207 bufl = fr->real_buffs[0]; 208 bufr = fr->real_buffs[1]; 209 210 if(fr->bo & 0x1) 211 { 212 b0l = bufl[0]; 213 b0r = bufr[0]; 214 bo1 = fr->bo; 215 dct64_real_avx(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l); 216 dct64_real_avx(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r); 217 } 218 else 219 { 220 b0l = bufl[1]; 221 b0r = bufr[1]; 222 bo1 = fr->bo+1; 223 dct64_real_avx(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l); 224 dct64_real_avx(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r); 225 } 226 227 synth_1to1_real_s_avx_asm(fr->decwin, b0l, b0r, samples, bo1); 228 229 fr->buffer.fill += 256; 230 231 return 0; 232 } 233 #endif 234 235 #if defined(OPT_SSE) || defined(OPT_SSE_VINTAGE) 236 /* Assembler routines. */ 237 int synth_1to1_real_sse_asm(real *window, real *b0, real *samples, int bo1); 238 int synth_1to1_real_s_sse_asm(real *window, real *b0l, real *b0r, real *samples, int bo1); 239 void dct64_real_sse(real *out0, real *out1, real *samples); 240 /* Hull for C mpg123 API */ 241 int synth_1to1_real_sse(real *bandPtr,int channel, mpg123_handle *fr, int final) 242 { 243 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 244 245 real *b0, **buf; 246 int bo1; 247 #ifndef NO_EQUALIZER 248 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer); 249 #endif 250 if(!channel) 251 { 252 fr->bo--; 253 fr->bo &= 0xf; 254 buf = fr->real_buffs[0]; 255 } 256 else 257 { 258 samples++; 259 buf = fr->real_buffs[1]; 260 } 261 262 if(fr->bo & 0x1) 263 { 264 b0 = buf[0]; 265 bo1 = fr->bo; 266 dct64_real_sse(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr); 267 } 268 else 269 { 270 b0 = buf[1]; 271 bo1 = fr->bo+1; 272 dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr); 273 } 274 275 synth_1to1_real_sse_asm(fr->decwin, b0, samples, bo1); 276 277 if(final) fr->buffer.fill += 256; 278 279 return 0; 280 } 281 282 int synth_1to1_real_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr) 283 { 284 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 285 286 real *b0l, *b0r, **bufl, **bufr; 287 int bo1; 288 #ifndef NO_EQUALIZER 289 if(fr->have_eq_settings) 290 { 291 do_equalizer(bandPtr_l,0,fr->equalizer); 292 do_equalizer(bandPtr_r,1,fr->equalizer); 293 } 294 #endif 295 fr->bo--; 296 fr->bo &= 0xf; 297 bufl = fr->real_buffs[0]; 298 bufr = fr->real_buffs[1]; 299 300 if(fr->bo & 0x1) 301 { 302 b0l = bufl[0]; 303 b0r = bufr[0]; 304 bo1 = fr->bo; 305 dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l); 306 dct64_real_sse(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r); 307 } 308 else 309 { 310 b0l = bufl[1]; 311 b0r = bufr[1]; 312 bo1 = fr->bo+1; 313 dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l); 314 dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r); 315 } 316 317 synth_1to1_real_s_sse_asm(fr->decwin, b0l, b0r, samples, bo1); 318 319 fr->buffer.fill += 256; 320 321 return 0; 322 } 323 #endif 324 325 #ifdef OPT_NEON 326 /* Assembler routines. */ 327 int synth_1to1_real_neon_asm(real *window, real *b0, real *samples, int bo1); 328 int synth_1to1_real_s_neon_asm(real *window, real *b0l, real *b0r, real *samples, int bo1); 329 void dct64_real_neon(real *out0, real *out1, real *samples); 330 /* Hull for C mpg123 API */ 331 int synth_1to1_real_neon(real *bandPtr,int channel, mpg123_handle *fr, int final) 332 { 333 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 334 335 real *b0, **buf; 336 int bo1; 337 #ifndef NO_EQUALIZER 338 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer); 339 #endif 340 if(!channel) 341 { 342 fr->bo--; 343 fr->bo &= 0xf; 344 buf = fr->real_buffs[0]; 345 } 346 else 347 { 348 samples++; 349 buf = fr->real_buffs[1]; 350 } 351 352 if(fr->bo & 0x1) 353 { 354 b0 = buf[0]; 355 bo1 = fr->bo; 356 dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr); 357 } 358 else 359 { 360 b0 = buf[1]; 361 bo1 = fr->bo+1; 362 dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr); 363 } 364 365 synth_1to1_real_neon_asm(fr->decwin, b0, samples, bo1); 366 367 if(final) fr->buffer.fill += 256; 368 369 return 0; 370 } 371 int synth_1to1_real_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr) 372 { 373 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 374 375 real *b0l, *b0r, **bufl, **bufr; 376 int bo1; 377 #ifndef NO_EQUALIZER 378 if(fr->have_eq_settings) 379 { 380 do_equalizer(bandPtr_l,0,fr->equalizer); 381 do_equalizer(bandPtr_r,1,fr->equalizer); 382 } 383 #endif 384 fr->bo--; 385 fr->bo &= 0xf; 386 bufl = fr->real_buffs[0]; 387 bufr = fr->real_buffs[1]; 388 389 if(fr->bo & 0x1) 390 { 391 b0l = bufl[0]; 392 b0r = bufr[0]; 393 bo1 = fr->bo; 394 dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l); 395 dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r); 396 } 397 else 398 { 399 b0l = bufl[1]; 400 b0r = bufr[1]; 401 bo1 = fr->bo+1; 402 dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l); 403 dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r); 404 } 405 406 synth_1to1_real_s_neon_asm(fr->decwin, b0l, b0r, samples, bo1); 407 408 fr->buffer.fill += 256; 409 410 return 0; 411 } 412 #endif 413 414 #ifdef OPT_NEON64 415 /* Assembler routines. */ 416 int synth_1to1_real_neon64_asm(real *window, real *b0, real *samples, int bo1); 417 int synth_1to1_real_s_neon64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1); 418 void dct64_real_neon64(real *out0, real *out1, real *samples); 419 /* Hull for C mpg123 API */ 420 int synth_1to1_real_neon64(real *bandPtr,int channel, mpg123_handle *fr, int final) 421 { 422 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 423 424 real *b0, **buf; 425 int bo1; 426 #ifndef NO_EQUALIZER 427 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer); 428 #endif 429 if(!channel) 430 { 431 fr->bo--; 432 fr->bo &= 0xf; 433 buf = fr->real_buffs[0]; 434 } 435 else 436 { 437 samples++; 438 buf = fr->real_buffs[1]; 439 } 440 441 if(fr->bo & 0x1) 442 { 443 b0 = buf[0]; 444 bo1 = fr->bo; 445 dct64_real_neon64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr); 446 } 447 else 448 { 449 b0 = buf[1]; 450 bo1 = fr->bo+1; 451 dct64_real_neon64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr); 452 } 453 454 synth_1to1_real_neon64_asm(fr->decwin, b0, samples, bo1); 455 456 if(final) fr->buffer.fill += 256; 457 458 return 0; 459 } 460 int synth_1to1_fltst_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr) 461 { 462 real *samples = (real *) (fr->buffer.data+fr->buffer.fill); 463 464 real *b0l, *b0r, **bufl, **bufr; 465 int bo1; 466 #ifndef NO_EQUALIZER 467 if(fr->have_eq_settings) 468 { 469 do_equalizer(bandPtr_l,0,fr->equalizer); 470 do_equalizer(bandPtr_r,1,fr->equalizer); 471 } 472 #endif 473 fr->bo--; 474 fr->bo &= 0xf; 475 bufl = fr->real_buffs[0]; 476 bufr = fr->real_buffs[1]; 477 478 if(fr->bo & 0x1) 479 { 480 b0l = bufl[0]; 481 b0r = bufr[0]; 482 bo1 = fr->bo; 483 dct64_real_neon64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l); 484 dct64_real_neon64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r); 485 } 486 else 487 { 488 b0l = bufl[1]; 489 b0r = bufr[1]; 490 bo1 = fr->bo+1; 491 dct64_real_neon64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l); 492 dct64_real_neon64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r); 493 } 494 495 synth_1to1_real_s_neon64_asm(fr->decwin, b0l, b0r, samples, bo1); 496 497 fr->buffer.fill += 256; 498 499 return 0; 500 } 501 #endif 502 503 #ifndef NO_DOWNSAMPLE 504 505 /* 506 Part 3b: 2to1 synth. Only generic and i386. 507 */ 508 #define BLOCK 0x20 /* One decoding block is 32 samples. */ 509 510 #define SYNTH_NAME synth_2to1_real 511 #include "synth.h" 512 #undef SYNTH_NAME 513 514 /* Mono-related synths; they wrap over _some_ synth_2to1_real (could be generic, could be i386). */ 515 #define SYNTH_NAME fr->synths.plain[r_2to1][f_real] 516 #define MONO_NAME synth_2to1_real_mono 517 #define MONO2STEREO_NAME synth_2to1_real_m2s 518 #include "synth_mono.h" 519 #undef SYNTH_NAME 520 #undef MONO_NAME 521 #undef MONO2STEREO_NAME 522 523 #ifdef OPT_X86 524 #define NO_AUTOINCREMENT 525 #define SYNTH_NAME synth_2to1_real_i386 526 #include "synth.h" 527 #undef SYNTH_NAME 528 /* i386 uses the normal mono functions. */ 529 #undef NO_AUTOINCREMENT 530 #endif 531 532 #undef BLOCK 533 534 /* 535 Part 3c: 4to1 synth. Only generic and i386. 536 */ 537 #define BLOCK 0x10 /* One decoding block is 16 samples. */ 538 539 #define SYNTH_NAME synth_4to1_real 540 #include "synth.h" 541 #undef SYNTH_NAME 542 543 /* Mono-related synths; they wrap over _some_ synth_4to1_real (could be generic, could be i386). */ 544 #define SYNTH_NAME fr->synths.plain[r_4to1][f_real] 545 #define MONO_NAME synth_4to1_real_mono 546 #define MONO2STEREO_NAME synth_4to1_real_m2s 547 #include "synth_mono.h" 548 #undef SYNTH_NAME 549 #undef MONO_NAME 550 #undef MONO2STEREO_NAME 551 552 #ifdef OPT_X86 553 #define NO_AUTOINCREMENT 554 #define SYNTH_NAME synth_4to1_real_i386 555 #include "synth.h" 556 #undef SYNTH_NAME 557 /* i386 uses the normal mono functions. */ 558 #undef NO_AUTOINCREMENT 559 #endif 560 561 #undef BLOCK 562 563 #endif /* NO_DOWNSAMPLE */ 564 565 #ifndef NO_NTOM 566 /* 567 Part 3d: ntom synth. 568 Same procedure as above... Just no extra play anymore, straight synth that may use an optimized dct64. 569 */ 570 571 /* These are all in one header, there's no flexibility to gain. */ 572 #define SYNTH_NAME synth_ntom_real 573 #define MONO_NAME synth_ntom_real_mono 574 #define MONO2STEREO_NAME synth_ntom_real_m2s 575 #include "synth_ntom.h" 576 #undef SYNTH_NAME 577 #undef MONO_NAME 578 #undef MONO2STEREO_NAME 579 580 #endif 581 582 #undef SAMPLE_T 583 #undef WRITE_SAMPLE 584 585 #endif /* non-fixed type */ 586