1
0

In oggtag a prefix Ogg was removed from funtions and consts. Also added the consts that hold len of sequences.

This commit is contained in:
Alexander Andreev 2023-10-02 01:25:43 +04:00
parent 17eeebf1f3
commit a741e3eb9a
Signed by: Arav
GPG Key ID: D22A817D95815393
2 changed files with 28 additions and 24 deletions

View File

@ -13,11 +13,13 @@ import (
) )
const bufferLength = 4096 const bufferLength = 4096
const OggMagicSequence = "OggS" const MagicSequence = "OggS"
const OggVorbisSequence = "vorbis" const MagicSequenceLen = len(MagicSequence)
const VorbisSequence = "vorbis"
const VorbisSequenceLen = len(VorbisSequence)
// OggReadFile returns a head of an OGG file, and a buffer contains last frame. // OggReadFile returns a head of an OGG file, and a buffer contains last frame.
func OggReadFile(path string) (buf_start, buf_end []byte, _ error) { func ReadFile(path string) (buf_start, buf_end []byte, _ error) {
f, err := os.Open(path) f, err := os.Open(path)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -49,7 +51,7 @@ func OggReadFile(path string) (buf_start, buf_end []byte, _ error) {
return nil, nil, err return nil, nil, err
} }
if bytes.Contains(buf_end, []byte(OggMagicSequence)) { if bytes.Contains(buf_end, []byte(MagicSequence)) {
break break
} }
} }
@ -63,7 +65,7 @@ func OggReadFile(path string) (buf_start, buf_end []byte, _ error) {
// It is a simple implementation that doesn't parse a header and instead just // It is a simple implementation that doesn't parse a header and instead just
// looking for a certain tag preceded with three zero bytes and ends with // looking for a certain tag preceded with three zero bytes and ends with
// an = character. // an = character.
func OggGetTag(buf []byte, tag string) string { func GetTag(buf []byte, tag string) string {
tagIdx := bytes.Index(buf, append([]byte{0, 0, 0}, (tag+"=")...)) tagIdx := bytes.Index(buf, append([]byte{0, 0, 0}, (tag+"=")...))
if tagIdx == -1 { if tagIdx == -1 {
tagIdx = bytes.Index(buf, append([]byte{0, 0, 0}, (strings.ToUpper(tag)+"=")...)) tagIdx = bytes.Index(buf, append([]byte{0, 0, 0}, (strings.ToUpper(tag)+"=")...))
@ -79,15 +81,15 @@ func OggGetTag(buf []byte, tag string) string {
} }
// OggGetDuration returns song's duration in milliseconds. // OggGetDuration returns song's duration in milliseconds.
func OggGetDuration(buf_start, buf_end []byte) time.Duration { func GetDuration(buf_start, buf_end []byte) time.Duration {
rateIdx := bytes.Index(buf_start, []byte(OggVorbisSequence)) + rateIdx := bytes.Index(buf_start, []byte(VorbisSequence)) +
len(OggVorbisSequence) + 5 VorbisSequenceLen + 5
rateBytes := buf_start[rateIdx : rateIdx+4] rateBytes := buf_start[rateIdx : rateIdx+4]
rate := int32(rateBytes[0]) + int32(rateBytes[1])<<8 + rate := int32(rateBytes[0]) + int32(rateBytes[1])<<8 +
int32(rateBytes[2])<<16 + int32(rateBytes[3])<<24 int32(rateBytes[2])<<16 + int32(rateBytes[3])<<24
granuleIdx := bytes.LastIndex(buf_end, []byte(OggMagicSequence)) + granuleIdx := bytes.LastIndex(buf_end, []byte(MagicSequence)) +
len(OggMagicSequence) + 2 MagicSequenceLen + 2
granuleBytes := buf_end[granuleIdx : granuleIdx+8] granuleBytes := buf_end[granuleIdx : granuleIdx+8]
granule := int64(granuleBytes[0]) + int64(granuleBytes[1])<<8 + granule := int64(granuleBytes[0]) + int64(granuleBytes[1])<<8 +
int64(granuleBytes[2])<<16 + int64(granuleBytes[3])<<24 + int64(granuleBytes[2])<<16 + int64(granuleBytes[3])<<24 +

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"os" "os"
"testing" "testing"
"time"
) )
const bufferSize = 4096 const bufferSize = 4096
@ -11,54 +12,55 @@ const sampleSong = "/mnt/data/appdata/radio/fallback.ogg"
const sampleArtist = "breskina" const sampleArtist = "breskina"
const sampleTitle = "Песня про мечты" const sampleTitle = "Песня про мечты"
func TestOggGetTag(t *testing.T) { func TestGetTag(t *testing.T) {
f, _ := os.Open(sampleSong) f, _ := os.Open(sampleSong)
buf := make([]byte, bufferSize) buf := make([]byte, bufferSize)
f.Read(buf) f.Read(buf)
tag := OggGetTag(buf, "artist") tag := GetTag(buf, "artist")
if tag != sampleArtist { if tag != sampleArtist {
t.Error(tag, "!=", sampleArtist) t.Error(tag, "!=", sampleArtist)
} }
tag = OggGetTag(buf, "title") tag = GetTag(buf, "title")
if tag != sampleTitle { if tag != sampleTitle {
t.Error(tag, "!=", sampleTitle) t.Error(tag, "!=", sampleTitle)
} }
} }
func BenchmarkOggGetTag(b *testing.B) { func BenchmarkGetTag(b *testing.B) {
f, _ := os.Open(sampleSong) f, _ := os.Open(sampleSong)
buf := make([]byte, bufferSize) buf := make([]byte, bufferSize)
f.Read(buf) f.Read(buf)
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
OggGetTag(buf, "artist") GetTag(buf, "artist")
} }
} }
func TestOggReadFile(t *testing.T) { func TestReadFile(t *testing.T) {
bs, bf, err := OggReadFile(sampleSong) bs, bf, err := ReadFile(sampleSong)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
t.Log("bs = ", len(bs), "; bf =", len(bf), "bf(OggS) =", bytes.LastIndex(bf, []byte("OggS"))) t.Log("bs = ", len(bs), "; bf =", len(bf), "bf(S) =", bytes.LastIndex(bf, []byte("S")))
} }
func BenchmarkOggGetDuration(b *testing.B) { func BenchmarkGetDuration(b *testing.B) {
bs, bf, err := OggReadFile(sampleSong) bs, bf, err := ReadFile(sampleSong)
if err != nil { if err != nil {
b.Error(err) b.Error(err)
} }
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
OggGetDuration(bs, bf) GetDuration(bs, bf)
} }
} }
func TestOggGetDuration(t *testing.T) { func TestGetDuration(t *testing.T) {
bs, bf, err := OggReadFile(sampleSong) bs, bf, err := ReadFile(sampleSong)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
t.Log(OggGetDuration(bs, bf)) dur := GetDuration(bs, bf)
t.Log(dur, ((dur)/time.Second)*time.Second, dur.Milliseconds())
} }