Skip to content

Commit

Permalink
fixed a variety of bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdoxsey committed Nov 17, 2013
1 parent a93a976 commit 75602a2
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 37 deletions.
17 changes: 10 additions & 7 deletions frames.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,23 @@ func GetFrames(src io.ReadSeeker) (*Frames, error) {
}
return &Frames{
src: stripped,
offset: 0,
offset: stripped.Offset(),
}, nil
}

func (this *Frames) Next() bool {
var err error
if this.count > 0 {
// skip to next frame
this.offset, err = this.src.Seek(this.offset+this.header.Size(), 0)
if err != nil {
this.err = fmt.Errorf("premature end of frame: %v", err)
return false
}
this.offset, err = this.src.Seek(this.header.Size-4, 1)
} else {
this.offset, err = this.src.Seek(0, 0)
}
if err != nil {
this.err = fmt.Errorf("premature end of frame: %v", err)
return false
}

bs := make([]byte, 4)
_, err = io.ReadAtLeast(this.src, bs, 4)
if err != nil {
Expand All @@ -56,7 +59,7 @@ func (this *Frames) Header() *FrameHeader {
}

func (this *Frames) Offset() int64 {
return this.src.Offset() + this.offset
return this.offset + this.src.Offset()
}

func (this *Frames) Error() error {
Expand Down
22 changes: 17 additions & 5 deletions header.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ type (
CopyRight bool
Original bool
Emphasis Emphasis

Size int64
Samples int
Duration time.Duration
}
)

Expand Down Expand Up @@ -100,6 +104,10 @@ func init() {
}

func (this *FrameHeader) Parse(bs []byte) error {
this.Size = 0
this.Samples = 0
this.Duration = 0

if len(bs) < 4 {
return fmt.Errorf("not enough bytes")
}
Expand Down Expand Up @@ -150,23 +158,27 @@ func (this *FrameHeader) Parse(bs []byte) error {
return fmt.Errorf("reserved emphasis")
}

this.Size = this.size()
this.Samples = this.samples()
this.Duration = this.duration()

return nil
}

func (this *FrameHeader) Samples() int {
func (this *FrameHeader) samples() int {
return samplesPerFrame[this.Version][this.Layer]
}

func (this *FrameHeader) Size() int64 {
bps := float64(this.Samples()) / 8
func (this *FrameHeader) size() int64 {
bps := float64(this.samples()) / 8
fsize := (bps * float64(this.Bitrate)) / float64(this.SampleRate)
if this.Pad {
fsize += float64(slotSize[this.Layer])
}
return int64(fsize)
}

func (this *FrameHeader) Duration() time.Duration {
ms := (1000 / float64(this.SampleRate)) * float64(this.Samples())
func (this *FrameHeader) duration() time.Duration {
ms := (1000 / float64(this.SampleRate)) * float64(this.samples())
return time.Duration(time.Duration(float64(time.Millisecond) * ms))
}
2 changes: 1 addition & 1 deletion length.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func Length(src io.ReadSeeker) (time.Duration, error) {
duration := time.Duration(0)

for frames.Next() {
duration += frames.Header().Duration()
duration += frames.Header().Duration
}

return duration, frames.Error()
Expand Down
24 changes: 11 additions & 13 deletions slice.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package mp3

import (
"fmt"
//"fmt"
"github.com/badgerodon/ioutil"
"io"
"time"
Expand All @@ -10,39 +10,37 @@ import (
func Slice(src io.ReadSeeker, cutPoints ...time.Duration) ([]io.ReadSeeker, error) {
pieces := make([]io.ReadSeeker, 0, len(cutPoints)+1)

_, err := src.Seek(0, 0)
stripped, err := Stripped(src)
if err != nil {
return nil, fmt.Errorf("failed to seek src to beginning: %v", err)
return nil, err
}

start := stripped.Offset()
end := stripped.Offset() + stripped.Length()

frames, err := GetFrames(src)
if err != nil {
return nil, err
}

length, err := src.Seek(0, 2)
if err != nil {
return nil, fmt.Errorf("failed to seek src to end: %v", err)
}

var elapsed time.Duration
var lastOffset int64
lastOffset := start
for frames.Next() {
if len(cutPoints) == 0 {
break
}

elapsed += frames.Header().Duration()
elapsed += frames.Header().Duration

if cutPoints[0] <= elapsed {
piece := ioutil.NewSectionReader(src, lastOffset, frames.Offset()-lastOffset)
piece := ioutil.NewSectionReader(src, lastOffset, frames.Offset()+frames.Header().Size-lastOffset)
pieces = append(pieces, piece)
lastOffset = frames.Offset()
lastOffset = frames.Offset() + frames.Header().Size
cutPoints = cutPoints[1:]
}
}

pieces = append(pieces, ioutil.NewSectionReader(src, lastOffset, length-lastOffset))
pieces = append(pieces, ioutil.NewSectionReader(src, lastOffset, end-lastOffset))

return pieces, frames.Error()
}
37 changes: 33 additions & 4 deletions slice_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mp3

import (
"github.com/badgerodon/ioutil"
"os"
"testing"
"time"
Expand Down Expand Up @@ -33,21 +34,49 @@ func TestSlice(t *testing.T) {
t.Errorf("Expected no error, got: %v", err)
}
if !nearlyEqual(len1, time.Second) {
t.Errorf("Expected the first slice to be %v, got %v", time.Second, len1)
t.Errorf("Expected %v to be %v, got %v", slices[0], time.Second, len1)
}
len2, err := Length(slices[1])
if err != nil {
t.Errorf("Expected no error, got: %v", err)
t.Errorf("Expected no error for %v, got: %v", slices[1], err)
}
if !nearlyEqual(len2, time.Second) {
t.Errorf("Expected the second slice to be %v, got %v", time.Second, len2)
t.Errorf("Expected %v to be %v, got %v", slices[1], time.Second, len2)
}
len3, err := Length(slices[2])
if err != nil {
t.Errorf("Expected no error, got: %v", err)
t.Errorf("Expected no error for %v, got: %v", slices[2], err)
}
if !nearlyEqual(len3, 3*time.Second) {
t.Errorf("Expected the third slice to be %v, got %v", 3*time.Second, len3)
}

}

func TestSlicedAndConcatenated(t *testing.T) {
f, err := os.Open("440hz.mp3")
if err != nil {
t.Fatalf("Error opening sample file: %v", err)
}
defer f.Close()

slices, err := Slice(f, time.Second, 2*time.Second, 3*time.Second)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}

concatenated := ioutil.NewMultiReadSeeker(slices...)

l1, err := Length(f)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
l2, err := Length(concatenated)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if l1 != l2 {
t.Errorf("Expected concatenated (%v) to be the same length as original (%v)", l2, l1)
}

}
13 changes: 9 additions & 4 deletions splice.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mp3

import (
"fmt"
"github.com/badgerodon/ioutil"
"io"
"sort"
Expand All @@ -20,7 +21,7 @@ func (this durationSorter) Less(i, j int) bool {
}

// Take a source MP3 and insert all the splice members into it (at the specified durations)
func Splice(src io.ReadSeeker, splice map[time.Duration]io.ReadSeeker) (io.ReadSeeker, error) {
func Splice(src io.ReadSeeker, splice map[time.Duration]io.ReadSeeker) (*ioutil.MultiReadSeeker, error) {
// Get the times
spliceTimes := []time.Duration{}
for k, _ := range splice {
Expand All @@ -31,13 +32,17 @@ func Splice(src io.ReadSeeker, splice map[time.Duration]io.ReadSeeker) (io.ReadS
// Slice up the src into len(splice)+1 pieces
sliced, err := Slice(src, spliceTimes...)
if err != nil {
return nil, err
return nil, fmt.Errorf("error slicing src: %v", err)
}

// Insert splice members between the slices
pieces := []io.ReadSeeker{}
pieces := []io.ReadSeeker{sliced[0]}
for i := 1; i < len(sliced); i++ {
pieces = append(pieces, sliced[i], splice[spliceTimes[i-1]])
stripped, err := Stripped(splice[spliceTimes[i-1]])
if err != nil {
return nil, err
}
pieces = append(pieces, stripped, sliced[i])
}

// Treat all the pieces as one big ReadSeeker
Expand Down
6 changes: 3 additions & 3 deletions stripped.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func getFirstRealFrameOffset(src io.ReadSeeker) (int64, error) {
return 0, err
}

if xing.Parse(bs[:int(hdr.Size())]) {
return off + hdr.Size(), nil
if xing.Parse(bs[:int(hdr.Size)]) {
return off + hdr.Size, nil
}

return off, nil
Expand All @@ -66,7 +66,7 @@ func getFirstRealFrameOffset(src io.ReadSeeker) (int64, error) {
func getLastFrameEnd(src io.ReadSeeker) (int64, error) {
end, err := src.Seek(-128, 2)
if err != nil {
return 0, err
return 0, nil
}

bs := make([]byte, 3)
Expand Down
5 changes: 5 additions & 0 deletions stripped_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ func TestStripped(t *testing.T) {
t.Errorf("Expected %v bytes, got %v", 30406, len(bs))
}

limited, err = Stripped(limited)
if err != nil {
t.Error(err)
}

}

0 comments on commit 75602a2

Please sign in to comment.