mirror of https://bitbucket.org/ausocean/av.git
107 lines
2.4 KiB
Go
107 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"flag"
|
|
"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
|
|
var wavPath string
|
|
flag.StringVar(&wavPath, "path", "before_compression.wav", "file path of input data")
|
|
flag.Parse()
|
|
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)
|
|
}
|
|
fmt.Println("Decoded wav. First 8 samples: ")
|
|
for i := 0; i < len(buf.Data) && i < 8; i++ {
|
|
fmt.Print(buf.Data[i], ", ")
|
|
}
|
|
fmt.Println()
|
|
// save pcm to file
|
|
var pcmBytes []byte
|
|
for _, sample := range buf.Data {
|
|
bs := make([]byte, 2)
|
|
binary.LittleEndian.PutUint16(bs, uint16(sample))
|
|
pcmBytes = append(pcmBytes, bs[0], bs[1])
|
|
}
|
|
pcmPath := "out.pcm"
|
|
err = ioutil.WriteFile(pcmPath, pcmBytes, 0644)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Println("Saved raw PCM to " + pcmPath + ". First 8 bytes: ")
|
|
for i := 0; i < len(pcmBytes) && i < 8; i++ {
|
|
fmt.Print(pcmBytes[i], ", ")
|
|
}
|
|
fmt.Println()
|
|
//encode adpcm
|
|
var comp []byte
|
|
adpcm.Encode(buf.Data, &comp)
|
|
// save adpcm to file
|
|
adpcmPath := "out.adpcm"
|
|
err = ioutil.WriteFile(adpcmPath, 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)
|
|
|
|
}
|