static int privatemem_create(pa_shm *m, size_t size) { pa_assert(m); pa_assert(size > 0); m->type = PA_MEM_TYPE_PRIVATE; m->id = 0; m->size = size; m->do_unlink = false; m->fd = -1; #ifdef MAP_ANONYMOUS if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) { pa_log("mmap() failed: %s", pa_cstrerror(errno)); return -1; } #elif defined(HAVE_POSIX_MEMALIGN) { int r; if ((r = posix_memalign(&m->ptr, PA_PAGE_SIZE, size)) < 0) { pa_log("posix_memalign() failed: %s", pa_cstrerror(r)); return r; } } #else m->ptr = pa_xmalloc(m->size); #endif return 0; }
static void __pulseaudio_stream_write_cb(pa_stream *stream, size_t length, void *user_data) { sf_count_t read_length; short *data; SOUND_INFO *info = NULL; mmf_return_if_fail(user_data); info = (SOUND_INFO *)user_data; _mmcam_dbg_log("START"); data = pa_xmalloc(length); read_length = (sf_count_t)(length/pa_frame_size(&(info->sample_spec))); if ((sf_readf_short(info->infile, data, read_length)) != read_length) { pa_xfree(data); return; } pa_stream_write(stream, data, length, pa_xfree, 0, PA_SEEK_RELATIVE); info->sample_length -= length; if (info->sample_length <= 0) { pa_stream_set_write_callback(info->sample_stream, NULL, NULL); pa_stream_finish_upload(info->sample_stream); pa_threaded_mainloop_signal(info->pulse_mainloop, 0); _mmcam_dbg_log("send signal DONE"); } _mmcam_dbg_log("DONE read_length %d", read_length); }
pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, bool create, size_t size) { pa_auth_cookie *c; char *t; pa_assert(core); pa_assert(size > 0); t = pa_sprintf_malloc("auth-cookie%s%s", cn ? "@" : "", cn ? cn : ""); if ((c = pa_shared_get(core, t))) { pa_xfree(t); if (c->size != size) return NULL; return pa_auth_cookie_ref(c); } c = pa_xmalloc(PA_ALIGN(sizeof(pa_auth_cookie)) + size); PA_REFCNT_INIT(c); c->core = core; c->name = t; c->size = size; pa_assert_se(pa_shared_set(core, t, c) >= 0); if (pa_authkey_load(cn, create, (uint8_t*) c + PA_ALIGN(sizeof(pa_auth_cookie)), size) < 0) { pa_auth_cookie_unref(c); return NULL; } return c; }
FileReader::Status FileReader::writeToStream(pa_stream *p, size_t nbytes) { int frameSize = pa_frame_size(&m_s); int len = qMin(nbytes, (nbytes/frameSize) * nbytes); void *buff = pa_xmalloc(len); if (!buff) { qWarning() << "Failed to allocate buffer"; return StatusError; } sf_count_t read = sf_read_raw(m_file, buff, len); if (pa_stream_write(p, buff, read, pa_xfree, 0, PA_SEEK_RELATIVE) < 0) { qWarning() << "Failed to write to pulse audio stream"; pa_xfree(buff); return StatusError; } m_pos += read; if (m_pos == size()) { // Over. return StatusEof; } if (read != len) { return StatusError; } return StatusOk; }
/* Thread-safe getgrnam() function. Returned value should be freed using pa_getgrnam_free() when the caller is finished with the returned group data. API is the same as getgrnam(), errors are indicated by a NULL return; consult errno for the error cause (zero it before calling). */ struct group *pa_getgrnam_malloc(const char *name) { size_t buflen, getgr_buflen; int err; void *buf; void *getgr_buf; struct group *result = NULL; buflen = starting_getgr_buflen(); buf = pa_xmalloc(buflen); getgr_buflen = buflen - sizeof(struct group); getgr_buf = (char *)buf + sizeof(struct group); while ((err = getgrnam_r(name, (struct group *)buf, getgr_buf, getgr_buflen, &result)) == ERANGE) { if (expand_buffer_trashcontents(&buf, &buflen)) break; getgr_buflen = buflen - sizeof(struct group); getgr_buf = (char *)buf + sizeof(struct group); } if (err || !result) { result = NULL; if (buf) { pa_xfree(buf); buf = NULL; } } pa_assert(result == buf || result == NULL); return result; }
pa_fdsem *pa_fdsem_new(void) { pa_fdsem *f; f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data))); #ifdef HAVE_SYS_EVENTFD_H if ((f->efd = eventfd(0, EFD_CLOEXEC)) >= 0) f->fds[0] = f->fds[1] = -1; else #endif { if (pa_pipe_cloexec(f->fds) < 0) { pa_xfree(f); return NULL; } } f->data = (pa_fdsem_data*) ((uint8_t*) f + PA_ALIGN(sizeof(pa_fdsem))); pa_atomic_store(&f->data->waiting, 0); pa_atomic_store(&f->data->signalled, 0); pa_atomic_store(&f->data->in_pipe, 0); return f; }
/* Thread-safe getpwuid() function. Returned value should be freed using pa_getpwuid_free() when the caller is finished with the returned group data. API is the same as getpwuid(), errors are indicated by a NULL return; consult errno for the error cause (zero it before calling). */ struct passwd *pa_getpwuid_malloc(uid_t uid) { size_t buflen, getpw_buflen; int err; void *buf; void *getpw_buf; struct passwd *result = NULL; buflen = starting_getpw_buflen(); buf = pa_xmalloc(buflen); getpw_buflen = buflen - sizeof(struct passwd); getpw_buf = (char *)buf + sizeof(struct passwd); while ((err = getpwuid_r(uid, (struct passwd *)buf, getpw_buf, getpw_buflen, &result)) == ERANGE) { if (expand_buffer_trashcontents(&buf, &buflen)) break; getpw_buflen = buflen - sizeof(struct passwd); getpw_buf = (char *)buf + sizeof(struct passwd); } if (err || !result) { result = NULL; if (buf) { pa_xfree(buf); buf = NULL; } } pa_assert(result == buf || result == NULL); return result; }
char* pa_utf8_filter (const char *str) { char *new_str; pa_assert(str); new_str = pa_xmalloc(strlen(str) + 1); return utf8_validate(str, new_str); }
pa_auth_cookie *pa_auth_cookie_create(pa_core *core, const void *data, size_t size) { pa_auth_cookie *c; char *t; pa_assert(core); pa_assert(data); pa_assert(size > 0); t = pa_xstrdup("auth-cookie"); if ((c = pa_shared_get(core, t))) { pa_xfree(t); if (c->size != size) return NULL; return pa_auth_cookie_ref(c); } c = pa_xmalloc(PA_ALIGN(sizeof(pa_auth_cookie)) + size); PA_REFCNT_INIT(c); c->core = core; c->name = t; c->size = size; pa_assert_se(pa_shared_set(core, t, c) >= 0); memcpy((uint8_t *) c + PA_ALIGN(sizeof(pa_auth_cookie)), data, size); return c; }
JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_pulseaudio_PA_cvolume_1new (JNIEnv *env, jclass clazz) { pa_cvolume *cv = pa_xmalloc(sizeof(pa_cvolume)); if (cv) cv = pa_cvolume_init(cv); return (intptr_t) cv; }
static void stream_request_cb(pa_stream *s, size_t length, void *userdata) { VLC_UNUSED( s ); aout_instance_t *p_aout = (aout_instance_t *)userdata; struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys; mtime_t next_date; assert(s); assert(p_sys); size_t buffer_size = p_sys->buffer_size; PULSE_DEBUG( "Pulse stream request %d", length); do { aout_buffer_t * p_buffer = NULL; if(p_sys->started) { pa_usec_t latency; int negative; if(pa_stream_get_latency(p_sys->stream, &latency, &negative)<0) { if (pa_context_errno(p_sys->context) != PA_ERR_NODATA) { msg_Err(p_aout, "pa_stream_get_latency() failed: %s", pa_strerror(pa_context_errno(p_sys->context))); } latency = 0; } PULSE_DEBUG( "Pulse stream request latency=%"PRId64"", latency); next_date = mdate() + latency; if(p_sys->start_date < next_date + AOUT_PTS_TOLERANCE ) { p_buffer = aout_OutputNextBuffer( p_aout, next_date, 0); } } if ( p_buffer != NULL ) { PULSE_DEBUG( "Pulse stream request write buffer %d", p_buffer->i_buffer); pa_stream_write(p_sys->stream, p_buffer->p_buffer, p_buffer->i_buffer, NULL, 0, PA_SEEK_RELATIVE); length -= p_buffer->i_buffer; aout_BufferFree( p_buffer ); } else { PULSE_DEBUG( "Pulse stream request write zeroes"); void *data = pa_xmalloc(buffer_size); bzero(data, buffer_size); pa_stream_write(p_sys->stream, data, buffer_size, pa_xfree, 0, PA_SEEK_RELATIVE); length -= buffer_size; } } while(length > buffer_size); pa_threaded_mainloop_signal(p_sys->mainloop, 0); }
static void client_ext_set_args(struct pa_client *client) { #if 0 char path[256]; char args[ARG_MAX]; int argc; char *argv[1024]; int fd, len; char *p, *e; int i, offs; snprintf(path, sizeof(path), "/proc/%d/cmdline", ext->pid); if ((fd = open(path, O_RDONLY)) < 0) { pa_log("can't obtain command line"); return; } for (;;) { if ((len = read(fd, args, sizeof(args)-1)) < 0) { if (errno == EINTR) continue; else return; } args[len] = '\0'; break; } for (e = (p = args) + len, argc = 0; argc < 1024 && p < e; argc++) { argv[argc] = p; while (*p++ && p < e) ; } p = pa_xmalloc((argc * sizeof(char *)) + len); memcpy(p, argv, (argc * sizeof(char *))); memcpy(p + (argc * sizeof(char *)), args, len); ext->argc = argc; ext->argv = (char **)p; offs = (p + (argc * sizeof(char *))) - args; for (i = 0; i < argc; i++) ext->argv[i] += offs; #endif }
JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_pulseaudio_PA_sample_1spec_1new (JNIEnv *env, jclass clazz, jint format, jint rate, jint channels) { pa_sample_spec *ss = pa_xmalloc(sizeof(pa_sample_spec)); if (ss) { ss->format = (pa_sample_format_t) format; ss->rate = (uint32_t) rate; ss->channels = (uint8_t) channels; } return (intptr_t) ss; }
/* Append up to l bytes of a string to the string buffer */ void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) { struct chunk *c; pa_assert(sb); pa_assert(t); if (!l) return; c = pa_xmalloc(PA_ALIGN(sizeof(struct chunk)) + l); c->length = l; memcpy(CHUNK_TO_TEXT(c), t, l); append(sb, c); }
static inline void extend(pa_tagstruct*t, size_t l) { pa_assert(t); pa_assert(t->type != PA_TAGSTRUCT_FIXED); if (t->length+l <= t->allocated) return; if (t->type == PA_TAGSTRUCT_DYNAMIC) t->data = pa_xrealloc(t->data, t->allocated = t->length + l + GROW_TAG_SIZE); else if (t->type == PA_TAGSTRUCT_APPENDED) { t->type = PA_TAGSTRUCT_DYNAMIC; t->data = pa_xmalloc(t->allocated = t->length + l + GROW_TAG_SIZE); memcpy(t->data, t->per_type.appended, t->length); } }
static char* iconv_simple(const char *str, const char *to, const char *from) { char *new_str; size_t len, inlen; iconv_t cd; ICONV_CONST char *inbuf; char *outbuf; size_t res, inbytes, outbytes; pa_assert(str); pa_assert(to); pa_assert(from); cd = iconv_open(to, from); if (cd == (iconv_t)-1) return NULL; inlen = len = strlen(str) + 1; new_str = pa_xmalloc(len); for (;;) { inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */ inbytes = inlen; outbuf = new_str; outbytes = len; res = iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes); if (res != (size_t)-1) break; if (errno != E2BIG) { pa_xfree(new_str); new_str = NULL; break; } pa_assert(inbytes != 0); len += inbytes; new_str = pa_xrealloc(new_str, len); } iconv_close(cd); return new_str; }
JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_pulseaudio_PA_buffer_1attr_1new (JNIEnv *env, jclass clazz, jint maxlength, jint tlength, jint prebuf, jint minreq, jint fragsize) { pa_buffer_attr *attr = pa_xmalloc(sizeof(pa_buffer_attr)); if (attr) { attr->maxlength = (uint32_t) maxlength; attr->tlength = (uint32_t) tlength; attr->prebuf = (uint32_t) prebuf; attr->minreq = (uint32_t) minreq; attr->fragsize = (uint32_t) fragsize; } return (intptr_t) attr; }
/** * Pulseaudio callback when new data is available. */ static void stream_read_callback (pa_stream * s, size_t length, void *userdata) { const void *data; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %u/%u bytes of PCM data\n", length, pcm_length); GNUNET_assert (NULL != s); GNUNET_assert (length > 0); if (stdio_event) mainloop_api->io_enable (stdio_event, PA_IO_EVENT_OUTPUT); if (pa_stream_peek (s, (const void **) &data, &length) < 0) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("pa_stream_peek() failed: %s\n"), pa_strerror (pa_context_errno (context))); quit (1); return; } GNUNET_assert (NULL != data); GNUNET_assert (length > 0); if (NULL != transmit_buffer) { transmit_buffer = pa_xrealloc (transmit_buffer, transmit_buffer_length + length); memcpy (&transmit_buffer[transmit_buffer_length], data, length); transmit_buffer_length += length; } else { transmit_buffer = pa_xmalloc (length); memcpy (transmit_buffer, data, length); transmit_buffer_length = length; transmit_buffer_index = 0; } pa_stream_drop (s); packetizer (); }
static ALuint PulseProc(ALvoid *param) { ALCdevice *Device = param; pulse_data *data = Device->ExtraData; ssize_t len; SetRTPriority(); pa_threaded_mainloop_lock(data->loop); do { len = (Device->Connected ? pa_stream_writable_size(data->stream) : 0); len -= len%(Device->UpdateSize*data->frame_size); if(len == 0) { pa_threaded_mainloop_wait(data->loop); continue; } while(len > 0) { size_t newlen = len; void *buf; pa_free_cb_t free_func = NULL; #if PA_CHECK_VERSION(0,9,16) if(!pa_stream_begin_write || pa_stream_begin_write(data->stream, &buf, &newlen) < 0) #endif { buf = pa_xmalloc(newlen); free_func = pa_xfree; } pa_threaded_mainloop_unlock(data->loop); aluMixData(Device, buf, newlen/data->frame_size); pa_threaded_mainloop_lock(data->loop); pa_stream_write(data->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE); len -= newlen; } } while(Device->Connected && !data->killNow); pa_threaded_mainloop_unlock(data->loop); return 0; }
static void preload_stream_write_cb(pa_stream *stream, size_t length, void *user_data) { struct play_feedback_data *pfd = user_data; void *buffer; ssize_t bread; buffer = pa_xmalloc(pfd->sample_length); bread = read(pfd->fd, buffer, pfd->sample_length); pfd->stream_written += bread; pa_stream_write(stream, buffer, bread, pa_xfree, 0, PA_SEEK_RELATIVE); if (pfd->stream_written == pfd->sample_length) { pa_stream_set_write_callback(stream, NULL, NULL); pa_stream_finish_upload(stream); } }
static ALCboolean pulse_open(ALCdevice *device, const ALCchar *device_name) //{{{ { pulse_data *data = pa_xmalloc(sizeof(pulse_data)); memset(data, 0, sizeof(*data)); if(!(data->loop = pa_threaded_mainloop_new())) { ERR("pa_threaded_mainloop_new() failed!\n"); goto out; } if(pa_threaded_mainloop_start(data->loop) < 0) { ERR("pa_threaded_mainloop_start() failed\n"); goto out; } pa_threaded_mainloop_lock(data->loop); device->ExtraData = data; data->context = connect_context(data->loop, AL_FALSE); if(!data->context) { pa_threaded_mainloop_unlock(data->loop); goto out; } pa_context_set_state_callback(data->context, context_state_callback2, device); device->szDeviceName = strdup(device_name); pa_threaded_mainloop_unlock(data->loop); return ALC_TRUE; out: if(data->loop) { pa_threaded_mainloop_stop(data->loop); pa_threaded_mainloop_free(data->loop); } device->ExtraData = NULL; pa_xfree(data); return ALC_FALSE; } //}}}
pa_packet* pa_packet_new(size_t length) { pa_packet *p; pa_assert(length > 0); if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(packets)))) p = pa_xnew(pa_packet, 1); PA_REFCNT_INIT(p); p->length = length; if (length > MAX_APPENDED_SIZE) { p->data = pa_xmalloc(length); p->type = PA_PACKET_DYNAMIC; } else { p->data = p->per_type.appended; p->type = PA_PACKET_APPENDED; } return p; }
/* New data on STDIN **/ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { size_t l, w = 0; ssize_t r; pa_assert(a == mainloop_api); pa_assert(e); pa_assert(stdio_event == e); if (buffer) { mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL); return; } if (!stream || pa_stream_get_state(stream) != PA_STREAM_READY || !(l = w = pa_stream_writable_size(stream))) l = 4096; buffer = pa_xmalloc(l); if ((r = read(fd, buffer, l)) <= 0) { if (r == 0) { if (verbose) pa_log(_("Got EOF.")); start_drain(); } else { pa_log(_("read() failed: %s"), strerror(errno)); quit(1); } mainloop_api->io_free(stdio_event); stdio_event = NULL; return; } buffer_length = (uint32_t) r; buffer_index = 0; if (w) do_stream_write(w); }
static char *get_cpuinfo(void) { char *cpuinfo; int n, fd; cpuinfo = pa_xmalloc(MAX_BUFFER); if ((fd = pa_open_cloexec("/proc/cpuinfo", O_RDONLY, 0)) < 0) { pa_xfree(cpuinfo); return NULL; } if ((n = pa_read(fd, cpuinfo, MAX_BUFFER-1, NULL)) < 0) { pa_xfree(cpuinfo); pa_close(fd); return NULL; } cpuinfo[n] = 0; pa_close(fd); return cpuinfo; }
/* Make a C string from the string buffer. The caller has to free * string with pa_xfree(). */ char *pa_strbuf_to_string(pa_strbuf *sb) { char *t, *e; struct chunk *c; pa_assert(sb); e = t = pa_xmalloc(sb->length+1); for (c = sb->head; c; c = c->next) { pa_assert((size_t) (e-t) <= sb->length); memcpy(e, CHUNK_TO_TEXT(c), c->length); e += c->length; } /* Trailing NUL */ *e = 0; pa_assert(e == t+sb->length); return t; }
/** * OPUS init */ static void opus_init () { int err; pcm_length = FRAME_SIZE * CHANNELS * sizeof (float); pcm_buffer = pa_xmalloc (pcm_length); opus_data = GNUNET_malloc (MAX_PAYLOAD_BYTES); enc = opus_encoder_create (SAMPLING_RATE, CHANNELS, CONV_OPUS_APP_TYPE, &err); opus_encoder_ctl (enc, OPUS_SET_PACKET_LOSS_PERC (CONV_OPUS_PACKET_LOSS_PERCENTAGE)); opus_encoder_ctl (enc, OPUS_SET_COMPLEXITY (CONV_OPUS_ENCODING_COMPLEXITY)); opus_encoder_ctl (enc, OPUS_SET_INBAND_FEC (CONV_OPUS_INBAND_FEC)); opus_encoder_ctl (enc, OPUS_SET_SIGNAL (CONV_OPUS_SIGNAL)); }
/* Given a memory allocation (*bufptr) and its length (*buflenptr), double the size of the allocation, updating the given buffer and length arguments. This function should be used in conjunction with the pa_*alloc and pa_xfree functions. Unlike realloc(), this function does *not* retain the original buffer's contents. Returns 0 on success, nonzero on error. The error cause is indicated by errno. */ static int expand_buffer_trashcontents(void **bufptr, size_t *buflenptr) { size_t newlen; if (!bufptr || !*bufptr || !buflenptr) { errno = EINVAL; return -1; } newlen = *buflenptr * 2; if (newlen < *buflenptr) { errno = EOVERFLOW; return -1; } /* Don't bother retaining memory contents; free & alloc anew */ pa_xfree(*bufptr); *bufptr = pa_xmalloc(newlen); *buflenptr = newlen; return 0; }
/* Write some data to the stream */ static void do_stream_write(size_t length) { size_t l; assert(length); printf("do stream write: Writing %d to stream\n", length); if (!buffer || !buffer_length) { buffer = pa_xmalloc(length); buffer_length = length; buffer_index = 0; //printf(" return without writing\n"); //return; } while (buffer_length > 0) { l = read(fdin, buffer + buffer_index, buffer_length); if (l <= 0) { start_drain(); return; } if (pa_stream_write(stream, (uint8_t*) buffer + buffer_index, l, NULL, 0, PA_SEEK_RELATIVE) < 0) { printf("pa_stream_write() failed: %s", pa_strerror(pa_context_errno(context))); exit(1); return; } buffer_length -= l; buffer_index += l; if (!buffer_length) { pa_xfree(buffer); buffer = NULL; buffer_index = buffer_length = 0; } } }
/* No lock necessary */ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { pa_memblock *b; pa_assert(p); pa_assert(length); /* If -1 is passed as length we choose the size for the caller. */ if (length == (size_t) -1) length = pa_mempool_block_size_max(p); b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length); PA_REFCNT_INIT(b); b->pool = p; b->type = PA_MEMBLOCK_APPENDED; b->read_only = b->is_silence = false; pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock))); b->length = length; pa_atomic_store(&b->n_acquired, 0); pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; }
/* This is called whenever new data may is available */ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) { pa_assert(s); pa_assert(length > 0); if (raw) { pa_assert(!sndfile); if (stdio_event) mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT); while (pa_stream_readable_size(s) > 0) { const void *data; if (pa_stream_peek(s, &data, &length) < 0) { pa_log(_("pa_stream_peek() failed: %s"), pa_strerror(pa_context_errno(context))); quit(1); return; } pa_assert(data); pa_assert(length > 0); if (buffer) { buffer = pa_xrealloc(buffer, buffer_length + length); memcpy((uint8_t*) buffer + buffer_length, data, length); buffer_length += length; } else { buffer = pa_xmalloc(length); memcpy(buffer, data, length); buffer_length = length; buffer_index = 0; } pa_stream_drop(s); } } else { pa_assert(sndfile); while (pa_stream_readable_size(s) > 0) { sf_count_t bytes; const void *data; if (pa_stream_peek(s, &data, &length) < 0) { pa_log(_("pa_stream_peek() failed: %s"), pa_strerror(pa_context_errno(context))); quit(1); return; } pa_assert(data); pa_assert(length > 0); if (writef_function) { size_t k = pa_frame_size(&sample_spec); if ((bytes = writef_function(sndfile, data, (sf_count_t) (length/k))) > 0) bytes *= (sf_count_t) k; } else bytes = sf_write_raw(sndfile, data, (sf_count_t) length); if (bytes < (sf_count_t) length) quit(1); pa_stream_drop(s); } } }