mirror of https://bitbucket.org/ausocean/av.git
exp/i2s: Write barebones i2s recording functionality (#440)
This change adds an experimental script which utilises the yobert/alsa golang package to record audio using an i2s sensor on a raspberry pi. The script saves an audio file to the local directory called audio.wav.
This commit is contained in:
parent
54d636b54e
commit
89e530644d
|
@ -0,0 +1,154 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"bitbucket.org/ausocean/av/codec/wav"
|
||||||
|
yalsa "github.com/yobert/alsa"
|
||||||
|
)
|
||||||
|
|
||||||
|
const i2sDevName =
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Set capture type.
|
||||||
|
var i string
|
||||||
|
var i2s bool
|
||||||
|
fmt.Printf("Force I2S recording? (y/n): ")
|
||||||
|
fmt.Scan(&i)
|
||||||
|
if i == "y" {
|
||||||
|
i2s = true
|
||||||
|
} else {
|
||||||
|
i2s = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set recording length.
|
||||||
|
var duration time.Duration
|
||||||
|
var err error
|
||||||
|
fmt.Printf("Recording time: ")
|
||||||
|
fmt.Scan(&i)
|
||||||
|
duration, err = time.ParseDuration(i)
|
||||||
|
if err != nil {
|
||||||
|
duration = 5 * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find devices.
|
||||||
|
cards, err := yalsa.OpenCards()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("failed to open cards:", err)
|
||||||
|
}
|
||||||
|
defer yalsa.CloseCards(cards)
|
||||||
|
|
||||||
|
var allDevices []*yalsa.Device
|
||||||
|
for _, card := range cards {
|
||||||
|
devices, err := card.Devices()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("could not get Devices:", err)
|
||||||
|
}
|
||||||
|
allDevices = append(allDevices, devices...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dev *yalsa.Device
|
||||||
|
if i2s {
|
||||||
|
// For I2S we know the name of the device, so select that card.
|
||||||
|
for _, device := range allDevices {
|
||||||
|
if device.Title == i2sDevName {
|
||||||
|
dev = device
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Otherwise, use the first recording device we find.
|
||||||
|
for _, card := range cards {
|
||||||
|
devices, err := card.Devices()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, device := range devices {
|
||||||
|
if device.Type != yalsa.PCM {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if device.Record && dev == nil {
|
||||||
|
dev = device
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dev == nil {
|
||||||
|
log.Println("No recording device found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("recording device is:", dev.Title)
|
||||||
|
|
||||||
|
// Setup device.
|
||||||
|
err = dev.Open()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("open failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer dev.Close()
|
||||||
|
|
||||||
|
channels, err := dev.NegotiateChannels(2)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("failed to negotiate channels:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("Number of channels is:", channels)
|
||||||
|
|
||||||
|
rate, err := dev.NegotiateRate(44100)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("rate negotiation failed:", rate)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("rate is:", rate)
|
||||||
|
|
||||||
|
bufferSize, err := dev.NegotiateBufferSize(8192, 16384)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("buffer size negotiation failed", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("buffer size is:", bufferSize)
|
||||||
|
|
||||||
|
err = dev.Prepare()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Prepare failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := dev.NewBufferDuration(duration)
|
||||||
|
log.Println("recording for:", duration)
|
||||||
|
err = dev.Read(buf.Data)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to read:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("Recording stopped.")
|
||||||
|
|
||||||
|
file, err := os.Create("audio.wav")
|
||||||
|
if err != nil {
|
||||||
|
log.Println("failed to create file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var audio wav.WAV
|
||||||
|
audio.Metadata = wav.Metadata{Channels: 2, AudioFormat: wav.PCMFormat, SampleRate: 44100, BitDepth: 16}
|
||||||
|
_, err = audio.Write(buf.Data)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to encode wav:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = file.Write(audio.Audio)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("failed to write audio:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Audio saved to audio.wav")
|
||||||
|
|
||||||
|
}
|
8
go.mod
8
go.mod
|
@ -7,8 +7,8 @@ require (
|
||||||
bitbucket.org/ausocean/utils v1.4.1
|
bitbucket.org/ausocean/utils v1.4.1
|
||||||
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7
|
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||||
github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480
|
github.com/go-audio/audio v1.0.0
|
||||||
github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884
|
github.com/go-audio/wav v1.1.0
|
||||||
github.com/google/go-cmp v0.4.1
|
github.com/google/go-cmp v0.4.1
|
||||||
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d
|
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d
|
||||||
github.com/mewkiz/flac v1.0.5
|
github.com/mewkiz/flac v1.0.5
|
||||||
|
@ -19,7 +19,7 @@ require (
|
||||||
golang.org/x/text v0.6.0 // indirect
|
golang.org/x/text v0.6.0 // indirect
|
||||||
gonum.org/v1/gonum v0.8.2
|
gonum.org/v1/gonum v0.8.2
|
||||||
gonum.org/v1/plot v0.9.0
|
gonum.org/v1/plot v0.9.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/fsnotify/fsnotify v1.6.0
|
require github.com/fsnotify/fsnotify v1.6.0
|
||||||
|
@ -27,11 +27,11 @@ require github.com/fsnotify/fsnotify v1.6.0
|
||||||
require (
|
require (
|
||||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af // indirect
|
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af // indirect
|
||||||
github.com/fogleman/gg v1.3.0 // indirect
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
|
github.com/go-audio/riff v1.0.0 // indirect
|
||||||
github.com/go-fonts/liberation v0.1.1 // indirect
|
github.com/go-fonts/liberation v0.1.1 // indirect
|
||||||
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07 // indirect
|
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07 // indirect
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
|
||||||
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21 // indirect
|
|
||||||
github.com/phpdave11/gofpdf v1.4.2 // indirect
|
github.com/phpdave11/gofpdf v1.4.2 // indirect
|
||||||
go.uber.org/atomic v1.3.2 // indirect
|
go.uber.org/atomic v1.3.2 // indirect
|
||||||
go.uber.org/multierr v1.1.0 // indirect
|
go.uber.org/multierr v1.1.0 // indirect
|
||||||
|
|
18
go.sum
18
go.sum
|
@ -7,7 +7,6 @@ bitbucket.org/ausocean/utils v1.4.1 h1:UTxWBy8vDFq5b77rq8vzuZmHW9Unxok3AcoxP9nuv
|
||||||
bitbucket.org/ausocean/utils v1.4.1/go.mod h1:XgvCH4DQLCd6NYMzsSqwhHmPr+qzYks5M8IDpdNnZiU=
|
bitbucket.org/ausocean/utils v1.4.1/go.mod h1:XgvCH4DQLCd6NYMzsSqwhHmPr+qzYks5M8IDpdNnZiU=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
|
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw=
|
github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw=
|
||||||
|
@ -38,12 +37,12 @@ github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/go-audio/aiff v0.0.0-20180403003018-6c3a8a6aff12/go.mod h1:AMSAp6W1zd0koOdX6QDgGIuBDTUvLa2SLQtm7d9eM3c=
|
github.com/go-audio/audio v1.0.0 h1:zS9vebldgbQqktK4H0lUqWrG8P0NxCJVqcj7ZpNnwd4=
|
||||||
github.com/go-audio/audio v0.0.0-20180206231410-b697a35b5608/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs=
|
github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs=
|
||||||
github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480 h1:4sGU+UABMMsRJyD+Y2yzMYxq0GJFUsRRESI0P1gZ2ig=
|
github.com/go-audio/riff v1.0.0 h1:d8iCGbDvox9BfLagY94fBynxSPHO80LmZCaOsmKxokA=
|
||||||
github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs=
|
github.com/go-audio/riff v1.0.0/go.mod h1:l3cQwc85y79NQFCRB7TiPoNiaijp6q8Z0Uv38rVG498=
|
||||||
github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884 h1:2TaXIaVA4ff/MHHezOj83tCypALTFAcXOImcFWNa3jw=
|
github.com/go-audio/wav v1.1.0 h1:jQgLtbqBzY7G+BM8fXF7AHUk1uHUviWS4X39d5rsL2g=
|
||||||
github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884/go.mod h1:UiqzUyfX0zs3pJ/DPyvS5v8sN6s5bXPUDDIVA5v8dks=
|
github.com/go-audio/wav v1.1.0/go.mod h1:mpe9qfwbScEbkd8uybLuIpTgHyrISw/OTuvjUW2iGtE=
|
||||||
github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
|
github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
|
||||||
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
|
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
|
||||||
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
|
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
|
||||||
|
@ -70,8 +69,6 @@ github.com/kortschak/nmea v0.0.0-20210407203620-e8c5d9a5a0ec/go.mod h1:Vq0wW4Bqk
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21 h1:Hc1iKlyxNHp3CV59G2E/qabUkHvEwOIJxDK0CJ7CRjA=
|
|
||||||
github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21/go.mod h1:LlQmBGkOuV/SKzEDXBPKauvN2UqCgzXO2XjecTGj40s=
|
|
||||||
github.com/mewkiz/flac v1.0.5 h1:dHGW/2kf+/KZ2GGqSVayNEhL9pluKn/rr/h/QqD9Ogc=
|
github.com/mewkiz/flac v1.0.5 h1:dHGW/2kf+/KZ2GGqSVayNEhL9pluKn/rr/h/QqD9Ogc=
|
||||||
github.com/mewkiz/flac v1.0.5/go.mod h1:EHZNU32dMF6alpurYyKHDLYpW1lYpBZ5WrXi/VuNIGs=
|
github.com/mewkiz/flac v1.0.5/go.mod h1:EHZNU32dMF6alpurYyKHDLYpW1lYpBZ5WrXi/VuNIGs=
|
||||||
github.com/mjibson/go-dsp v0.0.0-20180508042940-11479a337f12 h1:dd7vnTDfjtwCETZDrRe+GPYNLA1jBtbZeyfyE8eZCyk=
|
github.com/mjibson/go-dsp v0.0.0-20180508042940-11479a337f12 h1:dd7vnTDfjtwCETZDrRe+GPYNLA1jBtbZeyfyE8eZCyk=
|
||||||
|
@ -168,8 +165,9 @@ gonum.org/v1/plot v0.9.0 h1:3sEo36Uopv1/SA/dMFFaxXoL5XyikJ9Sf2Vll/k6+2E=
|
||||||
gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
|
gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|
Loading…
Reference in New Issue