diff options
Diffstat (limited to 'src/pulse')
-rw-r--r-- | src/pulse/context.c | 17 | ||||
-rw-r--r-- | src/pulse/context.h | 22 | ||||
-rw-r--r-- | src/pulse/def.h | 10 | ||||
-rw-r--r-- | src/pulse/stream.c | 10 | ||||
-rw-r--r-- | src/pulse/stream.h | 17 |
5 files changed, 70 insertions, 6 deletions
diff --git a/src/pulse/context.c b/src/pulse/context.c index 7468d0a9..e33143d9 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -1488,6 +1488,7 @@ pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_even struct timeval tv; pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_assert(c->mainloop); if (usec == PA_USEC_INVALID) @@ -1502,8 +1503,10 @@ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec) struct timeval tv; pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_assert(c->mainloop); + if (usec == PA_USEC_INVALID) c->mainloop->time_restart(e, NULL); else { @@ -1511,3 +1514,17 @@ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec) c->mainloop->time_restart(e, &tv); } } + +size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss) { + size_t fs, mbs; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1); + + fs = ss ? pa_frame_size(ss) : 1; + mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs); + return PA_MAX(mbs, fs); +} diff --git a/src/pulse/context.h b/src/pulse/context.h index ecff58df..6ac8ee56 100644 --- a/src/pulse/context.h +++ b/src/pulse/context.h @@ -255,12 +255,28 @@ pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[] uint32_t pa_context_get_index(pa_context *s); /** Create a new timer event source for the specified time (wrapper - for mainloop->time_new). \since 0.9.16 */ + * for mainloop->time_new). \since 0.9.16 */ pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata); -/** Restart a running or expired timer event source (wrapper - for mainloop->time_restart). \since 0.9.16 */ + +/** Restart a running or expired timer event source (wrapper for + * mainloop->time_restart). \since 0.9.16 */ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec); +/* Return the optimal block size for passing around audio buffers. It + * is recommended to allocate buffers of the size returned here when + * writing audio data to playback streams, if the latency constraints + * permit this. It is not recommended writing larger blocks than this + * because usually they will then be split up internally into chunks + * of this size. It is not recommended writing smaller blocks than + * this (unless required due to latency demands) because this + * increases CPU usage. If ss is NULL you will be returned the + * byte-exact tile size. If you pass a valid ss, then the tile size + * will be rounded down to multiple of the frame size. This is + * supposed to be used in a construct such as + * pa_context_get_tile_size(pa_stream_get_context(s), + * pa_stream_get_sample_spec(ss)); \since 0.9.20 */ +size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss); + PA_C_DECL_END #endif diff --git a/src/pulse/def.h b/src/pulse/def.h index 5d0a0b4b..30a076d5 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -276,11 +276,18 @@ typedef enum pa_stream_flags { * whether to create the stream in muted or in unmuted * state. \since 0.9.15 */ - PA_STREAM_FAIL_ON_SUSPEND = 0x20000U + PA_STREAM_FAIL_ON_SUSPEND = 0x20000U, /**< If the sink/source this stream is connected to is suspended * during the creation of this stream, cause it to fail. If the * sink/source is being suspended during creation of this stream, * make sure this stream is terminated. \since 0.9.15 */ + + PA_STREAM_RELATIVE_VOLUME = 0x40000U, + /**< If a volume is passed when this stream is created, consider + * it relative to the sink's current volume, never as absolute + * device volume. If this is not specified the volume will be + * consider absolute when the sink is in flat volume mode, + * relative otherwise. \since 0.9.20 */ } pa_stream_flags_t; /** \cond fulldocs */ @@ -307,6 +314,7 @@ typedef enum pa_stream_flags { #define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND #define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED #define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND +#define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME /** \endcond */ diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 2bc2b1e4..29979625 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -1025,7 +1025,8 @@ static int create_stream( PA_STREAM_EARLY_REQUESTS| PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND| PA_STREAM_START_UNMUTED| - PA_STREAM_FAIL_ON_SUSPEND)), PA_ERR_INVALID); + PA_STREAM_FAIL_ON_SUSPEND| + PA_STREAM_RELATIVE_VOLUME)), PA_ERR_INVALID); PA_CHECK_VALIDITY(s->context, s->context->version >= 12 || !(flags & PA_STREAM_VARIABLE_RATE), PA_ERR_NOTSUPPORTED); PA_CHECK_VALIDITY(s->context, s->context->version >= 13 || !(flags & PA_STREAM_PEAK_DETECT), PA_ERR_NOTSUPPORTED); @@ -1158,6 +1159,13 @@ static int create_stream( pa_tagstruct_put_boolean(t, flags & PA_STREAM_FAIL_ON_SUSPEND); } + if (s->context->version >= 17) { + + if (s->direction == PA_STREAM_PLAYBACK) + pa_tagstruct_put_boolean(t, flags & PA_STREAM_RELATIVE_VOLUME); + + } + pa_pstream_send_tagstruct(s->context->pstream, t); pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL); diff --git a/src/pulse/stream.h b/src/pulse/stream.h index 2e8e71a0..bc54a118 100644 --- a/src/pulse/stream.h +++ b/src/pulse/stream.h @@ -401,7 +401,22 @@ int pa_stream_is_suspended(pa_stream *s); * not, and negative on error. \since 0.9.11 */ int pa_stream_is_corked(pa_stream *s); -/** Connect the stream to a sink */ +/** Connect the stream to a sink. It is strongly recommended to pass + * NULL in both dev and volume and not to set either + * PA_STREAM_START_MUTED nor PA_STREAM_START_UNMUTED -- unless these + * options are directly dependant on user input or configuration. If + * you follow this rule then the sound server will have the full + * flexibility to choose the device, volume and mute status + * automatically, based on server-side policies, heuristics and stored + * information from previous uses. Also the server may choose to + * reconfigure audio devices to make other sinks/sources or + * capabilities available to be able to accept the stream. Before + * 0.9.20 it was not defined whether the 'volume' parameter was + * interpreted relative to the sink's current volume or treated as + * absolute device volume. Since 0.9.20 it is an absolute volume when + * the sink is in flat volume mode, and relative otherwise, thus + * making sure the volume passed here has always the same semantics as + * the volume passed to pa_context_set_sink_input_volume(). */ int pa_stream_connect_playback( pa_stream *s /**< The stream to connect to a sink */, const char *dev /**< Name of the sink to connect to, or NULL for default */ , |