/** Destroy libao driver */ static void uninit(int immed) { if (stream && !immed) { pa_threaded_mainloop_lock(mainloop); waitop(pa_stream_drain(stream, success_cb, NULL)); } if (mainloop) pa_threaded_mainloop_stop(mainloop); if (stream) { pa_stream_disconnect(stream); pa_stream_unref(stream); stream = NULL; } if (context) { pa_context_disconnect(context); pa_context_unref(context); context = NULL; } if (mainloop) { pa_threaded_mainloop_free(mainloop); mainloop = NULL; } }
static void pulse_output_close(struct audio_output *ao) { struct pulse_output *po = (struct pulse_output *)ao; pa_operation *o; assert(po->mainloop != NULL); pa_threaded_mainloop_lock(po->mainloop); if (pa_stream_get_state(po->stream) == PA_STREAM_READY) { o = pa_stream_drain(po->stream, pulse_output_stream_success_cb, po); if (o == NULL) { g_warning("pa_stream_drain() has failed: %s", pa_strerror(pa_context_errno(po->context))); } else pulse_wait_for_operation(po->mainloop, o); } pulse_output_delete_stream(po); if (po->context != NULL && pa_context_get_state(po->context) != PA_CONTEXT_READY) pulse_output_delete_context(po); pa_threaded_mainloop_unlock(po->mainloop); }
/***************************************************************************** * Close: close the audio device *****************************************************************************/ static void Close ( vlc_object_t *p_this ) { aout_instance_t *p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys = p_aout->output.p_sys; msg_Dbg(p_aout, "Pulse Close"); if(p_sys->stream) { pa_threaded_mainloop_lock(p_sys->mainloop); pa_stream_set_write_callback(p_sys->stream, NULL, NULL); pa_operation *o; o = pa_stream_flush(p_sys->stream, success_cb, p_aout); while( pa_operation_get_state(o) == PA_OPERATION_RUNNING ) pa_threaded_mainloop_wait(p_sys->mainloop); pa_operation_unref(o); o = pa_stream_drain(p_sys->stream, success_cb, p_aout); while( pa_operation_get_state(o) == PA_OPERATION_RUNNING ) pa_threaded_mainloop_wait(p_sys->mainloop); pa_operation_unref(o); pa_threaded_mainloop_unlock(p_sys->mainloop); } uninit(p_aout); }
static void uninit(struct ao *ao, bool cut_audio) { struct priv *priv = ao->priv; if (priv->stream && !cut_audio) { pa_threaded_mainloop_lock(priv->mainloop); waitop(priv, pa_stream_drain(priv->stream, success_cb, ao)); } if (priv->mainloop) pa_threaded_mainloop_stop(priv->mainloop); if (priv->stream) { pa_stream_disconnect(priv->stream); pa_stream_unref(priv->stream); priv->stream = NULL; } if (priv->context) { pa_context_disconnect(priv->context); pa_context_unref(priv->context); priv->context = NULL; } if (priv->mainloop) { pa_threaded_mainloop_free(priv->mainloop); priv->mainloop = NULL; } }
/// @brief Called by PA to request more data (and other things?) void PulseAudioPlayer::pa_stream_write(pa_stream *p, size_t length, PulseAudioPlayer *thread) { if (!thread->is_playing) return; if (thread->cur_frame >= thread->end_frame + thread->provider->GetSampleRate()) { // More than a second past end of stream thread->is_playing = false; pa_operation *op = pa_stream_drain(p, NULL, NULL); pa_operation_unref(op); //printf("PA requested more buffer, but no more to stream\n"); return; } else if (thread->cur_frame >= thread->end_frame) { // Past end of stream, but not a full second, add some silence void *buf = calloc(length, 1); ::pa_stream_write(p, buf, length, free, 0, PA_SEEK_RELATIVE); thread->cur_frame += length / thread->bpf; return; } //printf("PA requested more buffer, %lu bytes\n", (unsigned long)length); unsigned long bpf = thread->bpf; unsigned long frames = length / thread->bpf; unsigned long maxframes = thread->end_frame - thread->cur_frame; if (frames > maxframes) frames = maxframes; //printf("Handing it %lu frames\n", frames); void *buf = malloc(frames * bpf); thread->provider->GetAudioWithVolume(buf, thread->cur_frame, frames, thread->volume); ::pa_stream_write(p, buf, frames*bpf, free, 0, PA_SEEK_RELATIVE); thread->cur_frame += frames; }
int pa_simple_drain(pa_simple *p, int *rerror) { pa_operation *o = NULL; pa_assert(p); CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1); pa_threaded_mainloop_lock(p->mainloop); CHECK_DEAD_GOTO(p, rerror, unlock_and_fail); o = pa_stream_drain(p->stream, success_cb, p); CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail); p->operation_success = 0; while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) { pa_threaded_mainloop_wait(p->mainloop); CHECK_DEAD_GOTO(p, rerror, unlock_and_fail); } CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail); pa_operation_unref(o); pa_threaded_mainloop_unlock(p->mainloop); return 0; unlock_and_fail: if (o) { pa_operation_cancel(o); pa_operation_unref(o); } pa_threaded_mainloop_unlock(p->mainloop); return -1; }
/***************************************************************************** * Close: close the audio device *****************************************************************************/ static void Close ( vlc_object_t *p_this ) { aout_instance_t *p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys = p_aout->output.p_sys; msg_Dbg(p_aout, "Pulse Close"); if(p_sys->stream){ pa_operation *o; pa_threaded_mainloop_lock(p_sys->mainloop); pa_stream_set_write_callback(p_sys->stream, NULL, NULL); if((o = pa_stream_drain(p_sys->stream, success_cb, p_aout))){ while (pa_operation_get_state(o) != PA_OPERATION_DONE) { CHECK_DEAD_GOTO(fail); pa_threaded_mainloop_wait(p_sys->mainloop); } fail: pa_operation_unref(o); } pa_threaded_mainloop_unlock(p_sys->mainloop); } uninit(p_aout); }
static void pulse_drain(void) { pa_operation *o = NULL; int success = 0; CHECK_CONNECTED(); pa_threaded_mainloop_lock(mainloop); CHECK_DEAD_GOTO(fail, 0); if (!(o = pa_stream_drain(stream, stream_success_cb, &success))) { AUDDBG("pa_stream_drain() failed: %s", pa_strerror(pa_context_errno(context))); goto fail; } while (pa_operation_get_state(o) != PA_OPERATION_DONE) { CHECK_DEAD_GOTO(fail, 1); pa_threaded_mainloop_wait(mainloop); } if (!success) AUDDBG("pa_stream_drain() failed: %s", pa_strerror(pa_context_errno(context))); fail: if (o) pa_operation_unref(o); pa_threaded_mainloop_unlock(mainloop); }
static void drain(struct ao *ao) { struct priv *priv = ao->priv; if (priv->stream) { pa_threaded_mainloop_lock(priv->mainloop); waitop(priv, pa_stream_drain(priv->stream, success_cb, ao)); } }
void PulseOutput::drain() { if (stream) { pa_operation * operation = pa_stream_drain(stream,nullptr,nullptr); while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) context->wait_plugin_events(); pa_operation_unref(operation); } }
void CAESinkPULSE::Drain() { if (!m_IsAllocated) return; pa_threaded_mainloop_lock(m_MainLoop); WaitForOperation(pa_stream_drain(m_Stream, NULL, NULL), m_MainLoop, "Drain"); pa_threaded_mainloop_unlock(m_MainLoop); }
/*drain stream function*/ void quisk_drain_cork_stream(struct sound_dev *dev) { pa_stream *s = dev->handle; pa_operation *o; if (!(o = pa_stream_drain(s, stream_drain_complete, NULL))) { printf("pa_stream_drain(): %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); exit(1); } pa_operation_unref(o); }
void AudioOutputPulseAudio::Drain(void) { AudioOutputBase::Drain(); pa_threaded_mainloop_lock(mainloop); pa_operation *op = pa_stream_drain(pstream, NULL, this); pa_threaded_mainloop_unlock(mainloop); if (op) pa_operation_unref(op); else VBERROR("Drain, stream drain failed"); }
void CPulseAEStream::Drain() { if (!m_Initialized) return; if (m_DrainOperation) return; pa_threaded_mainloop_lock(m_MainLoop); m_DrainOperation = pa_stream_drain(m_Stream, CPulseAEStream::StreamDrainComplete, this); pa_threaded_mainloop_unlock(m_MainLoop); }
/* Shutdown the application. This is called from the pulseaudio mainloop * thread in stream_write_cb() */ static void do_shutdown(_mbx_out out) { mbx_log_debug(MBX_LOG_AUDIO_OUTPUT, "Shutting down."); unset_all_callbacks(out); /* stream_drain_complete_cb will be called when drain is done */ pa_operation *o = pa_stream_drain(out->stream,stream_drain_complete_cb,out); if ( o == NULL ) { mbx_log_error(MBX_LOG_AUDIO_OUTPUT, "Failed to start pulseaudio stream drain: %s", pa_msg(out)); /* In case of error, we do our best and continue manually */ stream_drain_complete_cb(out->stream, 0, out); } pa_operation_unref(o); }
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_request_callback(pa_stream * s, size_t nbytes, void * u) { cubeb_stream * stm; void * buffer; size_t size; int r; long got; size_t towrite; size_t frame_size; stm = u; if (stm->shutdown) return; frame_size = pa_frame_size(&stm->sample_spec); assert(nbytes % frame_size == 0); towrite = nbytes; while (towrite) { size = towrite; r = pa_stream_begin_write(s, &buffer, &size); assert(r == 0); assert(size > 0); assert(size % frame_size == 0); got = stm->data_callback(stm, stm->user_ptr, buffer, size / frame_size); if (got < 0) { pa_stream_cancel_write(s); stm->shutdown = 1; return; } r = pa_stream_write(s, buffer, got * frame_size, NULL, 0, PA_SEEK_RELATIVE); assert(r == 0); if ((size_t) got < size / frame_size) { stm->draining = pa_stream_drain(s, stream_drain_success_callback, stm); stm->shutdown = 1; return; } towrite -= size; } assert(towrite == 0); }
static void rdpsnd_pulse_close(rdpsndDevicePlugin* device) { rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; if (!pulse->context || !pulse->stream) return; pa_threaded_mainloop_lock(pulse->mainloop); rdpsnd_pulse_wait_for_operation(pulse, pa_stream_drain(pulse->stream, rdpsnd_pulse_stream_success_callback, pulse)); pa_stream_disconnect(pulse->stream); pa_stream_unref(pulse->stream); pulse->stream = NULL; pa_threaded_mainloop_unlock(pulse->mainloop); }
static BOOL tsmf_pulse_close_stream(TSMFPulseAudioDevice *pulse) { if(!pulse->context || !pulse->stream) return FALSE; DEBUG_TSMF(""); pa_threaded_mainloop_lock(pulse->mainloop); pa_stream_set_write_callback(pulse->stream, NULL, NULL); tsmf_pulse_wait_for_operation(pulse, pa_stream_drain(pulse->stream, tsmf_pulse_stream_success_callback, pulse)); pa_stream_disconnect(pulse->stream); pa_stream_unref(pulse->stream); pulse->stream = NULL; pa_threaded_mainloop_unlock(pulse->mainloop); return TRUE; }
static int tsmf_pulse_close_stream(TSMFPulseAudioDevice * pulse) { if (!pulse->context || !pulse->stream) return 1; LLOGLN(0, ("tsmf_pulse_close_stream:")); pa_threaded_mainloop_lock(pulse->mainloop); pa_stream_set_write_callback(pulse->stream, NULL, NULL); tsmf_pulse_wait_for_operation(pulse, pa_stream_drain(pulse->stream, tsmf_pulse_stream_success_callback, pulse)); pa_stream_disconnect(pulse->stream); pa_stream_unref(pulse->stream); pulse->stream = NULL; pa_threaded_mainloop_unlock(pulse->mainloop); return 0; }
/* Start draining */ static void start_drain(void) { printf("Draining\n"); if (stream) { pa_operation *o; pa_stream_set_write_callback(stream, NULL, NULL); if (!(o = pa_stream_drain(stream, stream_drain_complete, NULL))) { //printf("pa_stream_drain(): %s", pa_strerror(pa_context_errno(context))); exit(1); return; } pa_operation_unref(o); } else exit(0); }
/* Start draining */ static void start_drain(void) { if (stream) { pa_operation *o; pa_stream_set_write_callback(stream, NULL, NULL); if (!(o = pa_stream_drain(stream, stream_drain_complete, NULL))) { pa_log(_("pa_stream_drain(): %s"), pa_strerror(pa_context_errno(context))); quit(1); return; } pa_operation_unref(o); } else quit(0); }
static int rdpsnd_pulse_close(rdpsndDevicePlugin * devplugin) { struct pulse_device_data * pulse_data; pulse_data = (struct pulse_device_data *) devplugin->device_data; if (!pulse_data->context || !pulse_data->stream) return 1; LLOGLN(0, ("rdpsnd_pulse_close:")); pa_threaded_mainloop_lock(pulse_data->mainloop); rdpsnd_pulse_wait_for_operation(devplugin, pa_stream_drain(pulse_data->stream, rdpsnd_pulse_stream_success_callback, devplugin)); pa_stream_disconnect(pulse_data->stream); pa_stream_unref(pulse_data->stream); pulse_data->stream = NULL; pa_threaded_mainloop_unlock(pulse_data->mainloop); return 0; }
/** Destroy libao driver */ static void uninit(int immed) { if (stream) { if (!immed && pa_stream_get_state(stream) == PA_STREAM_READY) wait_for_operation(pa_stream_drain(stream, NULL, NULL)); pa_stream_unref(stream); stream = NULL; } if (context) { pa_context_unref(context); context = NULL; } if (mainloop) { pa_mainloop_free(mainloop); mainloop = NULL; } }
static int drain(void) { pa_operation *o = NULL; int success = 0; int ret = PULSE_ERROR; ENTER(__FUNCTION__); CHECK_CONNECTED(ret); pa_threaded_mainloop_lock(mainloop); CHECK_DEAD_GOTO(fail, 0); SHOW_TIME("pa_stream_drain (call)"); if (!(o = pa_stream_drain(stream, stream_success_cb, &success))) { SHOW("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context))); goto fail; } SHOW_TIME("pa_threaded_mainloop_wait (call)"); while (pa_operation_get_state(o) != PA_OPERATION_DONE) { CHECK_DEAD_GOTO(fail, 1); pa_threaded_mainloop_wait(mainloop); } SHOW_TIME("pa_threaded_mainloop_wait (ret)"); if (!success) { SHOW("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context))); } else { ret = PULSE_OK; } fail: SHOW_TIME("pa_operation_unref (call)"); if (o) pa_operation_unref(o); pa_threaded_mainloop_unlock(mainloop); SHOW_TIME("drain (ret)"); return ret; }
static PyObject* PulseAudio_flush(output_PulseAudio *self, PyObject *args) { pa_operation *op; /*ensure outuput stream is still running*/ /*FIXME*/ pa_threaded_mainloop_lock(self->mainloop); /*uncork output stream, if necessary*/ if (pa_stream_is_corked(self->stream)) { op = pa_stream_cork( self->stream, 0, (pa_stream_success_cb_t)success_callback, self->mainloop); while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) { pa_threaded_mainloop_wait(self->mainloop); } pa_operation_unref(op); } /*drain output stream*/ op = pa_stream_drain( self->stream, (pa_stream_success_cb_t)success_callback, self->mainloop); while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) { pa_threaded_mainloop_wait(self->mainloop); } pa_operation_unref(op); pa_threaded_mainloop_unlock(self->mainloop); Py_INCREF(Py_None); return Py_None; }
gboolean xmms_pulse_backend_drain (xmms_pulse *p, int *rerror) { pa_operation *o = NULL; assert (p); if (!check_pulse_health (p, rerror)) goto unlock_and_fail; o = pa_stream_drain (p->stream, drain_result_cb, p); if (!o) { if (rerror) *rerror = pa_context_errno ((p)->context); goto unlock_and_fail; } p->operation_success = 0; while (pa_operation_get_state (o) != PA_OPERATION_DONE) { pa_threaded_mainloop_wait (p->mainloop); if (!check_pulse_health (p, rerror)) goto unlock_and_fail; } pa_operation_unref (o); o = NULL; if (!p->operation_success) { if (rerror) *rerror = pa_context_errno ((p)->context); goto unlock_and_fail; } return TRUE; unlock_and_fail: if (o) { pa_operation_cancel (o); pa_operation_unref (o); } return FALSE; }
static void _eventd_sound_pulseaudio_stream_state_callback(pa_stream *stream, gpointer user_data) { EventdSoundPulseaudioEventData *data = user_data; pa_stream_state_t state = pa_stream_get_state(stream); pa_operation *op; switch ( state ) { case PA_STREAM_FAILED: g_warning("Failed sample creation"); case PA_STREAM_TERMINATED: g_free(data); pa_stream_unref(stream); break; case PA_STREAM_READY: pa_stream_write(stream, data->data, data->length, g_free, 0, PA_SEEK_RELATIVE); op = pa_stream_drain(stream, _eventd_sound_pulseaudio_stream_drain_callback, NULL); if ( op != NULL ) pa_operation_unref(op); default: break; } }
static void swfdec_playback_stream_close (Stream *stream) { /* Pull it off of the active stream list. */ stream->sound->streams = g_list_remove (stream->sound->streams, stream); /* If we have created a PA stream, defer freeing until we drain it. */ if (stream->pa != NULL) { pa_operation *o; stream->no_more = 1; o = pa_stream_drain (stream->pa, stream_drain_complete, stream); if (o != NULL) { pa_operation_unref (o); return; } else { g_printerr("PA stream drain failed: %s\n", pa_strerror(pa_context_errno(stream->sound->pa))); } } g_object_unref (stream->audio); g_free (stream); }
/* * Callback to be called whenever new data may be written to the * playback data stream */ static void stream_write_callback(pa_stream *stream, size_t length, void *userdata) { struct context *ctx = userdata; struct audio_file *file; struct pa_operation *operation; size_t to_write, write_unit; int ret; assert(ctx); assert(ctx->context); assert((file = ctx->file)); assert(file->buf); assert(file->readi <= file->size); /* Writes must be in multiple of audio sample size * channel count */ write_unit = pa_frame_size(&file->spec); to_write = file->size - file->readi; to_write = min(length, to_write); to_write -= (to_write % write_unit); ret = pa_stream_write(stream, &file->buf[file->readi], to_write, NULL, 0, PA_SEEK_RELATIVE); if (ret < 0) { error("Failed writing audio data to stream: %s", pa_strerror(pa_context_errno(ctx->context))); goto fail; } file->readi += to_write; assert(file->readi <= file->size); /* * EOF! yay .. * * When reaching audio EOF, do not just close the application! * Doing so leads to losing playback of the latest portion of * the audio file (~ 0.5 seconds). Moreover, it produces ugly, * quite loud, sound cracks :-( * * The playback stream needs to be drained first. Thus close * the application, and the PA event loop, only after getting * a confirmation that the stream drain is complete. */ if ((file->size - file->readi) < write_unit) { out("Success! - Reached end of file"); out("Draining playback stream before exit"); /* Don't invoke our write callback again */ pa_stream_set_write_callback(stream, NULL, NULL); operation = pa_stream_drain(stream, stream_drain_complete, ctx); if (!operation) { error("Could not drain playback stream: %s", pa_strerror(pa_context_errno(ctx->context))); goto fail; } } return; fail: quit(ctx, EXIT_FAILURE); }