Skip to content

Instantly share code, notes, and snippets.

@jul
Created June 24, 2012 14:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jul/2983547 to your computer and use it in GitHub Desktop.
Save jul/2983547 to your computer and use it in GitHub Desktop.
dumb spectogram
from scikits.audiolab import Sndfile
import numpy as np
import pylab as plt
import csv
import matplotlib.mlab as mlab
from math import floor, log
#NFFT windows make calculus faster if a power of 2
closest_2_power=lambda x : 1<<int(floor(log(x,2)))
def load_freq(fn="freq.csv"):
_csv=csv.reader(open(fn), delimiter='\t')
note={}
for i,row in enumerate(_csv):
if i:
note[row[0]]=float(row[1])
return note
koln=Sndfile("test.wav")
note=load_freq()
tempo= 120#tempo in beat per minutes
def ticks_in_range(_min=0,_max=16000,note=note):
note_name=[]
note_freq=[]
for k,v in sorted(note.iteritems()):
if _max >= v >= _min:
note_name+=[k]
note_freq+=[v]
return note_name, note_freq
_min_sec=5
_max_sec=10
_begin_at=_min_sec * koln.samplerate
_stop_at=_max_sec * koln.samplerate
#skipping n seconds
koln.read_frames(_begin_at)
sample=koln.read_frames(_stop_at-_begin_at)
#plt.interactive(True)
## something like the time window used to higher the resolution
## we take 1 measure 4 beats + shannon => * 2
NFFT=int(8.0* koln.samplerate/float(tempo)) #we want to see the round
## well I let 1 black note overlap
noverlap=NFFT>>2
## A4 flat frequency but I am french we say la not A
la=442.0
## freq lowest limit
lower=13
## A4/2 => A3
higher=la/2
plt.interactive(False)
## testing all colormap because ... it is hard to find the good one
maps=[m for m in plt.cm.datad if not m.endswith("_r")]
for _map in maps:
print _map
plt.clf()
fig=plt.figure( figsize=(30.0,14.0))
ax=fig.add_subplot(111)
pxx, freq, t,cax=ax.specgram(
## right chan
sample[:,0],
## for getting the time scale
Fs=koln.samplerate,
### Window size
NFFT=NFFT,
## overlap size
noverlap=noverlap,
### colormap
cmap=plt.get_cmap(_map))
ax.set_title(str(_map))
note_name,note_freq=ticks_in_range(lower,higher)
ax.set_ylim(lower,higher)
ax.set_yticks(np.array(note_freq))
ax.set_yticklabels(note_name)
step= 1.0 * ( _max_sec - _min_sec ) * tempo / 60
step=1/step
### trying to graph the ticks according to the guessed tempo
ax.set_xticks(np.arange(0 ,1.0*( _max_sec - _min_sec), step, float))
## colorbar is nice
fig.colorbar(cax)
##saving result
plt.savefig("sono.%s.png" % _map)
@mouuff
Copy link

mouuff commented Jun 25, 2012

Ça gère ;)

@bpgergo
Copy link

bpgergo commented Jun 25, 2012

You have left one line from your code listing:
maps=[m for m in plt.cm.datad if not m.endswith("_r")]

Nice post though, thank you. (I mean this one http://beauty-of-imagination.blogspot.fr/2012/06/color-of-music-why-not-discover-pythons.html)

@jul
Copy link
Author

jul commented Jun 25, 2012

corrected thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment