av/cmd/adpcm/main.go

81 lines
1.7 KiB
Go

package main
import (
"fmt"
"io/ioutil"
"os"
"github.com/bovarysme/adpcm"
"github.com/go-audio/audio"
"github.com/go-audio/wav"
"github.com/pkg/errors"
)
// This program is for compare data size of pcm and adpcm, it takes a wav file and compresses and encodes it to adpcm,
// the adpcm byte array is stored as a file and then the adpcm is decoded and the result saved as final.wav
func main() {
//open wav
wavPath := "out.wav"
f, err := os.Open(wavPath)
if err != nil {
panic(err)
}
defer f.Close()
//decode wav
dec := wav.NewDecoder(f)
if !dec.IsValidFile() {
panic(errors.Errorf("invalid WAV file %q", wavPath))
}
sampleRate, nchannels, bps := int(dec.SampleRate), int(dec.NumChans), int(dec.BitDepth)
buf, err := dec.FullPCMBuffer()
if err != nil {
panic(err)
}
//encode adpcm
var comp []byte
adpcm.Encode(buf.Data, &comp)
// save to file
pcmPath := "out.adpcm"
err = ioutil.WriteFile(pcmPath, comp, 0644)
if err != nil {
panic(err)
}
//decode adpcm
var decoded []int
deco := adpcm.NewDecoder(nchannels)
deco.Decode(comp, &decoded)
//encode wav and save to file
finalWavPath := "final.wav"
of, err := os.Create(finalWavPath)
if err != nil {
panic(err)
}
defer of.Close()
sampleBytes := bps / 8
// normal uncompressed WAV format
wavformat := 1
enc := wav.NewEncoder(of, sampleRate, bps, nchannels, wavformat)
format := &audio.Format{
NumChannels: nchannels,
SampleRate: sampleRate,
}
intBuf := &audio.IntBuffer{Data: decoded, Format: format, SourceBitDepth: sampleBytes * 8}
if err := enc.Write(intBuf); err != nil {
panic(err)
}
if err := enc.Close(); err != nil {
panic(err)
}
fmt.Printf("Saved audio to %s\n", finalWavPath)
}