func NewPulseMainLoop() *PulseMainLoop { pa := C.pa_threaded_mainloop_new() if pa == nil { return nil } return &PulseMainLoop{pa: pa} }
func NewClient(name string) (*Client, error) { rv := &Client{ ID: uuid.NewV4().String(), Name: name, OperationTimeout: (time.Duration(DEFAULT_OPERATION_TIMEOUT_MSEC) * time.Millisecond), state: make(chan error), } cgoregister(rv.ID, rv) rv.mainloop = C.pa_threaded_mainloop_new() if rv.mainloop == nil { return nil, fmt.Errorf("Failed to create PulseAudio mainloop") } rv.api = C.pa_threaded_mainloop_get_api(rv.mainloop) rv.context = C.pa_context_new(rv.api, C.CString(name)) C.pa_context_set_state_callback(rv.context, (C.pa_context_notify_cb_t)(C.pulse_context_state_callback), rv.ToUserdata()) // lock the mainloop until the context is ready rv.Lock() // start the mainloop rv.Start() // initiate context connect if int(C.pa_context_connect(rv.context, nil, (C.pa_context_flags_t)(0), nil)) != 0 { defer rv.Stop() defer rv.Destroy() return nil, rv.GetLastError() } // wait for context to be ready for { state := ContextState(int(C.pa_context_get_state(rv.context))) breakOut := false switch state { case StateUnconnected, StateConnecting, StateAuthorizing, StateSettingName: if err := rv.Wait(); err != nil { return nil, err } case StateFailed: return nil, rv.GetLastError() case StateTerminated: return nil, fmt.Errorf("PulseAudio connection was terminated during setup") case StateReady: breakOut = true default: return nil, fmt.Errorf("Encountered unknown connection state %d during setup", state) } if breakOut { break } } rv.Unlock() return rv, nil }