Upgrade oggreader to be segment aware
This commit is contained in:
parent
7b32fb7f78
commit
38e75cb5cf
|
@ -2,8 +2,8 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
|
@ -11,15 +11,18 @@ import (
|
|||
"github.com/pion/opus/pkg/oggreader"
|
||||
)
|
||||
|
||||
func main() {
|
||||
decoder := opus.NewDecoder()
|
||||
func convertFloatToByteSlice(i []float32) []byte {
|
||||
buf := new(bytes.Buffer)
|
||||
binary.Write(buf, binary.LittleEndian, i)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
panic("Usage: <in-file> <out-file>")
|
||||
}
|
||||
|
||||
file, err := os.Open(homeDir + "/opus/silk.ogg")
|
||||
file, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -29,12 +32,19 @@ func main() {
|
|||
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 {
|
||||
pageData, _, err := ogg.ParseNextPage()
|
||||
segments, _, err := ogg.ParseNextPage()
|
||||
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
} else if bytes.HasPrefix(pageData, []byte("OpusTags")) {
|
||||
} else if bytes.HasPrefix(segments[0], []byte("OpusTags")) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -42,11 +52,12 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
bandwidth, isStereo, err := decoder.Decode(pageData, out)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := range segments {
|
||||
if _, _, err = decoder.Decode(segments[i], out); err != nil {
|
||||
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) {
|
||||
payload, pageHeader, err := o.ParseNextPage()
|
||||
segments, pageHeader, err := o.ParseNextPage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -103,27 +103,27 @@ func (o *OggReader) readHeaders() (*OggHeader, error) {
|
|||
return nil, errBadIDPageType
|
||||
}
|
||||
|
||||
if len(payload) != idPagePayloadLength {
|
||||
if len(segments[0]) != idPagePayloadLength {
|
||||
return nil, errBadIDPageLength
|
||||
}
|
||||
|
||||
if s := string(payload[:8]); s != idPageSignature {
|
||||
if s := string(segments[0][:8]); s != idPageSignature {
|
||||
return nil, errBadIDPagePayloadSignature
|
||||
}
|
||||
|
||||
header.Version = payload[8]
|
||||
header.Channels = payload[9]
|
||||
header.PreSkip = binary.LittleEndian.Uint16(payload[10:12])
|
||||
header.SampleRate = binary.LittleEndian.Uint32(payload[12:16])
|
||||
header.OutputGain = binary.LittleEndian.Uint16(payload[16:18])
|
||||
header.ChannelMap = payload[18]
|
||||
header.Version = segments[0][8]
|
||||
header.Channels = segments[0][9]
|
||||
header.PreSkip = binary.LittleEndian.Uint16(segments[0][10:12])
|
||||
header.SampleRate = binary.LittleEndian.Uint32(segments[0][12:16])
|
||||
header.OutputGain = binary.LittleEndian.Uint16(segments[0][16:18])
|
||||
header.ChannelMap = segments[0][18]
|
||||
|
||||
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.
|
||||
func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
||||
func (o *OggReader) ParseNextPage() ([][]byte, *OggPageHeader, error) {
|
||||
h := make([]byte, pageHeaderLen)
|
||||
|
||||
n, err := io.ReadFull(o.stream, h)
|
||||
|
@ -149,14 +149,15 @@ func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
payloadSize := 0
|
||||
for _, s := range sizeBuffer {
|
||||
payloadSize += int(s)
|
||||
}
|
||||
segments := [][]byte{}
|
||||
|
||||
payload := make([]byte, payloadSize)
|
||||
if _, err = io.ReadFull(o.stream, payload); err != nil {
|
||||
return nil, nil, err
|
||||
for _, s := range sizeBuffer {
|
||||
segment := make([]byte, int(s))
|
||||
if _, err = io.ReadFull(o.stream, segment); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
segments = append(segments, segment)
|
||||
}
|
||||
|
||||
if o.doChecksum {
|
||||
|
@ -177,8 +178,11 @@ func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) {
|
|||
for _, s := range sizeBuffer {
|
||||
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 {
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue