mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
audio/mp3: Move L3_Stereo to Go
This commit is contained in:
parent
9e002e3e52
commit
53c2c5d810
146
audio/mp3/l3.go
146
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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user