Beispiel #1
0
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
}
Beispiel #2
0
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
}