1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
// capture some audio from the default device, and play it back.
//
// to run this example, simply `go run examples/echo.go`.
package main
import (
".." // pulse-simple
"encoding/binary"
"fmt"
"math"
)
func main() {
// define the sample spec we want,
// in this case single-channel 44100Hz little-endian 32-bit float.
ss := pulse.SampleSpec{pulse.SAMPLE_FLOAT32LE, 44100, 1}
// create the capture device and audio storage buffers
capture, err := pulse.Capture("pulse-simple test", "capture test", &ss)
defer capture.Free()
if err != nil {
fmt.Printf("Could not create capture stream: %s\n", err)
return
}
storage := make([]byte, 44100*4)
// 1/25 second buffer for volume meter and stop button responsiveness
buffer := make([]byte, 44100*4/25)
fmt.Println("Recording... (press ENTER to finish capture)")
// wait in the background for the user to press enter
stop := make(chan bool)
go func() {
var input string
fmt.Scanln(&input)
stop <- true
}()
// until the user presses enter, continue to capture audio
Capture:
for {
select {
case <-stop:
break Capture
default:
_, err := capture.Read(buffer)
if err != nil {
fmt.Printf("Aborting due to audio capture error: %s\n", err)
break Capture
}
storage = append(storage, buffer...)
// also display a crude volume-meter
display_volume(buffer)
}
}
fmt.Print("\r") // overwrite the enter from input
// create playback stream and play back the captured audio
playback, err := pulse.Playback("pulse-simple test", "playback test", &ss)
defer playback.Free()
defer playback.Drain()
if err != nil {
fmt.Printf("Could not create playback stream: %s\n", err)
return
}
fmt.Println("Playing back recorded audio...")
playback.Write(storage)
}
func display_volume(buffer []byte) {
numsamples := len(buffer) / 4
sumsquares := float64(0)
for i := 0; i < numsamples; i++ {
bits := binary.LittleEndian.Uint32(buffer[4*i : 4*i+4])
value := math.Float32frombits(bits)
sumsquares += float64(value * value)
}
// root mean square of the signal should give an approximation of volume
volume := math.Sqrt(sumsquares / float64(numsamples))
// print between 0 and 40 '#' characters as a volume meter
maxvolume := 0.5
fmt.Print("\r")
for i := 0.0; i < maxvolume; i += maxvolume / 40 {
if i < volume {
fmt.Print("#")
} else {
fmt.Print(" ")
}
}
}
|