diff --git a/audio/mp3/l3.go b/audio/mp3/l3.go index b7300d982..d4d0029d0 100644 --- a/audio/mp3/l3.go +++ b/audio/mp3/l3.go @@ -18,7 +18,6 @@ package mp3 // #include "pdmp3.h" // -// extern t_mpeg1_main_data g_main_data; // extern t_mpeg1_side_info g_side_info; // extern t_mpeg1_header g_frame_header; import "C" @@ -47,16 +46,16 @@ func requantizeProcessLong(gr, ch, is_pos, sfb int) { // https://github.com/technosaurus/PDMP3/issues/4 if sfb < 21 { pf_x_pt := float64(C.g_side_info.preflag[gr][ch]) * pretab[sfb] - tmp1 = math.Pow(2.0, -(sf_mult * (float64(C.g_main_data.scalefac_l[gr][ch][sfb]) + pf_x_pt))) + tmp1 = math.Pow(2.0, -(sf_mult * (float64(theMPEG1MainData.scalefac_l[gr][ch][sfb]) + pf_x_pt))) } tmp2 := math.Pow(2.0, 0.25*(float64(C.g_side_info.global_gain[gr][ch])-210)) tmp3 := 0.0 - if C.g_main_data.is[gr][ch][is_pos] < 0.0 { - tmp3 = -powtab34[int(-C.g_main_data.is[gr][ch][is_pos])] + if theMPEG1MainData.is[gr][ch][is_pos] < 0.0 { + tmp3 = -powtab34[int(-theMPEG1MainData.is[gr][ch][is_pos])] } else { - tmp3 = powtab34[int(C.g_main_data.is[gr][ch][is_pos])] + tmp3 = powtab34[int(theMPEG1MainData.is[gr][ch][is_pos])] } - C.g_main_data.is[gr][ch][is_pos] = C.float(tmp1 * tmp2 * tmp3) + theMPEG1MainData.is[gr][ch][is_pos] = float32(tmp1 * tmp2 * tmp3) } func requantizeProcessShort(gr, ch, is_pos, sfb, win int) { @@ -67,17 +66,17 @@ func requantizeProcessShort(gr, ch, is_pos, sfb, win int) { tmp1 := 1.0 // https://github.com/technosaurus/PDMP3/issues/4 if sfb < 12 { - tmp1 = math.Pow(2.0, -(sf_mult * float64(C.g_main_data.scalefac_s[gr][ch][sfb][win]))) + tmp1 = math.Pow(2.0, -(sf_mult * float64(theMPEG1MainData.scalefac_s[gr][ch][sfb][win]))) } tmp2 := math.Pow(2.0, 0.25*(float64(C.g_side_info.global_gain[gr][ch])-210.0- 8.0*float64(C.g_side_info.subblock_gain[gr][ch][win]))) tmp3 := 0.0 - if C.g_main_data.is[gr][ch][is_pos] < 0 { - tmp3 = -powtab34[int(-C.g_main_data.is[gr][ch][is_pos])] + if theMPEG1MainData.is[gr][ch][is_pos] < 0 { + tmp3 = -powtab34[int(-theMPEG1MainData.is[gr][ch][is_pos])] } else { - tmp3 = powtab34[int(C.g_main_data.is[gr][ch][is_pos])] + tmp3 = powtab34[int(theMPEG1MainData.is[gr][ch][is_pos])] } - C.g_main_data.is[gr][ch][is_pos] = C.float(tmp1 * tmp2 * tmp3) + theMPEG1MainData.is[gr][ch][is_pos] = float32(tmp1 * tmp2 * tmp3) } type sfBandIndices struct { @@ -200,7 +199,7 @@ func l3Reorder(gr int, ch int) { if i == next_sfb { /* Copy reordered data back to the original vector */ for j := 0; j < 3*win_len; j++ { - C.g_main_data.is[gr][ch][3*sfBandIndicesSet[sfreq].s[sfb]+j] = C.float(re[j]) + theMPEG1MainData.is[gr][ch][3*sfBandIndicesSet[sfreq].s[sfb]+j] = re[j] } /* Check if this band is above the rzero region,if so we're done */ if C.uint(i) >= C.g_side_info.count1[gr][ch] { @@ -212,14 +211,14 @@ func l3Reorder(gr int, ch int) { } for win := 0; win < 3; win++ { /* Do the actual reordering */ for j := 0; j < win_len; j++ { - re[j*3+win] = float32(C.g_main_data.is[gr][ch][i]) + re[j*3+win] = float32(theMPEG1MainData.is[gr][ch][i]) i++ } } } /* Copy reordered data of last band back to original vector */ for j := 0; j < 3*win_len; j++ { - C.g_main_data.is[gr][ch][3*sfBandIndicesSet[sfreq].s[12]+j] = C.float(re[j]) + theMPEG1MainData.is[gr][ch][3*sfBandIndicesSet[sfreq].s[12]+j] = re[j] } } } @@ -232,7 +231,7 @@ 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] + is_pos := theMPEG1MainData.scalefac_l[gr][0][sfb] if is_pos != 7 { sfreq := C.g_frame_header.sampling_frequency /* Setup sampling freq index */ sfb_start := sfBandIndicesSet[sfreq].l[sfb] @@ -246,8 +245,8 @@ func stereoProcessIntensityLong(gr int, sfb int) { } /* 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) + theMPEG1MainData.is[gr][0][i] *= is_ratio_l + theMPEG1MainData.is[gr][1][i] *= is_ratio_r } } } @@ -261,7 +260,7 @@ func stereoProcessIntensityShort(gr int, sfb int) { /* 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] + is_pos := theMPEG1MainData.scalefac_s[gr][0][sfb][win] if is_pos != 7 { sfb_start := sfBandIndicesSet[sfreq].s[sfb]*3 + win_len*win sfb_stop := sfb_start + win_len @@ -275,8 +274,8 @@ func stereoProcessIntensityShort(gr int, sfb int) { /* 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) + theMPEG1MainData.is[gr][0][i] *= is_ratio_l + theMPEG1MainData.is[gr][1][i] *= is_ratio_r } } } @@ -298,10 +297,10 @@ func l3Stereo(gr int) { /* 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 + left := (theMPEG1MainData.is[gr][0][i] + theMPEG1MainData.is[gr][1][i]) * invSqrt2 + right := (theMPEG1MainData.is[gr][0][i] - theMPEG1MainData.is[gr][1][i]) * invSqrt2 + theMPEG1MainData.is[gr][0][i] = left + theMPEG1MainData.is[gr][1][i] = right } } /* Do intensity stereo processing */ @@ -374,10 +373,10 @@ func l3Antialias(gr int, ch int) { for i := 0; i < 8; i++ { li := 18*sb - 1 - i ui := 18*sb + i - lb := C.g_main_data.is[gr][ch][li]*C.float(cs[i]) - C.g_main_data.is[gr][ch][ui]*C.float(ca[i]) - ub := C.g_main_data.is[gr][ch][ui]*C.float(cs[i]) + C.g_main_data.is[gr][ch][li]*C.float(ca[i]) - C.g_main_data.is[gr][ch][li] = lb - C.g_main_data.is[gr][ch][ui] = ub + lb := theMPEG1MainData.is[gr][ch][li]*cs[i] - theMPEG1MainData.is[gr][ch][ui]*ca[i] + ub := theMPEG1MainData.is[gr][ch][ui]*cs[i] + theMPEG1MainData.is[gr][ch][li]*ca[i] + theMPEG1MainData.is[gr][ch][li] = lb + theMPEG1MainData.is[gr][ch][ui] = ub } } } @@ -395,11 +394,11 @@ func l3HybridSynthesis(gr int, ch int) { /* Do the inverse modified DCT and windowing */ in := make([]float32, 18) for i := range in { - in[i] = float32(C.g_main_data.is[gr][ch][sb*18+i]) + in[i] = float32(theMPEG1MainData.is[gr][ch][sb*18+i]) } rawout := imdctWin(in, bt) for i := 0; i < 18; i++ { /* Overlapp add with stored vector into main_data vector */ - C.g_main_data.is[gr][ch][sb*18+i] = C.float(rawout[i] + store[ch][sb][i]) + theMPEG1MainData.is[gr][ch][sb*18+i] = rawout[i] + store[ch][sb][i] store[ch][sb][i] = rawout[i+18] } } @@ -408,7 +407,7 @@ func l3HybridSynthesis(gr int, ch int) { func l3FrequencyInversion(gr int, ch int) { for sb := 1; sb < 32; sb += 2 { //OPT? : for(sb = 18; sb < 576; sb += 36) for i := 1; i < 18; i += 2 { - C.g_main_data.is[gr][ch][sb*18+i] = -C.g_main_data.is[gr][ch][sb*18+i] + theMPEG1MainData.is[gr][ch][sb*18+i] = -theMPEG1MainData.is[gr][ch][sb*18+i] } } } @@ -573,7 +572,7 @@ func l3SubbandSynthesis(gr int, ch int, out []uint32) { 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] = float32(C.g_main_data.is[gr][ch][i*18+ss]) + s_vec[i] = float32(theMPEG1MainData.is[gr][ch][i*18+ss]) } for i := 0; i < 64; i++ { /* Matrix multiply input with n_win[][] matrix */ sum := float32(0) diff --git a/audio/mp3/maindata.go b/audio/mp3/maindata.go index fe3474add..e52b5535d 100644 --- a/audio/mp3/maindata.go +++ b/audio/mp3/maindata.go @@ -18,7 +18,6 @@ package mp3 // #include "pdmp3.h" // -// extern t_mpeg1_main_data g_main_data; // extern t_mpeg1_header g_frame_header; // extern t_mpeg1_side_info g_side_info; import "C" @@ -78,7 +77,7 @@ func readMainL3() error { if (C.g_side_info.win_switch_flag[gr][ch] != 0) && (C.g_side_info.block_type[gr][ch] == 2) { if C.g_side_info.mixed_block_flag[gr][ch] != 0 { for sfb := 0; sfb < 8; sfb++ { - C.g_main_data.scalefac_l[gr][ch][sfb] = C.uint(getMainBits(slen1)) + theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1) } for sfb := 3; sfb < 12; sfb++ { /*slen1 for band 3-5,slen2 for 6-11*/ @@ -87,7 +86,7 @@ func readMainL3() error { nbits = slen1 } for win := 0; win < 3; win++ { - C.g_main_data.scalefac_s[gr][ch][sfb][win] = C.uint(getMainBits(nbits)) + theMPEG1MainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits) } } } else { @@ -98,7 +97,7 @@ func readMainL3() error { nbits = slen1 } for win := 0; win < 3; win++ { - C.g_main_data.scalefac_s[gr][ch][sfb][win] = C.uint(getMainBits(nbits)) + theMPEG1MainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits) } } } @@ -106,45 +105,45 @@ func readMainL3() error { /* Scale factor bands 0-5 */ if (C.g_side_info.scfsi[ch][0] == 0) || (gr == 0) { for sfb := 0; sfb < 6; sfb++ { - C.g_main_data.scalefac_l[gr][ch][sfb] = C.uint(getMainBits(slen1)) + theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1) } } else if (C.g_side_info.scfsi[ch][0] == 1) && (gr == 1) { /* Copy scalefactors from granule 0 to granule 1 */ for sfb := 0; sfb < 6; sfb++ { - C.g_main_data.scalefac_l[1][ch][sfb] = C.g_main_data.scalefac_l[0][ch][sfb] + theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb] } } /* Scale factor bands 6-10 */ if (C.g_side_info.scfsi[ch][1] == 0) || (gr == 0) { for sfb := 6; sfb < 11; sfb++ { - C.g_main_data.scalefac_l[gr][ch][sfb] = C.uint(getMainBits(slen1)) + theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1) } } else if (C.g_side_info.scfsi[ch][1] == 1) && (gr == 1) { /* Copy scalefactors from granule 0 to granule 1 */ for sfb := 6; sfb < 11; sfb++ { - C.g_main_data.scalefac_l[1][ch][sfb] = C.g_main_data.scalefac_l[0][ch][sfb] + theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb] } } /* Scale factor bands 11-15 */ if (C.g_side_info.scfsi[ch][2] == 0) || (gr == 0) { for sfb := 11; sfb < 16; sfb++ { - C.g_main_data.scalefac_l[gr][ch][sfb] = C.uint(getMainBits(slen2)) + theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2) } } else if (C.g_side_info.scfsi[ch][2] == 1) && (gr == 1) { /* Copy scalefactors from granule 0 to granule 1 */ for sfb := 11; sfb < 16; sfb++ { - C.g_main_data.scalefac_l[1][ch][sfb] = C.uint(C.g_main_data.scalefac_l[0][ch][sfb]) + theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb] } } /* Scale factor bands 16-20 */ if (C.g_side_info.scfsi[ch][3] == 0) || (gr == 0) { for sfb := 16; sfb < 21; sfb++ { - C.g_main_data.scalefac_l[gr][ch][sfb] = C.uint(getMainBits(slen2)) + theMPEG1MainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2) } } else if (C.g_side_info.scfsi[ch][3] == 1) && (gr == 1) { /* Copy scalefactors from granule 0 to granule 1 */ for sfb := 16; sfb < 21; sfb++ { - C.g_main_data.scalefac_l[1][ch][sfb] = C.g_main_data.scalefac_l[0][ch][sfb] + theMPEG1MainData.scalefac_l[1][ch][sfb] = theMPEG1MainData.scalefac_l[0][ch][sfb] } } } diff --git a/audio/mp3/pdmp3.c b/audio/mp3/pdmp3.c index 02788ec33..cbb405beb 100644 --- a/audio/mp3/pdmp3.c +++ b/audio/mp3/pdmp3.c @@ -59,30 +59,8 @@ g_sampling_frequency[3] = { 44100 * Hz,48000 * Hz,32000 * Hz }; unsigned synth_init = 1; -/* 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} - } - }; - 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) */ #ifdef DEBUG static void dmp_fr(t_mpeg1_header *hdr){ diff --git a/audio/mp3/pdmp3.h b/audio/mp3/pdmp3.h index 48165b3c7..2fb917bec 100644 --- a/audio/mp3/pdmp3.h +++ b/audio/mp3/pdmp3.h @@ -72,16 +72,5 @@ typedef struct { /* MPEG1 Layer 3 Side Information : [2][2] means [gr][ch] */ unsigned count1[2][2]; /* Not in file,calc. by huff.dec.! */ } t_mpeg1_side_info; -typedef struct { /* MPEG1 Layer 3 Main Data */ - unsigned scalefac_l[2][2][21]; /* 0-4 bits */ - unsigned scalefac_s[2][2][12][3]; /* 0-4 bits */ - float is[2][2][576]; /* Huffman coded freq. lines */ -} -t_mpeg1_main_data; -typedef struct { /* Scale factor band indices,for long and short windows */ - unsigned l[23]; - unsigned s[14]; -} -t_sf_band_indices; #endif diff --git a/audio/mp3/read.go b/audio/mp3/read.go index ff254dab6..2be3a64fc 100644 --- a/audio/mp3/read.go +++ b/audio/mp3/read.go @@ -18,7 +18,6 @@ package mp3 // #include "pdmp3.h" // -// extern t_mpeg1_main_data g_main_data; // extern t_mpeg1_side_info g_side_info; // extern t_mpeg1_header g_frame_header; import "C" @@ -174,7 +173,7 @@ func readHuffman(part_2_start, gr, ch int) error { /* Check that there is any data to decode. If not,zero the array. */ if C.g_side_info.part2_3_length[gr][ch] == 0 { for is_pos := 0; is_pos < 576; is_pos++ { - C.g_main_data.is[gr][ch][is_pos] = 0.0 + theMPEG1MainData.is[gr][ch][is_pos] = 0.0 } return nil } @@ -210,9 +209,9 @@ func readHuffman(part_2_start, gr, ch int) error { return err } /* In the big_values area there are two freq lines per Huffman word */ - C.g_main_data.is[gr][ch][is_pos] = C.float(x) + theMPEG1MainData.is[gr][ch][is_pos] = float32(x) is_pos++ - C.g_main_data.is[gr][ch][is_pos] = C.float(y) + theMPEG1MainData.is[gr][ch][is_pos] = float32(y) } /* Read small values until is_pos = 576 or we run out of huffman data */ table_num := int(C.g_side_info.count1table_select[gr][ch]) + 32 @@ -223,22 +222,22 @@ func readHuffman(part_2_start, gr, ch int) error { if err != nil { return err } - C.g_main_data.is[gr][ch][is_pos] = C.float(v) + theMPEG1MainData.is[gr][ch][is_pos] = float32(v) is_pos++ if is_pos >= 576 { break } - C.g_main_data.is[gr][ch][is_pos] = C.float(w) + theMPEG1MainData.is[gr][ch][is_pos] = float32(w) is_pos++ if is_pos >= 576 { break } - C.g_main_data.is[gr][ch][is_pos] = C.float(x) + theMPEG1MainData.is[gr][ch][is_pos] = float32(x) is_pos++ if is_pos >= 576 { break } - C.g_main_data.is[gr][ch][is_pos] = C.float(y) + theMPEG1MainData.is[gr][ch][is_pos] = float32(y) } /* Check that we didn't read past the end of this section */ if getMainPos() > (bit_pos_end + 1) { @@ -249,7 +248,7 @@ func readHuffman(part_2_start, gr, ch int) error { C.g_side_info.count1[gr][ch] = C.unsigned(is_pos) /* Zero out the last part if necessary */ for ; /* is_pos comes from last for-loop */ is_pos < 576; is_pos++ { - C.g_main_data.is[gr][ch][is_pos] = 0.0 + theMPEG1MainData.is[gr][ch][is_pos] = 0.0 } /* Set the bitpos to point to the next part to read */ setMainPos(bit_pos_end + 1) diff --git a/audio/mp3/types.go b/audio/mp3/types.go new file mode 100644 index 000000000..28826442b --- /dev/null +++ b/audio/mp3/types.go @@ -0,0 +1,90 @@ +// Copyright 2017 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !js + +package mp3 + +type mpeg1Layer int + +const ( + mpeg1LayerReserved mpeg1Layer = 0 + mpeg1Layer3 mpeg1Layer = 1 + mpeg1Layer2 mpeg1Layer = 2 + mpeg1Layer1 mpeg1Layer = 3 +) + +type mpeg1Mode int + +const ( + mpeg1ModeStereo mpeg1Mode = iota + mpeg1ModeJointStereo + mpeg1ModeDualChannel + mpeg1ModeSingleChannel +) + +// A mepg1FrameHeader is MPEG1 Layer 1-3 frame header +type mpeg1FrameHeader struct { + id int // 1 bit + layer mpeg1Layer // 2 bits + protection_bit int // 1 bit + bitrate_index int // 4 bits + sampling_frequency int // 2 bits + padding_bit int // 1 bit + private_bit int // 1 bit + mode mpeg1Mode // 2 bits + mode_extension int // 2 bits + copyright int // 1 bit + original_or_copy int // 1 bit + emphasis int // 2 bits +} + +var theMPEG1FrameHeader mpeg1FrameHeader + +// A mpeg1SideInfo is MPEG1 Layer 3 Side Information. +// [2][2] means [gr][ch]. +type mpeg1SideInfo struct { + main_data_begin int // 9 bits + private_bits int // 3 bits in mono, 5 in stereo + scfsi [2][4]int // 1 bit + part2_3_length [2][2]int // 12 bits + big_values [2][2]int // 9 bits + global_gain [2][2]int // 8 bits + scalefac_compress [2][2]int // 4 bits + win_switch_flag [2][2]int // 1 bit + + block_type [2][2]int // 2 bits + mixed_block_flag [2][2]int // 1 bit + table_select [2][2][3]int // 5 bits + subblock_gain [2][2][3]int // 3 bits + + region0_count [2][2]int // 4 bits + region1_count [2][2]int // 3 bits + + preflag [2][2]int // 1 bit + scalefac_scale [2][2]int // 1 bit + count1table_select [2][2]int // 1 bit + count1 [2][2]int // Not in file,calc. by huff.dec.! +} + +var theMPEG1SideInfo mpeg1SideInfo + +// A mpeg1MainData is MPEG1 Layer 3 Main Data. +type mpeg1MainData struct { + scalefac_l [2][2][21]int // 0-4 bits + scalefac_s [2][2][12][3]int // 0-4 bits + is [2][2][576]float32 // Huffman coded freq. lines +} + +var theMPEG1MainData mpeg1MainData