diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/oss/oss-stream-control.c | 128 | 
1 files changed, 74 insertions, 54 deletions
| diff --git a/backends/oss/oss-stream-control.c b/backends/oss/oss-stream-control.c index 9bdd3a5..4ae238e 100644 --- a/backends/oss/oss-stream-control.c +++ b/backends/oss/oss-stream-control.c @@ -27,10 +27,14 @@  #include "oss-stream.h"  #include "oss-stream-control.h" +#define LEFT_CHANNEL  0 +#define RIGHT_CHANNEL 1 +  #define OSS_VOLUME_JOIN(left,right)   (((left) & 0xFF) | (((right) & 0xFF) << 8))  #define OSS_VOLUME_JOIN_SAME(volume)  (OSS_VOLUME_JOIN ((volume), (volume))) -#define OSS_VOLUME_JOIN_ARRAY(volume) (OSS_VOLUME_JOIN ((volume[0]), (volume[1]))) +#define OSS_VOLUME_JOIN_ARRAY(volume) (OSS_VOLUME_JOIN ((volume[LEFT_CHANNEL]), \ +                                                        (volume[RIGHT_CHANNEL])))  #define OSS_VOLUME_TAKE_LEFT(volume)  ((volume) & 0xFF)  #define OSS_VOLUME_TAKE_RIGHT(volume) (((volume) >> 8) & 0xFF) @@ -75,9 +79,12 @@ static guint                    oss_stream_control_get_max_volume       (MateMix  static guint                    oss_stream_control_get_normal_volume    (MateMixerStreamControl  *mmsc);  static guint                    oss_stream_control_get_base_volume      (MateMixerStreamControl  *mmsc); -static void                     read_balance                            (OssStreamControl        *control); +static void                     store_volume                            (OssStreamControl        *control, +                                                                         gint                     volume); + +static void                     update_balance                          (OssStreamControl        *control); -static gboolean                 write_and_set_volume                    (OssStreamControl        *control, +static gboolean                 write_and_store_volume                  (OssStreamControl        *control,                                                                           gint                     volume);  static void @@ -192,16 +199,7 @@ oss_stream_control_load (OssStreamControl *control)      if (ret == -1)          return; -    if (v != OSS_VOLUME_JOIN_ARRAY (control->priv->volume)) { -        control->priv->volume[0] = OSS_VOLUME_TAKE_LEFT (v); -        if (control->priv->stereo == TRUE) -            control->priv->volume[1] = OSS_VOLUME_TAKE_RIGHT (v); - -        g_object_notify (G_OBJECT (control), "volume"); -    } - -    if (control->priv->stereo == TRUE) -        read_balance (control); +    store_volume (control, v);  }  void @@ -234,9 +232,10 @@ oss_stream_control_get_volume (MateMixerStreamControl *mmsc)      control = OSS_STREAM_CONTROL (mmsc);      if (control->priv->stereo == TRUE) -        return MAX (control->priv->volume[0], control->priv->volume[1]); +        return MAX (control->priv->volume[LEFT_CHANNEL], +                    control->priv->volume[RIGHT_CHANNEL]);      else -        return control->priv->volume[0]; +        return control->priv->volume[LEFT_CHANNEL];  }  static gboolean @@ -251,7 +250,7 @@ oss_stream_control_set_volume (MateMixerStreamControl *mmsc, guint volume)      if G_UNLIKELY (control->priv->fd == -1)          return FALSE; -    return write_and_set_volume (control, OSS_VOLUME_JOIN_SAME (CLAMP (volume, 0, 100))); +    return write_and_store_volume (control, OSS_VOLUME_JOIN_SAME (CLAMP (volume, 0, 100)));  }  static guint @@ -264,11 +263,11 @@ oss_stream_control_get_channel_volume (MateMixerStreamControl *mmsc, guint chann      control = OSS_STREAM_CONTROL (mmsc);      if (control->priv->stereo == TRUE) { -        if (channel == 0 || channel == 1) +        if (channel == LEFT_CHANNEL || channel == RIGHT_CHANNEL)              return control->priv->volume[channel];      } else { -        if (channel == 0) -            return control->priv->volume[0]; +        if (channel == LEFT_CHANNEL) +            return control->priv->volume[LEFT_CHANNEL];      }      return 0;  } @@ -287,23 +286,18 @@ oss_stream_control_set_channel_volume (MateMixerStreamControl *mmsc,      if G_UNLIKELY (control->priv->fd == -1)          return FALSE; -    if (channel > 1 || (control->priv->stereo == FALSE && channel > 0)) + +    if (channel != LEFT_CHANNEL && +        (control->priv->stereo == FALSE || channel != RIGHT_CHANNEL))          return FALSE;      volume = CLAMP (volume, 0, 100); +    if (channel == LEFT_CHANNEL) +        v = OSS_VOLUME_JOIN (volume, control->priv->volume[RIGHT_CHANNEL]); +    else +        v = OSS_VOLUME_JOIN (control->priv->volume[LEFT_CHANNEL], volume); -    if (control->priv->stereo == TRUE) { -        /* Stereo channel volume - left channel is in the lower 8 bits and -         * right channel is in the higher 8 bits */ -        if (channel == 0) -            v = OSS_VOLUME_JOIN (volume, control->priv->volume[1]); -        else -            v = OSS_VOLUME_JOIN (control->priv->volume[0], volume); -    } else { -        /* Single channel volume - only lower 8 bits are used */ -        v = volume; -    } -    return write_and_set_volume (control, v); +    return write_and_store_volume (control, v);  }  static MateMixerChannelPosition @@ -316,12 +310,12 @@ oss_stream_control_get_channel_position (MateMixerStreamControl *mmsc, guint cha      control = OSS_STREAM_CONTROL (mmsc);      if (control->priv->stereo == TRUE) { -        if (channel == 0) +        if (channel == LEFT_CHANNEL)              return MATE_MIXER_CHANNEL_FRONT_LEFT; -        else if (channel == 1) +        else if (channel == RIGHT_CHANNEL)              return MATE_MIXER_CHANNEL_FRONT_RIGHT;      } else { -        if (channel == 0) +        if (channel == LEFT_CHANNEL)              return MATE_MIXER_CHANNEL_MONO;      }      return MATE_MIXER_CHANNEL_UNKNOWN; @@ -357,15 +351,16 @@ oss_stream_control_set_balance (MateMixerStreamControl *mmsc, gfloat balance)      if G_UNLIKELY (control->priv->fd == -1)          return FALSE; -    max = MAX (control->priv->volume[0], control->priv->volume[1]); +    max = MAX (control->priv->volume[LEFT_CHANNEL], +               control->priv->volume[RIGHT_CHANNEL]);      if (balance <= 0) { -        volume[1] = (balance + 1.0f) * max; -        volume[0] = max; +        volume[RIGHT_CHANNEL] = (balance + 1.0f) * max; +        volume[LEFT_CHANNEL]  = max;      } else { -        volume[0] = (1.0f - balance) * max; -        volume[1] = max; +        volume[LEFT_CHANNEL]  = (1.0f - balance) * max; +        volume[RIGHT_CHANNEL] = max;      } -    return write_and_set_volume (control, OSS_VOLUME_JOIN_ARRAY (volume)); +    return write_and_store_volume (control, OSS_VOLUME_JOIN_ARRAY (volume));  }  static guint @@ -399,11 +394,43 @@ oss_stream_control_get_base_volume (MateMixerStreamControl *mmsc)  }  static void -read_balance (OssStreamControl *control) +store_volume (OssStreamControl *control, gint volume) +{ +    if (control->priv->stereo == TRUE) { +        if (volume == OSS_VOLUME_JOIN_ARRAY (control->priv->volume)) +            return; + +        control->priv->volume[LEFT_CHANNEL]  = OSS_VOLUME_TAKE_LEFT (volume); +        control->priv->volume[RIGHT_CHANNEL] = OSS_VOLUME_TAKE_RIGHT (volume); + +        g_object_freeze_notify (G_OBJECT (control)); + +        g_object_notify (G_OBJECT (control), "volume"); + +        /* Emits signal if balance has changed */ +        update_balance (control); + +        g_object_thaw_notify (G_OBJECT (control)); +    } else { +        volume = OSS_VOLUME_TAKE_LEFT (volume); +        if (volume == control->priv->volume[LEFT_CHANNEL]) +            return; + +        control->priv->volume[LEFT_CHANNEL] = volume; + +        g_object_notify (G_OBJECT (control), "volume"); +    } +} + +static void +update_balance (OssStreamControl *control)  {      gfloat balance; -    guint  left  = control->priv->volume[0]; -    guint  right = control->priv->volume[1]; +    guint  left; +    guint  right; + +    left  = control->priv->volume[LEFT_CHANNEL]; +    right = control->priv->volume[RIGHT_CHANNEL];      if (left == right)          balance = 0.0f; @@ -417,7 +444,7 @@ read_balance (OssStreamControl *control)  }  static gboolean -write_and_set_volume (OssStreamControl *control, gint volume) +write_and_store_volume (OssStreamControl *control, gint volume)  {      gint ret; @@ -425,18 +452,11 @@ write_and_set_volume (OssStreamControl *control, gint volume)      if (volume == OSS_VOLUME_JOIN_ARRAY (control->priv->volume))          return TRUE; +    /* The ioctl might also change the passed volume */      ret = ioctl (control->priv->fd, MIXER_WRITE (control->priv->devnum), &volume);      if (ret == -1)          return FALSE; -    oss_stream_control_load (control); -    return TRUE; - -    /* The ioctl may make adjustments to the passed volume, so make sure we have -     * the correct value saved */ -    control->priv->volume[0] = OSS_VOLUME_TAKE_LEFT (volume); -    control->priv->volume[1] = OSS_VOLUME_TAKE_RIGHT (volume); - -    g_object_notify (G_OBJECT (control), "volume"); +    store_volume (control, volume & 0xFFFF);      return TRUE;  } | 
