Skip to content

Commit 3886dc8

Browse files
committed
Updated chromaprint fingerprinting
1 parent 3b0e833 commit 3886dc8

File tree

8 files changed

+218
-337
lines changed

8 files changed

+218
-337
lines changed

chromaprint.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package media
2+
3+
import (
4+
"io"
5+
)
6+
7+
////////////////////////////////////////////////////////////////////////////////
8+
// TYPES
9+
10+
// Chromaprint is a wrapper around the chromaprint library. Create a new
11+
// Chromaprint object by calling chromaprint.New(sample_rate, channels)
12+
type Chromaprint interface {
13+
io.Closer
14+
15+
// Write sample data to the fingerprinter. Expects 16-bit signed integers
16+
// and returns number of samples written
17+
Write([]int16) (int64, error)
18+
19+
// Finish the fingerprinting, and compute the fingerprint, return as a
20+
// string
21+
Finish() (string, error)
22+
}

pkg/chromaprint/doc.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/*
2+
chromaprint provides bindings to the Chromaprint library, which is a
3+
library for extracting audio fingerprints.
4+
*/
5+
package chromaprint

pkg/chromaprint/fingerprint.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package chromaprint
2+
3+
import (
4+
"io"
5+
"unsafe"
6+
7+
// Packages
8+
"github.com/mutablelogic/go-media/sys/chromaprint"
9+
)
10+
11+
////////////////////////////////////////////////////////////////////////////////
12+
// TYPES
13+
14+
// Chromaprint is a wrapper around the chromaprint library. Create a new
15+
// Chromaprint object by calling New(rate,channels)
16+
type Chromaprint interface {
17+
io.Closer
18+
19+
// Write sample data to the fingerprinter. Expects 16-bit signed integers
20+
// and returns number of samples written
21+
Write([]int16) (int64, error)
22+
23+
// Finish the fingerprinting, and compute the fingerprint, return as a
24+
// string
25+
Finish() (string, error)
26+
}
27+
28+
type fingerprint struct {
29+
n int64
30+
ctx *chromaprint.Context
31+
}
32+
33+
////////////////////////////////////////////////////////////////////////////////
34+
// LIFECYCLE
35+
36+
// Create a new fingerprint context
37+
func New(rate, channels int) *fingerprint {
38+
// Create a context
39+
ctx := chromaprint.NewChromaprint(chromaprint.ALGORITHM_DEFAULT)
40+
if ctx == nil {
41+
return nil
42+
}
43+
// Start the fingerprinting
44+
if err := ctx.Start(rate, channels); err != nil {
45+
ctx.Free()
46+
return nil
47+
}
48+
// Return success
49+
return &fingerprint{0, ctx}
50+
}
51+
52+
// Close the fingerprint to release resources
53+
func (fingerprint *fingerprint) Close() error {
54+
// Free the context
55+
if fingerprint.ctx != nil {
56+
fingerprint.ctx.Free()
57+
}
58+
59+
// Release resources
60+
fingerprint.ctx = nil
61+
62+
// Return success
63+
return nil
64+
}
65+
66+
////////////////////////////////////////////////////////////////////////////////
67+
// PUBLIC METHODS
68+
69+
// Write 16-bit signed integers with little-endian format, and
70+
// return the total number of bytes written
71+
func (fingerprint *fingerprint) Write(data []int16) (int64, error) {
72+
if fingerprint.ctx == nil {
73+
return 0, io.ErrClosedPipe
74+
}
75+
if err := fingerprint.ctx.WritePtr(uintptr(unsafe.Pointer(&data[0])), len(data)); err != nil {
76+
return 0, err
77+
}
78+
fingerprint.n += int64(len(data))
79+
return fingerprint.n, nil
80+
}
81+
82+
// Finish the fingerprinting, and compute the fingerprint, return as a string
83+
func (fingerprint *fingerprint) Finish() (string, error) {
84+
if fingerprint.ctx == nil {
85+
return "", io.ErrClosedPipe
86+
}
87+
if err := fingerprint.ctx.Finish(); err != nil {
88+
return "", err
89+
}
90+
return fingerprint.ctx.GetFingerprint()
91+
}

pkg/chromaprint/fingerprint_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package chromaprint_test
2+
3+
import (
4+
"encoding/binary"
5+
"io"
6+
"os"
7+
"testing"
8+
9+
"github.com/mutablelogic/go-media/pkg/chromaprint"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
const (
14+
// Test data
15+
testData1 = "../../etc/test/s16le_22050_1ch_audio.raw"
16+
)
17+
18+
func Test_fingerprint_000(t *testing.T) {
19+
chromaprint.PrintVersion(os.Stderr)
20+
}
21+
22+
func Test_fingerprint_001(t *testing.T) {
23+
assert := assert.New(t)
24+
fingerprint := chromaprint.New(22050, 1)
25+
assert.NotNil(fingerprint)
26+
assert.NoError(fingerprint.Close())
27+
}
28+
29+
func Test_fingerprint_002(t *testing.T) {
30+
assert := assert.New(t)
31+
fingerprint := chromaprint.New(22050, 1)
32+
assert.NotNil(fingerprint)
33+
34+
r, err := os.Open(testData1)
35+
assert.NoError(err)
36+
defer r.Close()
37+
38+
buf := make([]int16, 1024)
39+
for {
40+
if err := binary.Read(r, binary.LittleEndian, buf); err == io.EOF {
41+
break
42+
}
43+
assert.NoError(err)
44+
n, err := fingerprint.Write(buf)
45+
assert.NoError(err)
46+
assert.NotZero(n)
47+
}
48+
str, err := fingerprint.Finish()
49+
assert.NoError(err)
50+
assert.NotEmpty(str)
51+
assert.NoError(fingerprint.Close())
52+
}

pkg/chromaprint/stream.go_old

Lines changed: 0 additions & 189 deletions
This file was deleted.

0 commit comments

Comments
 (0)