David Henningsson | 29 Jul 16:43 2014

[PATCH v2 0/3] alsa: Support for only-multichannel devices

Fixes since v1:

 * Improved fallback logic so that input and output fallbacks are handled more
   independently
 * Fixed a bug in the exact-channels logic causing the sink to open with the old
   channel count
 * Renamed "Generic" to "Multichannel"
 * Removed unnecessary !!

David Henningsson (3):
  alsa: Add "exact-channels" mapping configurability
  alsa: Allow "fallback" configuration for mappings and profiles
  alsa: Add a multichannel fallback mapping

 src/modules/alsa/alsa-mixer.c                    | 121 +++++++++++++++++++++--
 src/modules/alsa/alsa-mixer.h                    |   4 +
 src/modules/alsa/mixer/profile-sets/default.conf |  15 ++-
 3 files changed, 130 insertions(+), 10 deletions(-)

--

-- 
1.9.1
Raymond Yau | 29 Jul 01:32 2014
Picon

Re: [RFC PATCH 0/3] alsa: Support for only-multichannel devices


>>  >
>>  >  * Exact-channels can be set to false to allow devices to be opened with
>>  >    any channel count instead of just the one specified in the channel
>> map.
>>
>> Do these kind of devices need more than one profile if they have same
>> channel Min and channel Max and both are larger than two ?
>
>
> This seems to be the common case that we're trying to handle here, and it will end up with the profiles "off", "generic input" "generic output" and "generic output + generic input".
>
>
>> How can user capture stereo from a FireWire device which only support 6
>> channels
>
>
> With this patch set, PA will setup a default channel map. I e, recording stereo will mean recording from the first two channels.
>
>
>> capture as pulseaudio downmix 6 channels to stereo for playback
>> stream?
>>
>> Can pulseaudio provide a control to select  stereo capture from first
>> Jack, second jack .... ?
>
>
> You'll need module-remap-source for that.
>

Will this change affect the 4 ch capture device ?

How do user select stereo or 4ch capture ?

http://cgit.freedesktop.org/pulseaudio/pulseaudio/commit/src/modules/alsa/mixer/profile-sets/default.conf?id=7bb8442c111d5e1fba20eb101eb854edd5392627

USB Mixer: usb_id=0x14152000, ctrlif=1, ctlerr=0
Card: OmniVision Technologies, Inc. USB Camera-B4.04.27.1 at usb-0000:00:1d.7-4, high
  Unit: 3
    Control: name="Mic Capture Volume", index=0
    Info: id=3, control=2, cmask=0xf, channels=4, type="S16"
    Volume: min=0, max=1, dBmin=0, dBmax=0

>
>> The problems are non standard volume control names
>
>
> The firewire drivers currently don't implement volume controls the normal ALSA mixer way.
> For some other cards (PCI, USB), you're right that the names are sometimes non standard. Please fix that in ALSA. :-)
>

Do pulseaudio really support 4 ch capture ?

_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Felipe Sateler | 28 Jul 22:33 2014
Picon

Pulseaudio test suite failures

Hi,

In the latest version of pulseaudio in Debian I enabled the test suite
at build time. Unfortunately, this resulted in failures in almost all
builds[1]. Several test failures occurred due to timeouts, which I
think could be fixed by simply extending the timeout period. These are
either in the thread or volume tests. However, many tests failed due
to assertions:

On freebsd, we couldn't build:

Debian does not #define __FreeBSD__ but instead defines
__FreeBSD_kernel__. This seems to have changed recently. I don't know
if real FreeBSD defines the kernel variant, but

On hurd-i386:

tests/get-binary-name-test.c:44:F:getbinaryname:getbinaryname_test:0: Failed

On armel:

tests/mix-test.c:266:F:mix:mix_test:0: Assertion '*u == *v' failed

On Powerpc:

tests/mix-test.c:180:F:mix:mix_test:0: Assertion '*u == *v' failed

On s390x:

tests/mix-test.c:180:F:mix:mix_test:0: Assertion '*u == *v' failed

On mips:

tests/mix-test.c:180:F:mix:mix_test:0: Assertion '*u == *v' failed

On sparc:

