Sunday, January 13, 2013

Raspberry Pi - Adjusting the audio output volume

Ok, I have to admit that Linux can be quite obtuse and difficult to use for the non-technical user. Luckily I've had over 30 years of working with computer software to help me wade through the geek world that Linux basically is. One of the geek barriers to break through on the Raspberry Pi was figuring out how to change the audio output volume. This is done using the amixer command which has a really bizarre syntax and interface which I guess is complicated by the need to support a variety of output devices. Anyway, I won't claim to know all the details of using this command but I did figure out how to get it to change the volume on the Raspberry Pi. So I put together a script to make this a bit easier

Without arguments it tries to report the current volume settings. I'm just assuming that the two numbers are left and right volume. Can anyone confirm that? If you give it a number between 0 and 100 it will try to set the volume. Let me know if you have problems or suggestions. I'm only using the audio jack so I don't know if this works for hdmi audio.
#!/usr/bin/python
import os, sys

def setVolume(id, percent):
   p = os.popen("amixer cset %s -- %d%%" % (id, percent))
   if p:
      gobble = p.read()
      p.close()


def getVolume(id):
   p = os.popen("amixer cget %s" % id)
   c = p.readlines()
   p.close()
   if len(c) > 2:
      range = c[1]
      value = c[2]

      # STUPID OUTPUT FORMAT:
      r = range.split(',')
      min = int(r[3].split('=')[1])
      max = int(r[4].split('=')[1])

      v = value.split(',')
      left  = float(v[0].split('=')[1])
      right = float(v[1].strip())

      range = max - min
      volume = [left, right, range]
   else:
      print
      volume = [-1, -1, 0]   # ??

   return volume


def showVolume(id):
   [left, right, range] = getVolume(id)
   print "Left: %d%% Right %d%%" % (int(left / range * 100.0 + 0.5), int(right / range * 100.0 + 0.5))


id = "numid=3"
p = os.popen("amixer controls | grep \"Master Playback Volume\"")
if p:
   c = p.readlines()
   p.close()
   if len(c) == 1:
      parms = c[0].split(',')
      id = parms[0]

argc = len( sys.argv )

if argc == 2:
   arg = int(sys.argv[1])
   percent = 0 if arg < 0 else 100 if arg > 100 else arg
   setVolume(id, arg)

showVolume(id)

No comments: