mirror of https://bitbucket.org/ausocean/av.git
Merged in alsa-device (pull request #278)
audio package name changed to alsa Approved-by: Alan Noble <anoble@gmail.com>
This commit is contained in:
commit
0412d6b141
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
NAME
|
||||
audio.go
|
||||
alsa.go
|
||||
|
||||
AUTHOR
|
||||
Alan Noble <alan@ausocean.org>
|
||||
|
@ -23,8 +23,8 @@ LICENSE
|
|||
If not, see [GNU licenses](http://www.gnu.org/licenses).
|
||||
*/
|
||||
|
||||
// Package audio provides access to input from audio devices.
|
||||
package audio
|
||||
// Package alsa provides access to input from ALSA audio devices.
|
||||
package alsa
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -33,7 +33,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/yobert/alsa"
|
||||
yalsa "github.com/yobert/alsa"
|
||||
|
||||
"bitbucket.org/ausocean/av/codec/adpcm"
|
||||
"bitbucket.org/ausocean/av/codec/codecutil"
|
||||
|
@ -45,7 +45,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
pkg = "audio: "
|
||||
pkg = "alsa: "
|
||||
rbTimeout = 100 * time.Millisecond
|
||||
rbNextTimeout = 100 * time.Millisecond
|
||||
rbLen = 200
|
||||
|
@ -63,15 +63,15 @@ const (
|
|||
|
||||
// An ALSA device holds everything we need to know about the audio input stream and implements io.Reader and device.AVDevice.
|
||||
type ALSA struct {
|
||||
l Logger // Logger for device's routines to log to.
|
||||
mode uint8 // Operating mode, either running, paused, or stopped.
|
||||
mu sync.Mutex // Provides synchronisation when changing modes concurrently.
|
||||
title string // Name of audio title, or empty for the default title.
|
||||
dev *alsa.Device // ALSA device's Audio input device.
|
||||
ab alsa.Buffer // ALSA device's buffer.
|
||||
rb *ring.Buffer // Our buffer.
|
||||
chunkSize int // This is the number of bytes that will be stored in rb at a time.
|
||||
Config // Configuration parameters for this device.
|
||||
l Logger // Logger for device's routines to log to.
|
||||
mode uint8 // Operating mode, either running, paused, or stopped.
|
||||
mu sync.Mutex // Provides synchronisation when changing modes concurrently.
|
||||
title string // Name of audio title, or empty for the default title.
|
||||
dev *yalsa.Device // ALSA device's Audio input device.
|
||||
ab yalsa.Buffer // ALSA device's buffer.
|
||||
rb *ring.Buffer // Our buffer.
|
||||
chunkSize int // This is the number of bytes that will be stored in rb at a time.
|
||||
Config // Configuration parameters for this device.
|
||||
}
|
||||
|
||||
// Config provides parameters used by the ALSA device.
|
||||
|
@ -228,11 +228,11 @@ func (d *ALSA) open() error {
|
|||
|
||||
// Open sound card and open recording device.
|
||||
d.l.Log(logger.Debug, pkg+"opening sound card")
|
||||
cards, err := alsa.OpenCards()
|
||||
cards, err := yalsa.OpenCards()
|
||||
if err != nil {
|
||||
return OpenError(err)
|
||||
}
|
||||
defer alsa.CloseCards(cards)
|
||||
defer yalsa.CloseCards(cards)
|
||||
|
||||
d.l.Log(logger.Debug, pkg+"finding audio device")
|
||||
for _, card := range cards {
|
||||
|
@ -241,7 +241,7 @@ func (d *ALSA) open() error {
|
|||
continue
|
||||
}
|
||||
for _, dev := range devices {
|
||||
if dev.Type != alsa.PCM || !dev.Record {
|
||||
if dev.Type != yalsa.PCM || !dev.Record {
|
||||
continue
|
||||
}
|
||||
if dev.Title == d.title || d.title == "" {
|
||||
|
@ -251,10 +251,10 @@ func (d *ALSA) open() error {
|
|||
}
|
||||
}
|
||||
if d.dev == nil {
|
||||
return OpenError(errors.New("no audio device found"))
|
||||
return OpenError(errors.New("no ALSA device found"))
|
||||
}
|
||||
|
||||
d.l.Log(logger.Debug, pkg+"opening audio device", "title", d.dev.Title)
|
||||
d.l.Log(logger.Debug, pkg+"opening ALSA device", "title", d.dev.Title)
|
||||
err = d.dev.Open()
|
||||
if err != nil {
|
||||
return OpenError(err)
|
||||
|
@ -302,12 +302,12 @@ func (d *ALSA) open() error {
|
|||
d.l.Log(logger.Debug, pkg+"alsa device sample rate set", "rate", rate)
|
||||
}
|
||||
|
||||
var aFmt alsa.FormatType
|
||||
var aFmt yalsa.FormatType
|
||||
switch d.BitDepth {
|
||||
case 16:
|
||||
aFmt = alsa.S16_LE
|
||||
aFmt = yalsa.S16_LE
|
||||
case 32:
|
||||
aFmt = alsa.S32_LE
|
||||
aFmt = yalsa.S32_LE
|
||||
default:
|
||||
return OpenError(fmt.Errorf("unsupported sample bits %v", d.BitDepth))
|
||||
}
|
||||
|
@ -317,9 +317,9 @@ func (d *ALSA) open() error {
|
|||
}
|
||||
var bitdepth int
|
||||
switch devFmt {
|
||||
case alsa.S16_LE:
|
||||
case yalsa.S16_LE:
|
||||
bitdepth = 16
|
||||
case alsa.S32_LE:
|
||||
case yalsa.S32_LE:
|
||||
bitdepth = 32
|
||||
default:
|
||||
return OpenError(fmt.Errorf("unsupported sample bits %v", d.BitDepth))
|
||||
|
@ -363,7 +363,7 @@ func (d *ALSA) input() {
|
|||
continue
|
||||
case stopped:
|
||||
if d.dev != nil {
|
||||
d.l.Log(logger.Debug, pkg+"closing audio device", "title", d.title)
|
||||
d.l.Log(logger.Debug, pkg+"closing ALSA device", "title", d.title)
|
||||
d.dev.Close()
|
||||
d.dev = nil
|
||||
}
|
||||
|
@ -414,14 +414,14 @@ func (d *ALSA) Read(p []byte) (int, error) {
|
|||
}
|
||||
|
||||
// formatBuffer returns audio that has been converted to the desired format.
|
||||
func (d *ALSA) formatBuffer() alsa.Buffer {
|
||||
func (d *ALSA) formatBuffer() yalsa.Buffer {
|
||||
var err error
|
||||
|
||||
// If nothing needs to be changed, return the original.
|
||||
if d.ab.Format.Channels == d.Channels && d.ab.Format.Rate == d.SampleRate {
|
||||
return d.ab
|
||||
}
|
||||
var formatted alsa.Buffer
|
||||
var formatted yalsa.Buffer
|
||||
if d.ab.Format.Channels != d.Channels {
|
||||
// Convert channels.
|
||||
// TODO(Trek): Make this work for conversions other than stereo to mono.
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
NAME
|
||||
audio_test.go
|
||||
alsa_test.go
|
||||
|
||||
AUTHOR
|
||||
Trek Hopton <trek@ausocean.org>
|
||||
|
@ -22,7 +22,7 @@ LICENSE
|
|||
If not, see [GNU licenses](http://www.gnu.org/licenses).
|
||||
*/
|
||||
|
||||
package audio
|
||||
package alsa
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
|
@ -21,28 +21,28 @@ package revid
|
|||
import (
|
||||
"time"
|
||||
|
||||
"bitbucket.org/ausocean/av/device/audio"
|
||||
"bitbucket.org/ausocean/av/device/alsa"
|
||||
"bitbucket.org/ausocean/utils/logger"
|
||||
)
|
||||
|
||||
// startAudioDevice is used to start capturing audio from an audio device and processing it.
|
||||
// startAudioDevice is used to start capturing audio from an ALSA audio device and processing it.
|
||||
// It returns a function that can be used to stop the device and any errors that occur.
|
||||
func (r *Revid) startAudioDevice() (func() error, error) {
|
||||
// Create audio device.
|
||||
ai := audio.NewALSA(r.cfg.Logger)
|
||||
ai := alsa.NewALSA(r.cfg.Logger)
|
||||
|
||||
err := ai.Set(r.cfg)
|
||||
if err != nil {
|
||||
r.cfg.Logger.Log(logger.Fatal, pkg+"failed to setup audio device", "error", err.Error())
|
||||
r.cfg.Logger.Log(logger.Fatal, pkg+"failed to setup ALSA device", "error", err.Error())
|
||||
}
|
||||
|
||||
// Start audio device
|
||||
// Start ALSA audio device
|
||||
err = ai.Start()
|
||||
if err != nil {
|
||||
r.cfg.Logger.Log(logger.Fatal, pkg+"failed to start audio device", "error", err.Error())
|
||||
r.cfg.Logger.Log(logger.Fatal, pkg+"failed to start ALSA device", "error", err.Error())
|
||||
}
|
||||
|
||||
// Process output from audio device.
|
||||
// Process output from ALSA audio device.
|
||||
r.cfg.ChunkSize = ai.ChunkSize()
|
||||
r.wg.Add(1)
|
||||
go r.processFrom(ai, time.Duration(float64(time.Second)/r.cfg.WriteRate))
|
||||
|
|
Loading…
Reference in New Issue