Re: [pulseaudio-discuss] [PATCH] fix the assumption that volume is always positive

2011-05-26 Thread Tanu Kaskinen
On Thu, 2011-05-26 at 09:50 +0100, Colin Guthrie wrote:
 'Twas brillig, and Lu Guanqun at 26/05/11 09:49 did gyre and gimble:
  Add a variable to track whether the actual volume is set or not.
  Suppose this:
  min volume: -126max volume: 0
  then when user wants to set some constant volume to -10, it would fail.
 
 Tanu, are you OK with this patch?

Maybe, maybe not. I posted a question to alsa-devel:
http://mailman.alsa-project.org/pipermail/alsa-devel/2011-May/040213.html

If negative steps are allowed, I expect there to be more bugs.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] How to change profile of bluetooth headset for different applications?

2011-05-26 Thread Tanu Kaskinen
On Mon, 2011-05-23 at 18:18 +0100, Colin Guthrie wrote:
 How about this:
 
 Define a new card property similar in concept to
 PA_PROP_DEVICE_INTENDED_ROLES (device.intended_roles) called
 PA_PROP_DEVICE_INTENDED_PROFILE (device.intended_profile).
 
 In bluetooth device, when loading a headset that has both HSP and A2DP,
 populate the device with the following code:
 
 if (supports_hsp  supports_a2dp)
 {
   char *k;
 
   k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, music);
   pa_proplist_sets(card_data.proplist, k, a2dp);
   pa_xfree(k);
 
   k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, video);
   pa_proplist_sets(card_data.proplist, k, a2dp);
   pa_xfree(k);
 
   k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, phone);
   pa_proplist_sets(card_data.proplist, k, hsp);
   pa_xfree(k);
 }
 
 This should result in pacmd list-cards dumping a proplist that includes:
 
  device.intended_profile.music = a2dp
  device.intended_profile.video = a2dp
  device.intended_profile.phone = hsp
 
 
 
 Then a separate module (module-intended-profiles?) could take care of
 listening quite generically for streams landing on sink and do the
 following logic:
 
 
 if (!si-sink || !si-sink-card)
   return PA_HOOK_OK;
 
 char *role = pa_proplist_gets(si-proplist, PA_PROP_MEDIA_ROLE);
 if (!role)
   return PA_HOOK_OK;
 
 char *k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, role);
 pa_card *card = si-sink-card;
 char *profile = pa_proplist_gets(card-proplist, k);
 pa_xfree(k);
 if (!profile)
   return PA_HOOK_OK;
 
 if (!pa_streq(card-active_profile, profile)) {
/* Save the current profile for later restoration */
...
 
if (pa_card_set_profile(card, profile, FALSE)  0)
/* Find the sink of this card as the above call will likely have
 changed it */
sink = pa_idxset_first(card-sinks, NULL);
 
pa_sink_input_move_to(si, sink, FALSE);
 }
 
 
 This code is then completely generic. I'm not 100% sure how well this
 will work in practice as there may be some nasty races etc. but I think
 this general approach could work... Perhaps others (i.e. Tanu :D) have
 better suggestions?

If the priority lists would exist already, the module deciding the
routing could examine the stream properties and pick the sink+port with
the highest priority that can be made available - if the sink+port isn't
immediately available, but can be made available, then the routing
module would change the profile and port as needed.

But the priority lists are not available. I believe the logic that you
propose is otherwise good, except that I don't see how the stream could
land on the bluetooth (a2dp) sink automatically on phone calls.
module-bluetooth-device tags only hsp sinks with the phone tag, not a2dp
sinks, so module-intended-roles can't do the required magic. If the hsp
sink doesn't exist because the a2dp profile is selected, I don't think
there's currently any logic to route the stream to the bluetooth sink.
If, however, by some magic the phone stream would be routed to the a2dp
sink, then I think your proposal would work fine.

For better suggestions, I don't think I have any. Except that use the
policy framework - Lin posted from an intel.com address, so I assume he
or she (sorry, I don't know Chinese names) is working on Meego, and I've
thought that Meego got the policy framework from Maemo. In Maemo the
routing is handled by module-policy-enforcement (which gets the command
to enable the bluetooth-hsp routing mode from the policy framework), and
it works pretty nicely for this kind of use cases.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] fix the assumption that volume is always positive

2011-05-26 Thread Tanu Kaskinen
On Thu, 2011-05-26 at 14:08 +0300, Tanu Kaskinen wrote:
 On Thu, 2011-05-26 at 09:50 +0100, Colin Guthrie wrote:
  'Twas brillig, and Lu Guanqun at 26/05/11 09:49 did gyre and gimble:
   Add a variable to track whether the actual volume is set or not.
   Suppose this:
 min volume: -126max volume: 0
   then when user wants to set some constant volume to -10, it would fail.
  
  Tanu, are you OK with this patch?
 
 Maybe, maybe not. I posted a question to alsa-devel:
 http://mailman.alsa-project.org/pipermail/alsa-devel/2011-May/040213.html
 
 If negative steps are allowed, I expect there to be more bugs.

I got a confirmation that negative volumes are allowed, so the patch
should be fine. Somebody should review the alsa mixer code for other
cases of the invalid assumption (I plan to do it in the indefinite
future, if nobody else does it).

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 1/2] alsa: add jack detection support

2011-05-25 Thread Tanu Kaskinen
Sorry for late reply...

On Fri, 2011-05-20 at 09:14 -0500, Jorge Eduardo Candelaria wrote:
  +if (event-value)
  +pa_hook_fire(u-core-hooks[PA_CORE_HOOK_JACK_INSERT], jack);
  +else
  +pa_hook_fire(u-core-hooks[PA_CORE_HOOK_JACK_REMOVE], jack);
  
  Firing core hooks directly from modules looks a bit dirty to me.
 
 I'm actually not very familiar with hooks, however do we need to signal the 
 jack 
 insertion/removal events from jack_report().
 
 What would be a more clean solution?

Adding just a couple of trivial functions to the core would probably
suffice:

void pa_jack_inserted(pa_core *c, pa_jack_event *e);
void pa_jack_removed(pa_core *c, pa_jack_event *e);

Those functions would do nothing but call pa_hook_fire(), so this is a
purely cosmetic thing...

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 2/2] alsa: load jack detection module

2011-05-25 Thread Tanu Kaskinen
On Thu, 2011-05-19 at 11:44 -0500, Jorge Eduardo Candelaria wrote:
 From: Margarita Olaya Cabrera m...@slimlogic.co.uk
 
 This patch adds support for udev detection of sound card jack event devices.
 
 When a new card is detected, the code now also checks for the presence of any
 associated input device via udev, and report the device to module-alsa-card
 via its jack_id parameter.
 
 Jack support development was kindly sponsored by Wolfson Microelectronics PLC
 
 Signed-off-by: Margarita Olaya Cabrera m...@slimlogic.co.uk
 Signed-off-by: Jorge Eduardo Candelaria j...@slimlogic.co.uk
 ---
 src/modules/module-udev-detect.c |   68 ++---
 1 files changed, 62 insertions(+), 6 deletions(-)
 
 diff --git a/src/modules/module-udev-detect.c 
 b/src/modules/module-udev-detect.c
 index 63ad195..4321b32 100644
 --- a/src/modules/module-udev-detect.c
 +++ b/src/modules/module-udev-detect.c
 @@ -71,6 +71,8 @@ struct userdata {
 
 int inotify_fd;
 pa_io_event *inotify_io;
 +
 +char *card_name;

This doesn't really seem to be used for anything.

 };
 
 static const char* const valid_modargs[] = {
 @@ -163,6 +165,21 @@ static pa_bool_t pcm_is_modem(const char *card_idx, 
 const char *pcm) {
 return is_modem;
 }
 
 +static pa_bool_t input_node_belongs_to_device(
 +struct device *d,
 +const char *node) {
 +
 +char *cd;
 +pa_bool_t b;
 +
 +cd = pa_sprintf_malloc(/sys%s, d-path);
 +
 +b = pa_startswith(node, cd);
 +pa_xfree(cd);
 +
 +return b;
 +}
 +
 static pa_bool_t is_card_busy(const char *id) {
 char *card_path = NULL, *pcm_path = NULL, *sub_status = NULL;
 DIR *card_dir = NULL, *pcm_dir = NULL;
 @@ -352,11 +369,26 @@ static void verify_access(struct userdata *u, struct 
 device *d) {
 }
 }
 
 +static const char *jack_get_input_id(const char *path) {
 +int i;
 +
 +for( i = 0; i  strlen(path); i++) {

strlen() is called in each iteration - it would be better to save its
return value outside the loop.

 +if (pa_startswith(path + i, /input))
 +return path + i + 6;
 +}
 +
 +return NULL;
 +}
 +
 static void card_changed(struct userdata *u, struct udev_device *dev) {
 struct device *d;
 +struct udev_enumerate *enumerate;
 +struct udev_list_entry *item, *first;
 const char *path;
 const char *t;
 char *n;
 +char *jack_path;
 +char *jack_input;
 
 pa_assert(u);
 pa_assert(dev);
 @@ -383,6 +415,28 @@ static void card_changed(struct userdata *u, struct 
 udev_device *dev) {
 
 n = pa_namereg_make_valid_name(t);
 d-card_name = pa_sprintf_malloc(alsa_card.%s, n);
 +
 +if (!(enumerate = udev_enumerate_new(u-udev)))
 +pa_log(Failed to initialize udev enumerator);
 +else {
 +if (!udev_enumerate_add_match_subsystem(enumerate, input))
 +pa_log_debug(Failed to match to subsystem input);
 +
 +if (udev_enumerate_scan_devices(enumerate))
 +pa_log_debug(Failed to scan for devices);

Should these two errors abort the enumeration, or is a debug message
really good enough error handling here?

 +
 +first = udev_enumerate_get_list_entry(enumerate);
 +udev_list_entry_foreach(item, first) {
 +jack_path = udev_list_entry_get_name(item);
 +if (input_node_belongs_to_device(d, jack_path)) {
 +jack_input = pa_xstrdup(jack_get_input_id(jack_path));
 +pa_log_debug(jack is %s\n, jack_input);

jack_input can, at least in theory, be null (or if it can't, you should
add an assertion to jack_get_input_id() instead of returning NULL). I'm
not sure what happens if you pass a null pointer as a string to the log
functions - does it crash, or does it work? There's the pa_strnull()
function that returns the string (null) if the argument is null, and
the function is being used in similar contexts as this one. Either you
should call pa_strnull() here, or the other uses of pa_strnull() are
redundant.

 +break;
 +}
 +}
 +udev_enumerate_unref(enumerate);
 +}
 +
 d-args = pa_sprintf_malloc(device_id=\%s\ 
 name=\%s\ 
 card_name=\%s\ 
 @@ -390,15 +444,19 @@ static void card_changed(struct userdata *u, struct 
 udev_device *dev) {
 tsched=%s 
 ignore_dB=%s 
 sync_volume=%s 
 +jack_id=\%s\ 
 
 card_properties=\module-udev-detect.discovered=1\,
 path_get_card_id(path),
 n,
 d-card_name,
 pa_yes_no(u-use_tsched),
 pa_yes_no(u-ignore_dB),
 -pa_yes_no(u-sync_volume));
 -pa_xfree(n);
 +  

Re: [pulseaudio-discuss] How to debug a protocol error message?

2011-05-25 Thread Tanu Kaskinen
Sorry for joining the discussion late... I haven't read Pulseaudio mail
since last Thursday.

On Tue, 2011-05-24 at 09:20 +0100, Colin Guthrie wrote:
 Yup Maarten's advice is good there.
 
 
 But what is interesting is that our official 0.9.15 version ships with
 protocol 15, not 16... Your debug suggests the the remote end is
 protocol 16..
 
 This suggests to me that the extensions in the Maemo version are
 non-standard and therefore require consultation with their lists. You
 should check their code to see what commits changed the protocol version
 to 16. It could be that they just backported the changes from our
 version 16 shipped in 0.9.16 (which was an API to select client side API
 detection) or it could be something completely custom.
 
 As I'm not familiar with their modifications, I cannot really help.

Fremantle's Pulseaudio protocol is not compatible with upstream versions
greater than 0.9.15. The changes that bumped the protocol version number
to 16 were originally supposed to go upstream, but the work never got
finished, and the incompatibilities didn't get fixed in time either. I'm
sorry for messing that up.

Quinn asked whether it's possible to force Pulseaudio to use an older
protocol version. That's not currently possible, but maybe it would make
sense to add such a feature? I imagine it wouldn't be too hard. I don't
think there are any other reasonably easy solutions.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Glitches on null sink?

2011-05-25 Thread Tanu Kaskinen
On Fri, 2011-05-20 at 21:28 +0200, mar...@saepia.net wrote:
 Hi,
 
 I continue to develop my radio audio routing software so I continue to
 encounter strange bugs.
 
 General idea that lies behind my project is to split some processing
 parts into separate processes. There are many reasons why this
 architecture has to be like this, it something fundamental and won't
 change.
 
 For processing individual elements I use GStreamer (no external
 bindings, my code is in C).
 
 There're many advanced dedicated input sources, such as
 RTP/VoIP/shoutcast. All of them load their own null sink module, and
 perform output on one. Other modules that broadcast the signal to the
 FM/net just leech from their .monitor PA sources. To this moment
 everything works flawlessly, even if I load huge amount of sources.
 
 The problem is when I try to perform some audio processing or/and
 mixing. Currently I do that in the following way:
 
 1. Load another null sink module for mix output.
 2. Run GStreamer's pipelines (each is also a separate process), e.g.:
  a) pulsesrc device=source1.monitor ! processor1 ! processor2 !
 pulsesink device=mix
  b) pulsesrc device=source2.monitor ! processor3 ! processor4 !
 pulsesink device=mix
 
 It generally works ok, but from time to time, output (captured from
 mix.monitor) becomes full of glitches. Sounds like something lost
 synchronisation. And it's really hard to reproduce. Sometimes I run
 that kind of pipeline and it works for a long time and then it starts
 doing weird things, sometimes it starts it from the beginning.
 
 When it starts producing glitches, pulsesrc element in the GStreamer
 pipeline throws an error that it cannot read samples fast enough. What
 is interesting, when it starts doing that, any other audio that I pass
 to this mix sink also sounds bad from the begin. Only reloading
 module helps.
 
 
 My theory is that I have to use module-combine to perform such mixing.
 Am I correct?

I don't think module-combine is relevant here. It should do mixing in
the exact same way as module-null-sink and all other sinks. I don't
guarantee that anyone will volunteer debugging this problem (it doesn't
sound easy), but could you upload somewhere a sample recording of the
glitchy audio?

 I wanted to avoid that as I am unable to dynamically add its slaves,
 but if it's the only way to perform such mix, I will do that, and
 reload it when my dedicated sources' list changes... It's not too
 pretty as it would produce short drops, but it's still acceptable.
 
 I just want you to ask if I am seeking for the problem in the correct
 place, just before I spend a week on refactoring my code. Maybe
 pipeline like shown above (pulseaudio - GStreamer - pulseaudio) also
 is a wrong approach?

Generally pulseaudio - app - pulseaudio is a non-optimal approach,
because the source and the sink usually have different clocks, and
therefore they drift. There should be some adaptive resampling to
mitigate the drift. I have an impression that GStreamer provides this
kind of resampling, though. If you don't already have one, you could try
adding a queue element in the GStreamer pipelines (this may be
completely bogus advice, though, as I'm not a GStreamer expert).

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] alsa-mixer: When setting hw volume, round always up with playback and always down with capture.

2011-05-19 Thread Tanu Kaskinen
On Tue, 2011-05-17 at 19:40 +0100, Colin Guthrie wrote:
 Just to report that a modified version of that patch does indeed fix the
 problem for me.
 
 What do you think overall? Should we try and hunt down the problems with
 the conversion or should this patch be included?

I think it would make sense to save the intermediate volume as integer
millibels - that way there couldn't be any rounding errors, because no
rounding would happen.

The patch works, though, so I'm not against applying it. That would be
the easier way forward - from a quick glance at the code it seems that
changing the volume format will involve more than just changing a
variable type.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] alsa-mixer: When setting hw volume, round always up with playback and always down with capture.

2011-05-19 Thread Tanu Kaskinen
On Tue, 2011-05-17 at 12:13 +0100, Colin Guthrie wrote:
 Thanks, I'll test this patch and see if it helps with my test case.
 
 Assuming that it does, is this something we should really push to alsa
 lib? When I first encountered the problem I did start hacking away at
 alsa lib looking for the problem.
 
 Perhaps a new direction argument -2 and +2 for nearest below bias and
 nearest above bias respectively? (the bias only coming into play when
 there you are exactly inbetween two possible values).

Nah, if we need rounding to the nearest step only for working around
rounding errors that are caused by ourselves due to
not-entirely-necessary format conversions, I don't think alsa-lib should
be changed just for that.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Jack detection (was: Re: [PATCHv3 0/4] Read and store UCM data as proplist)

2011-05-19 Thread Tanu Kaskinen
On Tue, 2011-05-17 at 13:44 +0200, David Henningsson wrote:
 Agree with the port property. About the port vs profile question, I 
 think we might think that backwards from a user's perspective. 
 Conceptually I'd say we select port first (manually or automatic; 
 doesn't matter for this reasoning), then we evaluate what profiles make 
 sense to try. If we're on headphones, only stereo profile makes sense, 
 if we're on line-out, we might want to consider surround profiles. At 
 least I would want it to work that way in the UI.
 
 Could you elaborate on having profiles without ports? IIRC Pulseaudio 
 would fail in this case.

No, Pulseaudio doesn't fail in the scenario that I'm talking about - the
no ports situation is an optimization for the case when there would be
only one port to select from. If the profile (or more precisely the
mapping associated with that profile) has only one path in the mixer
configuration, then the sink or source will not export any ports at all.
The reasoning for that is probably that having a single port on a sink
would be redundant, because currently the only functionality ports offer
is that the user can change between them.

However, if the available property is added to ports, then exposing
even just one port on a sink will not be redundant.

I'm not sure what you are proposing with regards to selecting ports. Did
I understand correctly that the user should be presented with all ports
of all sinks and sources of a card in one big list?

  Pulseaudio should have an abstraction for jacks. Jack objects would be
  created by whatever alsa module is appropriate for that. Maybe
  module-alsa-card would be the best choice, or maybe not. There exists
  hardware where physical jacks are shared between multiple alsa cards.
 
 Really? Is that some embedded scenario?

Yep. Simplifying a bit, one card handles the playback uses of the jack,
and one card handles the capture uses of the jack.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 1/2] alsa: add jack detection support

2011-05-19 Thread Tanu Kaskinen
I tried to apply the patch for easier review in meld, but unfortunately
it seems that some helpful software has eaten the first space on lines
that begin with one or more spaces. Because of that, git am doesn't
accept the patch.

I'll review this anyway, without meld.

Overall comments: there is some confusion about whether the jack stuff
is a core concept (hooks in pa_core) or an alsa specific thing (all jack
related type definitions are in alsa-jack.h). I think it probably makes
sense to keep alsa-jack.h as an alsa specific thing, but then the core
hooks shouldn't be tied to alsa-jack.h like they are now. In the longer
term I hope the thing how policy modules interact with jack detection
will be monitoring the (currently not existing) available status of the
port objects. However, if you don't want to start working on that now,
I'd just move alsa-jack.h under pulsecore (and of course rename it).

The only major issue in my opinion is the jack_fd reading. It should be
made non-blocking.

-- 
Tanu

On Thu, 2011-05-19 at 11:44 -0500, Jorge Eduardo Candelaria wrote:
 From: Margarita Olaya Cabrera m...@slimlogic.co.uk
 
 This patch adds support to module-alsa-card so that we can read jack insertion
 and removal events using the input device subsystem. i.e. we can detect
 headphone insertions and removals.
 
 This patch adds a new module parameter called jack_id that contains the ID of
 the jack input device associated with this sound card. If we receive a valid
 jack_id during module init then we start a reader thread that will read the
 jack input device and fire a hook on every removal and insertion event.
 
 Jack support development was kindly sponsored by Wolfson Microelectronics PLC
 
 Signed-off-by: Margarita Olaya Cabrera m...@slimlogic.co.uk
 Signed-off-by: Jorge Eduardo Candelaria j...@slimlogic.co.uk
 ---
 src/modules/alsa/alsa-jack.h|   42 
 src/modules/alsa/module-alsa-card.c |  120 +++
 src/pulsecore/core.h|2 +
 3 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 src/modules/alsa/alsa-jack.h
 
 diff --git a/src/modules/alsa/alsa-jack.h b/src/modules/alsa/alsa-jack.h
 new file mode 100644
 index 000..4fc67c6
 --- /dev/null
 +++ b/src/modules/alsa/alsa-jack.h
 @@ -0,0 +1,42 @@
 +#ifndef foopulsejackdetecthfoo
 +#define foopulsejackdetecthfoo
 +
 +/***
 +  This file is part of PulseAudio.
 +
 +  Copyright 2011 Wolfson Microelectronics PLC
 +  Author Margarita Olaya m...@slimlogic.co.uk
 +
 +  PulseAudio is free software; you can redistribute it and/or modify
 +  it under the terms of the GNU Lesser General Public License as published
 +  by the Free Software Foundation; either version 2.1 of the License,
 +  or (at your option) any later version.
 +
 +  PulseAudio is distributed in the hope that it will be useful, but
 +  WITHOUT ANY WARRANTY; without even the implied warranty of
 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +  General Public License for more details.
 +
 +  You should have received a copy of the GNU Lesser General Public License
 +  along with PulseAudio; if not, write to the Free Software
 +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 +  USA.
 +***/
 +
 +#include inttypes.h
 +
 +typedef enum pa_jack_event {
 +PA_JACK_HEADPHONES,
 +PA_JACK_HEADSET,
 +PA_JACK_MICROPHONE,
 +PA_JACK_LINEOUT,
 +PA_JACK_UNKNOWN,
 +PA_JACK_MAX
 +} pa_jack_event_t;
 +
 +typedef struct pa_jack_detect {
 +pa_jack_event_t event;
 +char *card;

Instead of the card name, would it be better to store a pa_card pointer
here? It seems that you have the card object available when you
initialize this struct.

 +} pa_jack_detect_t;

Structs shouldn't have the _t suffix. (Enum typedefs should, so the
pa_jack_event_t name is correct.)

If this is alsa specific, like it seems to be, judging from the file
location and name, I recommend prefixing the types with pa_alsa_jack_,
because all other alsa stuff uses pa_alsa_ prefix too. Hmm... on the
other hand, this struct is passed to a core hook, so maybe these types
are not really alsa specific, and should be defined in a header under
src/pulsecore/?

Also, I think pa_jack_event would be a better name for what you've now
named pa_jack_detect, and the enum could be pa_jack_type_t.

 +#endif
 diff --git a/src/modules/alsa/module-alsa-card.c 
 b/src/modules/alsa/module-alsa-card.c
 index e60aa5e..75202fb 100644
 --- a/src/modules/alsa/module-alsa-card.c
 +++ b/src/modules/alsa/module-alsa-card.c
 @@ -29,6 +29,9 @@
 #include pulsecore/core-util.h
 #include pulsecore/modargs.h
 #include pulsecore/queue.h
 +#include pulsecore/thread.h
 +
 +#include linux/input.h
 
 #include modules/reserve-wrap.h
 
 @@ -39,6 +42,7 @@
 #include alsa-util.h
 #include alsa-sink.h
 #include alsa-source.h
 +#include alsa-jack.h
 #include module-alsa-card-symdef.h
 
 PA_MODULE_AUTHOR(Lennart Poettering);
 @@ -55,6 +59,7 @@ 

Re: [pulseaudio-discuss] [PATCH] alsa-mixer: When setting hw volume, round always up with playback and always down with capture.

2011-05-17 Thread Tanu Kaskinen
On Mon, 2011-05-16 at 21:22 +0100, Colin Guthrie wrote:
 OK, here is the debug output from my run using this volume approach
 
 As you can see there are several points where the message:
 
 Written HW volume did not match with the request is shown. This is
 shown quite clearly when writing the volumes to h/w
 
 I suspect this problem arrises due to the use of pa_cvolume_divide()
 which is based around PA_VOLUME_NORM, when the second argument (the
 software volume) is  PA_VOLUME_NORM.
 
 Any thoughts on this are welcome.

I'll quote the log:

D: protocol-native.c: Client pavucontrol changes volume of source 
alsa_input.pci-_00_1b.0.analog-stereo.
D: alsa-source.c: Requested volume: 0:  45% 1:  45%
D: alsa-source.c:in dB: 0: -20.71 dB 1: -20.71 dB
D: alsa-source.c: Got hardware volume: 0:  45% 1:  45%
D: alsa-source.c:   in dB: 0: -21.00 dB 1: -21.00 dB
D: alsa-source.c: Calculated software volume: 0: 101% 1: 101% 
(accurate-enough=no)
D: alsa-source.c:  in dB: 0: 0.29 dB 1: 0.29 dB
D: source.c: Volume going up to 29273 at 270475970821
D: source.c: Volume change to 29273 at 270475970821 was written 34 usec late
D: alsa-source.c: Written HW volume did not match with the request: 0:  45% 1:  
45% (request) != 0:  42% 1:  42%
D: alsa-source.c:in dB: 0: -21.00 
dB 1: -21.00 dB (request) != 0: -22.50 dB 1: -22.50 dB

