Kirika/Kirika_test.go
DataHoarder d668ae6286
Some checks failed
continuous-integration/drone/push Build is failing
Update format/readme
2022-02-27 19:44:04 +01:00

430 lines
11 KiB
Go

package Kirika
import (
"bytes"
"encoding/hex"
"git.gammaspectra.live/S.O.N.G/Kirika/audio"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format/flac"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format/mp3"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format/opus"
"git.gammaspectra.live/S.O.N.G/Kirika/audio/format/tta"
"git.gammaspectra.live/S.O.N.G/Kirika/hasher"
"os"
"path"
"testing"
)
var TestSampleLocations = []string{
"resources/samples/cYsmix - Haunted House/",
"resources/samples/Babbe Music - RADIANT DANCEFLOOR/",
}
const TestSingleSample24 = "resources/samples/cYsmix - Haunted House/11. The Great Rigid Desert.flac"
const TestSingleSample16 = "resources/samples/Babbe Music - RADIANT DANCEFLOOR/01. ENTER.flac"
const TestSingleSample16TTA = "resources/samples/Babbe Music - RADIANT DANCEFLOOR/01. ENTER.tta"
func doTest(format format.Decoder, ext string, t *testing.T) {
for _, location := range TestSampleLocations {
entries, err := os.ReadDir(location)
if err != nil {
t.Error(err)
return
}
for _, f := range entries {
if path.Ext(f.Name()) == ext {
fullPath := path.Join(location, f.Name())
t.Run(f.Name(), func(t *testing.T) {
t.Parallel()
fp, err := os.Open(fullPath)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, err := format.Open(fp)
if err != nil {
t.Error(err)
return
}
//Decode
for range source.Blocks {
}
})
}
}
}
}
func TestFLACDecode(t *testing.T) {
doTest(flac.NewFormat(), ".flac", t)
}
func TestTTADecode(t *testing.T) {
doTest(tta.NewFormat(), ".tta", t)
}
func TestOpusDecode(t *testing.T) {
doTest(opus.NewFormat(), ".opus", t)
}
func TestMP3Decode(t *testing.T) {
doTest(mp3.NewFormat(), ".mp3", t)
}
func TestHasher24(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample24)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, analyzerChannel, err := flac.NewFormat().OpenAnalyzer(fp)
if err != nil {
t.Error(err)
return
}
chans := analyzerChannel.Split(2)
crc32 := hasher.NewHasher(chans[0], hasher.HashtypeCrc32)
sha256 := hasher.NewHasher(chans[1], hasher.HashtypeSha256)
//Decode
for range source.Blocks {
}
crc32.Wait()
sha256.Wait()
expectCrc32, _ := hex.DecodeString("A54636CD")
if bytes.Compare(crc32.GetResult(), expectCrc32) != 0 {
t.Errorf("Wrong CRC32 %08X != %08X", crc32.GetResult(), expectCrc32)
}
expectSha256, _ := hex.DecodeString("9B6715ED75B6C8074B749C630AC9C626994080DEACBEA363976391366DA4E4FA")
if bytes.Compare(sha256.GetResult(), expectSha256) != 0 {
t.Errorf("Wrong SHA256 %08X != %08X", sha256.GetResult(), expectSha256)
}
}
func TestHasher16(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample16)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, analyzerChannel, err := flac.NewFormat().OpenAnalyzer(fp)
if err != nil {
t.Error(err)
return
}
channels := analyzerChannel.Split(4)
cueToolsCrc32 := hasher.NewHasher(channels[0].SkipStartSamples(hasher.Int16SamplesPerSector*10), hasher.HashtypeCrc32)
arChannels := channels[1].SkipStartSamples(hasher.Int16SamplesPerSector*5 - 1).Split(2)
accurateRipV1 := hasher.NewHasher(arChannels[0], hasher.HashtypeAccurateRipV1Start)
accurateRipV2 := hasher.NewHasher(arChannels[1], hasher.HashtypeAccurateRipV2Start)
crc32 := hasher.NewHasher(channels[2], hasher.HashtypeCrc32)
sha256 := hasher.NewHasher(channels[3], hasher.HashtypeSha256)
//Decode
for range source.Blocks {
}
cueToolsCrc32.Wait()
accurateRipV1.Wait()
accurateRipV2.Wait()
crc32.Wait()
sha256.Wait()
expectCueToolsCrc32, _ := hex.DecodeString("18701E02")
if bytes.Compare(cueToolsCrc32.GetResult(), expectCueToolsCrc32) != 0 {
t.Errorf("Wrong CTDB CRC32 %08X != %08X", cueToolsCrc32.GetResult(), expectCueToolsCrc32)
}
expectAccurateRipV1, _ := hex.DecodeString("5593DA89")
if bytes.Compare(accurateRipV1.GetResult(), expectAccurateRipV1) != 0 {
t.Errorf("Wrong AccurateRip V1 %08X != %08X", accurateRipV1.GetResult(), expectAccurateRipV1)
}
expectAccurateRipV2, _ := hex.DecodeString("DAA40E75")
if bytes.Compare(accurateRipV2.GetResult(), expectAccurateRipV2) != 0 {
t.Errorf("Wrong AccurateRip V2 %08X != %08X", accurateRipV2.GetResult(), expectAccurateRipV2)
}
expectCrc32, _ := hex.DecodeString("50CE5057")
if bytes.Compare(crc32.GetResult(), expectCrc32) != 0 {
t.Errorf("Wrong CRC32 %08X != %08X", crc32.GetResult(), expectCrc32)
}
expectSha256, _ := hex.DecodeString("FEDF080D500D1A49DF8366BE619918D2A5D00413B7C7613A39DC00659FA25AC6")
if bytes.Compare(sha256.GetResult(), expectSha256) != 0 {
t.Errorf("Wrong SHA256 %X != %X", sha256.GetResult(), expectSha256)
}
}
func TestHasher16TTA(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample16TTA)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, analyzerChannel, err := tta.NewFormat().OpenAnalyzer(fp)
if err != nil {
t.Error(err)
return
}
channels := analyzerChannel.Split(4)
cueToolsCrc32 := hasher.NewHasher(channels[0].SkipStartSamples(hasher.Int16SamplesPerSector*10), hasher.HashtypeCrc32)
arChannels := channels[1].SkipStartSamples(hasher.Int16SamplesPerSector*5 - 1).Split(2)
accurateRipV1 := hasher.NewHasher(arChannels[0], hasher.HashtypeAccurateRipV1Start)
accurateRipV2 := hasher.NewHasher(arChannels[1], hasher.HashtypeAccurateRipV2Start)
crc32 := hasher.NewHasher(channels[2], hasher.HashtypeCrc32)
sha256 := hasher.NewHasher(channels[3], hasher.HashtypeSha256)
//Decode
for range source.Blocks {
}
cueToolsCrc32.Wait()
accurateRipV1.Wait()
accurateRipV2.Wait()
crc32.Wait()
sha256.Wait()
expectCueToolsCrc32, _ := hex.DecodeString("18701E02")
if bytes.Compare(cueToolsCrc32.GetResult(), expectCueToolsCrc32) != 0 {
t.Errorf("Wrong CTDB CRC32 %08X != %08X", cueToolsCrc32.GetResult(), expectCueToolsCrc32)
}
expectAccurateRipV1, _ := hex.DecodeString("5593DA89")
if bytes.Compare(accurateRipV1.GetResult(), expectAccurateRipV1) != 0 {
t.Errorf("Wrong AccurateRip V1 %08X != %08X", accurateRipV1.GetResult(), expectAccurateRipV1)
}
expectAccurateRipV2, _ := hex.DecodeString("DAA40E75")
if bytes.Compare(accurateRipV2.GetResult(), expectAccurateRipV2) != 0 {
t.Errorf("Wrong AccurateRip V2 %08X != %08X", accurateRipV2.GetResult(), expectAccurateRipV2)
}
expectCrc32, _ := hex.DecodeString("50CE5057")
if bytes.Compare(crc32.GetResult(), expectCrc32) != 0 {
t.Errorf("Wrong CRC32 %08X != %08X", crc32.GetResult(), expectCrc32)
}
expectSha256, _ := hex.DecodeString("FEDF080D500D1A49DF8366BE619918D2A5D00413B7C7613A39DC00659FA25AC6")
if bytes.Compare(sha256.GetResult(), expectSha256) != 0 {
t.Errorf("Wrong SHA256 %X != %X", sha256.GetResult(), expectSha256)
}
}
func TestFilterChain(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample24)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, err := flac.NewFormat().Open(fp)
if err != nil {
t.Error(err)
return
}
const sampleRate = 16000
result := audio.NewFilterChain(source, audio.MonoFilter{}, audio.NewResampleFilter(sampleRate, audio.BandlimitedFastest, 0), audio.StereoFilter{})
sink := audio.NewForwardSink(audio.NewNullSink())
sink.Process(result)
if result.SampleRate != sampleRate {
t.Errorf("Wrong SampleRate %d != %d", result.SampleRate, sampleRate)
}
if result.Channels != 2 {
t.Errorf("Wrong Channel Count %d != %d", result.SampleRate, 2)
}
if sink.SamplesRead != 6284999 {
t.Errorf("Wrong Sample Count %d != %d", sink.SamplesRead, 6284999)
}
}
func TestEncodeFLAC(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample24)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, err := flac.NewFormat().Open(fp)
if err != nil {
t.Error(err)
return
}
target, err := os.CreateTemp("/tmp", "encode_test_*.flac")
if err != nil {
t.Error(err)
return
}
defer func() {
name := target.Name()
target.Close()
os.Remove(name)
}()
err = flac.NewFormat().Encode(source, target, nil)
if err != nil {
t.Error(err)
return
}
}
func TestEncodeMP3(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample24)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, err := flac.NewFormat().Open(fp)
if err != nil {
t.Error(err)
return
}
target, err := os.CreateTemp("/tmp", "encode_test_*.mp3")
if err != nil {
t.Error(err)
return
}
defer func() {
name := target.Name()
target.Close()
os.Remove(name)
}()
err = mp3.NewFormat().Encode(source, target, nil)
if err != nil {
t.Error(err)
return
}
}
func TestEncodeOpus(t *testing.T) {
t.Parallel()
fp, err := os.Open(TestSingleSample24)
if err != nil {
t.Error(err)
return
}
defer fp.Close()
source, err := flac.NewFormat().Open(fp)
if err != nil {
t.Error(err)
return
}
target, err := os.CreateTemp("/tmp", "encode_test_*.opus")
if err != nil {
t.Error(err)
return
}
defer func() {
name := target.Name()
target.Close()
os.Remove(name)
}()
options := make(map[string]interface{})
options["bitrate"] = "256k"
err = opus.NewFormat().Encode(audio.NewResampleFilter(opus.FixedSampleRate, audio.Linear, 0).Process(source), target, nil)
if err != nil {
t.Error(err)
return
}
}
func TestQueue(t *testing.T) {
t.Parallel()
const sampleRate = 41000
q := audio.NewQueue(sampleRate, 2, 2)
flacFormat := flac.NewFormat()
for _, location := range TestSampleLocations {
entries, err := os.ReadDir(location)
if err != nil {
t.Error(err)
return
}
for _, f := range entries {
if path.Ext(f.Name()) == ".flac" {
fullPath := path.Join(location, f.Name())
fp, err := os.Open(fullPath)
if err != nil {
t.Error(err)
return
}
source, err := flacFormat.Open(fp)
if err != nil {
fp.Close()
t.Error(err)
return
}
q.Add(source, func(q *audio.Queue, entry *audio.QueueEntry) {
t.Logf("Started playback of %d %s\n", entry.Identifier, fullPath)
}, func(q *audio.Queue, entry *audio.QueueEntry) {
if len(q.GetQueue()) == 0 {
t.Log("Finished playback, closing\n")
q.Close()
}
t.Logf("Finished playback of %d %s: output %d samples\n", entry.Identifier, fullPath, entry.ReadSamples)
fp.Close()
})
}
}
}
//Decode
result := q.GetSource()
sink := audio.NewForwardSink(audio.NewNullSink())
sink.Process(result)
q.Wait()
if result.SampleRate != sampleRate {
t.Errorf("Wrong SampleRate %d != %d", result.SampleRate, sampleRate)
}
if result.Channels != 2 {
t.Errorf("Wrong Channel Count %d != %d", result.SampleRate, 2)
}
if sink.SamplesRead != 437731779 {
t.Errorf("Wrong Sample Count %d != %d", sink.SamplesRead, 437731779)
}
}