Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playback cutoff in blocking stream mode #38

Closed
nguillaumin opened this issue May 17, 2020 · 1 comment
Closed

Playback cutoff in blocking stream mode #38

nguillaumin opened this issue May 17, 2020 · 1 comment

Comments

@nguillaumin
Copy link

Hi,

I'm trying to decode and play an OGG file, but the playback is always cut off before the end of the file. I can get it to play fully if I add a few more stream.Write() calls at the end of my program, as if the output buffer was not completely exhausted somehow.

I wanted to try the play.go example to compare, but I was not able to find a WAV file that worked with the example code. I also tried with decoding a FLAC file but ran into the same issue.

Here's the code, and I'm attaching the sample OGG file as well. It's probably something wrong in my code and how I interact with the buffers, but I can't figure it out, any help would be appreciated!

Thanks!

package main

import (
	"fmt"
	"io"
	"os"

	"github.com/gordonklaus/portaudio"
	"github.com/jfreymuth/oggvorbis"
)

func main() {

	// PortAudio output buffer
	paBuf := make([]float32, 1024*8)

	file, err := os.Open("03 - OGG Sample.ogg")
	chk(err)
	defer file.Close()

	oggReader, err := oggvorbis.NewReader(file)
	chk(err)

	portaudio.Initialize()
	defer portaudio.Terminate()
	h, err := portaudio.DefaultHostApi()
	chk(err)

	fmt.Printf("Channels: %v, SampleRate: %v\n", oggReader.Channels(), oggReader.SampleRate())
	streamParameters := portaudio.StreamParameters{
		Output: portaudio.StreamDeviceParameters{
			Device:   h.DefaultOutputDevice,
			Channels: oggReader.Channels(),
			Latency:  h.DefaultOutputDevice.DefaultLowOutputLatency,
		},
		Input: portaudio.StreamDeviceParameters{
			Device: nil,
		},
		SampleRate:      float64(oggReader.SampleRate()),
		FramesPerBuffer: len(paBuf),
	}

	stream, err := portaudio.OpenStream(streamParameters, &paBuf)
	chk(err)

	defer stream.Close()
	chk(stream.Start())
	defer stream.Stop()

	var buffer []float32
	var n int
	for err != io.EOF {
		// Read enough data to fill paBuf
		for len(buffer) < len(paBuf) && err == nil {
			b := make([]float32, len(paBuf))
			n, err = oggReader.Read(b)
			buffer = append(buffer, b[:n]...)
		}

		fmt.Printf("buffer length: %v\n", len(buffer))

		if len(buffer) > 0 {
			n = copy(paBuf, buffer)
			buffer = buffer[n:]
			writeErr := stream.Write()
			chk(writeErr)
		}
	}

	fmt.Printf("finished. remaining in buffer: %v\n", len(buffer))
	for len(buffer) > 0 {
		n = Min(len(buffer), len(paBuf))
		copy(paBuf, buffer[:n])
		buffer = buffer[n:]
		writeErr := stream.Write()
		chk(writeErr)
	}

	// Uncomment these to get the complete playback
	// stream.Write()
	// stream.Write()
	// stream.Write()
	// stream.Write()

}

func chk(err error) {
	if err != nil {
		panic(err)
	}
}

func Min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

03 - OGG Sample.zip

@gordonklaus
Copy link
Owner

Sorry for never replying to this issue. If it's still a problem and you think it's an issue with portaudio-go, please re-open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants