mirror of https://bitbucket.org/ausocean/av.git
pcm, audio: style changes
This commit is contained in:
parent
01561e363d
commit
fb12a2f69e
|
@ -41,15 +41,14 @@ import (
|
|||
// - If the number of bytes in b.Data is not divisible by the decimation factor (ratioFrom), the remaining bytes will
|
||||
// not be included in the result. Eg. input of length 480002 downsampling 6:1 will result in output length 80000.
|
||||
func Resample(b alsa.Buffer, rate int) (alsa.Buffer, error) {
|
||||
var newBuf alsa.Buffer
|
||||
if b.Format.Rate == rate {
|
||||
return newBuf, nil
|
||||
return b, nil
|
||||
}
|
||||
if b.Format.Rate < 0 {
|
||||
return newBuf, fmt.Errorf("Unable to convert from: %v Hz", b.Format.Rate)
|
||||
return alsa.Buffer{}, fmt.Errorf("Unable to convert from: %v Hz", b.Format.Rate)
|
||||
}
|
||||
if rate < 0 {
|
||||
return newBuf, fmt.Errorf("Unable to convert to: %v Hz", rate)
|
||||
return alsa.Buffer{}, fmt.Errorf("Unable to convert to: %v Hz", rate)
|
||||
}
|
||||
|
||||
// The number of bytes in a sample.
|
||||
|
@ -60,7 +59,7 @@ func Resample(b alsa.Buffer, rate int) (alsa.Buffer, error) {
|
|||
case alsa.S16_LE:
|
||||
sampleLen = 2 * b.Format.Channels
|
||||
default:
|
||||
return newBuf, fmt.Errorf("Unhandled ALSA format: %v", b.Format.SampleFormat)
|
||||
return alsa.Buffer{}, fmt.Errorf("Unhandled ALSA format: %v", b.Format.SampleFormat)
|
||||
}
|
||||
inPcmLen := len(b.Data)
|
||||
|
||||
|
@ -71,7 +70,7 @@ func Resample(b alsa.Buffer, rate int) (alsa.Buffer, error) {
|
|||
|
||||
// ratioTo = 1 is the only number that will result in an even sampling.
|
||||
if ratioTo != 1 {
|
||||
return newBuf, fmt.Errorf("unhandled from:to rate ratio %v:%v: 'to' must be 1", ratioFrom, ratioTo)
|
||||
return alsa.Buffer{}, fmt.Errorf("unhandled from:to rate ratio %v:%v: 'to' must be 1", ratioFrom, ratioTo)
|
||||
}
|
||||
|
||||
newLen := inPcmLen / ratioFrom
|
||||
|
@ -100,28 +99,25 @@ func Resample(b alsa.Buffer, rate int) (alsa.Buffer, error) {
|
|||
resampled = append(resampled, bAvg...)
|
||||
}
|
||||
|
||||
// Create new alsa.Buffer with resampled data.
|
||||
newBuf = alsa.Buffer{
|
||||
// Return a new alsa.Buffer with resampled data.
|
||||
return alsa.Buffer{
|
||||
Format: alsa.BufferFormat{
|
||||
Channels: b.Format.Channels,
|
||||
SampleFormat: b.Format.SampleFormat,
|
||||
Rate: rate,
|
||||
},
|
||||
Data: resampled,
|
||||
}
|
||||
|
||||
return newBuf, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// StereoToMono returns raw mono audio data generated from only the left channel from
|
||||
// the given stereo recording (ALSA buffer)
|
||||
func StereoToMono(b alsa.Buffer) (alsa.Buffer, error) {
|
||||
var newBuf alsa.Buffer
|
||||
if b.Format.Channels == 1 {
|
||||
return b, nil
|
||||
}
|
||||
if b.Format.Channels != 2 {
|
||||
return newBuf, fmt.Errorf("Audio is not stereo or mono, it has %v channels", b.Format.Channels)
|
||||
return alsa.Buffer{}, fmt.Errorf("Audio is not stereo or mono, it has %v channels", b.Format.Channels)
|
||||
}
|
||||
|
||||
var stereoSampleBytes int
|
||||
|
@ -131,7 +127,7 @@ func StereoToMono(b alsa.Buffer) (alsa.Buffer, error) {
|
|||
case alsa.S16_LE:
|
||||
stereoSampleBytes = 4
|
||||
default:
|
||||
return newBuf, fmt.Errorf("Unhandled ALSA format %v", b.Format.SampleFormat)
|
||||
return alsa.Buffer{}, fmt.Errorf("Unhandled ALSA format %v", b.Format.SampleFormat)
|
||||
}
|
||||
|
||||
recLength := len(b.Data)
|
||||
|
@ -147,17 +143,15 @@ func StereoToMono(b alsa.Buffer) (alsa.Buffer, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Create new alsa.Buffer with resampled data.
|
||||
newBuf = alsa.Buffer{
|
||||
// Return a new alsa.Buffer with resampled data.
|
||||
return alsa.Buffer{
|
||||
Format: alsa.BufferFormat{
|
||||
Channels: 1,
|
||||
SampleFormat: b.Format.SampleFormat,
|
||||
Rate: b.Format.Rate,
|
||||
},
|
||||
Data: mono,
|
||||
}
|
||||
|
||||
return newBuf, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// gcd is used for calculating the greatest common divisor of two positive integers, a and b.
|
||||
|
|
|
@ -43,13 +43,16 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
pkg = "pkg: "
|
||||
pkg = "audio: "
|
||||
rbTimeout = 100 * time.Millisecond
|
||||
rbNextTimeout = 100 * time.Millisecond
|
||||
rbLen = 200
|
||||
defaultSampleRate = 48000
|
||||
)
|
||||
|
||||
// "running" means the input goroutine is reading from the ALSA device and writing to the ringbuffer.
|
||||
// "paused" means the input routine is sleeping until unpaused or stopped.
|
||||
// "stopped" means the input routine is stopped and the ALSA device is closed.
|
||||
const (
|
||||
running = iota
|
||||
paused
|
||||
|
@ -59,24 +62,17 @@ const (
|
|||
// Rates contains the standard audio sample rates used by package audio.
|
||||
var Rates = [8]int{8000, 16000, 32000, 44100, 48000, 88200, 96000, 192000}
|
||||
|
||||
// Device holds everything we need to know about the audio input stream.
|
||||
// Device holds everything we need to know about the audio input stream and implements io.Reader.
|
||||
type Device struct {
|
||||
l Logger
|
||||
|
||||
// Operating mode, either running, paused, or stopped.
|
||||
// "running" means the input goroutine is reading from the ALSA device and writing to the ringbuffer.
|
||||
// "paused" means the input routine is sleeping until unpaused or stopped.
|
||||
// "stopped" means the input routine is stopped and the ALSA device is closed.
|
||||
mode uint8
|
||||
|
||||
mu sync.Mutex
|
||||
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 // Audio input device.
|
||||
dev *alsa.Device // ALSA's Audio input device.
|
||||
ab alsa.Buffer // ALSA's buffer.
|
||||
rb *ring.Buffer // Our buffer.
|
||||
chunkSize int // This is the number of bytes that will be stored at a time.
|
||||
|
||||
*Config
|
||||
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 Device.
|
||||
|
@ -155,7 +151,7 @@ func (d *Device) Start() error {
|
|||
case running:
|
||||
return nil
|
||||
default:
|
||||
return errors.New("invalid mode")
|
||||
return fmt.Errorf("invalid mode: %d", mode)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +181,6 @@ func (d *Device) open() error {
|
|||
d.l.Log(logger.Debug, pkg+"opening sound card")
|
||||
cards, err := alsa.OpenCards()
|
||||
if err != nil {
|
||||
d.l.Log(logger.Debug, pkg+"failed to open sound card")
|
||||
return err
|
||||
}
|
||||
defer alsa.CloseCards(cards)
|
||||
|
@ -207,14 +202,12 @@ func (d *Device) open() error {
|
|||
}
|
||||
}
|
||||
if d.dev == nil {
|
||||
d.l.Log(logger.Debug, pkg+"failed to find audio device")
|
||||
return errors.New("no audio device found")
|
||||
}
|
||||
|
||||
d.l.Log(logger.Debug, pkg+"opening audio device", "title", d.dev.Title)
|
||||
err = d.dev.Open()
|
||||
if err != nil {
|
||||
d.l.Log(logger.Debug, pkg+"failed to open audio device")
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue