summaryrefslogtreecommitdiff
path: root/contributions/ossmeter/ossmeter.c
diff options
context:
space:
mode:
Diffstat (limited to 'contributions/ossmeter/ossmeter.c')
-rwxr-xr-xcontributions/ossmeter/ossmeter.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/contributions/ossmeter/ossmeter.c b/contributions/ossmeter/ossmeter.c
new file mode 100755
index 0000000..84726b4
--- /dev/null
+++ b/contributions/ossmeter/ossmeter.c
@@ -0,0 +1,322 @@
+/*
+ * Purpose: Sources for the ossmix command line mixer shipped with OSS
+ *
+ * Description:
+ * The {!xlink ossmeter} program was originally developed from a test bed
+ * program for the new mixer API. However it has been included in the
+ * oss package because there is need for a command line peak meter viewer.
+ *
+ * Authors: ?? Original author of ossmix
+ * D. Casey Tucker Producer of ossmeter
+ */
+/*
+ *
+ * This file should be part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <soundcard.h>
+#include <sys/ioctl.h>
+#ifndef LOCAL_BUILD
+#include <local_config.h>
+#endif
+
+static char *progname = NULL;
+static int mixerfd = -1, nrext = 0, quiet = 0, verbose = 0, verbose_info = 0, nlines = 0;
+
+static oss_mixext *extrec;
+static oss_mixext_root *root;
+
+static void change_level (int, const char *, const char *);
+static void dump_all (int);
+static void dump_devinfo (int);
+static int find_enum (const char *, oss_mixext *, const char *);
+static int find_name (const char *);
+static void load_devinfo (int);
+static void print_description (char *);
+static void show_devinfo (int);
+
+static void show_level (int, int);
+
+static char * show_choices (const char *, oss_mixext *);
+static char * show_enum (const char *, oss_mixext *, int);
+static void usage (void);
+static void verbose_devinfo (int);
+#ifdef CONFIG_OSS_MIDI
+static void midi_set (int, int, int);
+static void midi_mixer (int, char *, char **, int, int);
+static void smurf (int, int);
+#endif
+
+ static void
+usage (void)
+{
+ printf ("Usage: %s -h Displays help (this screen)\n", progname);
+ printf ("Usage: %s [-d<devno>] [arguments]\n", progname);
+ printf ("arguments:\n");
+ printf ("\t-D Display device information\n");
+ printf ("\t-a Dump mixer settings for all mixers (normal format)\n");
+ printf ("\t-c Dump mixer settings for all mixers (command format)\n");
+ printf ("\tctrl# value Change value of a mixer control\n");
+ printf ("\t-q Quiet mode\n");
+ printf ("\t-v1|-v2 Verbose mode (-v2 is more verbose).\n");
+ printf ("\t<no arguments> Display current/possible settings\n");
+ exit (-1);
+}
+
+static void
+load_devinfo (int dev)
+{
+ int i;
+ oss_mixext *thisrec;
+ oss_mixerinfo mi;
+
+ mi.dev = dev;
+ if (ioctl (mixerfd, SNDCTL_MIXERINFO, &mi) != -1)
+ {
+ close (mixerfd);
+
+ if ((mixerfd=open(mi.devnode, O_RDWR, 0)) == -1)
+ {
+ perror (mi.devnode);
+ exit (EXIT_FAILURE);
+ }
+ }
+ nrext = mi.nrext;
+
+ if (nrext < 1)
+ {
+ fprintf (stderr, "Mixer device %d has no functionality\n", dev);
+ exit (-1);
+ }
+
+ if ((extrec =
+ (oss_mixext *)malloc ((nrext + 1) * sizeof (oss_mixext))) == NULL)
+ {
+ fprintf (stderr, "malloc of %d entries failed\n", nrext+1);
+ exit (-1);
+ }
+
+ for (i = 0; i < nrext; i++)
+ {
+ thisrec = &extrec[i];
+ thisrec->dev = dev;
+ thisrec->ctrl = i;
+
+ if (ioctl (mixerfd, SNDCTL_MIX_EXTINFO, thisrec) == -1)
+ {
+ if (errno == EINVAL)
+ {
+ fprintf (stderr, "Incompatible OSS version\n");
+ exit (-1);
+ }
+ perror ("SNDCTL_MIX_EXTINFO");
+ exit (-1);
+ }
+
+ if (thisrec->type == MIXT_DEVROOT)
+ root = (oss_mixext_root *) thisrec->data;
+ }
+}
+
+static void
+verbose_devinfo (int dev)
+{
+ int i;
+ oss_mixext *thisrec;
+ oss_mixer_value val;
+ val.dev = dev;
+
+
+ if( nlines != 0 ) printf("\e[%dA", nlines);
+ nlines=0;
+ for (i = 0; i < nrext; i++)
+ {
+ thisrec = &extrec[i];
+
+ val.ctrl = i;
+ val.timestamp = thisrec->timestamp;
+ val.value = -1;
+
+ switch (thisrec->type)
+ {
+ case MIXT_STEREOVU:
+ case MIXT_STEREOPEAK:
+ printf ("%2d: %s \t", i, thisrec->id, thisrec->maxvalue);
+ show_level(dev, i );
+ nlines++;
+ break;
+ }
+
+ }
+}
+
+#define COLS 40
+#define DB18 COLS * 0.125
+#define DB6 COLS * 0.5
+#define DB1 COLS * 0.89
+
+void color(int c)
+{
+ if (c < DB18 )
+ printf("\e[36m");
+ else if (c < DB6)
+ printf("\e[32m");
+ else if ( c < DB1 )
+ printf("\e[33m");
+ else
+ printf("\e[31m");
+}
+
+static void
+show_level (int dev, int ctrl )
+{
+ int left = 0, right = 0;
+ oss_mixer_value val;
+ oss_mixext extrec;
+ int mask = 0xff;
+ int shift = 8;
+
+ float fl_left, fl_right, db,
+ fl_max, fl_min;
+
+ extrec.dev = dev;
+ extrec.ctrl = ctrl;
+
+ if (ioctl (mixerfd, SNDCTL_MIX_EXTINFO, &extrec) == -1)
+ {
+ perror ("SNDCTL_MIX_EXTINFO");
+ exit (-1);
+ }
+
+ val.dev = dev;
+ val.ctrl = ctrl;
+ val.timestamp = extrec.timestamp;
+ if (ioctl (mixerfd, SNDCTL_MIX_READ, &val) == -1)
+ {
+ perror ("SNDCTL_MIX_READ");
+ exit (-1);
+ }
+
+ if (extrec.type == MIXT_MONOSLIDER16 || extrec.type == MIXT_STEREOSLIDER16)
+ {
+ mask = 0xffff;
+ shift = 16;
+ }
+
+ switch (extrec.type)
+ {
+ case MIXT_STEREOSLIDER:
+ case MIXT_STEREOSLIDER16:
+ case MIXT_STEREODB:
+ case MIXT_STEREOPEAK:
+ case MIXT_STEREOVU:
+ left = val.value & mask;
+ right = (val.value >> shift) & mask;
+
+ /*
+ if (extrec.flags & MIXF_CENTIBEL)
+ printf ("%d.%d:%d.%d (dB)\n",
+ left / 10, left % 10, right / 10, right % 10);
+ else
+ printf ("%d:%d\n", left, right);
+ */
+ break;
+ case MIXT_VALUE:
+ //printf ("%d\n", val.value);
+ break;
+ default:
+ left = val.value & mask;
+
+ /*
+ if (extrec.flags & MIXF_CENTIBEL)
+ printf ("%d.%d (dB)\n",
+ left / 10, left % 10);
+ else
+ printf ("%d\n", left);
+ */
+ break;
+ }
+ fl_left = left / (float) extrec.maxvalue;
+ fl_right = right / (float) extrec.maxvalue;
+ fl_min = fl_left < fl_right ? fl_left : fl_right;
+ fl_max = fl_left > fl_right ? fl_left : fl_right;
+
+ int c=0;
+ for(; c < fl_min * COLS; c++){
+ color(c);
+ printf("▐");
+ }
+ for(; c < fl_left * COLS; c++){
+ color(c);
+ printf("▀");
+ }
+ for(; c < fl_right * COLS; c++){
+ color(c);
+ printf("▄");
+ }
+ for(; c < COLS; c++){
+ color(c);
+ printf("-");
+ }
+ db = 20. * log10(fl_max);
+ printf ("\e[0m %+8.2f \n", db );
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ extern char * optarg;
+ extern int optind, optopt;
+ int dev = 0, c;
+ const char * devmixer;
+
+ progname = argv[0];
+
+ if ((devmixer = getenv("OSS_MIXERDEV")) == NULL)
+ devmixer = "/dev/mixer";
+
+ if ((mixerfd = open (devmixer, O_RDWR, 0)) == -1)
+ {
+ perror (devmixer);
+ exit (-1);
+ }
+
+ verbose_info = 1;
+ load_devinfo (dev);
+
+ while(1)
+ {
+ verbose_devinfo (dev);
+ usleep(500*1000);
+ }
+ exit (0);
+
+ close (mixerfd);
+ return 0;
+}