예제 #1
0
파일: decode.go 프로젝트: tanema/amore
func readStreamInfo(r io.Reader) (*StreamInfo, error) {
	fs, err := bit.NewReader(r).ReadFields(16, 16, 24, 24, 20, 3, 5, 36)
	if err != nil {
		return nil, err
	}
	info := &StreamInfo{
		MinBlock:      int(fs[0]),
		MaxBlock:      int(fs[1]),
		MinFrame:      int(fs[2]),
		MaxFrame:      int(fs[3]),
		SampleRate:    int(fs[4]),
		NChannels:     int(fs[5]) + 1,
		BitsPerSample: int(fs[6]) + 1,
		TotalSamples:  int64(fs[7]),
	}

	csum, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}
	if len(csum) != md5.Size {
		return nil, errors.New("Bad MD5 checksum size")
	}
	copy(info.MD5[:], csum)

	if info.SampleRate == 0 {
		return info, errors.New("Bad sample rate")
	}

	return info, nil
}
예제 #2
0
파일: decode.go 프로젝트: tanema/amore
// Next returns the audio data from the next frame.
func (d *Decoder) Next() ([]byte, error) {
	defer func() { d.n++ }()

	raw := bytes.NewBuffer(nil)
	frame := io.TeeReader(d.r, raw)
	h, err := readFrameHeader(frame, d.StreamInfo)
	if err == io.EOF {
		return nil, err
	} else if err != nil {
		return nil, errors.New("Failed to read the frame header: " + err.Error())
	}

	br := bit.NewReader(frame)
	data := make([][]int32, h.channelAssignment.nChannels())
	for ch := range data {
		if data[ch], err = readSubFrame(br, h, ch); err != nil {
			return nil, err
		}
	}

	// The bit.Reader buffers up to the next byte, so reading from frame occurs
	// on the next byte boundary.  That takes care of the padding to align to the
	// next byte.
	var crc16 [2]byte
	if _, err := io.ReadFull(frame, crc16[:]); err != nil {
		return nil, err
	}
	if err = verifyCRC16(raw.Bytes()); err != nil {
		return nil, err
	}

	fixChannels(data, h.channelAssignment)
	return interleave(data, d.BitsPerSample)
}
예제 #3
0
파일: decode.go 프로젝트: tanema/amore
func readMetaDataHeader(r io.Reader) (last bool, kind blockType, n int32, err error) {
	const headerSize = 32 // bits
	br := bit.NewReader(&io.LimitedReader{R: r, N: headerSize})
	fs, err := br.ReadFields(1, 7, 24)
	if err != nil {
		return false, 0, 0, err
	}
	return fs[0] == 1, blockType(fs[1]), int32(fs[2]), nil
}
예제 #4
0
파일: decode_test.go 프로젝트: pmezard/flac
func TestUTF8Decode(t *testing.T) {
	tests := []struct {
		data []byte
		val  uint64
	}{
		{[]byte{0x7F}, 0x7F},

		{[]byte{0xC2, 0xA2}, 0xA2},
		{[]byte{0xC2, 0x80}, 0x080},
		{[]byte{0xDF, 0xBF}, 0x7FF},

		{[]byte{0xE2, 0x82, 0xAC}, 0x20AC},
		{[]byte{0xE0, 0xA0, 0x80}, 0x800},
		{[]byte{0xEF, 0xBF, 0xBF}, 0xFFFF},

		{[]byte{0xF0, 0x90, 0x80, 0x80}, 0x10000},
		{[]byte{0xF7, 0xBF, 0xBF, 0xBF}, 0x1FFFFF},
		{[]byte{0xF0, 0xA4, 0xAD, 0xA2}, 0x24B62},

		{[]byte{0xF8, 0x88, 0x80, 0x80, 0x80}, 0x200000},
		{[]byte{0xFB, 0xBF, 0xBF, 0xBF, 0xBF}, 0x3FFFFFF},

		{[]byte{0xFC, 0x84, 0x80, 0x80, 0x80, 0x80}, 0x4000000},
		{[]byte{0xFD, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF}, 0x7FFFFFFF},
	}

	for _, test := range tests {
		br := bit.NewReader(bytes.NewReader(test.data))
		switch v, err := utf8Decode(br); {
		case err != nil:
			t.Errorf("Unexpected error decoding %v: %v", test.data, err)

		case v != test.val:
			t.Errorf("Expected %v to decode to %v, got %v", test.data, test.val, v)
		}
	}
}
예제 #5
0
파일: decode.go 프로젝트: tanema/amore
func readFrameHeader(r io.Reader, info *StreamInfo) (*frameHeader, error) {
	raw := bytes.NewBuffer(nil)
	br := bit.NewReader(io.TeeReader(r, raw))

	const syncCode = 0x3FFE

	switch sync, err := br.Read(14); {
	case err == nil && sync != syncCode:
		return nil, errors.New("Failed to find the synchronize code for the next frame")
	case err != nil:
		return nil, err
	}

	fs, err := br.ReadFields(1, 1, 4, 4, 4, 3, 1)
	if err != nil {
		return nil, err
	}
	if fs[0] != 0 || fs[6] != 0 {
		return nil, errors.New("Invalid reserved value in frame header")
	}

	h := new(frameHeader)
	h.variableSize = fs[1] == 1

	blockSize := fs[2]

	sampleRate := fs[3]

	h.channelAssignment = channelAssignment(fs[4])
	if h.channelAssignment > midSide {
		return nil, errors.New("Bad channel assignment")
	}

	switch sampleSize := fs[5]; sampleSize {
	case 0:
		h.sampleSize = info.BitsPerSample
	case 3, 7:
		return nil, errors.New("Bad sample size in frame header")
	default:
		h.sampleSize = sampleSizes[sampleSize]
	}

	if h.number, err = utf8Decode(br); err != nil {
		return nil, err
	}

	switch blockSize {
	case 0:
		return nil, errors.New("Bad block size in frame header")
	case 6:
		sz, err := br.Read(8)
		if err != nil {
			return nil, err
		}
		h.blockSize = int(sz) + 1
	case 7:
		sz, err := br.Read(16)
		if err != nil {
			return nil, err
		}
		h.blockSize = int(sz) + 1
	default:
		h.blockSize = blockSizes[blockSize]
	}

	switch sampleRate {
	case 0:
		h.sampleRate = info.SampleRate
	case 12:
		r, err := br.Read(8)
		if err != nil {
			return nil, err
		}
		h.sampleRate = int(r)
	case 13:
		r, err := br.Read(16)
		if err != nil {
			return nil, err
		}
		h.sampleRate = int(r)
	case 14:
		r, err := br.Read(16)
		if err != nil {
			return nil, err
		}
		h.sampleRate = int(r * 10)
	default:
		h.sampleRate = sampleRates[sampleRate]
	}

	crc8, err := br.Read(8)
	if err != nil {
		return nil, err
	}
	h.crc8 = byte(crc8)

	return h, verifyCRC8(raw.Bytes())
}