Added query by TOC
This commit is contained in:
parent
0cf78c99eb
commit
64ed905c81
38
server.go
38
server.go
|
@ -14,6 +14,7 @@ import (
|
|||
"io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
|
@ -471,8 +472,10 @@ func processIndexDirectory(filePath, indexPath, kind string, wg *sync.WaitGroup)
|
|||
track.Original = strings.TrimSpace(strings.Join(getStringValue(entry.MainTitle, values), " "))
|
||||
case "lyrics", "vocals", "arranger", "composer", "producer", "remix":
|
||||
track.Artists = append(track.Artists, getArtistEntries(keyEntry, values)...)
|
||||
case "arrangement", "original arrangement":
|
||||
case "arrangement":
|
||||
track.Artists = append(track.Artists, getArtistEntries("arranger", values)...)
|
||||
case "original arrangement":
|
||||
track.Artists = append(track.Artists, getArtistEntries("original arranger", values)...)
|
||||
case "composition":
|
||||
track.Artists = append(track.Artists, getArtistEntries("composer", values)...)
|
||||
|
||||
|
@ -594,9 +597,31 @@ func normalizeStringCharacters(text string) (normalized string) {
|
|||
|
||||
type findByDurationResult struct {
|
||||
albumEntry *albumEntry
|
||||
cddb1 utilities.CDDB1
|
||||
toc utilities.TOC
|
||||
discIndex int
|
||||
}
|
||||
|
||||
func findByTOC(toc utilities.TOC, trackThreshold, discThreshold int) (results []findByDurationResult) {
|
||||
for _, result := range findByCDDB1(toc.GetCDDB1(), discThreshold) {
|
||||
func() {
|
||||
for i, track := range result.albumEntry.Discs[result.discIndex].Tracks {
|
||||
diff := math.Abs(float64(track.Duration) - toc.GetTrackDuration(i).Seconds())
|
||||
if diff > float64(trackThreshold) { //too much variation
|
||||
return
|
||||
}
|
||||
}
|
||||
results = append(results, result)
|
||||
}()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func findByCDDB1(cddb1 utilities.CDDB1, discThreshold int) []findByDurationResult {
|
||||
return findByTracksAndDuration(cddb1.GetTrackNumber(), int(cddb1.GetDuration().Seconds()), discThreshold)
|
||||
}
|
||||
|
||||
func findByTracksAndDuration(tracks, duration, threshold int) (results []findByDurationResult) {
|
||||
for _, r := range discTracksLookup[tracks] {
|
||||
for i, d := range r.Discs {
|
||||
|
@ -668,13 +693,20 @@ func main() {
|
|||
|
||||
cddb1 := utilities.NewCDDB1FromString(splits[2])
|
||||
|
||||
//cddb1_calc := utilities.GetCDDB1FromTOC(splits[3:])
|
||||
toc := utilities.NewTOCFromCDDBString(strings.Join(splits[3:], " "))
|
||||
if cddb1 == 0 {
|
||||
writer.Write([]byte("500 Command syntax error\n.\n"))
|
||||
return
|
||||
}
|
||||
|
||||
entries := findByTracksAndDuration(cddb1.GetTrackNumber(), int(cddb1.GetDuration().Seconds()), 10)
|
||||
var entries []findByDurationResult
|
||||
if toc != nil {
|
||||
cddb1 = toc.GetCDDB1()
|
||||
entries = findByTOC(toc, 3, 10)
|
||||
} else {
|
||||
entries = findByCDDB1(cddb1, 10)
|
||||
}
|
||||
|
||||
if len(entries) == 0 {
|
||||
writer.Write([]byte("202 No match found\n.\n"))
|
||||
return
|
||||
|
|
161
utilities/toc.go
Normal file
161
utilities/toc.go
Normal file
|
@ -0,0 +1,161 @@
|
|||
package utilities
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const TocPregap = 150
|
||||
const SectorsPerSecond = 75
|
||||
const DataTrackGap = 11400
|
||||
const BytesPerSector = 2352
|
||||
const CDChannels = 2
|
||||
const Int16SamplesPerSector = BytesPerSector / (2 * CDChannels)
|
||||
const CDSampleRate = Int16SamplesPerSector * SectorsPerSecond
|
||||
|
||||
//TOC includes a list, index 0 being total sectors/end, then start times follow, with TocPregap added
|
||||
type TOC []int
|
||||
|
||||
func NewTOCFromString(toc string, split ...string) (r TOC) {
|
||||
sep := " "
|
||||
if len(split) > 0 {
|
||||
sep = split[0]
|
||||
}
|
||||
for _, i := range strings.Split(toc, sep) {
|
||||
item, err := strconv.Atoi(i)
|
||||
if err == nil {
|
||||
r = append(r, item)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NewTOCFromCDDBString(toc string) (r TOC) {
|
||||
t := NewTOCFromString(toc)
|
||||
|
||||
if len(t) < 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
t = t[1 : len(t)-1] //cut
|
||||
r = append(TOC{t[len(t)-1]}, t[0:len(t)-1]...) //put last sample at the front
|
||||
for i := 0; i < len(t); i++ {
|
||||
r[i] += TocPregap
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NewTOCFromCTDBString(toc string) (r TOC) {
|
||||
t := NewTOCFromString(toc)
|
||||
|
||||
r = append(r, t[len(t)-1]+TocPregap)
|
||||
for i := 0; i < len(t)-1; i++ {
|
||||
r = append(r, t[i]+TocPregap)
|
||||
}
|
||||
return
|
||||
}
|
||||
func NewTOCFromCTDB2String(toc string) (r TOC) {
|
||||
t := NewTOCFromString(toc, ":")
|
||||
|
||||
r = append(r, t[len(t)-1]+TocPregap)
|
||||
for i := 0; i < len(t)-1; i++ {
|
||||
r = append(r, t[i]+TocPregap)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t TOC) GetTrackNumber() int {
|
||||
return len(t) - 1
|
||||
}
|
||||
|
||||
func (t TOC) GetDuration() time.Duration {
|
||||
return (time.Second * time.Duration(t[0]-t[1])) / SectorsPerSecond
|
||||
}
|
||||
|
||||
func (t TOC) GetTrackDuration(index int) time.Duration {
|
||||
if index < 0 || index > len(t)-2 {
|
||||
return 0
|
||||
} else if index == len(t)-2 {
|
||||
return (time.Second * time.Duration(t[0]-t[index+1])) / SectorsPerSecond
|
||||
} else {
|
||||
return (time.Second * time.Duration(t[index+2]-t[index+1])) / SectorsPerSecond
|
||||
}
|
||||
}
|
||||
|
||||
func (t TOC) CTDBString() string {
|
||||
toc := make([]string, 0, len(t))
|
||||
for _, o := range t[1:] {
|
||||
toc = append(toc, fmt.Sprintf("%d", o-TocPregap))
|
||||
}
|
||||
toc = append(toc, fmt.Sprintf("%d", t[0]-TocPregap))
|
||||
|
||||
return strings.Join(toc, ":")
|
||||
}
|
||||
|
||||
func (t TOC) CDDBString() string {
|
||||
return fmt.Sprintf("%s %d %s %d", t.GetCDDB1(), t.GetTrackNumber(), t[1:].String(), int(t.GetDuration().Seconds()))
|
||||
}
|
||||
|
||||
func (t TOC) MusicBrainzString() string {
|
||||
return fmt.Sprintf("1 %d %s", t.GetTrackNumber(), t.String())
|
||||
}
|
||||
|
||||
func (t TOC) String() string {
|
||||
toc := make([]string, 0, len(t))
|
||||
for _, o := range t {
|
||||
toc = append(toc, fmt.Sprintf("%d", o))
|
||||
}
|
||||
return strings.Join(toc, " ")
|
||||
}
|
||||
|
||||
func (t TOC) GetCDDB1() CDDB1 {
|
||||
|
||||
length := uint32(t.GetDuration().Seconds())
|
||||
checksum := uint32(0)
|
||||
for i := 1; i < len(t); i++ {
|
||||
n := uint32(t[i] / SectorsPerSecond)
|
||||
for n > 0 {
|
||||
checksum += n % 10
|
||||
n /= 10
|
||||
}
|
||||
}
|
||||
|
||||
return CDDB1(uint32((len(t)-1)&0xFF) | ((length & 0xFFFF) << 8) | ((checksum % 255) << 24))
|
||||
}
|
||||
|
||||
func (t TOC) GetAccurateRipData() (byte, uint32, uint32, CDDB1) {
|
||||
|
||||
var TrackOffsetsAdded uint32
|
||||
var TrackOffsetsMultiplied uint32
|
||||
var num uint32
|
||||
for i := 1; i < len(t); i++ {
|
||||
start := uint32(t[i] - TocPregap)
|
||||
TrackOffsetsAdded += start
|
||||
if start < 1 {
|
||||
start = 1
|
||||
}
|
||||
num++
|
||||
TrackOffsetsMultiplied += start * num
|
||||
}
|
||||
TrackOffsetsAdded += uint32(t[0] - TocPregap)
|
||||
num++
|
||||
TrackOffsetsMultiplied += uint32(t[0]-TocPregap) * num
|
||||
|
||||
return byte(t.GetTrackNumber()), TrackOffsetsAdded, TrackOffsetsMultiplied, t.GetCDDB1()
|
||||
}
|
||||
|
||||
func (t TOC) Equals(o TOC) bool {
|
||||
if len(t) != len(o) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, d := range t {
|
||||
if o[i] != d {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Loading…
Reference in a new issue