Upgrade oggreader to be segment aware
This commit is contained in:
parent
7b32fb7f78
commit
38e75cb5cf
|
@ -2,8 +2,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -11,15 +11,18 @@ import (
|
||||||
"github.com/pion/opus/pkg/oggreader"
|
"github.com/pion/opus/pkg/oggreader"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func convertFloatToByteSlice(i []float32) []byte {
|
||||||
decoder := opus.NewDecoder()
|
buf := new(bytes.Buffer)
|
||||||
|
binary.Write(buf, binary.LittleEndian, i)
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
homeDir, err := os.UserHomeDir()
|
func main() {
|
||||||
if err != nil {
|
if len(os.Args) != 3 {
|
||||||
panic(err)
|
panic("Usage: <in-file> <out-file>")
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(homeDir + "/opus/silk.ogg")
|
file, err := os.Open(os.Args[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -29,12 +32,19 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make([]float64, 320)
|
out := make([]float32, 320)
|
||||||
|
f, err := os.Create(os.Args[2])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder := opus.NewDecoder()
|
||||||
for {
|
for {
|
||||||
pageData, _, err := ogg.ParseNextPage()
|
segments, _, err := ogg.ParseNextPage()
|
||||||
|
|
||||||
if errors.Is(err, io.EOF) {
|
if errors.Is(err, io.EOF) {
|
||||||
break
|
break
|
||||||
} else if bytes.HasPrefix(pageData, []byte("OpusTags")) {
|
} else if bytes.HasPrefix(segments[0], []byte("OpusTags")) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,11 +52,12 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bandwidth, isStereo, err := decoder.Decode(pageData, out)
|
for i := range segments {
|
||||||
if err != nil {
|
if _, _, err = decoder.Decode(segments[i], out); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("bandwidth(%s) isStereo(%t) framesCount(%d)\n", bandwidth.String(), isStereo, len(out))
|
f.Write(floatarrtobytes(out))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ func newWith(in io.Reader, doChecksum bool) (*OggReader, *OggHeader, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OggReader) readHeaders() (*OggHeader, error) {
|
func (o *OggReader) readHeaders() (*OggHeader, error) {
|
||||||
payload, pageHeader, err := o.ParseNextPage()
|
segments, pageHeader, err := o.ParseNextPage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -103,27 +103,27 @@ func (o *OggReader) readHeaders() (*OggHeader, error) {
|
||||||
return nil, errBadIDPageType
|
return nil, errBadIDPageType
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(payload) != idPagePayloadLength {
|
if len(segments[0]) != idPagePayloadLength {
|
||||||
return nil, errBadIDPageLength
|
return nil, errBadIDPageLength
|
||||||
}
|
}
|
||||||
|
|
||||||
if s := string(payload[:8]); s != idPageSignature {
|
if s := string(segments[0][:8]); s != idPageSignature {
|
||||||
return nil, errBadIDPagePayloadSignature
|
return nil, errBadIDPagePayloadSignature
|
||||||
}
|
}
|
||||||
|
|
||||||
header.Version = payload[8]
|
header.Version = segments[0][8]
|
||||||
header.Channels = payload[9]
|
header.Channels = segments[0][9]
|
||||||
header.PreSkip = binary.LittleEndian.Uint16(payload[10:12])
|
header.PreSkip = binary.LittleEndian.Uint16(segments[0][10:12])
|
||||||
header.SampleRate = binary.LittleEndian.Uint32(payload[12:16])
|
header.SampleRate = binary.LittleEndian.Uint32(segments[0][12:16])
|
||||||
header.OutputGain = binary.LittleEndian.Uint16(payload[16:18])
|
header.OutputGain = binary.LittleEndian.Uint16(segments[0][16:18])
|
||||||
header.ChannelMap = payload[18]
|
header.ChannelMap = segments[0][18]
|
||||||
|
|
||||||
return header, nil
|
return header, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseNextPage reads from stream and returns Ogg page payload, header,
|
// ParseNextPage reads from stream and returns Ogg page segments, header,
|
||||||
// and an error if there is incomplete page data.
|
// and an error if there is incomplete page data.
|
||||||
func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
func (o *OggReader) ParseNextPage() ([][]byte, *OggPageHeader, error) {
|
||||||
h := make([]byte, pageHeaderLen)
|
h := make([]byte, pageHeaderLen)
|
||||||
|
|
||||||
n, err := io.ReadFull(o.stream, h)
|
n, err := io.ReadFull(o.stream, h)
|
||||||
|
@ -149,14 +149,15 @@ func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadSize := 0
|
segments := [][]byte{}
|
||||||
for _, s := range sizeBuffer {
|
|
||||||
payloadSize += int(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := make([]byte, payloadSize)
|
for _, s := range sizeBuffer {
|
||||||
if _, err = io.ReadFull(o.stream, payload); err != nil {
|
segment := make([]byte, int(s))
|
||||||
return nil, nil, err
|
if _, err = io.ReadFull(o.stream, segment); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
segments = append(segments, segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.doChecksum {
|
if o.doChecksum {
|
||||||
|
@ -177,8 +178,11 @@ func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
||||||
for _, s := range sizeBuffer {
|
for _, s := range sizeBuffer {
|
||||||
updateChecksum(s)
|
updateChecksum(s)
|
||||||
}
|
}
|
||||||
for index := range payload {
|
|
||||||
updateChecksum(payload[index])
|
for i := range segments {
|
||||||
|
for index := range segments[i] {
|
||||||
|
updateChecksum(segments[i][index])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary.LittleEndian.Uint32(h[22:22+4]) != checksum {
|
if binary.LittleEndian.Uint32(h[22:22+4]) != checksum {
|
||||||
|
@ -186,7 +190,7 @@ func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload, pageHeader, nil
|
return segments, pageHeader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetReader resets the internal stream of OggReader. This is useful
|
// ResetReader resets the internal stream of OggReader. This is useful
|
||||||
|
|
Loading…
Reference in a new issue