tests/mix-test.c:180:F:mix:mix_test:0: Assertion '*u == *v' failed

So, I would like to know if the test suite here is flagging real
errors, or perhaps I should disable the test suite on the debian
package?

I may need to disable it anyway because on some archs the thread-test
seems to take just too long (or perhaps there is a race?). But I
thought I should report here the results anyway.

[1] https://buildd.debian.org/status/logs.php?pkg=pulseaudio&ver=5.0-3&suite=sid

--

-- 

Saludos,
Felipe Sateler
Tanu Kaskinen | 28 Jul 10:55 2014
Picon

Patch review status wiki page updated

Patch review status updated:
http://www.freedesktop.org/wiki/Software/PulseAudio/PatchStatus/

Statistics:

* 2014-07-28
   * 117 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 250 days old.

* 2014-07-13
   * 117 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 235 days old.

* 2014-06-24
   * 135 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 279 days old.

* 2014-06-06
   * 145 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 261 days old.

* 2014-05-30
   * 158 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 254 days old.

* 2014-05-23
   * 169 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 247 days old.

* 2014-05-09
   * 169 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 297 days old.

* 2014-04-26
   * 183 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 284 days old.

* 2014-04-17
   * 157 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 275 days old.

* 2014-03-24
   * 138 patches are pending review (not counting the "in a github 
branch" patches).
   * The oldest pending patch is 251 days old.

--

-- 
Tanu
Craig Matsuura | 26 Jul 07:57 2014

latency in loopback between different audio devices

I have a question in regards to latency increasing?

I have an embedded system that is using pulseaudio 1.1 (sorry, this is what is supported at the moment for our platform).  We have connected two sound card devices using loopback.  One is a GSM modem with a sink/source and the other is a audio codec (AIC3104).  Using loopback module to connect the sink/source and source/sink GSM and Codec.

The delay is primarily from the Codec Mic source to the GSM sink.  So over the GSM I hear delayed audio from the mic of the codec.  After waiting some time after pulse has been running the delay becomes more significant (several secs, minutes even)

The GSM device uses a fixed sample spec: s16le 1ch 8000Hz, the codec is at sample spec: s16le 2ch 44100Hz.  (which is programmable according to the datasheet)

The codec can sample at different rates.

From the datasheet of the aic3104
"The stereo audio DAC supports sampling rates from 8 kHz to 96 kHz and includes programmable digital filtering
in the DAC path for 3D, bass, treble, midrange effects, speaker equalization, and de-emphasis for 32-kHz,
44.1-kHz, and 48-kHz sample rates. The stereo audio ADC supports sampling rates from 8 kHz to 96 kHz and is
preceded by programmable gain amplifiers or AGC that can provide up to 59.5-dB analog gain for low-level
microphone inputs. The TLV320AIC3104 provides an extremely high range of programmability for both attack
(8–1,408 ms) and for decay (0.05–22.4 seconds). This extended AGC range allows the AGC to be tuned for
many types of applications."

So I'm trying to understand why I get this delay.  I have setup the loopback as followed.

load-module module-loopback source="alsa_input.codec.input" sink="alsa_output.gsm.output" latency_msec=1
load-module module-loopback source="alsa_input.gsm.input" sink="alsa_output.codec.output" latency_msec=1

My devices are setup in my session file as follow:

load-module module-alsa-source device=hw:0,1 name=gsm.input
load-module module-alsa-sink device=hw:0,1 name=gsm.output

# Load the Codec source and sink given the names below
load-module module-alsa-source device=hw:0,0 name=codec.input control=PGA
load-module module-alsa-sink device=hw:0,0 name=codec.output control=PCM

What is confusing to me is the longer pulse is running seems the latency increase from the codec mic even if when I'm not using the mic.  Its like it is always capturing as I hear previous audio when I setup the loopback on the GSM side.

  • Should I be setting up the same sample rates?
  • So the codec source is forced to be at s16le 1ch 8000Hz to match the GSM so there is no resampling? 
  • Is it a buffer problem? 
  • Can I flush the codec mic side to not have any audio data in the buffers so when I connect up via loopback I don't here old audio? 

Also to note I have tried several different resample-methods and have had to stick with in trivial (kind of tinny sounding) or src-linear (sounds better) for the best performance as my ARM system does not seems to have enough CPU for any of the other resample methods.

I don't think it matter but I also have a DTMF monitor on the GSM source (alsa_input.gsm.input) so I can detect DTMF (which is working well for me using multimon-ng)

Thanks,
Craig
_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
David Henningsson | 25 Jul 15:31 2014

[RFC PATCH 0/3] alsa: Support for only-multichannel devices

This should allow us to automatically probe devices using the recent
firewire drivers, as well as some USB devices people have been asking
about lately.

Sorry that it has taken some time since I said I would work on this patch
set, and I've rewritten and rethought it as well a few times. Anyway, here's
a proposal.

 * Exact-channels can be set to false to allow devices to be opened with
   any channel count instead of just the one specified in the channel map.
   PA will make a standard ALSA channel map for the additional channels.

 * Fallback profiles will only be considered if all other profiles fail.

 * Then we add a "generic" fallback profile without the exact-channel restriction.
   We don't want this "generic" profile to show up for normal devices, hence
   the fallback logic.

It's the fallback stuff I'm most unsure about, e g if things can be fallback
in one direction but not the other, this algorithm is not perfect.
This probably needs another patch revision, but I'm sending this out for your
additional comments, thoughts and (hopefully) testing.

I'm also unsure of what ports (if any) to add for the generic mapping, and if it 
should be called "multichannel" instead of "generic", or something else.

David Henningsson (3):
  alsa: Add "exact-channels" mapping configurability
  alsa: Allow "fallback" configuration for mappings and profiles
  alsa: Add a generic fallback mapping

 src/modules/alsa/alsa-mixer.c                    | 79 +++++++++++++++++++++++-
 src/modules/alsa/alsa-mixer.h                    |  3 +
 src/modules/alsa/mixer/profile-sets/default.conf | 15 ++++-
 3 files changed, 92 insertions(+), 5 deletions(-)

--

-- 
1.9.1
Peter Meerwald | 24 Jul 09:49 2014
Picon

[PATCH] sconv: Use optimized conversion function for both directions

for example, the conversion function for
convert_from_float32ne(PA_SAMPLE_S16LE) can also be used for
convert_to_s16ne(PA_SAMPLE_FLOAT32LE)

Signed-off-by: Peter Meerwald <pmeerw <at> pmeerw.net>
---
 src/pulsecore/sconv_neon.c |    2 ++
 src/pulsecore/sconv_sse.c  |    3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/pulsecore/sconv_neon.c b/src/pulsecore/sconv_neon.c
index 6c2a2b3..8e6a23c 100644
--- a/src/pulsecore/sconv_neon.c
+++ b/src/pulsecore/sconv_neon.c
 <at>  <at>  -89,4 +89,6  <at>  <at>  void pa_convert_func_init_neon(pa_cpu_arm_flag_t flags) {
     pa_log_info("Initialising ARM NEON optimized conversions.");
     pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_neon);
     pa_set_convert_to_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_to_f32ne_neon);
