// Retrieve all available sinks from PulseAudio // func (self *Client) GetSinks() ([]Sink, error) { operation := NewOperation(self) sinks := make([]Sink, 0) operation.paOper = C.pa_context_get_sink_info_list(C.pulse_get_context(), (C.pa_sink_info_cb_t)(unsafe.Pointer(C.pulse_get_sink_info_list_callback)), unsafe.Pointer(operation)) // wait for the operation to finish and handle success and error cases return sinks, operation.WaitSuccess(func(op *Operation) error { // create a Sink{} for each returned payload for _, payload := range op.Payloads { sink := Sink{ Client: self, } if err := sink.Initialize(payload.Properties); err == nil { sinks = append(sinks, sink) } else { return err } } return nil }) }
// Set the volume of all channels of this sink to a factor of the maximum // volume (0.0 <= v <= 1.0). Factors greater than 1.0 will be accepted, but // clipping or distortion may occur beyond that value. // func (self *Sink) SetVolume(factor float64) error { if self.Channels > 0 { operation := NewOperation(self.Client) newVolume := &C.pa_cvolume{} // new volume is the (maximum number of normal volume steps * factor) newVolume = C.pa_cvolume_init(newVolume) newVolumeT := C.pa_volume_t(C.uint32_t(uint(float64(self.NumVolumeSteps) * factor))) // prepare newVolume for its journey into PulseAudio C.pa_cvolume_set(newVolume, C.uint(self.Channels), newVolumeT) // make the call operation.paOper = C.pa_context_set_sink_volume_by_index(C.pulse_get_context(), C.uint32_t(self.Index), newVolume, (C.pa_context_success_cb_t)(unsafe.Pointer(C.pulse_generic_success_callback)), unsafe.Pointer(operation)) // wait for the result, refresh, return any errors return operation.WaitSuccess(func(op *Operation) error { return self.Refresh() }) } else { return fmt.Errorf("Cannot set volume on sink %d, no channels defined", self.Index) } return nil }
// Explicitly set the muted or unmuted state of the sink. // func (self *Sink) SetMute(mute bool) error { operation := NewOperation(self.Client) var muting C.int if mute { muting = C.int(1) } else { muting = C.int(0) } operation.paOper = C.pa_context_set_sink_mute_by_index(C.pulse_get_context(), C.uint32_t(self.Index), muting, (C.pa_context_success_cb_t)(unsafe.Pointer(C.pulse_generic_success_callback)), unsafe.Pointer(operation)) // wait for the result, refresh, return any errors return operation.WaitSuccess(func(op *Operation) error { return self.Refresh() }) }
// Synchronize this sink's data with the PulseAudio daemon. // func (self *Sink) Refresh() error { operation := NewOperation(self.Client) operation.paOper = C.pa_context_get_sink_info_by_index(C.pulse_get_context(), C.uint32_t(self.Index), (C.pa_sink_info_cb_t)(unsafe.Pointer(C.pulse_get_sink_info_by_index_callback)), unsafe.Pointer(operation)) // wait for the operation to finish and handle success and error cases return operation.WaitSuccess(func(op *Operation) error { if l := len(op.Payloads); l == 1 { payload := operation.Payloads[0] if err := self.Initialize(payload.Properties); err != nil { return err } } else { return fmt.Errorf("Invalid sink response: expected 1 payload, got %d", l) } return nil }) }
// Retrieve information about the connected PulseAudio daemon // func (self *Client) GetServerInfo() (ServerInfo, error) { operation := NewOperation(self) info := ServerInfo{} operation.paOper = C.pa_context_get_server_info(C.pulse_get_context(), (C.pa_server_info_cb_t)(unsafe.Pointer(C.pulse_get_server_info_callback)), unsafe.Pointer(operation)) // wait for the operation to finish and handle success and error cases return info, operation.WaitSuccess(func(op *Operation) error { if len(op.Payloads) > 0 { payload := op.Payloads[0] if err := UnmarshalMap(payload.Properties, &info); err != nil { return err } } else { return fmt.Errorf("GetServerInfo() completed without retrieving any data") } return nil }) }