mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
137 lines
3.6 KiB
Go
137 lines
3.6 KiB
Go
//go:build ignore
|
|
// +build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
|
|
"github.com/vsariola/sointu/tracker"
|
|
)
|
|
|
|
type riffVisitor interface {
|
|
Enter(listType string)
|
|
Leave(listType string)
|
|
Visit(filePos int, chunkType string, data []byte)
|
|
}
|
|
|
|
type gmDlsVisitor struct {
|
|
outputFile io.Writer
|
|
entry tracker.GmDlsEntry
|
|
dataLength int
|
|
count int
|
|
}
|
|
|
|
func (v *gmDlsVisitor) Enter(listType string) {
|
|
if listType == "wave" {
|
|
v.entry = tracker.GmDlsEntry{}
|
|
v.dataLength = 0
|
|
}
|
|
}
|
|
|
|
func (v *gmDlsVisitor) Leave(listType string) {
|
|
if listType == "wave" {
|
|
if v.entry.LoopLength == 0 {
|
|
v.entry.LoopStart = v.dataLength/2 - 1
|
|
v.entry.LoopLength = 1
|
|
}
|
|
if v.entry.Name == "" {
|
|
v.entry.Name = fmt.Sprintf("#%v", v.count)
|
|
}
|
|
fmt.Fprintf(v.outputFile, "\t{Start: %v, LoopStart: %v, LoopLength: %v, SuggestedTranspose: %v, Name: \"%v\"},\n", v.entry.Start, v.entry.LoopStart, v.entry.LoopLength, v.entry.SuggestedTranspose, v.entry.Name)
|
|
v.count++
|
|
}
|
|
}
|
|
|
|
func (v *gmDlsVisitor) Visit(filePos int, chunkType string, data []byte) {
|
|
switch chunkType {
|
|
case "wsmp":
|
|
v.entry.SuggestedTranspose = 60 - int(binary.LittleEndian.Uint16(data[4:6]))
|
|
numLoops := binary.LittleEndian.Uint32(data[16:20])
|
|
if numLoops > 0 {
|
|
v.entry.LoopStart = int(binary.LittleEndian.Uint32(data[28:32]))
|
|
v.entry.LoopLength = int(binary.LittleEndian.Uint32(data[32:36]))
|
|
}
|
|
case "data":
|
|
v.entry.Start = filePos / 2
|
|
v.dataLength = len(data)
|
|
case "INAM":
|
|
v.entry.Name = string(data[:len(data)-1])
|
|
}
|
|
}
|
|
|
|
func readChunk(filePos int, reader io.Reader, visitor riffVisitor) int {
|
|
var chunkType [4]byte
|
|
n, err := io.ReadFull(reader, chunkType[:])
|
|
check(err)
|
|
if n < 4 {
|
|
panic("did not get full 4 bytes for a chunktype")
|
|
}
|
|
filePos += n
|
|
chunkTypeString := string(chunkType[:])
|
|
var chunkLength int32
|
|
check(binary.Read(reader, binary.LittleEndian, &chunkLength))
|
|
filePos += 4
|
|
if chunkTypeString == "RIFF" || chunkTypeString == "LIST" {
|
|
end := filePos + int(chunkLength)
|
|
var listType [4]byte
|
|
n, err := io.ReadFull(reader, listType[:])
|
|
check(err)
|
|
if n < 4 {
|
|
panic("did not get full 4 bytes for a subchunkname")
|
|
}
|
|
filePos += n
|
|
listTypeString := string(listType[:])
|
|
visitor.Enter(listTypeString)
|
|
for filePos < end {
|
|
filePos = readChunk(filePos, reader, visitor)
|
|
}
|
|
visitor.Leave(listTypeString)
|
|
} else {
|
|
data := make([]byte, chunkLength)
|
|
n, err := reader.Read(data)
|
|
check(err)
|
|
if n < int(chunkLength) {
|
|
panic(fmt.Sprintf("chunk %v was supposed to be %v bytes, got %v bytes", chunkTypeString, chunkLength, n))
|
|
}
|
|
visitor.Visit(filePos, chunkTypeString, data)
|
|
filePos += n
|
|
}
|
|
if chunkLength&1 == 1 {
|
|
io.CopyN(ioutil.Discard, reader, 1)
|
|
filePos++
|
|
}
|
|
return filePos
|
|
}
|
|
|
|
func check(e error) {
|
|
if e != nil {
|
|
panic(e)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
inputFile, err := os.Open("C:\\Windows\\System32\\drivers\\gm.dls")
|
|
check(err)
|
|
defer inputFile.Close()
|
|
//_, myname, _, _ := runtime.Caller(0)
|
|
//outputFilePath := path.Join(path.Dir(myname), "gmdlsentries.go")
|
|
//check(err)
|
|
outputFile, err := os.Create("gmdlsentries.go")
|
|
check(err)
|
|
defer outputFile.Close()
|
|
fmt.Fprintln(outputFile, "package tracker")
|
|
fmt.Fprintln(outputFile, "")
|
|
fmt.Fprintln(outputFile, "// Code generated by go generate; DO NOT EDIT.")
|
|
fmt.Fprintln(outputFile, "")
|
|
fmt.Fprintln(outputFile, "// GmDlsEntries is a list of all samples in the gm.dls file. Do not modify")
|
|
fmt.Fprintln(outputFile, "// during runtime.")
|
|
fmt.Fprintln(outputFile, "var GmDlsEntries = []GmDlsEntry{")
|
|
readChunk(0, inputFile, &gmDlsVisitor{outputFile: outputFile})
|
|
fmt.Fprintln(outputFile, "}")
|
|
}
|