+    pa_set_convert_from_s16ne_function(PA_SAMPLE_FLOAT32LE, (pa_convert_func_t) pa_sconv_s16le_to_f32ne_neon);
+    pa_set_convert_to_s16ne_function(PA_SAMPLE_FLOAT32LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_neon);
 }
diff --git a/src/pulsecore/sconv_sse.c b/src/pulsecore/sconv_sse.c
index 10943ba..9cfb9d9 100644
--- a/src/pulsecore/sconv_sse.c
+++ b/src/pulsecore/sconv_sse.c
 <at>  <at>  -168,10 +168,11  <at>  <at>  void pa_convert_func_init_sse(pa_cpu_x86_flag_t flags) {
     if (flags & PA_CPU_X86_SSE2) {
         pa_log_info("Initialising SSE2 optimized conversions.");
         pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
-
+        pa_set_convert_to_s16ne_function(PA_SAMPLE_FLOAT32LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
     } else if (flags & PA_CPU_X86_SSE) {
         pa_log_info("Initialising SSE optimized conversions.");
         pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
+        pa_set_convert_to_s16ne_function(PA_SAMPLE_FLOAT32LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
     }

 #endif /* defined (__i386__) || defined (__amd64__) */
--

-- 
1.7.9.5
JoonCheol Park | 22 Jul 09:50 2014
Picon

best benchmark tool for pulseaudio ?

Hello,

I'd like to optimize pulseaudio settings on my system (arm based).
and I'm planning to try test with several change settings to find best settings on my system.
To do this, I want to know what is the best way to measure the performance of pulseaudio for each settings. Especially I'd like to check the cpu consumption or latency.

I tried to googling for this and reviewed code briefly to find some unit tests for performance checking..
* oprofile - looks profile each function in point of developer view
* top or ptop or perf top - difficult to check exact start/end time of pulse
* cpu-test.c - looks only for resmapling performance

I couldn't find proper ways yet. but I believe that there's some official or usual tools which pulseaudio(or generic linux audio system) experts use to do benchmark or optimize settings on specific system.
If anybody can recommend something good tools or documents for this purpose, it would be really helpful for me.

Regards,
JC
_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
David Schlosser | 21 Jul 12:17 2014
Picon

Pulseaudio only recognises 3 of my 4 cards after reboot

Hi

I'm new here & to pulseaudio, so I hope this is the right place for asking about my problem. I'm using Pulseaudio v4.0

I have an internal sound card and also 3 USB DACs connected - When I boot, all 4 of these devices are listed by 'aplay -l', but, Pulseaudio as reported by  'pacmd list-cards' only shows 3 cards. 

However, after I then run 'alsa force-reload', and re-run pacmd list-cards, it will correctly show all four devices until I next reboot.

What's happening here & how do I ensure Pulseaudio finds all 4 cards on a reboot.

thanks, David
_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Lukas K | 20 Jul 20:33 2014
Picon

[PATCH] Add checkbutton for disabling volume meters

Add a checkbutton for disabling volume meters because of high CPU
utilisation when updating them
---
 src/mainwindow.cc          |  52 +++++++++++-
 src/mainwindow.h           |   2 +
 src/minimalstreamwidget.cc |  19 ++++-
 src/minimalstreamwidget.h  |   6 ++
 src/pavucontrol.glade      | 195 ++++++++++++++++++++++++++-------------------
 src/streamwidget.cc        |   1 -
 src/streamwidget.h         |   1 -
 7 files changed, 190 insertions(+), 86 deletions(-)

diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index 5a42318..7458039 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
 <at>  <at>  -93,6 +93,7  <at>  <at>  MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
     x->get_widget("sinkTypeComboBox", sinkTypeComboBox);
     x->get_widget("sourceTypeComboBox", sourceTypeComboBox);
     x->get_widget("notebook", notebook);
+    x->get_widget("showVolumeMetersCheckButton", showVolumeMetersCheckButton);

     cardsVBox->set_reallocate_redraws(true);
     sourcesVBox->set_reallocate_redraws(true);
 <at>  <at>  -109,6 +110,8  <at>  <at>  MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
     sourceOutputTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceOutputTypeComboBoxChanged));
     sinkTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSinkTypeComboBoxChanged));
     sourceTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceTypeComboBoxChanged));
