audio/mp3: Remove global variables 'reader*'

This commit is contained in:
Hajime Hoshi 2017-06-18 18:34:58 +09:00
parent cf05a581a4
commit 63f1dceb8b
4 changed files with 53 additions and 51 deletions

View File

@ -21,13 +21,6 @@ import (
"io"
)
var (
reader io.Reader
readerCache []uint8
readerPos int
readerEOF bool
)
func (f *frame) decodeL3() []uint8 {
out := make([]uint8, 576*4*2)
nch := f.header.numberOfChannels()
@ -50,31 +43,38 @@ func (f *frame) decodeL3() []uint8 {
return out
}
func getByte() (uint8, error) {
for len(readerCache) == 0 && !readerEOF {
type source struct {
reader io.Reader
readerCache []uint8
readerPos int
readerEOF bool
}
func (s *source) getByte() (uint8, error) {
for len(s.readerCache) == 0 && !s.readerEOF {
buf := make([]uint8, 4096)
n, err := reader.Read(buf)
readerCache = append(readerCache, buf[:n]...)
n, err := s.reader.Read(buf)
s.readerCache = append(s.readerCache, buf[:n]...)
if err != nil {
if err == io.EOF {
readerEOF = true
s.readerEOF = true
} else {
return 0, err
}
}
}
if len(readerCache) == 0 {
if len(s.readerCache) == 0 {
return 0, io.EOF
}
b := readerCache[0]
readerCache = readerCache[1:]
readerPos++
b := s.readerCache[0]
s.readerCache = s.readerCache[1:]
s.readerPos++
return b, nil
}
func getBytes(buf []int) (int, error) {
func (s *source) getBytes(buf []int) (int, error) {
for i := range buf {
v, err := getByte()
v, err := s.getByte()
buf[i] = int(v)
if err == io.EOF {
return i, io.EOF
@ -83,18 +83,20 @@ func getBytes(buf []int) (int, error) {
return len(buf), nil
}
func getFilepos() int {
return readerPos
func (s *source) getFilepos() int {
return s.readerPos
}
var eof = errors.New("mp3: expected EOF")
func decode(r io.Reader, w io.Writer) error {
reader = r
s := &source{
reader: r,
}
var f *frame
for {
var err error
f, err = f.readNextFrame()
f, err = s.readNextFrame(f)
if err == nil {
out := f.decodeL3()
if _, err := w.Write(out); err != nil {

View File

@ -26,7 +26,7 @@ var mpeg1ScalefacSizes = [16][2]int{
{2, 1}, {2, 2}, {2, 3}, {3, 1}, {3, 2}, {3, 3}, {4, 2}, {4, 3},
}
func readMainL3(prev *mainDataBytes, header *mpeg1FrameHeader, sideInfo *mpeg1SideInfo) (*mpeg1MainData, *mainDataBytes, error) {
func (s *source) readMainL3(prev *mainDataBytes, header *mpeg1FrameHeader, sideInfo *mpeg1SideInfo) (*mpeg1MainData, *mainDataBytes, error) {
nch := header.numberOfChannels()
// Calculate header audio data size
framesize := header.frameSize()
@ -48,7 +48,7 @@ func readMainL3(prev *mainDataBytes, header *mpeg1FrameHeader, sideInfo *mpeg1Si
// 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.
m, err := getMainData(prev, main_data_size, sideInfo.main_data_begin)
m, err := s.getMainData(prev, main_data_size, sideInfo.main_data_begin)
if err != nil {
// This could be due to not enough data in reservoir
return nil, nil, err
@ -151,7 +151,7 @@ type mainDataBytes struct {
pos int
}
func getMainData(prev *mainDataBytes, size int, offset int) (*mainDataBytes, error) {
func (s *source) getMainData(prev *mainDataBytes, size int, offset int) (*mainDataBytes, error) {
if size > 1500 {
return nil, fmt.Errorf("mp3: size = %d", size)
}
@ -164,7 +164,7 @@ func getMainData(prev *mainDataBytes, size int, offset int) (*mainDataBytes, err
n := 0
var err error
for n < size && err == nil {
nn, err2 := getBytes(buf)
nn, err2 := s.getBytes(buf)
n += nn
err = err2
}
@ -191,7 +191,7 @@ func getMainData(prev *mainDataBytes, size int, offset int) (*mainDataBytes, err
n := 0
var err error
for n < size && err == nil {
nn, err2 := getBytes(buf)
nn, err2 := s.getBytes(buf)
n += nn
err = err2
}

View File

@ -21,12 +21,12 @@ import (
"io"
)
func readCRC() error {
func (s *source) readCRC() error {
buf := make([]int, 2)
n := 0
var err error
for n < 2 && err == nil {
nn, err2 := getBytes(buf[n:])
nn, err2 := s.getBytes(buf[n:])
n += nn
err = err2
}
@ -42,14 +42,14 @@ func readCRC() error {
return nil
}
func (f *frame) readNextFrame() (*frame, error) {
h, err := readHeader()
func (s *source) readNextFrame(prev *frame) (*frame, error) {
h, err := s.readHeader()
if err != nil {
return nil, err
}
// Get CRC word if present
if h.protection_bit == 0 {
if err := readCRC(); err != nil {
if err := s.readCRC(); err != nil {
return nil, err
}
}
@ -57,7 +57,7 @@ func (f *frame) readNextFrame() (*frame, error) {
return nil, fmt.Errorf("mp3: only layer3 (want %d; got %d) is supported!", mpeg1Layer3, h.layer)
}
// Get side info
s, err := readSideInfo(h)
si, err := s.readSideInfo(h)
if err != nil {
return nil, err
}
@ -65,17 +65,17 @@ func (f *frame) readNextFrame() (*frame, error) {
// signal to calling function so that decoding isn't done!
// Get main data(scalefactors and Huffman coded frequency data)
var prevM *mainDataBytes
if f != nil {
prevM = f.mainDataBytes
if prev != nil {
prevM = prev.mainDataBytes
}
md, mdb, err := readMainL3(prevM, h, s)
md, mdb, err := s.readMainL3(prevM, h, si)
if err != nil {
return nil, err
}
nf := &frame{
prev: f,
prev: prev,
header: h,
sideInfo: s,
sideInfo: si,
mainData: md,
mainDataBytes: mdb,
}
@ -102,13 +102,13 @@ func isHeader(header uint32) bool {
return true
}
func readHeader() (*mpeg1FrameHeader, error) {
func (s *source) readHeader() (*mpeg1FrameHeader, error) {
// Get the next four bytes from the bitstream
buf := make([]int, 4)
n := 0
var err error
for n < 4 && err == nil {
nn, err2 := getBytes(buf[n:])
nn, err2 := s.getBytes(buf[n:])
n += nn
err = err2
}
@ -133,7 +133,7 @@ func readHeader() (*mpeg1FrameHeader, error) {
b2 = b3
b3 = b4
// Get one new byte from the bitstream
b, err := getByte()
b, err := s.getByte()
if err != nil {
if err == io.EOF {
return nil, fmt.Errorf("mp3: unexpected EOF at readHeader")
@ -162,23 +162,23 @@ func readHeader() (*mpeg1FrameHeader, error) {
// Check for invalid values and impossible combinations
if h.id != 3 {
return nil, fmt.Errorf("mp3: ID must be 3. Header word is 0x%08x at file pos %d",
header, getFilepos())
header, s.getFilepos())
}
if h.bitrate_index == 0 {
return nil, fmt.Errorf("mp3: Free bitrate format NIY! Header word is 0x%08x at file pos %d",
header, getFilepos())
header, s.getFilepos())
}
if h.bitrate_index == 15 {
return nil, fmt.Errorf("mp3: bitrate_index = 15 is invalid! Header word is 0x%08x at file pos %d",
header, getFilepos())
header, s.getFilepos())
}
if h.sampling_frequency == 3 {
return nil, fmt.Errorf("mp3: sampling_frequency = 3 is invalid! Header word is 0x%08x at file pos %d",
header, getFilepos())
header, s.getFilepos())
}
if h.layer == mpeg1LayerReserved {
return nil, fmt.Errorf("mp3: layer = %d is invalid! Header word is 0x%08x at file pos %d",
mpeg1LayerReserved, header, getFilepos())
mpeg1LayerReserved, header, s.getFilepos())
}
return h, nil
}

View File

@ -21,7 +21,7 @@ import (
"io"
)
func readSideInfo(header *mpeg1FrameHeader) (*mpeg1SideInfo, error) {
func (src *source) readSideInfo(header *mpeg1FrameHeader) (*mpeg1SideInfo, error) {
nch := header.numberOfChannels()
// Calculate header audio data size
framesize := header.frameSize()
@ -40,7 +40,7 @@ func readSideInfo(header *mpeg1FrameHeader) (*mpeg1SideInfo, error) {
main_data_size -= 2
}
// Read sideinfo from bitstream into buffer used by getSideBits()
s, err := getSideinfo(sideinfo_size)
s, err := src.getSideinfo(sideinfo_size)
if err != nil {
return nil, err
}
@ -107,12 +107,12 @@ type sideInfoBytes struct {
idx int // Index into the current byte(0-7)
}
func getSideinfo(size int) (*sideInfoBytes, error) {
func (src *source) getSideinfo(size int) (*sideInfoBytes, error) {
buf := make([]int, size)
n := 0
var err error
for n < size && err == nil {
nn, err2 := getBytes(buf[n:])
nn, err2 := src.getBytes(buf[n:])
n += nn
err = err2
}
@ -121,7 +121,7 @@ func getSideinfo(size int) (*sideInfoBytes, error) {
return nil, fmt.Errorf("mp3: unexpected EOF at getSideinfo")
}
return nil, fmt.Errorf("mp3: couldn't read sideinfo %d bytes at pos %d: %v",
size, getFilepos(), err)
size, src.getFilepos(), err)
}
s := &sideInfoBytes{
vec: buf[:n],