static gboolean check_pulse_health (xmms_pulse *p, int *rerror) { if (!p->context || pa_context_get_state (p->context) != PA_CONTEXT_READY || !p->stream || pa_stream_get_state (p->stream) != PA_STREAM_READY) { if ((p->context && pa_context_get_state (p->context) == PA_CONTEXT_FAILED) || (p->stream && pa_stream_get_state (p->stream) == PA_STREAM_FAILED)) { if (rerror) *(rerror) = pa_context_errno (p->context); } else if (rerror) *(rerror) = PA_ERR_BADSTATE; return FALSE; } return TRUE; }
static void inputStreamStateCallback(pa_stream *stream, void *userdata) { Q_UNUSED(userdata); pa_stream_state_t state = pa_stream_get_state(stream); #ifdef DEBUG_PULSE qDebug() << "Stream state: " << QPulseAudioInternal::stateToQString(state); #endif switch (state) { case PA_STREAM_CREATING: break; case PA_STREAM_READY: { #ifdef DEBUG_PULSE QPulseAudioInput *audioInput = static_cast<QPulseAudioInput*>(userdata); const pa_buffer_attr *buffer_attr = pa_stream_get_buffer_attr(stream); qDebug() << "*** maxlength: " << buffer_attr->maxlength; qDebug() << "*** prebuf: " << buffer_attr->prebuf; qDebug() << "*** fragsize: " << buffer_attr->fragsize; qDebug() << "*** minreq: " << buffer_attr->minreq; qDebug() << "*** tlength: " << buffer_attr->tlength; pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(audioInput->format()); qDebug() << "*** bytes_to_usec: " << pa_bytes_to_usec(buffer_attr->fragsize, &spec); #endif } break; case PA_STREAM_TERMINATED: break; case PA_STREAM_FAILED: default: qWarning() << QString("Stream error: %1").arg(pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); break; } }
static void rdpsnd_pulse_stream_state_callback(pa_stream * stream, void * userdata) { rdpsndDevicePlugin * devplugin; struct pulse_device_data * pulse_data; pa_stream_state_t state; devplugin = (rdpsndDevicePlugin *) userdata; pulse_data = (struct pulse_device_data *) devplugin->device_data; state = pa_stream_get_state(stream); switch (state) { case PA_STREAM_READY: LLOGLN(10, ("rdpsnd_pulse_stream_state_callback: PA_STREAM_READY")); pa_threaded_mainloop_signal (pulse_data->mainloop, 0); break; case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: LLOGLN(10, ("rdpsnd_pulse_stream_state_callback: state %d", (int)state)); pa_threaded_mainloop_signal (pulse_data->mainloop, 0); break; default: LLOGLN(10, ("rdpsnd_pulse_stream_state_callback: state %d", (int)state)); break; } }
/* * Stream state callbacks * * A 'stream' represents a data path between the client and server. * Sample streams include a playback stream, a recording stream, or * a file upload stream. * * A single client-server connection ('context') can have multiple * streams. Each stream can have its own latency and time fragment * requirements through PulseAudio buffer attributes. A stream can * be moved to a different sink during its lifetime. */ static void stream_state_callback(pa_stream *stream, void *userdata) { struct context *ctx = userdata; assert(ctx); assert(ctx->context); switch (pa_stream_get_state(stream)) { case PA_STREAM_CREATING: case PA_STREAM_TERMINATED: break; case PA_STREAM_READY: out("Playback stream succesfully created"); break; case PA_STREAM_FAILED: default: error("Playback stream error: %s", pa_strerror(pa_context_errno(ctx->context))); goto fail; } return; fail: quit(ctx, EXIT_FAILURE); }
float AudioDriverPulseAudio::get_latency() { if (latency == 0) { //only do this once since it's approximate anyway lock(); pa_usec_t palat = 0; if (pa_stream_get_state(pa_str) == PA_STREAM_READY) { int negative = 0; if (pa_stream_get_latency(pa_str, &palat, &negative) >= 0) { if (negative) { palat = 0; } } } if (palat > 0) { latency = double(palat) / 1000000.0; } unlock(); } return latency; }
bool AudioStream::isReady() { if (!audiostream_) return false; return pa_stream_get_state(audiostream_) == PA_STREAM_READY; }
void AudioSinksManager::InternalAudioSink::stream_state_change_callback(pa_stream* /*stream*/, void* userdata) { AudioSinksManager::InternalAudioSink* sink = static_cast<AudioSinksManager::InternalAudioSink*>(userdata); pa_stream_state_t state = pa_stream_get_state(sink->stream); const char* state_str = "Wrong impossible state"; switch (state) { case PA_STREAM_UNCONNECTED: state_str = "UNCONNECTED"; break; case PA_STREAM_CREATING: state_str = "CREATING"; break; case PA_STREAM_READY: state_str = "READY"; break; case PA_STREAM_FAILED: state_str = "FAILED"; break; case PA_STREAM_TERMINATED: state_str = "TERMINATED"; break; } sink->manager->logger->trace("(AudioSink '{}') Stream new state: {}", sink->name, state_str); switch (state) { case PA_STREAM_FAILED: sink->manager->logger->error("(AudioSink '{}') Stream failed: {}", sink->name, sink->manager->get_pa_error()); sink->state = State::DEAD; // FALLTHROUGH case PA_STREAM_TERMINATED: pa_stream_unref(sink->stream); sink->stream = nullptr; sink->stop_sink(); break; default: break; } }
int AudioOutputPulseAudio::GetBufferedOnSoundcard(void) const { pa_usec_t latency = 0; size_t buffered = 0; if (!pcontext || pa_context_get_state(pcontext) != PA_CONTEXT_READY) return 0; if (!pstream || pa_stream_get_state(pstream) != PA_STREAM_READY) return 0; const pa_buffer_attr *buf_attr = pa_stream_get_buffer_attr(pstream); size_t bfree = pa_stream_writable_size(pstream); buffered = buf_attr->tlength - bfree; pa_threaded_mainloop_lock(mainloop); while (pa_stream_get_latency(pstream, &latency, NULL) < 0) { if (pa_context_errno(pcontext) != PA_ERR_NODATA) { latency = 0; break; } pa_threaded_mainloop_wait(mainloop); } pa_threaded_mainloop_unlock(mainloop); return ((uint64_t)latency * samplerate * output_bytes_per_frame / 1000000) + buffered; }
static void tsmf_pulse_stream_state_callback(pa_stream * stream, void * userdata) { TSMFPulseAudioDevice * pulse = (TSMFPulseAudioDevice *) userdata; pa_stream_state_t state; state = pa_stream_get_state(stream); switch (state) { case PA_STREAM_READY: LLOGLN(10, ("tsmf_pulse_stream_state_callback: PA_STREAM_READY")); pa_threaded_mainloop_signal (pulse->mainloop, 0); break; case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: LLOGLN(10, ("tsmf_pulse_stream_state_callback: state %d", (int)state)); pa_threaded_mainloop_signal (pulse->mainloop, 0); break; default: LLOGLN(10, ("tsmf_pulse_stream_state_callback: state %d", (int)state)); break; } }
void AudioStream::stream_state_callback(pa_stream* s, void* /*user_data*/) { char str[PA_SAMPLE_SPEC_SNPRINT_MAX]; switch (pa_stream_get_state(s)) { case PA_STREAM_CREATING: DEBUG("Stream is creating..."); break; case PA_STREAM_TERMINATED: DEBUG("Stream is terminating..."); break; case PA_STREAM_READY: DEBUG("Stream successfully created, connected to %s", pa_stream_get_device_name(s)); DEBUG("maxlength %u", pa_stream_get_buffer_attr(s)->maxlength); DEBUG("tlength %u", pa_stream_get_buffer_attr(s)->tlength); DEBUG("prebuf %u", pa_stream_get_buffer_attr(s)->prebuf); DEBUG("minreq %u", pa_stream_get_buffer_attr(s)->minreq); DEBUG("fragsize %u", pa_stream_get_buffer_attr(s)->fragsize); DEBUG("samplespec %s", pa_sample_spec_snprint(str, sizeof(str), pa_stream_get_sample_spec(s))); break; case PA_STREAM_UNCONNECTED: DEBUG("Stream unconnected"); break; case PA_STREAM_FAILED: default: ERROR("Sink/Source doesn't exists: %s" , pa_strerror(pa_context_errno(pa_stream_get_context(s)))); break; } }
/** Play the specified data to the polypaudio server */ static int play(void* data, int len, int flags) { assert(stream && context); if (pa_stream_get_state(stream) != PA_STREAM_READY) return -1; if (!len) wait_for_operation(pa_stream_trigger(stream, NULL, NULL)); else pa_stream_write(stream, data, len, NULL, 0); wait_for_completion(); if (pa_stream_get_state(stream) != PA_STREAM_READY) return -1; return len; }
static void stream_state_cb(pa_stream *s, void *userdata) { switch (pa_stream_get_state(s)) { case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: pa_threaded_mainloop_signal(mainloop, 0); break; } }
void AudioOutputPulseAudio::WriteAudio(uchar *aubuf, int size) { QString fn_log_tag = "WriteAudio, "; pa_stream_state_t sstate = pa_stream_get_state(pstream); VBAUDIOTS(fn_log_tag + QString("writing %1 bytes").arg(size)); /* NB This "if" check can be replaced with PA_STREAM_IS_GOOD() in PulseAudio API from 0.9.11. As 0.9.10 is still widely used we use the more verbose version for now */ if (sstate == PA_STREAM_CREATING || sstate == PA_STREAM_READY) { int write_status = PA_ERR_INVALID; size_t to_write = size; unsigned char *buf_ptr = aubuf; pa_threaded_mainloop_lock(mainloop); while (to_write > 0) { write_status = 0; size_t writable = pa_stream_writable_size(pstream); if (writable > 0) { size_t write = min(to_write, writable); write_status = pa_stream_write(pstream, buf_ptr, write, NULL, 0, PA_SEEK_RELATIVE); if (0 != write_status) break; buf_ptr += write; to_write -= write; } else { pa_threaded_mainloop_wait(mainloop); } } pa_threaded_mainloop_unlock(mainloop); if (to_write > 0) { if (write_status != 0) VBERROR(fn_log_tag + QString("stream write failed: %1") .arg(write_status == PA_ERR_BADSTATE ? "PA_ERR_BADSTATE" : "PA_ERR_INVALID")); VBERROR(fn_log_tag + QString("short write, %1 of %2") .arg(size - to_write).arg(size)); } } else VBERROR(fn_log_tag + QString("stream state not good: %1") .arg(sstate,0,16)); }
// PulseAudio Event Callbacks //{{{ static void stream_state_callback(pa_stream *stream, void *pdata) //{{{ { pa_threaded_mainloop *loop = pdata; pa_stream_state_t state; state = pa_stream_get_state(stream); if(state == PA_STREAM_READY || !PA_STREAM_IS_GOOD(state)) pa_threaded_mainloop_signal(loop, 0); }//}}}
/** Return number of bytes that may be written to the server without blocking */ static int get_space(void) { uint32_t l; assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY); keep_alive(); l = pa_stream_writable_size(stream); return l; }
/** * Pulseaudio stream state callback */ static void stream_state_callback (pa_stream * s, void *userdata) { GNUNET_assert (NULL != s); switch (pa_stream_get_state (s)) { case PA_STREAM_CREATING: case PA_STREAM_TERMINATED: break; case PA_STREAM_READY: { const pa_buffer_attr *a; char cmt[PA_CHANNEL_MAP_SNPRINT_MAX]; char sst[PA_SAMPLE_SPEC_SNPRINT_MAX]; GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Stream successfully created.\n")); if (!(a = pa_stream_get_buffer_attr (s))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("pa_stream_get_buffer_attr() failed: %s\n"), pa_strerror (pa_context_errno (pa_stream_get_context (s)))); } else { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Buffer metrics: maxlength=%u, fragsize=%u\n"), a->maxlength, a->fragsize); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Using sample spec '%s', channel map '%s'.\n"), pa_sample_spec_snprint (sst, sizeof (sst), pa_stream_get_sample_spec (s)), pa_channel_map_snprint (cmt, sizeof (cmt), pa_stream_get_channel_map (s))); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Connected to device %s (%u, %ssuspended).\n"), pa_stream_get_device_name (s), pa_stream_get_device_index (s), pa_stream_is_suspended (s) ? "" : "not "); } break; case PA_STREAM_FAILED: default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Stream error: %s\n"), pa_strerror (pa_context_errno (pa_stream_get_context (s)))); quit (1); } }
static ALCenum pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) { pulse_data *data = device->ExtraData; ALCuint todo = samples * pa_frame_size(&data->spec); pa_threaded_mainloop_lock(data->loop); /* Capture is done in fragment-sized chunks, so we loop until we get all * that's available */ data->last_readable -= todo; while(todo > 0) { size_t rem = todo; if(data->cap_len == 0) { pa_stream_state_t state; state = pa_stream_get_state(data->stream); if(!PA_STREAM_IS_GOOD(state)) { aluHandleDisconnect(device); break; } if(pa_stream_peek(data->stream, &data->cap_store, &data->cap_len) < 0) { ERR("pa_stream_peek() failed: %s\n", pa_strerror(pa_context_errno(data->context))); aluHandleDisconnect(device); break; } data->cap_remain = data->cap_len; } if(rem > data->cap_remain) rem = data->cap_remain; memcpy(buffer, data->cap_store, rem); buffer = (ALbyte*)buffer + rem; todo -= rem; data->cap_store = (ALbyte*)data->cap_store + rem; data->cap_remain -= rem; if(data->cap_remain == 0) { pa_stream_drop(data->stream); data->cap_len = 0; } } if(todo > 0) memset(buffer, ((device->FmtType==DevFmtUByte) ? 0x80 : 0), todo); pa_threaded_mainloop_unlock(data->loop); return ALC_NO_ERROR; }
static void time_event_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) { if (stream && pa_stream_get_state(stream) == PA_STREAM_READY) { pa_operation *o; if (!(o = pa_stream_update_timing_info(stream, stream_update_timing_callback, NULL))) pa_log(_("pa_stream_update_timing_info() failed: %s"), pa_strerror(pa_context_errno(context))); else pa_operation_unref(o); } pa_context_rttime_restart(context, e, pa_rtclock_now() + TIME_EVENT_USEC); }
void PulseAudioSystem::stream_callback(pa_stream *s, void *userdata) { PulseAudioSystem *pas = reinterpret_cast<PulseAudioSystem *>(userdata); switch (pa_stream_get_state(s)) { case PA_STREAM_FAILED: qWarning("PulseAudio: Stream error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); break; default: break; } pas->wakeup(); }
static void stream_state_callback(pa_stream *s,void*){ fxmessage("[pulse] stream_state_callback:"); switch(pa_stream_get_state(s)) { case PA_STREAM_UNCONNECTED : fxmessage(" unconnected\n"); break; case PA_STREAM_CREATING : fxmessage(" creating\n"); break; case PA_STREAM_READY : fxmessage(" ready\n"); break; case PA_STREAM_FAILED : fxmessage(" failed\n"); break; case PA_STREAM_TERMINATED : fxmessage(" terminated\n"); break; default : fxmessage(" unknown\n"); break; } }
static int stream_wait(pa_stream *stream, pa_threaded_mainloop *mainloop) { pa_stream_state_t state; while ((state = pa_stream_get_state(stream)) != PA_STREAM_READY) { if (state == PA_STREAM_FAILED || state == PA_STREAM_TERMINATED) return -1; pa_threaded_mainloop_wait(mainloop); } return 0; }
/** Return the current latency in seconds */ static float get_delay(void) { pa_usec_t latency; assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY); /* latency = 0; */ /* wait_for_operation(pa_stream_get_latency(stream, latency_func, NULL)); */ /* pa_operation_unref(pa_stream_get_latency(stream, latency_func, NULL)); */ latency = pa_stream_get_interpolated_latency(stream, NULL); return (float) latency/1000000; }
static void stream_state_callback2(pa_stream *stream, void *pdata) //{{{ { ALCdevice *Device = pdata; pulse_data *data = Device->ExtraData; if(pa_stream_get_state(stream) == PA_STREAM_FAILED) { ERR("Received stream failure!\n"); aluHandleDisconnect(Device); } pa_threaded_mainloop_signal(data->loop, 0); }//}}}
static void stream_state_cb(pa_stream *s, void *userdata) { struct ao *ao = userdata; struct priv *priv = ao->priv; switch (pa_stream_get_state(s)) { case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: pa_threaded_mainloop_signal(priv->mainloop, 0); break; } }
/* * Create a new pulse audio stream and connect to it * * Return a negative value on error */ static int pulse_connect_stream(struct pulse_data *data) { pa_sample_spec spec; spec.format = data->format; spec.rate = data->samples_per_sec; spec.channels = get_audio_channels(data->speakers); if (!pa_sample_spec_valid(&spec)) { blog(LOG_ERROR, "pulse-input: Sample spec is not valid"); return -1; } data->bytes_per_frame = pa_frame_size(&spec); blog(LOG_DEBUG, "pulse-input: %u bytes per frame", (unsigned int) data->bytes_per_frame); pa_buffer_attr attr; attr.fragsize = get_buffer_size(data, 250); attr.maxlength = (uint32_t) -1; attr.minreq = (uint32_t) -1; attr.prebuf = (uint32_t) -1; attr.tlength = (uint32_t) -1; data->stream = pa_stream_new_with_proplist(data->context, obs_source_getname(data->source), &spec, NULL, data->props); if (!data->stream) { blog(LOG_ERROR, "pulse-input: Unable to create stream"); return -1; } pa_stream_flags_t flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY; if (pa_stream_connect_record(data->stream, NULL, &attr, flags) < 0) { blog(LOG_ERROR, "pulse-input: Unable to connect to stream"); return -1; } for (;;) { pulse_iterate(data); pa_stream_state_t state = pa_stream_get_state(data->stream); if (state == PA_STREAM_READY) { blog(LOG_DEBUG, "pulse-input: Stream ready"); break; } if (!PA_STREAM_IS_GOOD(state)) { blog(LOG_ERROR, "pulse-input: Stream connect failed"); return -1; } } return 0; }
static void stream_state_wait(cubeb_stream * stm, pa_stream_state_t target_state) { pa_threaded_mainloop_lock(stm->context->mainloop); for (;;) { pa_stream_state_t state = pa_stream_get_state(stm->stream); assert(PA_CONTEXT_IS_GOOD(state)); if (state == target_state) break; pa_threaded_mainloop_wait(stm->context->mainloop); } pa_threaded_mainloop_unlock(stm->context->mainloop); }
static void stream_state_callback(pa_stream *s, void *userdata) { pa_audio_mode_t *pam = (pa_audio_mode_t *)userdata; pa_operation *o; if(pa_stream_get_state(s) == PA_STREAM_FAILED) { pam->stream_error = pa_context_errno(pam->context); TRACE(TRACE_ERROR, "PA", "Stream failure: %s", pa_strerror(pam->stream_error)); } if(pa_stream_get_state(s) == PA_STREAM_READY && pam->muted) { o = pa_context_set_sink_input_mute(pam->context, pa_stream_get_index(pam->stream), pam->muted, NULL, NULL); if(o != NULL) pa_operation_unref(o); } pa_threaded_mainloop_signal(mainloop, 0); }
/** * Check if the stream is (already) connected, and waits for a signal * if not. The mainloop must be locked before calling this function. * * @return the current stream state */ static pa_stream_state_t pulse_output_check_stream(struct pulse_output *po) { pa_stream_state_t state = pa_stream_get_state(po->stream); assert(po->mainloop != NULL); switch (state) { case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: case PA_STREAM_UNCONNECTED: break; case PA_STREAM_CREATING: pa_threaded_mainloop_wait(po->mainloop); state = pa_stream_get_state(po->stream); break; } return state; }
void m1sdr_PlayStop(void) { #if 0 pa_operation *op; #endif #ifdef USE_SDL if (lnxdrv_apimode == 0) { SDL_PauseAudio(1); } #endif if (lnxdrv_apimode == 1) { // snd_pcm_pause(pHandle, 1); snd_pcm_drop(pHandle); } #if PULSE_USE_SIMPLE if ((lnxdrv_apimode == 3) && (my_simple)) { pa_simple_flush(my_simple, NULL); pa_simple_free(my_simple); my_simple = NULL; } #else #if 0 if (lnxdrv_apimode == 3) { op = pa_stream_drain(my_pa_stream, &pa_stream_drain_complete, NULL); if (op) { while (pa_operation_get_state(op) != PA_OPERATION_DONE) { if (pa_context_get_state(my_pa_context) != PA_CONTEXT_READY || pa_stream_get_state(my_pa_stream) != PA_STREAM_READY || pa_mainloop_iterate(my_pa_mainloop, 0, NULL) < 0) { pa_operation_cancel(op); break; } } } } #endif #endif waveLogStop(); oss_playing = 0; }
static void stream_state_callback(pa_stream *stream, void *userdata) { sa_stream_t* s = (sa_stream_t*)userdata; switch (pa_stream_get_state(stream)) { case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: pa_threaded_mainloop_signal(s->m, 0); break; case PA_STREAM_UNCONNECTED: case PA_STREAM_CREATING: break; } }