+    showVolumeMetersCheckButton->signal_toggled().connect(sigc::mem_fun(*this, &MainWindow::onShowVolumeMetersCheckButtonToggled));
+

     GKeyFile* config = g_key_file_new();
     g_assert(config);
 <at>  <at>  -120,6 +123,10  <at>  <at>  MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
     if (g_key_file_load_from_file (config, m_config_filename, flags, &err)) {
         int width  = g_key_file_get_integer(config, "window", "width", NULL);
         int height = g_key_file_get_integer(config, "window", "height", NULL);
+        /* When upgrading from a previous version, set showVolumeMeters to TRUE (default from glade file), so
users don't complain about missing volume meters. */
+        if(g_key_file_has_key(config, "window", "showVolumeMeters", NULL)) {
+            showVolumeMetersCheckButton->set_active(g_key_file_get_boolean(config, "window",
"showVolumeMeters", NULL));
+        }

         int default_width, default_height;
         get_default_size(default_width, default_height);
 <at>  <at>  -202,6 +209,7  <at>  <at>  MainWindow::~MainWindow() {
     get_size(width, height);
     g_key_file_set_integer(config, "window", "width", width);
     g_key_file_set_integer(config, "window", "height", height);
+    g_key_file_set_integer(config, "window", "showVolumeMeters", showVolumeMetersCheckButton->get_active());

     gsize filelen;
     GError *err = NULL;
 <at>  <at>  -421,6 +429,7  <at>  <at>  bool MainWindow::updateSink(const pa_sink_info &info) {
         is_new = true;

         w->setBaseVolume(info.base_volume);
+        w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active());
     }

     w->updating = true;
 <at>  <at>  -482,6 +491,7  <at>  <at>  static void suspended_callback(pa_stream *s, void *userdata) {
 }

 static void read_callback(pa_stream *s, size_t length, void *userdata) {
+    printf("read from stream %p\n", s);
     MainWindow *w = static_cast<MainWindow*>(userdata);
     const void *data;
     double v;
 <at>  <at>  -535,7 +545,8  <at>  <at>  pa_stream* MainWindow::createMonitorStreamForSource(uint32_t source_idx, uint32_
     pa_stream_set_suspended_callback(s, suspended_callback, this);

     flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT |
PA_STREAM_ADJUST_LATENCY |
-                                 (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS));
+                                 (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS) |
+                                (!showVolumeMetersCheckButton->get_active() ? PA_STREAM_START_CORKED : PA_STREAM_NOFLAGS));

     if (pa_stream_connect_record(s, t, &attr, flags) < 0) {
         show_error(_("Failed to connect monitoring stream"));
 <at>  <at>  -574,9 +585,10  <at>  <at>  void MainWindow::updateSource(const pa_source_info &info) {
         is_new = true;

         w->setBaseVolume(info.base_volume);
+        w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active());

         if (pa_context_get_server_protocol_version(get_context()) >= 13)
-            createMonitorStreamForSource(info.index, -1, !!(info.flags & PA_SOURCE_NETWORK));
+            w->peak = createMonitorStreamForSource(info.index, -1, !!(info.flags & PA_SOURCE_NETWORK));
     }

     w->updating = true;
 <at>  <at>  -689,6 +701,7  <at>  <at>  void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
         w->index = info.index;
         w->clientIndex = info.client;
         is_new = true;
+        w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active());

         if (pa_context_get_server_protocol_version(get_context()) >= 13)
             createMonitorStreamForSinkInput(w, info.sink);
 <at>  <at>  -746,6 +759,7  <at>  <at>  void MainWindow::updateSourceOutput(const pa_source_output_info &info) {
         w->index = info.index;
         w->clientIndex = info.client;
         is_new = true;
+        w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active());
     }

     w->updating = true;
 <at>  <at>  -1220,3 +1234,37  <at>  <at>  void MainWindow::onSourceOutputTypeComboBoxChanged() {

     updateDeviceVisibility();
 }
