Last IAP, I ran into a problem. I have lots of kinds of audio signal sources: my laptop, my desktop, and mp3 players are the major ones, and each produces a separate mix of sounds. However, my preferred destination for all these sources is my pumpin’ Klipsh desktop speakers. I wanted a way to mix all these sources through software without having to acquire or build a lot of new hardware.
My solution was to use the sound card of my desktop, which has ports for line out, mic in, and line in. My speakers are connected to the line out port, and I have a 10′ trs cable running from the line in to my desk, which I generally have plugged into my laptop. I could hypothetically use the mic in to mix another device.
To control the relative mix of these signals, I programmed the mixer below in python 3. The first fader controls the master mix; the second fader controls the audio signal from only programs on my desktop computer; and the third fader controls the signal on the line in.
To make the faders, I used the tkinter module and created a Fader
class, which inherits from tkinter’s Scale widget. The constructor for this class creates a Scale with the minimalist design shown, and it also gives Fader
objects control over a Mixer
object, which is described below. The Fader
class also adds a changeVolume
method, which is called when the user moves the fader on screen. The changeVolume
method sets the volume of the Mixer
object attribute based on the height of the fader.
The Mixer
object comes from the alsaaudio module, which can be found here. From the site, “This package contains wrappers for accessing the ALSA API from Python.” A Mixer
object represents a way to manipulate controls for different ALSA lines where each line carries a different signal. The names that ALSA gives to the lines that I’m controlling are “Master” for the master mix, “PCM” for the mix coming out of software on my pc, and “Line” for the mix coming into the line in port.
The changeVolume
method also does some math before adjusting the mixer. The position of the fader on screen maps linearly to a height value read by the Fader
object. However, the perceived intensity level of sound is logarithmic with respect to its amplitude. To compensate for this, the changeVolume
method curves the input from the fader before it applies it to the mixer. As a result, moving the fader at low volumes causes the mixer volume to change slightly, and moving the fader at high volumes causes the mixer volume to change dramatically, so the intensity out of the speakers sounds linearly increasing from bottom to top of the fader.
This mixer is pretty minimalist, but in the future it would be cool to have something more like the native mixer in Windows 7, which not only shows the fader but also bars visualizing the volume of the signal for each input.
Now, I’m working with some temperature sensors to regulate things in my room and display information about temperature on my screen, too. I’ll keep you updated!