diff options
Diffstat (limited to 'src/pulsecore')
-rw-r--r-- | src/pulsecore/core-util.c | 91 | ||||
-rw-r--r-- | src/pulsecore/core-util.h | 3 | ||||
-rw-r--r-- | src/pulsecore/protocol-native.c | 16 | ||||
-rw-r--r-- | src/pulsecore/sink-input.c | 11 | ||||
-rw-r--r-- | src/pulsecore/sink.c | 22 | ||||
-rw-r--r-- | src/pulsecore/svolume_mmx.c | 11 | ||||
-rw-r--r-- | src/pulsecore/svolume_sse.c | 4 |
7 files changed, 132 insertions, 26 deletions
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 8e98e857..258e8eec 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -117,6 +117,7 @@ #include <pulsecore/strbuf.h> #include <pulsecore/usergroup.h> #include <pulsecore/strlist.h> +#include <pulsecore/cpu-x86.h> #include "core-util.h" @@ -2867,3 +2868,93 @@ const char *pa_get_temp_dir(void) { return "/tmp"; } + +char *pa_read_line_from_file(const char *fn) { + FILE *f; + char ln[256] = "", *r; + + if (!(f = fopen(fn, "r"))) + return NULL; + + r = fgets(ln, sizeof(ln)-1, f); + fclose(f); + + if (!r) { + errno = EIO; + return NULL; + } + + pa_strip_nl(ln); + return pa_xstrdup(ln); +} + +pa_bool_t pa_running_in_vm(void) { + +#if defined(__i386__) || defined(__x86_64__) + + /* Both CPUID and DMI are x86 specific interfaces... */ + + uint32_t eax = 0x40000000; + union { + uint32_t sig32[3]; + char text[13]; + } sig; + +#ifdef __linux__ + const char *const dmi_vendors[] = { + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", + "/sys/class/dmi/id/bios_vendor" + }; + + unsigned i; + + for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) { + char *s; + + if ((s = pa_read_line_from_file(dmi_vendors[i]))) { + + if (pa_startswith(s, "QEMU") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + pa_startswith(s, "VMware") || + pa_startswith(s, "VMW") || + pa_startswith(s, "Microsoft Corporation") || + pa_startswith(s, "innotek GmbH") || + pa_startswith(s, "Xen")) { + + pa_xfree(s); + return TRUE; + } + + pa_xfree(s); + } + } + +#endif + + /* http://lwn.net/Articles/301888/ */ + pa_zero(sig); + + __asm__ __volatile__ ( + /* ebx/rbx is being used for PIC! */ + " push %%"PA_REG_b" \n\t" + " cpuid \n\t" + " mov %%ebx, %1 \n\t" + " pop %%"PA_REG_b" \n\t" + + : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) + : "0" (eax) + ); + + if (pa_streq(sig.text, "XenVMMXenVMM") || + pa_streq(sig.text, "KVMKVMKVM") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + pa_streq(sig.text, "VMwareVMware") || + /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */ + pa_streq(sig.text, "Microsoft Hv")) + return TRUE; + +#endif + + return FALSE; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 84752d4d..eba1b404 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -251,4 +251,7 @@ pa_bool_t pa_run_from_build_tree(void); const char *pa_get_temp_dir(void); +char *pa_read_line_from_file(const char *fn); +pa_bool_t pa_running_in_vm(void); + #endif diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index d06dd4eb..6e357624 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -1044,13 +1044,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 = TRUE; + 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; @@ -2612,7 +2620,7 @@ static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint3 pa_tagstruct_put_usec(reply, s->current_monitor_latency); pa_tagstruct_put_usec(reply, s->current_source_latency + - pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->sample_spec)); + pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->source->sample_spec)); pa_tagstruct_put_boolean(reply, pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING && pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 1af2823f..aa84ccb1 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -717,14 +717,15 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p pa_memchunk rchunk; pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk); - if (nvfs) { - pa_memchunk_make_writable(&rchunk, 0); - pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink); - } - /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */ if (rchunk.memblock) { + + if (nvfs) { + pa_memchunk_make_writable(&rchunk, 0); + pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink); + } + pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk); pa_memblock_unref(rchunk.memblock); } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index bda92fcc..e6d718f7 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -926,18 +926,16 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume); - if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) { - if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) { - pa_memblock_unref(result->memblock); - pa_silence_memchunk_get(&s->core->silence_cache, - s->core->mempool, - result, - &s->sample_spec, - result->length); - } else { - pa_memchunk_make_writable(result, 0); - pa_volume_memchunk(result, &s->sample_spec, &volume); - } + if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) { + pa_memblock_unref(result->memblock); + pa_silence_memchunk_get(&s->core->silence_cache, + s->core->mempool, + result, + &s->sample_spec, + result->length); + } else if (!pa_cvolume_is_norm(&volume)) { + pa_memchunk_make_writable(result, 0); + pa_volume_memchunk(result, &s->sample_spec, &volume); } } else { void *ptr; diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c index 1768eb50..46923ed3 100644 --- a/src/pulsecore/svolume_mmx.c +++ b/src/pulsecore/svolume_mmx.c @@ -60,7 +60,9 @@ " movq "#s", %%mm5 \n\t" \ " pmulhw "#v", "#s" \n\t" /* .. | 0 | vl*p0 | */ \ " paddw %%mm4, "#s" \n\t" /* .. | 0 | vl*p0 | + sign correct */ \ + " pslld $16, "#s" \n\t" /* .. | vl*p0 | 0 | */ \ " psrld $16, "#v" \n\t" /* .. | 0 | vh | */ \ + " psrad $16, "#s" \n\t" /* .. | vl*p0 | sign extend */ \ " pmaddwd %%mm5, "#v" \n\t" /* .. | p0 * vh | */ \ " paddd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \ " packssdw "#v", "#v" \n\t" /* .. | p1*v1 | p0*v0 | */ @@ -152,7 +154,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi " emms \n\t" : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp) - : "X" ((pa_reg_x86)channels) + : "rm" ((pa_reg_x86)channels) : "cc" ); } @@ -228,7 +230,7 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi " emms \n\t" : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp) - : "X" ((pa_reg_x86)channels) + : "rm" ((pa_reg_x86)channels) : "cc" ); } @@ -255,11 +257,14 @@ static void run_test (void) { printf ("checking MMX %zd\n", sizeof (samples)); pa_random (samples, sizeof (samples)); + /* for (i = 0; i < SAMPLES; i++) + samples[i] = -1; */ memcpy (samples_ref, samples, sizeof (samples)); memcpy (samples_orig, samples, sizeof (samples)); for (i = 0; i < CHANNELS; i++) volumes[i] = rand() >> 1; + /* volumes[i] = 0x0000ffff; */ for (padding = 0; padding < PADDING; padding++, i++) volumes[i] = volumes[padding]; @@ -267,7 +272,7 @@ static void run_test (void) { pa_volume_s16ne_mmx (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], + printf ("%d: %04x != %04x (%04x * %08x)\n", i, samples[i], samples_ref[i], samples_orig[i], volumes[i % CHANNELS]); } } diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c index ab9394fb..1cc4e0aa 100644 --- a/src/pulsecore/svolume_sse.c +++ b/src/pulsecore/svolume_sse.c @@ -149,7 +149,7 @@ pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns "8: \n\t" : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp) - : "X" ((pa_reg_x86)channels) + : "rm" ((pa_reg_x86)channels) : "cc" ); } @@ -237,7 +237,7 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns "8: \n\t" : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp) - : "X" ((pa_reg_x86)channels) + : "rm" ((pa_reg_x86)channels) : "cc" ); } |