bool audio_set_volume(audio_t *audio, unsigned volume) { struct mixer *mixer; bool res; mixer = mixer_open(audio->dev.card); if (! mixer) { fprintf(stderr, "Failed to open mixer\n"); return false; } if (audio->dev.playback) { res = do_set_volume(mixer, "PCM Playback Volume", volume) || mixer_set(mixer, "PCM Playback Route", 1); } else { res = do_set_volume(mixer, "Mic Capture Volume", volume) || mixer_set(mixer, "Mic Capture Switch", 1) || mixer_set(mixer, "Speaker Playback Switch", 0) || mixer_set(mixer, "Mic Playback Switch", 0); } mixer_close(mixer); return res; }
void sb16_device::mixer_reset() { m_mixer.status = 0x80; m_mixer.main_vol[0] = 0xc0; m_mixer.main_vol[1] = 0xc0; m_mixer.dac_vol[0] = 0xc0; m_mixer.dac_vol[1] = 0xc0; m_mixer.fm_vol[0] = 0xc0; m_mixer.fm_vol[1] = 0xc0; m_mixer.cd_vol[0] = 0x00; m_mixer.cd_vol[1] = 0x00; m_mixer.line_vol[0] = 0x00; m_mixer.line_vol[1] = 0x00; m_mixer.mic_vol = 0x00; m_mixer.pc_speaker_vol = 0x00; m_mixer.output_ctl = 0x1f; m_mixer.input_ctl[0] = 0x15; m_mixer.input_ctl[1] = 0x0b; m_mixer.input_gain[0] = 0x00; m_mixer.input_gain[1] = 0x00; m_mixer.output_gain[0] = 0x00; m_mixer.output_gain[1] = 0x00; m_mixer.agc = 0x00; m_mixer.treble[0] = 0x80; m_mixer.treble[1] = 0x80; m_mixer.bass[0] = 0x80; m_mixer.bass[1] = 0x80; mixer_set(); }
/*=========================================================================* * 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; }
/*===========================================================================* * dsp_init *===========================================================================*/ PRIVATE int dsp_init() { int i, s; if(dsp_reset () != OK) { dprint("sb16: No SoundBlaster card detected\n"); return -1; } DspVersion[0] = DspVersion[1] = 0; dsp_command(DSP_GET_VERSION); /* Get DSP version bytes */ for(i = 1000; i; i--) { if(sb16_inb(DSP_DATA_AVL) & 0x80) { if(DspVersion[0] == 0) { DspVersion[0] = sb16_inb(DSP_READ); } else { DspVersion[1] = sb16_inb(DSP_READ); break; } } } if(DspVersion[0] < 4) { dprint("sb16: No SoundBlaster 16 compatible card detected\n"); return -1; } dprint("sb16: SoundBlaster DSP version %d.%d detected\n", DspVersion[0], DspVersion[1]); /* set SB to use our IRQ and DMA channels */ mixer_set(MIXER_SET_IRQ, (1 << (SB_IRQ / 2 - 1))); mixer_set(MIXER_SET_DMA, (1 << SB_DMA_8 | 1 << SB_DMA_16)); /* register interrupt vector and enable irq */ if ((s=sys_irqsetpolicy(SB_IRQ, IRQ_REENABLE, &irq_hook_id )) != OK) panic("Couldn't set IRQ policy: %d", s); if ((s=sys_irqenable(&irq_hook_id)) != OK) panic("Couldn't enable IRQ: %d", s); DspAvail = 1; return OK; }
PUBLIC int drv_init_hw(void) { int i; int DspVersion[2]; Dprint(("drv_init_hw():\n")); if(drv_reset () != OK) { Dprint(("sb16: No SoundBlaster card detected\n")); return -1; } DspVersion[0] = DspVersion[1] = 0; dsp_command(DSP_GET_VERSION); /* Get DSP version bytes */ for(i = 1000; i; i--) { if(sb16_inb(DSP_DATA_AVL) & 0x80) { if(DspVersion[0] == 0) { DspVersion[0] = sb16_inb(DSP_READ); } else { DspVersion[1] = sb16_inb(DSP_READ); break; } } } if(DspVersion[0] < 4) { Dprint(("sb16: No SoundBlaster 16 compatible card detected\n")); return -1; } Dprint(("sb16: SoundBlaster DSP version %d.%d detected!\n", DspVersion[0], DspVersion[1])); /* set SB to use our IRQ and DMA channels */ mixer_set(MIXER_SET_IRQ, (1 << (SB_IRQ / 2 - 1))); mixer_set(MIXER_SET_DMA, (1 << SB_DMA_8 | 1 << SB_DMA_16)); DspFragmentSize = sub_dev[AUDIO].DmaSize / sub_dev[AUDIO].NrOfDmaFragments; return OK; }
/*=========================================================================* * get_set_input * *=========================================================================*/ PRIVATE int get_set_input(const message *m_ptr, int flag, int channel) /* * flag 0 = get, 1 = set * channel 0 = left, 1 = right */ { struct inout_ctrl input; int input_cmd, input_mask, mask, del_mask, shift; sys_datacopy(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->ADDRESS, SELF, (vir_bytes)&input, (phys_bytes)sizeof(input)); 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) {
int mixer_init(snddev_info *d, snd_mixer *m, void *devinfo) { if (d == NULL) return -1; d->mixer = *m; d->mixer.devinfo = devinfo; bzero(&d->mixer.level, sizeof d->mixer.level); if (d->mixer.init != NULL && d->mixer.init(&d->mixer) == 0) { int i; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { u_int16_t v = snd_mixerdefaults[i]; mixer_set(d, i, v | (v << 8)); } mixer_setrecsrc(d, SOUND_MASK_MIC); return 0; } else return -1; }
/*=========================================================================* * 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 void vol_change(GtkRange *range, struct channel *c) { mixer_set(c, gtk_range_get_value(range)); }
/*=========================================================================* * get_set_volume * *=========================================================================*/ PRIVATE int get_set_volume(const message *m_ptr, int flag) /* flag 0 = get, 1 = set */ { struct volume_level level; int cmd_left, cmd_right, shift, max_level; sys_datacopy(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->ADDRESS, SELF, (vir_bytes)&level, (phys_bytes)sizeof(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; /* Copy back to user */ sys_datacopy(SELF, (vir_bytes)&level, m_ptr->IO_ENDPT, (vir_bytes)m_ptr->ADDRESS, (phys_bytes)sizeof(level)); } return OK; }
/*=========================================================================* * 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; }