Skip to content

Commit 8f5aff2

Browse files
authored
Merge pull request #45 from mutablelogic/ffmpeg71
Fixed segmenter bug
2 parents d05aee3 + 35b4734 commit 8f5aff2

File tree

4 files changed

+26
-29
lines changed

4 files changed

+26
-29
lines changed

cmd/media/fingerprint.go

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"os"
6+
"time"
67

78
// Packages
89
chromaprint "github.com/mutablelogic/go-media/pkg/chromaprint"
@@ -18,10 +19,11 @@ type FingerprintCommands struct {
1819
}
1920

2021
type MatchMusic struct {
21-
Path string `arg:"" type:"path" help:"File"`
22-
APIKey string `env:"CHROMAPRINT_KEY" help:"API key for the music matching service (https://acoustid.org/login)"`
23-
Type []string `cmd:"" help:"Type of match to perform" enum:"any,recording,release,releasegroup,track" default:"any"`
24-
Score float64 `cmd:"" help:"Minimum match scoreto perform" default:"0.9"`
22+
Path string `arg:"" type:"path" help:"File"`
23+
APIKey string `env:"CHROMAPRINT_KEY" help:"API key for the music matching service (https://acoustid.org/login)"`
24+
Type []string `cmd:"" help:"Type of match to perform" enum:"any,recording,release,releasegroup,track" default:"any"`
25+
Score float64 `cmd:"" help:"Minimum match scoreto perform" default:"0.9"`
26+
Duration time.Duration `cmd:"" help:"Length of audio to use for fingerprinting" default:"30s"`
2527
}
2628

2729
///////////////////////////////////////////////////////////////////////////////
@@ -62,7 +64,7 @@ func (cmd *MatchMusic) Run(app server.Cmd) error {
6264
}
6365

6466
// Create the matches
65-
matches, err := client.Match(app.Context(), r, meta)
67+
matches, err := client.Match(app.Context(), r, cmd.Duration, meta)
6668
if err != nil {
6769
return err
6870
}
@@ -78,17 +80,3 @@ func (cmd *MatchMusic) Run(app server.Cmd) error {
7880
fmt.Println(result)
7981
return nil
8082
}
81-
82-
/*
83-
84-
META_RECORDING Meta = (1 << iota)
85-
META_RECORDINGID
86-
META_RELEASE
87-
META_RELEASEID
88-
META_RELEASEGROUP
89-
META_RELEASEGROUPID
90-
META_TRACK
91-
META_COMPRESS
92-
META_USERMETA
93-
META_SOURCE
94-
*/

pkg/chromaprint/client.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ const (
3838

3939
// defaultQps rate limits number of requests per second
4040
defaultQps = 3
41+
42+
// sample rate used for fingerprinting
43+
sampleRate = 32000
4144
)
4245

4346
///////////////////////////////////////////////////////////////////////////////
@@ -94,10 +97,11 @@ func (c *Client) Lookup(fingerprint string, duration time.Duration, flags Meta)
9497
////////////////////////////////////////////////////////////////////////////////
9598
// FINGERPRINT
9699

97-
// Match a media file and lookup any matches
98-
func (c *Client) Match(ctx context.Context, r io.Reader, flags Meta) ([]*ResponseMatch, error) {
100+
// Match a media file and lookup any matches, using up to "dur" seconds
101+
// to fingerprint (or zero for no limit). The fingerprint is calculated
102+
func (c *Client) Match(ctx context.Context, r io.Reader, dur time.Duration, flags Meta) ([]*ResponseMatch, error) {
99103
// Create a segmenter
100-
segmenter, err := segmenter.NewReader(r, 0, 32000)
104+
segmenter, err := segmenter.NewReader(r, dur, sampleRate)
101105
if err != nil {
102106
return nil, err
103107
}
@@ -111,13 +115,17 @@ func (c *Client) Match(ctx context.Context, r io.Reader, flags Meta) ([]*Respons
111115
defer fp.Free()
112116

113117
// Start the fingerprinting
114-
if err := fp.Start(32000, 1); err != nil {
118+
if err := fp.Start(sampleRate, 1); err != nil {
115119
return nil, err
116120
}
117121

118-
// Perform fingerprinting
122+
// Perform fingerprinting. Segment the audio into 'dur' segments, only feed
123+
// the fingerprinter when the timestamp is less than 'dur'
119124
if err := segmenter.DecodeInt16(ctx, func(timestamp time.Duration, data []int16) error {
120-
return fp.WritePtr(uintptr(unsafe.Pointer(&data[0])), len(data))
125+
if dur == 0 || timestamp < dur {
126+
return fp.WritePtr(uintptr(unsafe.Pointer(&data[0])), len(data))
127+
}
128+
return nil
121129
}); err != nil {
122130
return nil, err
123131
}
@@ -127,6 +135,7 @@ func (c *Client) Match(ctx context.Context, r io.Reader, flags Meta) ([]*Respons
127135
return nil, err
128136
}
129137

138+
// Get fingerprint value
130139
value, err := fp.GetFingerprint()
131140
if err != nil {
132141
return nil, err

pkg/chromaprint/client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func Test_client_004(t *testing.T) {
8989
}
9090
defer r.Close()
9191

92-
matches, err := client.Match(context.Background(), r, META_ALL)
92+
matches, err := client.Match(context.Background(), r, 0, META_ALL)
9393
assert.NoError(err)
9494
t.Log(matches)
9595
}

pkg/segmenter/segmenter.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (s *Segmenter) Close() error {
8787

8888
// Return current timestamp
8989
func (s *Segmenter) Duration() time.Duration {
90-
return s.ts
90+
return s.reader.Duration()
9191
}
9292

9393
// Segments are output through a callback, with the samples and a timestamp
@@ -109,7 +109,7 @@ func (s *Segmenter) DecodeFloat32(ctx context.Context, fn SegmentFuncFloat32) er
109109

110110
// Allocate the buffer
111111
if s.n > 0 {
112-
s.buf_flt = make([]float32, s.n)
112+
s.buf_flt = make([]float32, 0, s.n)
113113
}
114114

115115
// Decode samples and segment
@@ -174,7 +174,7 @@ func (s *Segmenter) DecodeInt16(ctx context.Context, fn SegmentFuncInt16) error
174174

175175
// Allocate the buffer
176176
if s.n > 0 {
177-
s.buf_s16 = make([]int16, s.n)
177+
s.buf_s16 = make([]int16, 0, s.n)
178178
}
179179

180180
// Decode samples and segment

0 commit comments

Comments
 (0)