+
+
+void MainWindow::onShowVolumeMetersCheckButtonToggled() {
+    bool state = showVolumeMetersCheckButton->get_active();
+    printf("toggled %d\n", state);
+    for (std::map<uint32_t, SinkWidget*>::iterator it = sinkWidgets.begin() ; it != sinkWidgets.end();
it++) {
+        SinkWidget *sw = it->second;
+        if(sw->peak) {
+            pa_stream_cork(sw->peak, (int)!state, NULL, NULL);
+        }
+        sw->setVolumeMeterVisible(state);
+    }
+    for (std::map<uint32_t, SourceWidget*>::iterator it = sourceWidgets.begin() ; it !=
sourceWidgets.end(); it++) {
+        SourceWidget *sw = it->second;
+        if(sw->peak) {
+            pa_stream_cork(sw->peak, (int)!state, NULL, NULL);
+        }
+        sw->setVolumeMeterVisible(state);
+    }
+    for (std::map<uint32_t, SinkInputWidget*>::iterator it = sinkInputWidgets.begin() ; it !=
sinkInputWidgets.end(); it++) {
+        SinkInputWidget *sw = it->second;
+        if(sw->peak) {
+            pa_stream_cork(sw->peak, (int)!state, NULL, NULL);
+        }
+        sw->setVolumeMeterVisible(state);
+    }
+    for (std::map<uint32_t, SourceOutputWidget*>::iterator it = sourceOutputWidgets.begin() ; it !=
sourceOutputWidgets.end(); it++) {
+        SourceOutputWidget *sw = it->second;
+        if(sw->peak) {
+            pa_stream_cork(sw->peak, (int)!state, NULL, NULL);
+        }
+        sw->setVolumeMeterVisible(state);
+    }
+}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 5c501f7..30e1ad0 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
 <at>  <at>  -68,6 +68,7  <at>  <at>  public:
     Gtk::VBox *streamsVBox, *recsVBox, *sinksVBox, *sourcesVBox, *cardsVBox;
     Gtk::Label *noStreamsLabel, *noRecsLabel, *noSinksLabel, *noSourcesLabel, *noCardsLabel, *connectingLabel;
     Gtk::ComboBox *sinkInputTypeComboBox, *sourceOutputTypeComboBox, *sinkTypeComboBox, *sourceTypeComboBox;
