Esempio n. 1
0
File: prefs.c Progetto: Cw1X/pnmixer
void fill_card_combo(GtkWidget *combo, GtkWidget *channels_combo) {
  struct acard* c;
  GSList *cur_card;
  gchar* selected_card;
  int fs=0,idx,sidx=0;

  GtkTreeIter iter;
  GtkListStore* store = GTK_LIST_STORE(gtk_combo_box_get_model
				       (GTK_COMBO_BOX(combo)));

  cur_card = cards;
  selected_card = get_selected_card();
  idx = 0;
  while (cur_card) {
    c = cur_card->data;
    if (!c->channels) {
      cur_card = cur_card->next;
      continue;
    }
    if (selected_card && !strcmp(c->name,selected_card)) {
      gchar *sel_chan = get_selected_channel(c->name);
      sidx = idx;
      fill_channel_combo(c->channels,channels_combo,sel_chan);
      fs = 1;
      if (sel_chan)
	g_free(sel_chan);
    }
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, c->name, -1);
    cur_card = cur_card->next;
    idx++;
  }
  if (!fs) {
    gchar *sel_chan;
    c = cards->data;
    sel_chan = get_selected_channel(c->name);
    fill_channel_combo(c->channels,channels_combo,sel_chan);
    if (sel_chan)
      g_free(sel_chan);
  }
  gtk_combo_box_set_active (GTK_COMBO_BOX (combo),sidx);
  if (selected_card)
    g_free(selected_card);
}
Esempio n. 2
0
/**
 * Initializes the alsa system by getting the cards
 * and channels and setting the io watch for external
 * volume changes.
 *
 * @return 0 on success otherwise negative error code
 */
static int
alsaset(void)
{
    char *card_name;
    char *channel;

    // update list of available cards
    DEBUG_PRINT("Getting available cards...");
    get_cards();
    assert(cards != NULL);

    // get selected card
    assert(active_card == NULL);
    card_name = get_selected_card();
    DEBUG_PRINT("Selected card: %s", card_name);
    if (card_name) {
        active_card = find_card(card_name);
        g_free(card_name);
    }
    // if not available, use the default card
    if (!active_card) {
        DEBUG_PRINT("Using default soundcard");
        active_card = cards->data;
    }
    // If no playable channels, iterate on card list until a valid card is
    // found.
    // In most situations, the first card of the list (which is the
    // Alsa default card) can be opened.
    // However, in some situations the default card may be unavailable.
    // For example, when it's an USB DAC, and it's disconnected.
    if (!active_card->channels) {
        GSList *item;
        DEBUG_PRINT("Card '%s' has no playable channels, iterating on card list",
                    active_card->dev);
        for (item = cards; item; item = item->next) {
            active_card = item->data;
            if (active_card->channels)
                break;
        }
        assert(item != NULL);
    }
    // open card
    DEBUG_PRINT("Opening card '%s'...", active_card->dev);
    smixer_options.device = active_card->dev;
    handle = open_mixer(active_card->dev, &smixer_options, smixer_level);
    assert(handle != NULL);

    // Set the channel
    // We have to handle the fact that the channel name defined
    // in PNMixer configuration is not necessarily valid.
    // For example, this may happen when the default alsa soundcard
    // is modified. The channel names of the new default card may
    // not match the channel names of the previous default card.
    assert(elem == NULL);
    channel = get_selected_channel(active_card->name);
    if (channel) {
        snd_mixer_selem_id_t *sid;
        snd_mixer_selem_id_alloca(&sid);
        snd_mixer_selem_id_set_name(sid, channel);
        elem = snd_mixer_find_selem(handle, sid);
        g_free(channel);
    }
    if (elem == NULL) {
        elem = snd_mixer_first_elem(handle);
    }
    assert(elem != NULL);

    // Set callback
    DEBUG_PRINT("Using channel '%s'", snd_mixer_selem_get_name(elem));
    snd_mixer_elem_set_callback(elem, alsa_cb);

    // set watch for volume changes
    set_io_watch(handle);

    return 0;
}