func (i FrameSideInfo) NDataBegin() uint16 {
	return (uint16(i[0]) << 1 & (uint16(i[1]) >> 7))
}
NDataBegin is the number of bytes before the frame header at which the sample data begins
0 indicates that the data begins after the side channel information. This data is the
data from the "bit reservoir" and can be up to 511 bytes
package mp3
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"time"
)
type (
	Decoder struct {
		src io.Reader
		err error
	}
	Frame struct {
		buf []byte
	}
	FrameHeader []byte
	FrameVersion byte
	FrameLayer byte
	FrameEmphasis byte
	FrameChannelMode byte
	FrameBitRate int
	FrameSampleRate int
	FrameSideInfo []byte
)
const (
	MPEG25 FrameVersion = iota
	MPEGReserved
	MPEG2
	MPEG1
	VERSIONMAX
)
const (
	LayerReserved FrameLayer = iota
	Layer3
	Layer2
	Layer1
	LayerMax
)
const (
	EmphNone FrameEmphasis = iota
	Emph5015
	EmphReserved
	EmphCCITJ17
	EmphMax
)
const (
	Stereo FrameChannelMode = iota
	JointStereo
	DualChannel
	SingleChannel
	ChannelModeMax
)
const (
	ErrInvalidBitrate FrameBitRate = -1
)
var (
	bitrates = [VERSIONMAX][LayerMax][15]int{
		{  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                        
			{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},       
			{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},       
			{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},  
		},
		{  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
		},
		{  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                        
			{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},       
			{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},       
			{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},  
		},
		{  
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                           
			{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320},      
			{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},     
			{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448},  
		},
	}
	sampleRates = [int(VERSIONMAX)][3]int{
		{11025, 12000, 8000},   
		{0, 0, 0},              
		{22050, 24000, 16000},  
		{44100, 48000, 32000},  
	}
	ErrInvalidSampleRate = FrameSampleRate(-1)
	samplesPerFrame = [VERSIONMAX][LayerMax]int{
		{  
			0,
			576,
			1152,
			384,
		},
		{  
			0,
			0,
			0,
			0,
		},
		{  
			0,
			576,
			1152,
			384,
		},
		{  
			0,
			1152,
			1152,
			384,
		},
	}
	slotSize = [LayerMax]int{
		0,  
		1,  
		1,  
		4,  
	}
	ErrNoSyncBits = errors.New("EOF before sync bits found")
	ErrPrematureEOF = errors.New("EOF mid stream")
)
func init() {
	bitrates[MPEG25] = bitrates[MPEG2]
	samplesPerFrame[MPEG25] = samplesPerFrame[MPEG2]
}
func NewDecoder(r io.Reader) *Decoder {
	return &Decoder{r, nil}
}
func fillbuf(d []byte, r io.Reader, l int) (res []byte, err error) {
	if len(d) >= l {
		return d, nil
	}
	missing := l - len(d)
	if cap(d) < l {
		if d == nil {
			d = make([]byte, l)
		} else {
			il := len(d)
			d = d[:cap(d)]  
			d = append(d, make([]byte, l-cap(d))...)
			d = d[:il]  
		}
	}
	d = d[:l]
	_, err = io.ReadFull(r, d[len(d)-missing:])
	return d, err
}
func (d *Decoder) Decode(v *Frame, skipped *int) (err error) {
	v.buf = v.buf[:0]
	hLen := 4
	*skipped = 0
	for {
		v.buf, err = fillbuf(v.buf, d.src, hLen)
		if err != nil {
			return err
		}
		if v.buf[0] == 0xFF && (v.buf[1]&0xE0 == 0xE0) &&
			v.Header().Emphasis() != EmphReserved &&
			v.Header().Layer() != LayerReserved &&
			v.Header().Version() != MPEGReserved &&
			v.Header().SampleRate() != -1 &&
			v.Header().BitRate() != -1 {
			break
		}
		switch {
		case v.buf[1] == 0xFF:
			v.buf = v.buf[1:]
			*skipped++
		default:
			v.buf = v.buf[2:]
			*skipped += 2
		}
	}
	crcLen := 0
	if v.Header().Protection() {
		crcLen = 2
		v.buf, err = fillbuf(v.buf, d.src, hLen+crcLen)
		if err != nil {
			return err
		}
	}
	sideLen, err := v.SideInfoLength()
	if err != nil {
		return err
	}
	v.buf, err = fillbuf(v.buf, d.src, hLen+crcLen+sideLen)
	if err != nil {
		return err
	}
	dataLen := v.Size()
	v.buf, err = fillbuf(v.buf, d.src, dataLen)
	if err != nil {
		return err
	}
	return nil
}
func (f *Frame) SideInfoLength() (int, error) {
	switch f.Header().Version() {
	case MPEG1:
		switch f.Header().ChannelMode() {
		case SingleChannel:
			return 17, nil
		case Stereo, JointStereo, DualChannel:
			return 32, nil
		default:
			return 0, errors.New("bad channel mode")
		}
	case MPEG2, MPEG25:
		switch f.Header().ChannelMode() {
		case SingleChannel:
			return 9, nil
		case Stereo, JointStereo, DualChannel:
			return 17, nil
		default:
			return 0, errors.New("bad channel mode")
		}
	default:
		return 0, fmt.Errorf("bad version (%v)", f.Header().Version())
	}
}
func (f *Frame) Header() FrameHeader {
	return FrameHeader(f.buf[0:4])
}
func (f *Frame) CRC() (uint16, error) {
	var crc uint16
	if !f.Header().Protection() {
		return 0, nil
	}
	crcdata := bytes.NewReader(f.buf[4:6])
	err := binary.Read(crcdata, binary.BigEndian, &crc)
	return crc, err
}
func (f *Frame) SideInfo() FrameSideInfo {
	if f.Header().Protection() {
		return FrameSideInfo(f.buf[6:])
	}
	return FrameSideInfo(f.buf[4:])
}
func (f *Frame) String() string {
	str := ""
	str += fmt.Sprintf("Header: \n%s", f.Header())
	str += fmt.Sprintf("SideInfo: \n%s", f.SideInfo())
	crc, err := f.CRC()
	str += fmt.Sprintf("CRC: %x (err: %v)\n", crc, err)
	str += fmt.Sprintf("Samples: %v\n", f.Samples())
	str += fmt.Sprintf("Size: %v\n", f.Size())
	str += fmt.Sprintf("Duration: %v\n", f.Duration())
	return str
}
func (h FrameHeader) Version() FrameVersion {
	return FrameVersion((h[1] >> 3) & 0x03)
}
func (h FrameHeader) Layer() FrameLayer {
	return FrameLayer((h[1] >> 1) & 0x03)
}
func (h FrameHeader) Protection() bool {
	return (h[1] & 0x01) != 0x01
}
func (h FrameHeader) BitRate() FrameBitRate {
	bitrateIdx := (h[2] >> 4) & 0x0F
	if bitrateIdx == 0x0F {
		return ErrInvalidBitrate
	}
	br := bitrates[h.Version()][h.Layer()][bitrateIdx] * 1000
	if br == 0 {
		return ErrInvalidBitrate
	}
	return FrameBitRate(br)
}
func (h FrameHeader) SampleRate() FrameSampleRate {
	sri := (h[2] >> 2) & 0x03
	if sri == 0x03 {
		return ErrInvalidSampleRate
	}
	return FrameSampleRate(sampleRates[h.Version()][sri])
}
func (h FrameHeader) Pad() bool {
	return ((h[2] >> 1) & 0x01) == 0x01
}
func (h FrameHeader) Private() bool {
	return (h[2] & 0x01) == 0x01
}
func (h FrameHeader) ChannelMode() FrameChannelMode {
	return FrameChannelMode((h[3] >> 6) & 0x03)
}
func (h FrameHeader) CopyRight() bool {
	return (h[3]>>3)&0x01 == 0x01
}
func (h FrameHeader) Original() bool {
	return (h[3]>>2)&0x01 == 0x01
}
func (h FrameHeader) Emphasis() FrameEmphasis {
	return FrameEmphasis((h[3] & 0x03))
}
func (h FrameHeader) String() string {
	str := ""
	str += fmt.Sprintf(" Layer: %v\n", h.Layer())
	str += fmt.Sprintf(" Version: %v\n", h.Version())
	str += fmt.Sprintf(" Protection: %v\n", h.Protection())
	str += fmt.Sprintf(" BitRate: %v\n", h.BitRate())
	str += fmt.Sprintf(" SampleRate: %v\n", h.SampleRate())
	str += fmt.Sprintf(" Pad: %v\n", h.Pad())
	str += fmt.Sprintf(" Private: %v\n", h.Private())
	str += fmt.Sprintf(" ChannelMode: %v\n", h.ChannelMode())
	str += fmt.Sprintf(" CopyRight: %v\n", h.CopyRight())
	str += fmt.Sprintf(" Original: %v\n", h.Original())
	str += fmt.Sprintf(" Emphasis: %v\n", h.Emphasis())
	return str
}