From 0291330a1b1573a11991579894966314abb44493 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 18 Jun 2017 16:45:36 +0900 Subject: [PATCH] audio/mp3: Remove global variable theMainDataBytes --- audio/mp3/decode_notjs.go | 4 +- audio/mp3/huffman.go | 20 ++++----- audio/mp3/maindata.go | 92 ++++++++++++++++++++------------------- audio/mp3/read.go | 30 +++++++------ audio/mp3/types.go | 4 ++ 5 files changed, 80 insertions(+), 70 deletions(-) diff --git a/audio/mp3/decode_notjs.go b/audio/mp3/decode_notjs.go index 96dc1acf3..29cac5204 100644 --- a/audio/mp3/decode_notjs.go +++ b/audio/mp3/decode_notjs.go @@ -98,8 +98,10 @@ var eof = errors.New("mp3: expected EOF") func decode(r io.Reader, w io.Writer) error { reader = r + var f *frame for { - f, err := readFrame() + var err error + f, err = f.readNextFrame() if err == nil { out := f.decodeL3() if _, err := w.Write(out); err != nil { diff --git a/audio/mp3/huffman.go b/audio/mp3/huffman.go index 0506ca095..0312e34ff 100644 --- a/audio/mp3/huffman.go +++ b/audio/mp3/huffman.go @@ -345,7 +345,7 @@ var huffmanMain = [...]huffTables{ {huffmanTable[2261:], 31, 0}, /* Table 33 */ } -func huffmanDecode(table_num int) (x, y, v, w int, err error) { +func huffmanDecode(m *mainDataBytes, table_num int) (x, y, v, w int, err error) { point := 0 error := 1 bitsleft := 32 @@ -363,7 +363,7 @@ func huffmanDecode(table_num int) (x, y, v, w int, err error) { y = int(htptr[point] & 0xf) break } - if getMainBit() != 0 { /* Go right in tree */ + if m.getMainBit() != 0 { /* Go right in tree */ for (htptr[point] & 0xff) >= 250 { point += int(htptr[point]) & 0xff } @@ -389,29 +389,29 @@ func huffmanDecode(table_num int) (x, y, v, w int, err error) { w = (y >> 2) & 1 x = (y >> 1) & 1 y = y & 1 - if (v > 0) && (getMainBit() == 1) { + if (v > 0) && (m.getMainBit() == 1) { v = -v } - if (w > 0) && (getMainBit() == 1) { + if (w > 0) && (m.getMainBit() == 1) { w = -w } - if (x > 0) && (getMainBit() == 1) { + if (x > 0) && (m.getMainBit() == 1) { x = -x } - if (y > 0) && (getMainBit() == 1) { + if (y > 0) && (m.getMainBit() == 1) { y = -y } } else { if (linbits > 0) && (x == 15) { - x += getMainBits(linbits) /* Get linbits */ + x += m.getMainBits(linbits) /* Get linbits */ } - if (x > 0) && (getMainBit() == 1) { + if (x > 0) && (m.getMainBit() == 1) { x = -x /* Get sign bit */ } if (linbits > 0) && (y == 15) { - y += getMainBits(linbits) /* Get linbits */ + y += m.getMainBits(linbits) /* Get linbits */ } - if (y > 0) && (getMainBit() == 1) { + if (y > 0) && (m.getMainBit() == 1) { y = -y /* Get sign bit */ } } diff --git a/audio/mp3/maindata.go b/audio/mp3/maindata.go index a01409066..70ea5a114 100644 --- a/audio/mp3/maindata.go +++ b/audio/mp3/maindata.go @@ -52,20 +52,22 @@ func (f *frame) readMainL3() error { // two frames. main_data_begin indicates how many bytes from previous // frames that should be used. This buffer is later accessed by the // getMainBits function in the same way as the side info is. - if err := getMainData(main_data_size, f.sideInfo.main_data_begin); err != nil { + m, err := getMainData(f.prev, main_data_size, f.sideInfo.main_data_begin) + if err != nil { // This could be due to not enough data in reservoir return err } + f.mainDataBytes = m for gr := 0; gr < 2; gr++ { for ch := 0; ch < nch; ch++ { - part_2_start := getMainPos() + part_2_start := m.getMainPos() // Number of bits in the bitstream for the bands slen1 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][0] slen2 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][1] if (f.sideInfo.win_switch_flag[gr][ch] != 0) && (f.sideInfo.block_type[gr][ch] == 2) { if f.sideInfo.mixed_block_flag[gr][ch] != 0 { for sfb := 0; sfb < 8; sfb++ { - f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1) + f.mainData.scalefac_l[gr][ch][sfb] = m.getMainBits(slen1) } for sfb := 3; sfb < 12; sfb++ { //slen1 for band 3-5,slen2 for 6-11 @@ -74,7 +76,7 @@ func (f *frame) readMainL3() error { nbits = slen1 } for win := 0; win < 3; win++ { - f.mainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits) + f.mainData.scalefac_s[gr][ch][sfb][win] = m.getMainBits(nbits) } } } else { @@ -85,7 +87,7 @@ func (f *frame) readMainL3() error { nbits = slen1 } for win := 0; win < 3; win++ { - f.mainData.scalefac_s[gr][ch][sfb][win] = getMainBits(nbits) + f.mainData.scalefac_s[gr][ch][sfb][win] = m.getMainBits(nbits) } } } @@ -93,7 +95,7 @@ func (f *frame) readMainL3() error { // Scale factor bands 0-5 if (f.sideInfo.scfsi[ch][0] == 0) || (gr == 0) { for sfb := 0; sfb < 6; sfb++ { - f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1) + f.mainData.scalefac_l[gr][ch][sfb] = m.getMainBits(slen1) } } else if (f.sideInfo.scfsi[ch][0] == 1) && (gr == 1) { // Copy scalefactors from granule 0 to granule 1 @@ -104,7 +106,7 @@ func (f *frame) readMainL3() error { // Scale factor bands 6-10 if (f.sideInfo.scfsi[ch][1] == 0) || (gr == 0) { for sfb := 6; sfb < 11; sfb++ { - f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen1) + f.mainData.scalefac_l[gr][ch][sfb] = m.getMainBits(slen1) } } else if (f.sideInfo.scfsi[ch][1] == 1) && (gr == 1) { // Copy scalefactors from granule 0 to granule 1 @@ -115,7 +117,7 @@ func (f *frame) readMainL3() error { // Scale factor bands 11-15 if (f.sideInfo.scfsi[ch][2] == 0) || (gr == 0) { for sfb := 11; sfb < 16; sfb++ { - f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2) + f.mainData.scalefac_l[gr][ch][sfb] = m.getMainBits(slen2) } } else if (f.sideInfo.scfsi[ch][2] == 1) && (gr == 1) { // Copy scalefactors from granule 0 to granule 1 @@ -126,7 +128,7 @@ func (f *frame) readMainL3() error { // Scale factor bands 16-20 if (f.sideInfo.scfsi[ch][3] == 0) || (gr == 0) { for sfb := 16; sfb < 21; sfb++ { - f.mainData.scalefac_l[gr][ch][sfb] = getMainBits(slen2) + f.mainData.scalefac_l[gr][ch][sfb] = m.getMainBits(slen2) } } else if (f.sideInfo.scfsi[ch][3] == 1) && (gr == 1) { // Copy scalefactors from granule 0 to granule 1 @@ -150,18 +152,15 @@ type mainDataBytes struct { vec []int // Index into the current byte(0-7) idx int - pos int } -var theMainDataBytes mainDataBytes - -func getMainData(size int, offset int) error { +func getMainData(prevFrame *frame, size int, offset int) (*mainDataBytes, error) { if size > 1500 { - return fmt.Errorf("mp3: size = %d", size) + return nil, fmt.Errorf("mp3: size = %d", size) } // Check that there's data available from previous frames if needed - if offset > len(theMainDataBytes.vec) { + if prevFrame != nil && offset > len(prevFrame.mainDataBytes.vec) { // No,there is not, so we skip decoding this frame, but we have to // read the main_data bits from the bitstream in case they are needed // for decoding the next frame. @@ -175,19 +174,23 @@ func getMainData(size int, offset int) error { } if n < size { if err == io.EOF { - return fmt.Errorf("mp3: unexpected EOF at getMainData") + return nil, fmt.Errorf("mp3: unexpected EOF at getMainData") } - return err + return nil, err + } + m := &mainDataBytes{} + if prevFrame != nil { + m.vec = append(prevFrame.mainDataBytes.vec, buf...) } - theMainDataBytes.vec = append(theMainDataBytes.vec, buf...) - // Set up pointers - theMainDataBytes.pos = 0 - theMainDataBytes.idx = 0 // TODO: Define a special error and enable to continue the next frame. - return fmt.Errorf("mp3: frame can't be decoded") + return m, fmt.Errorf("mp3: frame can't be decoded") } // Copy data from previous frames - theMainDataBytes.vec = theMainDataBytes.vec[len(theMainDataBytes.vec)-offset:] + vec := []int{} + if prevFrame != nil { + v := prevFrame.mainDataBytes.vec + vec = v[len(v)-offset:] + } // Read the main_data from file buf := make([]int, size) n := 0 @@ -199,54 +202,53 @@ func getMainData(size int, offset int) error { } if n < size { if err == io.EOF { - return fmt.Errorf("mp3: unexpected EOF at getMainData") + return nil, fmt.Errorf("mp3: unexpected EOF at getMainData") } - return err + return nil, err } - theMainDataBytes.vec = append(theMainDataBytes.vec, buf...) - // Set up pointers - theMainDataBytes.pos = 0 - theMainDataBytes.idx = 0 - return nil + m := &mainDataBytes{ + vec: append(vec, buf...), + } + return m, nil } -func getMainBit() int { - tmp := uint(theMainDataBytes.vec[theMainDataBytes.pos]) >> (7 - uint(theMainDataBytes.idx)) +func (m *mainDataBytes) getMainBit() int { + tmp := uint(m.vec[m.pos]) >> (7 - uint(m.idx)) tmp &= 0x01 - theMainDataBytes.pos += (theMainDataBytes.idx + 1) >> 3 - theMainDataBytes.idx = (theMainDataBytes.idx + 1) & 0x07 + m.pos += (m.idx + 1) >> 3 + m.idx = (m.idx + 1) & 0x07 return int(tmp) } -func getMainBits(num int) int { +func (m *mainDataBytes) getMainBits(num int) int { if num == 0 { return 0 } // Form a word of the next four bytes b := make([]int, 4) - copy(b, theMainDataBytes.vec[theMainDataBytes.pos:]) + copy(b, m.vec[m.pos:]) tmp := (uint32(b[0]) << 24) | (uint32(b[1]) << 16) | (uint32(b[2]) << 8) | (uint32(b[3]) << 0) // Remove bits already used - tmp = tmp << uint(theMainDataBytes.idx) + tmp = tmp << uint(m.idx) // Remove bits after the desired bits tmp = tmp >> (32 - uint(num)) // Update pointers - theMainDataBytes.pos += (theMainDataBytes.idx + num) >> 3 - theMainDataBytes.idx = (theMainDataBytes.idx + num) & 0x07 + m.pos += (m.idx + num) >> 3 + m.idx = (m.idx + num) & 0x07 return int(tmp) } -func getMainPos() int { - pos := theMainDataBytes.pos +func (m *mainDataBytes) getMainPos() int { + pos := m.pos pos *= 8 // Multiply by 8 to get number of bits - pos += theMainDataBytes.idx + pos += m.idx return pos } -func setMainPos(bit_pos int) { - theMainDataBytes.pos = bit_pos >> 3 - theMainDataBytes.idx = bit_pos & 0x7 +func (m *mainDataBytes) setMainPos(bit_pos int) { + m.pos = bit_pos >> 3 + m.idx = bit_pos & 0x7 } diff --git a/audio/mp3/read.go b/audio/mp3/read.go index 5fb4a9c90..726f393d2 100644 --- a/audio/mp3/read.go +++ b/audio/mp3/read.go @@ -42,31 +42,33 @@ func readCRC() error { return nil } -func readFrame() (*frame, error) { - f := &frame{} - if err := f.readHeader(); err != nil { +func (f *frame) readNextFrame() (*frame, error) { + nf := &frame{ + prev: f, + } + if err := nf.readHeader(); err != nil { return nil, err } // Get CRC word if present - if f.header.protection_bit == 0 { + if nf.header.protection_bit == 0 { if err := readCRC(); err != nil { return nil, err } } - if f.header.layer != mpeg1Layer3 { - return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, f.header.layer) + if nf.header.layer != mpeg1Layer3 { + return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, nf.header.layer) } // Get side info - if err := f.readAudioL3(); err != nil { + if err := nf.readAudioL3(); err != nil { return nil, err } // 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 err := f.readMainL3(); err != nil { + if err := nf.readMainL3(); err != nil { return nil, err } - return f, nil + return nf, nil } func isHeader(header uint32) bool { @@ -200,7 +202,7 @@ func (f *frame) readHuffman(part_2_start, gr, ch int) error { table_num = f.sideInfo.table_select[gr][ch][2] } /* Get next Huffman coded words */ - x, y, _, _, err := huffmanDecode(table_num) + x, y, _, _, err := huffmanDecode(f.mainDataBytes, table_num) if err != nil { return err } @@ -212,9 +214,9 @@ func (f *frame) readHuffman(part_2_start, gr, ch int) error { /* Read small values until is_pos = 576 or we run out of huffman data */ table_num := f.sideInfo.count1table_select[gr][ch] + 32 is_pos := f.sideInfo.big_values[gr][ch] * 2 - for ; (is_pos <= 572) && (getMainPos() <= bit_pos_end); is_pos++ { + for ; (is_pos <= 572) && (f.mainDataBytes.getMainPos() <= bit_pos_end); is_pos++ { /* Get next Huffman coded words */ - x, y, v, w, err := huffmanDecode(table_num) + x, y, v, w, err := huffmanDecode(f.mainDataBytes, table_num) if err != nil { return err } @@ -236,7 +238,7 @@ func (f *frame) readHuffman(part_2_start, gr, ch int) error { f.mainData.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) { + if f.mainDataBytes.getMainPos() > (bit_pos_end + 1) { /* Remove last words read */ is_pos -= 4 } @@ -247,6 +249,6 @@ func (f *frame) readHuffman(part_2_start, gr, ch int) error { f.mainData.is[gr][ch][is_pos] = 0.0 } /* Set the bitpos to point to the next part to read */ - setMainPos(bit_pos_end + 1) + f.mainDataBytes.setMainPos(bit_pos_end + 1) return nil } diff --git a/audio/mp3/types.go b/audio/mp3/types.go index 95ed14023..6b336d650 100644 --- a/audio/mp3/types.go +++ b/audio/mp3/types.go @@ -84,7 +84,11 @@ type mpeg1MainData struct { } type frame struct { + prev *frame + header mpeg1FrameHeader sideInfo mpeg1SideInfo mainData mpeg1MainData + + mainDataBytes *mainDataBytes }