audio: Reduce panic on Windows

This commit is contained in:
Hajime Hoshi 2016-04-04 02:50:00 +09:00
parent 68cf7bf6fa
commit ab793d9c8b

View File

@ -25,6 +25,7 @@ package audio
import "C" import "C"
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"time" "time"
@ -37,9 +38,7 @@ type header struct {
waveHdr C.WAVEHDR waveHdr C.WAVEHDR
} }
// TODO: Reduce panics and use errors instead func newHeader(waveOut C.HWAVEOUT, bufferSize int) (header, error) {
func newHeader(waveOut C.HWAVEOUT, bufferSize int) header {
// NOTE: This is never freed so far. // NOTE: This is never freed so far.
buf := C.malloc(C.size_t(bufferSize)) buf := C.malloc(C.size_t(bufferSize))
h := header{ h := header{
@ -52,19 +51,20 @@ func newHeader(waveOut C.HWAVEOUT, bufferSize int) header {
} }
// TODO: Need to unprepare to avoid memory leak? // TODO: Need to unprepare to avoid memory leak?
if err := C.waveOutPrepareHeader(waveOut, &h.waveHdr, C.sizeOfWavehdr); err != C.MMSYSERR_NOERROR { if err := C.waveOutPrepareHeader(waveOut, &h.waveHdr, C.sizeOfWavehdr); err != C.MMSYSERR_NOERROR {
panic(fmt.Sprintf("audio: waveOutPrepareHeader error %d", err)) return header{}, fmt.Errorf("audio: waveOutPrepareHeader error: %d", err)
} }
return h return h, nil
} }
func (h *header) Write(waveOut C.HWAVEOUT, data []byte) { func (h *header) Write(waveOut C.HWAVEOUT, data []byte) error {
if len(data) != h.bufferSize { if len(data) != h.bufferSize {
panic("audio: len(data) must equal to h.bufferSize") return errors.New("audio: len(data) must equal to h.bufferSize")
} }
C.memcpy(h.buffer, unsafe.Pointer(&data[0]), C.size_t(h.bufferSize)) C.memcpy(h.buffer, unsafe.Pointer(&data[0]), C.size_t(h.bufferSize))
if err := C.waveOutWrite(waveOut, &h.waveHdr, C.sizeOfWavehdr); err != C.MMSYSERR_NOERROR { if err := C.waveOutWrite(waveOut, &h.waveHdr, C.sizeOfWavehdr); err != C.MMSYSERR_NOERROR {
panic(fmt.Sprintf("audio: waveOutWriter error %d", err)) return fmt.Errorf("audio: waveOutWriter error: %d", err)
} }
return nil
} }
const numHeader = 8 const numHeader = 8
@ -107,7 +107,11 @@ func startPlaying(src io.Reader, sampleRate int) error {
headers: make([]header, numHeader), headers: make([]header, numHeader),
} }
for i := 0; i < numHeader; i++ { for i := 0; i < numHeader; i++ {
p.headers[i] = newHeader(w, bufferSize) var err error
p.headers[i], err = newHeader(w, bufferSize)
if err != nil {
return err
}
} }
go func() { go func() {
defer p.close() defer p.close()
@ -133,7 +137,9 @@ func (p *player) proceed() error {
p.buffer = append(p.buffer, b[:n]...) p.buffer = append(p.buffer, b[:n]...)
for bufferSize <= len(p.buffer) { for bufferSize <= len(p.buffer) {
sem <- struct{}{} sem <- struct{}{}
p.headers[p.i].Write(p.out, p.buffer[:bufferSize]) if err := p.headers[p.i].Write(p.out, p.buffer[:bufferSize]); err != nil {
return err
}
p.buffer = p.buffer[bufferSize:] p.buffer = p.buffer[bufferSize:]
p.i++ p.i++
p.i %= len(p.headers) p.i %= len(p.headers)