func (m *Mixer) Close() error { if err := alsa(C.snd_mixer_close(m.mixer)); err != nil { return fmt.Errorf("alsa: closing mixer: %v", err) } return nil }
func OpenMixer() (*Mixer, error) { var mix *C.snd_mixer_t if err := alsa(C.snd_mixer_open(&mix, 0)); err != nil { return nil, fmt.Errorf("alsa: opening mixer: %v", err) } defer func() { if mix != nil { if err := alsa(C.snd_mixer_close(mix)); err != nil { log.Printf("alsa: closing mixer: %v", err) } } }() card := C.CString(alsaCard) defer C.free(unsafe.Pointer(card)) if err := alsa(C.snd_mixer_attach(mix, card)); err != nil { return nil, fmt.Errorf("alsa: attaching mixer master volume: %v", err) } if err := alsa(C.snd_mixer_selem_register(mix, nil, nil)); err != nil { return nil, fmt.Errorf("alsa: mixer register: %v", err) } if err := alsa(C.snd_mixer_load(mix)); err != nil { return nil, fmt.Errorf("alsa: mixer load: %v", err) } var sid *C.snd_mixer_selem_id_t if err := alsa(C.snd_mixer_selem_id_malloc(&sid)); err != nil { return nil, fmt.Errorf("alsa: allocating mixer element: %v", err) } name := C.CString(mixerElemMaster) defer C.free(unsafe.Pointer(name)) C.snd_mixer_selem_id_set_name(sid, name) elem := C.snd_mixer_find_selem(mix, sid) if elem == nil { return nil, fmt.Errorf("alsa: cannot find mixer element") } if C.snd_mixer_selem_has_playback_volume(elem) == 0 { return nil, errors.New("alsa: mixer has no playback volume") } var min, max C.long if err := alsa(C.snd_mixer_selem_get_playback_volume_range(elem, &min, &max)); err != nil { return nil, fmt.Errorf("alsa: cannot get volume range: %v", err) } if C.snd_mixer_selem_has_playback_switch(elem) == 0 { return nil, errors.New("alsa: mixer has no mute") } m := &Mixer{ mixer: mix, elem: elem, min: int32(min), max: int32(max), } mix = nil elem = nil return m, nil }