Skip to content

Instantly share code, notes, and snippets.

@breadchris
Created September 15, 2023 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save breadchris/b2051cca4cbe3bbbb8397110563dea38 to your computer and use it in GitHub Desktop.
Save breadchris/b2051cca4cbe3bbbb8397110563dea38 to your computer and use it in GitHub Desktop.
Go Split WAV File
package main
import (
"fmt"
"github.com/go-audio/wav"
"github.com/lunabrain-ai/lunabrain/pkg/store/bucket"
"github.com/pkg/errors"
"math"
"os"
"path"
)
func splitWAVFile(fileStore *bucket.Bucket, id string, filepath string, maxFileSize int, cb func(string) error) error {
headerSize := 44 + 1024
file, err := os.Open(filepath)
if err != nil {
return err
}
defer file.Close()
decoder := wav.NewDecoder(file)
buf, err := decoder.FullPCMBuffer()
if err != nil {
return err
}
frameCount := buf.NumFrames()
sampleSize := (buf.SourceBitDepth / 8) * buf.Format.NumChannels
maxSamplesPerChunk := (maxFileSize - headerSize) / sampleSize
chunks := int(math.Ceil(float64(frameCount) / float64(maxSamplesPerChunk)))
d, err := fileStore.NewDir(id + "_chunks")
if err != nil {
return errors.Wrapf(err, "failed to create bucket dir for file %s", filepath)
}
for i := 0; i < chunks; i++ {
start := i * maxSamplesPerChunk
end := start + maxSamplesPerChunk
if end > frameCount {
end = frameCount
}
bucketFile := path.Join(d, fmt.Sprintf("chunk_%d.wav", i))
outFile, err := os.Create(bucketFile)
if err != nil {
return errors.Wrapf(err, "failed to create file")
}
enc := wav.NewEncoder(outFile, buf.Format.SampleRate, buf.SourceBitDepth, buf.Format.NumChannels, 1)
// take a slice of the audio buffer for the chunk
b := buf.Clone().AsIntBuffer()
b.Data = buf.Data[start*buf.Format.NumChannels : end*buf.Format.NumChannels]
err = enc.Write(b)
if err != nil {
return err
}
if err := enc.Close(); err != nil {
return err
}
err = cb(bucketFile)
if err != nil {
return err
}
}
return nil
}
func main() {
fileStore, err := bucket.New(bucket.Config{
Path: "/tmp/audio",
})
if err != nil {
panic(err)
}
err = splitWAVFile(fileStore, "test", "test.wav", 25*1024*1024, func(chunkFilePath string) error {
println("chunk", chunkFilePath)
})
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment