mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-23 22:25:41 +00:00
355 lines
9.9 KiB
C++
355 lines
9.9 KiB
C++
/**
|
|
** Supermodel
|
|
** A Sega Model 3 Arcade Emulator.
|
|
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
|
**
|
|
** This file is part of Supermodel.
|
|
**
|
|
** Supermodel is free software: you can redistribute it and/or modify it under
|
|
** the terms of the GNU General Public License as published by the Free
|
|
** Software Foundation, either version 3 of the License, or (at your option)
|
|
** any later version.
|
|
**
|
|
** Supermodel 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 General Public License for
|
|
** more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License along
|
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
|
**/
|
|
|
|
/*
|
|
* layer2.cpp
|
|
*
|
|
* Amp library internal module.
|
|
*/
|
|
|
|
|
|
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
|
|
*/
|
|
|
|
/* layer2.c MPEG audio layer2 support
|
|
*
|
|
* Created by: Tomislav Uzelac Mar 1996
|
|
* merged with amp, May 19 1997
|
|
*/
|
|
#include "amp.h"
|
|
#include "amp_audio.h"
|
|
#include "getbits.h"
|
|
#include "transform.h"
|
|
|
|
#define LAYER2
|
|
#include "layer2.h"
|
|
|
|
#include "Supermodel.h"
|
|
|
|
int layer2_frame(struct AUDIO_HEADER *header,int cnt)
|
|
{
|
|
int i,s,sb,ch,gr,bitrate,bound=0;
|
|
char (*nbal)[],(*bit_alloc_index)[][16];
|
|
unsigned char allocation[2][32];
|
|
unsigned char scfsi[2][32];
|
|
float scalefactor[2][32][3];
|
|
float subband_sample[2][32][36];
|
|
int sblimit,nlevels,grouping;
|
|
|
|
float c,d;
|
|
int no_of_bits,mpi;
|
|
unsigned short sb_sample_buf[3];
|
|
|
|
int hsize,fs,mean_frame_size;
|
|
|
|
bit_alloc_index=(char (*)[][16])&t_alloc0;
|
|
nbal=(char (*)[])&t_nbal0; // shut up compiler
|
|
sblimit = 0;
|
|
|
|
hsize=4;
|
|
if (header->protection_bit==0) hsize+=2;
|
|
|
|
bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
|
|
fs=t_sampling_frequency[header->ID][header->sampling_frequency];
|
|
if (header->ID) mean_frame_size=144000*bitrate/fs;
|
|
else mean_frame_size=72000*bitrate/fs;
|
|
|
|
/* layers 1 and 2 do not have a 'bit reservoir'
|
|
*/
|
|
append=::data=0;
|
|
|
|
fillbfr(mean_frame_size + header->padding_bit - hsize);
|
|
|
|
switch (header->mode)
|
|
{
|
|
case 0 :
|
|
case 2 : nch=2; bound=32; bitrate=bitrate/2;
|
|
break;
|
|
case 3 : nch=1; bound=32;
|
|
break;
|
|
case 1 : nch=2; bitrate=bitrate/2; bound=(header->mode_extension+1)*4;
|
|
}
|
|
|
|
if (header->ID==1) switch (header->sampling_frequency) {
|
|
case 0 : switch (bitrate) /* 0 = 44.1 kHz */
|
|
{
|
|
case 56 :
|
|
case 64 :
|
|
case 80 : bit_alloc_index=(char (*)[][16])&t_alloc0;
|
|
nbal=(char (*)[])&t_nbal0;
|
|
sblimit=27;
|
|
break;
|
|
case 96 :
|
|
case 112 :
|
|
case 128 :
|
|
case 160 :
|
|
case 192 : bit_alloc_index=(char (*)[][16])&t_alloc1;
|
|
nbal=(char (*)[])&t_nbal1;
|
|
sblimit=30;
|
|
break;
|
|
case 32 :
|
|
case 48 : bit_alloc_index=(char (*)[][16])&t_alloc2;
|
|
nbal=(char (*)[])&t_nbal2;
|
|
sblimit=8;
|
|
break;
|
|
default : ErrorLog("Internal error in MPEG decoder (%s:%d).", __FILE__, __LINE__);
|
|
}
|
|
break;
|
|
case 1 : switch (bitrate) /* 1 = 48 kHz */
|
|
{
|
|
case 56 :
|
|
case 64 :
|
|
case 80 :
|
|
case 96 :
|
|
case 112 :
|
|
case 128 :
|
|
case 160 :
|
|
case 192 : bit_alloc_index=(char (*)[][16])&t_alloc0;
|
|
nbal=(char (*)[])&t_nbal0;
|
|
sblimit=27;
|
|
break;
|
|
case 32 :
|
|
case 48 : bit_alloc_index=(char (*)[][16])&t_alloc2;
|
|
nbal=(char (*)[])&t_nbal2;
|
|
sblimit=8;
|
|
break;
|
|
default : ErrorLog("Internal error in MPEG decoder (%s:%d).", __FILE__, __LINE__);
|
|
}
|
|
break;
|
|
case 2 : switch (bitrate) /* 2 = 32 kHz */
|
|
{
|
|
case 56 :
|
|
case 64 :
|
|
case 80 : bit_alloc_index=(char (*)[][16])&t_alloc0;
|
|
nbal=(char (*)[])&t_nbal0;
|
|
sblimit=27;
|
|
break;
|
|
case 96 :
|
|
case 112 :
|
|
case 128 :
|
|
case 160 :
|
|
case 192 : bit_alloc_index=(char (*)[][16])&t_alloc1;
|
|
nbal=(char (*)[])&t_nbal1;
|
|
sblimit=30;
|
|
break;
|
|
case 32 :
|
|
case 48 : bit_alloc_index=(char (*)[][16])&t_alloc3;
|
|
nbal=(char (*)[])&t_nbal3;
|
|
sblimit=12;
|
|
break;
|
|
default : ErrorLog("Internal error in MPEG decoder (%s:%d).", __FILE__, __LINE__);
|
|
}
|
|
break;
|
|
default : ErrorLog("Internal error in MPEG decoder (%s:%d).", __FILE__, __LINE__); // sampling frequency no good
|
|
} else {
|
|
bit_alloc_index=(char (*)[][16])&t_allocMPG2;
|
|
nbal=(char (*)[])&t_nbalMPG2;
|
|
sblimit=30;
|
|
}
|
|
|
|
/*
|
|
* bit allocation per subband per channel decoding *****************************
|
|
*/
|
|
|
|
if (bound==32) bound=sblimit; /* bound=32 means there is no intensity stereo */
|
|
|
|
for (sb=0;sb<bound;sb++)
|
|
for (ch=0;ch<nch;ch++)
|
|
allocation[ch][sb]=getbits((*nbal)[sb]);
|
|
|
|
for (sb=bound;sb<sblimit;sb++)
|
|
allocation[1][sb] = allocation[0][sb] = getbits((*nbal)[sb]);
|
|
|
|
|
|
/*
|
|
* scfsi ***********************************************************************
|
|
*/
|
|
|
|
for (sb=0;sb<sblimit;sb++)
|
|
for (ch=0;ch<nch;ch++)
|
|
if (allocation[ch][sb]!=0) scfsi[ch][sb]=getbits(2);
|
|
else scfsi[ch][sb]=0;
|
|
|
|
/*
|
|
* scalefactors ****************************************************************
|
|
*/
|
|
|
|
for (sb=0;sb<sblimit;sb++)
|
|
for (ch=0;ch<nch;ch++)
|
|
if (allocation[ch][sb]!=0) {
|
|
scalefactor[ch][sb][0]=(float)t_scalefactor[getbits(6)];
|
|
switch (scfsi[ch][sb])
|
|
{
|
|
case 0: scalefactor[ch][sb][1]=(float)t_scalefactor[getbits(6)];
|
|
scalefactor[ch][sb][2]=(float)t_scalefactor[getbits(6)];
|
|
break;
|
|
case 1: scalefactor[ch][sb][2]=(float)t_scalefactor[getbits(6)];
|
|
scalefactor[ch][sb][1]=scalefactor[ch][sb][0];
|
|
break;
|
|
case 2: scalefactor[ch][sb][1]=(float)scalefactor[ch][sb][0];
|
|
scalefactor[ch][sb][2]=scalefactor[ch][sb][0];
|
|
break;
|
|
case 3: scalefactor[ch][sb][2]=(float)t_scalefactor[getbits(6)];
|
|
scalefactor[ch][sb][1]=scalefactor[ch][sb][2];
|
|
}
|
|
}
|
|
else scalefactor[ch][sb][0]=scalefactor[ch][sb][1]=\
|
|
scalefactor[ch][sb][2]=0.0;
|
|
|
|
|
|
/*
|
|
* samples *********************************************************************
|
|
*/
|
|
|
|
for (gr=0;gr<12;gr++) {
|
|
/*
|
|
* normal ********************************
|
|
*/
|
|
|
|
for (sb=0;sb<bound;sb++)
|
|
for (ch=0;ch<nch;ch++)
|
|
if (allocation[ch][sb]!=0) {
|
|
mpi=(*bit_alloc_index)[sb][allocation[ch][sb]];
|
|
no_of_bits=t_bpc[mpi];
|
|
c=(float)t_c[mpi];
|
|
d=(float)t_d[mpi];
|
|
grouping=t_grouping[mpi];
|
|
nlevels=t_nlevels[mpi];
|
|
|
|
if (grouping) {
|
|
int samplecode=getbits(no_of_bits);
|
|
convert_samplecode(samplecode,grouping,sb_sample_buf);
|
|
|
|
for (s=0;s<3;s++)
|
|
subband_sample[ch][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[ch][sb][gr/4]);
|
|
} else {
|
|
for (s=0;s<3;s++) sb_sample_buf[s]=getbits(no_of_bits);
|
|
|
|
for (s=0;s<3;s++) {
|
|
/*subband_sample[ch][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[ch][sb][gr/4]);*/
|
|
subband_sample[ch][sb][3*gr+s]=(t_dd[mpi]+sb_sample_buf[s]*t_nli[mpi])*c*scalefactor[ch][sb][gr>>2];
|
|
}
|
|
}
|
|
} else
|
|
for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;
|
|
|
|
|
|
/*
|
|
* joint stereo ********************************************
|
|
*/
|
|
|
|
for (sb=bound;sb<sblimit;sb++)
|
|
if (allocation[0][sb]!=0) {
|
|
/*ispravka!
|
|
*/
|
|
mpi=(*bit_alloc_index)[sb][allocation[0][sb]];
|
|
no_of_bits=t_bpc[mpi];
|
|
c=(float)t_c[mpi];
|
|
d=(float)t_d[mpi];
|
|
grouping=t_grouping[mpi];
|
|
nlevels=t_nlevels[mpi];
|
|
|
|
if (grouping) {
|
|
int samplecode=getbits(no_of_bits);
|
|
convert_samplecode(samplecode,grouping,sb_sample_buf);
|
|
|
|
for (s=0;s<3;s++) {
|
|
subband_sample[0][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[0][sb][gr/4]);
|
|
subband_sample[1][sb][3*gr+s]=subband_sample[0][sb][3*gr+s];
|
|
}
|
|
} else {
|
|
for (s=0;s<3;s++) sb_sample_buf[s]=getbits(no_of_bits);
|
|
|
|
for (s=0;s<3;s++) {
|
|
subband_sample[0][sb][3*gr+s]=subband_sample[1][sb][3*gr+s]=\
|
|
(t_dd[mpi]+sb_sample_buf[s]*t_nli[mpi])*c*scalefactor[0][sb][gr>>2];
|
|
}
|
|
}
|
|
|
|
} else for (s=0;s<3;s++) {
|
|
subband_sample[0][sb][3*gr+s]=0;
|
|
subband_sample[1][sb][3*gr+s]=0;
|
|
}
|
|
|
|
/*
|
|
* the rest *******************************************
|
|
*/
|
|
for (sb=sblimit;sb<32;sb++)
|
|
for (ch=0;ch<nch;ch++)
|
|
|
|
for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;
|
|
}
|
|
|
|
/*
|
|
* this is, in fact, horrible, but I had to adjust it to amp/mp3. The hack to make downmixing
|
|
* work is as ugly as possible.
|
|
*/
|
|
|
|
if (A_DOWNMIX && header->mode!=3) {
|
|
for (ch=0;ch<nch;ch++)
|
|
for (sb=0;sb<32;sb++)
|
|
for (i=0;i<36;i++)
|
|
subband_sample[0][sb][i]=(subband_sample[0][sb][i]+subband_sample[1][sb][i])*0.5f;
|
|
nch=1;
|
|
}
|
|
|
|
for (ch=0;ch<nch;ch++) {
|
|
for (sb=0;sb<32;sb++)
|
|
for (i=0;i<18;i++) res[sb][i]=subband_sample[ch][sb][i];
|
|
for (i=0;i<18;i++)
|
|
poly(ch,i);
|
|
}
|
|
printout();
|
|
for (ch=0;ch<nch;ch++) {
|
|
for (sb=0;sb<32;sb++)
|
|
for (i=0;i<18;i++) res[sb][i]=subband_sample[ch][sb][i+18];
|
|
for (i=0;i<18;i++)
|
|
poly(ch,i);
|
|
}
|
|
printout();
|
|
|
|
if (A_DOWNMIX && header->mode!=3) nch=2;
|
|
|
|
return 0;
|
|
}
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
|
|
void convert_samplecode(unsigned int samplecode,unsigned int nlevels,unsigned short* sb_sample_buf)
|
|
{
|
|
int i;
|
|
|
|
for (i=0;i<3;i++) {
|
|
*sb_sample_buf=samplecode%nlevels;
|
|
samplecode=samplecode/nlevels;
|
|
sb_sample_buf++;
|
|
}
|
|
}
|
|
|
|
float requantize_sample(unsigned short s4,unsigned short nlevels,float c,float d,float factor)
|
|
{
|
|
register float s,s2,s3;
|
|
s3=(float) (-1.0+s4*2.0/(nlevels+1));
|
|
s2=c*(s3+d);
|
|
s=factor*s2;
|
|
return s;
|
|
}
|