alsa, revid: added correct device configuration and defaulting for audio

This commit is contained in:
Trek H 2020-08-11 11:43:17 +09:30
parent 7fb61edb0d
commit 5fe586913f
3 changed files with 68 additions and 34 deletions

View File

@ -45,11 +45,10 @@ import (
) )
const ( const (
pkg = "alsa: " pkg = "alsa: "
rbTimeout = 100 * time.Millisecond rbTimeout = 100 * time.Millisecond
rbNextTimeout = 2000 * time.Millisecond rbNextTimeout = 2000 * time.Millisecond
rbLen = 200 rbLen = 200
defaultSampleRate = 48000
) )
// "running" means the input goroutine is reading from the ALSA device and writing to the ringbuffer. // "running" means the input goroutine is reading from the ALSA device and writing to the ringbuffer.
@ -61,6 +60,23 @@ const (
stopped stopped
) )
const (
defaultSampleRate = 48000
defaultBitDepth = 16
defaultChannels = 1
defaultRecPeriod = 1.0
defaultCodec = codecutil.PCM
)
// Configuration field errors.
var (
errInvalidSampleRate = errors.New("invalid sample rate, defaulting")
errInvalidChannels = errors.New("invalid number of channels, defaulting")
errInvalidBitDepth = errors.New("invalid bitdepth, defaulting")
errInvalidRecPeriod = errors.New("invalid record period, defaulting")
errInvalidCodec = errors.New("invalid audio codec, defaulting")
)
// An ALSA device holds everything we need to know about the audio input stream and implements io.Reader and device.AVDevice. // An ALSA device holds everything we need to know about the audio input stream and implements io.Reader and device.AVDevice.
type ALSA struct { type ALSA struct {
l Logger // Logger for device's routines to log to. l Logger // Logger for device's routines to log to.
@ -107,19 +123,24 @@ func (d *ALSA) Name() string {
func (d *ALSA) Set(c config.Config) error { func (d *ALSA) Set(c config.Config) error {
var errs device.MultiError var errs device.MultiError
if c.SampleRate <= 0 { if c.SampleRate <= 0 {
errs = append(errs, fmt.Errorf("invalid sample rate: %v", c.SampleRate)) errs = append(errs, errInvalidSampleRate)
c.SampleRate = defaultSampleRate
} }
if c.Channels <= 0 { if c.Channels <= 0 {
errs = append(errs, fmt.Errorf("invalid number of channels: %v", c.Channels)) errs = append(errs, errInvalidChannels)
c.Channels = defaultChannels
} }
if c.BitDepth <= 0 { if c.BitDepth <= 0 {
errs = append(errs, fmt.Errorf("invalid bitdepth: %v", c.BitDepth)) errs = append(errs, errInvalidBitDepth)
c.BitDepth = defaultBitDepth
} }
if c.RecPeriod <= 0 { if c.RecPeriod <= 0 {
errs = append(errs, fmt.Errorf("invalid recording period: %v", c.RecPeriod)) errs = append(errs, errInvalidRecPeriod)
c.RecPeriod = defaultRecPeriod
} }
if !codecutil.IsValid(c.InputCodec) { if c.InputCodec != codecutil.ADPCM && c.InputCodec != codecutil.PCM {
errs = append(errs, errors.New("invalid codec")) errs = append(errs, errInvalidCodec)
c.InputCodec = defaultCodec
} }
d.Config = Config{ d.Config = Config{
SampleRate: c.SampleRate, SampleRate: c.SampleRate,

View File

@ -50,7 +50,6 @@ const (
InputAudio InputAudio
// Outputs. // Outputs.
OutputAudio
OutputRTMP OutputRTMP
OutputRTP OutputRTP
OutputHTTP OutputHTTP

View File

@ -40,20 +40,19 @@ import (
// Default variable values. // Default variable values.
const ( const (
// General revid defaults. // General revid defaults.
defaultInput = InputRaspivid defaultInput = InputRaspivid
defaultOutput = OutputHTTP defaultOutput = OutputHTTP
defaultInputCodec = codecutil.H264 defaultInputCodec = codecutil.H264
defaultVerbosity = logger.Error defaultVerbosity = logger.Error
defaultRTPAddr = "localhost:6970" defaultRTPAddr = "localhost:6970"
defaultCameraIP = "192.168.1.50" defaultCameraIP = "192.168.1.50"
defaultBurstPeriod = 10 // Seconds defaultBurstPeriod = 10 // Seconds
defaultMinFrames = 100 defaultMinFrames = 100
defaultFrameRate = 25 defaultFrameRate = 25
defaultWriteRate = 25 defaultWriteRate = 25
defaultClipDuration = 0 defaultClipDuration = 0
defaultAudioInputCodec = codecutil.ADPCM defaultPSITime = 2
defaultPSITime = 2 defaultFileFPS = 0
defaultFileFPS = 0
// Ring buffer defaults. // Ring buffer defaults.
defaultRBCapacity = 50000000 // => 50MB defaultRBCapacity = 50000000 // => 50MB
@ -138,6 +137,11 @@ var Variables = []struct {
} }
}, },
}, },
{
Name: "Channels",
Type_: "uint",
Update: func(c *Config, v string) { c.Channels = parseUint("Channels", v, c) },
},
{ {
Name: "Exposure", Name: "Exposure",
Type_: "enum:auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks", Type_: "enum:auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks",
@ -243,14 +247,8 @@ var Variables = []struct {
switch c.InputCodec { switch c.InputCodec {
case codecutil.H264, codecutil.MJPEG, codecutil.PCM, codecutil.ADPCM: case codecutil.H264, codecutil.MJPEG, codecutil.PCM, codecutil.ADPCM:
default: default:
switch c.Input { c.LogInvalidField("InputCodec", defaultInputCodec)
case OutputAudio: c.InputCodec = defaultInputCodec
c.LogInvalidField("InputCodec", defaultAudioInputCodec)
c.InputCodec = defaultAudioInputCodec
default:
c.LogInvalidField("InputCodec", defaultInputCodec)
c.InputCodec = defaultInputCodec
}
} }
}, },
}, },
@ -449,6 +447,17 @@ var Variables = []struct {
c.RBWriteTimeout = lessThanOrEqual("RBWriteTimeout", c.RBWriteTimeout, 0, c, defaultRBWriteTimeout) c.RBWriteTimeout = lessThanOrEqual("RBWriteTimeout", c.RBWriteTimeout, 0, c, defaultRBWriteTimeout)
}, },
}, },
{
Name: "RecPeriod",
Type_: "float",
Update: func(c *Config, v string) {
_v, err := strconv.ParseFloat(v, 64)
if err != nil {
c.Logger.Log(logger.Warning, fmt.Sprintf("invalid %s param", "RecPeriod"), "value", v)
}
return _v
},
},
{ {
Name: "Rotation", Name: "Rotation",
Type_: "uint", Type_: "uint",
@ -470,6 +479,11 @@ var Variables = []struct {
} }
}, },
}, },
{
Name: "SampleRate",
Type_: "uint",
Update: func(c *Config, v string) { c.SampleRate = parseUint("SampleRate", v, c) },
},
{ {
Name: "Saturation", Name: "Saturation",
Type_: "int", Type_: "int",