Android audio applications

Filed under: Uncategorized
Created 11/24/2009 (1:02 am) | Updated 05/13/2010 (5:48 pm)

Signal generator 1.0.2

  • Outputs sine, pink noise, and white noise
  • Volume and frequency sliders
    • Controls are hard to grab at the edges
    • Volume control is independent from the phone’s volume control
    • Doesn’t go below 100 Hz
  • Sine waves are distorted and badly aliased at high frequencies.  THD+N measurements:
    • 100 Hz 0.149%
    • 1 kHz: 0.08%
    • 10 kHz: 7.1%
    • 20 kHz: 20.15%
    • Spectrum for 997 Hz:
    • signal generator 997 Hz
  • Although the control says “1.00 kHz” at startup, it’s actually playing 765 Hz.  Frequencies are correct after you start moving it around, though.
  • White noise level is higher than sine wave — sine wave never reaches the peak output of the phone, even at “0 dB”
  • There doesn’t seem to be any way to enter levels other than 0 dB manually, since it doesn’t let you type a minus sign.
  • White noise sounds like it’s repeating every 1.4 seconds
  • Noise is the same in both channels

Frequency generator 200909150

  • Outputs sine, square, triangle, sawtooth
  • Playing more than one sine wave causes clipping, but you can decrease the phone’s volume control
  • Default setting is 440, 444, and 448 Hz, but when played together, the waveform changes abruptly once per second
  • Sine wave THD+N:
    • 40 Hz: 1.00%
    • 440 Hz: 0.056%
    • 10 kHz: 0.051%
    • 20 kHz: 0.222%
  • I don’t know how the square, triangle and sawtooth are generated, but it ain’t right.
    • This is what the “square wave” looks like at 10 kHz:
    • freq gen square 10 kHz
    • And this is the spectrum:
    • frequency generator 10 kHz square
    • Nooot even close

(Using ExtUSB headphone cable, Adobe Audition, Audio Precision.)

A simple FastICA example

Filed under: Uncategorized
Created 11/22/2009 (12:55 am) | Updated 05/13/2010 (5:46 pm)

Wikipedia describes independent component analysis as “a computational method for separating a multivariate signal into additive subcomponents supposing the mutual statistical independence of the non-Gaussian source signals”. (Clearly, this was written as part of their campaign to make technical articles accessible.)

In normal people words, ICA is a form of blind source separation — a method of unmixing signals after they have been mixed together, without knowing exactly how they were mixed. It’s not as bad as Wikipedia makes it sound. It’s just the signal processing equivalent of this:

One of the problems I always have with learning stuff like this is the lack of clear examples. They exist, but they’re not generally very good. (And why do researchers always work with awful noisy 3-second 8 kHz recordings?) So, upon getting working results, I wrote up this little example.  This is in Python and requires the MDP (python-mdp in Ubuntu) and Audiolab packages (sudo easy_install scikits.audiolab).

In order for ICA to work, it requires at least one different recording for each signal you want to unmix. So if you have two musical instruments playing together in a room, and want to unmix them to get separate recordings of each individual instrument, you’ll need two different recordings of the mixture to work with (like a stereo microphone). If you have three instruments playing together, you’ll need three microphones to separate out all three original signals, etc. So, first, create the mix:

  1. Find or make two mono sound files. I just used clips of music.
  2. Mix them together to a stereo track, with both sounds mixed into both channels, but with each panned a little differently, so the two channels are not identical. They should sound all jumbled together, but the left channel should sound slightly different from the right.
  3. Save in a format that libsndfile can read, like FLAC or WAV (not mp3):
    • Mixed music
    • Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

So now you have the mixed signals, and you can pretend you don’t know how they were mixed. To unmix them automatically, run something like this in Python:

from mdp import fastica
from scikits.audiolab import flacread, flacwrite
from numpy import abs, max

# Load in the stereo file
recording, fs, enc = flacread('mix.flac')

# Perform FastICA algorithm on the two channels
sources = fastica(recording)

# The output levels of this algorithm are arbitrary, so normalize them to 1.0.
sources /= max(abs(sources), axis = 0)

# Write back to a file
flacwrite(sources, 'sources.flac', fs, enc)

The output has each signal in its own channel:

You can hear some crosstalk, but it’s pretty good:

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

For more than two sources, I just read them in separately and combined them in Python:

rec1, fs, enc = flacread('Mixdown (1).flac') # Mono file
rec2, fs, enc = flacread('Mixdown (2).flac')
rec3, fs, enc = flacread('Mixdown (3).flac')

sources = fastica(array([rec1,rec2,rec3]).transpose())

flacwrite() has no problem writing multi-channel files.

