示例#1
0
文件: pulsego.go 项目: deadsy/xsynth
func NewPulseMainLoop() *PulseMainLoop {
	pa := C.pa_threaded_mainloop_new()
	if pa == nil {
		return nil
	}
	return &PulseMainLoop{pa: pa}
}
示例#2
0
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
}