// Write writes given PCM data. // Returns wrote value is total bytes was written. func (handle *Handle) Write(buf []byte) (wrote int, err error) { frames := len(buf) / handle.SampleSize() / handle.Channels w := C.snd_pcm_writei(handle.cHandle, unsafe.Pointer(&buf[0]), _Ctype_snd_pcm_uframes_t(frames)) // Underrun? Retry. if w == -C.EPIPE { C.snd_pcm_prepare(handle.cHandle) w = C.snd_pcm_writei(handle.cHandle, unsafe.Pointer(&buf[0]), _Ctype_snd_pcm_uframes_t(frames)) } if w < 0 { return 0, errors.New(fmt.Sprintf("Write failed. %s", strError(_Ctype_int(w)))) } wrote = int(w) wrote *= handle.FrameSize() return wrote, nil }
// Write writes a buffer of data to a playback device. func (p *PlaybackDevice) Write(buffer interface{}) (samples int, err error) { bufferType := reflect.TypeOf(buffer) if !(bufferType.Kind() == reflect.Array || bufferType.Kind() == reflect.Slice) { return 0, errors.New("Write requires an array type") } sizeError := errors.New("Write requires a matching sample size") switch bufferType.Elem().Kind() { case reflect.Int8: if p.formatSampleSize() != 1 { return 0, sizeError } case reflect.Int16: if p.formatSampleSize() != 2 { return 0, sizeError } case reflect.Int32, reflect.Float32: if p.formatSampleSize() != 4 { return 0, sizeError } case reflect.Float64: if p.formatSampleSize() != 8 { return 0, sizeError } default: return 0, errors.New("Write does not support this format") } val := reflect.ValueOf(buffer) length := val.Len() sliceData := val.Slice(0, length) var frames = C.snd_pcm_uframes_t(length / p.Channels) bufPtr := unsafe.Pointer(sliceData.Index(0).Addr().Pointer()) ret := C.snd_pcm_writei(p.h, bufPtr, frames) if ret == -C.EPIPE { C.snd_pcm_prepare(p.h) return 0, ErrUnderrun } else if ret < 0 { return 0, createError("write error", C.int(ret)) } samples = int(ret) * p.Channels return }