Created
September 15, 2023 21:15
-
-
Save breadchris/b2051cca4cbe3bbbb8397110563dea38 to your computer and use it in GitHub Desktop.
Go Split WAV File
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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