From 7cafa6e6ba3a19b71b0f0032eec5cca84463f66f Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Tue, 23 Jan 2018 18:19:42 -0800 Subject: [PATCH] start work on the smpl metadata codec --- smpl_chunk.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 smpl_chunk.go diff --git a/smpl_chunk.go b/smpl_chunk.go new file mode 100644 index 0000000..79f2651 --- /dev/null +++ b/smpl_chunk.go @@ -0,0 +1,69 @@ +package wav + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/mattetti/audio/riff" +) + +// smpl chunk is documented here: +// https://sites.google.com/site/musicgapi/technical-documents/wav-file-format#smpl + +// DecodeSamplerChunk decodes a smpl chunk and put the data in Decoder.Metadata.SamplerInfo +func DecodeSamplerChunk(d *Decoder, ch *riff.Chunk) error { + if ch == nil { + return fmt.Errorf("can't decode a nil chunk") + } + if d == nil { + return fmt.Errorf("nil decoder") + } + if ch.ID == CIDSmpl { + // read the entire chunk in memory + buf := make([]byte, ch.Size) + var err error + if _, err = ch.Read(buf); err != nil { + return fmt.Errorf("failed to read the smpl chunk - %v", err) + } + if d.Metadata == nil { + d.Metadata = &Metadata{} + } + + d.Metadata.SamplerInfo = &SamplerInfo{} + + r := bytes.NewReader(buf) + + scratch := make([]byte, 4) + if _, err = r.Read(scratch); err != nil { + return fmt.Errorf("failed to read the smpl Manufacturer") + } + copy(d.Metadata.SamplerInfo.Manufacturer[:], scratch[:4]) + if _, err = r.Read(scratch); err != nil { + return fmt.Errorf("failed to read the smpl Product") + } + copy(d.Metadata.SamplerInfo.Product[:], scratch[:4]) + + if err := binary.Read(r, binary.BigEndian, &d.Metadata.SamplerInfo.SamplePeriod); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &d.Metadata.SamplerInfo.MIDIUnityNote); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &d.Metadata.SamplerInfo.MIDIPitchFraction); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &d.Metadata.SamplerInfo.SMPTEFormat); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &d.Metadata.SamplerInfo.SMPTEOffset); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &d.Metadata.SamplerInfo.NumSampleLoops); err != nil { + return err + } + //TODO: loops + } + ch.Drain() + return nil +}