// Close closes a device and frees the resources associated with it. func (d *device) Close() { if d.h != nil { C.snd_pcm_drain(d.h) C.snd_pcm_close(d.h) d.h = nil } runtime.SetFinalizer(d, nil) }
// Drain stream. For playback wait for all pending frames to be played and // then stop the PCM. For capture stop PCM permitting to retrieve residual frames. func (handle *Handle) Drain() error { err := C.snd_pcm_drain(handle.cHandle) if err < 0 { return errors.New(fmt.Sprintf("Cannot drain stream. %s", strError(err))) } return nil }
// ApplyHwParams changes ALSA hardware parameters for the current stream. func (handle *Handle) ApplyHwParams() error { var cHwParams *C.snd_pcm_hw_params_t err := C.snd_pcm_hw_params_malloc(&cHwParams) if err < 0 { return errors.New(fmt.Sprintf("Cannot allocate hardware parameter structure. %s", strError(err))) } err = C.snd_pcm_hw_params_any(handle.cHandle, cHwParams) if err < 0 { return errors.New(fmt.Sprintf("Cannot initialize hardware parameter structure. %s", strError(err))) } err = C.snd_pcm_hw_params_set_access(handle.cHandle, cHwParams, C.SND_PCM_ACCESS_RW_INTERLEAVED) if err < 0 { return errors.New(fmt.Sprintf("Cannot set access type. %s", strError(err))) } err = C.snd_pcm_hw_params_set_format(handle.cHandle, cHwParams, _Ctype_snd_pcm_format_t(handle.SampleFormat)) if err < 0 { return errors.New(fmt.Sprintf("Cannot set sample format. %s", strError(err))) } var cSampleRate _Ctype_uint = _Ctype_uint(handle.SampleRate) err = C.snd_pcm_hw_params_set_rate_near(handle.cHandle, cHwParams, &cSampleRate, nil) if err < 0 { return errors.New(fmt.Sprintf("Cannot set sample rate. %s", strError(err))) } err = C.snd_pcm_hw_params_set_channels(handle.cHandle, cHwParams, _Ctype_uint(handle.Channels)) if err < 0 { return errors.New(fmt.Sprintf("Cannot set number of channels. %s", strError(err))) } // Drain current data and make sure we aren't underrun. C.snd_pcm_drain(handle.cHandle) err = C.snd_pcm_hw_params(handle.cHandle, cHwParams) if err < 0 { return errors.New(fmt.Sprintf("Cannot set hardware parameters. %s", strError(err))) } C.snd_pcm_hw_params_free(cHwParams) return nil }
// ApplyHwParams changes ALSA hardware parameters for the current stream. func (handle *Handle) ApplyHwParams() error { var cHwParams *C.snd_pcm_hw_params_t err := C.snd_pcm_hw_params_malloc(&cHwParams) if err < 0 { return errors.New(fmt.Sprintf("Cannot allocate hardware parameter structure. %s", strError(err))) } err = C.snd_pcm_hw_params_any(handle.cHandle, cHwParams) if err < 0 { return errors.New(fmt.Sprintf("Cannot initialize hardware parameter structure. %s", strError(err))) } err = C.snd_pcm_hw_params_set_access(handle.cHandle, cHwParams, C.SND_PCM_ACCESS_RW_INTERLEAVED) if err < 0 { return errors.New(fmt.Sprintf("Cannot set access type. %s", strError(err))) } err = C.snd_pcm_hw_params_set_format(handle.cHandle, cHwParams, C.snd_pcm_format_t(handle.SampleFormat)) if err < 0 { return errors.New(fmt.Sprintf("Cannot set sample format. %s", strError(err))) } var cSampleRate _Ctype_uint = _Ctype_uint(handle.SampleRate) err = C.snd_pcm_hw_params_set_rate_near(handle.cHandle, cHwParams, &cSampleRate, nil) if err < 0 { return errors.New(fmt.Sprintf("Cannot set sample rate. %s", strError(err))) } err = C.snd_pcm_hw_params_set_channels(handle.cHandle, cHwParams, _Ctype_uint(handle.Channels)) if err < 0 { return errors.New(fmt.Sprintf("Cannot set number of channels. %s", strError(err))) } if handle.Periods > 0 { // Set number of periods. Periods used to be called fragments. /*err = C.snd_pcm_hw_params_set_periods(handle.cHandle, cHwParams, _Ctype_uint(handle.Periods), 0) if err < 0 { return os.NewError(fmt.Sprintf("Cannot set number of periods. %s", strError(err))) }*/ var cPeriods _Ctype_uint = _Ctype_uint(handle.Periods) var cDir _Ctype_int = 0 // Exact value is <,=,> the returned one following dir (-1,0,1) err = C.snd_pcm_hw_params_set_periods_near(handle.cHandle, cHwParams, &cPeriods, &cDir) if err < 0 { return errors.New(fmt.Sprintf("Cannot set number of periods. %s", strError(err))) } } if handle.Buffersize > 0 { // Set buffer size (in frames). The resulting latency is given by // latency = periodsize * periods / (rate * bytes_per_frame) /*err = C.snd_pcm_hw_params_set_buffer_size(handle.cHandle, cHwParams, _Ctypedef_snd_pcm_uframes_t(handle.Buffersize)) if err < 0 { return os.NewError(fmt.Sprintf("Cannot set buffersize. %s", strError(err))) }*/ var cBuffersize C.snd_pcm_uframes_t = C.snd_pcm_uframes_t(handle.Buffersize) err = C.snd_pcm_hw_params_set_buffer_size_near(handle.cHandle, cHwParams, &cBuffersize) if err < 0 { return errors.New(fmt.Sprintf("Cannot set buffersize. %s", strError(err))) } } // Drain current data and make sure we aren't underrun. C.snd_pcm_drain(handle.cHandle) err = C.snd_pcm_hw_params(handle.cHandle, cHwParams) if err < 0 { return errors.New(fmt.Sprintf("Cannot set hardware parameters. %s", strError(err))) } C.snd_pcm_hw_params_free(cHwParams) return nil }