From 53c2c5d810cd06bcd334e998497b1575a85d6b94 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Thu, 15 Jun 2017 01:54:25 +0900 Subject: [PATCH] audio/mp3: Move L3_Stereo to Go --- audio/mp3/l3.go | 146 ++++++++++++++++++++++++++++++++++++++++++++++ audio/mp3/pdmp3.c | 141 +------------------------------------------- audio/mp3/pdmp3.h | 1 + 3 files changed, 148 insertions(+), 140 deletions(-) diff --git a/audio/mp3/l3.go b/audio/mp3/l3.go index 428efad8e..7306881eb 100644 --- a/audio/mp3/l3.go +++ b/audio/mp3/l3.go @@ -28,6 +28,152 @@ import ( "unsafe" ) +type sfBandIndices struct { + l [23]int + s [14]int +} + +var ( + is_ratios = [6]float32{0.000000, 0.267949, 0.577350, 1.000000, 1.732051, 3.732051} + g_sf_band_indices = [3]sfBandIndices{ + { + l: [...]int{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576}, + s: [...]int{0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192}, + }, + { + l: [...]int{0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576}, + s: [...]int{0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192}, + }, + { + l: [...]int{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576}, + s: [...]int{0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192}, + }, + } +) + +func stereoProcessIntensityLong(gr int, sfb int) { + is_ratio_l := float32(0) + is_ratio_r := float32(0) + /* Check that((is_pos[sfb]=scalefac) != 7) => no intensity stereo */ + is_pos := C.g_main_data.scalefac_l[gr][0][sfb] + if is_pos != 7 { + sfreq := C.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.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++ { + C.g_main_data.is[gr][0][i] *= C.float(is_ratio_l) + C.g_main_data.is[gr][1][i] *= C.float(is_ratio_r) + } + } +} + +func stereoProcessIntensityShort(gr int, sfb int) { + is_ratio_l := float32(0) + is_ratio_r := float32(0) + sfreq := C.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 */ + is_pos := C.g_main_data.scalefac_s[gr][0][sfb][win] + if is_pos != 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++ { + // https://github.com/technosaurus/PDMP3/issues/3 + C.g_main_data.is[gr][0][i] *= C.float(is_ratio_l) + C.g_main_data.is[gr][1][i] *= C.float(is_ratio_r) + } + } + } +} + +//export L3_Stereo +func L3_Stereo(gr C.unsigned) { + /* Do nothing if joint stereo is not enabled */ + if (C.g_frame_header.mode != 1) || (C.g_frame_header.mode_extension == 0) { + return + } + /* Do Middle/Side("normal") stereo processing */ + if (C.g_frame_header.mode_extension & 0x2) != 0 { + /* Determine how many frequency lines to transform */ + i := 0 + if C.g_side_info.count1[gr][0] > C.g_side_info.count1[gr][1] { + i = 1 + } + max_pos := int(C.g_side_info.count1[gr][i]) + /* Do the actual processing */ + const invSqrt2 = math.Sqrt2 / 2 + for i := 0; i < max_pos; i++ { + left := (C.g_main_data.is[gr][0][i] + C.g_main_data.is[gr][1][i]) * invSqrt2 + right := (C.g_main_data.is[gr][0][i] - C.g_main_data.is[gr][1][i]) * invSqrt2 + C.g_main_data.is[gr][0][i] = left + C.g_main_data.is[gr][1][i] = right + } + } + /* Do intensity stereo processing */ + if (C.g_frame_header.mode_extension & 0x1) != 0 { + /* Setup sampling frequency index */ + sfreq := C.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 (C.g_side_info.win_switch_flag[gr][0] == 1) && + (C.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 C.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 C.unsigned(g_sf_band_indices[sfreq].l[sfb]) >= C.g_side_info.count1[gr][1] { + stereoProcessIntensityLong(int(gr), int(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 C.unsigned(g_sf_band_indices[sfreq].s[sfb])*3 >= C.g_side_info.count1[gr][1] { + stereoProcessIntensityShort(int(gr), int(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 C.unsigned(g_sf_band_indices[sfreq].s[sfb])*3 >= C.g_side_info.count1[gr][1] { + stereoProcessIntensityShort(int(gr), int(sfb)) /* intensity stereo processing */ + } + } + } + } else { /* Only long blocks */ + for sfb := 0; sfb < 21; sfb++ { + /* Is this scale factor band above count1 for the right channel? */ + if C.unsigned(g_sf_band_indices[sfreq].l[sfb]) >= C.g_side_info.count1[gr][1] { + /* Perform the intensity stereo processing */ + stereoProcessIntensityLong(int(gr), int(sfb)) + } + } + } + } +} + var store = [2][32][18]float32{} //export L3_Hybrid_Synthesis diff --git a/audio/mp3/pdmp3.c b/audio/mp3/pdmp3.c index 5b8617de1..fb60d7036 100644 --- a/audio/mp3/pdmp3.c +++ b/audio/mp3/pdmp3.c @@ -47,12 +47,9 @@ static void Error(const char *s,int e); static void L3_Antialias(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 Read_Ancillary(void); 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 */ @@ -70,8 +67,7 @@ g_sampling_frequency[3] = { 44100 * Hz,48000 * Hz,32000 * Hz }; static const float //ci[8]={-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037}, 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}, - is_ratios[6] = {0.000000f,0.267949f,0.577350f,1.000000f,1.732051f,3.732051f}; + ca[8]={-0.514496,-0.471732,-0.313377,-0.181913,-0.094574,-0.040966,-0.014199,-0.003700}; #ifdef POW34_ITERATE static const float powtab34[32] = { 0.000000f,1.000000f,2.519842f,4.326749f,6.349605f,8.549880f,10.902724f, @@ -583,73 +579,6 @@ static void L3_Requantize(unsigned gr,unsigned ch){ 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: 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]. @@ -757,74 +686,6 @@ static void Requantize_Process_Short(unsigned gr,unsigned ch,unsigned is_pos,uns 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 diff --git a/audio/mp3/pdmp3.h b/audio/mp3/pdmp3.h index eeb7c1382..f6ac84a7c 100644 --- a/audio/mp3/pdmp3.h +++ b/audio/mp3/pdmp3.h @@ -99,6 +99,7 @@ int Read_Audio_L3(void); static int Read_Header(void); void Read_Huffman(unsigned part_2_start,unsigned gr,unsigned ch); +void L3_Stereo(unsigned gr); void L3_Hybrid_Synthesis(unsigned gr,unsigned ch); void L3_Frequency_Inversion(unsigned gr,unsigned ch); void L3_Subband_Synthesis(unsigned gr,unsigned ch, unsigned* outdata);