Mixed speech:

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

After demixing, there’s very little crosstalk, though the noise floor increases considerably.  This seems to be the case when the mixes are very similar:

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Although this method was recommended to me for real-life audio signals and microphones, as I’ve described above, it turns out that ICA doesn’t actually work well when the signals occur at different delays in the different sensor channels; it assumes instantaneous mixing (that the signals are in perfect sync with each other in all the different recordings).  Delay would happen in a real-life situation with performers and microphones, since each source is a different distance from each microphone. This is exactly the application I had in mind, though, so I don’t really have any further interest in ICA…

Errors in “Op Amps for Everyone”

Filed under: Electronics
Created 11/04/2009 (4:14 pm) | Updated 05/13/2010 (5:38 pm)

I’ve been trying to learn op-amp noise calculations, and was trying to use the book Op Amps for Everyone as one of my sources.  I found a few obvious errors in Section 10.6 – Putting It All Together, and also, now that I’ve learned more about the topic, it seems that the analysis in this section is quite flawed.

I’m not sure I understand it perfectly, though, so I hope others can check my work and see if you agree:

  1. Section 10.6: “The output noise equals the input noise multiplied by the gain, which is 100 (40 dB).”  Is it the inverting gain of 100, or the non-inverting gain (“noise gain”) of 101?  Obviously, these are very close for this particular circuit, but for circuits with lower gain they are not the same.  This source says to multiply by the non-inverting gain: Part III: Resistor Noise And Sample Calculations
  2. The IC in Fig 10-15 and 10-16 should be a TLC2201, not TLE2201.
  3. The capacitor in Fig 10-15 and 10-16 should probably be 0.1 µF, not 0.1 F.
  4. Equation 10-23 is supposed to be the total output noise of the amplifier and the resistor divider, but I don’t think it’s correct.
    • The noise of the two resistors is summed (5.73 µV²‎ + 5.73 µV²‎), which would produce a total noise of 8.1 µV.  But don’t the resistors load down each other’s noise sources, so the total contribution is equivalent to the resistors in parallel?  It would be equal to a single 50 kΩ resistor producing 4.0 µV.  A 1 MΩ resistor in parallel with a 1 Ω resistor produces the same noise as a lone 1 Ω resistor, not the noise of a lone 1 MΩ.
    • The noise of the resistors (5.7 µV) that appears at the input of the op-amp is being summed with the output noise of the op-amp (1.13 µV x 100 = 113.1 µV).  Shouldn’t the resistor noise be multiplied by the gain, too?
    • It says “The amplifier noise is swamping the resistor noise”, but this isn’t true if you multiply the resistor noise by the gain, too.
  5. Equation 10-25 is obviously wrong.
    • The left side of the equation is equal to 113.24, not 126.8.  It was probably meant to include 57.3, not 5.73.
    • The text says “Adding this [the 57.3 µV noise from the 10M] and the 100-kΩ resistor noise to the amplifier noise”.  This is three terms (10 MΩ, 100 kΩ, op-amp), but there are only two in the equation.
    • But again, these two resistors should be paralleled before the noise is calculated.  The noise is actually that of a single 99 kΩ resistor, (5.707 µV).  So the left side of the equation is actually close to correct, but possibly by accident, and doesn’t match the result on the right side anyway.
    • Again, the resistor noise is not multiplied by the gain, even though the text says it should be:  “The noise associated with it appears as a voltage source at the inverting input of the op amp, and, therefore, is multiplied by a factor of 100 through the circuit.”
    • If I understand correctly, I think the correct equation would be the noise of a 50 kΩ resistor (100k||100k) summed with a 99 kΩ resistor (10M||100k) and the op-amp’s input noise, which is then multiplied by the non-inverting noise gain:
      • √(4.06 µV²‎ + 5.707 µV²‎ + 1.131 µV²‎) × 101 = 716.3 µV
      • A TINA-TI simulation of this circuit produces 633.44 µV, which is similar, while the text gives only 126.8 µV
  6. Equation 10-27 has similar problems to the others.
    • Because of the addition of the 0.1 µF cap, the resistor divider is being ignored.  The equation then seems to be summing the 100 kΩ and 1 kΩ of the inverting side, but they should be in parallel (100 kΩ || 1 kΩ = 990.1 Ω → 0.5707 µV).
    • If the 50 kΩ resistor is ignored, it becomes:
      • √(0.5707 µV²‎ + 1.131 µV²‎) × 101 = 127.9 µV
      • A TINA simulation with the cap in place gives 112.3 µV
    • So in this case the book’s answer of 113.2 µV is close to correct, but I think the derivation is not.