Looking at the last line, the requested volume seems to hit exactly the
right step (-21.00dB), but for some reason Alsa decides to choose
something else. I'm pretty sure that this happens because of rounding
errors. In the first phase we ask Alsa what dB value we should set, and
it returns -21.00 dB. The value is given as a long int, but we convert
that to pa_cvolume. Then when we set the volume, we convert the
pa_cvolume value back to a long integer. At this point I believe it gets
converted to -2101. This is not visible in the debug message for some
reason - the rounding algorithm must be different from what was used
with the pa_cvolume - long conversion.

Here's a patch that should fix the problem:

http://meego.gitorious.org/maemo-multimedia/pulseaudio/commit/a88c2b1d9f8c2088a430a257470a70efeaaf4b34

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] alsa-mixer: When setting hw volume, round always up with playback and always down with capture.

2011-05-15 Thread Tanu Kaskinen
This was discussed on the mailing list:

https://tango.0pointer.de/pipermail/pulseaudio-discuss/2011-May/010091.html
---
 src/modules/alsa/alsa-mixer.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index f236da0..8375a2f 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -893,7 +893,7 @@ static int element_set_volume(pa_alsa_element *e, 
snd_mixer_t *m, const pa_chann
 
 if (e-has_dB) {
 long value = to_alsa_dB(f);
-int rounding = value  0 ? -1 : +1;
+int rounding = e-direction == PA_ALSA_DIRECTION_OUTPUT ? +1 : -1;
 
 if (e-volume_limit = 0  value  (e-max_dB * 100))
 value = e-max_dB * 100;
-- 
1.7.5.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] bluetooth: Add missing return statement.

2011-05-14 Thread Tanu Kaskinen
---
 src/modules/bluetooth/module-bluetooth-device.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index 086fce9..ae522bc 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1957,6 +1957,8 @@ static int sco_over_pcm_state_update(struct userdata *u, 
pa_bool_t changed) {
 
 return 0;
 }
+
+return 0;
 }
 
 static pa_hook_result_t sink_state_changed_cb(pa_core *c, pa_sink *s, struct 
userdata *u) {
-- 
1.7.5.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] loopback: Add a modarg for disabling remixing.

2011-05-14 Thread Tanu Kaskinen
---
 src/modules/module-loopback.c |   18 +-
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index 9a8640b..024337f 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -59,7 +59,8 @@ PA_MODULE_USAGE(
 sink_input_role=media.role for the sink input 
 source_output_role=media.role for the source output 
 source_dont_move=boolean 
-sink_dont_move=boolean);
+sink_dont_move=boolean 
+remix=remix channels? );
 
 #define DEFAULT_LATENCY_MSEC 200
 
@@ -120,6 +121,7 @@ static const char* const valid_modargs[] = {
 source_output_role,
 source_dont_move,
 sink_dont_move,
+remix,
 NULL,
 };
 
@@ -407,7 +409,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t 
nbytes, pa_memchunk *chunk
 u-in_pop = FALSE;
 
 if (pa_memblockq_peek(u-memblockq, chunk)  0) {
-pa_log_info(Coud not peek into queue);
+pa_log_info(Could not peek into queue);
 return -1;
 }
 
