mirror of https://bitbucket.org/ausocean/av.git
81 lines
1.7 KiB
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)
|
|
|
|
}
|