generating spectrograms in python with less noise I'm trying to do something similar to Shazam (paper here) in Python. Basically the idea is to use FFT with sliding window to transform both WAV files and recorded audio to the same spectral representations for recognition purposes. 

The only problem is the spectrograms I extract from certain songs just seem to generate lots of useless peaks that become false positives when heard in other songs. They look a lot like noise. Examples below.

Spectrogram of SONG_1 [channel 1]:



Spectrogram of SONG_2 (dominates and generates WAY more peaks) [channel 1]:



Spectrogram of SONG_3 [channel 1]:



Spectrogram of SONG_1, recorded through my laptop mic (looks like noise) [channel 1]:



Here's the code I use to generate the spectrograms:

import pylab
from scipy.io import wavfile

fs, frames = wavfile.read("song1.wav")

channels = [
    np.array(frames[:, 0]),
    np.array(frames[:, 1])
]

# generate specgram
Pxx, freqs, t, plot = pylab.specgram(
    channels[0],
    NFFT=4096, 
    Fs=44100, 
    detrend=pylab.detrend_none,
    window=pylab.window_hanning,
    noverlap=int(4096 * 0.5))


I've implemented the hashing, storage, recognition, etc as well but they are rather useless unless the extracted peaks are distinct to the song heard.

I should mention my peak extraction algorithm is not just a threshold - I find points in Pxx that are the highest value in a neighborhood of around 15-20 adjacent points.

What am I doing wrong? How can I get more distinctive spectrograms out of audio sample channels?
None of these spectrograms show music. I would validate your algorithms by substituting a known signal, e.g. a 440 Hz pure tone. That should be a single line in your spectrogram. Audacity can generate that as a .wav file, but you can also numerically generate the signal in Python. Next, mix two known tones and check if your spectrogram is lineair (i.e. showing two lines).

Audacity can also show you what the spectrogram should be for your inputs.