static void add_channel(struct channel *c) { c->vbox = gtk_vbox_new(FALSE, 5); c->vscale = gtk_vscale_new(GTK_ADJUSTMENT(gtk_adjustment_new( mixer_get(c), 0, 100, 0, 0, 0))); gtk_scale_set_draw_value(GTK_SCALE(c->vscale), FALSE); gtk_range_set_inverted(GTK_RANGE(c->vscale), TRUE); gtk_container_add(GTK_CONTAINER(hbox), c->vbox); gtk_box_pack_start(GTK_BOX(c->vbox), c->vscale, TRUE, TRUE, 0); g_signal_connect((gpointer)c->vscale, "value_changed", G_CALLBACK(vol_change), c); g_signal_connect(c->vscale, "scroll-event", G_CALLBACK(scale_scroll), c); if (_has_switch(c->elem, c->playback)) { c->mute = gtk_check_button_new_with_label( c->playback ? _("Mute") : _("Capture")); g_signal_connect((gpointer)c->mute, "toggled", G_CALLBACK(mute), c); gtk_box_pack_end(GTK_BOX(c->vbox), c->mute, FALSE, FALSE, 0); } update_gui(c); }
static void update_gui(struct channel *c) { mixer_getmute(c); update_icon(c); if (c->mute) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(c->mute), !c->muteval); } else { c->muteval = 1; } gtk_range_set_value(GTK_RANGE(c->vscale), mixer_get(c)); }
/*=========================================================================* * mixer_init *=========================================================================*/ PUBLIC int mixer_init() { /* Try to detect the mixer by writing to MIXER_DAC_LEVEL if the * value written can be read back the mixer is there */ mixer_set(MIXER_DAC_LEVEL, 0x10); /* write something to it */ if(mixer_get(MIXER_DAC_LEVEL) != 0x10) { dprint("sb16: Mixer not detected\n"); return EIO; } /* Enable Automatic Gain Control */ mixer_set(MIXER_AGC, 0x01); dprint("Mixer detected\n"); return OK; }
/*=========================================================================* * get_set_input * *=========================================================================*/ PRIVATE int get_set_input(struct inout_ctrl *input, int flag, int channel) { int input_cmd, input_mask, mask, del_mask, shift; input_cmd = (channel == 0 ? MIXER_IN_LEFT : MIXER_IN_RIGHT); mask = mixer_get(input_cmd); switch (input->device) { case Fm: shift = 5; del_mask = 0x1F; break; case Cd: shift = 1; del_mask = 0x79; break; case Line: shift = 3; del_mask = 0x67; break; case Mic: shift = 0; del_mask = 0x7E; break; default: return EINVAL; } if (flag) { /* Set input */ input_mask = ((input->left == ON ? 1 : 0) << 1) | (input->right == ON ? 1 : 0); if (shift > 0) input_mask <<= shift; else input_mask >>= 1; mask &= del_mask; mask |= input_mask; mixer_set(input_cmd, mask); } else { /* Get input */ if (shift > 0) {
static int mixer_get_avg(int i) { int v = mixer_get(i); return ((v >> 8) + (v & 0xFF)) / 2; }
int mixer_is_mute(int i) { return !mixer_get(i); }
static int mixer_get_right(int i) { return mixer_get(i) & 0xFF; }
/*=========================================================================* * get_set_volume * *=========================================================================*/ PRIVATE int get_set_volume(struct volume_level *level, int flag) { int cmd_left, cmd_right, shift, max_level; shift = 3; max_level = 0x1F; switch(level->device) { case Master: cmd_left = MIXER_MASTER_LEFT; cmd_right = MIXER_MASTER_RIGHT; break; case Dac: cmd_left = MIXER_DAC_LEFT; cmd_right = MIXER_DAC_RIGHT; break; case Fm: cmd_left = MIXER_FM_LEFT; cmd_right = MIXER_FM_RIGHT; break; case Cd: cmd_left = MIXER_CD_LEFT; cmd_right = MIXER_CD_RIGHT; break; case Line: cmd_left = MIXER_LINE_LEFT; cmd_right = MIXER_LINE_RIGHT; break; case Mic: cmd_left = cmd_right = MIXER_MIC_LEVEL; break; case Speaker: cmd_left = cmd_right = MIXER_PC_LEVEL; shift = 6; max_level = 0x03; break; case Treble: cmd_left = MIXER_TREBLE_LEFT; cmd_right = MIXER_TREBLE_RIGHT; shift = 4; max_level = 0x0F; break; case Bass: cmd_left = MIXER_BASS_LEFT; cmd_right = MIXER_BASS_RIGHT; shift = 4; max_level = 0x0F; break; default: return EINVAL; } if(flag) { /* Set volume level */ if(level->right < 0) level->right = 0; else if(level->right > max_level) level->right = max_level; if(level->left < 0) level->left = 0; else if(level->left > max_level) level->left = max_level; mixer_set(cmd_right, (level->right << shift)); mixer_set(cmd_left, (level->left << shift)); } else { /* Get volume level */ level->left = mixer_get(cmd_left); level->right = mixer_get(cmd_right); level->left >>= shift; level->right >>= shift; } return OK; }