diff --git a/device/alsa/alsa.go b/device/alsa/alsa.go index 372d934d..0ebfa931 100644 --- a/device/alsa/alsa.go +++ b/device/alsa/alsa.go @@ -116,11 +116,11 @@ func (d *ALSA) Name() string { return "ALSA" } -// Set will take a Config struct, check the validity of the relevant fields -// and then performs any configuration necessary. If fields are not valid, +// Setup will take a Config struct, check the validity of the relevant fields +// and then perform any configuration necessary. If fields are not valid, // an error is added to the multiError and a default value is used. // It then initialises the ALSA device which can then be started, read from, and stopped. -func (d *ALSA) Set(c config.Config) error { +func (d *ALSA) Setup(c config.Config) error { var errs device.MultiError if c.SampleRate <= 0 { errs = append(errs, errInvalidSampleRate) @@ -185,6 +185,14 @@ func (d *ALSA) Set(c config.Config) error { return nil } +// Set exists to satisfy the implementation of the Device interface that revid uses. +// Everything that would usually be in Set is in the Setup function. +// This is because an ALSA device is different to other devices in that it +// outputs binary non-packetised data and it requires a different configuration procedure. +func (d *ALSA) Set(c config.Config) error { + return nil +} + // Start will start recording audio and writing to the ringbuffer. // Once an ALSA device has been stopped it cannot be started again. This is likely to change in future. func (d *ALSA) Start() error { @@ -458,6 +466,12 @@ func (d *ALSA) formatBuffer() pcm.Buffer { return formatted } +// DataSize returns the size in bytes of the data ALSA device d will +// output in the duration of a single recording period. +func (d *ALSA) DataSize() int { + return pcm.DataSize(d.SampleRate, d.Channels, d.BitDepth, d.RecPeriod, d.Codec) +} + // nearestPowerOfTwo finds and returns the nearest power of two to the given integer. // If the lower and higher power of two are the same distance, it returns the higher power. // For negative values, 1 is returned. diff --git a/device/alsa/alsa_test.go b/device/alsa/alsa_test.go index aeeb6ac9..918a022a 100644 --- a/device/alsa/alsa_test.go +++ b/device/alsa/alsa_test.go @@ -53,7 +53,7 @@ func TestDevice(t *testing.T) { // Create a new ALSA device, start, read/lex, and then stop it. l := logger.New(logger.Debug, os.Stderr, true) ai := New(l) - err := ai.Set(c) + err := ai.Setup(c) // If there was an error opening the device, skip this test. if _, ok := err.(OpenError); ok { t.Skip(err) @@ -119,7 +119,7 @@ func TestIsRunning(t *testing.T) { l := logger.New(logger.Debug, &bytes.Buffer{}, true) // Discard logs. d := New(l) - err := d.Set(config.Config{ + err := d.Setup(config.Config{ SampleRate: sampleRate, Channels: channels, BitDepth: bitDepth, diff --git a/revid/audio_linux.go b/revid/audio_linux.go index d7c78b28..d3d08a58 100644 --- a/revid/audio_linux.go +++ b/revid/audio_linux.go @@ -29,13 +29,32 @@ import ( "strconv" "bitbucket.org/ausocean/av/codec/codecutil" - "bitbucket.org/ausocean/av/codec/pcm" "bitbucket.org/ausocean/av/container/mts" "bitbucket.org/ausocean/av/device/alsa" "bitbucket.org/ausocean/utils/logger" ) func (r *Revid) setupAudio() error { + // Create new ALSA device. + d := alsa.New(r.cfg.Logger) + r.input = d + + // Configure ALSA device. + r.cfg.Logger.Log(logger.Debug, "configuring input device") + err := d.Setup(r.cfg) + if err != nil { + r.cfg.Logger.Log(logger.Warning, "errors from configuring input device", "errors", err) + } + r.cfg.Logger.Log(logger.Info, "input device configured") + + // Set revid's lexer. + l, err := codecutil.NewByteLexer(d.DataSize()) + if err != nil { + return err + } + r.lexTo = l.Lex + + // Add metadata. mts.Meta.Add("sampleRate", strconv.Itoa(int(r.cfg.SampleRate))) mts.Meta.Add("channels", strconv.Itoa(int(r.cfg.Channels))) mts.Meta.Add("period", fmt.Sprintf("%.6f", r.cfg.RecPeriod)) @@ -50,13 +69,5 @@ func (r *Revid) setupAudio() error { r.cfg.Logger.Log(logger.Fatal, "no audio codec set in config") } - r.input = alsa.New(r.cfg.Logger) - - l, err := codecutil.NewByteLexer(pcm.DataSize(r.cfg.SampleRate, r.cfg.Channels, r.cfg.BitDepth, r.cfg.RecPeriod, r.cfg.InputCodec)) - if err != nil { - return err - } - r.lexTo = l.Lex - return nil }