@@ -645,6 +647,7 @@ int pa__init(pa_module *m) {
 pa_memchunk silence;
 uint32_t adjust_time_sec;
 const char *n;
+pa_bool_t remix = TRUE;
 
 pa_assert(m);
 
@@ -663,6 +666,11 @@ int pa__init(pa_module *m) {
 goto fail;
 }
 
+if (pa_modargs_get_value_boolean(ma, remix, remix)  0) {
+pa_log(Invalid boolean remix parameter);
+goto fail;
+}
+
 ss = sink-sample_spec;
 map = sink-channel_map;
 if (pa_modargs_get_sample_spec_and_channel_map(ma, ss, map, 
PA_CHANNEL_MAP_DEFAULT)  0) {
@@ -713,7 +721,7 @@ int pa__init(pa_module *m) {
 
 pa_sink_input_new_data_set_sample_spec(sink_input_data, ss);
 pa_sink_input_new_data_set_channel_map(sink_input_data, map);
-sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE;
+sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE | (remix ? 0 : 
PA_SINK_INPUT_NO_REMIX);
 
 sink_dont_move = FALSE;
 if (pa_modargs_get_value_boolean(ma, sink_dont_move, sink_dont_move)  
0) {
@@ -764,8 +772,8 @@ int pa__init(pa_module *m) {
 pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ICON_NAME, 
n);
 
 pa_source_output_new_data_set_sample_spec(source_output_data, ss);
-pa_sink_input_new_data_set_channel_map(sink_input_data, map);
-source_output_data.flags = (pa_source_output_flags_t)0;
+pa_source_output_new_data_set_channel_map(source_output_data, map);
+source_output_data.flags = (remix ? 0 : PA_SOURCE_OUTPUT_NO_REMIX);
 
 source_dont_move = FALSE;
 if (pa_modargs_get_value_boolean(ma, source_dont_move, 
source_dont_move)  0) {
-- 
1.7.5.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] Reverting ade0a6f88464d8aecf83982d400ccfc402341920

2011-05-13 Thread Tanu Kaskinen
Hello,

Should this commit be reverted?

http://git.0pointer.de/?p=pulseaudio.git;a=commit;h=ade0a6f88464d8aecf83982d400ccfc402341920

I don't know what problem that commit solves, but it introduces a new
problem: if Pulseaudio requests a volume that is above 0dB in the alsa
volume element scale, then it can easily happen that alsa will round the
request down. That rounding is then compensated with software volume,
which in this case is amplification. We don't want software
amplification, or do we?

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Is there any way to remap source channels?

2011-05-13 Thread Tanu Kaskinen
On Fri, 2011-05-13 at 11:30 +0200, mar...@saepia.net wrote:
 Hi,
 
 is there any way to remap source channels?
 
 I need the same functionality as provided by module-remap-sink, but
 for sources - I use multichannel soundcard (RME Hammerfall) and I want
 to create virtual sources that map to stereo pairs of my inputs. Then
 I want to use their names in my application.

module-remap-source would be nice to have. But we don't have it.

A very ugly hack, which I'm not sure even works, would be to configure
the channel map of the sound card to have only aux channels (required to
prevent remixing), then load a null sink with two channels (channel map
matched to the desired channels on the sound card), then load
module-loopback that loops the sound card to the null sink. Then you can
record from the null sink's monitor.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Is there any way to remap source channels?

2011-05-13 Thread Tanu Kaskinen
On Fri, 2011-05-13 at 14:14 +0200, mar...@saepia.net wrote:
 Why should I prevent remixing? Can't I just use module-loopback with
 channel_map set?

I think this is what happens (I haven't tested): if you have non-aux
channels on the sound card, let's say front-left, front-right, rear-left
and rear-right, and you try to loop back just rear-left and rear-right,
the resampler (which really takes care of more conversion than just
sample rate) will try to be smart and mix some of front-left and
front-right into the rear-left and rear-right channels. The same logic
is involved always when a stream - be it capture or playback - is
connected to a device that doesn't have the same parameters as the
stream. Configuring the device to use aux channels should disable the
intelligent remixing - only the channels specified by the stream will
be taken from the source.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Reverting ade0a6f88464d8aecf83982d400ccfc402341920

2011-05-13 Thread Tanu Kaskinen
On Fri, 2011-05-13 at 17:29 +0200, David Henningsson wrote:
 In short; if we e g have Mic Boost levels at (0dB, 20dB, 40dB and 60dB) 
 and the user wants 30 dB, better have 20dB in hardware and +10dB in 
 software than 40dB in hardware and -10dB in software, as the latter one 
 is more likely to have digital distortion when the signal passes through 
 the ADC.
 
 There is a longer email on this list a while back, explaining more of 
 the philosophy behind, but I can't seem to find it right now.

Ok, I think I understand why rounding down makes sense when recording.
With playback, however, rounding towards 0 dB is definetely broken. My
ability to think clearly happens to be currently a bit weakened, so I
have to ask you: what's so magic about 0 dB? With playback rounding
should always be done up - would it make sense to round always down with
capture?

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Is there any way to remap source channels?

2011-05-13 Thread Tanu Kaskinen
On Fri, 2011-05-13 at 17:05 +0100, Colin Guthrie wrote:
 FWIW, some modules, like module-remap-sink take a remix=yes|no argument
 to control this behaviour even when using standard channel names.

module-loopback should have a similar argument, but it doesn't...

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] realtime kernel RLIMIT_RTTIME crashes, rewinds

2011-05-04 Thread Tanu Kaskinen
Sorry for the delayed reply.

On Wed, 2011-04-27 at 13:23 +0300, Dan Muresan wrote:
 I've patched (as in attachment) src/daemon/main.c to set the soft
 rttime limit lower than the hard limit. This way I was able to get a
 backtrace in gdb when pulseaudio received SIGXCPU due to excessive
 real-time CPU usage:
 
 #0  0x0012d422 in ?? ()
 #1  0x00475edb in write () at ../sysdeps/unix/syscall-template.S:82
 #2  0x00153a55 in pa_fdsem_post (f=0x806e178) at pulsecore/fdsem.c:205
 #3  0x0013cb0f in push (l=0x8071bc8, p=0x8, wait_op=false) at
 pulsecore/asyncq.c:161
 #4  0x0013d291 in pa_asyncq_post (l=0x8071bc8, p=0x80736d8) at
 pulsecore/asyncq.c:203
 #5  0x0013c1ee in pa_asyncmsgq_post (a=0x8071a90, object=0xb6a16a08,
 code=7, userdata=0x0, offset=0, chunk=0xb590, free_cb=0) at
 pulsecore/asyncmsgq.c:139
 #6  0x009811d7 in pstream_memblock_callback (p=0x808cf78, channel=0,
 offset=0, seek=PA_SEEK_RELATIVE, chunk=0xb590, userdata=0x80b6480)
 at pulsecore/protocol-native.c:4445
 #7  0x001dd20b in ?? () from /usr/lib/libpulsecommon-0.9.22.so
 #8  0x001c823e in ?? () from /usr/lib/libpulsecommon-0.9.22.so
 #9  0x0021b5fb in pa_mainloop_dispatch () from /usr/lib/libpulse.so.0
 #10 0x0021bb11 in pa_mainloop_iterate () from /usr/lib/libpulse.so.0
 #11 0x0021bbd4 in pa_mainloop_run () from /usr/lib/libpulse.so.0
 #12 0x08052e85 in main (argc=1, argv=0xb854) at daemon/main.c:974
 
 Can someone point out the likely cause, or is this not enough
 information? This is pulseaudio 0.9.22 from Ubuntu Natty.

I would guess that the excessive cpu use is caused by doing rewinds in
rapid succession. That's just a guess, though - the backtrace doesn't
really give any clue. There have been issues with rewinds happening in
some kind of a loop. David Henningson has been working on this problem
and he has made at least a few patches that help with the problem. The
patches are in Pulseaudio's git repository at least. Since David works
for Canonical, I would expect the fixes to be also in Ubuntu, but I
don't know for sure.

David, what's the status of the fighting rewinds patches in Ubuntu
Natty? Is the problem supposed to be fixed already?

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] match: Support for both merging and replacing proplist updates.

2011-04-29 Thread Tanu Kaskinen
This patch adds a new update mode specifier that can be optionally
given in match rules after the regexp. Propertly list updates triggered
by the rule will honour the given mode. The two allowed modes are 'merge'
and 'replace', corresponding to PA_UPDATE_MERGE and PA_UPDATE_REPLACE
respectively. If omitted, the mode defaults to PA_UPDATE_MERGE, ie. to
the original behavior.

For example, to force 'media.role' to be overwritten with 'bar' for
streams matching foo you can use an entry like this:

foo replace bar

This will really overwrite media.role to bar even if it has already been
set to something else by the application.

Thanks to Krisztian Litkey for the original patch and the description
above. In addition to implementing the new feature, this patch fixes
a number of bugs in the parsing code.
---
 src/modules/module-match.c |   97 +++-
 1 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index b3316d4..c94ef79 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -60,6 +60,9 @@ PA_MODULE_USAGE(table=filename 
 #define DEFAULT_MATCH_TABLE_FILE PA_DEFAULT_CONFIG_DIR/match.table
 #define DEFAULT_MATCH_TABLE_FILE_USER match.table
 
+#define UPDATE_REPLACE replace
+#define UPDATE_MERGE merge
+
 static const char* const valid_modargs[] = {
 table,
 key,
@@ -70,6 +73,7 @@ struct rule {
 regex_t regex;
 pa_volume_t volume;
 pa_proplist *proplist;
+pa_update_mode_t mode;
 struct rule *next;
 };
 
@@ -101,13 +105,14 @@ static int load_rules(struct userdata *u, const char 
*filename) {
 pa_lock_fd(fileno(f), 1);
 
 while (!feof(f)) {
-char *d, *v;
+char *token_end, *value_str;
 pa_volume_t volume = PA_VOLUME_NORM;
 uint32_t k;
 regex_t regex;
 char ln[256];
 struct rule *rule;
 pa_proplist *proplist = NULL;
+pa_update_mode_t mode = (pa_update_mode_t) -1;
 
 if (!fgets(ln, sizeof(ln), f))
 break;
@@ -119,51 +124,72 @@ static int load_rules(struct userdata *u, const char 
*filename) {
 if (ln[0] == '#' || !*ln )
 continue;
 
-d = ln+strcspn(ln, WHITESPACE);
-v = d+strspn(d, WHITESPACE);
+token_end = ln + strcspn(ln, WHITESPACE);
+value_str = token_end + strspn(token_end, WHITESPACE);
+*token_end = 0;
 
+if (!*ln) {
+pa_log([%s:%u] failed to parse line - missing regexp, fn, n);
+goto finish;
+}
 
-if (!*v) {
-pa_log(__FILE__ : [%s:%u] failed to parse line - too few words, 
filename, n);
+if (!*value_str) {
+pa_log([%s:%u] failed to parse line - too few words, fn, n);
 goto finish;
 }
 
-*d = 0;
-if (pa_atou(v, k) = 0) {
+if (pa_atou(value_str, k) = 0)
 volume = (pa_volume_t) PA_CLAMP_VOLUME(k);
-} else if (*v == '') {
-char *e;
-
-e = strchr(v+1, '');
-if (!e) {
-pa_log(__FILE__ : [%s:%u] failed to parse line - missing role 
closing quote, filename, n);
-goto finish;
-}
-
-*e = '\0';
-e = pa_sprintf_malloc(media.role=\%s\, v+1);
-proplist = pa_proplist_from_string(e);
-pa_xfree(e);
-} else {
-char *e;
-
-e = v+strspn(v, WHITESPACE);
-if (!*e) {
-pa_log(__FILE__ : [%s:%u] failed to parse line - missing end 
of property list, filename, n);
-goto finish;
-}
-*e = '\0';
-proplist = pa_proplist_from_string(v);
+else {
+size_t len;
+
+token_end = value_str + strcspn(value_str, WHITESPACE);
+
+len = token_end - value_str;
+if (len == (sizeof(UPDATE_REPLACE) - 1)  !strncmp(value_str, 
UPDATE_REPLACE, len))
+mode = PA_UPDATE_REPLACE;
+else if (len == (sizeof(UPDATE_MERGE) - 1)  !strncmp(value_str, 
UPDATE_MERGE, len))
+mode = PA_UPDATE_MERGE;
+
+if (mode != (pa_update_mode_t) -1) {
+value_str = token_end + strspn(token_end, WHITESPACE);
+
+if (!*value_str) {
+pa_log([%s:%u] failed to parse line - too few words, fn, 
n);
+goto finish;
+}
+} else
+mode = PA_UPDATE_MERGE;
+
+if (*value_str == '') {
+value_str++;
+
+token_end = strchr(value_str, '');
+if (!token_end) {
+pa_log([%s:%u] failed to parse line - missing role 
closing quote, fn, n);
+goto finish;
+}
+} else
+token_end = value_str + strcspn(value_str, WHITESPACE);
+
+*token_end = 0;
+
+

[pulseaudio-discuss] [PATCH 0/2] Fixing module-dbus-protocol unloading

2011-04-29 Thread Tanu Kaskinen
There were a couple of crash bugs in the
module-dbus-protocol unloading code, which became visible
when unloading the module while there were still clients
connected.

Tanu Kaskinen (2):
  dbus: Fix connection idxset freeing when unloading the module.
  dbus: Fix the order of freeing stuff when unloading
module-dbus-protocol.

 src/modules/dbus/module-dbus-protocol.c |   29 +++--
 1 files changed, 15 insertions(+), 14 deletions(-)

-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 2/2] dbus: Fix the order of freeing stuff when unloading module-dbus-protocol.

2011-04-29 Thread Tanu Kaskinen
---
 src/modules/dbus/module-dbus-protocol.c |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/modules/dbus/module-dbus-protocol.c 
b/src/modules/dbus/module-dbus-protocol.c
index 276c6ba..4969585 100644
--- a/src/modules/dbus/module-dbus-protocol.c
+++ b/src/modules/dbus/module-dbus-protocol.c
@@ -592,14 +592,20 @@ void pa__done(pa_module *m) {
 if (u-core_iface)
 pa_dbusiface_core_free(u-core_iface);
 
-if (u-cleanup_event)
-m-core-mainloop-defer_free(u-cleanup_event);
-
 while ((c = pa_idxset_steal_first(u-connections, NULL)))
 connection_free(c);
 
 pa_idxset_free(u-connections, NULL, NULL);
 
+/* This must not be called before the connections are freed, because if
+ * there are any connections left, they will emit the
+ * org.freedesktop.DBus.Local.Disconnected signal, and
+ * disconnection_filter_cb() will be called. disconnection_filter_cb() then
+ * tries to enable the defer event, and if it's already freed, an assertion
+ * will be hit in mainloop.c. */
+if (u-cleanup_event)
+m-core-mainloop-defer_free(u-cleanup_event);
+
 if (u-tcp_server)
 server_free(u-tcp_server);
 
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/2] dbus: Fix connection idxset freeing when unloading the module.

2011-04-29 Thread Tanu Kaskinen
If u-connections isn't empty when module-dbus-protocol is
unloaded, then connection_free() is called for the
remaining connections when the idxset is freed.
connection_free() tries to remove the connection from the
idxset, but that fails, because the item has already been
removed from the idxset in this scenario.

The problem is solved by not trying to remove the connection
from the idxset in connection_free(). Instead, whoever wants
to delete connections, has to remove the connection from the
idxset in addition to calling connection_free().
---
 src/modules/dbus/module-dbus-protocol.c |   21 -
 1 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/src/modules/dbus/module-dbus-protocol.c 
b/src/modules/dbus/module-dbus-protocol.c
index aa11cdf..276c6ba 100644
--- a/src/modules/dbus/module-dbus-protocol.c
+++ b/src/modules/dbus/module-dbus-protocol.c
@@ -105,7 +105,6 @@ static void connection_free(struct connection *c) {
 
pa_assert_se(pa_dbus_protocol_unregister_connection(c-server-userdata-dbus_protocol,
 pa_dbus_wrap_connection_get(c-wrap_conn)) = 0);
 
 pa_client_free(c-client);
-pa_assert_se(pa_idxset_remove_by_data(c-server-userdata-connections, c, 
NULL));
 pa_dbus_wrap_connection_free(c-wrap_conn);
 pa_xfree(c);
 }
@@ -514,8 +513,10 @@ static void cleanup_cb(pa_mainloop_api *a, pa_defer_event 
*e, void *userdata) {
 uint32_t idx;
 
 PA_IDXSET_FOREACH(conn, u-connections, idx) {
-if 
(!dbus_connection_get_is_connected(pa_dbus_wrap_connection_get(conn-wrap_conn)))
+if 
(!dbus_connection_get_is_connected(pa_dbus_wrap_connection_get(conn-wrap_conn)))
 {
+pa_idxset_remove_by_data(u-connections, conn, NULL);
 connection_free(conn);
+}
 }
 
 u-module-core-mainloop-defer_enable(e, 0);
@@ -579,17 +580,9 @@ fail:
 return -1;
 }
 
-/* Called by idxset when the connection set is freed. */
-static void connection_free_cb(void *p, void *userdata) {
-struct connection *conn = p;
-
-pa_assert(conn);
-
-connection_free(conn);
-}
-
 void pa__done(pa_module *m) {
 struct userdata *u;
+struct connection *c;
 
 pa_assert(m);
 
@@ -602,8 +595,10 @@ void pa__done(pa_module *m) {
 if (u-cleanup_event)
 m-core-mainloop-defer_free(u-cleanup_event);
 
-if (u-connections)
-pa_idxset_free(u-connections, connection_free_cb, NULL);
+while ((c = pa_idxset_steal_first(u-connections, NULL)))
+connection_free(c);
+
+pa_idxset_free(u-connections, NULL, NULL);
 
 if (u-tcp_server)
 server_free(u-tcp_server);
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] stream-restore: Enable database dumping if DEBUG_VOLUME is defined.

2011-04-28 Thread Tanu Kaskinen
On Thu, 2011-04-28 at 12:48 +0300, Colin Guthrie wrote:
 'Twas brillig, and Tanu Kaskinen at 27/04/11 11:08 did gyre and gimble:
  From: Tanu Kaskinen ext-tanu.kaski...@nokia.com
  
  ---
   src/modules/module-stream-restore.c |4 ++--
   1 files changed, 2 insertions(+), 2 deletions(-)
  
  diff --git a/src/modules/module-stream-restore.c 
  b/src/modules/module-stream-restore.c
  index c1baf8f..56672f7 100644
  --- a/src/modules/module-stream-restore.c
  +++ b/src/modules/module-stream-restore.c
  @@ -1778,8 +1778,8 @@ static void apply_entry(struct userdata *u, const 
  char *name, struct entry *e) {
   }
   }
   
  -#if 0
  -static void dump_database(struct userdata *u) {
  +#ifdef DEBUG_VOLUME
  +PA_GCC_UNUSED static void stream_restore_dump_database(struct userdata *u) 
  {
   pa_datum key;
   pa_bool_t done;
   
 
 Forgive my ignorance here but I cannot see where this is called... Is
 there some magic way to call this function?

You can call it in gdb.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] stream-restore: Enable database dumping if DEBUG_VOLUME is defined.

2011-04-27 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

---
 src/modules/module-stream-restore.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index c1baf8f..56672f7 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -1778,8 +1778,8 @@ static void apply_entry(struct userdata *u, const char 
*name, struct entry *e) {
 }
 }
 
-#if 0
-static void dump_database(struct userdata *u) {
+#ifdef DEBUG_VOLUME
+PA_GCC_UNUSED static void stream_restore_dump_database(struct userdata *u) {
 pa_datum key;
 pa_bool_t done;
 
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] module: new null-source module

2011-04-27 Thread Tanu Kaskinen
From: Marc-André Lureau marcandre.lur...@gmail.com

---
 src/Makefile.am  |6 +
 src/modules/module-null-source.c |  294 ++
 2 files changed, 300 insertions(+), 0 deletions(-)
 create mode 100644 src/modules/module-null-source.c

diff --git a/src/Makefile.am b/src/Makefile.am
index fb846cd..275334d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1024,6 +1024,7 @@ modlibexec_LTLIBRARIES += \
module-simple-protocol-tcp.la \
module-null-sink.la \
module-sine-source.la \
+   module-null-source.la \
module-detect.la \
module-volume-restore.la \
module-device-manager.la \
@@ -1289,6 +1290,7 @@ SYMDEF_FILES = \
module-tunnel-source-symdef.h \
module-null-sink-symdef.h \
module-sine-source-symdef.h \
+   module-null-source-symdef.h \
module-esound-sink-symdef.h \
module-zeroconf-publish-symdef.h \
module-zeroconf-discover-symdef.h \
@@ -1481,6 +1483,10 @@ module_sine_source_la_SOURCES = 
modules/module-sine-source.c
 module_sine_source_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_sine_source_la_LIBADD = $(MODULE_LIBADD)
 
+module_null_source_la_SOURCES = modules/module-null-source.c
+module_null_source_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_null_source_la_LIBADD = $(MODULE_LIBADD)
+
 # Couplings
 
 module_combine_la_SOURCES = modules/module-combine.c
diff --git a/src/modules/module-null-source.c b/src/modules/module-null-source.c
new file mode 100644
index 000..358ffc6
--- /dev/null
+++ b/src/modules/module-null-source.c
@@ -0,0 +1,294 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2008 Lennart Poettering
+  Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include config.h
+#endif
+
+#include stdlib.h
+#include sys/stat.h
+#include stdio.h
+#include errno.h
+#include string.h
+#include fcntl.h
+#include unistd.h
+#include limits.h
+
+#include pulse/rtclock.h
+#include pulse/timeval.h
+#include pulse/xmalloc.h
+
+#include pulsecore/core-error.h
+#include pulsecore/core-rtclock.h
+#include pulsecore/core-util.h
+#include pulsecore/log.h
+#include pulsecore/macro.h
+#include pulsecore/modargs.h
+#include pulsecore/module.h
+#include pulsecore/rtpoll.h
+#include pulsecore/source.h
+#include pulsecore/thread-mq.h
+#include pulsecore/thread.h
+
+#include module-null-source-symdef.h
+
+PA_MODULE_AUTHOR(Lennart Poettering  Marc-Andre Lureau);
+PA_MODULE_DESCRIPTION(Clocked NULL source);
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+format=sample format 
+channels=number of channels 
+rate=sample rate 
+source_name=name of source 
+channel_map=channel map 
+description=description for the source 
+latency_time=latency time in ms);
+
+#define DEFAULT_SOURCE_NAME source.null
+#define DEFAULT_LATENCY_TIME 20
+#define MAX_LATENCY_USEC (PA_USEC_PER_SEC * 2)
+
+struct userdata {
+pa_core *core;
+pa_module *module;
+pa_source *source;
+
+pa_thread *thread;
+pa_thread_mq thread_mq;
+pa_rtpoll *rtpoll;
+
+size_t block_size;
+
+pa_usec_t block_usec;
+pa_usec_t timestamp;
+pa_usec_t latency_time;
+};
+
+static const char* const valid_modargs[] = {
+rate,
+format,
+channels,
+source_name,
+channel_map,
+description,
+latency_time,
+NULL
+};
+
+static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t 
offset, pa_memchunk *chunk) {
+struct userdata *u = PA_SOURCE(o)-userdata;
+
+switch (code) {
+case PA_SOURCE_MESSAGE_SET_STATE:
+
+if (PA_PTR_TO_UINT(data) == PA_SOURCE_RUNNING)
+u-timestamp = pa_rtclock_now();
+
+break;
+
+case PA_SOURCE_MESSAGE_GET_LATENCY: {
+pa_usec_t now;
+
+now = pa_rtclock_now();
+*((pa_usec_t*) data) = u-timestamp  now ? u-timestamp - now : 0;
+
+return 0;
+}
+}
+
+return pa_source_process_msg(o, code, data, offset, chunk);
+}
+
+static void 

Re: [pulseaudio-discuss] [PATCH] module: new null-source module

2011-04-27 Thread Tanu Kaskinen
On Wed, 2011-04-27 at 14:50 +0300, Tanu Kaskinen wrote:
 From: Marc-André Lureau marcandre.lur...@gmail.com
 
 ---
  src/Makefile.am  |6 +
  src/modules/module-null-source.c |  294 
 ++
  2 files changed, 300 insertions(+), 0 deletions(-)
  create mode 100644 src/modules/module-null-source.c

This module isn't actually used by anyone currently. We (at Nokia)
switched to null-sink's monitor a long time ago (for reasons unknown to
me), so the code hasn't had much testing lately. Even though there are
no users for the module currently, I'm sending the patch anyway, just in
case people think that the module might be useful in some situation.

I quickly tested that I can record silence with parec from source.null -
I can't give any further guarantees that the code is correct.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] how to set buffer attributes in 0.9.15

2011-04-25 Thread Tanu Kaskinen
On Thu, 2011-04-21 at 22:48 -0700, sohail abbasi wrote:
 
 hi everyone,
 
 
 
 I am stuck in the pulseaudio programing, I am adding pulseaudio support
 in my existing application.Design of the application is synchronous and
 multithreaded. I need exactly 320 samples  (320*4 bytes) for reading
 and writing. While using pulseaudio 0.9.14 , below parameters works
 fine but with 0.9.15  readablesize is not as expecting :( .

If 0.9.14 worked as you want, the switch to timer-based scheduling
probably caused the change in behavior. If this application is used only
on systems where you can dictate the pulseaudio daemon settings, then
adding tsched=0 to the line in /etc/pulse/default.pa where
module-hal-detect is loaded may help.

If you can't control the pulseaudio configuration of your users, then I
believe you can't get the behavior anymore that you got with 0.9.14.
According to the documentation, the fragsize buffer attribute should do
what you want for capture streams, but apparently that's not the case in
practice (based on what you've told - I haven't done any tests myself).

Does anyone know what fragsize actually does? Does it have any meaning
anymore? The documentation should be fixed...

I'm fairly sure that you are able to fake fixed-size fragments in your
pulseaudio support code, though. Just buffer the data locally, and
transfer only 320 at a time with the rest of the application.

 One more
 thing , are playattributes and record attributes related to each other
 or have any effect on one another ?

No, they don't have any effect on each other.

 
 ***
 
 PLAYBACK ATTRIBUTES:
 
 play_attributes = (pa_buffer_attr*) malloc (sizeof (pa_buffer_attr));
 
  play_attributes-maxlength =  
 pa_usec_to_bytes(21*PA_USEC_PER_MSEC,_sample_spec);

This doesn't seem like a good idea. Maxlength doesn't affect the request
size. What does 21 ms mean anyway? How many samples is it?

  play_attributes-tlength = (uint32_t) -1;
 
  play_attributes-prebuf = 0;
 
play_attributes-fragsize = pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, 
 _sample_spec);

Fragsize is only for capture streams. It doesn't have any meaning for
playback streams. See
http://0pointer.de/lennart/projects/pulseaudio/doxygen/structpa__buffer__attr.html

 play_attributes-minreq = (uint32_t) -1;

If you set the PA_STREAM_EARLY_REQUESTS, you can use minreq to get
requests of some constant size, like you seem to want to do. See the
flag description at
http://0pointer.de/lennart/projects/pulseaudio/doxygen/def_8h.html#a6966d809483170bc6d2e6c16188850fc

 
 
 
 RECORD ATTRIBUTES:
 
 
 
 record_attributes = (pa_buffer_attr*) malloc (sizeof (pa_buffer_attr));
 
  record_attributes-maxlength = pa_usec_to_bytes (21 * PA_USEC_PER_MSEC, 
 _sample_spec); 

Set maxlength to -1 here too.

 record_attributes-tlength = (uint32_t) -1;

tlength doesn't have any effect on capture streams (-1 is probably a
fine initialization value, though).

 record_attributes-prebuf = (uint32_t) 0;

Prebuf doesn't have any effect on capture streams either.

 record_attributes-fragsize = pa_usec_to_bytes (20 * 
 PA_USEC_PER_MSEC, _sample_spec);

Is your samplerate 16 kHz?

  record_attributes-minreq 
 =pa_usec_to_bytes(1*PA_USEC_PER_SEC,_sample_spec);

Minreq doesn't have any effect on capture streams.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] stream-restore: simple fallback volume table

2011-04-21 Thread Tanu Kaskinen
From: Marc-André Lureau marcandre.lur...@gmail.com

Comment from Tanu Kaskinen: I made a few tweaks, so blame
me if the patch contains bugs.
---
 src/modules/module-stream-restore.c |   97 ++-
 1 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index 4d1ea04..c1baf8f 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -68,17 +68,24 @@ PA_MODULE_USAGE(
 restore_volume=Save/restore volumes? 
 restore_muted=Save/restore muted states? 
 on_hotplug=When new device becomes available, recheck streams? 
-on_rescue=When device becomes unavailable, recheck streams?);
+on_rescue=When device becomes unavailable, recheck streams? 
+fallback_table=filename);
 
 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
 #define IDENTIFICATION_PROPERTY module-stream-restore.id
 
+#define DEFAULT_FALLBACK_FILE PA_DEFAULT_CONFIG_DIR/stream-restore.table
+#define DEFAULT_FALLBACK_FILE_USER stream-restore.table
+
+#define WHITESPACE \n\r \t
+
 static const char* const valid_modargs[] = {
 restore_device,
 restore_volume,
 restore_muted,
 on_hotplug,
 on_rescue,
+fallback_table,
 NULL
 };
 
@@ -1596,7 +1603,88 @@ static pa_hook_result_t 
source_unlink_hook_callback(pa_core *c, pa_source *sourc
 return PA_HOOK_OK;
 }
 
-#define EXT_VERSION 1
+static int fill_db(struct userdata *u, const char *filename) {
+FILE *f;
+int n = 0;
+int ret = -1;
+char *fn = NULL;
+
+pa_assert(u);
+
+if (filename)
+f = fopen(fn = pa_xstrdup(filename), r);
+else
+f = pa_open_config_file(DEFAULT_FALLBACK_FILE, 
DEFAULT_FALLBACK_FILE_USER, NULL, fn);
+
+if (!f) {
+if (filename)
+pa_log(Failed to open %s: %s, filename, pa_cstrerror(errno));
+else
+ret = 0;
+
+goto finish;
+}
+
+while (!feof(f)) {
+char ln[256];
+char *d, *v;
+double db;
+
+if (!fgets(ln, sizeof(ln), f))
+break;
+
+n++;
+
+pa_strip_nl(ln);
+
+if (ln[0] == '#' || !*ln )
+continue;
+
+d = ln+strcspn(ln, WHITESPACE);
+v = d+strspn(d, WHITESPACE);
+
+if (!*v) {
+pa_log([%s:%u] failed to parse line - too few words, fn, n);
+goto finish;
+}
+
+*d = 0;
+if (pa_atod(v, db) = 0) {
+if (db = 0.0) {
+pa_datum key, data;
+struct entry e;
+
+pa_zero(e);
+e.version = ENTRY_VERSION;
+e.volume_valid = TRUE;
+pa_cvolume_set(e.volume, 1, pa_sw_volume_from_dB(db));
+pa_channel_map_init_mono(e.channel_map);
+
+key.data = (void *) ln;
+key.size = strlen(ln);
+
+data.data = (void *) e;
+data.size = sizeof(e);
+
+if (pa_database_set(u-database, key, data, FALSE) == 0)
+pa_log_debug(Setting %s to %0.2f dB., ln, db);
+} else
+pa_log_warn([%s:%u] Positive dB values are not allowed, not 
setting entry %s., fn, n, ln);
+} else
+pa_log_warn([%s:%u] Couldn't parse '%s' as a double, not setting 
entry %s., fn, n, v, ln);
+}
+
+trigger_save(u);
+ret = 0;
+
+finish:
+if (f)
+fclose(f);
+
+pa_xfree(fn);
+
+return ret;
+}
 
 static void apply_entry(struct userdata *u, const char *name, struct entry *e) 
{
 pa_sink_input *si;
@@ -1724,6 +1812,8 @@ static void dump_database(struct userdata *u) {
 }
 #endif
 
+#define EXT_VERSION 1
+
 static int extension_cb(pa_native_protocol *p, pa_module *m, 
pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
 struct userdata *u;
 uint32_t command;
@@ -2063,6 +2153,9 @@ int pa__init(pa_module*m) {
 pa_log_info(Successfully opened database file '%s'., fname);
 pa_xfree(fname);
 
+if (fill_db(u, pa_modargs_get_value(ma, fallback_table, NULL))  0)
+goto fail;
+
 #ifdef HAVE_DBUS
 u-dbus_protocol = pa_dbus_protocol_get(u-core);
 u-dbus_entries = pa_hashmap_new(pa_idxset_string_hash_func, 
pa_idxset_string_compare_func);
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] stream-restore: simple fallback volume table

2011-04-21 Thread Tanu Kaskinen
On Thu, 2011-04-21 at 14:31 +0300, Tanu Kaskinen wrote:
 From: Marc-André Lureau marcandre.lur...@gmail.com
 
 Comment from Tanu Kaskinen: I made a few tweaks, so blame
 me if the patch contains bugs.

The commit message is a bit short... The purpose of this patch is to
make it possible to configure stream volumes before pulseaudio is run
for the first time. This is useful, for example, in embedded products
where the default volumes have to be sensible already in the first boot.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2] call-state-tracker: New component.

2011-04-20 Thread Tanu Kaskinen
On Wed, 2011-04-20 at 11:36 +0300, Colin Guthrie wrote:
  The api object header could be located in
  src/extra_apis - that would make the api not directly dependent on a
  particular module. 
 
 If the API is not dependant on a particular module, what code calls
 pa_extra_api_register? I'd be happy enough defining this extra API as an
 IMC (c.f. IPC) system and thus make it very much tied to modules.

Hmm... did you get the impression that these apis would not necessarily
be tied to any modules at all? That was not the idea - the apis would be
implemented always by modules, but not necessarily by any particular
module. For example, if there was an api for getting the current call
state, it could be implemented by multiple modules, each of which would
use different logic for determining whether a call is active or not. The
modules would of course conflict with each other, so they could not be
loaded at the same time. This would be handled by
pa_extra_api_register() - only one module could have the api registered
at any given time, the other modules would get an error when they try to
call pa_extra_api_register().

  I've been using the term extra api here. I don't think it's the
  greatest name in the world, but that's the best I could think of. I'd
  like extension more, but that word is already used for other purposes.
 
 Yeah extension is already in use for protocol extensions I guess.
 
 How about pa_imc_*? (for inter-module comms) or is that perhaps too
 cryptic?

Yeah, it's cryptic, but it's also shorter. And extra api isn't an
obvious name either. I'm not sure which I like more. Probably imc.
Regarding function names, they will actually have form pa_imc_manager_*
or pa_extra_api_manager_* if I get to decide... The functions can be
methods of either some manager object or pa_core. If they're
implemented directly by pa_core, then the prefix will of course be
pa_core_, but I'd prefer having a separate manager object.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] match: don't double free in case of missing table file

2011-04-20 Thread Tanu Kaskinen
From: Marc-André Lureau marcandre.lur...@gmail.com

---
 src/modules/module-match.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index c8f2706..3eba149 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -95,7 +95,6 @@ static int load_rules(struct userdata *u, const char 
*filename) {
 f = pa_open_config_file(DEFAULT_MATCH_TABLE_FILE, 
DEFAULT_MATCH_TABLE_FILE_USER, NULL, fn);
 
 if (!f) {
-pa_xfree(fn);
 pa_log(Failed to open file config file: %s, pa_cstrerror(errno));
 goto finish;
 }
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] match: match rule earlier, in SINK_INPUT_NEW

2011-04-20 Thread Tanu Kaskinen
From: Marc-André Lureau marcandre.lur...@gmail.com

---
 src/modules/module-match.c |   35 +--
 1 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index 3eba149..b3316d4 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -43,7 +43,6 @@
 #include pulsecore/core-util.h
 #include pulsecore/modargs.h
 #include pulsecore/log.h
-#include pulsecore/core-subscribe.h
 #include pulsecore/sink-input.h
 #include pulsecore/core-util.h
 
@@ -77,7 +76,7 @@ struct rule {
 struct userdata {
 struct rule *rules;
 char *property_key;
-pa_subscription *subscription;
+pa_hook_slot *sink_input_new_hook_slot;
 };
 
 static int load_rules(struct userdata *u, const char *filename) {
@@ -191,23 +190,15 @@ finish:
 return ret;
 }
 
-static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, 
void *userdata) {
-struct userdata *u =  userdata;
-pa_sink_input *si;
+static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, 
pa_sink_input_new_data *si, struct userdata *u) {
 struct rule *r;
 const char *n;
 
 pa_assert(c);
 pa_assert(u);
 
-if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW))
-return;
-
-if (!(si = pa_idxset_get_by_index(c-sink_inputs, idx)))
-return;
-
 if (!(n = pa_proplist_gets(si-proplist, u-property_key)))
-return;
+return PA_HOOK_OK;
 
 pa_log_debug(Matching with %s, n);
 
@@ -216,14 +207,17 @@ static void callback(pa_core *c, 
pa_subscription_event_type_t t, uint32_t idx, v
 if (r-proplist) {
 pa_log_debug(updating proplist of sink input '%s', n);
 pa_proplist_update(si-proplist, PA_UPDATE_MERGE, r-proplist);
-} else {
+} else if (si-volume_writable) {
 pa_cvolume cv;
 pa_log_debug(changing volume of sink input '%s' to 0x%03x, 
n, r-volume);
 pa_cvolume_set(cv, si-sample_spec.channels, r-volume);
-pa_sink_input_set_volume(si, cv, TRUE, FALSE);
-}
+pa_sink_input_new_data_set_volume(si, cv);
+} else
+pa_log_debug(the volume of sink input '%s' is not writable, 
can't change it, n);
 }
 }
+
+return PA_HOOK_OK;
 }
 
 int pa__init(pa_module*m) {
@@ -239,7 +233,6 @@ int pa__init(pa_module*m) {
 
 u = pa_xnew(struct userdata, 1);
 u-rules = NULL;
-u-subscription = NULL;
 m-userdata = u;
 
 u-property_key = pa_xstrdup(pa_modargs_get_value(ma, key, 
PA_PROP_MEDIA_NAME));
@@ -247,10 +240,8 @@ int pa__init(pa_module*m) {
 if (load_rules(u, pa_modargs_get_value(ma, table, NULL))  0)
 goto fail;
 
-/* FIXME: Doing this asynchronously is just broken. This needs to
- * use a hook! */
-
-u-subscription = pa_subscription_new(m-core, 
PA_SUBSCRIPTION_MASK_SINK_INPUT, callback, u);
+/* hook EARLY - 1, to match before stream-restore */
+u-sink_input_new_hook_slot = 
pa_hook_connect(m-core-hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY - 
1, (pa_hook_cb_t) sink_input_new_hook_callback, u);
 
 pa_modargs_free(ma);
 return 0;
@@ -272,8 +263,8 @@ void pa__done(pa_module*m) {
 if (!(u = m-userdata))
 return;
 
-if (u-subscription)
-pa_subscription_free(u-subscription);
+if (u-sink_input_new_hook_slot)
+pa_hook_slot_free(u-sink_input_new_hook_slot);
 
 if (u-property_key)
 pa_xfree(u-property_key);
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2] call-state-tracker: New component.

2011-04-20 Thread Tanu Kaskinen
On Wed, 2011-04-20 at 15:19 +0300, Colin Guthrie wrote:
 OK, so the manager object is separate but kept in the core? Seems fine
 by me to keep things neatly separated.

Yep.

 I thinking of taking a pop at this at some point soon (if you don't beat
 me to it), so can we decide on the name now?
 
 Anyone got any better naming suggestions?
 
 pa_imc_manager_* (Pro: short, Con: Inter Module Comms cryptic)
 pa_extra_api_manager_* (Pro: clear, Con: long, Extension vs. Extra which
 is which and for what purpose?)
 pa_xapi_manager_* (Pro: short, Con: might be confused with X11)
 pa_mxapi_manager_* (Pro: quite short, Con: Module eXtension API but
 still quite cryptic)
 
 I'm not really blown away by any of them :s

I'll vote for pa_imc_manager_*.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] RFC: Filter module loader

2011-04-20 Thread Tanu Kaskinen
On Fri, 2011-04-15 at 20:55 +0200, Colin Guthrie wrote:
 Also, I had to apply this patch to equalizer-sink to prevent it from
 crashing the server on unload:
 
 diff --git a/src/modules/module-equalizer-sink.c
 b/src/modules/module-equalizer-sink.c
 index 0bbb23a..611f7dd 100644
 --- a/src/modules/module-equalizer-sink.c
 +++ b/src/modules/module-equalizer-sink.c
 @@ -1286,7 +1286,7 @@ void pa__done(pa_module*m) {
 
  save_state(u);
 
 -dbus_done(u);
 +//dbus_done(u);
 
  for(c = 0; c  u-channels; ++c)
  pa_xfree(u-base_profiles[c]);
 
 
 I mentioned this in another thread... hopefully someone more familiar
 with dbus can take a look at the underlying issue here :)

I took a look. The issue was that the dbus protocol used a string from
the equalizer module as a key to an internal hashmap, instead a copy of
the string. This caused trouble when the equalizer module freed the
string.

A patch is coming.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] protocol-dbus: Fix some memory management bugs.

2011-04-20 Thread Tanu Kaskinen
There were several memory leaks. In addition to those,
pa_dbus_protocol_add_interface() used a string from the
caller as a key to a hashmap, instead of a copy of the
string. This caused trouble when the caller freed the
string while the key was still in use in the hashmap.
---
 src/pulsecore/protocol-dbus.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
index c329915..8784c34 100644
--- a/src/pulsecore/protocol-dbus.c
+++ b/src/pulsecore/protocol-dbus.c
@@ -742,7 +742,7 @@ int pa_dbus_protocol_add_interface(pa_dbus_protocol *p,
 obj_entry-interfaces = pa_hashmap_new(pa_idxset_string_hash_func, 
pa_idxset_string_compare_func);
 obj_entry-introspection = NULL;
 
-pa_hashmap_put(p-objects, path, obj_entry);
+pa_hashmap_put(p-objects, obj_entry-path, obj_entry);
 obj_entry_created = TRUE;
 }
 
@@ -770,11 +770,6 @@ int pa_dbus_protocol_add_interface(pa_dbus_protocol *p,
 return 0;
 
 fail:
-if (obj_entry_created) {
-pa_hashmap_remove(p-objects, path);
-pa_xfree(obj_entry);
-}
-
 return -1;
 }
 
@@ -804,6 +799,7 @@ static void method_handler_free_cb(void *p, void *userdata) 
{
 }
 
 pa_xfree((pa_dbus_arg_info *) h-arguments);
+pa_xfree(h);
 }
 
 static void method_signature_free_cb(void *p, void *userdata) {
@@ -945,6 +941,7 @@ static void signal_paths_entry_free(struct 
signal_paths_entry *e) {
 while ((path = pa_idxset_steal_first(e-paths, NULL)))
 pa_xfree(path);
 
+pa_idxset_free(e-paths, NULL, NULL);
 pa_xfree(e);
 }
 
@@ -966,9 +963,12 @@ int 
pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *
 while ((object_path = 
pa_idxset_steal_first(conn_entry-all_signals_objects, NULL)))
 pa_xfree(object_path);
 
+pa_idxset_free(conn_entry-all_signals_objects, NULL, NULL);
+
 while ((signal_paths_entry = 
pa_hashmap_steal_first(conn_entry-listening_signals)))
 signal_paths_entry_free(signal_paths_entry);
 
+pa_hashmap_free(conn_entry-listening_signals, NULL, NULL);
 pa_xfree(conn_entry);
 
 return 0;
-- 
1.7.4.4

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] glib functions on PA

2011-04-20 Thread Tanu Kaskinen
On Thu, 2011-04-21 at 10:13 +0530, Arun Raghavan wrote:
 On Wed, 2011-04-20 at 23:26 -0500, Margarita Olaya wrote:
  Hi,
  
  The initial implementation of  jack detection is using threads and
  simple file operations like open, close and read currently I'm looking
  into using pa_threads and glib functions. First step It is simple
  enough e.g change threads by pa_threads and for file operations I have
  
  u-fd = g_open(u-device_id, O_RDONLY)
  ioch = g_io_channel_unix_new(u-fd);
  
  then use g_io_channel_read_chars() instead of read.
  
  I'm wonder if it is the beast approach or I'm missing any PA function
  that fits better for this purpose.
 
 I'm not aware of any PA code that uses glib for this. module-pipe-sink
 seems to do most of the things you need so that might serve as a good
 starting point.

Also, the server side code doesn't use glib for anything - the glib
dependency has been avoided on purpose. (I don't know or remember the
details why Lennart has been avoiding glib - is it only to keep the
amount of dependencies low, or are there some other reasons why PA
shouldn't use glib.)

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] tests: improve resampler test

2011-04-19 Thread Tanu Kaskinen
From: Marc-André Lureau marcandre.lur...@gmail.com

---
 src/tests/resampler-test.c |  207 +--
 1 files changed, 197 insertions(+), 10 deletions(-)

diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c
index 82198b5..69d7ab0 100644
--- a/src/tests/resampler-test.c
+++ b/src/tests/resampler-test.c
@@ -22,7 +22,13 @@
 #endif
 
 #include stdio.h
+#include getopt.h
+#include locale.h
 
+#include pulse/i18n.h
+#include pulse/pulseaudio.h
+
+#include pulse/rtclock.h
 #include pulse/sample.h
 #include pulse/volume.h
 
@@ -31,6 +37,8 @@
 #include pulsecore/endianmacros.h
 #include pulsecore/memblock.h
 #include pulsecore/sample-util.h
+#include pulsecore/core-rtclock.h
+#include pulsecore/core-util.h
 
 static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
 void *d;
@@ -241,10 +249,78 @@ static pa_memblock* generate_block(pa_mempool *pool, 
const pa_sample_spec *ss) {
 return r;
 }
 
+static void help(const char *argv0) {
+printf(_(%s [options]\n\n
+ -h, --helpShow this help\n
+ -v, --verbose Print debug messages\n
+   --from-rate=SAMPLERATE  From sample rate in Hz 
(defaults to 44100)\n
+   --from-format=SAMPLEFORMAT  From sample type (defaults 
to s16le)\n
+   --from-channels=CHANNELSFrom number of channels 
(defaults to 1)\n
+   --to-rate=SAMPLERATETo sample rate in Hz 
(defaults to 44100)\n
+   --to-format=SAMPLEFORMATTo sample type (defaults 
to s16le)\n
+   --to-channels=CHANNELS  To number of channels 
(defaults to 1)\n
+   --resample-method=METHODResample method (defaults 
to auto)\n
+   --seconds=SECONDS   From stream duration 
(defaults to 60)\n
+ \n
+ If the formats are not specified, the test performs all formats 
combinations,\n
+ back and forth.\n
+ \n
+ Sample type must be one of s16le, s16be, u8, float32le, 
float32be, ulaw, alaw,\n
+ 32le, s32be (defaults to s16ne)\n
+ \n
+ See --dump-resample-methods for possible values of resample 
methods.\n),
+ argv0);
+}
+
+enum {
+ARG_VERSION = 256,
+ARG_FROM_SAMPLERATE,
+ARG_FROM_SAMPLEFORMAT,
+ARG_FROM_CHANNELS,
+ARG_TO_SAMPLERATE,
+ARG_TO_SAMPLEFORMAT,
+ARG_TO_CHANNELS,
+ARG_SECONDS,
+ARG_RESAMPLE_METHOD,
+ARG_DUMP_RESAMPLE_METHODS
+};
+
+static void dump_resample_methods(void) {
+int i;
+
+for (i = 0; i  PA_RESAMPLER_MAX; i++)
+if (pa_resample_method_supported(i))
+printf(%s\n, pa_resample_method_to_string(i));
+
+}
+
 int main(int argc, char *argv[]) {
-pa_mempool *pool;
+pa_mempool *pool = NULL;
 pa_sample_spec a, b;
 pa_cvolume v;
+int ret = 1, verbose = 0, c;
+pa_bool_t all_formats = TRUE;
+pa_resample_method_t method;
+int seconds;
+
+static const struct option long_options[] = {
+{help,  0, NULL, 'h'},
+{verbose,   0, NULL, 'v'},
+{version,   0, NULL, ARG_VERSION},
+{from-rate, 1, NULL, ARG_FROM_SAMPLERATE},
+{from-format,   1, NULL, ARG_FROM_SAMPLEFORMAT},
+{from-channels, 1, NULL, ARG_FROM_CHANNELS},
+{to-rate,   1, NULL, ARG_TO_SAMPLERATE},
+{to-format, 1, NULL, ARG_TO_SAMPLEFORMAT},
+{to-channels,   1, NULL, ARG_TO_CHANNELS},
+{seconds,   1, NULL, ARG_SECONDS},
+{resample-method,   1, NULL, ARG_RESAMPLE_METHOD},
+{dump-resample-methods, 0, NULL, ARG_DUMP_RESAMPLE_METHODS},
+{NULL,0, NULL, 0}
+};
+
+setlocale(LC_ALL, );
+bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
 
 pa_log_set_level(PA_LOG_DEBUG);
 
@@ -252,22 +328,131 @@ int main(int argc, char *argv[]) {
 
 a.channels = b.channels = 1;
 a.rate = b.rate = 44100;
-
+a.format = b.format = PA_SAMPLE_S16LE;
 v.channels = a.channels;
 v.values[0] = pa_sw_volume_from_linear(0.5);
 
+method = PA_RESAMPLER_AUTO;
+seconds = 60;
+
+while ((c = getopt_long(argc, argv, hv, long_options, NULL)) != -1) {
+
+switch (c) {
+case 'h' :
+help(argv[0]);
+ret = 0;
+goto quit;
+
+case 'v':
+pa_log_set_level(PA_LOG_DEBUG);
+verbose = 1;
+ret = 0;
+break;
+
+case ARG_VERSION:
+printf(_(%s %s\n), argv[0], PACKAGE_VERSION);
+ret = 0;
+goto quit;
+
+case ARG_DUMP_RESAMPLE_METHODS:
+dump_resample_methods();
+ret = 0;
+   

Re: [pulseaudio-discuss] [PATCH v2] call-state-tracker: New component.

2011-04-18 Thread Tanu Kaskinen
On Mon, 2011-04-18 at 11:35 +0300, Colin Guthrie wrote:
  I'd be interested in implementing at some point (no promises or
  timelines) a small framework for making inter-module communication
  easier, or at least cleaner (this kind of hacks in pulsecore are
  actually very easy to work with, but clean they are not). The main
  motivation for this would be ripping out the dbus stuff from
  module-stream-restore. The dbus API implementation in
  module-stream-restore.c takes about a half of the whole file, which
  makes reading the stream-restore code more difficult than it should be.
  I'd like to keep the dbus interface implementation in
  module-dbus-protocol only. For this to be possible, there would need to
  be some way for the modules to talk to each other. It could be solved in
  a similar way as this call-state-tracker is done, but I'd prefer a
  generic framework that modules could use to publish extra APIs that
  other modules can then use.
 
 
 Which probably makes my comments seem a little more sane :D
 
 Do you have any specific requirements for this inter-module IPC? Do we
 just need a hook system with random data pointer + userdata? The random
 data pointer would be specific to the caller/callee pair and the
 userdata would be as per usual. Anything more specific than that needed?

I'm not sure what you exactly mean. This is what I had in mind for the
stuff that needs to be added to the core, I guess it's pretty close to
what you described:

For publishing APIs:

/* Returns a negative error code if the extra api is already registered. */
int pa_extra_api_register(const char *name, void *api);

void pa_extra_api_unregister(const_char *name);

For consuming APIs:

/* Returns the currently registered api object,
 * or NULL if the api isn't registered right now. */
void *pa_extra_api_get(const char *name);

Additionally, there would be a couple of hooks defined for getting
notifications about APIs getting registered and unregistered.

The api object would be a struct with function pointers. The API
provider would create instances of that struct and provide the function
implementation. The API consumer would talk to the provider using those
function pointers. The api object header could be located in
src/extra_apis - that would make the api not directly dependent on a
particular module. I don't really have real-world requirements for
generic apis that could be provided by multiple modules, but I can't
see any costs either for this genericity, other than some minimal added
clutter in the src directory.

I've been using the term extra api here. I don't think it's the
greatest name in the world, but that's the best I could think of. I'd
like extension more, but that word is already used for other purposes.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] sink-input: Check flat volume with pa_sink_flat_volume_enabled().

2011-04-15 Thread Tanu Kaskinen
Checking just the flag doesn't work if the sink uses volume sharing, because
such sinks never have PA_SINK_FLAT_VOLUME set.
---
 src/pulsecore/sink-input.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 46f26f9..1931d99 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -1020,7 +1020,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const 
pa_cvolume *volume, pa_boo
 pa_assert(volume-channels == 1 || pa_cvolume_compatible(volume, 
i-sample_spec));
 pa_assert(i-volume_writable);
 
-if ((i-sink-flags  PA_SINK_FLAT_VOLUME)  !absolute) {
+if (!absolute  pa_sink_flat_volume_enabled(i-sink)) {
 v = i-sink-reference_volume;
 pa_cvolume_remap(v, i-sink-channel_map, i-channel_map);
 
@@ -1043,7 +1043,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const 
pa_cvolume *volume, pa_boo
 i-volume = *volume;
 i-save_volume = save;
 
-if (i-sink-flags  PA_SINK_FLAT_VOLUME) {
+if (pa_sink_flat_volume_enabled(i-sink)) {
 /* We are in flat volume mode, so let's update all sink input
  * volumes and update the flat volume of the sink */
 
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] pulseaudio

2011-04-12 Thread Tanu Kaskinen
On Tue, 2011-04-12 at 12:30 -0400, Sean McNamara wrote:
 Hi,
 
 On Tue, Apr 12, 2011 at 12:15 PM, duportail po...@telenet.be wrote:
  Try to test the new xubuntu 11.04 with kde on a multi-user system.
  The first user (for example user1) can log in and gets a default sink from
  pulse.
  The second user(for example user2) that will log in gets a auto_null because
  pulse did not found any sinks.
  If i log out user1, than user2 can get a default sink by kill and start
  pulse.
  Where should be the reason?
 
 This is the classic multi-user problem: you're using a soundcard
 without hardware mixing, so only one ALSA application can take direct
 control of the hardware device at a time. user1's pulseaudio daemon
 takes control of it, so obviously user2's PA daemon will just get
 Device or resource busy when trying to snd_pcm_open() on hw:0 (for
 example). This problem has existed since ALSA existed. There's no
 direct fix without scrapping the API and rewriting it.

Actually, this situation is supposed to be handled just fine (unless
duportail expects both users to be able to use the audio hw
simultaneously, which he doesn't mention). If this doesn't work, xubuntu
is broken. Some things that can cause this problem: the users are in the
audio group, consolekit isn't running or consolekit's udev-acl isn't
in use.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] sink-input: Don't assert while trying to get non-readable volume

2011-04-11 Thread Tanu Kaskinen
On Sun, 2011-04-10 at 16:52 +0530, Arun Raghavan wrote:
 Since no clients currently handle non-readable volumes, we handle this
 condition more gracefully (return PA_VOLUME_NORM). In the future, this
 could probably changed into an error return instead of an assert so that
 a non-conformant client doesn't bring the daemon down.

When I added the assertion, the idea was that whatever code calls
pa_sink_input_get_volume() calls first
pa_sink_input_is_volume_readable(). And I at least tried to add those
checks everywhere. How are you able to hit the assertion?

My current plan for non-readable volume is a slightly different, btw.
Instead of having a volume_readable property, I plan to have a
volume_enabled property. When volume_enabled is false, within the daemon
the volume is still readable and writable (unless volume_writable is
false), it just doesn't have any effect. This gets rid of the problem of
how to restore the old volume after the volume is re-enabled when
switching between passthrough and normal modes. To the clients this is
not a very visible change - they still can not read (or they get always
PA_VOLUME_NORM as the value) or write the sink volume when it's in the
passthrough mode. But this behavior is implemented within
protocol-native etc, not enforced by the core.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] call-state-tracker: New component.

2011-04-06 Thread Tanu Kaskinen
On Wed, 2011-04-06 at 00:57 +0300, Maarten Bosmans wrote:
 What are the users of this state tracker? Is it only some out-of-tree
 Meego modules? Are you planning to submit those too? At least a
 snippet of how it should be used would be nice.

The users are mentioned in call-state-tracker.h. I guess I should have
said See call-state-tracker.h for details. in the commit message.
(Colin, feel free to add that sentence in the commit message, if you
decide to accept this patch.) So yes, only some out-of-tree Meego
modules use the call state tracker. About upstreaming those - there are
no concrete plans that I'm aware of. I guess the only issue is that we
are not confident that the code is clean enough...

 If I read correctly it is a global boolean state tracker that is a
 thin wrapper around pa_shared. Is it possible to add the update-hook
 capability pa_shared and just use that from the modules. It would
 probably mean a couple of lines more in the modules, but the
 functionality in pulsecore would be more generic and more widely
 usable then.

Adding an update hook to pa_shared would cover part of this, but it
wouldn't take care of the lifecycle management. pa_shared must be empty
when the daemon is shut down. The two modules that use the call state
tracker can (at least in theory) be loaded completely independently and
in any order. How should they take care of removing the item from
pa_shared? The most sensible way that I can see is reference counting,
and implementing that is easiest to do by having the code in
libpulsecore. I'd argue this is not in any significant way different
from what is done also by protocol-native.c and protocol-dbus.c etc.

Anyway, I do agree that it's not nice to clutter pulsecore with these
inter-module libraries. I sent the following message as a reply to the
patch yesterday, but from a wrong email address, so it got stuck in the
moderation queue:


This is sort of ugly - I think pulsecore isn't really the right place
for this kind of things. But take it if you don't think it's too ugly.
We depend on this patch on Maemo (and Meego too, I believe).

I'd be interested in implementing at some point (no promises or
timelines) a small framework for making inter-module communication
easier, or at least cleaner (this kind of hacks in pulsecore are
actually very easy to work with, but clean they are not). The main
motivation for this would be ripping out the dbus stuff from
module-stream-restore. The dbus API implementation in
module-stream-restore.c takes about a half of the whole file, which
makes reading the stream-restore code more difficult than it should be.
I'd like to keep the dbus interface implementation in
module-dbus-protocol only. For this to be possible, there would need to
be some way for the modules to talk to each other. It could be solved in
a similar way as this call-state-tracker is done, but I'd prefer a
generic framework that modules could use to publish extra APIs that
other modules can then use.


-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v2] call-state-tracker: New component.

2011-04-06 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

See call-state-tracker.h for details.

Changed in patch v2:
Don't take a reference of pa_core. The previous version would have
reintroduced the bug that was fixed in 1e381fbf.
---
 src/Makefile.am|1 +
 src/pulsecore/call-state-tracker.c |  125 
 src/pulsecore/call-state-tracker.h |   54 +++
 3 files changed, 180 insertions(+), 0 deletions(-)
 create mode 100644 src/pulsecore/call-state-tracker.c
 create mode 100644 src/pulsecore/call-state-tracker.h

diff --git a/src/Makefile.am b/src/Makefile.am
index bdedded..85c5602 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -835,6 +835,7 @@ libpulsecore_@PA_MAJORMINOR@_la_SOURCES = \
pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \
pulsecore/asyncq.c pulsecore/asyncq.h \
pulsecore/auth-cookie.c pulsecore/auth-cookie.h \
+   pulsecore/call-state-tracker.c pulsecore/call-state-tracker.h \
pulsecore/cli-command.c pulsecore/cli-command.h \
pulsecore/cli-text.c pulsecore/cli-text.h \
pulsecore/client.c pulsecore/client.h \
diff --git a/src/pulsecore/call-state-tracker.c 
b/src/pulsecore/call-state-tracker.c
new file mode 100644
index 000..0ac9be5
--- /dev/null
+++ b/src/pulsecore/call-state-tracker.c
@@ -0,0 +1,125 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include config.h
+#endif
+
+#include pulsecore/core.h
+#include pulsecore/hook-list.h
+#include pulsecore/log.h
+#include pulsecore/macro.h
+#include pulsecore/refcnt.h
+#include pulsecore/shared.h
+
+#include call-state-tracker.h
+
+struct pa_call_state_tracker {
+PA_REFCNT_DECLARE;
+
+pa_core *core;
+pa_bool_t active;
+pa_hook hooks[PA_CALL_STATE_HOOK_MAX];
+};
+
+static pa_call_state_tracker* call_state_tracker_new(pa_core *c) {
+pa_call_state_tracker *t;
+pa_call_state_hook_t h;
+
+pa_assert(c);
+
+t = pa_xnew0(pa_call_state_tracker, 1);
+PA_REFCNT_INIT(t);
+t-core = c;
+t-active = FALSE;
+
+for (h = 0; h  PA_CALL_STATE_HOOK_MAX; h++)
+pa_hook_init(t-hooks[h], t);
+
+pa_assert_se(pa_shared_set(c, call-state-tracker, t) = 0);
+
+return t;
+}
+
+pa_call_state_tracker *pa_call_state_tracker_get(pa_core *core) {
+pa_call_state_tracker *t;
+
+if ((t = pa_shared_get(core, call-state-tracker)))
+return pa_call_state_tracker_ref(t);
+
+return call_state_tracker_new(core);
+}
+
+pa_call_state_tracker *pa_call_state_tracker_ref(pa_call_state_tracker *t) {
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+PA_REFCNT_INC(t);
+
+return t;
+}
+
+void pa_call_state_tracker_unref(pa_call_state_tracker *t) {
+pa_call_state_hook_t h;
+
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+if (PA_REFCNT_DEC(t)  0)
+return;
+
+for (h = 0; h  PA_CALL_STATE_HOOK_MAX; h++)
+pa_hook_done(t-hooks[h]);
+
+pa_assert_se(pa_shared_remove(t-core, call-state-tracker) = 0);
+
+pa_xfree(t);
+}
+
+pa_bool_t pa_call_state_tracker_get_active(pa_call_state_tracker *t) {
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+return t-active;
+}
+
+void pa_call_state_tracker_set_active(pa_call_state_tracker *t, pa_bool_t 
active) {
+pa_bool_t changed;
+
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+changed = active != t-active;
+
+t-active = active;
+
+if (changed)
+pa_hook_fire(t-hooks[PA_CALL_STATE_HOOK_CHANGED], (void *) active);
+
+pa_log_debug(Call state set %s (%s), active ? active : inactive, 
changed ? changed : not changed);
+}
+
+pa_hook *pa_call_state_tracker_hooks(pa_call_state_tracker *t) {
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+return t-hooks;
+}
diff --git a/src/pulsecore/call-state-tracker.h 
b/src/pulsecore/call-state-tracker.h
new file mode 100644
index 000..9a6c60b
--- /dev/null
+++ b/src/pulsecore/call-state-tracker.h
@@ -0,0 +1,54 @@
+#ifndef foocallstatetrackerhfoo
+#define foocallstatetrackerhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright

Re: [pulseaudio-discuss] [PATCH] call-state-tracker: New component.

2011-04-06 Thread Tanu Kaskinen
On Wed, 2011-04-06 at 11:41 +0300, Tanu Kaskinen wrote:
 On Wed, 2011-04-06 at 00:57 +0300, Maarten Bosmans wrote:
  What are the users of this state tracker? Is it only some out-of-tree
  Meego modules? Are you planning to submit those too? At least a
  snippet of how it should be used would be nice.
 
 The users are mentioned in call-state-tracker.h. I guess I should have
 said See call-state-tracker.h for details. in the commit message.
 (Colin, feel free to add that sentence in the commit message, if you
 decide to accept this patch.) So yes, only some out-of-tree Meego
 modules use the call state tracker. About upstreaming those - there are
 no concrete plans that I'm aware of. I guess the only issue is that we
 are not confident that the code is clean enough...

I was reminded that we actually already have libmeego-common (a
support library for the out-of-tree modules) in the package that
provides the meego modules, and this feature would arguably fit better
in libmeego-common than libpulsecore. I would still like to see as much
stuff in upstream as possible, so I won't recommend that you reject the
patch, but it really isn't a big deal if you do.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2] call-state-tracker: New component.

2011-04-06 Thread Tanu Kaskinen
On Wed, 2011-04-06 at 14:23 +0100, Colin Guthrie wrote:
 'Twas brillig, and Tanu Kaskinen at 06/04/11 12:33 did gyre and gimble:
  +/* This is a shared singleton object, currently used by Meego's voice and
  + * policy enforcement modules. The purpose of the object is just to 
  maintain
  + * a boolean state of call is active or call is not active, and to 
  provide
  + * notification hooks for tracking state changes. So one module will be 
  setting
  + * the state (the voice module) and one or more modules will follow the 
  state
  + * through the hooks (the policy enforcement module). */
 
 Could I use this approach to, for example, extend module-stream-restore
 and module-device-restore, to save particular keys in a stream, or
 device proplist?
snip

I don't see any reason why you couldn't.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] stream-restore: add version to new entry.

2011-04-05 Thread Tanu Kaskinen
From: Harri Mähönen ext-harri.maho...@nokia.com

---
 src/modules/module-stream-restore.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index 8edfee0..d27982b 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -650,6 +650,7 @@ static void handle_add_entry(DBusConnection *conn, 
DBusMessage *msg, void *userd
 pa_assert_se(pa_hashmap_put(u-dbus_entries, dbus_entry-entry_name, 
dbus_entry) == 0);
 
 e = pa_xnew0(struct entry, 1);
+e-version = ENTRY_VERSION;
 e-muted_valid = TRUE;
 e-volume_valid = !!map.channels;
 e-device_valid = !!device[0];
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] call-state-tracker: New component.

2011-04-05 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

---
 src/Makefile.am|1 +
 src/pulsecore/call-state-tracker.c |  127 
 src/pulsecore/call-state-tracker.h |   54 +++
 3 files changed, 182 insertions(+), 0 deletions(-)
 create mode 100644 src/pulsecore/call-state-tracker.c
 create mode 100644 src/pulsecore/call-state-tracker.h

diff --git a/src/Makefile.am b/src/Makefile.am
index bdedded..85c5602 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -835,6 +835,7 @@ libpulsecore_@PA_MAJORMINOR@_la_SOURCES = \
pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \
pulsecore/asyncq.c pulsecore/asyncq.h \
pulsecore/auth-cookie.c pulsecore/auth-cookie.h \
+   pulsecore/call-state-tracker.c pulsecore/call-state-tracker.h \
pulsecore/cli-command.c pulsecore/cli-command.h \
pulsecore/cli-text.c pulsecore/cli-text.h \
pulsecore/client.c pulsecore/client.h \
diff --git a/src/pulsecore/call-state-tracker.c 
b/src/pulsecore/call-state-tracker.c
new file mode 100644
index 000..a605685
--- /dev/null
+++ b/src/pulsecore/call-state-tracker.c
@@ -0,0 +1,127 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include config.h
+#endif
+
+#include pulsecore/core.h
+#include pulsecore/hook-list.h
+#include pulsecore/log.h
+#include pulsecore/macro.h
+#include pulsecore/refcnt.h
+#include pulsecore/shared.h
+
+#include call-state-tracker.h
+
+struct pa_call_state_tracker {
+PA_REFCNT_DECLARE;
+
+pa_core *core;
+pa_bool_t active;
+pa_hook hooks[PA_CALL_STATE_HOOK_MAX];
+};
+
+static pa_call_state_tracker* call_state_tracker_new(pa_core *c) {
+pa_call_state_tracker *t;
+pa_call_state_hook_t h;
+
+pa_assert(c);
+
+t = pa_xnew0(pa_call_state_tracker, 1);
+PA_REFCNT_INIT(t);
+t-core = pa_core_ref(c);
+t-active = FALSE;
+
+for (h = 0; h  PA_CALL_STATE_HOOK_MAX; h++)
+pa_hook_init(t-hooks[h], t);
+
+pa_assert_se(pa_shared_set(c, call-state-tracker, t) = 0);
+
+return t;
+}
+
+pa_call_state_tracker *pa_call_state_tracker_get(pa_core *core) {
+pa_call_state_tracker *t;
+
+if ((t = pa_shared_get(core, call-state-tracker)))
+return pa_call_state_tracker_ref(t);
+
+return call_state_tracker_new(core);
+}
+
+pa_call_state_tracker *pa_call_state_tracker_ref(pa_call_state_tracker *t) {
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+PA_REFCNT_INC(t);
+
+return t;
+}
+
+void pa_call_state_tracker_unref(pa_call_state_tracker *t) {
+pa_call_state_hook_t h;
+
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+if (PA_REFCNT_DEC(t)  0)
+return;
+
+for (h = 0; h  PA_CALL_STATE_HOOK_MAX; h++)
+pa_hook_done(t-hooks[h]);
+
+pa_assert_se(pa_shared_remove(t-core, call-state-tracker) = 0);
+
+pa_core_unref(t-core);
+
+pa_xfree(t);
+}
+
+pa_bool_t pa_call_state_tracker_get_active(pa_call_state_tracker *t) {
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+return t-active;
+}
+
+void pa_call_state_tracker_set_active(pa_call_state_tracker *t, pa_bool_t 
active) {
+pa_bool_t changed;
+
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+changed = active != t-active;
+
+t-active = active;
+
+if (changed)
+pa_hook_fire(t-hooks[PA_CALL_STATE_HOOK_CHANGED], (void *) active);
+
+pa_log_debug(Call state set %s (%s), active ? active : inactive, 
changed ? changed : not changed);
+}
+
+pa_hook *pa_call_state_tracker_hooks(pa_call_state_tracker *t) {
+pa_assert(t);
+pa_assert(PA_REFCNT_VALUE(t) = 1);
+
+return t-hooks;
+}
diff --git a/src/pulsecore/call-state-tracker.h 
b/src/pulsecore/call-state-tracker.h
new file mode 100644
index 000..9a6c60b
--- /dev/null
+++ b/src/pulsecore/call-state-tracker.h
@@ -0,0 +1,54 @@
+#ifndef foocallstatetrackerhfoo
+#define foocallstatetrackerhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+
+  PulseAudio is free software; you can redistribute it and/or modify

[pulseaudio-discuss] [PATCH] bluetooth: drop data every 500ms on oor condition

2011-04-04 Thread Tanu Kaskinen
From: Marc-André Lureau marc-andre.lur...@nokia.com

---
 src/modules/bluetooth/module-bluetooth-device.c |   25 --
 1 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index e4a2cef..bd1511b 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1671,17 +1671,20 @@ static void thread_func(void *userdata) {
 writable = FALSE;
 }
 
-if ((!u-source || 
!PA_SOURCE_IS_LINKED(u-source-thread_info.state))  do_write = 0  
writable) {
-pa_usec_t time_passed, next_write_at, sleep_for;
-
-/* Hmm, there is no input stream we could synchronize
- * to. So let's estimate when we need to wake up the 
latest */
-
-time_passed = pa_rtclock_now() - u-started_at;
-next_write_at = pa_bytes_to_usec(u-write_index, 
u-sample_spec);
-sleep_for = time_passed  next_write_at ? next_write_at - 
time_passed : 0;
-
-/* pa_log(Sleeping for %lu; time passed %lu, next write at 
%lu, (unsigned long) sleep_for, (unsigned long) time_passed, (unsigned 
long)next_write_at); */
+if ((!u-source || 
!PA_SOURCE_IS_LINKED(u-source-thread_info.state))  do_write = 0) {
+pa_usec_t sleep_for;
+pa_usec_t time_passed, next_write_at;
+
+if (writable) {
+/* Hmm, there is no input stream we could synchronize
+ * to. So let's estimate when we need to wake up the 
latest */
+time_passed = pa_rtclock_now() - u-started_at;
+next_write_at = pa_bytes_to_usec(u-write_index, 
u-sample_spec);
+sleep_for = time_passed  next_write_at ? 
next_write_at - time_passed : 0;
+/* pa_log(Sleeping for %lu; time passed %lu, next 
write at %lu, (unsigned long) sleep_for, (unsigned long) time_passed, 
(unsigned long)next_write_at); */
+} else
+/* drop stream every 500 ms */
+sleep_for = PA_USEC_PER_MSEC * 500;
 
 pa_rtpoll_set_timer_relative(u-rtpoll, sleep_for);
 disable_timer = FALSE;
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] alsa: Fix log output to inform about positive base volumes correctly.

2011-04-04 Thread Tanu Kaskinen
This fix was done for _set_port_cb() already, but the first fix didn't fix
setup_mixer(). Now that's done too.
---
 src/modules/alsa/alsa-sink.c   |5 +
 src/modules/alsa/alsa-source.c |5 +
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 9ed4d4d..ccbc062 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1724,10 +1724,7 @@ static int setup_mixer(struct userdata *u, pa_bool_t 
ignore_dB, pa_bool_t sync_v
 u-sink-base_volume = 
pa_sw_volume_from_dB(-u-mixer_path-max_dB);
 u-sink-n_volume_steps = PA_VOLUME_NORM+1;
 
-if (u-mixer_path-max_dB  0.0)
-pa_log_info(Fixing base volume to %0.2f dB, 
pa_sw_volume_to_dB(u-sink-base_volume));
-else
-pa_log_info(No particular base volume set, fixing to 0 dB);
+pa_log_info(Fixing base volume to %0.2f dB, 
pa_sw_volume_to_dB(u-sink-base_volume));
 
 } else {
 pa_log_info(Hardware volume ranges from %li to %li., 
u-mixer_path-min_volume, u-mixer_path-max_volume);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 6d18e60..3355fbd 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1465,10 +1465,7 @@ static int setup_mixer(struct userdata *u, pa_bool_t 
ignore_dB) {
 u-source-base_volume = 
pa_sw_volume_from_dB(-u-mixer_path-max_dB);
 u-source-n_volume_steps = PA_VOLUME_NORM+1;
 
-if (u-mixer_path-max_dB  0.0)
-pa_log_info(Fixing base volume to %0.2f dB, 
pa_sw_volume_to_dB(u-source-base_volume));
-else
-pa_log_info(No particular base volume set, fixing to 0 dB);
+pa_log_info(Fixing base volume to %0.2f dB, 
pa_sw_volume_to_dB(u-source-base_volume));
 
 } else {
 pa_log_info(Hardware volume ranges from %li to %li., 
u-mixer_path-min_volume, u-mixer_path-max_volume);
-- 
1.7.4.2

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] how to read exactly 320 samples

2011-04-04 Thread Tanu Kaskinen
On Mon, 2011-04-04 at 00:27 -0700, sohail abbasi wrote:
 Hi , everyone 
 
 I am new to audio programing(as well pulseaudio). I have to add
 pulseaudio support in an application already working with ALSA and
 OSS. the designe of my application is such that I have to read 320
 samples in read function each time. stream attributes are 16bit ,
 16khz , and 2 channels. So I need to read 1280 bytes in
 pa_stream_peek. 
 
 But I am unable to read 320 samples each time. some time more , some
 time less ,and some time 0. How can I set buffer attributes to force
 pa_stream_read to read 320 samples each time.

Hmm... The documentation for the fragsize field of pa_buffer_attr seems
to imply that the fragment size is always a constant, which according to
your experience is not true. That's the only parameter for controlling
the fragment sizes when recording, so there's probably no way you can
make Pulseaudio give you constant size fragments.

You probably can and have to do some buffering in the pulseaudio support
component for the application you're working on. So when you get a
fragment from pulseaudio, you copy the data to an internal buffer and
give data to the application only if there's at least 1280 bytes
available, and of course exactly 1280 bytes at a time - any leftovers
will be saved until the next fragment arrives.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 5/5] bluetooth: Refuse to use the HSP profile if there is some other HSP device active.

2011-04-01 Thread Tanu Kaskinen
On Thu, 2011-03-31 at 15:30 +0300, Tanu Kaskinen wrote:
 On Thu, 2011-03-31 at 15:11 +0300, Tanu Kaskinen wrote:
  If no volunteers pop up, I guess I'll have to get a bluetooth dongle for
  my desktop so that I can test this myself.
 
 Never mind, I found a dongle already - I'll test it tomorrow.

Ok, tests are now done. I couldn't get any audio in the HSP mode (A2DP
worked fine). The sink seemed to be running and there were no errors,
the problem seemed to be just that the sink was not getting any wakeups
from the hardware. Before any BT hardware was connected,
module-bluetooth-discover printed some errors at startup, but apart from
this no-audio-with-hsp problem the errors didn't seem to cause any
trouble. The behavior was identical with the current git master and with
my patches applied.

Even though I got no audio, looking at pulseaudio logs it seemed like
sink_set_volume_cb was working alright, which was the only thing I
wanted to test anyway. So, I suggest now that patches 1-4 get merged,
along with the bluetooth: Fix HSP volume handling patch.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] bluetooth: Fix HSP volume handling.

2011-03-31 Thread Tanu Kaskinen
Previously the userdata for the volume callbacks was saved to
pa_core.shared only once when loading module-bluetooth-device, and only when
the SCO over PCM feature was used. That breaks volume handling in cases where
the HSP profile is used without the SCO over PCM setup. Now the userdata is
set always when a sink or source is created, and removed when a sink or source
is removed.
---
 src/modules/bluetooth/module-bluetooth-device.c |  101 +++---
 1 files changed, 69 insertions(+), 32 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index 540d48c..fd82ece 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1961,6 +1961,8 @@ static pa_hook_result_t source_state_changed_cb(pa_core 
*c, pa_source *s, struct
 
 /* Run from main thread */
 static int add_sink(struct userdata *u) {
+char *k;
+
 if (USE_SCO_OVER_PCM(u)) {
 pa_proplist *p;
 
@@ -2014,6 +2016,10 @@ static int add_sink(struct userdata *u) {
 if (u-profile == PROFILE_HSP) {
 u-sink-set_volume = sink_set_volume_cb;
 u-sink-n_volume_steps = 16;
+
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-sink);
+pa_shared_set(u-core, k, u);
+pa_xfree(k);
 }
 
 return 0;
@@ -2021,6 +2027,8 @@ static int add_sink(struct userdata *u) {
 
 /* Run from main thread */
 static int add_source(struct userdata *u) {
+char *k;
+
 if (USE_SCO_OVER_PCM(u)) {
 u-source = u-hsp.sco_source;
 pa_proplist_sets(u-source-proplist, bluetooth.protocol, hsp);
@@ -2079,6 +2087,10 @@ static int add_source(struct userdata *u) {
 if (u-profile == PROFILE_HSP) {
 u-source-set_volume = source_set_volume_cb;
 u-source-n_volume_steps = 16;
+
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-source);
+pa_shared_set(u-core, k, u);
+pa_xfree(k);
 }
 
 return 0;
@@ -2325,6 +2337,8 @@ static int init_profile(struct userdata *u) {
 
 /* Run from main thread */
 static void stop_thread(struct userdata *u) {
+char *k;
+
 pa_assert(u);
 
 if (u-thread) {
@@ -2349,11 +2363,23 @@ static void stop_thread(struct userdata *u) {
 }
 
 if (u-sink) {
+if (u-profile == PROFILE_HSP) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-sink);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+}
+
 pa_sink_unref(u-sink);
 u-sink = NULL;
 }
 
 if (u-source) {
+if (u-profile == PROFILE_HSP) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-source);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+}
+
 pa_source_unref(u-source);
 u-source = NULL;
 }
@@ -2383,8 +2409,20 @@ static int start_thread(struct userdata *u) {
 
 if (USE_SCO_OVER_PCM(u)) {
 if (sco_over_pcm_state_update(u)  0) {
-u-sink = NULL;
-u-source = NULL;
+char *k;
+
+if (u-sink) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-sink);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+u-sink = NULL;
+}
+if (u-source) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) 
u-source);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+u-source = NULL;
+}
 return -1;
 }
 
@@ -2421,6 +2459,22 @@ static int start_thread(struct userdata *u) {
 return 0;
 }
 
+static void save_sco_volume_callbacks(struct userdata *u) {
+pa_assert(u);
+pa_assert(USE_SCO_OVER_PCM(u));
+
+u-hsp.sco_sink_set_volume = u-hsp.sco_sink-set_volume;
+u-hsp.sco_source_set_volume = u-hsp.sco_source-set_volume;
+}
+
+static void restore_sco_volume_callbacks(struct userdata *u) {
+pa_assert(u);
+pa_assert(USE_SCO_OVER_PCM(u));
+
+u-hsp.sco_sink-set_volume = u-hsp.sco_sink_set_volume;
+u-hsp.sco_source-set_volume = u-hsp.sco_source_set_volume;
+}
+
 /* Run from main thread */
 static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
 struct userdata *u;
@@ -2474,9 +2528,15 @@ static int card_set_profile(pa_card *c, pa_card_profile 
*new_profile) {
 stop_thread(u);
 shutdown_bt(u);
 
+if (USE_SCO_OVER_PCM(u))
+restore_sco_volume_callbacks(u);
+
 u-profile = *d;
 u-sample_spec = u-requested_sample_spec;
 
+if (USE_SCO_OVER_PCM(u))
+save_sco_volume_callbacks(u);
+
 init_bt(u);
 
 if (u-profile != PROFILE_OFF)
@@ -2641,6 +2701,9 @@ static int add_card(struct userdata *u, const 
pa_bluetooth_device *device) {
 d = PA_CARD_PROFILE_DATA(u-card-active_profile);
 u-profile = *d;
 
+if (USE_SCO_OVER_PCM(u))
+save_sco_volume_callbacks(u);
+
 return 0;
 }
 
@@ -2704,7 

Re: [pulseaudio-discuss] [PATCH 5/5] bluetooth: Refuse to use the HSP profile if there is some other HSP device active.

2011-03-31 Thread Tanu Kaskinen
On Thu, 2011-03-31 at 15:11 +0300, Tanu Kaskinen wrote:
 If no volunteers pop up, I guess I'll have to get a bluetooth dongle for
 my desktop so that I can test this myself.

Never mind, I found a dongle already - I'll test it tomorrow.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 5/5] bluetooth: Refuse to use the HSP profile if there is some other HSP device active.

2011-03-30 Thread Tanu Kaskinen
On Mon, 2011-03-28 at 18:17 +0300, Luiz Augusto von Dentz wrote:
 There is a similar policy in BlueZ already for this and it is
 configurable via /etc/bluetooth/audio.conf, so I don't think
 hardcoding this on PA would do any better.

Ah, excellent, I didn't know that.

So the HSP profile locking part is unnecessary. It seems that I also put
some fixes for the userdata handling of the volume callbacks in the same
patch - I'll make a new patch for that part.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 5/5] bluetooth: Refuse to use the HSP profile if there is some other HSP device active.

2011-03-30 Thread Tanu Kaskinen
On Tue, 2011-03-29 at 23:16 +0300, Colin Guthrie wrote:
 'Twas brillig, and Luiz Augusto von Dentz at 28/03/11 16:17 did gyre and
 gimble:
  There is a similar policy in BlueZ already for this and it is
  configurable via /etc/bluetooth/audio.conf, so I don't think
  hardcoding this on PA would do any better.
 
 Tanu, what's the best route forward? Patches 1-4 still OK/valid or?

Yep, they're good (although it seems that the volume callbacks' userdata
handling needed some tuning still in the fifth patch, but I propose you
take the four patches and I send a new patch that fixes what there is to
fix).

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 0/5] SCO over PCM fixes

2011-03-28 Thread Tanu Kaskinen
Here are some fixes for the bluetooth SCO over PCM functionality. The patches
are old (except the one that removes the #ifdefs), so they should be pretty
well tested in Maemo. Rebasing on top of new upstream code isn't tested,
though, because I don't have a good setup for that.

Marc-André Lureau (3):
  bluetooth: use sco_sink/source to start with right state
  bluetooth: fix set_volume_cb on sco over pcm
  bluetooth: restore original sco_{sink,src}-set_volume when unloading

Tanu Kaskinen (2):
  bluetooth: Drop all #ifdef NOKIA directives.
  bluetooth: Refuse to use the HSP profile if there is some other HSP
device active.

 src/modules/bluetooth/module-bluetooth-device.c |  217 +++
 1 files changed, 145 insertions(+), 72 deletions(-)

-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/5] bluetooth: Drop all #ifdef NOKIA directives.

2011-03-28 Thread Tanu Kaskinen
The #ifdefs only added clutter. I don't see any reason to not compile the
SCO over PCM support in all the time.
---
 src/modules/bluetooth/module-bluetooth-device.c |   57 +++---
 1 files changed, 8 insertions(+), 49 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index ac0f16f..af08003 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -78,14 +78,9 @@ PA_MODULE_USAGE(
 rate=sample rate 
 channels=number of channels 
 path=device object path 
-auto_connect=automatically connect?);
-
-/*
-#ifdef NOKIA
+auto_connect=automatically connect? 
 sco_sink=SCO over PCM sink name 
-sco_source=SCO over PCM source name
-#endif
-*/
+sco_source=SCO over PCM source name);
 
 /* TODO: not close fd when entering suspend mode in a2dp */
 
@@ -103,10 +98,8 @@ static const char* const valid_modargs[] = {
 channels,
 path,
 auto_connect,
-#ifdef NOKIA
 sco_sink,
 sco_source,
-#endif
 NULL
 };
 
@@ -126,10 +119,8 @@ struct a2dp_info {
 
 struct hsp_info {
 pcm_capabilities_t pcm_capabilities;
-#ifdef NOKIA
 pa_sink *sco_sink;
 pa_source *sco_source;
-#endif
 pa_hook_slot *sink_state_changed_slot;
 pa_hook_slot *source_state_changed_slot;
 };
@@ -191,9 +182,7 @@ struct userdata {
 
 #define MAX_PLAYBACK_CATCH_UP_USEC (100*PA_USEC_PER_MSEC)
 
-#ifdef NOKIA
 #define USE_SCO_OVER_PCM(u) (u-profile == PROFILE_HSP  (u-hsp.sco_sink  
u-hsp.sco_source))
-#endif
 
 static int init_bt(struct userdata *u);
 static int init_profile(struct userdata *u);
@@ -1884,8 +1873,6 @@ static char *get_name(const char *type, pa_modargs *ma, 
const char *device_id, p
 return pa_sprintf_malloc(bluez_%s.%s, type, n);
 }
 
-#ifdef NOKIA
-
 static void sco_over_pcm_state_update(struct userdata *u) {
 pa_assert(u);
 pa_assert(USE_SCO_OVER_PCM(u));
@@ -1948,12 +1935,8 @@ static pa_hook_result_t source_state_changed_cb(pa_core 
*c, pa_source *s, struct
 return PA_HOOK_OK;
 }
 
-#endif
-
 /* Run from main thread */
 static int add_sink(struct userdata *u) {
-
-#ifdef NOKIA
 if (USE_SCO_OVER_PCM(u)) {
 pa_proplist *p;
 
@@ -1966,10 +1949,7 @@ static int add_sink(struct userdata *u) {
 if (!u-hsp.sink_state_changed_slot)
 u-hsp.sink_state_changed_slot = 
pa_hook_connect(u-core-hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], 
PA_HOOK_NORMAL, (pa_hook_cb_t) sink_state_changed_cb, u);
 
-} else
-#endif
-
-{
+} else {
 pa_sink_new_data data;
 pa_bool_t b;
 
@@ -2017,8 +1997,6 @@ static int add_sink(struct userdata *u) {
 
 /* Run from main thread */
 static int add_source(struct userdata *u) {
-
-#ifdef NOKIA
 if (USE_SCO_OVER_PCM(u)) {
 u-source = u-hsp.sco_source;
 pa_proplist_sets(u-source-proplist, bluetooth.protocol, hsp);
@@ -2026,10 +2004,7 @@ static int add_source(struct userdata *u) {
 if (!u-hsp.source_state_changed_slot)
 u-hsp.source_state_changed_slot = 
pa_hook_connect(u-core-hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], 
PA_HOOK_NORMAL, (pa_hook_cb_t) source_state_changed_cb, u);
 
-} else
-#endif
-
-{
+} else {
 pa_source_new_data data;
 pa_bool_t b;
 
@@ -2290,12 +2265,10 @@ static int setup_bt(struct userdata *u) {
 
 pa_log_debug(Connection to the device configured);
 
-#ifdef NOKIA
 if (USE_SCO_OVER_PCM(u)) {
 pa_log_debug(Configured to use SCO over PCM);
 return 0;
 }
-#endif
 
 pa_log_debug(Got the stream socket);
 
@@ -2384,7 +2357,6 @@ static int start_thread(struct userdata *u) {
 u-rtpoll = pa_rtpoll_new();
 pa_thread_mq_init(u-thread_mq, u-core-mainloop, u-rtpoll);
 
-#ifdef NOKIA
 if (USE_SCO_OVER_PCM(u)) {
 if (u-transport) {
 if (bt_transport_acquire(u, TRUE)  0)
@@ -2397,7 +2369,6 @@ static int start_thread(struct userdata *u) {
 /* FIXME: monitor stream_fd error */
 return 0;
 }
-#endif
 
 if (!(u-thread = pa_thread_new(bluetooth, thread_func, u))) {
 pa_log_error(Failed to create IO thread);
@@ -2464,17 +2435,15 @@ static int card_set_profile(pa_card *c, pa_card_profile 
*new_profile) {
 
 if (u-sink) {
 inputs = pa_sink_move_all_start(u-sink, NULL);
-#ifdef NOKIA
+
 if (!USE_SCO_OVER_PCM(u))
-#endif
 pa_sink_unlink(u-sink);
 }
 
 if (u-source) {
 outputs = pa_source_move_all_start(u-source, NULL);
-#ifdef NOKIA
+
 if (!USE_SCO_OVER_PCM(u))
-#endif
 pa_source_unlink(u-source);
 }
 
@@ -2731,7 +2700,6 @@ int pa__init(pa_module* m) {
 u-sample_spec = m-core-default_sample_spec;
 u-modargs = ma;
 
-#ifdef NOKIA
 if (pa_modargs_get_value(ma, sco_sink, NULL) 
 !(u-hsp.sco_sink = pa_namereg_get(m-core, pa_modargs_get_value(ma, 
sco_sink, NULL), 

[pulseaudio-discuss] [PATCH 2/5] bluetooth: use sco_sink/source to start with right state

2011-03-28 Thread Tanu Kaskinen
From: Marc-André Lureau marc-andre.lur...@nokia.com

Note from Tanu Kaskinen: I resolved some conflicts with newer upstream code, so
if this patch is broken, blame me..
---
 src/modules/bluetooth/module-bluetooth-device.c |   39 +-
 1 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index af08003..10fb5ed 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1873,39 +1873,46 @@ static char *get_name(const char *type, pa_modargs *ma, 
const char *device_id, p
 return pa_sprintf_malloc(bluez_%s.%s, type, n);
 }
 
-static void sco_over_pcm_state_update(struct userdata *u) {
+static int sco_over_pcm_state_update(struct userdata *u) {
 pa_assert(u);
 pa_assert(USE_SCO_OVER_PCM(u));
 
 if (PA_SINK_IS_OPENED(pa_sink_get_state(u-hsp.sco_sink)) ||
 PA_SOURCE_IS_OPENED(pa_source_get_state(u-hsp.sco_source))) {
 
-if (u-service_fd = 0)
-return;
+if (u-service_fd = 0  u-stream_fd = 0)
+return 0;
 
 init_bt(u);
 
 pa_log_debug(Resuming SCO over PCM);
-if (init_profile(u)  0)
+if (init_profile(u)  0) {
 pa_log(Can't resume SCO over PCM);
+return -1;
+}
 
 if (u-transport)
-bt_transport_acquire(u, TRUE);
+return bt_transport_acquire(u, TRUE);
 else
-start_stream_fd(u);
+return start_stream_fd(u);
+
 } else {
+if (u-service_fd  0  u-stream_fd  0)
+return 0;
 
-if (u-service_fd  0)
-return;
+pa_log_debug(Closing SCO over PCM);
 
 if (u-transport)
 bt_transport_release(u);
-else
+else if (u-stream_fd = 0)
 stop_stream_fd(u);
 
-pa_log_debug(Closing SCO over PCM);
-pa_close(u-service_fd);
-u-service_fd = -1;
+if (u-service_fd = 0) {
+pa_close(u-service_fd);
+u-service_fd = -1;
+}
+
+return 0;
 }
 }
 
@@ -2358,11 +2365,11 @@ static int start_thread(struct userdata *u) {
 pa_thread_mq_init(u-thread_mq, u-core-mainloop, u-rtpoll);
 
 if (USE_SCO_OVER_PCM(u)) {
-if (u-transport) {
-if (bt_transport_acquire(u, TRUE)  0)
-return -1;
-} else if (start_stream_fd(u)  0)
+if (sco_over_pcm_state_update(u)  0) {
+u-sink = NULL;
+u-source = NULL;
 return -1;
+}
 
 pa_sink_ref(u-sink);
 pa_source_ref(u-source);
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 4/5] bluetooth: restore original sco_{sink, src}-set_volume when unloading

2011-03-28 Thread Tanu Kaskinen
From: Marc-André Lureau marc-andre.lur...@nokia.com

---
 src/modules/bluetooth/module-bluetooth-device.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index 455a53a..540d48c 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -121,7 +121,9 @@ struct a2dp_info {
 struct hsp_info {
 pcm_capabilities_t pcm_capabilities;
 pa_sink *sco_sink;
+void (*sco_sink_set_volume)(pa_sink *s);
 pa_source *sco_source;
+void (*sco_source_set_volume)(pa_source *s);
 pa_hook_slot *sink_state_changed_slot;
 pa_hook_slot *source_state_changed_slot;
 };
@@ -2804,12 +2806,14 @@ int pa__init(pa_module* m) {
 init_bt(u);
 
 if (u-hsp.sco_sink) {
+u-hsp.sco_sink_set_volume = u-hsp.sco_sink-set_volume;
 k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-hsp.sco_sink);
 pa_shared_set(u-core, k, u);
 pa_xfree(k);
 }
 
 if (u-hsp.sco_source) {
+u-hsp.sco_source_set_volume = u-hsp.sco_source-set_volume;
 k = pa_sprintf_malloc(bluetooth-device@%p, (void*) 
u-hsp.sco_source);
 pa_shared_set(u-core, k, u);
 pa_xfree(k);
@@ -2890,12 +2894,14 @@ void pa__done(pa_module *m) {
 shutdown_bt(u);
 
 if (u-hsp.sco_sink) {
+u-hsp.sco_sink-set_volume = u-hsp.sco_sink_set_volume;
 k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-hsp.sco_sink);
 pa_shared_remove(u-core, k);
 pa_xfree(k);
 }
 
 if (u-hsp.sco_source) {
+u-hsp.sco_source-set_volume = u-hsp.sco_source_set_volume;
 k = pa_sprintf_malloc(bluetooth-device@%p, (void*) 
u-hsp.sco_source);
 pa_shared_remove(u-core, k);
 pa_xfree(k);
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 3/5] bluetooth: fix set_volume_cb on sco over pcm

2011-03-28 Thread Tanu Kaskinen
From: Marc-André Lureau marc-andre.lur...@nokia.com

The current implementation is totally bogus, it cast the over_sink
userdata to the bluetooth-device userdata... It was failing nicely
because the previous code had a gentle safe-guard in u-profile ==
PROFILE_HSP, and u-profile was just random.

There is no easy way to associate additional data to a sink or
source. Two solutions seems possible: looking up loaded modules and
check which one was handling the sink/source, or using pa_shared. I
went for the second solution.
---
 src/modules/bluetooth/module-bluetooth-device.c |   59 +++
 1 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index 10fb5ed..455a53a 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -39,6 +39,7 @@
 #include pulsecore/core-rtclock.h
 #include pulsecore/core-util.h
 #include pulsecore/core-error.h
+#include pulsecore/shared.h
 #include pulsecore/socket-util.h
 #include pulsecore/thread.h
 #include pulsecore/thread-mq.h
@@ -1798,14 +1799,21 @@ fail:
 
 /* Run from main thread */
 static void sink_set_volume_cb(pa_sink *s) {
-struct userdata *u = s-userdata;
 DBusMessage *m;
 dbus_uint16_t gain;
+struct userdata *u;
+char *k;
 
-pa_assert(u);
+pa_assert(s);
+pa_assert(s-core);
 
-if (u-profile != PROFILE_HSP)
-return;
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) s);
+u = pa_shared_get(s-core, k);
+pa_xfree(k);
+
+pa_assert(u);
+pa_assert(u-sink == s);
+pa_assert(u-profile == PROFILE_HSP);
 
 gain = (pa_cvolume_max(s-real_volume) * 15) / PA_VOLUME_NORM;
 
@@ -1822,14 +1830,21 @@ static void sink_set_volume_cb(pa_sink *s) {
 
 /* Run from main thread */
 static void source_set_volume_cb(pa_source *s) {
-struct userdata *u = s-userdata;
 DBusMessage *m;
 dbus_uint16_t gain;
+struct userdata *u;
+char *k;
 
-pa_assert(u);
+pa_assert(s);
+pa_assert(s-core);
 
-if (u-profile != PROFILE_HSP)
-return;
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) s);
+u = pa_shared_get(s-core, k);
+pa_xfree(k);
+
+pa_assert(u);
+pa_assert(u-source == s);
+pa_assert(u-profile == PROFILE_HSP);
 
 gain = (pa_cvolume_max(s-volume) * 15) / PA_VOLUME_NORM;
 
@@ -2687,7 +2702,7 @@ int pa__init(pa_module* m) {
 struct userdata *u;
 const char *address, *path;
 DBusError err;
-char *mike, *speaker, *transport;
+char *mike, *speaker, *transport, *k;
 const pa_bluetooth_device *device;
 
 pa_assert(m);
@@ -2788,6 +2803,18 @@ int pa__init(pa_module* m) {
 /* Connect to the BT service */
 init_bt(u);
 
+if (u-hsp.sco_sink) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-hsp.sco_sink);
+pa_shared_set(u-core, k, u);
+pa_xfree(k);
+}
+
+if (u-hsp.sco_source) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) 
u-hsp.sco_source);
+pa_shared_set(u-core, k, u);
+pa_xfree(k);
+}
+
 if (u-profile != PROFILE_OFF)
 if (init_profile(u)  0)
 goto fail;
@@ -2820,6 +2847,8 @@ int pa__get_n_used(pa_module *m) {
 
 void pa__done(pa_module *m) {
 struct userdata *u;
+char *k;
+
 pa_assert(m);
 
 if (!(u = m-userdata))
@@ -2860,6 +2889,18 @@ void pa__done(pa_module *m) {
 
 shutdown_bt(u);
 
+if (u-hsp.sco_sink) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-hsp.sco_sink);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+}
+
+if (u-hsp.sco_source) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) 
u-hsp.sco_source);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+}
+
 if (u-a2dp.buffer)
 pa_xfree(u-a2dp.buffer);
 
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 5/5] bluetooth: Refuse to use the HSP profile if there is some other HSP device active.

2011-03-28 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

---
 src/modules/bluetooth/module-bluetooth-device.c |  126 +--
 1 files changed, 93 insertions(+), 33 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index 540d48c..1154651 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -185,6 +185,8 @@ struct userdata {
 
 #define MAX_PLAYBACK_CATCH_UP_USEC (100*PA_USEC_PER_MSEC)
 
+#define CURRENT_HSP_DEVICE_KEY current-hsp-device /* Key to core-shared. */
+
 #define USE_SCO_OVER_PCM(u) (u-profile == PROFILE_HSP  (u-hsp.sco_sink  
u-hsp.sco_source))
 
 static int init_bt(struct userdata *u);
@@ -1961,6 +1963,8 @@ static pa_hook_result_t source_state_changed_cb(pa_core 
*c, pa_source *s, struct
 
 /* Run from main thread */
 static int add_sink(struct userdata *u) {
+char *k;
+
 if (USE_SCO_OVER_PCM(u)) {
 pa_proplist *p;
 
@@ -2014,6 +2018,10 @@ static int add_sink(struct userdata *u) {
 if (u-profile == PROFILE_HSP) {
 u-sink-set_volume = sink_set_volume_cb;
 u-sink-n_volume_steps = 16;
+
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-sink);
+pa_shared_set(u-core, k, u);
+pa_xfree(k);
 }
 
 return 0;
@@ -2021,6 +2029,8 @@ static int add_sink(struct userdata *u) {
 
 /* Run from main thread */
 static int add_source(struct userdata *u) {
+char *k;
+
 if (USE_SCO_OVER_PCM(u)) {
 u-source = u-hsp.sco_source;
 pa_proplist_sets(u-source-proplist, bluetooth.protocol, hsp);
@@ -2079,6 +2089,10 @@ static int add_source(struct userdata *u) {
 if (u-profile == PROFILE_HSP) {
 u-source-set_volume = source_set_volume_cb;
 u-source-n_volume_steps = 16;
+
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-source);
+pa_shared_set(u-core, k, u);
+pa_xfree(k);
 }
 
 return 0;
@@ -2325,6 +2339,8 @@ static int init_profile(struct userdata *u) {
 
 /* Run from main thread */
 static void stop_thread(struct userdata *u) {
+char *k;
+
 pa_assert(u);
 
 if (u-thread) {
@@ -2349,11 +2365,23 @@ static void stop_thread(struct userdata *u) {
 }
 
 if (u-sink) {
+if (u-profile == PROFILE_HSP) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-sink);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+}
+
 pa_sink_unref(u-sink);
 u-sink = NULL;
 }
 
 if (u-source) {
+if (u-profile == PROFILE_HSP) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-source);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+}
+
 pa_source_unref(u-source);
 u-source = NULL;
 }
@@ -2383,8 +2411,20 @@ static int start_thread(struct userdata *u) {
 
 if (USE_SCO_OVER_PCM(u)) {
 if (sco_over_pcm_state_update(u)  0) {
-u-sink = NULL;
-u-source = NULL;
+char *k;
+
+if (u-sink) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) u-sink);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+u-sink = NULL;
+}
+if (u-source) {
+k = pa_sprintf_malloc(bluetooth-device@%p, (void*) 
u-source);
+pa_shared_remove(u-core, k);
+pa_xfree(k);
+u-source = NULL;
+}
 return -1;
 }
 
@@ -2421,9 +2461,25 @@ static int start_thread(struct userdata *u) {
 return 0;
 }
 
+static void save_sco_volume_callbacks(struct userdata *u) {
+pa_assert(u);
+pa_assert(USE_SCO_OVER_PCM(u));
+
+u-hsp.sco_sink_set_volume = u-hsp.sco_sink-set_volume;
+u-hsp.sco_source_set_volume = u-hsp.sco_source-set_volume;
+}
+
+static void restore_sco_volume_callbacks(struct userdata *u) {
+pa_assert(u);
+pa_assert(USE_SCO_OVER_PCM(u));
+
+u-hsp.sco_sink-set_volume = u-hsp.sco_sink_set_volume;
+u-hsp.sco_source-set_volume = u-hsp.sco_source_set_volume;
+}
+
 /* Run from main thread */
 static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
-struct userdata *u;
+struct userdata *u, *other_hsp_device;
 enum profile *d;
 pa_queue *inputs = NULL, *outputs = NULL;
 const pa_bluetooth_device *device;
@@ -2439,6 +2495,9 @@ static int card_set_profile(pa_card *c, pa_card_profile 
*new_profile) {
 return -PA_ERR_IO;
 }
 
+if (u-profile == PROFILE_HSP)
+pa_shared_remove(u-core, CURRENT_HSP_DEVICE_KEY);
+
 /* The state signal is sent by bluez, so it is racy to check
strictly for CONNECTED, we should also accept STREAMING state
as being good enough. However, if the profile is used
@@ -2448,6 +2507,10 @@ static int card_set_profile(pa_card *c, pa_card_profile 
*new_profile) {
 pa_log_warn(HSP

[pulseaudio-discuss] [PATCH] .gitignore: Add ChangeLog and src/envelope-test to the ignore list

2011-03-27 Thread Tanu Kaskinen
---
 .gitignore |1 +
 src/.gitignore |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 85c0fe5..3a840d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,4 @@ libtool
 ltmain.sh
 missing
 stamp-*
+ChangeLog
diff --git a/src/.gitignore b/src/.gitignore
index e56c225..1f959ec 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -66,3 +66,4 @@ start-pulseaudio-x11
 start-pulseaudio-kde
 vector-test
 *-symdef.h
+envelope-test
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] .gitignore: Add ChangeLog and src/envelope-test to the ignore list

2011-03-27 Thread Tanu Kaskinen
On Sun, 2011-03-27 at 20:19 +0530, Arun Raghavan wrote:
 On Sun, 2011-03-27 at 17:39 +0300, Tanu Kaskinen wrote:
 [...]
  diff --git a/src/.gitignore b/src/.gitignore
  index e56c225..1f959ec 100644
  --- a/src/.gitignore
  +++ b/src/.gitignore
  @@ -66,3 +66,4 @@ start-pulseaudio-x11
   start-pulseaudio-kde
   vector-test
   *-symdef.h
  +envelope-test
 
 This test has been removed. Probably a stale binary in your tree.

Oops, you're right. I'll send a fixed patch.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] .gitignore: Add ChangeLog to the ignore list.

2011-03-27 Thread Tanu Kaskinen
---
 .gitignore |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 85c0fe5..3a840d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,4 @@ libtool
 ltmain.sh
 missing
 stamp-*
+ChangeLog
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] alsa-mixer: Get rid of a compiler warning.

2011-03-27 Thread Tanu Kaskinen
On 64-bit systems LONG_MAX is greater than the largest possible value of a
uint32_t variable, which caused the compiler to warn about a comparison that is
always false. On 32-bit systems pa_atou() can return a value that will overflow
when assigned to e-volume_limit, which has type long, so the comparison was
necessary.

This dilemma is resolved by using pa_atol() instead of pa_atou().
---
 src/modules/alsa/alsa-mixer.c |4 ++--
 src/pulsecore/core-util.c |   30 +++---
 src/pulsecore/core-util.h |1 +
 3 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 286931f..3b13879 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1920,14 +1920,14 @@ static int element_parse_volume_limit(
 
 pa_alsa_path *p = userdata;
 pa_alsa_element *e;
-uint32_t volume_limit;
+long volume_limit;
 
 if (!(e = element_get(p, section, TRUE))) {
 pa_log([%s:%u] volume-limit makes no sense in '%s', filename, line, 
section);
 return -1;
 }
 
-if (pa_atou(rvalue, volume_limit)  0 || volume_limit  LONG_MAX) {
+if (pa_atol(rvalue, volume_limit)  0 || volume_limit  0) {
 pa_log([%s:%u] Invalid value for volume-limit, filename, line);
 return -1;
 }
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 4823198..890efde 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2018,14 +2018,8 @@ int pa_atoi(const char *s, int32_t *ret_i) {
 pa_assert(s);
 pa_assert(ret_i);
 
-errno = 0;
-l = strtol(s, x, 0);
-
-if (!x || *x || errno) {
-if (!errno)
-errno = EINVAL;
+if (pa_atol(s, l)  0)
 return -1;
-}
 
 if ((int32_t) l != l) {
 errno = ERANGE;
@@ -2064,6 +2058,28 @@ int pa_atou(const char *s, uint32_t *ret_u) {
 return 0;
 }
 
+/* Convert the string s to a signed long integer in *ret_l. */
+int pa_atol(const char *s, long *ret_l) {
+char *x = NULL;
+long l;
+
+pa_assert(s);
+pa_assert(ret_l);
+
+errno = 0;
+l = strtol(s, x, 0);
+
+if (!x || *x || errno) {
+if (!errno)
+errno = EINVAL;
+return -1;
+}
+
+*ret_l = l;
+
+return 0;
+}
+
 #ifdef HAVE_STRTOF_L
 static locale_t c_locale = NULL;
 
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 32641a3..0b34a18 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -135,6 +135,7 @@ char *pa_state_path(const char *fn, pa_bool_t 
prepend_machine_id);
 
 int pa_atoi(const char *s, int32_t *ret_i);
 int pa_atou(const char *s, uint32_t *ret_u);
+int pa_atol(const char *s, long *ret_l);
 int pa_atod(const char *s, double *ret_d);
 
 size_t pa_snprintf(char *str, size_t size, const char *format, ...);
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] alsa-mixer: Get rid of a compiler warning.

2011-03-27 Thread Tanu Kaskinen
On Sun, 2011-03-27 at 21:20 +0300, Tanu Kaskinen wrote:
 @@ -2018,14 +2018,8 @@ int pa_atoi(const char *s, int32_t *ret_i) {
  pa_assert(s);
  pa_assert(ret_i);
  
 -errno = 0;
 -l = strtol(s, x, 0);
 -
 -if (!x || *x || errno) {
 -if (!errno)
 -errno = EINVAL;
 +if (pa_atol(s, l)  0)
  return -1;
 -}
  
  if ((int32_t) l != l) {
  errno = ERANGE;

Damn, this causes another warning: x is now an unused variable. Fixup
coming...

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] alsa-mixer: Get rid of a compiler warning.

2011-03-27 Thread Tanu Kaskinen
On 64-bit systems LONG_MAX is greater than the largest possible value of a
uint32_t variable, which caused the compiler to warn about a comparison that is
always false. On 32-bit systems pa_atou() can return a value that will overflow
when assigned to e-volume_limit, which has type long, so the comparison was
necessary.

This dilemma is resolved by using pa_atol() instead of pa_atou().
---
 src/modules/alsa/alsa-mixer.c |4 ++--
 src/pulsecore/core-util.c |   31 +++
 src/pulsecore/core-util.h |1 +
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 286931f..3b13879 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1920,14 +1920,14 @@ static int element_parse_volume_limit(
 
 pa_alsa_path *p = userdata;
 pa_alsa_element *e;
-uint32_t volume_limit;
+long volume_limit;
 
 if (!(e = element_get(p, section, TRUE))) {
 pa_log([%s:%u] volume-limit makes no sense in '%s', filename, line, 
section);
 return -1;
 }
 
-if (pa_atou(rvalue, volume_limit)  0 || volume_limit  LONG_MAX) {
+if (pa_atol(rvalue, volume_limit)  0 || volume_limit  0) {
 pa_log([%s:%u] Invalid value for volume-limit, filename, line);
 return -1;
 }
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 4823198..f769b32 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2012,20 +2012,13 @@ char *pa_state_path(const char *fn, pa_bool_t 
appendmid) {
 
 /* Convert the string s to a signed integer in *ret_i */
 int pa_atoi(const char *s, int32_t *ret_i) {
-char *x = NULL;
 long l;
 
 pa_assert(s);
 pa_assert(ret_i);
 
-errno = 0;
-l = strtol(s, x, 0);
-
-if (!x || *x || errno) {
-if (!errno)
-errno = EINVAL;
+if (pa_atol(s, l)  0)
 return -1;
-}
 
 if ((int32_t) l != l) {
 errno = ERANGE;
@@ -2064,6 +2057,28 @@ int pa_atou(const char *s, uint32_t *ret_u) {
 return 0;
 }
 
+/* Convert the string s to a signed long integer in *ret_l. */
+int pa_atol(const char *s, long *ret_l) {
+char *x = NULL;
+long l;
+
+pa_assert(s);
+pa_assert(ret_l);
+
+errno = 0;
+l = strtol(s, x, 0);
+
+if (!x || *x || errno) {
+if (!errno)
+errno = EINVAL;
+return -1;
+}
+
+*ret_l = l;
+
+return 0;
+}
+
 #ifdef HAVE_STRTOF_L
 static locale_t c_locale = NULL;
 
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 32641a3..0b34a18 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -135,6 +135,7 @@ char *pa_state_path(const char *fn, pa_bool_t 
prepend_machine_id);
 
 int pa_atoi(const char *s, int32_t *ret_i);
 int pa_atou(const char *s, uint32_t *ret_u);
+int pa_atol(const char *s, long *ret_l);
 int pa_atod(const char *s, double *ret_d);
 
 size_t pa_snprintf(char *str, size_t size, const char *format, ...);
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] sink-input: Add volume_writable to pa_sink_input.

2011-03-27 Thread Tanu Kaskinen
This is pretty cosmetic change; there's no actual functionality added.
Previously the volume_writable information was available through the
pa_sink_input_is_volume_writable() function, but I find it cleaner to have a
real variable.

The sink input introspection variable name was also changed from
read_only_volume to volume_writable for consistency.
---
 PROTOCOL|2 +-
 src/modules/dbus/iface-stream.c |   10 
 src/modules/module-stream-restore.c |6 ++--
 src/pulse/introspect.c  |6 ++--
 src/pulse/introspect.h  |2 +-
 src/pulsecore/cli-command.c |2 +-
 src/pulsecore/protocol-native.c |4 +-
 src/pulsecore/sink-input.c  |   36 ++
 src/pulsecore/sink-input.h  |6 +++-
 9 files changed, 27 insertions(+), 47 deletions(-)

diff --git a/PROTOCOL b/PROTOCOL
index c2bb209..a15d116 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -212,4 +212,4 @@ New flag at the end of sink input and source output 
introspection data:
 Two new flags at the end of sink input introspection data:
 
 bool has_volume
-bool read_only_volume
+bool volume_writable
diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c
index e3464fd..d9f1237 100644
--- a/src/modules/dbus/iface-stream.c
+++ b/src/modules/dbus/iface-stream.c
@@ -57,7 +57,6 @@ struct pa_dbusiface_stream {
 pa_proplist *proplist;
 
 pa_bool_t has_volume;
-pa_bool_t read_only_volume;
 
 pa_dbus_protocol *dbus_protocol;
 pa_subscription *subscription;
@@ -357,6 +356,7 @@ static void handle_get_volume(DBusConnection *conn, 
DBusMessage *msg, void *user
 
 static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, 
DBusMessageIter *iter, void *userdata) {
 pa_dbusiface_stream *s = userdata;
+pa_bool_t volume_writable = TRUE;
 DBusMessageIter array_iter;
 int stream_channels = 0;
 dbus_uint32_t *volume = NULL;
@@ -369,12 +369,14 @@ static void handle_set_volume(DBusConnection *conn, 
DBusMessage *msg, DBusMessag
 pa_assert(iter);
 pa_assert(s);
 
-if (!s-has_volume || s-read_only_volume) {
+volume_writable = (s-type == STREAM_TYPE_PLAYBACK) ? 
s-sink_input-volume_writable : FALSE;
+
+if (!s-has_volume || !volume_writable) {
 char *str = stream_to_string(s);
 
 if (!s-has_volume)
 pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, %s 
doesn't have volume., str);
-else if (s-read_only_volume)
+else if (!volume_writable)
 pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, %s has 
read-only volume., str);
 pa_xfree(str);
 
@@ -853,7 +855,6 @@ pa_dbusiface_stream 
*pa_dbusiface_stream_new_playback(pa_dbusiface_core *core, p
 s-sink = pa_sink_ref(sink_input-sink);
 s-sample_rate = sink_input-sample_spec.rate;
 s-has_volume = pa_sink_input_is_volume_readable(sink_input);
-s-read_only_volume = s-has_volume ? 
!pa_sink_input_is_volume_writable(sink_input) : FALSE;
 
 if (s-has_volume)
 pa_sink_input_get_volume(sink_input, s-volume, TRUE);
@@ -891,7 +892,6 @@ pa_dbusiface_stream 
*pa_dbusiface_stream_new_record(pa_dbusiface_core *core, pa_
 s-mute = FALSE;
 s-proplist = pa_proplist_copy(source_output-proplist);
 s-has_volume = FALSE;
-s-read_only_volume = FALSE;
 s-dbus_protocol = pa_dbus_protocol_get(source_output-core);
 s-subscription = pa_subscription_new(source_output-core, 
PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscription_cb, s);
 s-send_event_slot = 
pa_hook_connect(source_output-core-hooks[PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT],
diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index df48dce..8edfee0 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -1168,7 +1168,7 @@ static void subscribe_callback(pa_core *c, 
pa_subscription_event_type_t t, uint3
 }
 
 if (sink_input-save_volume) {
-pa_assert(pa_sink_input_is_volume_writable(sink_input));
+pa_assert(sink_input-volume_writable);
 
 entry.channel_map = sink_input-channel_map;
 pa_sink_input_get_volume(sink_input, entry.volume, FALSE);
@@ -1329,7 +1329,7 @@ static pa_hook_result_t 
sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
 if ((e = read_entry(u, name))) {
 
 if (u-restore_volume  e-volume_valid) {
-if (!pa_sink_input_new_data_is_volume_writable(new_data))
+if (!new_data-volume_writable)
 pa_log_debug(Not restoring volume for sink input %s, because 
its volume can't be changed., name);
 else if (new_data-volume_is_set)
 pa_log_debug(Not restoring volume for sink input %s, because 
already set., name);
@@ -1619,7 +1619,7 @@ static void apply_entry(struct userdata *u, const char 
*name, struct entry *e) {
 }
 

Re: [pulseaudio-discuss] Current problems with git master

2011-03-25 Thread Tanu Kaskinen
On Fri, 2011-03-25 at 09:11 +, Colin Guthrie wrote:
 This patch should fix up these issues right?

Yep, seems correct to me.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Current problems with git master

2011-03-25 Thread Tanu Kaskinen
On Fri, 2011-03-25 at 23:09 +, Colin Guthrie wrote:
 Does this patch look OK to everyone (especially Tanu!)

Looks ok to me! Thanks for fixing this.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Current problems with git master

2011-03-25 Thread Tanu Kaskinen
On Sat, 2011-03-26 at 00:13 +, Colin Guthrie wrote:
 FWIW, the attached patch seems to work for me... simply not ref'ing the
 core. If this is OK, then I'll push it.

Yep, my bad. I think there's a rule that object A shall not ref object B
if B owns A. And here core owns everything, including the dbus objects.
Nobody should ref core. It's then a bit strange why the core is
refcounted in the first place, but I guess it's because the intention is
to make the Pulseaudio core pluggable into other programs, and those
other programs may want to have multiple references to the Pulseaudio
core object.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] loopback: Always use the trivial resampler.

2011-03-24 Thread Tanu Kaskinen
Adjusting the sample rate is done in the IO thread, which can cause
interruptions in the audio if the adjustment requires heavy computation. The
trivial resampler is guaranteed to be light on the cpu.

It would be better to adjust the sample rate in some other thread (FWIW,
module-combine uses the main thread), but this quick hack fixes the immediate
problem of spending too much time in the IO thread.
---
 src/modules/module-loopback.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index 9a8640b..3ade248 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -714,6 +714,7 @@ int pa__init(pa_module *m) {
 pa_sink_input_new_data_set_sample_spec(sink_input_data, ss);
 pa_sink_input_new_data_set_channel_map(sink_input_data, map);
 sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE;
+sink_input_data.resample_method = PA_RESAMPLER_TRIVIAL;
 
 sink_dont_move = FALSE;
 if (pa_modargs_get_value_boolean(ma, sink_dont_move, sink_dont_move)  
0) {
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] loopback: Always use the trivial resampler.

2011-03-24 Thread Tanu Kaskinen
On Thu, 2011-03-24 at 15:31 +0200, pl bossart wrote:
 On Thu, Mar 24, 2011 at 8:16 AM, Tanu Kaskinen tanu.kaski...@digia.com 
 wrote:
  Adjusting the sample rate is done in the IO thread, which can cause
  interruptions in the audio if the adjustment requires heavy computation. The
  trivial resampler is guaranteed to be light on the cpu.
 
  It would be better to adjust the sample rate in some other thread (FWIW,
  module-combine uses the main thread), but this quick hack fixes the 
  immediate
  problem of spending too much time in the IO thread.
 
 I don't think it's the right or only way to solve the problem. If you
 are using the loopback and SRC is required, the assumption is that you
 don't care too much about latency. If the audio events are spaced
 enough, there should be plenty of time to run the resampling. we
 should instead adjust the sink/source latencies to reduce the number
 of events and not compromize on quality.

Aren't you assuming here that the resampling adjustment timeout happens
right after the buffers are filled, and never when the buffer is running
low and a refill is scheduled right after the adjustment timeout?

 This trivial resampler should only be used if for some reason you want
 both real-time behavior and low-latency while using an SRC. I fail to
 see in what cases you would care? In what practical cases did you
 encounter underflows?

The sink may be running in a low-latency mode even if the loopback
stream doesn't have any latency requirements - there may be other
streams active at the same time with stricter timing requirements.

FWIW, the practical case here was a very simple test of looping null
sink's monitor to a hw sink with default settings on Harmattan. It may
be that our setup is more suspectible to this kind of problems than
normal systems, but I still think that non-realtime-safe stuff should
be kept out of the IO threads, regardless of the setup, especially if
such stuff can very well be done outside the IO thread.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 1/2] pactl: Accept more volume specification formats

2011-03-24 Thread Tanu Kaskinen
On Thu, 2011-03-24 at 22:22 +0530, Arun Raghavan wrote:
 On Thu, 2011-03-24 at 13:07 +, Colin Guthrie wrote:
  'Twas brillig, and Maarten Bosmans at 24/03/11 12:44 did gyre and gimble:
   2011/3/24 Maarten Bosmans mkbosm...@gmail.com:
   With this you can specify the volume with 6554, 10%, 0.001 or -60dB,
   all resulting in the same volume change.
   
   I was also going to add relative volumes, such as +3dB and -5%, by
   detecting a + or - sign in the volume. But that clashes with the
   absolute dB scale (insofar a dB can ever be absolute) that can also be
   negative.
   
   Any suggestions for graceful handling of this?
  
  How about if the first letter of the volume change is an i or a d
  then this indicated increment or decrement relative volume?
  
  It's not as clean as the +/- labelling sadly but such is life.
  
  Alternatively your absolute dB volumes could be specified as 60-dB or
  7+dB (where 7dB implies 7+dB)... That way the prefix +/- notation
  could be used for relative adjustments. The only downside there is that
  setting absolute dB volumes is more confusing (you'd never need to use
  anything other than XdB for relative adjustments anyway).
  
  Personally I'd go for the later as I think relative adjustments are
  probably more common, so it's syntax should be neatest, but I could be
  very wrong :D
 
 Or maybe just do this as a separate set-volume-step command (or
 -increment or something better named)?

I agree - I think a separate command is a good idea. For command naming,
I suggest increase-sink-volume and decrease-sink-volume.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] loopback: Always use the trivial resampler.

2011-03-24 Thread Tanu Kaskinen
On Thu, 2011-03-24 at 09:09 -0500, pl bossart wrote:
  The sink may be running in a low-latency mode even if the loopback
  stream doesn't have any latency requirements - there may be other
  streams active at the same time with stricter timing requirements.
 
  FWIW, the practical case here was a very simple test of looping null
  sink's monitor to a hw sink with default settings on Harmattan. It may
  be that our setup is more suspectible to this kind of problems than
  normal systems, but I still think that non-realtime-safe stuff should
  be kept out of the IO threads, regardless of the setup, especially if
  such stuff can very well be done outside the IO thread.
 
 if you are still using 10ms periods on the hw sinks, then yes it's an
 artifical use case in a constrained environment that doesn't use
 timer-based scheduling...
 I don't disagree that doing SRC in an io thread is not that kosher,
 but keep in mind that we also do mixing and volume control in the IO
 thread. There is some amount of DSP in this thread which will impact
 response time to hw events.

It might be that you have misunderstood the reason for the patch. Now
that I read the patch description again, it indeed isn't entirely clear:
the problem that I'm having is that the periodic (every 10 seconds)
reinitialization of the resampler takes too much CPU time. The
resampling itself is fine - I don't think it's even possible to move
that out of the IO thread, or if it's possible, it probably wouldn't
bring any benefits.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Current problems with git master

2011-03-24 Thread Tanu Kaskinen
On Thu, 2011-03-24 at 21:30 +, Colin Guthrie wrote:
 If someone could double check, I'd appreciate it (seeing as I'd rather
 any bugs in my commit last less than a year and a half!!)

Problems found:

The first process: daemon_pipe is not closed if the first fork() call
fails. Even if it doesn't fail, the first process never closes
daemon_pipe[0].

The second process: daemon_pipe[1] is not closed if anything fails
between the first and the second fork() call. Also, if the second fork
fails, then the finish section writes to daemon_pipe2[1], even though
only the third process should do that. Also, if anything fails between
the first and the second fork, then the second process never writes
anything to daemon_pipe[1]. I don't know what happens in the first
process in this case - does it get an error or does pa_loop_read() get
stuck.

The third process: No problems :)

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 0/2] Rebased bluetooth patches

2011-03-23 Thread Tanu Kaskinen
Colin wrote:
 Can you rebase these two on git master please? I just merged a whole
 bunch of changes from BT guys and these both fail now.

Sure, refreshed patches coming.

Tanu Kaskinen (2):
  bluetooth: Don't log an error if an endpoint type is disabled.
  bluetooth: Get rid of warnings about unused stuff when building
against a D-Bus version that doesn't have fd-passing support.

 src/modules/bluetooth/bluetooth-util.c |   43 +++-
 src/modules/bluetooth/bluetooth-util.h |2 +
 2 files changed, 33 insertions(+), 12 deletions(-)

-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/2 rebased] bluetooth: Don't log an error if an endpoint type is disabled.

2011-03-23 Thread Tanu Kaskinen
It's perfectly normal for BlueZ to disable some endpoint types, so printing a
log message at error level isn't a good idea.

For facilitating an informative message in case some endpoint type is disabled,
the send_and_add_to_pending() function interface is also changed to be more
generic (the pa_bluetooth_device pointer is replaced with a void pointer).
---
 src/modules/bluetooth/bluetooth-util.c |   33 ---
 src/modules/bluetooth/bluetooth-util.h |2 +
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c 
b/src/modules/bluetooth/bluetooth-util.c
index 293e024..a79ff91 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -73,7 +73,7 @@ struct pa_bluetooth_discovery {
 };
 
 static void get_properties_reply(DBusPendingCall *pending, void *userdata);
-static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, 
pa_bluetooth_device *d, DBusMessage *m, DBusPendingCallNotifyFunction func);
+static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, 
DBusMessage *m, DBusPendingCallNotifyFunction func, void *call_data);
 
 static pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value) {
 pa_assert(value);
@@ -280,21 +280,21 @@ static int parse_device_property(pa_bluetooth_discovery 
*y, pa_bluetooth_device
 /* Vudentz said the interfaces are here when the UUIDs are 
announced */
 if (strcasecmp(HSP_AG_UUID, value) == 0 || 
strcasecmp(HFP_AG_UUID, value) == 0) {
 pa_assert_se(m = 
dbus_message_new_method_call(org.bluez, d-path, 
org.bluez.HandsfreeGateway, GetProperties));
-send_and_add_to_pending(y, d, m, get_properties_reply);
+send_and_add_to_pending(y, m, get_properties_reply, d);
 } else if (strcasecmp(HSP_HS_UUID, value) == 0 || 
strcasecmp(HFP_HS_UUID, value) == 0) {
 pa_assert_se(m = 
dbus_message_new_method_call(org.bluez, d-path, org.bluez.Headset, 
GetProperties));
-send_and_add_to_pending(y, d, m, get_properties_reply);
+send_and_add_to_pending(y, m, get_properties_reply, d);
 } else if (strcasecmp(A2DP_SINK_UUID, value) == 0) {
 pa_assert_se(m = 
dbus_message_new_method_call(org.bluez, d-path, org.bluez.AudioSink, 
GetProperties));
-send_and_add_to_pending(y, d, m, get_properties_reply);
+send_and_add_to_pending(y, m, get_properties_reply, d);
 } else if (strcasecmp(A2DP_SOURCE_UUID, value) == 0) {
 pa_assert_se(m = 
dbus_message_new_method_call(org.bluez, d-path, org.bluez.AudioSource, 
GetProperties));
-send_and_add_to_pending(y, d, m, get_properties_reply);
+send_and_add_to_pending(y, m, get_properties_reply, d);
 }
 
 /* this might eventually be racy if .Audio is not there 
yet, but the State change will come anyway later, so this call is for 
cold-detection mostly */
 pa_assert_se(m = dbus_message_new_method_call(org.bluez, 
d-path, org.bluez.Audio, GetProperties));
-send_and_add_to_pending(y, d, m, get_properties_reply);
+send_and_add_to_pending(y, m, get_properties_reply, d);
 
 if (!dbus_message_iter_next(ai))
 break;
@@ -394,7 +394,7 @@ static pa_bluetooth_device 
*found_device(pa_bluetooth_discovery *y, const char*
 pa_hashmap_put(y-devices, d-path, d);
 
 pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, 
org.bluez.Device, GetProperties));
-send_and_add_to_pending(y, d, m, get_properties_reply);
+send_and_add_to_pending(y, m, get_properties_reply, d);
 
 /* Before we read the other properties (Audio, AudioSink, AudioSource,
  * Headset) we wait that the UUID is read */
@@ -503,7 +503,7 @@ finish2:
 pa_dbus_pending_free(p);
 }
 
-static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, 
pa_bluetooth_device *d, DBusMessage *m, DBusPendingCallNotifyFunction func) {
+static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, 
DBusMessage *m, DBusPendingCallNotifyFunction func, void *call_data) {
 pa_dbus_pending *p;
 DBusPendingCall *call;
 
@@ -512,7 +512,7 @@ static pa_dbus_pending* 
send_and_add_to_pending(pa_bluetooth_discovery *y, pa_bl
 
 
pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(y-connection),
 m, call, -1));
 
-p = pa_dbus_pending_new(pa_dbus_connection_get(y-connection), m, call, y, 
d);
+p = pa_dbus_pending_new(pa_dbus_connection_get(y-connection), m, call, y, 
call_data);
 PA_LLIST_PREPEND(pa_dbus_pending, y-pending, p);
 dbus_pending_call_set_notify(call, 

[pulseaudio-discuss] [PATCH 2/2 rebased] bluetooth: Get rid of warnings about unused stuff when building against a D-Bus version that doesn't have fd-passing support.

2011-03-23 Thread Tanu Kaskinen
---
 src/modules/bluetooth/bluetooth-util.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c 
b/src/modules/bluetooth/bluetooth-util.c
index a79ff91..f1c7c4c 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -519,6 +519,7 @@ static pa_dbus_pending* 
send_and_add_to_pending(pa_bluetooth_discovery *y, DBusM
 return p;
 }
 
+#ifdef DBUS_TYPE_UNIX_FD
 static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) {
 DBusError e;
 DBusMessage *r;
@@ -559,6 +560,7 @@ finish:
 
 pa_xfree(endpoint);
 }
+#endif
 
 static void list_devices_reply(DBusPendingCall *pending, void *userdata) {
 DBusError e;
@@ -607,6 +609,7 @@ finish:
 pa_dbus_pending_free(p);
 }
 
+#ifdef DBUS_TYPE_UNIX_FD
 static void register_endpoint(pa_bluetooth_discovery *y, const char *path, 
const char *endpoint, const char *uuid) {
 DBusMessage *m;
 DBusMessageIter i, d;
@@ -654,6 +657,7 @@ static void register_endpoint(pa_bluetooth_discovery *y, 
const char *path, const
 
 send_and_add_to_pending(y, m, register_endpoint_reply, 
pa_xstrdup(endpoint));
 }
+#endif
 
 static void found_adapter(pa_bluetooth_discovery *y, const char *path) {
 DBusMessage *m;
@@ -1042,7 +1046,9 @@ int pa_bluetooth_transport_acquire(const 
pa_bluetooth_transport *t, const char *
 if (omtu)
 *omtu = o;
 
+#ifdef DBUS_TYPE_UNIX_FD
 fail:
+#endif
 dbus_message_unref(r);
 return ret;
 }
@@ -1083,6 +1089,7 @@ static int setup_dbus(pa_bluetooth_discovery *y) {
 return 0;
 }
 
+#ifdef DBUS_TYPE_UNIX_FD
 static pa_bluetooth_transport *transport_new(pa_bluetooth_discovery *y, const 
char *path, enum profile p, const uint8_t *config, int size) {
 pa_bluetooth_transport *t;
 
@@ -1435,13 +1442,16 @@ static DBusHandlerResult 
endpoint_handler(DBusConnection *c, DBusMessage *m, voi
 
 return DBUS_HANDLER_RESULT_HANDLED;
 }
+#endif /* DBUS_TYPE_UNIX_FD */
 
 pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
 DBusError err;
 pa_bluetooth_discovery *y;
+#ifdef DBUS_TYPE_UNIX_FD
 static const DBusObjectPathVTable vtable_endpoint = {
 .message_function = endpoint_handler,
 };
+#endif
 
 pa_assert(c);
 
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] alsa-mixer: Check that the kernel driver returns consistent limits with both snd_mixer_selem_get_*_dB_range() and _ask_*_vol_dB().

2011-03-23 Thread Tanu Kaskinen
The check is inspired by a driver that returned higher dB limit from
snd_mixer_selem_get_playback_dB_range() than what _ask_playback_vol_dB()
returned at maximum integer volume.
---
 src/modules/alsa/alsa-mixer.c |   37 +
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 51a6cd6..b425ce5 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1398,6 +1398,43 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t 
*m) {
 else
 e-has_dB = snd_mixer_selem_get_capture_dB_range(me, 
min_dB, max_dB) = 0;
 
+/* Check that the kernel driver returns consistent limits with
+ * both _get_*_dB_range() and _ask_*_vol_dB(). */
+if (e-has_dB  !e-db_fix) {
+long min_dB_checked = 0;
+long max_dB_checked = 0;
+
+if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
+r = snd_mixer_selem_ask_playback_vol_dB(me, 
e-min_volume, min_dB_checked);
+else
+r = snd_mixer_selem_ask_capture_vol_dB(me, 
e-min_volume, min_dB_checked);
+
+if (r  0) {
+pa_log_warn(Failed to query the dB value for %s at 
volume level %li, e-alsa_name, e-min_volume);
+return -1;
+}
+
+if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
+r = snd_mixer_selem_ask_playback_vol_dB(me, 
e-max_volume, max_dB_checked);
+else
+r = snd_mixer_selem_ask_capture_vol_dB(me, 
e-max_volume, max_dB_checked);
+
+if (r  0) {
+pa_log_warn(Failed to query the dB value for %s at 
volume level %li, e-alsa_name, e-max_volume);
+return -1;
+}
+
+if (min_dB != min_dB_checked || max_dB != max_dB_checked) {
+pa_log_warn(Your kernel driver is broken: the 
reported dB range for %s (from %0.2f dB to %0.2f dB) 
+doesn't match the dB values at minimum 
and maximum volume levels: %0.2f dB at level %li, 
+%0.2f dB at level %li.,
+e-alsa_name,
+min_dB / 100.0, max_dB / 100.0,
+min_dB_checked / 100.0, e-min_volume, 
max_dB_checked / 100.0, e-max_volume);
+return -1;
+}
+}
+
 if (e-has_dB) {
 #ifdef HAVE_VALGRIND_MEMCHECK_H
 VALGRIND_MAKE_MEM_DEFINED(min_dB, sizeof(min_dB));
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] alsa-mixer: Make sure that SND_MIXER_SCHN_UNKNOWN isn't used when indexing e-masks.

2011-03-23 Thread Tanu Kaskinen
SND_MIXER_SCHN_UNKNOWN is defined as -1, so that's not a good array index...
---
 src/modules/alsa/alsa-mixer.c |   13 +++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index b425ce5..c9adbb0 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1490,8 +1490,13 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t 
*m) {
 e-n_channels = 1;
 
 if (!e-override_map) {
-for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p  
PA_CHANNEL_POSITION_MAX; p++)
+for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p  
PA_CHANNEL_POSITION_MAX; p++) {
+if (alsa_channel_ids[p] == SND_MIXER_SCHN_UNKNOWN)
+continue;
+
 e-masks[alsa_channel_ids[p]][e-n_channels-1] = 0;
+}
+
 e-masks[SND_MIXER_SCHN_MONO][e-n_channels-1] = 
PA_CHANNEL_POSITION_MASK_ALL;
 }
 
@@ -1531,8 +1536,12 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t 
*m) {
 }
 
 e-merged_mask = 0;
-for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p  
PA_CHANNEL_POSITION_MAX; p++)
+for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p  
PA_CHANNEL_POSITION_MAX; p++) {
+if (alsa_channel_ids[p] == SND_MIXER_SCHN_UNKNOWN)
+continue;
+
 e-merged_mask |= 
e-masks[alsa_channel_ids[p]][e-n_channels-1];
+}
 }
 }
 }
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] ALSA or PulseAudio for low-latency voice?

2011-03-20 Thread Tanu Kaskinen
On Sun, 2011-03-20 at 11:07 +0100, David Henningsson wrote:
 On 2011-03-19 17:45, Philip Jägenstedt wrote:
  Hi PulseAudionauts,
 
  I've been meaning to experiment a bit with low-latency voice codecs
  and naturally want to add as little latency as possible to what is
  imposed by the codec on both capture and playback. (My guess is that
  the latency added would be between min(capture_latency,
  playback_latency) and capture_latency+playback_latency, depending on
  how well capture end and playback begin are synchronized.)
 
  Q: Does it matters for latency if I program against ALSA or PulseAudio?
 
 Well, that kind of depends on what scale you're on. If you need 
 latencies under say - and this is just a qualified guess - ~ 10-20 ms, 
 you'll need to program against ALSA or Jack. Above that and you'll be 
 good with PulseAudio.
 
  This is assuming a setup like on Ubuntu, where the default ALSA device
  is using a PulseAudio backend. (Portability and code complexity may
  favor one solution or the other, but that's not what I'm asking.)
 
 When I say program against ALSA above, I mean directly against an ALSA 
 sound card, i e bypassing Pulseaudio. As for if ALSA plugin - 
 PulseAudio - ALSA - HW gives worse latency than PulseAudio - ALSA - 
 HW, I don't think that matters much.

A while back I discussed in IRC with someone who wanted to have low
latency with Pulseaudio. According to his experiments, it seemed like
libpulse enforces for some reason a minimum client-side buffering of 100
ms or so, unless pa_stream_begin_write() is used when writing data. The
alsa plugin doesn't use that function (I don't know why, maybe it just
can't use it for some reason), so I would guess that it's impossible to
get lower than 100 ms latencies through the alsa plugin. You can of
course try, and results of such experiment would be interesting
regardless of the outcome.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 1/5] module-coreaudio-detect: fix pa__done()

2011-03-20 Thread Tanu Kaskinen
On Sun, 2011-03-20 at 18:39 +0100, Daniel Mack wrote:
  void pa__done(pa_module *m) {
 -struct userdata *u;
 +struct userdata *u = m-userdata;
  struct ca_device *dev = u-devices;
  AudioObjectPropertyAddress property_address;
  
 -pa_assert(m);
 -pa_assert_se(u = m-userdata);
 -
  property_address.mSelector = kAudioHardwarePropertyDevices;
  property_address.mScope = kAudioObjectPropertyScopeGlobal;
  property_address.mElement = kAudioObjectPropertyElementMaster;

I think the old assertions were good. I'd rather initialize dev after
the assertions.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] More patches for OS X

2011-03-20 Thread Tanu Kaskinen
On Sun, 2011-03-20 at 18:39 +0100, Daniel Mack wrote:
   osx: re-order module locations

This patch didn't reach the list for some reason.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 3/5] osx: add -headerpad_max_install_names to LDFLAGS

2011-03-20 Thread Tanu Kaskinen
On Sun, 2011-03-20 at 18:39 +0100, Daniel Mack wrote:
 This is needed for sufficient padding of library names in linked
 binaries.
 ---
  src/Makefile.am |5 +
  1 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/src/Makefile.am b/src/Makefile.am
 index ff98ddb..c182483 100644
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
 @@ -82,6 +82,11 @@ FOREIGN_CFLAGS = -w
  MODULE_LDFLAGS = $(AM_LDFLAGS) -module -disable-static -avoid-version 
 $(LDFLAGS_NOUNDEFINED)
  MODULE_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la 
 libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
  
 +if OS_IS_DARWIN
 +AM_LDFLAGS+=-headerpad_max_install_names
 +MODULE_LDFLAGS+=-headerpad_max_install_names
 +endif

If you put this block before MODULE_LDFLAGS is defined, then you don't
need to touch MODULE_LDFLAGS, because they include AM_LDFLAGS
automatically.

Cosmetic: spaces around += would be nice (it seems that it wasn't
entirely consistent before either...)

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 2/2] bluetooth: Get rid of warnings about unused stuff when building against a D-Bus version that doesn't have fd-passing support.

2011-03-18 Thread Tanu Kaskinen
---
 src/modules/bluetooth/bluetooth-util.c |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c 
b/src/modules/bluetooth/bluetooth-util.c
index 68ee808..cae7f16 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -519,6 +519,7 @@ static pa_dbus_pending* 
send_and_add_to_pending(pa_bluetooth_discovery *y, DBusM
 return p;
 }
 
+#ifdef DBUS_TYPE_UNIX_FD
 static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) {
 DBusError e;
 DBusMessage *r;
@@ -559,6 +560,7 @@ finish:
 
 pa_xfree(endpoint);
 }
+#endif
 
 static void list_devices_reply(DBusPendingCall *pending, void *userdata) {
 DBusError e;
@@ -607,6 +609,7 @@ finish:
 pa_dbus_pending_free(p);
 }
 
+#ifdef DBUS_TYPE_UNIX_FD
 static void register_endpoint(pa_bluetooth_discovery *y, const char *path, 
const char *endpoint, const char *uuid) {
 DBusMessage *m;
 DBusMessageIter i, d;
@@ -654,6 +657,7 @@ static void register_endpoint(pa_bluetooth_discovery *y, 
const char *path, const
 
 send_and_add_to_pending(y, m, register_endpoint_reply, 
pa_xstrdup(endpoint));
 }
+#endif
 
 static void found_adapter(pa_bluetooth_discovery *y, const char *path) {
 DBusMessage *m;
@@ -968,11 +972,9 @@ int pa_bluetooth_transport_acquire(const 
pa_bluetooth_transport *t, const char *
 pa_log(Failed to parse org.bluez.MediaTransport.Acquire(): %s, 
err.message);
 ret = -1;
 dbus_error_free(err);
-goto fail;
 }
 #endif
 
-fail:
 dbus_message_unref(r);
 return ret;
 }
@@ -1013,6 +1015,7 @@ static int setup_dbus(pa_bluetooth_discovery *y) {
 return 0;
 }
 
+#ifdef DBUS_TYPE_UNIX_FD
 static pa_bluetooth_transport *transport_new(pa_bluetooth_discovery *y, const 
char *path, enum profile p, const uint8_t *config, int size) {
 pa_bluetooth_transport *t;
 
@@ -1358,13 +1361,16 @@ static DBusHandlerResult 
endpoint_handler(DBusConnection *c, DBusMessage *m, voi
 
 return DBUS_HANDLER_RESULT_HANDLED;
 }
+#endif /* DBUS_TYPE_UNIX_FD */
 
 pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
 DBusError err;
 pa_bluetooth_discovery *y;
+#ifdef DBUS_TYPE_UNIX_FD
 static const DBusObjectPathVTable vtable_endpoint = {
 .message_function = endpoint_handler,
 };
+#endif
 
 pa_assert(c);
 
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 2/2] alsa-mixer: Refactoring: merge element_mute_volume(), element_zero_volume() and element_apply_constant_volume() into a single function.

2011-03-17 Thread Tanu Kaskinen
---
 src/modules/alsa/alsa-mixer.c |  102 ++---
 1 files changed, 35 insertions(+), 67 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 2893b47..aa3422a 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1084,10 +1084,14 @@ int pa_alsa_path_set_mute(pa_alsa_path *p, snd_mixer_t 
*m, pa_bool_t muted) {
 return 0;
 }
 
-static int element_mute_volume(pa_alsa_element *e, snd_mixer_t *m) {
-snd_mixer_elem_t *me;
-snd_mixer_selem_id_t *sid;
-int r;
+/* Depending on whether e-volume_use is _OFF, _ZERO or _CONSTANT, this
+ * function sets all channels of the volume element to e-min_volume, 0 dB or
+ * e-constant_volume. */
+static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
+snd_mixer_elem_t *me = NULL;
+snd_mixer_selem_id_t *sid = NULL;
+int r = 0;
+long volume = -1;
 
 pa_assert(m);
 pa_assert(e);
@@ -1098,74 +1102,44 @@ static int element_mute_volume(pa_alsa_element *e, 
snd_mixer_t *m) {
 return -1;
 }
 
-if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
-r = snd_mixer_selem_set_playback_volume_all(me, e-min_volume);
-else
-r = snd_mixer_selem_set_capture_volume_all(me, e-min_volume);
-
-if (r  0)
-pa_log_warn(Failed to set volume to muted of %s: %s, e-alsa_name, 
pa_alsa_strerror(errno));
+switch (e-volume_use) {
+case PA_ALSA_VOLUME_OFF:
+volume = e-min_volume;
+break;
 
-return r;
-}
+case PA_ALSA_VOLUME_ZERO:
+if (e-db_fix) {
+long dB = 0;
 
-/* The volume to 0dB */
-static int element_zero_volume(pa_alsa_element *e, snd_mixer_t *m) {
-snd_mixer_elem_t *me;
-snd_mixer_selem_id_t *sid;
-int r;
+volume = decibel_fix_get_step(e-db_fix, dB, +1);
+}
+break;
 
-pa_assert(m);
-pa_assert(e);
+case PA_ALSA_VOLUME_CONSTANT:
+volume = e-constant_volume;
+break;
 
-SELEM_INIT(sid, e-alsa_name);
-if (!(me = snd_mixer_find_selem(m, sid))) {
-pa_log_warn(Element %s seems to have disappeared., e-alsa_name);
-return -1;
+default:
+pa_assert_not_reached();
 }
 
-if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
-if (e-db_fix) {
-long value = 0;
+if (volume = 0) {
+if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
+r = snd_mixer_selem_set_playback_volume_all(me, volume);
+else
+r = snd_mixer_selem_set_capture_volume_all(me, volume);
+} else {
+pa_assert(e-volume_use == PA_ALSA_VOLUME_ZERO);
+pa_assert(!e-db_fix);
 
-r = snd_mixer_selem_set_playback_volume_all(me, 
decibel_fix_get_step(e-db_fix, value, +1));
-} else
+if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
 r = snd_mixer_selem_set_playback_dB_all(me, 0, +1);
-else
-if (e-db_fix) {
-long value = 0;
-
-r = snd_mixer_selem_set_capture_volume_all(me, 
decibel_fix_get_step(e-db_fix, value, +1));
-} else
+else
 r = snd_mixer_selem_set_capture_dB_all(me, 0, +1);
-
-if (r  0)
-pa_log_warn(Failed to set volume to 0dB of %s: %s, e-alsa_name, 
pa_alsa_strerror(errno));
-
-return r;
-}
-
-static int element_apply_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
-snd_mixer_elem_t *me;
-snd_mixer_selem_id_t *sid;
-int r;
-
-pa_assert(m);
-pa_assert(e);
-
-SELEM_INIT(sid, e-alsa_name);
-if (!(me = snd_mixer_find_selem(m, sid))) {
-pa_log_warn(Element %s seems to have disappeared., e-alsa_name);
-return -1;
 }
 
-if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
-r = snd_mixer_selem_set_playback_volume_all(me, e-constant_volume);
-else
-r = snd_mixer_selem_set_capture_volume_all(me, e-constant_volume);
-
 if (r  0)
-pa_log_warn(Failed to set volume to %li of %s: %s, 
e-constant_volume, e-alsa_name, pa_alsa_strerror(errno));
+pa_log_warn(Failed to set volume of %s: %s, e-alsa_name, 
pa_alsa_strerror(errno));
 
 return r;
 }
@@ -1203,15 +1177,9 @@ int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) 
{
 
 switch (e-volume_use) {
 case PA_ALSA_VOLUME_OFF:
-r = element_mute_volume(e, m);
-break;
-
 case PA_ALSA_VOLUME_ZERO:
-r = element_zero_volume(e, m);
-break;
-
 case PA_ALSA_VOLUME_CONSTANT:
-r = element_apply_constant_volume(e, m);
+r = element_set_constant_volume(e, m);
 break;
 
 case PA_ALSA_VOLUME_MERGE:
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [WIP] Passthrough support

2011-03-16 Thread Tanu Kaskinen
On Tue, 2011-03-15 at 17:36 -0500, pl bossart wrote:
  I pushed your change along with a fix for the assert you saw to my tree
  as well.
 
 I tested the latest batch of patches with AC3/SPDIF this time. Works
 well in general, however I found some interesting points:
 - in Rhythmbox, the passthrough mode is only enabled if the first file
 of playlist is compressed. If you start with PCM/WAV, it always uses
 the PCM mode.
 - in Totem, the passthrough mode works when the visual effects are
 disabled. I see a nice DD on my receiver...However the playback stops
 if you play with the volume slider. I get a pop-up error window saying
 'an error occurred: pa_stream_set_sink_input_volume(): invalid
 argument'
 
 On a related note, maybe we want to change the approach to volume
 control. Depending on the sink, there might be ways of using
 side/in-band channels to send volume control information to the
 decoder. It's going to be protocol-specific. So maybe we need to
 provide the client with an information coming from the sink on whether
 volume control is actually supported or not.

Yes, that information will be provided in the sink and source
introspection data.

Somewhat related: I've been thinking that maybe the volume channels
should be separate from the stream channels. For example, maybe it's
possible that some future sink implementation can only provide a simple
single-channel volume interface, while the actual audio stream has
multiple channels. Are you aware of any real-world cases where this
separation would be beneficial?

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] 2ch - 6ch upmixing with flatvolumes

2011-03-12 Thread Tanu Kaskinen
On Sat, 2011-03-12 at 14:46 +, Colin Guthrie wrote:
 Hi,
 
 I was working with Valodim on IRC and stumbled on an issue with flat
 volumes on 5.1 sinks when playing a 2ch sink input.
 
 I try to adjust the Rear left+right to be 0, but it just doesn't let me.
 It seems the flat volume logic somehow forces it back to the same as the
 other channels.

I'm not sure what you mean by it just doesn't let me. I could try and
see for myself, but I'm too lazy... I did read some code a bit, and I
didn't find out what could cause the volume to get stuck in a
user-visible way. The remapping stuff is a bit complicated to think
about, though, so I didn't gain confidence that the volume couldn't get
stuck, either.

What I knew beforehand, however, was that if a sink has streams that
don't have the same channel map as the sink, then the real volume of the
sink is forced to be flat - all channels have the same volume. This
probably in some way causes the trouble that you're having. I got the
impression that you're setting the sink volume in pavucontrol, and the
sliders would be stuck in some value. When the sink volume is adjusted,
the reference volume is set before the real volume is calculated, so
when the real volume is forced to be flat, that shouldn't be visible in
the GUI (which shows the reference volume).

There's this comment in cvolume_remap_minimal_impact() in sink.c:

/* Much like pa_cvolume_remap(), but tries to minimize impact when
 * mapping from sink input to sink volumes:
 *
 * If template is a possible remapping from v it is used instead
 * of remapping anew.
 *
 * If the channel maps don't match we set an all-channel volume on
 * the sink to ensure that changing a volume on one stream has no
 * effect that cannot be compensated for in another stream that
 * does not have the same channel map as the sink. */

I wonder if that all-channel volume part is really needed. I find the
current implementation really hard to reason about, but I think forcing
the real volume to be flat wouldn't be needed at least if the volumes
were handled a bit differently:

- Sink inputs would maintain two copies of their volume variables: one
set of variables for the sink input's channel map and one set for the
sink's channel map. When a volume variable in either set is updated, the
corresponding variable in the other set is updated too, using the normal
remapping function.

- When the sink has to calculate its real volume from the sink inputs,
it would look only at the sink input volume that uses the sink's channel
map. This way there's no need to do do any remapping at this phase -
each channel of the real volume would simply be set to the maximum found
in all sink inputs for that channel. There's no way any stream could
step on some other stream's toes either.

It would be nice to know what scenario the comment refers to, when it
says that without that precaution there can be a situation where one
stream's volume change can't be compensated for in some other stream.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [RFC] allow conditionals in config input files like default.pa.in

2011-03-12 Thread Tanu Kaskinen
Hi Maarten,

Did you ever get any feedback? At least there are no replies on the
mailing list.

On Fri, 2011-03-04 at 00:26 +0100, Maarten Bosmans wrote:
 It would be nice to have the ability to use @if HAVE_FEATURE@ in the
 configuration file templates. You could see it either as an extension
 of the current @VARIABLE@ replacement or as a compile-time variant of
 .ifexists.
 
 Incidentally, does anybody know why these files are currently
 generated in the Makefile using sed, instead of being included in
 AC_CONFIG_FILES?

At least I don't know.

 Adding that ability has several advantages:
  - The default.pa.in and default.pa.win32 files can be merged.
  - The BSDs still use module-hal-detect, so it can be included in
 default.pa without littering it with [.ifexists module-hal-detect\n
 load-module module-hal-detect\n .endif] for Linux users, so they
 cannot be confused by it.
  - And thirdly, if sys/resource.h is not found the daemon does not
 understand the --rlimit-* options, so in that case those lines should
 be omitted from daemon.conf.
 
 Would this be a good change, or are we then preprocessing at too many levels?

Sounds useful to me. In case my opinion matters, you have my
acceptance :)

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/2] alsa-mixer: Implement support for setting element specific upper limits for volume.

2011-03-10 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

This feature is mainly useful in embedded systems that have built-in speakers.
In such situations the full audio path is known beforehand, so it's possible to
know what is the maximum sensible volume, and any higher volume can be
disabled.

The volume limit is set in path configuration files in the [Element] section,
using option volume-limit. The value is the desired maximum volume step of
the volume element.
---
 src/modules/alsa/alsa-mixer.c  |   68 +++-
 src/modules/alsa/alsa-mixer.h  |1 +
 .../alsa/mixer/paths/analog-output.conf.common |1 +
 3 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 9a7e045..41997a7 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -895,6 +895,9 @@ static int element_set_volume(pa_alsa_element *e, 
snd_mixer_t *m, const pa_chann
 long value = to_alsa_dB(f);
 int rounding = value  0 ? -1 : +1;
 
+if (e-volume_limit = 0  value  (e-max_dB * 100))
+value = e-max_dB * 100;
+
 if (e-direction == PA_ALSA_DIRECTION_OUTPUT) {
 /* If we call set_playback_volume() without checking first
  * if the channel is available, ALSA behaves very
@@ -1284,6 +1287,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t 
*m) {
 
 pa_assert(m);
 pa_assert(e);
+pa_assert(e-path);
 
 SELEM_INIT(sid, e-alsa_name);
 
@@ -1407,6 +1411,36 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t 
*m) {
 }
 }
 
+if (e-volume_limit = 0) {
+if (e-volume_limit = e-min_volume || e-volume_limit  
e-max_volume)
+pa_log_warn(Volume limit for element %s of path %s is 
invalid: %li isn't within the valid range 
+%li-%li. The volume limit is ignored.,
+e-alsa_name, e-path-name, 
e-volume_limit, e-min_volume + 1, e-max_volume);
+
+else {
+e-max_volume = e-volume_limit;
+
+if (e-has_dB) {
+if (e-db_fix) {
+e-db_fix-max_step = e-max_volume;
+e-max_dB = ((double) 
e-db_fix-db_values[e-db_fix-max_step - e-db_fix-min_step]) / 100.0;
+
+} else {
+if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
+r = 
snd_mixer_selem_ask_playback_vol_dB(me, e-max_volume, max_dB);
+else
+r = snd_mixer_selem_ask_capture_vol_dB(me, 
e-max_volume, max_dB);
+
+if (r  0) {
+pa_log_warn(Failed to get dB value of %s: 
%s, e-alsa_name, pa_alsa_strerror(r));
+e-has_dB = FALSE;
+} else
+e-max_dB = ((double) max_dB) / 100.0;
+}
+}
+}
+}
+
 if (e-direction == PA_ALSA_DIRECTION_OUTPUT)
 is_mono = snd_mixer_selem_is_playback_mono(me)  0;
 else
@@ -1530,6 +1564,7 @@ static pa_alsa_element* element_get(pa_alsa_path *p, 
const char *section, pa_boo
 e-path = p;
 e-alsa_name = pa_xstrdup(section);
 e-direction = p-direction;
+e-volume_limit = -1;
 
 PA_LLIST_INSERT_AFTER(pa_alsa_element, p-elements, p-last_element, e);
 
@@ -1864,6 +1899,33 @@ static int element_parse_direction_try_other(
 return 0;
 }
 
+static int element_parse_volume_limit(
+const char *filename,
+unsigned line,
+const char *section,
+const char *lvalue,
+const char *rvalue,
+void *data,
+void *userdata) {
+
+pa_alsa_path *p = userdata;
+pa_alsa_element *e;
+uint32_t volume_limit;
+
+if (!(e = element_get(p, section, TRUE))) {
+pa_log([%s:%u] volume-limit makes no sense in '%s', filename, line, 
section);
+return -1;
+}
+
+if (pa_atou(rvalue, volume_limit)  0 || volume_limit  LONG_MAX) {
+pa_log([%s:%u] Invalid value for volume-limit, filename, line);
+return -1;
+}
+
+e-volume_limit = volume_limit;
+return 0;
+}
+
 static pa_channel_position_mask_t parse_mask(const char *m) {
 pa_channel_position_mask_t v;
 
@@ -2141,6 +2203,7 @@ pa_alsa_path* pa_alsa_path_new(const char *fname, 
pa_alsa_direction_t direction)
 { required-absent, element_parse_required,NULL, NULL 
},
 { direction,   element_parse_direction,   NULL, NULL 
},
 { direction-try-other

[pulseaudio-discuss] [PATCH 2/2] alsa-mixer: When figuring out the max_dB of a path, use only channels that are used by the path elements.

2011-03-10 Thread Tanu Kaskinen
Without this, p-max_dB could never be less than 0 dB, because the loop at the
end of pa_alsa_path_probe() would reset p-max_dB to 0 as soon as the loop
encountered a channel that wasn't touched by any element.
---
 src/modules/alsa/alsa-mixer.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 41997a7..3eef5f9 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -2400,6 +2400,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, 
pa_bool_t ignore_dB) {
 pa_alsa_element *e;
 double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX];
 pa_channel_position_t t;
+pa_channel_position_mask_t path_volume_channels = 0;
 
 pa_assert(p);
 pa_assert(m);
@@ -2436,6 +2437,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, 
pa_bool_t ignore_dB) {
 if (PA_CHANNEL_POSITION_MASK(t)  e-merged_mask) {
 min_dB[t] = e-min_dB;
 max_dB[t] = e-max_dB;
+path_volume_channels |= 
PA_CHANNEL_POSITION_MASK(t);
 }
 
 p-has_dB = TRUE;
@@ -2446,6 +2448,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, 
pa_bool_t ignore_dB) {
 if (PA_CHANNEL_POSITION_MASK(t)  e-merged_mask) {
 min_dB[t] += e-min_dB;
 max_dB[t] += e-max_dB;
+path_volume_channels |= 
PA_CHANNEL_POSITION_MASK(t);
 }
 } else {
 /* Hmm, there's another element before us
@@ -2484,11 +2487,13 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, 
pa_bool_t ignore_dB) {
 p-max_dB = -INFINITY;
 
 for (t = 0; t  PA_CHANNEL_POSITION_MAX; t++) {
-if (p-min_dB  min_dB[t])
-p-min_dB = min_dB[t];
+if (path_volume_channels  PA_CHANNEL_POSITION_MASK(t)) {
+if (p-min_dB  min_dB[t])
+p-min_dB = min_dB[t];
 
-if (p-max_dB  max_dB[t])
-p-max_dB = max_dB[t];
+if (p-max_dB  max_dB[t])
+p-max_dB = max_dB[t];
+}
 }
 
 return 0;
-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 2/7 v2] alsa-mixer: Use decibel fixes when getting and setting decibel volumes.

2011-03-09 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

---
 src/modules/alsa/alsa-mixer.c |  260 -
 src/modules/alsa/alsa-mixer.h |8 +-
 2 files changed, 212 insertions(+), 56 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index c0bbaa0..340e063 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -491,6 +491,15 @@ static void option_free(pa_alsa_option *o) {
 pa_xfree(o);
 }
 
+static void decibel_fix_free(pa_alsa_decibel_fix *db_fix) {
+pa_assert(db_fix);
+
+pa_xfree(db_fix-name);
+pa_xfree(db_fix-db_values);
+
+pa_xfree(db_fix);
+}
+
 static void element_free(pa_alsa_element *e) {
 pa_alsa_option *o;
 pa_assert(e);
@@ -500,6 +509,9 @@ static void element_free(pa_alsa_element *e) {
 option_free(o);
 }
 
+if (e-db_fix)
+decibel_fix_free(e-db_fix);
+
 pa_xfree(e-alsa_name);
 pa_xfree(e);
 }
@@ -593,14 +605,60 @@ static int element_get_volume(pa_alsa_element *e, 
snd_mixer_t *m, const pa_chann
 long value = 0;
 
 if (e-direction == PA_ALSA_DIRECTION_OUTPUT) {
-if (snd_mixer_selem_has_playback_channel(me, c))
-r = snd_mixer_selem_get_playback_dB(me, c, value);
-else
+if (snd_mixer_selem_has_playback_channel(me, c)) {
+if (e-db_fix) {
+if ((r = snd_mixer_selem_get_playback_volume(me, c, 
value)) = 0) {
+/* If the channel volume is outside the limits set
+ * by the dB fix, we clamp the hw volume to be
+ * within the limits. */
+if (value  e-db_fix-min_step) {
+value = e-db_fix-min_step;
+snd_mixer_selem_set_playback_volume(me, c, 
value);
+pa_log_debug(Playback volume for element %s 
channel %i was below the dB fix limit. 
+ Volume reset to %0.2f dB., 
e-alsa_name, c,
+ e-db_fix-db_values[value - 
e-db_fix-min_step] / 100.0);
+} else if (value  e-db_fix-max_step) {
+value = e-db_fix-max_step;
+snd_mixer_selem_set_playback_volume(me, c, 
value);
+pa_log_debug(Playback volume for element %s 
channel %i was over the dB fix limit. 
+ Volume reset to %0.2f dB., 
e-alsa_name, c,
+ e-db_fix-db_values[value - 
e-db_fix-min_step] / 100.0);
+}
+
+/* Volume step - dB value conversion. */
+value = e-db_fix-db_values[value - 
e-db_fix-min_step];
+}
+} else
+r = snd_mixer_selem_get_playback_dB(me, c, value);
+} else
 r = -1;
 } else {
-if (snd_mixer_selem_has_capture_channel(me, c))
-r = snd_mixer_selem_get_capture_dB(me, c, value);
-else
+if (snd_mixer_selem_has_capture_channel(me, c)) {
+if (e-db_fix) {
+if ((r = snd_mixer_selem_get_capture_volume(me, c, 
value)) = 0) {
+/* If the channel volume is outside the limits set
+ * by the dB fix, we clamp the hw volume to be
+ * within the limits. */
+if (value  e-db_fix-min_step) {
+value = e-db_fix-min_step;
+snd_mixer_selem_set_capture_volume(me, c, 
value);
+pa_log_debug(Capture volume for element %s 
channel %i was below the dB fix limit. 
+ Volume reset to %0.2f dB., 
e-alsa_name, c,
+ e-db_fix-db_values[value - 
e-db_fix-min_step] / 100.0);
+} else if (value  e-db_fix-max_step) {
+value = e-db_fix-max_step;
+snd_mixer_selem_set_capture_volume(me, c, 
value);
+pa_log_debug(Capture volume for element %s 
channel %i was over the dB fix limit. 
+ Volume reset to %0.2f dB., 
e-alsa_name, c,
+ e-db_fix-db_values[value - 
e-db_fix-min_step] / 100.0);
+}
+
+/* Volume step - dB value conversion. */
+value = e-db_fix-db_values[value - 
e-db_fix-min_step

Re: [pulseaudio-discuss] [PATCH 0/7] Working around bad decibel information

2011-03-09 Thread Tanu Kaskinen
On Wed, 2011-03-09 at 12:53 +0200, David Henningsson wrote:
 On 2011-03-04 16:42, Tanu Kaskinen wrote:
  Here's a pile of patches. The first two implement the concept of decibel
  fixes for alsa devices. A decibel fix is basically a table that maps the
  raw volume steps of a mixer element to manually configured decibel values.
 
 Hmm, taking Lennart's hat on, shouldn't bad decibel information be fixed 
 in the kernel, rather than in Pulseaudio? Then other non-PA applications 
 would benefit from the change as well.

Yes, the fixes should be pushed to alsa. Maybe the DecibelFix
documentation in profile-sets/default.conf should even say that if
you're using this feature and not actively pushing the fixes to alsa,
then you're doing it wrong.

But if the kernel driver is already correct in the sense that it follows
the chip specifications, then I believe this feature is useful for
convincing the alsa developers to fix the driver - if the decibel
mapping has been tested in Pulseaudio already, we can give a ready-made
table to the alsa devs and they don't need to bother with the
measurement part.

I think measuring the correct levels is quite practical to do with
pulseaudio: the flat volume and sync volume features make it possible to
easily compare the subjective volume difference between hw attenuation
and with sw attenuation. If you play a quiet stream (eg. pacat
--volume=1  /dev/urandom) and then play short clips of silence at
full volume, the flat volume feature switches smoothly between hw and sw
attenuation for the quiet stream, and incorrect dB information is easy
to observe. Based on some personal experience, I believe subjective
measurement is even more accurate than measuring the levels using an
oscilloscope - at low volume levels the background noise can make
getting an accurate measurement really hard with an oscilloscope.

It's possible that this feature will lead to lowered pressure to report
dB problems to alsa, and if that means less fixes in alsa, then these
patches should be removed. But since anyone can try out tweaking the dB
values in pulseaudio's configuration easily (relative to hacking alsa
drivers), maybe this will actually increase the amount of fixes in
alsa...

These patches are old (only now I got around to polishing them and
sending them to upstream), and I've actually already asked Lennart's
opinion of this feature about a year ago. At that time he ok'd the
concept.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Volume algorithm

2011-03-06 Thread Tanu Kaskinen
On Sat, 2011-03-05 at 11:29 +, Tarantism wrote:
 On Sat, 2011-03-05 at 11:08 +, Colin Guthrie wrote:
  'Twas brillig, and Tarantism at 04/03/11 22:23 did gyre and gimble:
   I need to implement a volume scaling in a pulse module.
   I have 0-100 input values.
   What algorithm does pulse usually implement for this so that I can match
   it?
  
  Can you explain a little more what you're trying to do? You shouldn't
  generally need to worry about volume scaling in PA modules.
 The module is a signal source for the default sink (based on
 module-sine.c) so it creates a sink_input and provides pop (etc)
 callbacks for that. I'm using it to produce low latency sound on Maemo.

Are you planning to use the module outside Maemo 5 (I assume you're
talking about Maemo 5)? I ask because Pulseaudio's internal API that
modules use isn't stable, so modules that aren't part of Pulseaudio
itself break very likely if you try to use them with any other version
of Pulseaudio than what they were compiled against. If Maemo 5 is enough
for you, then you probably won't have problems - I don't think
Pulseaudio will get significant updates on that OS anymore.

 I had expected that system volume would be handled downstream of the
 sink_input but changing system volume has no effect. I've managed to
 hook up to the system volume level by dbus and just want to know how to
 scale my data correctly.

The volume system on Maemo is a bit peculiar. The system volume doesn't
touch any sink volumes (except with bluetooth in HSP/HFP mode), all
volume control is done by adjusting stream volumes. If you want to use
the same volume as eg. the music player, set the media.role property of
the sink input to x-maemo. That's a special role for pretty much
everything else than phone and event sound streams.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 0/7] Working around bad decibel information

2011-03-04 Thread Tanu Kaskinen
Here's a pile of patches. The first two implement the concept of decibel
fixes for alsa devices. A decibel fix is basically a table that maps the
raw volume steps of a mixer element to manually configured decibel values.

The rest of the patches are random fixes that have piled up while testing
the decibel fix patches. The pacat memory leak fix hasn't been verified
that it works (it's just a quick fix to a seemingly obvious, but difficult to
test bug), otherwise I have tested the fixes.

Tanu Kaskinen (7):
  alsa-mixer: Add DecibelFix section to the profile set config file
format.
  alsa-mixer: Use decibel fixes when getting and setting decibel
volumes.
  pacat: Fix memory leak when draining the context.
  alsa-mixer: Add a default case for a switch, so that the compiler
won't complain about unhandled cases.
  alsa-card: Print the profile set configuration when loading the card.
  dbusiface-stream: Fix crash when there's no resampling used.
  dbus: Always accept mono volumes when setting device or stream
volume.

 src/modules/alsa/alsa-mixer.c|  500 +++---
 src/modules/alsa/alsa-mixer.h|   27 +-
 src/modules/alsa/mixer/profile-sets/default.conf |   49 ++-
 src/modules/alsa/module-alsa-card.c  |1 +
 src/modules/dbus/iface-device.c  |9 +-
 src/modules/dbus/iface-stream.c  |   14 +-
 src/utils/pacat.c|4 +-
 7 files changed, 517 insertions(+), 87 deletions(-)

-- 
1.7.4.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/7] alsa-mixer: Add DecibelFix section to the profile set config file format.

2011-03-04 Thread Tanu Kaskinen
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com

This commit only implements the parser, the decibel fix data is not yet used
for anything.
---
 src/modules/alsa/alsa-mixer.c|  223 +-
 src/modules/alsa/alsa-mixer.h|   19 ++
 src/modules/alsa/mixer/profile-sets/default.conf |   49 -
 3 files changed, 277 insertions(+), 14 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index fa07674..c0bbaa0 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -2640,6 +2640,15 @@ static void profile_free(pa_alsa_profile *p) {
 pa_xfree(p);
 }
 
+static void decibel_fix_free(pa_alsa_decibel_fix *db_fix) {
+pa_assert(db_fix);
+
+pa_xfree(db_fix-name);
+pa_xfree(db_fix-db_values);
+
+pa_xfree(db_fix);
+}
+
 void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
 pa_assert(ps);
 
@@ -2661,6 +2670,15 @@ void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
 pa_hashmap_free(ps-mappings, NULL, NULL);
 }
 
+if (ps-decibel_fixes) {
+pa_alsa_decibel_fix *db_fix;
+
+while ((db_fix = pa_hashmap_steal_first(ps-decibel_fixes)))
+decibel_fix_free(db_fix);
+
+pa_hashmap_free(ps-decibel_fixes, NULL, NULL);
+}
+
 pa_xfree(ps);
 }
 
@@ -2705,6 +2723,26 @@ static pa_alsa_profile *profile_get(pa_alsa_profile_set 
*ps, const char *name) {
 return p;
 }
 
+static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const 
char *name) {
+pa_alsa_decibel_fix *db_fix;
+
+if (!pa_startswith(name, DecibelFix ))
+return NULL;
+
+name += 11;
+
+if ((db_fix = pa_hashmap_get(ps-decibel_fixes, name)))
+return db_fix;
+
+db_fix = pa_xnew0(pa_alsa_decibel_fix, 1);
+db_fix-profile_set = ps;
+db_fix-name = pa_xstrdup(name);
+
+pa_hashmap_put(ps-decibel_fixes, db_fix-name, db_fix);
+
+return db_fix;
+}
+
 static int mapping_parse_device_strings(
 const char *filename,
 unsigned line,
@@ -2975,6 +3013,130 @@ static int profile_parse_skip_probe(
 return 0;
 }
 
+static int decibel_fix_parse_db_values(
+const char *filename,
+unsigned line,
+const char *section,
+const char *lvalue,
+const char *rvalue,
+void *data,
+void *userdata) {
+
+pa_alsa_profile_set *ps = userdata;
+pa_alsa_decibel_fix *db_fix;
+char **items;
+char *item;
+long *db_values;
+unsigned n = 8; /* Current size of the db_values table. */
+unsigned min_step = 0;
+unsigned max_step = 0;
+unsigned i = 0; /* Index to the items table. */
+unsigned prev_step = 0;
+double prev_db = 0;
+
+pa_assert(filename);
+pa_assert(section);
+pa_assert(lvalue);
+pa_assert(rvalue);
+pa_assert(ps);
+
+if (!(db_fix = decibel_fix_get(ps, section))) {
+pa_log([%s:%u] %s invalid in section %s, filename, line, lvalue, 
section);
+return -1;
+}
+
+if (!(items = pa_split_spaces_strv(rvalue))) {
+pa_log([%s:%u] Value missing, pa_strnull(filename), line);
+return -1;
+}
+
+db_values = pa_xnew(long, n);
+
+while ((item = items[i++])) {
+char *s = item; /* Step value string. */
+char *d = item; /* dB value string. */
+uint32_t step;
+double db;
+
+/* Move d forward until it points to a colon or to the end of the 
item. */
+for (; *d  *d != ':'; ++d);
+
+if (d == s) {
+/* item started with colon. */
+pa_log([%s:%u] No step value found in %s, filename, line, item);
+goto fail;
+}
+
+if (!*d || !*(d + 1)) {
+/* No colon found, or it was the last character in item. */
+pa_log([%s:%u] No dB value found in %s, filename, line, item);
+goto fail;
+}
+
+/* pa_atou() needs a null-terminating string. Let's replace the colon
+ * with a zero byte. */
+*d++ = '\0';
+
+if (pa_atou(s, step)  0) {
+pa_log([%s:%u] Invalid step value: %s, filename, line, s);
+goto fail;
+}
+
+if (pa_atod(d, db)  0) {
+pa_log([%s:%u] Invalid dB value: %s, filename, line, d);
+goto fail;
+}
+
+if (step = prev_step  i != 1) {
+pa_log([%s:%u] Step value %u not greater than the previous value 
%u, filename, line, step, prev_step);
+goto fail;
+}
+
+if (db  prev_db  i != 1) {
+pa_log([%s:%u] Decibel value %0.2f less than the previous value 
%0.2f, filename, line, db, prev_db);
+goto fail;
+}
+
+if (i == 1) {
+min_step = step;
+db_values[0] = (long) (db * 100.0);
+prev_step = step;
+prev_db = db;
+} else {
+/* Interpolate linearly. */
+double db_increment = (db - prev_db

  1   2   3   4   >