2017-06-11 11:12:12 +02:00
|
|
|
// https://github.com/technosaurus/PDMP3
|
|
|
|
// License: Public Domain
|
|
|
|
|
|
|
|
#include "pdmp3.h"
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#define C_SYNC 0xffe00000
|
|
|
|
#define C_EOF 0xffffffff
|
|
|
|
#define C_PI 3.14159265358979323846
|
|
|
|
#define C_INV_SQRT_2 0.70710678118654752440
|
|
|
|
#define Hz 1
|
|
|
|
#define kHz 1000*Hz
|
|
|
|
#define bit_s 1
|
|
|
|
#define kbit_s 1000*bit_s
|
|
|
|
#define FRAG_SIZE_LN2 0x0011 /* 2^17=128kb */
|
|
|
|
#define FRAG_NUMS 0x0004
|
|
|
|
|
|
|
|
#define DBG(str,args...) { printf(str,## args); printf("\n"); }
|
|
|
|
#define ERR(str,args...) { fprintf(stderr,str,## args) ; fprintf(stderr,"\n"); }
|
|
|
|
#define EXIT(str,args...) { printf(str,## args); printf("\n"); exit(0); }
|
|
|
|
|
|
|
|
#ifdef DEBUG //debug functions
|
|
|
|
static void dmp_fr(t_mpeg1_header *hdr);
|
|
|
|
static void dmp_si(t_mpeg1_header *hdr,t_mpeg1_side_info *si);
|
|
|
|
static void dmp_scf(t_mpeg1_side_info *si,t_mpeg1_main_data *md,int gr,int ch);
|
|
|
|
static void dmp_huff(t_mpeg1_main_data *md,int gr,int ch);
|
|
|
|
static void dmp_samples(t_mpeg1_main_data *md,int gr,int ch,int type);
|
|
|
|
#else
|
|
|
|
#define dmp_fr(...) do{}while(0)
|
|
|
|
#define dmp_si(...) do{}while(0)
|
|
|
|
#define dmp_scf(...) do{}while(0)
|
|
|
|
#define dmp_huff(...) do{}while(0)
|
|
|
|
#define dmp_samples(...) do{}while(0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void audio_write(unsigned *samples,unsigned nsamples,int sample_rate);
|
|
|
|
static void audio_write_raw(unsigned *samples,unsigned nsamples);
|
|
|
|
static void Decode_L3_Init_Song(void);
|
|
|
|
static void Error(const char *s,int e);
|
|
|
|
static void L3_Antialias(unsigned gr,unsigned ch);
|
|
|
|
static void L3_Frequency_Inversion(unsigned gr,unsigned ch);
|
|
|
|
static void L3_Hybrid_Synthesis(unsigned gr,unsigned ch);
|
|
|
|
static void L3_Requantize(unsigned gr,unsigned ch);
|
|
|
|
static void L3_Reorder(unsigned gr,unsigned ch);
|
|
|
|
static void L3_Stereo(unsigned gr);
|
|
|
|
static void L3_Subband_Synthesis(unsigned gr,unsigned ch,unsigned outdata[576]);
|
|
|
|
static void Read_Ancillary(void);
|
|
|
|
static void Read_Huffman(unsigned part_2_start,unsigned gr,unsigned ch);
|
|
|
|
static void Requantize_Process_Long(unsigned gr,unsigned ch,unsigned is_pos,unsigned sfb);
|
|
|
|
static void Requantize_Process_Short(unsigned gr,unsigned ch,unsigned is_pos,unsigned sfb,unsigned win);
|
|
|
|
static void Stereo_Process_Intensity_Long(unsigned gr,unsigned sfb);
|
|
|
|
static void Stereo_Process_Intensity_Short(unsigned gr,unsigned sfb);
|
|
|
|
|
|
|
|
static const unsigned g_mpeg1_bitrates[3 /* layer 1-3 */][15 /* header bitrate_index */] = {
|
|
|
|
{ /* Layer 1 */
|
|
|
|
0, 32000, 64000, 96000,128000,160000,192000,224000,
|
|
|
|
256000,288000,320000,352000,384000,416000,448000
|
|
|
|
},{ /* Layer 2 */
|
|
|
|
0, 32000, 48000, 56000, 64000, 80000, 96000,112000,
|
|
|
|
128000,160000,192000,224000,256000,320000,384000
|
|
|
|
},{ /* Layer 3 */
|
|
|
|
0, 32000, 40000, 48000, 56000, 64000, 80000, 96000,
|
|
|
|
112000,128000,160000,192000,224000,256000,320000
|
|
|
|
}
|
|
|
|
},
|
|
|
|
g_sampling_frequency[3] = { 44100 * Hz,48000 * Hz,32000 * Hz },
|
|
|
|
mpeg1_scalefac_sizes[16][2 /* slen1,slen2 */] = {
|
|
|
|
{0,0},{0,1},{0,2},{0,3},{3,0},{1,1},{1,2},{1,3},
|
|
|
|
{2,1},{2,2},{2,3},{3,1},{3,2},{3,3},{4,2},{4,3}
|
|
|
|
};
|
|
|
|
|
2017-06-13 18:36:49 +02:00
|
|
|
static const float //ci[8]={-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037},
|
2017-06-11 11:12:12 +02:00
|
|
|
cs[8]={0.857493,0.881742,0.949629,0.983315,0.995518,0.999161,0.999899,0.999993},
|
|
|
|
ca[8]={-0.514496,-0.471732,-0.313377,-0.181913,-0.094574,-0.040966,-0.014199,-0.003700},
|
2017-06-13 18:36:49 +02:00
|
|
|
is_ratios[6] = {0.000000f,0.267949f,0.577350f,1.000000f,1.732051f,3.732051f};
|
2017-06-11 11:12:12 +02:00
|
|
|
#ifdef POW34_ITERATE
|
2017-06-13 18:36:49 +02:00
|
|
|
static const float powtab34[32] = {
|
2017-06-11 11:12:12 +02:00
|
|
|
0.000000f,1.000000f,2.519842f,4.326749f,6.349605f,8.549880f,10.902724f,
|
|
|
|
13.390519f,16.000001f,18.720756f,21.544349f,24.463783f,27.473145f,30.567354f,
|
|
|
|
33.741995f,36.993185f,40.317478f,43.711792f,47.173351f,50.699637f,54.288359f,
|
|
|
|
57.937415f,61.644873f,65.408949f,69.227988f,73.100453f,77.024908f,81.000011f,
|
|
|
|
85.024502f,89.097200f,93.216988f,97.382814f
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
g_synth_dtbl[512] = {
|
|
|
|
0.000000000,-0.000015259,-0.000015259,-0.000015259,
|
|
|
|
-0.000015259,-0.000015259,-0.000015259,-0.000030518,
|
|
|
|
-0.000030518,-0.000030518,-0.000030518,-0.000045776,
|
|
|
|
-0.000045776,-0.000061035,-0.000061035,-0.000076294,
|
|
|
|
-0.000076294,-0.000091553,-0.000106812,-0.000106812,
|
|
|
|
-0.000122070,-0.000137329,-0.000152588,-0.000167847,
|
|
|
|
-0.000198364,-0.000213623,-0.000244141,-0.000259399,
|
|
|
|
-0.000289917,-0.000320435,-0.000366211,-0.000396729,
|
|
|
|
-0.000442505,-0.000473022,-0.000534058,-0.000579834,
|
|
|
|
-0.000625610,-0.000686646,-0.000747681,-0.000808716,
|
|
|
|
-0.000885010,-0.000961304,-0.001037598,-0.001113892,
|
|
|
|
-0.001205444,-0.001296997,-0.001388550,-0.001480103,
|
|
|
|
-0.001586914,-0.001693726,-0.001785278,-0.001907349,
|
|
|
|
-0.002014160,-0.002120972,-0.002243042,-0.002349854,
|
|
|
|
-0.002456665,-0.002578735,-0.002685547,-0.002792358,
|
|
|
|
-0.002899170,-0.002990723,-0.003082275,-0.003173828,
|
|
|
|
0.003250122, 0.003326416, 0.003387451, 0.003433228,
|
|
|
|
0.003463745, 0.003479004, 0.003479004, 0.003463745,
|
|
|
|
0.003417969, 0.003372192, 0.003280640, 0.003173828,
|
|
|
|
0.003051758, 0.002883911, 0.002700806, 0.002487183,
|
|
|
|
0.002227783, 0.001937866, 0.001617432, 0.001266479,
|
|
|
|
0.000869751, 0.000442505,-0.000030518,-0.000549316,
|
|
|
|
-0.001098633,-0.001693726,-0.002334595,-0.003005981,
|
|
|
|
-0.003723145,-0.004486084,-0.005294800,-0.006118774,
|
|
|
|
-0.007003784,-0.007919312,-0.008865356,-0.009841919,
|
|
|
|
-0.010848999,-0.011886597,-0.012939453,-0.014022827,
|
|
|
|
-0.015121460,-0.016235352,-0.017349243,-0.018463135,
|
|
|
|
-0.019577026,-0.020690918,-0.021789551,-0.022857666,
|
|
|
|
-0.023910522,-0.024932861,-0.025909424,-0.026840210,
|
|
|
|
-0.027725220,-0.028533936,-0.029281616,-0.029937744,
|
|
|
|
-0.030532837,-0.031005859,-0.031387329,-0.031661987,
|
|
|
|
-0.031814575,-0.031845093,-0.031738281,-0.031478882,
|
|
|
|
0.031082153, 0.030517578, 0.029785156, 0.028884888,
|
|
|
|
0.027801514, 0.026535034, 0.025085449, 0.023422241,
|
|
|
|
0.021575928, 0.019531250, 0.017257690, 0.014801025,
|
|
|
|
0.012115479, 0.009231567, 0.006134033, 0.002822876,
|
|
|
|
-0.000686646,-0.004394531,-0.008316040,-0.012420654,
|
|
|
|
-0.016708374,-0.021179199,-0.025817871,-0.030609131,
|
|
|
|
-0.035552979,-0.040634155,-0.045837402,-0.051132202,
|
|
|
|
-0.056533813,-0.061996460,-0.067520142,-0.073059082,
|
|
|
|
-0.078628540,-0.084182739,-0.089706421,-0.095169067,
|
|
|
|
-0.100540161,-0.105819702,-0.110946655,-0.115921021,
|
|
|
|
-0.120697021,-0.125259399,-0.129562378,-0.133590698,
|
|
|
|
-0.137298584,-0.140670776,-0.143676758,-0.146255493,
|
|
|
|
-0.148422241,-0.150115967,-0.151306152,-0.151962280,
|
|
|
|
-0.152069092,-0.151596069,-0.150497437,-0.148773193,
|
|
|
|
-0.146362305,-0.143264771,-0.139450073,-0.134887695,
|
|
|
|
-0.129577637,-0.123474121,-0.116577148,-0.108856201,
|
|
|
|
0.100311279, 0.090927124, 0.080688477, 0.069595337,
|
|
|
|
0.057617188, 0.044784546, 0.031082153, 0.016510010,
|
|
|
|
0.001068115,-0.015228271,-0.032379150,-0.050354004,
|
|
|
|
-0.069168091,-0.088775635,-0.109161377,-0.130310059,
|
|
|
|
-0.152206421,-0.174789429,-0.198059082,-0.221984863,
|
|
|
|
-0.246505737,-0.271591187,-0.297210693,-0.323318481,
|
|
|
|
-0.349868774,-0.376800537,-0.404083252,-0.431655884,
|
|
|
|
-0.459472656,-0.487472534,-0.515609741,-0.543823242,
|
|
|
|
-0.572036743,-0.600219727,-0.628295898,-0.656219482,
|
|
|
|
-0.683914185,-0.711318970,-0.738372803,-0.765029907,
|
|
|
|
-0.791213989,-0.816864014,-0.841949463,-0.866363525,
|
|
|
|
-0.890090942,-0.913055420,-0.935195923,-0.956481934,
|
|
|
|
-0.976852417,-0.996246338,-1.014617920,-1.031936646,
|
|
|
|
-1.048156738,-1.063217163,-1.077117920,-1.089782715,
|
|
|
|
-1.101211548,-1.111373901,-1.120223999,-1.127746582,
|
|
|
|
-1.133926392,-1.138763428,-1.142211914,-1.144287109,
|
|
|
|
1.144989014, 1.144287109, 1.142211914, 1.138763428,
|
|
|
|
1.133926392, 1.127746582, 1.120223999, 1.111373901,
|
|
|
|
1.101211548, 1.089782715, 1.077117920, 1.063217163,
|
|
|
|
1.048156738, 1.031936646, 1.014617920, 0.996246338,
|
|
|
|
0.976852417, 0.956481934, 0.935195923, 0.913055420,
|
|
|
|
0.890090942, 0.866363525, 0.841949463, 0.816864014,
|
|
|
|
0.791213989, 0.765029907, 0.738372803, 0.711318970,
|
|
|
|
0.683914185, 0.656219482, 0.628295898, 0.600219727,
|
|
|
|
0.572036743, 0.543823242, 0.515609741, 0.487472534,
|
|
|
|
0.459472656, 0.431655884, 0.404083252, 0.376800537,
|
|
|
|
0.349868774, 0.323318481, 0.297210693, 0.271591187,
|
|
|
|
0.246505737, 0.221984863, 0.198059082, 0.174789429,
|
|
|
|
0.152206421, 0.130310059, 0.109161377, 0.088775635,
|
|
|
|
0.069168091, 0.050354004, 0.032379150, 0.015228271,
|
|
|
|
-0.001068115,-0.016510010,-0.031082153,-0.044784546,
|
|
|
|
-0.057617188,-0.069595337,-0.080688477,-0.090927124,
|
|
|
|
0.100311279, 0.108856201, 0.116577148, 0.123474121,
|
|
|
|
0.129577637, 0.134887695, 0.139450073, 0.143264771,
|
|
|
|
0.146362305, 0.148773193, 0.150497437, 0.151596069,
|
|
|
|
0.152069092, 0.151962280, 0.151306152, 0.150115967,
|
|
|
|
0.148422241, 0.146255493, 0.143676758, 0.140670776,
|
|
|
|
0.137298584, 0.133590698, 0.129562378, 0.125259399,
|
|
|
|
0.120697021, 0.115921021, 0.110946655, 0.105819702,
|
|
|
|
0.100540161, 0.095169067, 0.089706421, 0.084182739,
|
|
|
|
0.078628540, 0.073059082, 0.067520142, 0.061996460,
|
|
|
|
0.056533813, 0.051132202, 0.045837402, 0.040634155,
|
|
|
|
0.035552979, 0.030609131, 0.025817871, 0.021179199,
|
|
|
|
0.016708374, 0.012420654, 0.008316040, 0.004394531,
|
|
|
|
0.000686646,-0.002822876,-0.006134033,-0.009231567,
|
|
|
|
-0.012115479,-0.014801025,-0.017257690,-0.019531250,
|
|
|
|
-0.021575928,-0.023422241,-0.025085449,-0.026535034,
|
|
|
|
-0.027801514,-0.028884888,-0.029785156,-0.030517578,
|
|
|
|
0.031082153, 0.031478882, 0.031738281, 0.031845093,
|
|
|
|
0.031814575, 0.031661987, 0.031387329, 0.031005859,
|
|
|
|
0.030532837, 0.029937744, 0.029281616, 0.028533936,
|
|
|
|
0.027725220, 0.026840210, 0.025909424, 0.024932861,
|
|
|
|
0.023910522, 0.022857666, 0.021789551, 0.020690918,
|
|
|
|
0.019577026, 0.018463135, 0.017349243, 0.016235352,
|
|
|
|
0.015121460, 0.014022827, 0.012939453, 0.011886597,
|
|
|
|
0.010848999, 0.009841919, 0.008865356, 0.007919312,
|
|
|
|
0.007003784, 0.006118774, 0.005294800, 0.004486084,
|
|
|
|
0.003723145, 0.003005981, 0.002334595, 0.001693726,
|
|
|
|
0.001098633, 0.000549316, 0.000030518,-0.000442505,
|
|
|
|
-0.000869751,-0.001266479,-0.001617432,-0.001937866,
|
|
|
|
-0.002227783,-0.002487183,-0.002700806,-0.002883911,
|
|
|
|
-0.003051758,-0.003173828,-0.003280640,-0.003372192,
|
|
|
|
-0.003417969,-0.003463745,-0.003479004,-0.003479004,
|
|
|
|
-0.003463745,-0.003433228,-0.003387451,-0.003326416,
|
|
|
|
0.003250122, 0.003173828, 0.003082275, 0.002990723,
|
|
|
|
0.002899170, 0.002792358, 0.002685547, 0.002578735,
|
|
|
|
0.002456665, 0.002349854, 0.002243042, 0.002120972,
|
|
|
|
0.002014160, 0.001907349, 0.001785278, 0.001693726,
|
|
|
|
0.001586914, 0.001480103, 0.001388550, 0.001296997,
|
|
|
|
0.001205444, 0.001113892, 0.001037598, 0.000961304,
|
|
|
|
0.000885010, 0.000808716, 0.000747681, 0.000686646,
|
|
|
|
0.000625610, 0.000579834, 0.000534058, 0.000473022,
|
|
|
|
0.000442505, 0.000396729, 0.000366211, 0.000320435,
|
|
|
|
0.000289917, 0.000259399, 0.000244141, 0.000213623,
|
|
|
|
0.000198364, 0.000167847, 0.000152588, 0.000137329,
|
|
|
|
0.000122070, 0.000106812, 0.000106812, 0.000091553,
|
|
|
|
0.000076294, 0.000076294, 0.000061035, 0.000061035,
|
|
|
|
0.000045776, 0.000045776, 0.000030518, 0.000030518,
|
|
|
|
0.000030518, 0.000030518, 0.000015259, 0.000015259,
|
|
|
|
0.000015259, 0.000015259, 0.000015259, 0.000015259,
|
|
|
|
//},g_synth_n_win[64][32]={
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2017-06-12 19:25:27 +02:00
|
|
|
static unsigned hsynth_init = 1,synth_init = 1;
|
2017-06-11 11:12:12 +02:00
|
|
|
|
|
|
|
/* Scale factor band indices
|
|
|
|
*
|
|
|
|
* One table per sample rate. Each table contains the frequency indices
|
|
|
|
* for the 12 short and 21 long scalefactor bands. The short indices
|
|
|
|
* must be multiplied by 3 to get the actual index.
|
|
|
|
*/
|
|
|
|
static const t_sf_band_indices g_sf_band_indices[3 /* Sampling freq. */] = {
|
|
|
|
{
|
|
|
|
{0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576},
|
|
|
|
{0,4,8,12,16,22,30,40,52,66,84,106,136,192}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576},
|
|
|
|
{0,4,8,12,16,22,28,38,50,64,80,100,126,192}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576},
|
|
|
|
{0,4,8,12,16,22,30,42,58,78,104,138,180,192}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-06-13 19:22:11 +02:00
|
|
|
t_mpeg1_header g_frame_header;
|
|
|
|
t_mpeg1_side_info g_side_info; /* < 100 words */
|
|
|
|
t_mpeg1_main_data g_main_data; /* Large static data(~2500 words) */
|
2017-06-11 11:12:12 +02:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
static void dmp_fr(t_mpeg1_header *hdr){
|
|
|
|
printf("rate %d,sfreq %d,pad %d,mod %d,modext %d,emph %d\n",
|
|
|
|
hdr->bitrate_index,hdr->sampling_frequency,hdr->padding_bit,
|
|
|
|
hdr->mode,hdr->mode_extension,hdr->emphasis);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dmp_si(t_mpeg1_header *hdr,t_mpeg1_side_info *si){
|
|
|
|
int nch,ch,gr;
|
|
|
|
|
|
|
|
nch = hdr->mode == mpeg1_mode_single_channel ? 1 : 2;
|
|
|
|
printf("main_data_begin %d,priv_bits %d\n",si->main_data_begin,si->private_bits);
|
|
|
|
for(ch = 0; ch < nch; ch++) {
|
|
|
|
printf("scfsi %d %d %d %d\n",si->scfsi[ch][0],si->scfsi[ch][1],si->scfsi[ch][2],si->scfsi[ch][3]);
|
|
|
|
for(gr = 0; gr < 2; gr++) {
|
|
|
|
printf("p23l %d,bv %d,gg %d,scfc %d,wsf %d,bt %d\n",
|
|
|
|
si->part2_3_length[gr][ch],si->big_values[gr][ch],
|
|
|
|
si->global_gain[gr][ch],si->scalefac_compress[gr][ch],
|
|
|
|
si->win_switch_flag[gr][ch],si->block_type[gr][ch]);
|
|
|
|
if(si->win_switch_flag[gr][ch]) {
|
|
|
|
printf("mbf %d,ts1 %d,ts2 %d,sbg1 %d,sbg2 %d,sbg3 %d\n",
|
|
|
|
si->mixed_block_flag[gr][ch],si->table_select[gr][ch][0],
|
|
|
|
si->table_select[gr][ch][1],si->subblock_gain[gr][ch][0],
|
|
|
|
si->subblock_gain[gr][ch][1],si->subblock_gain[gr][ch][2]);
|
|
|
|
}else{
|
|
|
|
printf("ts1 %d,ts2 %d,ts3 %d\n",si->table_select[gr][ch][0],
|
|
|
|
si->table_select[gr][ch][1],si->table_select[gr][ch][2]);
|
|
|
|
}
|
|
|
|
printf("r0c %d,r1c %d\n",si->region0_count[gr][ch],si->region1_count[gr][ch]);
|
|
|
|
printf("pf %d,scfs %d,c1ts %d\n",si->preflag[gr][ch],si->scalefac_scale[gr][ch],si->count1table_select[gr][ch]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dmp_scf(t_mpeg1_side_info *si,t_mpeg1_main_data *md,int gr,int ch){
|
|
|
|
int sfb,win;
|
|
|
|
|
|
|
|
if((si->win_switch_flag[gr][ch] != 0) &&(si->block_type[gr][ch] == 2)) {
|
|
|
|
if(si->mixed_block_flag[gr][ch] != 0) { /* First the long block scalefacs */
|
|
|
|
for(sfb = 0; sfb < 8; sfb++)
|
|
|
|
printf("scfl%d %d%s",sfb,md->scalefac_l[gr][ch][sfb],(sfb==7)?"\n":",");
|
|
|
|
for(sfb = 3; sfb < 12; sfb++) /* And next the short block scalefacs */
|
|
|
|
for(win = 0; win < 3; win++)
|
|
|
|
printf("scfs%d,%d %d%s",sfb,win,md->scalefac_s[gr][ch][sfb][win],(win==2)?"\n":",");
|
|
|
|
}else{ /* Just short blocks */
|
|
|
|
for(sfb = 0; sfb < 12; sfb++)
|
|
|
|
for(win = 0; win < 3; win++)
|
|
|
|
printf("scfs%d,%d %d%s",sfb,win,md->scalefac_s[gr][ch][sfb][win],(win==2)?"\n":",");
|
|
|
|
}
|
|
|
|
}else for(sfb = 0; sfb < 21; sfb++) /* Just long blocks; scalefacs first */
|
|
|
|
printf("scfl%d %d%s",sfb,md->scalefac_l[gr][ch][sfb], (sfb == 20)?"\n":",");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dmp_huff(t_mpeg1_main_data *md,int gr,int ch){
|
|
|
|
int i;
|
|
|
|
printf("HUFFMAN\n");
|
|
|
|
for(i = 0; i < 576; i++) printf("%d: %d\n",i,(int) md->is[gr][ch][i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dmp_samples(t_mpeg1_main_data *md,int gr,int ch,int type){
|
|
|
|
int i,val;
|
|
|
|
extern double rint(double);
|
|
|
|
|
|
|
|
printf("SAMPLES%d\n",type);
|
|
|
|
for(i = 0; i < 576; i++) {
|
|
|
|
val =(int) rint(md->is[gr][ch][i] * 32768.0);
|
|
|
|
if(val >= 32768) val = 32767;
|
|
|
|
if(val < -32768) val = -32768;
|
|
|
|
printf("%d: %d\n",i,val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**Description: calculates y=x^(4/3) when requantizing samples.
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static inline float Requantize_Pow_43(unsigned is_pos){
|
|
|
|
#ifdef POW34_TABLE
|
|
|
|
static float powtab34[8207];
|
|
|
|
static int init = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if(init == 0) { /* First time initialization */
|
|
|
|
for(i = 0; i < 8207; i++)
|
|
|
|
powtab34[i] = pow((float) i,4.0 / 3.0);
|
|
|
|
init = 1;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
|
|
if(is_pos > 8206) {
|
|
|
|
ERR("is_pos = %d larger than 8206!",is_pos);
|
|
|
|
is_pos = 8206;
|
|
|
|
}
|
|
|
|
#endif /* DEBUG */
|
|
|
|
return(powtab34[is_pos]); /* Done */
|
|
|
|
#elif defined POW34_ITERATE
|
|
|
|
float a4,a2,x,x2,x3,x_next,is_f1,is_f2,is_f3;
|
|
|
|
unsigned i;
|
|
|
|
//static unsigned init = 0;
|
|
|
|
//static float powtab34[32];
|
|
|
|
static float coeff[3] = {-1.030797119e+02,6.319399834e+00,2.395095071e-03};
|
|
|
|
//if(init == 0) { /* First time initialization */
|
|
|
|
// for(i = 0; i < 32; i++) powtab34[i] = pow((float) i,4.0 / 3.0);
|
|
|
|
// init = 1;
|
|
|
|
//}
|
|
|
|
/* We use a table for 0<is_pos<32 since they are so common */
|
|
|
|
if(is_pos < 32) return(powtab34[is_pos]);
|
|
|
|
a2 = is_pos * is_pos;
|
|
|
|
a4 = a2 * a2;
|
|
|
|
is_f1 =(float) is_pos;
|
|
|
|
is_f2 = is_f1 * is_f1;
|
|
|
|
is_f3 = is_f1 * is_f2;
|
|
|
|
/* x = coeff[0] + coeff[1]*is_f1 + coeff[2]*is_f2 + coeff[3]*is_f3; */
|
|
|
|
x = coeff[0] + coeff[1]*is_f1 + coeff[2]*is_f2;
|
|
|
|
for(i = 0; i < 3; i++) {
|
|
|
|
x2 = x*x;
|
|
|
|
x3 = x*x2;
|
|
|
|
x_next =(2*x3 + a4) /(3*x2);
|
|
|
|
x = x_next;
|
|
|
|
}
|
|
|
|
return(x);
|
|
|
|
#else /* no optimization */
|
|
|
|
return powf((float)is_pos,4.0f / 3.0f);
|
|
|
|
#endif /* POW34_TABLE || POW34_ITERATE */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: decodes a layer 3 bitstream into audio samples.
|
|
|
|
* Parameters: Outdata vector.
|
|
|
|
* Return value: OK or ERROR if the frame contains errors.
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
int Decode_L3(void){
|
|
|
|
unsigned gr,ch,nch,out[576];
|
|
|
|
|
|
|
|
/* Number of channels(1 for mono and 2 for stereo) */
|
|
|
|
nch =(g_frame_header.mode == mpeg1_mode_single_channel ? 1 : 2);
|
|
|
|
for(gr = 0; gr < 2; gr++) {
|
|
|
|
for(ch = 0; ch < nch; ch++) {
|
|
|
|
dmp_scf(&g_side_info,&g_main_data,gr,ch); //noop unless debug
|
|
|
|
dmp_huff(&g_main_data,gr,ch); //noop unless debug
|
|
|
|
L3_Requantize(gr,ch); /* Requantize samples */
|
|
|
|
dmp_samples(&g_main_data,gr,ch,0); //noop unless debug
|
|
|
|
L3_Reorder(gr,ch); /* Reorder short blocks */
|
|
|
|
} /* end for(ch... */
|
|
|
|
L3_Stereo(gr); /* Stereo processing */
|
|
|
|
dmp_samples(&g_main_data,gr,0,1); //noop unless debug
|
|
|
|
dmp_samples(&g_main_data,gr,1,1); //noop unless debug
|
|
|
|
for(ch = 0; ch < nch; ch++) {
|
|
|
|
L3_Antialias(gr,ch); /* Antialias */
|
|
|
|
dmp_samples(&g_main_data,gr,ch,2); //noop unless debug
|
|
|
|
L3_Hybrid_Synthesis(gr,ch); /*(IMDCT,windowing,overlapp add) */
|
|
|
|
L3_Frequency_Inversion(gr,ch); /* Frequency inversion */
|
|
|
|
dmp_samples(&g_main_data,gr,ch,3); //noop unless debug
|
|
|
|
L3_Subband_Synthesis(gr,ch,out); /* Polyphase subband synthesis */
|
|
|
|
} /* end for(ch... */
|
|
|
|
#ifdef DEBUG
|
|
|
|
{
|
|
|
|
int i,ctr = 0;
|
|
|
|
printf("PCM:\n");
|
|
|
|
for(i = 0; i < 576; i++) {
|
|
|
|
printf("%d: %d\n",ctr++,(out[i] >> 16) & 0xffff);
|
|
|
|
if(nch == 2) printf("%d: %d\n",ctr++,out[i] & 0xffff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* DEBUG */
|
|
|
|
/*FIXME - replace with simple interface stream*/
|
|
|
|
audio_write((unsigned *) out,576,
|
|
|
|
g_sampling_frequency[g_frame_header.sampling_frequency]);
|
|
|
|
} /* end for(gr... */
|
|
|
|
return(OK); /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: Search for next frame and read it into buffer. Main data in
|
|
|
|
this frame is saved for two frames since it might be needed by them.
|
|
|
|
* Parameters: None
|
|
|
|
* Return value: OK if a frame is successfully read,ERROR otherwise.
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
int Read_Frame(void){
|
|
|
|
unsigned first = 0;
|
|
|
|
|
|
|
|
if(Get_Filepos() == 0) Decode_L3_Init_Song();
|
|
|
|
/* Try to find the next frame in the bitstream and decode it */
|
|
|
|
if(Read_Header() != OK) return(ERROR);
|
|
|
|
#ifdef DEBUG
|
|
|
|
{ static int framenum = 0;
|
|
|
|
printf("\nFrame %d\n",framenum++);
|
|
|
|
dmp_fr(&g_frame_header);
|
|
|
|
}
|
|
|
|
DBG("Starting decode,Layer: %d,Rate: %6d,Sfreq: %05d",
|
|
|
|
g_frame_header.layer,
|
|
|
|
g_mpeg1_bitrates[g_frame_header.layer - 1][g_frame_header.bitrate_index],
|
|
|
|
g_sampling_frequency[g_frame_header.sampling_frequency]);
|
|
|
|
#endif
|
|
|
|
/* Get CRC word if present */
|
|
|
|
if((g_frame_header.protection_bit==0)&&(Read_CRC()!=OK)) return(ERROR);
|
|
|
|
if(g_frame_header.layer == 3) { /* Get audio data */
|
|
|
|
Read_Audio_L3(); /* Get side info */
|
|
|
|
dmp_si(&g_frame_header,&g_side_info); /* DEBUG */
|
|
|
|
/* If there's not enough main data in the bit reservoir,
|
|
|
|
* signal to calling function so that decoding isn't done! */
|
|
|
|
/* Get main data(scalefactors and Huffman coded frequency data) */
|
|
|
|
if(Read_Main_L3() != OK) return(ERROR);
|
|
|
|
}else{
|
|
|
|
ERR("Only layer 3(!= %d) is supported!\n",g_frame_header.layer);
|
|
|
|
return(ERROR);
|
|
|
|
}
|
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_header(unsigned header) {
|
|
|
|
/* Are the high 11 bits the syncword(0xffe)? */
|
|
|
|
if ((header & C_SYNC) != C_SYNC) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Bitrate must not be 15.
|
|
|
|
if ((header & (0xf<<12)) == 0xf<<12) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Sample Frequency must not be 3.
|
|
|
|
if ((header & (3<<10)) == 3<<10) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: Scans bitstream for syncword until we find it or EOF. The
|
|
|
|
syncword must be byte-aligned. It then reads and parses audio header.
|
|
|
|
* Parameters: None
|
|
|
|
* Return value: OK or ERROR if the syncword can't be found,or the header
|
|
|
|
* contains impossible values.
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static int Read_Header(void) {
|
|
|
|
unsigned b1,b2,b3,b4,header;
|
|
|
|
|
|
|
|
/* Get the next four bytes from the bitstream */
|
|
|
|
b1 = Get_Byte();
|
|
|
|
b2 = Get_Byte();
|
|
|
|
b3 = Get_Byte();
|
|
|
|
b4 = Get_Byte();
|
|
|
|
/* If we got an End Of File condition we're done */
|
|
|
|
if((b1==C_EOF)||(b2==C_EOF)||(b3==C_EOF)||(b4==C_EOF))
|
|
|
|
return(ERROR);
|
|
|
|
header =(b1 << 24) |(b2 << 16) |(b3 << 8) |(b4 << 0);
|
|
|
|
while(!is_header(header)) {
|
|
|
|
/* No,so scan the bitstream one byte at a time until we find it or EOF */
|
|
|
|
/* Shift the values one byte to the left */
|
|
|
|
b1 = b2;
|
|
|
|
b2 = b3;
|
|
|
|
b3 = b4;
|
|
|
|
/* Get one new byte from the bitstream */
|
|
|
|
b4 = Get_Byte();
|
|
|
|
/* If we got an End Of File condition we're done */
|
|
|
|
if(b4 == C_EOF) return(ERROR);
|
|
|
|
/* Make up the new header */
|
|
|
|
header = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0);
|
|
|
|
} /* while... */
|
|
|
|
/* If we get here we've found the sync word,and can decode the header
|
|
|
|
* which is in the low 20 bits of the 32-bit sync+header word. */
|
|
|
|
/* Decode the header */
|
|
|
|
g_frame_header.id =(header & 0x00180000) >> 19;
|
|
|
|
g_frame_header.layer =(header & 0x00060000) >> 17;
|
|
|
|
g_frame_header.protection_bit =(header & 0x00010000) >> 16;
|
|
|
|
g_frame_header.bitrate_index =(header & 0x0000f000) >> 12;
|
|
|
|
g_frame_header.sampling_frequency =(header & 0x00000c00) >> 10;
|
|
|
|
g_frame_header.padding_bit =(header & 0x00000200) >> 9;
|
|
|
|
g_frame_header.private_bit =(header & 0x00000100) >> 8;
|
|
|
|
g_frame_header.mode =(header & 0x000000c0) >> 6;
|
|
|
|
g_frame_header.mode_extension =(header & 0x00000030) >> 4;
|
|
|
|
g_frame_header.copyright =(header & 0x00000008) >> 3;
|
|
|
|
g_frame_header.original_or_copy =(header & 0x00000004) >> 2;
|
|
|
|
g_frame_header.emphasis =(header & 0x00000003) >> 0;
|
|
|
|
/* Check for invalid values and impossible combinations */
|
|
|
|
if(g_frame_header.id != 3) {
|
|
|
|
ERR("ID must be 3\nHeader word is 0x%08x at file pos %d\n",header,Get_Filepos());
|
|
|
|
return(ERROR);
|
|
|
|
}
|
|
|
|
if(g_frame_header.bitrate_index == 0) {
|
|
|
|
ERR("Free bitrate format NIY!\nHeader word is 0x%08x at file pos %d\n",header,Get_Filepos());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if(g_frame_header.bitrate_index == 15) {
|
|
|
|
ERR("bitrate_index = 15 is invalid!\nHeader word is 0x%08x at file pos %d\n",header,Get_Filepos());
|
|
|
|
return(ERROR);
|
|
|
|
}
|
|
|
|
if(g_frame_header.sampling_frequency == 3) {
|
|
|
|
ERR("sampling_frequency = 3 is invalid!\n");
|
|
|
|
ERR("Header word is 0x%08x at file pos %d\n",header,Get_Filepos());
|
|
|
|
return(ERROR);
|
|
|
|
}
|
|
|
|
if(g_frame_header.layer == 0) {
|
|
|
|
ERR("layer = 0 is invalid!\n");
|
|
|
|
ERR("Header word is 0x%08x at file pos %d\n",header,
|
|
|
|
Get_Filepos());
|
|
|
|
return(ERROR);
|
|
|
|
}
|
|
|
|
g_frame_header.layer = 4 - g_frame_header.layer;
|
|
|
|
/* DBG("Header = 0x%08x\n",header); */
|
|
|
|
return(OK); /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: reads main data for layer 3 from main_data bit reservoir.
|
|
|
|
* Parameters: None
|
|
|
|
* Return value: OK or ERROR if the data contains errors.
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static int Read_Main_L3(void){
|
|
|
|
unsigned framesize,sideinfo_size,main_data_size,gr,ch,nch,sfb,win,slen1,slen2,nbits,part_2_start;
|
|
|
|
|
|
|
|
/* Number of channels(1 for mono and 2 for stereo) */
|
|
|
|
nch =(g_frame_header.mode == mpeg1_mode_single_channel ? 1 : 2);
|
|
|
|
|
|
|
|
/* Calculate header audio data size */
|
|
|
|
framesize = (144 *
|
|
|
|
g_mpeg1_bitrates[g_frame_header.layer-1][g_frame_header.bitrate_index]) /
|
|
|
|
g_sampling_frequency[g_frame_header.sampling_frequency] +
|
|
|
|
g_frame_header.padding_bit;
|
|
|
|
|
|
|
|
if(framesize > 2000) {
|
|
|
|
ERR("framesize = %d\n",framesize);
|
|
|
|
return(ERROR);
|
|
|
|
}
|
|
|
|
/* Sideinfo is 17 bytes for one channel and 32 bytes for two */
|
|
|
|
sideinfo_size =(nch == 1 ? 17 : 32);
|
|
|
|
/* Main data size is the rest of the frame,including ancillary data */
|
|
|
|
main_data_size = framesize - sideinfo_size - 4 /* sync+header */;
|
|
|
|
/* CRC is 2 bytes */
|
|
|
|
if(g_frame_header.protection_bit == 0) main_data_size -= 2;
|
|
|
|
/* Assemble main data buffer with data from this frame and the previous
|
|
|
|
* two frames. main_data_begin indicates how many bytes from previous
|
|
|
|
* frames that should be used. This buffer is later accessed by the
|
|
|
|
* Get_Main_Bits function in the same way as the side info is.
|
|
|
|
*/
|
|
|
|
if(Get_Main_Data(main_data_size,g_side_info.main_data_begin) != OK)
|
|
|
|
return(ERROR); /* This could be due to not enough data in reservoir */
|
|
|
|
for(gr = 0; gr < 2; gr++) {
|
|
|
|
for(ch = 0; ch < nch; ch++) {
|
|
|
|
part_2_start = Get_Main_Pos();
|
|
|
|
/* Number of bits in the bitstream for the bands */
|
|
|
|
slen1 = mpeg1_scalefac_sizes[g_side_info.scalefac_compress[gr][ch]][0];
|
|
|
|
slen2 = mpeg1_scalefac_sizes[g_side_info.scalefac_compress[gr][ch]][1];
|
|
|
|
if((g_side_info.win_switch_flag[gr][ch] != 0)&&(g_side_info.block_type[gr][ch] == 2)) {
|
|
|
|
if(g_side_info.mixed_block_flag[gr][ch] != 0) {
|
|
|
|
for(sfb = 0; sfb < 8; sfb++)
|
|
|
|
g_main_data.scalefac_l[gr][ch][sfb] = Get_Main_Bits(slen1);
|
|
|
|
for(sfb = 3; sfb < 12; sfb++) {
|
|
|
|
nbits = (sfb < 6)?slen1:slen2;/*slen1 for band 3-5,slen2 for 6-11*/
|
|
|
|
for(win = 0; win < 3; win++)
|
|
|
|
g_main_data.scalefac_s[gr][ch][sfb][win]=Get_Main_Bits(nbits);
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
for(sfb = 0; sfb < 12; sfb++){
|
|
|
|
nbits = (sfb < 6)?slen1:slen2;/*slen1 for band 3-5,slen2 for 6-11*/
|
|
|
|
for(win = 0; win < 3; win++)
|
|
|
|
g_main_data.scalefac_s[gr][ch][sfb][win]=Get_Main_Bits(nbits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{ /* block_type == 0 if winswitch == 0 */
|
|
|
|
/* Scale factor bands 0-5 */
|
|
|
|
if((g_side_info.scfsi[ch][0] == 0) ||(gr == 0)) {
|
|
|
|
for(sfb = 0; sfb < 6; sfb++)
|
|
|
|
g_main_data.scalefac_l[gr][ch][sfb] = Get_Main_Bits(slen1);
|
|
|
|
}else if((g_side_info.scfsi[ch][0] == 1) &&(gr == 1)) {
|
|
|
|
/* Copy scalefactors from granule 0 to granule 1 */
|
|
|
|
for(sfb = 0; sfb < 6; sfb++)
|
|
|
|
g_main_data.scalefac_l[1][ch][sfb]=g_main_data.scalefac_l[0][ch][sfb];
|
|
|
|
}
|
|
|
|
/* Scale factor bands 6-10 */
|
|
|
|
if((g_side_info.scfsi[ch][1] == 0) ||(gr == 0)) {
|
|
|
|
for(sfb = 6; sfb < 11; sfb++)
|
|
|
|
g_main_data.scalefac_l[gr][ch][sfb] = Get_Main_Bits(slen1);
|
|
|
|
}else if((g_side_info.scfsi[ch][1] == 1) &&(gr == 1)) {
|
|
|
|
/* Copy scalefactors from granule 0 to granule 1 */
|
|
|
|
for(sfb = 6; sfb < 11; sfb++)
|
|
|
|
g_main_data.scalefac_l[1][ch][sfb]=g_main_data.scalefac_l[0][ch][sfb];
|
|
|
|
}
|
|
|
|
/* Scale factor bands 11-15 */
|
|
|
|
if((g_side_info.scfsi[ch][2] == 0) ||(gr == 0)) {
|
|
|
|
for(sfb = 11; sfb < 16; sfb++)
|
|
|
|
g_main_data.scalefac_l[gr][ch][sfb] = Get_Main_Bits(slen2);
|
|
|
|
} else if((g_side_info.scfsi[ch][2] == 1) &&(gr == 1)) {
|
|
|
|
/* Copy scalefactors from granule 0 to granule 1 */
|
|
|
|
for(sfb = 11; sfb < 16; sfb++)
|
|
|
|
g_main_data.scalefac_l[1][ch][sfb]=g_main_data.scalefac_l[0][ch][sfb];
|
|
|
|
}
|
|
|
|
/* Scale factor bands 16-20 */
|
|
|
|
if((g_side_info.scfsi[ch][3] == 0) ||(gr == 0)) {
|
|
|
|
for(sfb = 16; sfb < 21; sfb++)
|
|
|
|
g_main_data.scalefac_l[gr][ch][sfb] = Get_Main_Bits(slen2);
|
|
|
|
}else if((g_side_info.scfsi[ch][3] == 1) &&(gr == 1)) {
|
|
|
|
/* Copy scalefactors from granule 0 to granule 1 */
|
|
|
|
for(sfb = 16; sfb < 21; sfb++)
|
|
|
|
g_main_data.scalefac_l[1][ch][sfb]=g_main_data.scalefac_l[0][ch][sfb];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Read Huffman coded data. Skip stuffing bits. */
|
|
|
|
Read_Huffman(part_2_start,gr,ch);
|
|
|
|
} /* end for(gr... */
|
|
|
|
} /* end for(ch... */
|
|
|
|
/* The ancillary data is stored here,but we ignore it. */
|
|
|
|
return(OK); /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Error(const char *s,int e){
|
|
|
|
(void) fwrite(s,1,strlen(s),stderr);
|
|
|
|
exit(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: reinit decoder before playing new song,or seeking current song.
|
|
|
|
* Parameters: None
|
|
|
|
* Return value: None
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Decode_L3_Init_Song(void){
|
|
|
|
hsynth_init = synth_init = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Antialias(unsigned gr,unsigned ch){
|
|
|
|
unsigned sb /* subband of 18 samples */,i,sblim,ui,li;
|
|
|
|
float ub,lb;
|
|
|
|
|
|
|
|
/* No antialiasing is done for short blocks */
|
|
|
|
if((g_side_info.win_switch_flag[gr][ch] == 1) &&
|
|
|
|
(g_side_info.block_type[gr][ch] == 2) &&
|
|
|
|
(g_side_info.mixed_block_flag[gr][ch]) == 0) {
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
/* Setup the limit for how many subbands to transform */
|
|
|
|
sblim =((g_side_info.win_switch_flag[gr][ch] == 1) &&
|
|
|
|
(g_side_info.block_type[gr][ch] == 2) &&
|
|
|
|
(g_side_info.mixed_block_flag[gr][ch] == 1))?2:32;
|
|
|
|
/* Do the actual antialiasing */
|
|
|
|
for(sb = 1; sb < sblim; sb++) {
|
|
|
|
for(i = 0; i < 8; i++) {
|
|
|
|
li = 18*sb-1-i;
|
|
|
|
ui = 18*sb+i;
|
|
|
|
lb = g_main_data.is[gr][ch][li]*cs[i] - g_main_data.is[gr][ch][ui]*ca[i];
|
|
|
|
ub = g_main_data.is[gr][ch][ui]*cs[i] + g_main_data.is[gr][ch][li]*ca[i];
|
|
|
|
g_main_data.is[gr][ch][li] = lb;
|
|
|
|
g_main_data.is[gr][ch][ui] = ub;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Frequency_Inversion(unsigned gr,unsigned ch){
|
|
|
|
unsigned sb,i;
|
|
|
|
|
|
|
|
for(sb = 1; sb < 32; sb += 2) { //OPT? : for(sb = 18; sb < 576; sb += 36)
|
|
|
|
for(i = 1; i < 18; i += 2)
|
|
|
|
g_main_data.is[gr][ch][sb*18 + i] = -g_main_data.is[gr][ch][sb*18 + i];
|
|
|
|
}
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Hybrid_Synthesis(unsigned gr,unsigned ch){
|
|
|
|
unsigned sb,i,j,bt;
|
|
|
|
float rawout[36];
|
|
|
|
static float store[2][32][18];
|
|
|
|
|
|
|
|
if(hsynth_init) { /* Clear stored samples vector. OPT? use memset */
|
|
|
|
for(j = 0; j < 2; j++) {
|
|
|
|
for(sb = 0; sb < 32; sb++) {
|
|
|
|
for(i = 0; i < 18; i++) {
|
|
|
|
store[j][sb][i] = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hsynth_init = 0;
|
|
|
|
} /* end if(hsynth_init) */
|
|
|
|
for(sb = 0; sb < 32; sb++) { /* Loop through all 32 subbands */
|
|
|
|
/* Determine blocktype for this subband */
|
|
|
|
bt =((g_side_info.win_switch_flag[gr][ch] == 1) &&
|
|
|
|
(g_side_info.mixed_block_flag[gr][ch] == 1) &&(sb < 2))
|
|
|
|
? 0 : g_side_info.block_type[gr][ch];
|
|
|
|
/* Do the inverse modified DCT and windowing */
|
|
|
|
IMDCT_Win(&(g_main_data.is[gr][ch][sb*18]),rawout,bt);
|
|
|
|
for(i = 0; i < 18; i++) { /* Overlapp add with stored vector into main_data vector */
|
|
|
|
g_main_data.is[gr][ch][sb*18 + i] = rawout[i] + store[ch][sb][i];
|
|
|
|
store[ch][sb][i] = rawout[i + 18];
|
|
|
|
} /* end for(i... */
|
|
|
|
} /* end for(sb... */
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Reorder(unsigned gr,unsigned ch){
|
|
|
|
unsigned sfreq,i,j,next_sfb,sfb,win_len,win;
|
|
|
|
float re[576];
|
|
|
|
|
|
|
|
sfreq = g_frame_header.sampling_frequency; /* Setup sampling freq index */
|
|
|
|
/* Only reorder short blocks */
|
|
|
|
if((g_side_info.win_switch_flag[gr][ch] == 1) &&
|
|
|
|
(g_side_info.block_type[gr][ch] == 2)) { /* Short blocks */
|
|
|
|
/* Check if the first two subbands
|
|
|
|
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
|
|
|
|
sfb = (g_side_info.mixed_block_flag[gr][ch] != 0)?3:0; /* 2 longbl. sb first */
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].s[sfb+1] * 3;
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] - g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
for(i =((sfb == 0) ? 0 : 36); i < 576; /* i++ done below! */) {
|
|
|
|
/* Check if we're into the next scalefac band */
|
|
|
|
if(i == next_sfb) { /* Yes */
|
|
|
|
/* Copy reordered data back to the original vector */
|
|
|
|
for(j = 0; j < 3*win_len; j++)
|
|
|
|
g_main_data.is[gr][ch][3*g_sf_band_indices[sfreq].s[sfb] + j] = re[j];
|
|
|
|
/* Check if this band is above the rzero region,if so we're done */
|
|
|
|
if(i >= g_side_info.count1[gr][ch]) return; /* Done */
|
|
|
|
sfb++;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].s[sfb+1] * 3;
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] - g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
} /* end if(next_sfb) */
|
|
|
|
for(win = 0; win < 3; win++) { /* Do the actual reordering */
|
|
|
|
for(j = 0; j < win_len; j++) {
|
|
|
|
re[j*3 + win] = g_main_data.is[gr][ch][i];
|
|
|
|
i++;
|
|
|
|
} /* end for(j... */
|
|
|
|
} /* end for(win... */
|
|
|
|
} /* end for(i... */
|
|
|
|
/* Copy reordered data of last band back to original vector */
|
|
|
|
for(j = 0; j < 3*win_len; j++)
|
|
|
|
g_main_data.is[gr][ch][3 * g_sf_band_indices[sfreq].s[12] + j] = re[j];
|
|
|
|
} /* end else(only long blocks) */
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Requantize(unsigned gr,unsigned ch){
|
|
|
|
unsigned sfb /* scalefac band index */,next_sfb /* frequency of next sfb */,
|
|
|
|
sfreq,i,j,win,win_len;
|
|
|
|
|
|
|
|
/* Setup sampling frequency index */
|
|
|
|
sfreq = g_frame_header.sampling_frequency;
|
|
|
|
/* Determine type of block to process */
|
|
|
|
if((g_side_info.win_switch_flag[gr][ch] == 1) && (g_side_info.block_type[gr][ch] == 2)) { /* Short blocks */
|
|
|
|
/* Check if the first two subbands
|
|
|
|
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
|
|
|
|
if(g_side_info.mixed_block_flag[gr][ch] != 0) { /* 2 longbl. sb first */
|
|
|
|
/* First process the 2 long block subbands at the start */
|
|
|
|
sfb = 0;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].l[sfb+1];
|
|
|
|
for(i = 0; i < 36; i++) {
|
|
|
|
if(i == next_sfb) {
|
|
|
|
sfb++;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].l[sfb+1];
|
|
|
|
} /* end if */
|
|
|
|
Requantize_Process_Long(gr,ch,i,sfb);
|
|
|
|
}
|
|
|
|
/* And next the remaining,non-zero,bands which uses short blocks */
|
|
|
|
sfb = 3;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].s[sfb+1] * 3;
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] -
|
|
|
|
g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
|
|
|
|
for(i = 36; i < g_side_info.count1[gr][ch]; /* i++ done below! */) {
|
|
|
|
/* Check if we're into the next scalefac band */
|
|
|
|
if(i == next_sfb) { /* Yes */
|
|
|
|
sfb++;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].s[sfb+1] * 3;
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] -
|
|
|
|
g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
} /* end if(next_sfb) */
|
|
|
|
for(win = 0; win < 3; win++) {
|
|
|
|
for(j = 0; j < win_len; j++) {
|
|
|
|
Requantize_Process_Short(gr,ch,i,sfb,win);
|
|
|
|
i++;
|
|
|
|
} /* end for(j... */
|
|
|
|
} /* end for(win... */
|
|
|
|
|
|
|
|
} /* end for(i... */
|
|
|
|
}else{ /* Only short blocks */
|
|
|
|
sfb = 0;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].s[sfb+1] * 3;
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] -
|
|
|
|
g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
for(i = 0; i < g_side_info.count1[gr][ch]; /* i++ done below! */) {
|
|
|
|
/* Check if we're into the next scalefac band */
|
|
|
|
if(i == next_sfb) { /* Yes */
|
|
|
|
sfb++;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].s[sfb+1] * 3;
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] -
|
|
|
|
g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
} /* end if(next_sfb) */
|
|
|
|
for(win = 0; win < 3; win++) {
|
|
|
|
for(j = 0; j < win_len; j++) {
|
|
|
|
Requantize_Process_Short(gr,ch,i,sfb,win);
|
|
|
|
i++;
|
|
|
|
} /* end for(j... */
|
|
|
|
} /* end for(win... */
|
|
|
|
} /* end for(i... */
|
|
|
|
} /* end else(only short blocks) */
|
|
|
|
}else{ /* Only long blocks */
|
|
|
|
sfb = 0;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].l[sfb+1];
|
|
|
|
for(i = 0; i < g_side_info.count1[gr][ch]; i++) {
|
|
|
|
if(i == next_sfb) {
|
|
|
|
sfb++;
|
|
|
|
next_sfb = g_sf_band_indices[sfreq].l[sfb+1];
|
|
|
|
} /* end if */
|
|
|
|
Requantize_Process_Long(gr,ch,i,sfb);
|
|
|
|
}
|
|
|
|
} /* end else(only long blocks) */
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Stereo(unsigned gr){
|
|
|
|
unsigned max_pos,i,sfreq,sfb /* scalefac band index */;
|
|
|
|
float left,right;
|
|
|
|
|
|
|
|
/* Do nothing if joint stereo is not enabled */
|
|
|
|
if((g_frame_header.mode != 1)||(g_frame_header.mode_extension == 0)) return;
|
|
|
|
/* Do Middle/Side("normal") stereo processing */
|
|
|
|
if(g_frame_header.mode_extension & 0x2) {
|
|
|
|
/* Determine how many frequency lines to transform */
|
|
|
|
max_pos = g_side_info.count1[gr][!!(g_side_info.count1[gr][0] > g_side_info.count1[gr][1])];
|
|
|
|
/* Do the actual processing */
|
|
|
|
for(i = 0; i < max_pos; i++) {
|
|
|
|
left =(g_main_data.is[gr][0][i] + g_main_data.is[gr][1][i])
|
|
|
|
*(C_INV_SQRT_2);
|
|
|
|
right =(g_main_data.is[gr][0][i] - g_main_data.is[gr][1][i])
|
|
|
|
*(C_INV_SQRT_2);
|
|
|
|
g_main_data.is[gr][0][i] = left;
|
|
|
|
g_main_data.is[gr][1][i] = right;
|
|
|
|
} /* end for(i... */
|
|
|
|
} /* end if(ms_stereo... */
|
|
|
|
/* Do intensity stereo processing */
|
|
|
|
if(g_frame_header.mode_extension & 0x1) {
|
|
|
|
/* Setup sampling frequency index */
|
|
|
|
sfreq = g_frame_header.sampling_frequency;
|
|
|
|
/* First band that is intensity stereo encoded is first band scale factor
|
|
|
|
* band on or above count1 frequency line. N.B.: Intensity stereo coding is
|
|
|
|
* only done for higher subbands, but logic is here for lower subbands. */
|
|
|
|
/* Determine type of block to process */
|
|
|
|
if((g_side_info.win_switch_flag[gr][0] == 1) &&
|
|
|
|
(g_side_info.block_type[gr][0] == 2)) { /* Short blocks */
|
|
|
|
/* Check if the first two subbands
|
|
|
|
*(=2*18 samples = 8 long or 3 short sfb's) uses long blocks */
|
|
|
|
if(g_side_info.mixed_block_flag[gr][0] != 0) { /* 2 longbl. sb first */
|
|
|
|
for(sfb = 0; sfb < 8; sfb++) {/* First process 8 sfb's at start */
|
|
|
|
/* Is this scale factor band above count1 for the right channel? */
|
|
|
|
if(g_sf_band_indices[sfreq].l[sfb] >= g_side_info.count1[gr][1])
|
|
|
|
Stereo_Process_Intensity_Long(gr,sfb);
|
|
|
|
} /* end if(sfb... */
|
|
|
|
/* And next the remaining bands which uses short blocks */
|
|
|
|
for(sfb = 3; sfb < 12; sfb++) {
|
|
|
|
/* Is this scale factor band above count1 for the right channel? */
|
|
|
|
if(g_sf_band_indices[sfreq].s[sfb]*3 >= g_side_info.count1[gr][1])
|
|
|
|
Stereo_Process_Intensity_Short(gr,sfb); /* intensity stereo processing */
|
|
|
|
}
|
|
|
|
}else{ /* Only short blocks */
|
|
|
|
for(sfb = 0; sfb < 12; sfb++) {
|
|
|
|
/* Is this scale factor band above count1 for the right channel? */
|
|
|
|
if(g_sf_band_indices[sfreq].s[sfb]*3 >= g_side_info.count1[gr][1])
|
|
|
|
Stereo_Process_Intensity_Short(gr,sfb); /* intensity stereo processing */
|
|
|
|
}
|
|
|
|
} /* end else(only short blocks) */
|
|
|
|
}else{ /* Only long blocks */
|
|
|
|
for(sfb = 0; sfb < 21; sfb++) {
|
|
|
|
/* Is this scale factor band above count1 for the right channel? */
|
|
|
|
if(g_sf_band_indices[sfreq].l[sfb] >= g_side_info.count1[gr][1]) {
|
|
|
|
/* Perform the intensity stereo processing */
|
|
|
|
Stereo_Process_Intensity_Long(gr,sfb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* end else(only long blocks) */
|
|
|
|
} /* end if(intensity_stereo processing) */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: TBD
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void L3_Subband_Synthesis(unsigned gr,unsigned ch,unsigned outdata[576]){
|
|
|
|
float u_vec[512],s_vec[32],sum; /* u_vec can be used insted of s_vec */
|
|
|
|
int32_t samp;
|
|
|
|
static unsigned init = 1;
|
|
|
|
unsigned i,j,ss,nch;
|
|
|
|
static float g_synth_n_win[64][32],v_vec[2 /* ch */][1024];
|
|
|
|
|
|
|
|
/* Number of channels(1 for mono and 2 for stereo) */
|
|
|
|
nch =(g_frame_header.mode == mpeg1_mode_single_channel) ? 1 : 2 ;
|
|
|
|
/* Setup the n_win windowing vector and the v_vec intermediate vector */
|
|
|
|
|
|
|
|
if(init) {
|
|
|
|
for(i = 0; i < 64; i++) {
|
|
|
|
for(j = 0; j < 32; j++) /*TODO: put in lookup table*/
|
|
|
|
g_synth_n_win[i][j] = cos(((float)(16+i)*(2*j+1)) *(C_PI/64.0));
|
|
|
|
}
|
|
|
|
for(i = 0; i < 2; i++) /* Setup the v_vec intermediate vector */
|
|
|
|
for(j = 0; j < 1024; j++) v_vec[i][j] = 0.0; /*TODO: memset */
|
|
|
|
init = 0;
|
|
|
|
} /* end if(init) */
|
|
|
|
|
|
|
|
if(synth_init) {
|
|
|
|
for(i = 0; i < 2; i++) /* Setup the v_vec intermediate vector */
|
|
|
|
for(j = 0; j < 1024; j++) v_vec[i][j] = 0.0; /*TODO: memset*/
|
|
|
|
synth_init = 0;
|
|
|
|
} /* end if(synth_init) */
|
|
|
|
|
|
|
|
for(ss = 0; ss < 18; ss++){ /* Loop through 18 samples in 32 subbands */
|
|
|
|
for(i = 1023; i > 63; i--) /* Shift up the V vector */
|
|
|
|
v_vec[ch][i] = v_vec[ch][i-64];
|
|
|
|
for(i = 0; i < 32; i++) /* Copy next 32 time samples to a temp vector */
|
|
|
|
s_vec[i] =((float) g_main_data.is[gr][ch][i*18 + ss]);
|
|
|
|
for(i = 0; i < 64; i++){ /* Matrix multiply input with n_win[][] matrix */
|
|
|
|
sum = 0.0;
|
|
|
|
for(j = 0; j < 32; j++) sum += g_synth_n_win[i][j] * s_vec[j];
|
|
|
|
v_vec[ch][i] = sum;
|
|
|
|
} /* end for(i... */
|
|
|
|
for(i = 0; i < 8; i++) { /* Build the U vector */
|
|
|
|
for(j = 0; j < 32; j++) { /* <<7 == *128 */
|
|
|
|
u_vec[(i << 6) + j] = v_vec[ch][(i << 7) + j];
|
|
|
|
u_vec[(i << 6) + j + 32] = v_vec[ch][(i << 7) + j + 96];
|
|
|
|
}
|
|
|
|
} /* end for(i... */
|
|
|
|
for(i = 0; i < 512; i++) /* Window by u_vec[i] with g_synth_dtbl[i] */
|
|
|
|
u_vec[i] = u_vec[i] * g_synth_dtbl[i];
|
|
|
|
for(i = 0; i < 32; i++) { /* Calc 32 samples,store in outdata vector */
|
|
|
|
sum = 0.0;
|
|
|
|
for(j = 0; j < 16; j++) /* sum += u_vec[j*32 + i]; */
|
|
|
|
sum += u_vec[(j << 5) + i];
|
|
|
|
/* sum now contains time sample 32*ss+i. Convert to 16-bit signed int */
|
|
|
|
samp =(int32_t)(sum * 32767.0);
|
|
|
|
if(samp > 32767) samp = 32767;
|
|
|
|
else if(samp < -32767) samp = -32767;
|
|
|
|
samp &= 0xffff;
|
|
|
|
if(ch == 0) { /* This function must be called for channel 0 first */
|
|
|
|
/* We always run in stereo mode,& duplicate channels here for mono */
|
|
|
|
if(nch == 1) {
|
|
|
|
outdata[32*ss + i] =(samp << 16) |(samp);
|
|
|
|
}else{
|
|
|
|
outdata[32*ss + i] = samp << 16;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
outdata[32*ss + i] |= samp;
|
|
|
|
}
|
|
|
|
} /* end for(i... */
|
|
|
|
} /* end for(ss... */
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: called by Read_Main_L3 to read Huffman coded data from bitstream.
|
|
|
|
* Parameters: None
|
|
|
|
* Return value: None. The data is stored in g_main_data.is[ch][gr][freqline].
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Read_Huffman(unsigned part_2_start,unsigned gr,unsigned ch){
|
|
|
|
int32_t x,y,v,w;
|
|
|
|
unsigned table_num,is_pos,bit_pos_end,sfreq;
|
|
|
|
unsigned region_1_start,region_2_start; /* region_0_start = 0 */
|
|
|
|
|
|
|
|
/* Check that there is any data to decode. If not,zero the array. */
|
|
|
|
if(g_side_info.part2_3_length[gr][ch] == 0) {
|
|
|
|
for(is_pos = 0; is_pos < 576; is_pos++)
|
|
|
|
g_main_data.is[gr][ch][is_pos] = 0.0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Calculate bit_pos_end which is the index of the last bit for this part. */
|
|
|
|
bit_pos_end = part_2_start + g_side_info.part2_3_length[gr][ch] - 1;
|
|
|
|
/* Determine region boundaries */
|
|
|
|
if((g_side_info.win_switch_flag[gr][ch] == 1)&&
|
|
|
|
(g_side_info.block_type[gr][ch] == 2)) {
|
|
|
|
region_1_start = 36; /* sfb[9/3]*3=36 */
|
|
|
|
region_2_start = 576; /* No Region2 for short block case. */
|
|
|
|
}else{
|
|
|
|
sfreq = g_frame_header.sampling_frequency;
|
|
|
|
region_1_start =
|
|
|
|
g_sf_band_indices[sfreq].l[g_side_info.region0_count[gr][ch] + 1];
|
|
|
|
region_2_start =
|
|
|
|
g_sf_band_indices[sfreq].l[g_side_info.region0_count[gr][ch] +
|
|
|
|
g_side_info.region1_count[gr][ch] + 2];
|
|
|
|
}
|
|
|
|
/* Read big_values using tables according to region_x_start */
|
|
|
|
for(is_pos = 0; is_pos < g_side_info.big_values[gr][ch] * 2; is_pos++) {
|
|
|
|
if(is_pos < region_1_start) {
|
|
|
|
table_num = g_side_info.table_select[gr][ch][0];
|
|
|
|
} else if(is_pos < region_2_start) {
|
|
|
|
table_num = g_side_info.table_select[gr][ch][1];
|
|
|
|
}else table_num = g_side_info.table_select[gr][ch][2];
|
|
|
|
/* Get next Huffman coded words */
|
|
|
|
(void) Huffman_Decode(table_num,&x,&y,&v,&w);
|
|
|
|
/* In the big_values area there are two freq lines per Huffman word */
|
|
|
|
g_main_data.is[gr][ch][is_pos++] = x;
|
|
|
|
g_main_data.is[gr][ch][is_pos] = y;
|
|
|
|
}
|
|
|
|
/* Read small values until is_pos = 576 or we run out of huffman data */
|
|
|
|
table_num = g_side_info.count1table_select[gr][ch] + 32;
|
|
|
|
for(is_pos = g_side_info.big_values[gr][ch] * 2;
|
|
|
|
(is_pos <= 572) &&(Get_Main_Pos() <= bit_pos_end); is_pos++) {
|
|
|
|
/* Get next Huffman coded words */
|
|
|
|
(void) Huffman_Decode(table_num,&x,&y,&v,&w);
|
|
|
|
g_main_data.is[gr][ch][is_pos++] = v;
|
|
|
|
if(is_pos >= 576) break;
|
|
|
|
g_main_data.is[gr][ch][is_pos++] = w;
|
|
|
|
if(is_pos >= 576) break;
|
|
|
|
g_main_data.is[gr][ch][is_pos++] = x;
|
|
|
|
if(is_pos >= 576) break;
|
|
|
|
g_main_data.is[gr][ch][is_pos] = y;
|
|
|
|
}
|
|
|
|
/* Check that we didn't read past the end of this section */
|
|
|
|
if(Get_Main_Pos() >(bit_pos_end+1)) /* Remove last words read */
|
|
|
|
is_pos -= 4;
|
|
|
|
/* Setup count1 which is the index of the first sample in the rzero reg. */
|
|
|
|
g_side_info.count1[gr][ch] = is_pos;
|
|
|
|
/* Zero out the last part if necessary */
|
|
|
|
for(/* is_pos comes from last for-loop */; is_pos < 576; is_pos++)
|
|
|
|
g_main_data.is[gr][ch][is_pos] = 0.0;
|
|
|
|
/* Set the bitpos to point to the next part to read */
|
|
|
|
(void) Set_Main_Pos(bit_pos_end+1);
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: requantize sample in subband that uses long blocks.
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Requantize_Process_Long(unsigned gr,unsigned ch,unsigned is_pos,unsigned sfb){
|
|
|
|
float res,tmp1,tmp2,tmp3,sf_mult,pf_x_pt;
|
|
|
|
static float pretab[21] = { 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2 };
|
|
|
|
|
|
|
|
sf_mult = g_side_info.scalefac_scale[gr][ch] ? 1.0 : 0.5;
|
|
|
|
pf_x_pt = g_side_info.preflag[gr][ch] * pretab[sfb];
|
|
|
|
tmp1 = pow(2.0,-(sf_mult *(g_main_data.scalefac_l[gr][ch][sfb] + pf_x_pt)));
|
|
|
|
tmp2 = pow(2.0,0.25 *((int32_t) g_side_info.global_gain[gr][ch] - 210));
|
|
|
|
if(g_main_data.is[gr][ch][is_pos] < 0.0)
|
|
|
|
tmp3 = -Requantize_Pow_43(-g_main_data.is[gr][ch][is_pos]);
|
|
|
|
else tmp3 = Requantize_Pow_43(g_main_data.is[gr][ch][is_pos]);
|
|
|
|
res = g_main_data.is[gr][ch][is_pos] = tmp1 * tmp2 * tmp3;
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: requantize sample in subband that uses short blocks.
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Requantize_Process_Short(unsigned gr,unsigned ch,unsigned is_pos,unsigned sfb,unsigned win){
|
|
|
|
float res,tmp1,tmp2,tmp3,sf_mult;
|
|
|
|
|
|
|
|
sf_mult = g_side_info.scalefac_scale[gr][ch] ? 1.0f : 0.5f;
|
|
|
|
tmp1 = pow(2.0f,-(sf_mult * g_main_data.scalefac_s[gr][ch][sfb][win]));
|
|
|
|
tmp2 = pow(2.0f,0.25f *((float) g_side_info.global_gain[gr][ch] - 210.0f -
|
|
|
|
8.0f *(float) g_side_info.subblock_gain[gr][ch][win]));
|
|
|
|
tmp3 =(g_main_data.is[gr][ch][is_pos] < 0.0)
|
|
|
|
? -Requantize_Pow_43(-g_main_data.is[gr][ch][is_pos])
|
|
|
|
: Requantize_Pow_43(g_main_data.is[gr][ch][is_pos]);
|
|
|
|
res = g_main_data.is[gr][ch][is_pos] = tmp1 * tmp2 * tmp3;
|
|
|
|
return; /* Done */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**Description: intensity stereo processing for entire subband with long blocks.
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Stereo_Process_Intensity_Long(unsigned gr,unsigned sfb){
|
|
|
|
unsigned i,sfreq,sfb_start,sfb_stop,is_pos;
|
|
|
|
float is_ratio_l,is_ratio_r,left,right;
|
|
|
|
|
|
|
|
/* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */
|
|
|
|
if((is_pos = g_main_data.scalefac_l[gr][0][sfb]) != 7) {
|
|
|
|
sfreq = g_frame_header.sampling_frequency; /* Setup sampling freq index */
|
|
|
|
sfb_start = g_sf_band_indices[sfreq].l[sfb];
|
|
|
|
sfb_stop = g_sf_band_indices[sfreq].l[sfb+1];
|
|
|
|
if(is_pos == 6) { /* tan((6*PI)/12 = PI/2) needs special treatment! */
|
|
|
|
is_ratio_l = 1.0f;
|
|
|
|
is_ratio_r = 0.0f;
|
|
|
|
}else{
|
|
|
|
is_ratio_l = is_ratios[is_pos] /(1.0f + is_ratios[is_pos]);
|
|
|
|
is_ratio_r = 1.0f /(1.0f + is_ratios[is_pos]);
|
|
|
|
}
|
|
|
|
/* Now decode all samples in this scale factor band */
|
|
|
|
for(i = sfb_start; i < sfb_stop; i++) {
|
|
|
|
left = is_ratio_l * g_main_data.is[gr][0][i];
|
|
|
|
right = is_ratio_r * g_main_data.is[gr][0][i];
|
|
|
|
g_main_data.is[gr][0][i] = left;
|
|
|
|
g_main_data.is[gr][1][i] = right;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return; /* Done */
|
|
|
|
} /* end Stereo_Process_Intensity_Long() */
|
|
|
|
|
|
|
|
/**Description: This function is used to perform intensity stereo processing
|
|
|
|
* for an entire subband that uses short blocks.
|
|
|
|
* Parameters: TBD
|
|
|
|
* Return value: TBD
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void Stereo_Process_Intensity_Short(unsigned gr,unsigned sfb){
|
|
|
|
unsigned sfb_start,sfb_stop,is_pos,is_ratio_l,is_ratio_r,i,sfreq,win,win_len;
|
|
|
|
float left,right;
|
|
|
|
|
|
|
|
sfreq = g_frame_header.sampling_frequency; /* Setup sampling freq index */
|
|
|
|
/* The window length */
|
|
|
|
win_len = g_sf_band_indices[sfreq].s[sfb+1] - g_sf_band_indices[sfreq].s[sfb];
|
|
|
|
/* The three windows within the band has different scalefactors */
|
|
|
|
for(win = 0; win < 3; win++) {
|
|
|
|
/* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */
|
|
|
|
if((is_pos = g_main_data.scalefac_s[gr][0][sfb][win]) != 7) {
|
|
|
|
sfb_start = g_sf_band_indices[sfreq].s[sfb]*3 + win_len*win;
|
|
|
|
sfb_stop = sfb_start + win_len;
|
|
|
|
if(is_pos == 6) { /* tan((6*PI)/12 = PI/2) needs special treatment! */
|
|
|
|
is_ratio_l = 1.0;
|
|
|
|
is_ratio_r = 0.0;
|
|
|
|
}else{
|
|
|
|
is_ratio_l = is_ratios[is_pos] /(1.0 + is_ratios[is_pos]);
|
|
|
|
is_ratio_r = 1.0 /(1.0 + is_ratios[is_pos]);
|
|
|
|
}
|
|
|
|
/* Now decode all samples in this scale factor band */
|
|
|
|
for(i = sfb_start; i < sfb_stop; i++) {
|
|
|
|
left = is_ratio_l = g_main_data.is[gr][0][i];
|
|
|
|
right = is_ratio_r = g_main_data.is[gr][0][i];
|
|
|
|
g_main_data.is[gr][0][i] = left;
|
|
|
|
g_main_data.is[gr][1][i] = right;
|
|
|
|
}
|
|
|
|
} /* end if(not illegal is_pos) */
|
|
|
|
} /* end for(win... */
|
|
|
|
return; /* Done */
|
|
|
|
} /* end Stereo_Process_Intensity_Short() */
|
|
|
|
|
|
|
|
/**Description: output audio data
|
|
|
|
* Parameters: Pointers to the samples,the number of samples
|
|
|
|
* Return value: None
|
|
|
|
* Author: Krister Lagerström(krister@kmlager.com) **/
|
|
|
|
static void audio_write(unsigned *samples,unsigned nsamples,int sample_rate){
|
|
|
|
static int init = 0,audio,curr_sample_rate = 0;
|
|
|
|
int tmp,dsp_speed = 44100,dsp_stereo = 2;
|
|
|
|
|
|
|
|
#ifdef OUTPUT_RAW
|
|
|
|
audio_write_raw(samples,nsamples);
|
|
|
|
#endif /* OUTPUT_RAW */
|
|
|
|
return;
|
|
|
|
} /* audio_write() */
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Name: audio_write_raw
|
|
|
|
* Author: Krister Lagerström(krister@unidata.se)
|
|
|
|
* Description: This function is used to output raw data
|
|
|
|
* Parameters: Pointers to the samples,the number of samples
|
|
|
|
* Return value: None
|
|
|
|
* Revision History:
|
|
|
|
* Author Date Change
|
|
|
|
* krister 010101 Initial revision
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
|
|
|
static void audio_write_raw(unsigned *samples,unsigned nsamples){
|
|
|
|
char fname[1024];
|
|
|
|
unsigned lo,hi;
|
|
|
|
int i,nch;
|
|
|
|
unsigned short s[576*2];
|
|
|
|
|
|
|
|
nch =(g_frame_header.mode == mpeg1_mode_single_channel ? 1 : 2);
|
|
|
|
for(i = 0; i < nsamples; i++) {
|
|
|
|
if(nch == 1) {
|
|
|
|
lo = samples[i] & 0xffff;
|
|
|
|
s[i] = lo;
|
|
|
|
}else{
|
|
|
|
lo = samples[i] & 0xffff;
|
|
|
|
hi =(samples[i] & 0xffff0000) >> 16;
|
|
|
|
s[2*i] = hi;
|
|
|
|
s[2*i+1] = lo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(writeToWriter((char *) s,nsamples * 2 * nch) != nsamples * 2 * nch)
|
|
|
|
Error("Unable to write raw data\n",-1);
|
|
|
|
return;
|
|
|
|
} /* audio_write_raw() */
|