GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Thu Apr 17, 2014 4:10 am

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Help with code for GtkVolumeButton
PostPosted: Mon Jan 28, 2013 11:44 pm 
Offline
Familiar Face

Joined: Thu Nov 22, 2012 3:46 pm
Posts: 19
This code is for alsa mixer volume

Code:
static const char alsa_core_devnames[] = "default";
static char *card, *channel;
static int muted = 0;
static int mutecount = 0;
static snd_mixer_t *handle = NULL;
static snd_mixer_elem_t *elem = NULL;

static long alsa_min, alsa_max, alsa_vol;

/* Volume saved to file */
static int alsa_get_unmute_volume( void )
{
    long val;
    assert (elem);

    if (snd_mixer_selem_is_playback_mono(elem)) {
        snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
        return val;
    } else {
        int c, n = 0;
        long sum = 0;
        for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
            if (snd_mixer_selem_has_playback_channel(elem, c)) {
                snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
                sum += val;
                n++;
            }
        }
        if (! n) {
            return 0;
        }

        val = sum / n;
        sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);

        if (sum != val) {
           alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
        }
        return alsa_vol;
    }
}

static int alsa_get_volume( void )
{
    if (muted)
        return 0;
    else
        return alsa_get_unmute_volume();
}

static int alsa_set_volume( int percentdiff )
{
    long volume;

    alsa_get_volume();

    alsa_vol += percentdiff;
    if( alsa_vol > 100 ) alsa_vol = 100;
    if( alsa_vol < 0 ) alsa_vol = 0;

    volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);

    snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
    snd_mixer_selem_set_playback_switch_all(elem, 1);
    muted = 0;
    mutecount = 0;

    return alsa_vol;
}

static void alsa_mute( int mute )
{
    if( !mute && mutecount ) mutecount--;
    if( mutecount ) return;

    if( mute ) {
        mutecount++;
        muted = 1;
        if (snd_mixer_selem_has_playback_switch(elem))
            snd_mixer_selem_set_playback_switch_all(elem, 0);
        else
            fprintf(stderr, "mixer: mute not implemented\n");
    } else {
        muted = 0;
        if (snd_mixer_selem_has_playback_switch(elem))
            snd_mixer_selem_set_playback_switch_all(elem, 1);
        else
            fprintf(stderr, "mixer: mute not implemented\n");
    }
}

static int alsa_ismute( void )
{
    return muted;
}


Please help me to write a GtkVolumeButton to work with the code above with the following functions:

1. volume value changed
2. toggle mute volume

Tried this but when value from gtk button is changed up or down, alsa mixer always jumps to 100 %:

Code:
void start_mixer(GtkWidget *app)
{
   gint vol;
   
   char *mixer_device = "hw:0/Line";
   mixer_set_device(mixer_device);
   vol = alsa_get_volume();
   if (vol >= 0) {
      gtk_volume_button_set_value(button, vol);
   }
}

int gtk_volume_button_get_value (GtkWidget *button)
{
   return (int) (gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100);
}

void gtk_volume_button_set_value (GtkWidget *button, int value)
{
   gtk_scale_button_set_value(GTK_SCALE_BUTTON(button), (gdouble) value / 100);
}

void volume_value_changed_cb(GtkVolumeButton *button, gpointer user_data)
{
   int vol = (int)(gtk_volume_button_get_value(button) + 0.5);
   
   alsa_set_volume(vol);
}

void toggle_volume(void)
{
   static int old_vol;
   int vol = alsa_get_volume();
   
   if (vol) {
      old_vol = vol;
      vol = 0;
   } else {
      vol = old_vol;
   }   
   alsa_set_volume(vol);
   gtk_volume_button_set_value(button, vol);
}


Top
 Profile  
 
 Post subject: Re: Help with code for GtkVolumeButton
PostPosted: Wed Feb 06, 2013 10:37 pm 
Offline
Never Seen the Sunlight

Joined: Thu Mar 24, 2011 2:10 pm
Posts: 328
Location: Sydney, Australia
It is hard to say as you've given barely any code from the GUI side. The mistake I can most readily imagine would be if the adjustment on the scale button is not set right, but as I see gtk_volume_button used in places I don't think that is the case.
gtk_volume_button_set/get_value; however, are not functions so I have no idea how your code runs at all. Maybe these are just typos.
You are doing a lot of floating point arithmetic on integers. There are a number of times you haven't converted to floating point before adding the 0.5. You would be better to use the rounding functions in math.h (floor, ceil, etc.) so as to avoid making these mistakes regularly.
Not too sure if its important but the first alsa function only checks if alsa_vol is current for the else case. I also don't see why alsa_vol needs to be a long, being limited from 0 to 100.
You will also likely have some major issues in your last function as old_vol is uninitialised.

*****For that matter, as far as I know alsa_vol is also uninitialised. In which case when you go through the value changed callback and somehow get a value then call alsa_get_unmute_volume, let's say its mono in which case alsa_vol is unupdated and remains uninitialised, you then run the rest of set_volume adding percent diff to this uninitialised (and likely very big) number and hey presto its coerced to 100 in 100-10000*(2^-32)% of the cases.*****

The fact that the code has so many one line wrapper functions makes it difficult to read with having to jump from place to place.
Did you compile your code with warnings enabled? Usually it picks up issues like this.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group