Golang : Record voice(audio) from microphone to .WAV file
Problem:
You need to activate your microphone, record your voice and save the data into a .wav
file from command line. How to do that?
Solution:
The code example below is combination of PortAudio (https://github.com/gordonklaus/portaudio/blob/master/examples/record.go) and Golang wave file reader/writer (https://github.com/zenwerk/go-wave/blob/master/example/writing.go).
What it does is to activate your default microphone and start recording. Encode the data([]byte) to the wave.Write() function and save to a given .wav
file.
Here you go!
record2wave.go
package main
/*
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
char getch(){
char ch = 0;
struct termios old = {0};
fflush(stdout);
if( tcgetattr(0, &old) < 0 ) perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if( tcsetattr(0, TCSANOW, &old) < 0 ) perror("tcsetattr ICANON");
if( read(0, &ch,1) < 0 ) perror("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if(tcsetattr(0, TCSADRAIN, &old) < 0) perror("tcsetattr ~ICANON");
return ch;
}
*/
import "C"
// stackoverflow.com/questions/14094190/golang-function-similar-to-getchar
import (
"fmt"
"github.com/gordonklaus/portaudio"
wave "github.com/zenwerk/go-wave"
"math/rand"
"os"
"strings"
"time"
)
func errCheck(err error) {
if err != nil {
panic(err)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Printf("Usage : %s <audiofilename.wav>\n", os.Args[0])
os.Exit(0)
}
audioFileName := os.Args[1]
fmt.Println("Recording. Press ESC to quit.")
if !strings.HasSuffix(audioFileName, ".wav") {
audioFileName += ".wav"
}
waveFile, err := os.Create(audioFileName)
errCheck(err)
// www.people.csail.mit.edu/hubert/pyaudio/ - under the Record tab
inputChannels := 1
outputChannels := 0
sampleRate := 44100
framesPerBuffer := make([]byte, 64)
// init PortAudio
portaudio.Initialize()
//defer portaudio.Terminate()
stream, err := portaudio.OpenDefaultStream(inputChannels, outputChannels, float64(sampleRate), len(framesPerBuffer), framesPerBuffer)
errCheck(err)
//defer stream.Close()
// setup Wave file writer
param := wave.WriterParam{
Out: waveFile,
Channel: inputChannels,
SampleRate: sampleRate,
BitsPerSample: 8, // if 16, change to WriteSample16()
}
waveWriter, err := wave.NewWriter(param)
errCheck(err)
//defer waveWriter.Close()
go func() {
key := C.getch()
fmt.Println()
fmt.Println("Cleaning up ...")
if key == 27 {
// better to control
// how we close then relying on defer
waveWriter.Close()
stream.Close()
portaudio.Terminate()
fmt.Println("Play", audioFileName, "with a audio player to hear the result.")
os.Exit(0)
}
}()
// recording in progress ticker. From good old DOS days.
ticker := []string{
"-",
"\\",
"/",
"|",
}
rand.Seed(time.Now().UnixNano())
// start reading from microphone
errCheck(stream.Start())
for {
errCheck(stream.Read())
fmt.Printf("\rRecording is live now. Say something to your microphone! [%v]", ticker[rand.Intn(len(ticker)-1)])
// write to wave file
_, err := waveWriter.Write([]byte(framesPerBuffer)) // WriteSample16 for 16 bits
errCheck(err)
}
errCheck(stream.Stop())
}
References:
See also : Golang : Save webcamera frames to video file
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+22.3k Golang : Print leading(padding) zero or spaces in fmt.Printf?
+12.8k Golang : Remove or trim extra comma from CSV
+13.5k Golang : Get constant name from value
+29.5k Golang : Login(Authenticate) with Facebook example
+8.4k Golang : Configure Apache and NGINX to access your Go service example
+6.2k Linux/Unix : Commands that you need to be careful about
+10.6k RPM : error: db3 error(-30974) from dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
+12.9k Swift : Convert (cast) Int or int32 value to CGFloat
+4.8k PHP : Extract part of a string starting from the middle
+5.4k Golang : Pad file extension automagically
+6k Golang : Use NLP to get sentences for each paragraph example
+27.8k PHP : Convert(cast) string to bigInt