All pastes #155625 Raw Edit

Miscellany

public text v1 · immutable
#155625 ·published 2006-08-31 05:22 UTC
rendered paste body
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <alsa/asoundlib.h>

/*
FIXME: If needed, allow the selection of another card besides "default"
ALSO: Handle the channels better. ;)
*/
/*
typedef struct opt_s {
	char *name;
	enum { opt_flag, opt_optinal, opt_required } type;
	char *value;
} opt_t;

opt_t opts[] = {
	{ "get",  opt_flag,     NULL },
	{ "set",  opt_required, NULL },
	{ "inc",  opt_flag,     NULL },
	{ "dec",  opt_flag,     NULL },
	{ "sr",   opt_flag,     NULL },
	{ "er",   opt_flag,     NULL },
	{ "card", opt_required, NULL },
	{ "elem", opt_required, NULL },
	{ NULL,   0,            NULL },
};


int parseopts(int argc, char **argv)
{
	int i = 0;

	for(i=0; i<argc-1; i++) {
		if(strcmp(argv[i], "--")==0) break;

	}

	return i;
}
*/
#ifdef DEBUG
#define debug(a,b...) printf(a, ##b)
#else
#define debug(a,b...) (void)0
#endif

int main(int argc, char **argv)
{
	snd_mixer_t *mixer = NULL;
	snd_mixer_elem_t *elem = NULL;

	enum { GET=1, SET, INC, DEC, START_RANGE, END_RANGE } mode;
	if(argc < 3)
		goto useage;

	if(strcasecmp(argv[1], "GET") != 0) {
		if(strcasecmp(argv[1], "SET") != 0) {
			if(strcasecmp(argv[1], "INC") != 0) {
				if(strcasecmp(argv[1], "DEC") != 0) {
					if(strcasecmp(argv[1], "SRANGE") != 0) {
						if(strcasecmp(argv[1], "ERANGE") != 0) {
							goto useage;
						} else
							mode = END_RANGE;
					} else
						mode = START_RANGE;
				} else {
					mode = DEC;
				}
			} else {
				mode = INC;
			}
		} else {
			if(argc < 4)
				goto useage;
			mode = SET;
		}
	} else
		mode = GET;

	debug("opening mixer\n");

	{
		char *string = NULL;
		int i = 0;

		while(i > -1) {
			snd_card_get_name(i, &string);
			//printf("Card name: \"%s\"\n", string);
			snd_card_next(&i);
		}
	}

	if(snd_mixer_open(&mixer, 0) < 0) {
		debug("Failed...\n");
		exit(EXIT_FAILURE);
	}

	debug("attaching card to mixer\n");

	if(snd_mixer_attach(mixer, "default") < 0) {
		debug("Failed...\n");
		exit(EXIT_FAILURE);
	}

	if(snd_mixer_selem_register (mixer, NULL, NULL) < 0) {
		debug("Failed...\n");
		exit(EXIT_FAILURE);
	}

	debug("loading mixer elems\n");

	if(snd_mixer_load(mixer) < 0) {
		debug("Failed...\n");
		exit(EXIT_FAILURE);
	}

	elem = snd_mixer_first_elem(mixer);

	while(elem) {

		const char *name = snd_mixer_selem_get_name(elem);
		long min=0, max=0;
		unsigned int id = snd_mixer_selem_get_index(elem);

		//printf("elem \"%s\" == \"%i\"\n", name, id);

		if(strcasecmp(name, argv[2]) != 0) {
			elem = snd_mixer_elem_next(elem);
			continue;
		}

		switch(mode) {
			case GET: {
				long vol = 0;
				snd_mixer_selem_get_playback_volume(elem, 0, &vol);
				printf("%li\n", vol);
			} break;

			case SET: {
				long vol = strtol(argv[3], NULL, 0);
				snd_mixer_selem_set_playback_volume(elem, 0, vol);
				snd_mixer_selem_set_playback_volume(elem, 1, vol);
			} break;

			case INC: {
				long inc = argc > 3 ? strtol(argv[3], NULL, 0) : 1, vol = 0;
				snd_mixer_selem_get_playback_volume(elem, 0, &vol);
				snd_mixer_selem_set_playback_volume(elem, 0, vol+inc);
				snd_mixer_selem_set_playback_volume(elem, 1, vol+inc);
			} break;

			case DEC: {
				long dec = argc > 3 ? strtol(argv[3], NULL, 0) : 1, vol = 0;
				snd_mixer_selem_get_playback_volume(elem, 0, &vol);
				snd_mixer_selem_set_playback_volume(elem, 0, vol-dec);
				snd_mixer_selem_set_playback_volume(elem, 1, vol-dec);
			} break;

			case START_RANGE: {
				snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
				printf("%li\n", min);
			} break;

			case END_RANGE: {
				snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
				printf("%li\n", max);
			}
		}

		elem = snd_mixer_elem_next(elem);
		// break;
	}

	snd_mixer_close(mixer);

	return 0;

	useage:
		fprintf(stderr, "Useage: %s (set|get|inc|dec|srange|erange) \"control name\" <value>\n", argv[0]);
		exit(EXIT_FAILURE);
}