static void moko_notify_init (MokoNotify *notify) { MokoNotifyPrivate *priv; pa_threaded_mainloop *mainloop = NULL; pa_mainloop_api *mapi = NULL; priv = notify->priv = MOKO_NOTIFY_GET_PRIVATE (notify); priv->started = 0; priv->pac = NULL; /* Start up pulse audio */ mainloop = pa_threaded_mainloop_new (); if (!mainloop) { g_warning ("Unable to create PulseAudio mainloop."); return; } mapi = pa_threaded_mainloop_get_api (mainloop); priv->pac = pa_context_new (mapi, "Openmoko Dialer"); if (!priv->pac) { g_warning ("Could create the PulseAudio context"); return; } pa_context_connect (priv->pac, NULL, 0, NULL); pa_threaded_mainloop_start (mainloop); }
/** * This function does the context initialization. */ static gboolean xvd_connect_to_pulse (XvdInstance *i) { pa_context_flags_t flags = PA_CONTEXT_NOFAIL; if (i->pulse_context) { pa_context_unref (i->pulse_context); i->pulse_context = NULL; } i->pulse_context = pa_context_new (pa_glib_mainloop_get_api (i->pa_main_loop), XVD_APPNAME); g_assert(i->pulse_context); pa_context_set_state_callback (i->pulse_context, xvd_context_state_callback, i); if (pa_context_connect (i->pulse_context, NULL, flags, NULL) < 0) { g_warning ("xvd_connect_to_pulse: failed to connect context: %s", pa_strerror (pa_context_errno (i->pulse_context))); return FALSE; } return TRUE; }
static int tsmf_pulse_open(ITSMFAudioDevice * audio, const char * device) { TSMFPulseAudioDevice * pulse = (TSMFPulseAudioDevice *) audio; if (device) { strcpy(pulse->device, device); } pulse->mainloop = pa_threaded_mainloop_new(); if (!pulse->mainloop) { LLOGLN(0, ("tsmf_pulse_open: pa_threaded_mainloop_new failed")); return 1; } pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); if (!pulse->context) { LLOGLN(0, ("tsmf_pulse_open: pa_context_new failed")); return 1; } pa_context_set_state_callback(pulse->context, tsmf_pulse_context_state_callback, pulse); if (tsmf_pulse_connect(pulse)) { LLOGLN(0, ("tsmf_pulse_open: tsmf_pulse_connect failed")); return 1; } LLOGLN(0, ("tsmf_pulse_open: open device %s", pulse->device)); return 0; }
bool PulseHandler::Init(void) { if (m_initialised) return m_valid; m_initialised = true; // Initialse our connection to the server m_loop = pa_mainloop_new(); if (!m_loop) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to get PulseAudio mainloop"); return m_valid; } pa_mainloop_api *api = pa_mainloop_get_api(m_loop); if (!api) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to get PulseAudio api"); return m_valid; } if (pa_signal_init(api) != 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to initialise signaling"); return m_valid; } const char *client = "mythtv"; m_ctx = pa_context_new(api, client); if (!m_ctx) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create context"); return m_valid; } // remember which thread created this object for later sanity debugging m_thread = QThread::currentThread(); // we set the callback, connect and then run the main loop 'by hand' // until we've successfully connected (or not) pa_context_set_state_callback(m_ctx, StatusCallback, this); pa_context_connect(m_ctx, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); int ret = 0; int tries = 0; while ((tries++ < 100) && !IS_READY(m_ctx_state)) { pa_mainloop_iterate(m_loop, 0, &ret); usleep(10000); } if (PA_CONTEXT_READY != m_ctx_state) { LOG(VB_GENERAL, LOG_ERR, LOC + "Context not ready after 1000ms"); return m_valid; } LOG(VB_AUDIO, LOG_INFO, LOC + "Initialised handler"); m_valid = true; return m_valid; }
/** * Create, set up and connect a context. * * Caller must lock the main loop. * * @return true on success, false on error */ static bool pulse_output_setup_context(struct pulse_output *po, GError **error_r) { assert(po != NULL); assert(po->mainloop != NULL); po->context = pa_context_new(pa_threaded_mainloop_get_api(po->mainloop), MPD_PULSE_NAME); if (po->context == NULL) { g_set_error(error_r, pulse_output_quark(), 0, "pa_context_new() has failed"); return false; } pa_context_set_state_callback(po->context, pulse_output_context_state_cb, po); pa_context_set_subscribe_callback(po->context, pulse_output_subscribe_cb, po); if (!pulse_output_connect(po, error_r)) { pulse_output_delete_context(po); return false; } return true; }
bool PulseDeviceFinder::Reconnect() { if (context_) { pa_context_disconnect(context_); pa_context_unref(context_); } context_ = pa_context_new(pa_mainloop_get_api(mainloop_), "Clementine device finder"); if (!context_) { qLog(Warning) << "Failed to create pulseaudio context"; return false; } if (pa_context_connect(context_, nullptr, PA_CONTEXT_NOFLAGS, nullptr) < 0) { qLog(Warning) << "Failed to connect pulseaudio context"; return false; } // Wait for the context to be connected. forever { const pa_context_state state = pa_context_get_state(context_); if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) { qLog(Warning) << "Connection to pulseaudio failed"; return false; } if (state == PA_CONTEXT_READY) { return true; } pa_mainloop_iterate(mainloop_, true, nullptr); } }
static BOOL tsmf_pulse_open(ITSMFAudioDevice *audio, const char *device) { TSMFPulseAudioDevice *pulse = (TSMFPulseAudioDevice *) audio; if(device) { strcpy(pulse->device, device); } pulse->mainloop = pa_threaded_mainloop_new(); if(!pulse->mainloop) { DEBUG_WARN("pa_threaded_mainloop_new failed"); return FALSE; } pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); if(!pulse->context) { DEBUG_WARN("pa_context_new failed"); return FALSE; } pa_context_set_state_callback(pulse->context, tsmf_pulse_context_state_callback, pulse); if(tsmf_pulse_connect(pulse)) { DEBUG_WARN("tsmf_pulse_connect failed"); return FALSE; } DEBUG_TSMF("open device %s", pulse->device); return TRUE; }
void vis::PulseAudioSource::populate_default_source_name() { #ifdef _ENABLE_PULSE pa_mainloop_api *mainloop_api; pa_context *pulseaudio_context; // Create a mainloop API and connection to the default server m_pulseaudio_mainloop = pa_mainloop_new(); mainloop_api = pa_mainloop_get_api(m_pulseaudio_mainloop); pulseaudio_context = pa_context_new(mainloop_api, "vis device list"); // This function connects to the pulse server pa_context_connect(pulseaudio_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr); // This function defines a callback so the server will tell us its state. pa_context_set_state_callback(pulseaudio_context, pulseaudio_context_state_callback, reinterpret_cast<void *>(this)); int ret; if (pa_mainloop_run(m_pulseaudio_mainloop, &ret) < 0) { VIS_LOG(vis::LogLevel::ERROR, "Could not open pulseaudio mainloop to " "find default device name: %d", ret); } #endif }
void guac_pa_start_stream(guac_client* client) { vnc_guac_client_data* client_data = (vnc_guac_client_data*) client->data; pa_context* context; guac_client_log_info(client, "Starting audio stream"); guac_audio_stream_begin(client_data->audio, GUAC_VNC_AUDIO_RATE, GUAC_VNC_AUDIO_CHANNELS, GUAC_VNC_AUDIO_BPS); /* Init main loop */ client_data->pa_mainloop = pa_threaded_mainloop_new(); /* Create context */ context = pa_context_new( pa_threaded_mainloop_get_api(client_data->pa_mainloop), "Guacamole Audio"); /* Set up context */ pa_context_set_state_callback(context, __context_state_callback, client); pa_context_connect(context, client_data->pa_servername, PA_CONTEXT_NOAUTOSPAWN, NULL); /* Start loop */ pa_threaded_mainloop_start(client_data->pa_mainloop); }
int PulseAudioDriver::thread_body() { m_main_loop = pa_mainloop_new(); pa_mainloop_api* api = pa_mainloop_get_api(m_main_loop); pa_io_event* ioev = api->io_new(api, m_pipe[0], PA_IO_EVENT_INPUT, pipe_callback, this); m_ctx = pa_context_new(api, "Hydrogen"); pa_context_set_state_callback(m_ctx, ctx_state_callback, this); pa_context_connect(m_ctx, 0, pa_context_flags_t(0), 0); int retval; pa_mainloop_run(m_main_loop, &retval); if (m_stream) { pa_stream_set_state_callback(m_stream, 0, 0); pa_stream_set_write_callback(m_stream, 0, 0); pa_stream_unref(m_stream); m_stream = 0; } api->io_free(ioev); pa_context_unref(m_ctx); pa_mainloop_free(m_main_loop); return retval; }
int main(int argc, char *argv[]) { // Define our pulse audio loop and connection variables pa_mainloop *pa_ml; pa_mainloop_api *pa_mlapi; pa_operation *pa_op; pa_time_event *time_event; // Create a mainloop API and connection to the default server pa_ml = pa_mainloop_new(); pa_mlapi = pa_mainloop_get_api(pa_ml); context = pa_context_new(pa_mlapi, "Device list"); // This function connects to the pulse server pa_context_connect(context, NULL, 0, NULL); // This function defines a callback so the server will tell us its state. pa_context_set_state_callback(context, context_state_cb, NULL); if (pa_mainloop_run(pa_ml, &ret) < 0) { printf("pa_mainloop_run() failed."); exit(1); } }
void Context::connectToDaemon() { Q_ASSERT(m_context == nullptr); // We require a glib event loop if (!QByteArray(QAbstractEventDispatcher::instance()->metaObject()->className()).contains("EventDispatcherGlib")) { qCWarning(PLASMAPA) << "Disabling PulseAudio integration for lack of GLib event loop"; return; } qCDebug(PLASMAPA) << "Attempting connection to PulseAudio sound daemon"; if (!m_mainloop) { m_mainloop = pa_glib_mainloop_new(nullptr); Q_ASSERT(m_mainloop); } pa_mainloop_api *api = pa_glib_mainloop_get_api(m_mainloop); Q_ASSERT(api); m_context = pa_context_new(api, "QPulse"); Q_ASSERT(m_context); if (pa_context_connect(m_context, NULL, PA_CONTEXT_NOFAIL, nullptr) < 0) { pa_context_unref(m_context); pa_glib_mainloop_free(m_mainloop); m_context = nullptr; m_mainloop = nullptr; return; } pa_context_set_state_callback(m_context, &context_state_callback, this); }
Error AudioDriverPulseAudio::init() { active = false; thread_exited = false; exit_thread = false; mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE); pa_ml = pa_mainloop_new(); ERR_FAIL_COND_V(pa_ml == NULL, ERR_CANT_OPEN); pa_ctx = pa_context_new(pa_mainloop_get_api(pa_ml), "Godot"); ERR_FAIL_COND_V(pa_ctx == NULL, ERR_CANT_OPEN); pa_ready = 0; pa_context_set_state_callback(pa_ctx, pa_state_cb, (void *)this); int ret = pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL); if (ret < 0) { if (pa_ctx) { pa_context_unref(pa_ctx); pa_ctx = NULL; } if (pa_ml) { pa_mainloop_free(pa_ml); pa_ml = NULL; } return ERR_CANT_OPEN; } while (pa_ready == 0) { pa_mainloop_iterate(pa_ml, 1, NULL); } if (pa_ready < 0) { if (pa_ctx) { pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_ctx = NULL; } if (pa_ml) { pa_mainloop_free(pa_ml); pa_ml = NULL; } return ERR_CANT_OPEN; } Error err = init_device(); if (err == OK) { mutex = Mutex::create(); thread = Thread::create(AudioDriverPulseAudio::thread_func, this); } return OK; }
static int pa_get_devicelist(AudioDeviceInfoList& input) { pa_mainloop *pa_ml; pa_mainloop_api *pa_mlapi; pa_operation *pa_op; pa_context *pa_ctx; int state = 0; int pa_ready = 0; pa_ml = pa_mainloop_new(); pa_mlapi = pa_mainloop_get_api(pa_ml); pa_ctx = pa_context_new(pa_mlapi, "USBqemu-devicelist"); pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL); pa_context_set_state_callback(pa_ctx, pa_context_state_cb, &pa_ready); for (;;) { if (pa_ready == 0) { pa_mainloop_iterate(pa_ml, 1, NULL); continue; } // Connection failed if (pa_ready == 2) { pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); return -1; } switch (state) { case 0: pa_op = pa_context_get_source_info_list(pa_ctx, pa_sourcelist_cb, &input); state++; break; case 1: if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE) { pa_operation_unref(pa_op); pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); return 0; } break; default: return -1; } pa_mainloop_iterate(pa_ml, 1, NULL); } }
/* * Public API. */ xmms_pulse * xmms_pulse_backend_new (const char *server, const char *name, int *rerror) { xmms_pulse *p; int error = PA_ERR_INTERNAL; if (server && !*server) { if (rerror) *rerror = PA_ERR_INVALID; return NULL; } p = g_new0 (xmms_pulse, 1); if (!p) return NULL; p->volume = 100; p->mainloop = pa_threaded_mainloop_new (); if (!p->mainloop) goto fail; p->context = pa_context_new (pa_threaded_mainloop_get_api (p->mainloop), name); if (!p->context) goto fail; pa_context_set_state_callback (p->context, context_state_cb, p); if (pa_context_connect (p->context, server, 0, NULL) < 0) { error = pa_context_errno (p->context); goto fail; } pa_threaded_mainloop_lock (p->mainloop); if (pa_threaded_mainloop_start (p->mainloop) < 0) goto unlock_and_fail; /* Wait until the context is ready */ pa_threaded_mainloop_wait (p->mainloop); if (pa_context_get_state (p->context) != PA_CONTEXT_READY) { error = pa_context_errno (p->context); goto unlock_and_fail; } pa_threaded_mainloop_unlock (p->mainloop); return p; unlock_and_fail: pa_threaded_mainloop_unlock (p->mainloop); fail: if (rerror) *rerror = error; xmms_pulse_backend_free (p); return NULL; }
JNIEXPORT jlong JNICALL Java_com_harrcharr_pulse_PulseContext_JNICreate( JNIEnv *jenv, jclass jcls, pa_threaded_mainloop *m) { dlog(0, "%d", m); pa_mainloop_api *api = pa_threaded_mainloop_get_api(m); pa_context *c = pa_context_new(api, "primary"); return c; }
static void init_pulse_context(){ if (context==NULL){ pa_loop=pa_threaded_mainloop_new(); context=pa_context_new(pa_threaded_mainloop_get_api(pa_loop),NULL); pa_context_set_state_callback(context,state_notify,NULL); pa_context_connect(context,NULL,0,NULL); pa_threaded_mainloop_start(pa_loop); atexit(uninit_pulse_context); } }
bool PulseAudio::init(bool) { pa_ml = pa_mainloop_new(); pa_mainloop_api* pa_mlapi = pa_mainloop_get_api(pa_ml); pa_context* pa_ctx = pa_context_new(pa_mlapi, "MuseScore"); if (pa_context_connect(pa_ctx, NULL, pa_context_flags_t(0), NULL) != 0) qDebug("PulseAudio Context Connect Failed with Error: %s", pa_strerror(pa_context_errno(pa_ctx))); int pa_ready = 0; pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready); while (pa_ready == 0) pa_mainloop_iterate(pa_ml, 1, NULL); if (pa_ready == 2) return false; ss.rate = _sampleRate; ss.channels = 2; ss.format = PA_SAMPLE_FLOAT32LE; pa_stream* playstream = pa_stream_new(pa_ctx, "Playback", &ss, NULL); if (!playstream) { qDebug("pa_stream_new failed"); return false; } pa_stream_set_write_callback(playstream, paCallback, this); bufattr.fragsize = (uint32_t)-1; bufattr.maxlength = FRAMES * 2 * sizeof(float); bufattr.minreq = FRAMES * 1 * sizeof(float); // pa_usec_to_bytes(0, &ss); bufattr.prebuf = (uint32_t)-1; bufattr.tlength = bufattr.maxlength; int r = pa_stream_connect_playback(playstream, NULL, &bufattr, pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), NULL, NULL); if (r < 0) { // Old pulse audio servers don't like the ADJUST_LATENCY flag, so retry without that r = pa_stream_connect_playback(playstream, NULL, &bufattr, pa_stream_flags_t(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE), NULL, NULL); } if (r < 0) { qDebug("pa_stream_connect_playback failed"); pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); pa_ml = 0; return false; } return true; }
void PulseAudioSinksManager::retrieveSinks() { pa_mainloop_api *pa_mlapi; // Create a mainloop API and connection to the default server pa_ml.reset(pa_threaded_mainloop_new()); pa_mlapi = pa_threaded_mainloop_get_api(pa_ml.get()); pa_ctx.reset(pa_context_new(pa_mlapi, "QAudioSwitcher")); pa_context_set_state_callback(pa_ctx.get(), PulseAudioSinksManager::pulseAudioStateCallback, this); pa_context_connect(pa_ctx.get(), NULL, PA_CONTEXT_NOFAIL , NULL); pa_threaded_mainloop_start(pa_ml.get()); }
static void connect(void) { int r; ctxt = pa_context_new(pa_glib_mainloop_get_api(m), NULL); g_assert(ctxt); r = pa_context_connect(ctxt, NULL, PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL, NULL); g_assert(r == 0); pa_context_set_state_callback(ctxt, context_state_callback, NULL); }
WavegenClient::WavegenClient(std::string const& name) : name_(name) { paMainLoop_ = pa_threaded_mainloop_new(); pa_threaded_mainloop_set_name(paMainLoop_, name_.c_str()); pa_threaded_mainloop_start(paMainLoop_); paMainApi_ = pa_threaded_mainloop_get_api(paMainLoop_); paContext_ = pa_context_new(paMainApi_, name_.c_str()); pa_context_set_state_callback(paContext_, &WavegenClient::contextStateCallback, this); }
int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { rdpsndPulsePlugin* pulse; RDP_PLUGIN_DATA* data; pulse = xnew(rdpsndPulsePlugin); pulse->device.Open = rdpsnd_pulse_open; pulse->device.FormatSupported = rdpsnd_pulse_format_supported; pulse->device.SetFormat = rdpsnd_pulse_set_format; pulse->device.SetVolume = rdpsnd_pulse_set_volume; pulse->device.Play = rdpsnd_pulse_play; pulse->device.Start = rdpsnd_pulse_start; pulse->device.Close = rdpsnd_pulse_close; pulse->device.Free = rdpsnd_pulse_free; data = pEntryPoints->plugin_data; if (data && strcmp((char*)data->data[0], "pulse") == 0) { if(data->data[1] && strlen((char*)data->data[1]) > 0) pulse->device_name = xstrdup((char*)data->data[1]); else pulse->device_name = NULL; } pulse->dsp_context = freerdp_dsp_context_new(); pulse->mainloop = pa_threaded_mainloop_new(); if (!pulse->mainloop) { DEBUG_WARN("pa_threaded_mainloop_new failed"); rdpsnd_pulse_free((rdpsndDevicePlugin*)pulse); return 1; } pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); if (!pulse->context) { DEBUG_WARN("pa_context_new failed"); rdpsnd_pulse_free((rdpsndDevicePlugin*)pulse); return 1; } pa_context_set_state_callback(pulse->context, rdpsnd_pulse_context_state_callback, pulse); if (!rdpsnd_pulse_connect((rdpsndDevicePlugin*)pulse)) { DEBUG_WARN("rdpsnd_pulse_connect failed"); rdpsnd_pulse_free((rdpsndDevicePlugin*)pulse); return 1; } pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)pulse); return 0; }
int pa_get_devicelist(pa_devicelist_t *output) { pa_mainloop *pa_ml = NULL; pa_mainloop_api *pa_mlapi = NULL; pa_operation *pa_op = NULL; pa_context *pa_ctx = NULL; uint8_t state = 0; int pa_ready = 0; memset(output, 0, sizeof(pa_devicelist_t) * 16); if ( (pa_ml = pa_mainloop_new()) == NULL) return -1; if ( (pa_mlapi = pa_mainloop_get_api(pa_ml)) == NULL ) return -2; if ( (pa_ctx = pa_context_new(pa_mlapi, "test")) == NULL) return -3; pa_context_connect(pa_ctx, NULL, 0, NULL); pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready); while (1) { if (pa_ready == 0) { pa_mainloop_iterate(pa_ml, 1, NULL); continue; } if (pa_ready == 2) { pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); return -1; } switch (state) { case 0: pa_op = pa_context_get_sink_info_list(pa_ctx, pa_sinklist_cb, output); state++; break; case 1: if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE) { pa_operation_unref(pa_op); pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); return 0; } break; default: return -1; } pa_mainloop_iterate(pa_ml, 1, NULL); } }
bool PulseAudio::PulseInit() { m_pa_error = 0; m_pa_connected = 0; // create pulseaudio main loop and context // also register the async state callback which is called when the connection to the pa server has changed m_pa_ml = pa_mainloop_new(); m_pa_mlapi = pa_mainloop_get_api(m_pa_ml); m_pa_ctx = pa_context_new(m_pa_mlapi, "dolphin-emu"); m_pa_error = pa_context_connect(m_pa_ctx, nullptr, PA_CONTEXT_NOFLAGS, nullptr); pa_context_set_state_callback(m_pa_ctx, StateCallback, this); // wait until we're connected to the pulseaudio server while (m_pa_connected == 0 && m_pa_error >= 0) m_pa_error = pa_mainloop_iterate(m_pa_ml, 1, nullptr); if (m_pa_connected == 2 || m_pa_error < 0) { ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s", pa_strerror(m_pa_error)); return false; } // create a new audio stream with our sample format // also connect the callbacks for this stream pa_sample_spec ss; ss.format = PA_SAMPLE_S16LE; ss.channels = 2; ss.rate = m_mixer->GetSampleRate(); m_pa_s = pa_stream_new(m_pa_ctx, "Playback", &ss, nullptr); pa_stream_set_write_callback(m_pa_s, WriteCallback, this); pa_stream_set_underflow_callback(m_pa_s, UnderflowCallback, this); // connect this audio stream to the default audio playback // limit buffersize to reduce latency m_pa_ba.fragsize = -1; m_pa_ba.maxlength = -1; // max buffer, so also max latency m_pa_ba.minreq = -1; // don't read every byte, try to group them _a bit_ m_pa_ba.prebuf = -1; // start as early as possible m_pa_ba.tlength = BUFFER_SIZE; // designed latency, only change this flag for low latency output pa_stream_flags flags = pa_stream_flags(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE); m_pa_error = pa_stream_connect_playback(m_pa_s, nullptr, &m_pa_ba, flags, nullptr, nullptr); if (m_pa_error < 0) { ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s", pa_strerror(m_pa_error)); return false; } INFO_LOG(AUDIO, "Pulse successfully initialized"); return true; }
bool CPulseAE::Initialize() { m_Volume = g_settings.m_fVolumeLevel; if ((m_MainLoop = pa_threaded_mainloop_new()) == NULL) { CLog::Log(LOGERROR, "PulseAudio: Failed to allocate main loop"); return false; } if ((m_Context = pa_context_new(pa_threaded_mainloop_get_api(m_MainLoop), "XBMC")) == NULL) { CLog::Log(LOGERROR, "PulseAudio: Failed to allocate context"); return false; } pa_context_set_state_callback(m_Context, ContextStateCallback, m_MainLoop); if (pa_context_connect(m_Context, NULL, (pa_context_flags_t)0, NULL) < 0) { CLog::Log(LOGERROR, "PulseAudio: Failed to connect context"); return false; } pa_threaded_mainloop_lock(m_MainLoop); if (pa_threaded_mainloop_start(m_MainLoop) < 0) { CLog::Log(LOGERROR, "PulseAudio: Failed to start MainLoop"); pa_threaded_mainloop_unlock(m_MainLoop); return false; } /* Wait until the context is ready */ do { pa_threaded_mainloop_wait(m_MainLoop); CLog::Log(LOGDEBUG, "PulseAudio: Context %s", ContextStateToString(pa_context_get_state(m_Context))); } while (pa_context_get_state(m_Context) != PA_CONTEXT_READY && pa_context_get_state(m_Context) != PA_CONTEXT_FAILED); if (pa_context_get_state(m_Context) == PA_CONTEXT_FAILED) { CLog::Log(LOGERROR, "PulseAudio: Waited for the Context but it failed"); pa_threaded_mainloop_unlock(m_MainLoop); return false; } pa_threaded_mainloop_unlock(m_MainLoop); return true; }
int main(int argc, const char *argv[]) { pa_mainloop *pa_ml = NULL; pa_mainloop_api *pa_mlapi = NULL; pa_operation *pa_op = NULL; pa_context *pa_ctx = NULL; int pa_ready = 0; int state = 0; pa_ml = pa_mainloop_new(); pa_mlapi = pa_mainloop_get_api(pa_ml); pa_ctx = pa_context_new(pa_mlapi, "deepin"); pa_context_connect(pa_ctx, NULL, 0, NULL); pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready); for (;;) { if (pa_ready == 0) { pa_mainloop_iterate(pa_ml, 1, NULL); continue; } if (pa_ready == 2) { pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); return -1; } switch (state) { case 0: pa_op = pa_context_get_source_output_info_list(pa_ctx, pa_source_output_cb, NULL); state++; break; case 1: if (pa_operation_get_state(pa_op) == PA_OPERATION_DONE) { pa_operation_unref(pa_op); pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); return 0; } break; default: fprintf(stderr, "in state %d\n", state); return -1; } pa_mainloop_iterate(pa_ml, 1, NULL); } return 0; }
bool CAESinkPULSE::SetupContext(const char *host, pa_context **context, pa_threaded_mainloop **mainloop) { if ((*mainloop = pa_threaded_mainloop_new()) == NULL) { CLog::Log(LOGERROR, "PulseAudio: Failed to allocate main loop"); return false; } if (((*context) = pa_context_new(pa_threaded_mainloop_get_api(*mainloop), "Kodi")) == NULL) { CLog::Log(LOGERROR, "PulseAudio: Failed to allocate context"); return false; } pa_context_set_state_callback(*context, ContextStateCallback, *mainloop); if (pa_context_connect(*context, host, (pa_context_flags_t)0, NULL) < 0) { CLog::Log(LOGERROR, "PulseAudio: Failed to connect context"); return false; } pa_threaded_mainloop_lock(*mainloop); if (pa_threaded_mainloop_start(*mainloop) < 0) { CLog::Log(LOGERROR, "PulseAudio: Failed to start MainLoop"); pa_threaded_mainloop_unlock(*mainloop); return false; } /* Wait until the context is ready */ do { pa_threaded_mainloop_wait(*mainloop); CLog::Log(LOGDEBUG, "PulseAudio: Context %s", ContextStateToString(pa_context_get_state(*context))); } while (pa_context_get_state(*context) != PA_CONTEXT_READY && pa_context_get_state(*context) != PA_CONTEXT_FAILED); if (pa_context_get_state(*context) == PA_CONTEXT_FAILED) { CLog::Log(LOGERROR, "PulseAudio: Waited for the Context but it failed"); pa_threaded_mainloop_unlock(*mainloop); return false; } pa_threaded_mainloop_unlock(*mainloop); return true; }
bool PulseAudio::init(bool) { pa_ml = pa_mainloop_new(); pa_mainloop_api* pa_mlapi = pa_mainloop_get_api(pa_ml); pa_context* pa_ctx = pa_context_new(pa_mlapi, "MuseScore"); if (pa_context_connect(pa_ctx, NULL, pa_context_flags_t(0), NULL) != 0) { qDebug("PulseAudio Context Connect Failed with Error: %s", pa_strerror(pa_context_errno(pa_ctx))); return false; } int pa_ready = 0; pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready); while (pa_ready == 0) pa_mainloop_iterate(pa_ml, 1, NULL); if (pa_ready == 2) return false; ss.rate = _sampleRate; ss.channels = 2; ss.format = PA_SAMPLE_FLOAT32LE; pa_stream* playstream = pa_stream_new(pa_ctx, "Playback", &ss, NULL); if (!playstream) { qDebug("pa_stream_new failed: %s", pa_strerror(pa_context_errno(pa_ctx))); return false; } pa_stream_set_write_callback(playstream, paCallback, this); bufattr.fragsize = (uint32_t)-1; bufattr.maxlength = FRAMES * 2 * sizeof(float); bufattr.minreq = FRAMES * 1 * sizeof(float); // pa_usec_to_bytes(0, &ss); bufattr.prebuf = (uint32_t)-1; bufattr.tlength = bufattr.maxlength; int r = pa_stream_connect_playback(playstream, nullptr, &bufattr, PA_STREAM_NOFLAGS, nullptr, nullptr); if (r < 0) { qDebug("pa_stream_connect_playback failed"); pa_context_disconnect(pa_ctx); pa_context_unref(pa_ctx); pa_mainloop_free(pa_ml); pa_ml = 0; return false; } return true; }
void AudioSinksManager::start_pa_connection() { context = pa_context_new(pa_mainloop.get_api(), "chromecast-sink"); if (!context) { report_error("Couldn't create context" + get_pa_error()); return; } pa_context_set_state_callback(context, context_state_callback, this); pa_context_set_event_callback(context, context_event_callback, this); pa_context_set_subscribe_callback(context, context_subscription_callback, this); if (pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) { report_error("Couldn't connect to PulseAudio server" + get_pa_error()); return; } }
int main(int argc, char *argv[]) { struct stat st; off_t size; ssize_t nread; // We'll need these state variables to keep track of our requests int state = 0; int pa_ready = 0; if (argc != 2) { fprintf(stderr, "Usage: %s file\n", argv[0]); exit(1); } // slurp the whole file into buffer if ((fdin = open(argv[1], O_RDONLY)) == -1) { perror("open"); exit(1); } // Create a mainloop API and connection to the default server mainloop = pa_mainloop_new(); mainloop_api = pa_mainloop_get_api(mainloop); context = pa_context_new(mainloop_api, "test"); // This function connects to the pulse server pa_context_connect(context, NULL, 0, NULL); printf("Connecting\n"); // This function defines a callback so the server will tell us it's state. // Our callback will wait for the state to be ready. The callback will // modify the variable to 1 so we know when we have a connection and it's // ready. // If there's an error, the callback will set pa_ready to 2 pa_context_set_state_callback(context, state_cb, &pa_ready); if (pa_mainloop_run(mainloop, &ret) < 0) { printf("pa_mainloop_run() failed."); exit(1); // goto quit } }