diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/map-file | 1 | ||||
| -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 | ||||
| -rw-r--r-- | src/pulsecore/memblock.c | 2 | ||||
| -rw-r--r-- | src/pulsecore/protocol-native.c | 29 | ||||
| -rw-r--r-- | src/pulsecore/svolume_mmx.c | 4 | ||||
| -rw-r--r-- | src/pulsecore/svolume_sse.c | 10 | ||||
| -rw-r--r-- | src/pulsecore/time-smoother.c | 7 | ||||
| -rw-r--r-- | src/utils/pactl.c | 22 | ||||
| -rw-r--r-- | src/utils/pasuspender.c | 2 | 
13 files changed, 131 insertions, 22 deletions
diff --git a/src/map-file b/src/map-file index 6f7bdace..50111224 100644 --- a/src/map-file +++ b/src/map-file @@ -66,6 +66,7 @@ pa_context_get_source_info_list;  pa_context_get_source_output_info;  pa_context_get_source_output_info_list;  pa_context_get_state; +pa_context_get_tile_size;  pa_context_is_local;  pa_context_is_pending;  pa_context_kill_client; 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 */ , diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index eac4a59b..f38b17c6 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -54,7 +54,7 @@   * stored in SHM and our OS does not commit the memory before we use   * it for the first time. */  #define PA_MEMPOOL_SLOTS_MAX 1024 -#define PA_MEMPOOL_SLOT_SIZE (128*1024) +#define PA_MEMPOOL_SLOT_SIZE (64*1024)  #define PA_MEMEXPORT_SLOTS_MAX 128 diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index d06dd4eb..bb29a196 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -1002,6 +1002,7 @@ static playback_stream* playback_stream_new(          pa_proplist *p,          pa_bool_t adjust_latency,          pa_bool_t early_requests, +        pa_bool_t relative_volume,          int *ret) {      playback_stream *s, *ssync; @@ -1044,13 +1045,21 @@ static playback_stream* playback_stream_new(      data.driver = __FILE__;      data.module = c->options->module;      data.client = c->client; -    data.sink = sink; +    if (sink) { +        data.sink = sink; +        data.save_sink = TRUE; +    }      pa_sink_input_new_data_set_sample_spec(&data, ss);      pa_sink_input_new_data_set_channel_map(&data, map); -    if (volume) +    if (volume) {          pa_sink_input_new_data_set_volume(&data, volume); -    if (muted_set) +        data.volume_is_absolute = !relative_volume; +        data.save_volume = TRUE; +    } +    if (muted_set) {          pa_sink_input_new_data_set_muted(&data, muted); +        data.save_muted = TRUE; +    }      data.sync_base = ssync ? ssync->sink_input : NULL;      data.flags = flags; @@ -1838,7 +1847,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u          early_requests = FALSE,          dont_inhibit_auto_suspend = FALSE,          muted_set = FALSE, -        fail_on_suspend = FALSE; +        fail_on_suspend = FALSE, +        relative_volume = FALSE;      pa_sink_input_flags_t flags = 0;      pa_proplist *p;      pa_bool_t volume_set = TRUE; @@ -1931,6 +1941,15 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u          }      } +    if (c->version >= 17) { + +        if (pa_tagstruct_get_boolean(t, &relative_volume) < 0) { +            protocol_error(c); +            pa_proplist_free(p); +            return; +        } +    } +      if (!pa_tagstruct_eof(t)) {          protocol_error(c);          pa_proplist_free(p); @@ -1970,7 +1989,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u       * flag. For older versions we synthesize it here */      muted_set = muted_set || muted; -    s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, &ret); +    s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, relative_volume, &ret);      pa_proplist_free(p);      CHECK_VALIDITY(c->pstream, s, tag, ret); diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c index 745c7de0..5bf72ed0 100644 --- a/src/pulsecore/svolume_mmx.c +++ b/src/pulsecore/svolume_mmx.c @@ -25,6 +25,8 @@  #endif  #include <pulse/timeval.h> +#include <pulse/rtclock.h> +  #include <pulsecore/random.h>  #include <pulsecore/macro.h>  #include <pulsecore/g711.h> @@ -287,6 +289,8 @@ static void run_test (void) {      }      stop = pa_rtclock_now();      pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); + +    pa_assert_se(memcmp(samples_ref, samples, sizeof(samples)) == 0);  }  #endif diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c index 1cc4e0aa..620524fa 100644 --- a/src/pulsecore/svolume_sse.c +++ b/src/pulsecore/svolume_sse.c @@ -25,6 +25,8 @@  #endif  #include <pulse/timeval.h> +#include <pulse/rtclock.h> +  #include <pulsecore/random.h>  #include <pulsecore/macro.h>  #include <pulsecore/g711.h> @@ -261,7 +263,7 @@ static void run_test (void) {      func = pa_get_volume_func (PA_SAMPLE_S16NE); -    printf ("checking SSE %zd\n", sizeof (samples)); +    printf ("checking SSE2 %zd\n", sizeof (samples));      pa_random (samples, sizeof (samples));      memcpy (samples_ref, samples, sizeof (samples)); @@ -273,7 +275,7 @@ static void run_test (void) {          volumes[i] = volumes[padding];      func (samples_ref, volumes, CHANNELS, sizeof (samples)); -    pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples)); +    pa_volume_s16ne_sse2 (samples, volumes, CHANNELS, sizeof (samples));      for (i = 0; i < SAMPLES; i++) {          if (samples[i] != samples_ref[i]) {              printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], @@ -284,7 +286,7 @@ static void run_test (void) {      start = pa_rtclock_now();      for (j = 0; j < TIMES; j++) {          memcpy (samples, samples_orig, sizeof (samples)); -        pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples)); +        pa_volume_s16ne_sse2 (samples, volumes, CHANNELS, sizeof (samples));      }      stop = pa_rtclock_now();      pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start)); @@ -296,6 +298,8 @@ static void run_test (void) {      }      stop = pa_rtclock_now();      pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); + +    pa_assert_se(memcmp(samples_ref, samples, sizeof(samples)) == 0);  }  #endif  #endif /* defined (__i386__) || defined (__amd64__) */ diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c index d6c37878..1371ad56 100644 --- a/src/pulsecore/time-smoother.c +++ b/src/pulsecore/time-smoother.c @@ -196,6 +196,13 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {      int64_t ax = 0, ay = 0, k, t;      double r; +    /* FIXME: Optimization: Jason Newton suggested that instead of +     * going through the history on each iteration we could calculated +     * avg_gradient() as we go. +     * +     * Second idea: it might make sense to weight history entries: +     * more recent entries should matter more than old ones. */ +      /* Too few measurements, assume gradient of 1 */      if (s->n_history < s->min_history)          return 1; diff --git a/src/utils/pactl.c b/src/utils/pactl.c index 141ab5b1..ee67c425 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -44,8 +44,6 @@  #include <pulsecore/log.h>  #include <pulsecore/sndfile-util.h> -#define BUFSIZE (16*1024) -  static pa_context *context = NULL;  static pa_mainloop_api *mainloop_api = NULL; @@ -158,10 +156,23 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi          return;      } +    printf(_("Server String: %s\n" +             "Library Protocol Version: %u\n" +             "Server Protocol Version: %u\n" +             "Is Local: %s\n" +             "Client Index: %u\n" +             "Tile Size: %zu\n"), +             pa_context_get_server(c), +             pa_context_get_protocol_version(c), +             pa_context_get_server_protocol_version(c), +             pa_yes_no(pa_context_is_local(c)), +             pa_context_get_index(c), +             pa_context_get_tile_size(c, NULL)); +      pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec);      pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map); -    printf(_("User name: %s\n" +    printf(_("User Name: %s\n"               "Host Name: %s\n"               "Server Name: %s\n"               "Server Version: %s\n" @@ -169,7 +180,7 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi               "Default Channel Map: %s\n"               "Default Sink: %s\n"               "Default Source: %s\n" -             "Cookie: %08x\n"), +             "Cookie: %04x:%04x\n"),             i->user_name,             i->host_name,             i->server_name, @@ -178,7 +189,8 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi             cm,             i->default_sink_name,             i->default_source_name, -           i->cookie); +           i->cookie >> 16, +           i->cookie & 0xFFFFU);      complete_action();  } diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c index c327ee41..534b77b4 100644 --- a/src/utils/pasuspender.c +++ b/src/utils/pasuspender.c @@ -45,8 +45,6 @@  #include <pulse/pulseaudio.h>  #include <pulsecore/macro.h> -#define BUFSIZE 1024 -  static pa_context *context = NULL;  static pa_mainloop_api *mainloop_api = NULL;  static char **child_argv = NULL;  | 