+    Gtk::CheckButton *showVolumeMetersCheckButton;

     std::map<uint32_t, CardWidget*> cardWidgets;
     std::map<uint32_t, SinkWidget*> sinkWidgets;
 <at>  <at>  -85,6 +86,7  <at>  <at>  public:
     virtual void onSourceOutputTypeComboBoxChanged();
     virtual void onSinkTypeComboBoxChanged();
     virtual void onSourceTypeComboBoxChanged();
+    virtual void onShowVolumeMetersCheckButtonToggled();

     void setConnectionState(gboolean connected);
     void updateDeviceVisibility();
diff --git a/src/minimalstreamwidget.cc b/src/minimalstreamwidget.cc
index 562739d..d1f26e1 100644
--- a/src/minimalstreamwidget.cc
+++ b/src/minimalstreamwidget.cc
 <at>  <at>  -29,8 +29,10  <at>  <at>  MinimalStreamWidget::MinimalStreamWidget(BaseObjectType* cobject, const Glib::Re
     Gtk::VBox(cobject),
     peakProgressBar(),
     lastPeak(0),
+    peak(NULL),
     updating(false),
-    volumeMeterEnabled(false) {
+    volumeMeterEnabled(false),
+    volumeMeterVisible(true) {

     x->get_widget("channelsVBox", channelsVBox);
     x->get_widget("nameLabel", nameLabel);
 <at>  <at>  -69,6 +71,19  <at>  <at>  void MinimalStreamWidget::enableVolumeMeter() {
         return;

     volumeMeterEnabled = true;
-    peakProgressBar.show();
+    if(volumeMeterVisible) {
+        peakProgressBar.show();
+    }
 }

+void MinimalStreamWidget::setVolumeMeterVisible(bool v) {
+    volumeMeterVisible=v;
+    if(v) {
+        if(volumeMeterEnabled) {
+            peakProgressBar.show();
+        }
+    }
+    else {
+        peakProgressBar.hide();
+    }
+}
diff --git a/src/minimalstreamwidget.h b/src/minimalstreamwidget.h
index 7d5ee24..8bfc5bc 100644
--- a/src/minimalstreamwidget.h
+++ b/src/minimalstreamwidget.h
 <at>  <at>  -32,6 +32,7  <at>  <at>  public:
     Gtk::Image *iconImage;
     Gtk::ProgressBar peakProgressBar;
     double lastPeak;
+    pa_stream *peak;

     bool updating;

 <at>  <at>  -41,6 +42,11  <at>  <at>  public:
     bool volumeMeterEnabled;
     void enableVolumeMeter();
     void updatePeak(double v);
+    void setVolumeMeterVisible(bool v);
+
+private :
+    bool volumeMeterVisible;
+
 };

 #endif
diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade
index 5116632..725a1dc 100644
--- a/src/pavucontrol.glade
+++ b/src/pavucontrol.glade
 <at>  <at>  -7,6 +7,66  <at>  <at> 
     <property name="value">44.2408370972</property>
     <property name="step_increment">5</property>
   </object>
+  <object class="GtkWindow" id="channelWindow">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="title" translatable="yes">window2</property>
+    <child>
+      <object class="GtkHBox" id="channelWidget">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="channelLabel">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+            <property name="label" translatable="yes">&lt;b&gt;left-front&lt;/b&gt;</property>
+            <property name="use_markup">True</property>
+            <property name="width_chars">15</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkHScale" id="volumeScale">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="adjustment">adjustment1</property>
+            <property name="digits">0</property>
+            <property name="draw_value">False</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="volumeLabel">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="yalign">0</property>
+            <property name="xpad">8</property>
+            <property name="label" translatable="yes">&lt;small&gt;50%&lt;/small&gt;</property>
+            <property name="use_markup">True</property>
+            <property name="justify">right</property>
+            <property name="width_chars">9</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
   <object class="GtkWindow" id="cardWindow">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
 <at>  <at>  -137,66 +197,6  <at>  <at> 
       </object>
     </child>
   </object>
-  <object class="GtkWindow" id="channelWindow">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="title" translatable="yes">window2</property>
-    <child>
-      <object class="GtkHBox" id="channelWidget">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="spacing">6</property>
-        <child>
-          <object class="GtkLabel" id="channelLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="xalign">0</property>
-            <property name="yalign">0</property>
-            <property name="label" translatable="yes">&lt;b&gt;left-front&lt;/b&gt;</property>
-            <property name="use_markup">True</property>
-            <property name="width_chars">15</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHScale" id="volumeScale">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="adjustment">adjustment1</property>
-            <property name="digits">0</property>
-            <property name="draw_value">False</property>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="volumeLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="xalign">1</property>
-            <property name="yalign">0</property>
-            <property name="xpad">8</property>
-            <property name="label" translatable="yes">&lt;small&gt;50%&lt;/small&gt;</property>
-            <property name="use_markup">True</property>
-            <property name="justify">right</property>
-            <property name="width_chars">9</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
   <object class="GtkWindow" id="deviceWindow">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
 <at>  <at>  -278,7 +278,6  <at>  <at> 
                         <property name="spacing">3</property>
                         <child>
                           <object class="GtkToggleButton" id="muteToggleButton">
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
 <at>  <at>  -301,7 +300,6  <at>  <at> 
                         </child>
                         <child>
                           <object class="GtkToggleButton" id="lockToggleButton">
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
 <at>  <at>  -325,7 +323,6  <at>  <at> 
                         </child>
                         <child>
                           <object class="GtkToggleButton" id="defaultToggleButton">
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
 <at>  <at>  -430,7 +427,6  <at>  <at> 
                             <child>
                               <object class="GtkCheckButton" id="encodingFormatPCM">
                                 <property name="label" translatable="yes">PCM</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="sensitive">False</property>
                                 <property name="can_focus">True</property>
 <at>  <at>  -442,7 +438,6  <at>  <at> 
                             <child>
                               <object class="GtkCheckButton" id="encodingFormatAC3">
                                 <property name="label" translatable="yes">AC3</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
 <at>  <at>  -456,7 +451,6  <at>  <at> 
                             <child>
                               <object class="GtkCheckButton" id="encodingFormatDTS">
                                 <property name="label" translatable="yes">DTS</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
 <at>  <at>  -470,7 +464,6  <at>  <at> 
                             <child>
                               <object class="GtkCheckButton" id="encodingFormatEAC3">
                                 <property name="label" translatable="yes">EAC3</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
 <at>  <at>  -484,7 +477,6  <at>  <at> 
                             <child>
                               <object class="GtkCheckButton" id="encodingFormatMPEG">
                                 <property name="label" translatable="yes">MPEG</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
 <at>  <at>  -500,7 +492,6  <at>  <at> 
                             <child>
                               <object class="GtkCheckButton" id="encodingFormatAAC">
                                 <property name="label" translatable="yes">AAC</property>
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
 <at>  <at>  -698,7 +689,6  <at>  <at> 
       <object class="GtkVBox" id="vbox20">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="border_width">12</property>
         <property name="spacing">12</property>
         <child>
           <object class="GtkNotebook" id="notebook">
 <at>  <at>  -1194,18 +1184,29  <at>  <at> 
                         <property name="can_focus">False</property>
                         <property name="shadow_type">none</property>
                         <child>
-                          <object class="GtkVBox" id="cardsVBox">
+                          <object class="GtkVBox" id="vbox3">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <child>
-                              <object class="GtkLabel" id="noCardsLabel">
+                              <object class="GtkVBox" id="cardsVBox">
                                 <property name="visible">True</property>
-                                <property name="sensitive">False</property>
                                 <property name="can_focus">False</property>
-                                <property name="xpad">16</property>
-                                <property name="ypad">16</property>
-                                <property name="label" translatable="yes">&lt;i&gt;No cards available for configuration&lt;/i&gt;</property>
-                                <property name="use_markup">True</property>
+                                <child>
+                                  <object class="GtkLabel" id="noCardsLabel">
+                                    <property name="visible">True</property>
+                                    <property name="sensitive">False</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xpad">16</property>
+                                    <property name="ypad">16</property>
+                                    <property name="label" translatable="yes">&lt;i&gt;No cards available for configuration&lt;/i&gt;</property>
+                                    <property name="use_markup">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">True</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
                               </object>
                               <packing>
                                 <property name="expand">True</property>
 <at>  <at>  -1213,6 +1214,43  <at>  <at> 
                                 <property name="position">0</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkVBox" id="vbox4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkHSeparator" id="hseparator1">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="showVolumeMetersCheckButton">
+                                    <property name="label" translatable="yes">Show volume meters</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">True</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
                           </object>
                         </child>
                       </object>
 <at>  <at>  -1412,7 +1450,6  <at>  <at> 
                         <child>
                           <object class="GtkButton" id="deviceButton">
                             <property name="label" translatable="yes">Device</property>
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
 <at>  <at>  -1440,7 +1477,6  <at>  <at> 
                         <property name="spacing">3</property>
                         <child>
                           <object class="GtkToggleButton" id="muteToggleButton">
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
 <at>  <at>  -1463,7 +1499,6  <at>  <at> 
                         </child>
                         <child>
                           <object class="GtkToggleButton" id="lockToggleButton">
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
diff --git a/src/streamwidget.cc b/src/streamwidget.cc
index 94363ec..9492f4b 100644
--- a/src/streamwidget.cc
+++ b/src/streamwidget.cc
 <at>  <at>  -31,7 +31,6  <at>  <at> 
 /*** StreamWidget ***/
 StreamWidget::StreamWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& x) :
     MinimalStreamWidget(cobject, x),
-    peak(NULL),
     mpMainWindow(NULL) {

     x->get_widget("lockToggleButton", lockToggleButton);
diff --git a/src/streamwidget.h b/src/streamwidget.h
index b797ec5..160dc52 100644
--- a/src/streamwidget.h
+++ b/src/streamwidget.h
 <at>  <at>  -43,7 +43,6  <at>  <at>  public:

     pa_channel_map channelMap;
     pa_cvolume volume;
-    pa_stream *peak;

     ChannelWidget *channelWidgets[PA_CHANNELS_MAX];

--

-- 
2.0.2
Michael DePaulo | 20 Jul 14:56 2014
Picon

Make PulseAudio listen only on loopback ?

Hi guys,

So with X2Go's 2 clients for Windows (the regular "X2Go Client", and
"PyHoca-GUI"), we start pulseaudio.exe with a script like this one:

load-module module-native-protocol-tcp port=4713 auth-cookie=\.pulse-cookie
load-module module-esound-protocol-tcp port=4714
load-module module-waveout

This causes pulseaudio.exe to listen on all network interfaces. It
also causes a Windows Firewall prompt, which is a nuisance to users.

However, with X2Go, there is an option to tunnel all the sound traffic
over SSH. So when this option is set, we only need to pusleaudio.exe
to listen on loopback. Is there a way to do this?

Thanks in advance,
Mike DePaulo
Windows Maintainer for X2Go

Gmane