wav
wav copied to clipboard
What am I doing wrong trying to encode a stream from Portaudio as a .wav?
func recordWav() string {
audioFileName := "temp.wav" //os.Args[1]
fmt.Println("Recording. Press ESC to quit.")
waveFile, err := os.Create(audioFileName)
chk(err)
// www.people.csail.mit.edu/hubert/pyaudio/ - under the Record tab
inputChannels := 1
outputChannels := 0
sampleRate := 44100
// init PortAudio
portaudio.Initialize()
//defer portaudio.Terminate()
encoder := wav.NewEncoder(waveFile, sampleRate, 16, 1, 1)
format := &audio.Format{
NumChannels: 1,
SampleRate: 44100,
}
data := make([]int, 4096)
buf := &audio.IntBuffer{Data: data, Format: format, SourceBitDepth: 16}
buf32 := buf.AsFloat32Buffer()
stream, err := portaudio.OpenDefaultStream(inputChannels, outputChannels, float64(sampleRate), 64, buf32.Data)
chk(err)
chk(stream.Start())
for start := time.Now(); time.Since(start) < time.Second*7; {
chk(stream.Read())
log.Println("Recording...")
// write to wave file
err := encoder.Write(buf)
chk(err)
}
stream.Close()
portaudio.Terminate()
return audioFileName
}
The only array type that portaudio and audio.IntBuffer both support is float32[]. When I run this code, nothing gets recorded. The file is silent. I don't know if this is the right place for this, but what the heck am I doing wrong? Is it something to do with converting to float32?
I'm not in front of my computer but if I recall correctly, it doesn't seem that you are using the port audio API properly. Your buffer isn't 7s long and I believe port audio has some sort of callback mechanism when the buffer is ready to be dumped
Also you need to close the encoder to add the right headers to the file
did you manage to make them work together?
This code successfully saves a wav file, but the resulting file has weird clicking in the audio.
NOTE: s.Audio is []int32
audioFile, err := os.Create(path.Join(dir, "audio.wav"))
if err != nil {
return err
}
defer audioFile.Close()
e := wav.NewEncoder(audioFile, sampleRate, 32, 1, 1)
defer e.Close()
buf := audio.IntBuffer{
Format: audio.FormatMono44100,
SourceBitDepth: 32,
}
for _, sample := range s.Audio {
buf.Data = append(buf.Data, int(sample))
}
err = e.Write(&buf)
if err != nil {
return err
}
The problem I was having was that I wasn't waiting until there was enough audio to fill the buffer, and that was causing samples to get recorded twice.
for avail := 0; avail < len(in); avail, _ = stream.AvailableToRead() {
time.Sleep(time.Second / sampleRate * time.Duration(len(in)-avail))
}