[nas] patch: output gain scaling

Paul Fox pgf at foxharp.boston.ma.us
Mon Jul 24 19:00:43 MDT 2006


i have a response composed for erik, but just got both of jon's
replies, so i need to think some more.  :-)

in the meantime, here's my support for limiting output gain, via
a percentage scale factor specified in the config file.

when i started implementing this, i was surprised that a) so much
fo the config i've taken for granted as being applicable to all
platforms is voxware only, and b) that someone already started
implementing a maximum gain feature in the device independent
layer:  search for AuSetMaxOutputGain() in server/dia/auprocess.c,
and observe that it's never called by anyone.  but since there's
currently no real config capability for that layer, this patch
doesn't use that code, or modifiy it.

this patch also doesn't apply to input -- it affects output only.

paul

Index: server/nasd.conf.man
===================================================================
--- server/nasd.conf.man	(revision 162)
+++ server/nasd.conf.man	(working copy)
@@ -53,12 +53,17 @@
 .B gain number
 Specifies the default volume (0-100). The default is 50.
 .PP
+.B gainscale number
+This factor (expressed as a percentage) is applied to all volume-setting
+requests.  This lets the server transparently limit the actual
+maximum volume that can be set by clients.
+.PP
 .B maxrate number
-the maximum number of samples per second that we'll drive the
+The maximum number of samples per second that we'll drive the
 card at.
 .PP
 .B minrate number
-the minimum number of samples per second that the card will be driven
+The minimum number of samples per second that the card will be driven
 at.
 .PP
 .B maxfrags number
Index: server/dda/voxware/auvoxware.c
===================================================================
--- server/dda/voxware/auvoxware.c	(revision 162)
+++ server/dda/voxware/auvoxware.c	(working copy)
@@ -265,7 +265,8 @@
 	1,			/* autoOpen */
 	0,			/* forceRate */
 	0,			/* isPCSpeaker */
-	50			/* default gain */
+	50,			/* default gain */
+	100			/* gain reduction factor */
 }, sndStatOut =
 {
 	-1,			/* fd */
@@ -287,7 +288,8 @@
 	1,			/* autoOpen */
 	0,			/* forceRate */
 	0,			/* isPCSpeaker */
-	50			/* default gain */
+	50,			/* default gain */
+	100			/* gain reduction factor */
 };
 
 #define auDefaultInputGain	AuFixedPointFromSum(sndStatIn.gain, 0)
@@ -956,6 +958,12 @@
     if (g < 0)
         g = 0;
     lastPhysicalOutputGain = g;
+
+    if (sndStatOut.gainScale ) {
+	g *= sndStatOut.gainScale;
+	g /= 100;
+    }
+
     gusvolume = g | (g << 8);
     if (mixerfd != -1)
       if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &gusvolume) == -1)
Index: server/dda/voxware/config.c
===================================================================
--- server/dda/voxware/config.c	(revision 162)
+++ server/dda/voxware/config.c	(working copy)
@@ -43,6 +43,14 @@
       confStat->forceRate = num ;
       break;
 
+    case GAINSCALE :
+      num = (int) value;
+      if (num < 0 || num > 100) 
+	osLogMsg("config: gain scaling must be within the range 0-100\n");
+      else
+      confStat->gainScale = num ;
+      break;
+
     case GAIN :
       num = (int) value;
       /* the default is 50, so if it's just out of range, don't
Index: server/dda/voxware/config.h
===================================================================
--- server/dda/voxware/config.h	(revision 162)
+++ server/dda/voxware/config.h	(working copy)
@@ -25,7 +25,8 @@
   int	autoOpen ;
   int	forceRate ;
   int isPCSpeaker;
-  int gain;			/* default gain */
+  int gain;		/* default gain */
+  int gainScale;	/* percentage by which gain is always reduced */ 
 } SndStat;
 
 
Index: server/dia/lex.l
===================================================================
--- server/dia/lex.l	(revision 162)
+++ server/dia/lex.l	(working copy)
@@ -21,6 +21,7 @@
 [Oo][Uu][Tt][Pp][Uu][Tt][Ss][Ee][Cc][Tt][Ii][Oo][Nn] { return OUTPUTSECTION; }
 [Ee][Nn][Dd]                            { return ENDSECTION; }
 [Gg][Aa][Ii][Nn]                        { return GAIN; }
+[Gg][Aa][Ii][Nn][Ss][Cc][Aa][Ll][Ee]    { return GAINSCALE; }
 [Ww][Oo][Rr][Dd][Ss][Ii][Zz][Ee]	{ return WORDSIZE; }
 [Ff][Rr][Aa][Gg][Ss][Ii][Zz][Ee]	{ return FRAGSIZE; }
 [Mm][Ii][Nn][Ff][Rr][Aa][Gg][Ss]	{ return MINFRAGS; }
Index: server/dia/gram.y
===================================================================
--- server/dia/gram.y	(revision 162)
+++ server/dia/gram.y	(working copy)
@@ -28,7 +28,7 @@
 %token <num> INPUTSECTION OUTPUTSECTION ENDSECTION WORDSIZE FRAGSIZE MAXFRAGS
 %token <num> MINFRAGS MAXRATE MINRATE NUMCHANS MIXER DEVICE NUMBER 
 %token <num> CDEBUG VERBOSE
-%token <num> READWRITE FORCERATE AUTOOPEN GAIN
+%token <num> READWRITE FORCERATE AUTOOPEN GAIN GAINSCALE
 %token <num> RELEASEDEVICE OUTDEVTYPE MIXERINIT
 %token <ptr> STRING 
 
@@ -141,6 +141,8 @@
 			{ ddaSetConfig(MINRATE, (void *)$2); }
 		| GAIN number
 			{ ddaSetConfig(GAIN, (void *)$2); }
+		| GAINSCALE number
+			{ ddaSetConfig(GAINSCALE, (void *)$2); }
                 ;
 
 string		: STRING		{ ptr = (char *)malloc(strlen($1)+1);

=---------------------
 paul fox, pgf at foxharp.boston.ma.us (arlington, ma, where it's 68.7 degrees)



More information about the Nas mailing list