revid: changed writeRates and recPeriods to floats

This commit is contained in:
Trek H 2019-05-21 12:39:10 +09:30
parent 7ba9d023a3
commit c58c573cd7
6 changed files with 83 additions and 34 deletions

View File

@ -138,7 +138,7 @@ func handleFlags() revid.Config {
// Audio specific flags.
sampleRatePtr = flag.Int("SampleRate", 48000, "Sample rate of recorded audio")
channelsPtr = flag.Int("Channels", 1, "Record in Mono or Stereo (1 or 2)")
recPeriodPtr = flag.Int("recPeriod", 1, "How many seconds to record at a time")
recPeriodPtr = flag.Float64("recPeriod", 1, "How many seconds to record at a time")
bitDepthPtr = flag.Int("bitDepth", 16, "Bit Depth to record audio at.")
)
@ -209,9 +209,9 @@ func handleFlags() revid.Config {
switch *inputPtr {
case "Audio":
cfg.WriteRate = uint(*recPeriodPtr)
cfg.WriteRate = 1.0 / (*recPeriodPtr)
default:
cfg.WriteRate = *frameRatePtr
cfg.WriteRate = float64(*frameRatePtr)
}
if len(outputs) == 0 {

View File

@ -52,6 +52,8 @@ const (
stopped
)
var rates = [8]int{8000, 16000, 32000, 44100, 48000, 88200, 96000, 192000}
var log *logger.Logger
// audioDevice holds everything we need to know about the audio input stream.
@ -141,7 +143,7 @@ func (a *audioDevice) Start() {
a.mu.Unlock()
}
// Stop will stop recording audio and close
// Stop will stop recording audio and close the device
func (a *audioDevice) Stop() {
a.mu.Lock()
a.mode = stopped
@ -178,7 +180,7 @@ func (a *audioDevice) open() error {
for _, card := range cards {
devices, err := card.Devices()
if err != nil {
return err
continue
}
for _, dev := range devices {
if dev.Type != alsa.PCM || !dev.Record {
@ -214,8 +216,7 @@ func (a *audioDevice) open() error {
// so that it can be easily downsampled to the wanted rate.
// Note: if a card thinks it can record at a rate but can't actually, this can cause a failure. Eg.
// the audioinjector is supposed to record at 8000Hz and 16000Hz but it can't due to a firmware issue,
// to fix this 8000 and 16000 must be removed from this slice.
rates := [8]int{8000, 16000, 32000, 44100, 48000, 88200, 96000, 192000}
// to fix this 8000 and 16000 must be removed from the rates slice.
foundRate := false
for i := 0; i < len(rates) && !foundRate; i++ {
if rates[i] < a.SampleRate {

View File

@ -3,32 +3,80 @@ package revid
import (
"testing"
"bitbucket.org/ausocean/av/container/mts"
"bitbucket.org/ausocean/av/container/mts/meta"
"bitbucket.org/ausocean/iot/pi/netsender"
"github.com/yobert/alsa"
)
func TestAudioPipeline(t *testing.T) {
mts.Meta = meta.New()
var logger testLogger
ns, err := netsender.New(&logger, nil, nil, nil)
func TestAudioDevice(t *testing.T) {
// We want to open a device with a standard configuration.
ac := &AudioConfig{
SampleRate: 8000,
Channels: 1,
RecPeriod: 1,
BitDepth: 16,
Codec: ADPCM,
}
// Check that a device exists with the desired parameters.
cards, err := alsa.OpenCards()
if err != nil {
t.Errorf("netsender.New failed with error %v", err)
t.Skip("skipping, no audio card found")
}
var c Config
c.Logger = &logger
c.Input = File
c.InputPath = "../../test/test-data/av/input/original_8kHz_adpcm_test.pcm"
c.Outputs = []uint8{File}
c.OutputPath = "./test-temp"
rv, err := New(c, ns)
defer alsa.CloseCards(cards)
var testDev *alsa.Device
for _, card := range cards {
devices, err := card.Devices()
if err != nil {
t.Errorf("revid.New failed with error %v", err)
} else if rv == nil {
t.Errorf("revid.New did not return a new revid")
continue
}
for _, dev := range devices {
if dev.Type != alsa.PCM || !dev.Record {
continue
}
testDev = dev
break
}
}
if testDev == nil {
t.Skip("skipping, no suitable audio device found")
}
_, err = testDev.NegotiateChannels(2)
if err != nil {
t.Skip("skipping, no suitable audio device found")
}
foundRate := false
for i := 0; i < len(rates) && !foundRate; i++ {
if rates[i] < ac.SampleRate {
continue
}
if rates[i]%ac.SampleRate == 0 {
_, err = testDev.NegotiateRate(rates[i])
if err == nil {
foundRate = true
}
}
}
if !foundRate {
_, err = testDev.NegotiateRate(defaultSampleRate)
if err != nil {
t.Skip("skipping, no suitable audio device found")
}
}
_, err = testDev.NegotiateFormat(alsa.S16_LE)
if err != nil {
t.Skip("skipping, no suitable audio device found")
}
_, err = testDev.NegotiateBufferSize(8192, 16384)
if err != nil {
t.Skip("skipping, no suitable audio device found")
}
if err = testDev.Prepare(); err != nil {
t.Skip("skipping, no suitable audio device found")
}
testDev.Close()
rv.Stop()
ai := NewAudioDevice(ac)
ai.Start()
ai.Stop()
}

View File

@ -53,7 +53,7 @@ type Config struct {
IntraRefreshPeriod uint
RtpAddress string
SendRetry bool
WriteRate uint // How many times a second revid encoders will be written to.
WriteRate float64 // How many times a second revid encoders will be written to.
// Video
Height uint

View File

@ -161,8 +161,8 @@ func (r *Revid) reset(config Config) error {
r.config.Logger.SetLevel(config.LogLevel)
err = r.setupPipeline(
func(dst io.WriteCloser, fps, medType int) (io.WriteCloser, error) {
e := mts.NewEncoder(dst, float64(fps), medType)
func(dst io.WriteCloser, fps float64, medType int) (io.WriteCloser, error) {
e := mts.NewEncoder(dst, fps, medType)
return e, nil
},
func(dst io.WriteCloser, fps int) (io.WriteCloser, error) {
@ -196,7 +196,7 @@ func (r *Revid) setConfig(config Config) error {
// mtsEnc and flvEnc will be called to obtain an mts encoder and flv encoder
// respectively. multiWriter will be used to create an ioext.multiWriteCloser
// so that encoders can write to multiple senders.
func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate, mediaType int) (io.WriteCloser, error), flvEnc func(dst io.WriteCloser, rate int) (io.WriteCloser, error), multiWriter func(...io.WriteCloser) io.WriteCloser) error {
func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64, mediaType int) (io.WriteCloser, error), flvEnc func(dst io.WriteCloser, rate int) (io.WriteCloser, error), multiWriter func(...io.WriteCloser) io.WriteCloser) error {
// encoders will hold the encoders that are required for revid's current
// configuration.
var encoders []io.WriteCloser
@ -246,7 +246,7 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate, mediaType in
} else {
mediaType = mts.Video
}
e, _ := mtsEnc(mw, int(r.config.WriteRate), mediaType)
e, _ := mtsEnc(mw, r.config.WriteRate, mediaType)
encoders = append(encoders, e)
}

View File

@ -232,7 +232,7 @@ func TestResetEncoderSenderSetup(t *testing.T) {
// This logic is what we want to check.
err = rv.setupPipeline(
func(dst io.WriteCloser, rate int, mediaType int) (io.WriteCloser, error) {
func(dst io.WriteCloser, rate float64, mediaType int) (io.WriteCloser, error) {
return &tstMtsEncoder{dst: dst}, nil
},
func(dst io.WriteCloser, rate int) (io.WriteCloser, error) {