From 796a3b9a9772d1db336ba67adfe7c91aa018c6a7 Mon Sep 17 00:00:00 2001 From: Trek H Date: Wed, 13 Nov 2019 16:54:41 +1030 Subject: [PATCH] pcm: changed term clip to buffer --- cmd/audio-netsender/main.go | 42 +++++++++++----------- codec/pcm/pcm.go | 44 ++++++++++++------------ codec/pcm/pcm_test.go | 12 +++---- device/alsa/alsa.go | 26 +++++++------- exp/pcm/resample/resample.go | 6 ++-- exp/pcm/stereo-to-mono/stereo-to-mono.go | 6 ++-- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/cmd/audio-netsender/main.go b/cmd/audio-netsender/main.go index 4987cc71..142c4441 100644 --- a/cmd/audio-netsender/main.go +++ b/cmd/audio-netsender/main.go @@ -78,11 +78,11 @@ type audioClient struct { parameters // internals - dev *yalsa.Device // audio input device - clip pcm.Clip // Clip to contain the recording. - rb *ring.Buffer // our buffer - ns *netsender.Sender // our NetSender - vs int // our "var sum" to track var changes + dev *yalsa.Device // audio input device + buf pcm.Buffer // Buffer to contain the recording. + rb *ring.Buffer // our buffer + ns *netsender.Sender // our NetSender + vs int // our "var sum" to track var changes } type parameters struct { @@ -141,17 +141,17 @@ func main() { if err != nil { log.Log(logger.Error, err.Error()) } - cf := pcm.ClipFormat{ + cf := pcm.BufferFormat{ SFormat: sf, Channels: ab.Format.Channels, Rate: ab.Format.Rate, } - ac.clip = pcm.Clip{ + ac.buf = pcm.Buffer{ Format: cf, Data: ab.Data, } - recSize := (((len(ac.clip.Data) / ac.dev.BufferFormat().Channels) * ac.channels) / ac.dev.BufferFormat().Rate) * ac.rate + recSize := (((len(ac.buf.Data) / ac.dev.BufferFormat().Channels) * ac.channels) / ac.dev.BufferFormat().Rate) * ac.rate rbLen := rbDuration / ac.period ac.rb = ring.NewBuffer(rbLen, recSize, rbTimeout) @@ -332,7 +332,7 @@ func (ac *audioClient) open() error { // Re-opens the device and tries again if ASLA returns an error. // Spends a lot of time sleeping in Paused mode. // ToDo: Currently, reading audio and writing to the ringbuffer are synchronous. -// Need a way to asynchronously read from the clip, i.e., _while_ it is recording to avoid any gaps. +// Need a way to asynchronously read from the buf, i.e., _while_ it is recording to avoid any gaps. func (ac *audioClient) input() { for { ac.mu.Lock() @@ -344,7 +344,7 @@ func (ac *audioClient) input() { } log.Log(logger.Debug, "recording audio for period", "seconds", ac.period) ac.mu.Lock() - err := ac.dev.Read(ac.clip.Data) + err := ac.dev.Read(ac.buf.Data) ac.mu.Unlock() if err != nil { log.Log(logger.Debug, "device.Read failed", "error", err.Error()) @@ -386,7 +386,7 @@ func (ac *audioClient) input() { // This function also handles NetReceiver configuration requests and updating of NetReceiver vars. func (ac *audioClient) output() { // Calculate the size of the output data based on wanted channels and rate. - outLen := (((len(ac.clip.Data) / ac.clip.Format.Channels) * ac.channels) / ac.clip.Format.Rate) * ac.rate + outLen := (((len(ac.buf.Data) / ac.buf.Format.Channels) * ac.channels) / ac.buf.Format.Rate) * ac.rate buf := make([]byte, outLen) mime := "audio/x-wav;codec=pcm;rate=" + strconv.Itoa(ac.rate) + ";channels=" + strconv.Itoa(ac.channels) + ";bits=" + strconv.Itoa(ac.bits) @@ -523,9 +523,9 @@ func read(rb *ring.Buffer, buf []byte) (int, error) { return n, nil } -// formatBuffer returns a Clip that has the recording data from the ac's original Clip but stored +// formatBuffer returns a Buffer that has the recording data from the ac's original Buffer but stored // in the desired format specified by the ac's parameters. -func (ac *audioClient) formatBuffer() pcm.Clip { +func (ac *audioClient) formatBuffer() pcm.Buffer { var err error ac.mu.Lock() wantChannels := ac.channels @@ -533,17 +533,17 @@ func (ac *audioClient) formatBuffer() pcm.Clip { ac.mu.Unlock() // If nothing needs to be changed, return the original. - if ac.clip.Format.Channels == wantChannels && ac.clip.Format.Rate == wantRate { - return ac.clip + if ac.buf.Format.Channels == wantChannels && ac.buf.Format.Rate == wantRate { + return ac.buf } - formatted := pcm.Clip{Format: ac.clip.Format} + formatted := pcm.Buffer{Format: ac.buf.Format} bufCopied := false - if ac.clip.Format.Channels != wantChannels { + if ac.buf.Format.Channels != wantChannels { // Convert channels. - if ac.clip.Format.Channels == 2 && wantChannels == 1 { - if formatted, err = pcm.StereoToMono(ac.clip); err != nil { + if ac.buf.Format.Channels == 2 && wantChannels == 1 { + if formatted, err = pcm.StereoToMono(ac.buf); err != nil { log.Log(logger.Warning, "channel conversion failed, audio has remained stereo", "error", err.Error()) } else { formatted.Format.Channels = 1 @@ -552,13 +552,13 @@ func (ac *audioClient) formatBuffer() pcm.Clip { } } - if ac.clip.Format.Rate != wantRate { + if ac.buf.Format.Rate != wantRate { // Convert rate. if bufCopied { formatted, err = pcm.Resample(formatted, wantRate) } else { - formatted, err = pcm.Resample(ac.clip, wantRate) + formatted, err = pcm.Resample(ac.buf, wantRate) } if err != nil { log.Log(logger.Warning, "rate conversion failed, audio has remained original rate", "error", err.Error()) diff --git a/codec/pcm/pcm.go b/codec/pcm/pcm.go index 5500c97e..9c0b8c6e 100644 --- a/codec/pcm/pcm.go +++ b/codec/pcm/pcm.go @@ -35,7 +35,7 @@ import ( "github.com/pkg/errors" ) -// SampleFormat is the format that a PCM Clip's samples can be in. +// SampleFormat is the format that a PCM Buffer's samples can be in. type SampleFormat int // Used to represent an unknown format. @@ -52,33 +52,33 @@ const ( // https://trac.ffmpeg.org/wiki/audio%20types ) -// ClipFormat contains the format for a PCM Clip. -type ClipFormat struct { +// BufferFormat contains the format for a PCM Buffer. +type BufferFormat struct { SFormat SampleFormat Rate int Channels int } -// Clip contains a clip of PCM data and the format that it is in. -type Clip struct { - Format ClipFormat +// Buffer contains a buffer of PCM data and the format that it is in. +type Buffer struct { + Format BufferFormat Data []byte } -// Resample takes Clip c and resamples the pcm audio data to 'rate' Hz and returns a Clip with the resampled data. +// Resample takes Buffer c and resamples the pcm audio data to 'rate' Hz and returns a Buffer with the resampled data. // Notes: // - Currently only downsampling is implemented and c's rate must be divisible by 'rate' or an error will occur. // - If the number of bytes in c.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(c Clip, rate int) (Clip, error) { +func Resample(c Buffer, rate int) (Buffer, error) { if c.Format.Rate == rate { return c, nil } if c.Format.Rate < 0 { - return Clip{}, fmt.Errorf("Unable to convert from: %v Hz", c.Format.Rate) + return Buffer{}, fmt.Errorf("Unable to convert from: %v Hz", c.Format.Rate) } if rate < 0 { - return Clip{}, fmt.Errorf("Unable to convert to: %v Hz", rate) + return Buffer{}, fmt.Errorf("Unable to convert to: %v Hz", rate) } // The number of bytes in a sample. @@ -89,7 +89,7 @@ func Resample(c Clip, rate int) (Clip, error) { case S16_LE: sampleLen = 2 * c.Format.Channels default: - return Clip{}, fmt.Errorf("Unhandled ALSA format: %v", c.Format.SFormat) + return Buffer{}, fmt.Errorf("Unhandled ALSA format: %v", c.Format.SFormat) } inPcmLen := len(c.Data) @@ -100,7 +100,7 @@ func Resample(c Clip, rate int) (Clip, error) { // ratioTo = 1 is the only number that will result in an even sampling. if ratioTo != 1 { - return Clip{}, fmt.Errorf("unhandled from:to rate ratio %v:%v: 'to' must be 1", ratioFrom, ratioTo) + return Buffer{}, fmt.Errorf("unhandled from:to rate ratio %v:%v: 'to' must be 1", ratioFrom, ratioTo) } newLen := inPcmLen / ratioFrom @@ -129,9 +129,9 @@ func Resample(c Clip, rate int) (Clip, error) { resampled = append(resampled, bAvg...) } - // Return a new Clip with resampled data. - return Clip{ - Format: ClipFormat{ + // Return a new Buffer with resampled data. + return Buffer{ + Format: BufferFormat{ Channels: c.Format.Channels, SFormat: c.Format.SFormat, Rate: rate, @@ -141,13 +141,13 @@ func Resample(c Clip, rate int) (Clip, error) { } // StereoToMono returns raw mono audio data generated from only the left channel from -// the given stereo Clip -func StereoToMono(c Clip) (Clip, error) { +// the given stereo Buffer +func StereoToMono(c Buffer) (Buffer, error) { if c.Format.Channels == 1 { return c, nil } if c.Format.Channels != 2 { - return Clip{}, fmt.Errorf("Audio is not stereo or mono, it has %v channels", c.Format.Channels) + return Buffer{}, fmt.Errorf("Audio is not stereo or mono, it has %v channels", c.Format.Channels) } var stereoSampleBytes int @@ -157,7 +157,7 @@ func StereoToMono(c Clip) (Clip, error) { case S16_LE: stereoSampleBytes = 4 default: - return Clip{}, fmt.Errorf("Unhandled sample format %v", c.Format.SFormat) + return Buffer{}, fmt.Errorf("Unhandled sample format %v", c.Format.SFormat) } recLength := len(c.Data) @@ -173,9 +173,9 @@ func StereoToMono(c Clip) (Clip, error) { } } - // Return a new Clip with resampled data. - return Clip{ - Format: ClipFormat{ + // Return a new Buffer with resampled data. + return Buffer{ + Format: BufferFormat{ Channels: 1, SFormat: c.Format.SFormat, Rate: c.Format.Rate, diff --git a/codec/pcm/pcm_test.go b/codec/pcm/pcm_test.go index e2324121..8e9cf891 100644 --- a/codec/pcm/pcm_test.go +++ b/codec/pcm/pcm_test.go @@ -45,19 +45,19 @@ func TestResample(t *testing.T) { log.Fatal(err) } - format := ClipFormat{ + format := BufferFormat{ Channels: 1, Rate: 48000, SFormat: S16_LE, } - clip := Clip{ + buf := Buffer{ Format: format, Data: inPcm, } // Resample pcm. - resampled, err := Resample(clip, 8000) + resampled, err := Resample(buf, 8000) if err != nil { log.Fatal(err) } @@ -86,19 +86,19 @@ func TestStereoToMono(t *testing.T) { log.Fatal(err) } - format := ClipFormat{ + format := BufferFormat{ Channels: 2, Rate: 44100, SFormat: S16_LE, } - clip := Clip{ + buf := Buffer{ Format: format, Data: inPcm, } // Convert audio. - mono, err := StereoToMono(clip) + mono, err := StereoToMono(buf) if err != nil { log.Fatal(err) } diff --git a/device/alsa/alsa.go b/device/alsa/alsa.go index b37090e7..47f614bc 100644 --- a/device/alsa/alsa.go +++ b/device/alsa/alsa.go @@ -68,7 +68,7 @@ type ALSA struct { 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. - clip pcm.Clip // Clip to contain the recording. + buf pcm.Buffer // Buffer to contain the recording. 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. @@ -139,18 +139,18 @@ func (d *ALSA) Set(c config.Config) error { d.l.Log(logger.Error, pkg+err.Error()) return err } - cf := pcm.ClipFormat{ + cf := pcm.BufferFormat{ SFormat: sf, Channels: ab.Format.Channels, Rate: ab.Format.Rate, } - d.clip = pcm.Clip{ + d.buf = pcm.Buffer{ Format: cf, Data: ab.Data, } // Account for channel conversion. - chunkSize := float64(len(d.clip.Data) / d.dev.BufferFormat().Channels * d.Channels) + chunkSize := float64(len(d.buf.Data) / d.dev.BufferFormat().Channels * d.Channels) // Account for resampling. chunkSize = (chunkSize / float64(d.dev.BufferFormat().Rate)) * float64(d.SampleRate) @@ -386,7 +386,7 @@ func (d *ALSA) input() { // Read from audio device. d.l.Log(logger.Debug, pkg+"recording audio for period", "seconds", d.RecPeriod) - err := d.dev.Read(d.clip.Data) + err := d.dev.Read(d.buf.Data) if err != nil { d.l.Log(logger.Debug, pkg+"read failed", "error", err.Error()) err = d.open() // re-open @@ -428,26 +428,26 @@ func (d *ALSA) Read(p []byte) (int, error) { } // formatBuffer returns audio that has been converted to the desired format. -func (d *ALSA) formatBuffer() pcm.Clip { +func (d *ALSA) formatBuffer() pcm.Buffer { var err error // If nothing needs to be changed, return the original. - if d.clip.Format.Channels == d.Channels && d.clip.Format.Rate == d.SampleRate { - return d.clip + if d.buf.Format.Channels == d.Channels && d.buf.Format.Rate == d.SampleRate { + return d.buf } - var formatted pcm.Clip - if d.clip.Format.Channels != d.Channels { + var formatted pcm.Buffer + if d.buf.Format.Channels != d.Channels { // Convert channels. // TODO(Trek): Make this work for conversions other than stereo to mono. - if d.clip.Format.Channels == 2 && d.Channels == 1 { - formatted, err = pcm.StereoToMono(d.clip) + if d.buf.Format.Channels == 2 && d.Channels == 1 { + formatted, err = pcm.StereoToMono(d.buf) if err != nil { d.l.Log(logger.Fatal, pkg+"channel conversion failed", "error", err.Error()) } } } - if d.clip.Format.Rate != d.SampleRate { + if d.buf.Format.Rate != d.SampleRate { // Convert rate. formatted, err = pcm.Resample(formatted, d.SampleRate) if err != nil { diff --git a/exp/pcm/resample/resample.go b/exp/pcm/resample/resample.go index 00e9da28..6c7106b6 100644 --- a/exp/pcm/resample/resample.go +++ b/exp/pcm/resample/resample.go @@ -62,19 +62,19 @@ func main() { log.Fatalf("Unhandled ALSA format: %v", SFString) } - format := pcm.ClipFormat{ + format := pcm.BufferFormat{ Channels: channels, Rate: from, SFormat: sf, } - clip := pcm.Clip{ + buf := pcm.Buffer{ Format: format, Data: inPcm, } // Resample audio. - resampled, err := pcm.Resample(clip, to) + resampled, err := pcm.Resample(buf, to) if err != nil { log.Fatal(err) } diff --git a/exp/pcm/stereo-to-mono/stereo-to-mono.go b/exp/pcm/stereo-to-mono/stereo-to-mono.go index dca08d7f..84700737 100644 --- a/exp/pcm/stereo-to-mono/stereo-to-mono.go +++ b/exp/pcm/stereo-to-mono/stereo-to-mono.go @@ -59,18 +59,18 @@ func main() { log.Fatalf("Unhandled sample format: %v", SFString) } - format := pcm.ClipFormat{ + format := pcm.BufferFormat{ Channels: 2, SFormat: sf, } - clip := pcm.Clip{ + buf := pcm.Buffer{ Format: format, Data: inPcm, } // Convert audio. - mono, err := pcm.StereoToMono(clip) + mono, err := pcm.StereoToMono(buf) if err != nil { log.Fatal(err) }