audio/mp3: Remove global variable theMainDataBytes

This commit is contained in:
Hajime Hoshi 2017-06-18 16:45:36 +09:00
parent 782284efd9
commit 0291330a1b
5 changed files with 80 additions and 70 deletions

View File

@ -98,8 +98,10 @@ var eof = errors.New("mp3: expected EOF")
func decode(r io.Reader, w io.Writer) error { func decode(r io.Reader, w io.Writer) error {
reader = r reader = r
var f *frame
for { for {
f, err := readFrame() var err error
f, err = f.readNextFrame()
if err == nil { if err == nil {
out := f.decodeL3() out := f.decodeL3()
if _, err := w.Write(out); err != nil { if _, err := w.Write(out); err != nil {

View File

@ -345,7 +345,7 @@ var huffmanMain = [...]huffTables{
{huffmanTable[2261:], 31, 0}, /* Table 33 */ {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 point := 0
error := 1 error := 1
bitsleft := 32 bitsleft := 32
@ -363,7 +363,7 @@ func huffmanDecode(table_num int) (x, y, v, w int, err error) {
y = int(htptr[point] & 0xf) y = int(htptr[point] & 0xf)
break break
} }
if getMainBit() != 0 { /* Go right in tree */ if m.getMainBit() != 0 { /* Go right in tree */
for (htptr[point] & 0xff) >= 250 { for (htptr[point] & 0xff) >= 250 {
point += int(htptr[point]) & 0xff 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 w = (y >> 2) & 1
x = (y >> 1) & 1 x = (y >> 1) & 1
y = y & 1 y = y & 1
if (v > 0) && (getMainBit() == 1) { if (v > 0) && (m.getMainBit() == 1) {
v = -v v = -v
} }
if (w > 0) && (getMainBit() == 1) { if (w > 0) && (m.getMainBit() == 1) {
w = -w w = -w
} }
if (x > 0) && (getMainBit() == 1) { if (x > 0) && (m.getMainBit() == 1) {
x = -x x = -x
} }
if (y > 0) && (getMainBit() == 1) { if (y > 0) && (m.getMainBit() == 1) {
y = -y y = -y
} }
} else { } else {
if (linbits > 0) && (x == 15) { 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 */ x = -x /* Get sign bit */
} }
if (linbits > 0) && (y == 15) { 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 */ y = -y /* Get sign bit */
} }
} }

View File

@ -52,20 +52,22 @@ func (f *frame) readMainL3() error {
// two frames. main_data_begin indicates how many bytes from previous // two frames. main_data_begin indicates how many bytes from previous
// frames that should be used. This buffer is later accessed by the // frames that should be used. This buffer is later accessed by the
// getMainBits function in the same way as the side info is. // 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 // This could be due to not enough data in reservoir
return err return err
} }
f.mainDataBytes = m
for gr := 0; gr < 2; gr++ { for gr := 0; gr < 2; gr++ {
for ch := 0; ch < nch; ch++ { for ch := 0; ch < nch; ch++ {
part_2_start := getMainPos() part_2_start := m.getMainPos()
// Number of bits in the bitstream for the bands // Number of bits in the bitstream for the bands
slen1 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][0] slen1 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][0]
slen2 := mpeg1_scalefac_sizes[f.sideInfo.scalefac_compress[gr][ch]][1] 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.win_switch_flag[gr][ch] != 0) && (f.sideInfo.block_type[gr][ch] == 2) {
if f.sideInfo.mixed_block_flag[gr][ch] != 0 { if f.sideInfo.mixed_block_flag[gr][ch] != 0 {
for sfb := 0; sfb < 8; sfb++ { 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++ { for sfb := 3; sfb < 12; sfb++ {
//slen1 for band 3-5,slen2 for 6-11 //slen1 for band 3-5,slen2 for 6-11
@ -74,7 +76,7 @@ func (f *frame) readMainL3() error {
nbits = slen1 nbits = slen1
} }
for win := 0; win < 3; win++ { 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 { } else {
@ -85,7 +87,7 @@ func (f *frame) readMainL3() error {
nbits = slen1 nbits = slen1
} }
for win := 0; win < 3; win++ { 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 // Scale factor bands 0-5
if (f.sideInfo.scfsi[ch][0] == 0) || (gr == 0) { if (f.sideInfo.scfsi[ch][0] == 0) || (gr == 0) {
for sfb := 0; sfb < 6; sfb++ { 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) { } else if (f.sideInfo.scfsi[ch][0] == 1) && (gr == 1) {
// Copy scalefactors from granule 0 to granule 1 // Copy scalefactors from granule 0 to granule 1
@ -104,7 +106,7 @@ func (f *frame) readMainL3() error {
// Scale factor bands 6-10 // Scale factor bands 6-10
if (f.sideInfo.scfsi[ch][1] == 0) || (gr == 0) { if (f.sideInfo.scfsi[ch][1] == 0) || (gr == 0) {
for sfb := 6; sfb < 11; sfb++ { 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) { } else if (f.sideInfo.scfsi[ch][1] == 1) && (gr == 1) {
// Copy scalefactors from granule 0 to granule 1 // Copy scalefactors from granule 0 to granule 1
@ -115,7 +117,7 @@ func (f *frame) readMainL3() error {
// Scale factor bands 11-15 // Scale factor bands 11-15
if (f.sideInfo.scfsi[ch][2] == 0) || (gr == 0) { if (f.sideInfo.scfsi[ch][2] == 0) || (gr == 0) {
for sfb := 11; sfb < 16; sfb++ { 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) { } else if (f.sideInfo.scfsi[ch][2] == 1) && (gr == 1) {
// Copy scalefactors from granule 0 to granule 1 // Copy scalefactors from granule 0 to granule 1
@ -126,7 +128,7 @@ func (f *frame) readMainL3() error {
// Scale factor bands 16-20 // Scale factor bands 16-20
if (f.sideInfo.scfsi[ch][3] == 0) || (gr == 0) { if (f.sideInfo.scfsi[ch][3] == 0) || (gr == 0) {
for sfb := 16; sfb < 21; sfb++ { 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) { } else if (f.sideInfo.scfsi[ch][3] == 1) && (gr == 1) {
// Copy scalefactors from granule 0 to granule 1 // Copy scalefactors from granule 0 to granule 1
@ -150,18 +152,15 @@ type mainDataBytes struct {
vec []int vec []int
// Index into the current byte(0-7) // Index into the current byte(0-7)
idx int idx int
pos int pos int
} }
var theMainDataBytes mainDataBytes func getMainData(prevFrame *frame, size int, offset int) (*mainDataBytes, error) {
func getMainData(size int, offset int) error {
if size > 1500 { 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 // 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 // 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 // read the main_data bits from the bitstream in case they are needed
// for decoding the next frame. // for decoding the next frame.
@ -175,19 +174,23 @@ func getMainData(size int, offset int) error {
} }
if n < size { if n < size {
if err == io.EOF { 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. // 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 // 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 // Read the main_data from file
buf := make([]int, size) buf := make([]int, size)
n := 0 n := 0
@ -199,54 +202,53 @@ func getMainData(size int, offset int) error {
} }
if n < size { if n < size {
if err == io.EOF { 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...) m := &mainDataBytes{
// Set up pointers vec: append(vec, buf...),
theMainDataBytes.pos = 0 }
theMainDataBytes.idx = 0 return m, nil
return nil
} }
func getMainBit() int { func (m *mainDataBytes) getMainBit() int {
tmp := uint(theMainDataBytes.vec[theMainDataBytes.pos]) >> (7 - uint(theMainDataBytes.idx)) tmp := uint(m.vec[m.pos]) >> (7 - uint(m.idx))
tmp &= 0x01 tmp &= 0x01
theMainDataBytes.pos += (theMainDataBytes.idx + 1) >> 3 m.pos += (m.idx + 1) >> 3
theMainDataBytes.idx = (theMainDataBytes.idx + 1) & 0x07 m.idx = (m.idx + 1) & 0x07
return int(tmp) return int(tmp)
} }
func getMainBits(num int) int { func (m *mainDataBytes) getMainBits(num int) int {
if num == 0 { if num == 0 {
return 0 return 0
} }
// Form a word of the next four bytes // Form a word of the next four bytes
b := make([]int, 4) 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) tmp := (uint32(b[0]) << 24) | (uint32(b[1]) << 16) | (uint32(b[2]) << 8) | (uint32(b[3]) << 0)
// Remove bits already used // Remove bits already used
tmp = tmp << uint(theMainDataBytes.idx) tmp = tmp << uint(m.idx)
// Remove bits after the desired bits // Remove bits after the desired bits
tmp = tmp >> (32 - uint(num)) tmp = tmp >> (32 - uint(num))
// Update pointers // Update pointers
theMainDataBytes.pos += (theMainDataBytes.idx + num) >> 3 m.pos += (m.idx + num) >> 3
theMainDataBytes.idx = (theMainDataBytes.idx + num) & 0x07 m.idx = (m.idx + num) & 0x07
return int(tmp) return int(tmp)
} }
func getMainPos() int { func (m *mainDataBytes) getMainPos() int {
pos := theMainDataBytes.pos pos := m.pos
pos *= 8 // Multiply by 8 to get number of bits pos *= 8 // Multiply by 8 to get number of bits
pos += theMainDataBytes.idx pos += m.idx
return pos return pos
} }
func setMainPos(bit_pos int) { func (m *mainDataBytes) setMainPos(bit_pos int) {
theMainDataBytes.pos = bit_pos >> 3 m.pos = bit_pos >> 3
theMainDataBytes.idx = bit_pos & 0x7 m.idx = bit_pos & 0x7
} }

View File

@ -42,31 +42,33 @@ func readCRC() error {
return nil return nil
} }
func readFrame() (*frame, error) { func (f *frame) readNextFrame() (*frame, error) {
f := &frame{} nf := &frame{
if err := f.readHeader(); err != nil { prev: f,
}
if err := nf.readHeader(); err != nil {
return nil, err return nil, err
} }
// Get CRC word if present // Get CRC word if present
if f.header.protection_bit == 0 { if nf.header.protection_bit == 0 {
if err := readCRC(); err != nil { if err := readCRC(); err != nil {
return nil, err return nil, err
} }
} }
if f.header.layer != mpeg1Layer3 { if nf.header.layer != mpeg1Layer3 {
return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, f.header.layer) return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, nf.header.layer)
} }
// Get side info // Get side info
if err := f.readAudioL3(); err != nil { if err := nf.readAudioL3(); err != nil {
return nil, err return nil, err
} }
// If there's not enough main data in the bit reservoir, // If there's not enough main data in the bit reservoir,
// signal to calling function so that decoding isn't done! // signal to calling function so that decoding isn't done!
// Get main data(scalefactors and Huffman coded frequency data) // 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 nil, err
} }
return f, nil return nf, nil
} }
func isHeader(header uint32) bool { 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] table_num = f.sideInfo.table_select[gr][ch][2]
} }
/* Get next Huffman coded words */ /* Get next Huffman coded words */
x, y, _, _, err := huffmanDecode(table_num) x, y, _, _, err := huffmanDecode(f.mainDataBytes, table_num)
if err != nil { if err != nil {
return err 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 */ /* Read small values until is_pos = 576 or we run out of huffman data */
table_num := f.sideInfo.count1table_select[gr][ch] + 32 table_num := f.sideInfo.count1table_select[gr][ch] + 32
is_pos := f.sideInfo.big_values[gr][ch] * 2 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 */ /* 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 { if err != nil {
return err 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) f.mainData.is[gr][ch][is_pos] = float32(y)
} }
/* Check that we didn't read past the end of this section */ /* 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 */ /* Remove last words read */
is_pos -= 4 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 f.mainData.is[gr][ch][is_pos] = 0.0
} }
/* Set the bitpos to point to the next part to read */ /* 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 return nil
} }

View File

@ -84,7 +84,11 @@ type mpeg1MainData struct {
} }
type frame struct { type frame struct {
prev *frame
header mpeg1FrameHeader header mpeg1FrameHeader
sideInfo mpeg1SideInfo sideInfo mpeg1SideInfo
mainData mpeg1MainData mainData mpeg1MainData
mainDataBytes *mainDataBytes
} }