/* * osdmixer version 0.9 by Peter Kupietz (peter.kupietz@gmx.net) * * osdmixer displays master volume and pcm settings with xosd * depends on xosd (http://www.ignavus.net/software.html) * * to compile type: * * make * * (gcc `xosd-config --cflags --libs` -lpthread main.c -o osdmixer) * * usage: * osdmixer pos_x pos_y delay fonttype * * pos_x horizontal space in pixels (default 48) * pos_y vertical space in pixels (default 48) * delay delay before OSD closes (default 4, 2 - 6 is useful) * fonttype change font (default 1) * 1 for -adobe-helvetica-bold-r-normal-*-*-240-*-*-p-*-iso8859-1 * 2 for -adobe-helvetica-bold-r-normal-*-*-320-*-*-p-*-iso8859-1 * * examples: * osdmixer 68 48 4 1 (these are default values) * osdmixer d 80 d d (use d for default value) * * main.c */ #include #include #include #include #include #include #include #include #include #include #include #include static int master = 0; static int pcm = 0; // handles static int fd_mixer; static xosd *osd = NULL; // style and position static int font_type = 1; static char *font1 = "-adobe-helvetica-bold-r-normal-*-*-240-*-*-p-*-iso8859-1"; static char *font2 = "-adobe-helvetica-bold-r-normal-*-*-320-*-*-p-*-iso8859-1"; static int pos_x = 48; static int pos_y = 48; static int osd_delay = 4; static int system_delay = 40000; void* volume_read (void* v); void init_bars (void); int changed (int m, int p); int main (int argc, char *argv[]) { pthread_t mythread; fd_mixer = open("/dev/mixer", O_RDWR); int m_prev, p_prev; int countdown = osd_delay * 10; if (argc < 5) { // help printf ("\nosdmixer version 0.9\n"); printf ("\nUsage:\n"); printf ("osdmixer pos_x pos_y delay fonttype\n"); printf ("\npos_x horizontal space in pixels (default 48)\n"); printf ("pos_y vertical space in pixels (default 48)\n"); printf ("delay delay before OSD closes (default 4, 2 - 6 is useful)\n"); printf ("fonttype change font (default 1)\n"); printf (" 1 for %s\n", font1); printf (" 2 for %s\n", font2); printf ("\nExamples:\n"); printf ("osdmixer 48 48 4 1 (these are default values)\n"); printf ("osdmixer d 80 d d (use d for default value)\n\n"); return 0; } // get arguments, ignore them, if they are not plausible, use strtol() in future if (argv[1] != "d") { if ((atoi(argv[1]) < 2000) && (atoi(argv[1]) > 0)) { pos_x = atoi(argv[1]); } } if (argv[2] != "d") { if ((atoi(argv[2]) < 1500) && (atoi(argv[2]) > 0)) { pos_y = atoi(argv[2]); } } if (argv[3] != "d") { if ((atoi(argv[3]) < 10) && (atoi(argv[3]) > 0)) { osd_delay = atoi(argv[3]); } } if (argv[4] != "d") { if ((atoi(argv[4]) < 3) && (atoi(argv[4]) > 0)) { font_type = atoi(argv[4]); } } setlocale (LC_ALL, ""); pthread_create (&mythread,NULL, volume_read,NULL); // keeps master and pcm up-to-date while (1) { m_prev = master; p_prev = pcm; usleep (system_delay); if ((changed (m_prev, p_prev)) || (countdown == -1)) { // volume has been changed by user countdown = osd_delay * 10; if (osd == NULL) { // no init needed if countdown == -1 (OSD has not been destroyed) init_bars (); } while(countdown > 0) { // delay before closing OSD after last volume change, check for new changes while (changed (m_prev, p_prev)) { countdown = 0; if (master == 0) { xosd_display (osd, 1, XOSD_string, "(muted)"); } else { xosd_display (osd, 1, XOSD_percentage, master / 257); // first bar, line 2 } if (pcm == 0) { xosd_display (osd, 3, XOSD_string, "(muted)"); } else { xosd_display (osd, 3, XOSD_percentage, pcm / 257); // second bar, line 4 } m_prev = master; p_prev = pcm; } // volume changes -> break, show change countdown--; } } if (countdown == 0) { xosd_destroy (osd); osd = NULL; } // close OSD because there were no more volume changes // countdown == -1 when volume changes during countdown } close (fd_mixer); return 0; } int changed (int m, int p) { // returns 1 when volume was changed usleep (system_delay); if ((m != master) || (p != pcm)) { return 1; } else { return 0; } } void init_bars (void) { // init OSD osd = xosd_create (4); // we need 4 lines if (osd == NULL) { perror ("Could not create \"osd\""); exit (1); } // style and position switch(font_type) { case 1: xosd_set_font (osd, font1); break; case 2: xosd_set_font (osd, font2); break; default: xosd_set_font (osd, font2); break; } xosd_set_outline_offset(osd, 2); xosd_set_outline_colour(osd, "black"); //xosd_set_shadow_offset (osd, 3); xosd_set_colour (osd, "lawngreen"); xosd_set_pos (osd, XOSD_bottom); xosd_set_vertical_offset (osd, pos_y); xosd_set_align (osd, XOSD_left); xosd_set_horizontal_offset (osd, pos_x); xosd_set_bar_length (osd, 50); xosd_display (osd, 0, XOSD_string, "Master"); // display line 1 xosd_display (osd, 2, XOSD_string, "PCM"); // display line 3 usleep (2500); } void* volume_read (void* v) { // read mixer, read mixer, read mixer, ..... while (1) { if (fd_mixer) { ioctl(fd_mixer,SOUND_MIXER_READ_VOLUME,&master); ioctl(fd_mixer,SOUND_MIXER_READ_PCM,&pcm); usleep (system_delay); } } return NULL; }