 # Untitled

Jul 27th, 2014
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. # https://codegolf.stackexchange.com/questions/34540/print-the-lyrics-to-twinkle-twinkle-little-star
2. # https://en.wikipedia.org/wiki/File:Twinkle_Twinkle_Little_Star_plain.ogg
3.
4. import pyaudio
5. from array import array
6. import scipy.signal
7. import numpy
8. import math
9. import sys
10.
11. MIN_AMPLITUDE = -52
12. FRAMERATE = 44100
13.
14. # This function is a little
15. # Why is pred here anyways?
16. def first(list, pred):
17.     for i in range(len(list)):
18.         if(list[i] > 0):
19.             return i;
20.     return 0;
21. # You would usually want to write it like this:
22. def first(list, pred):
23.     for x in list:
24.         if x > 0:
25.             return x
26.     return 0
27. # Note that use of ; delimiter is only necessary if you
28. # have multiple statements in one line. That's never.
29. # I removed them from rest of the code.
30.
31. # Based on: https://en.wikipedia.org/wiki/Decibel#Acoustics
32. def getAmplitude(sig):
33.     total = 0
34.     elems = float(len(sig))
35.     for x in sig:
36.         total += numpy.abs(x) / elems
37.     if(total == 0):
38.         return -99
39.     else:
40.         return 20 * math.log(total / 32768., 10)
41.
42. # Based on: https://en.wikipedia.org/wiki/Piano_key_frequencies
43. def getNote(freq):
44.     return int(12 * math.log(freq / 440, 2) + 49)
45.
46. # --------------------------------------------------------------------------
47. # This is stolen straight from here w/ very slight modifications: https://gist.github.com/endolith/255291
48. def parabolic(f, x):
49.     return 1/2. * (f[x-1] - f[x+1]) / (f[x-1] - 2 * f[x] + f[x+1]) + x
50.
51. def getFrequency(sig):
52.     # Calculate autocorrelation (same thing as convolution, but with
53.     # one input reversed in time), and throw away the negative lags
54.     corr = scipy.signal.fftconvolve(sig, sig[::-1], mode='full')
55.     corr = corr[len(corr)/2:]
56.
57.     # Find the first low point
58.     diffs = numpy.diff(corr)
59.
60.      # Find the next peak after the low point (other than 0 lag). This bit is
61.     # not reliable for long signals, due to the desired peak occurring between
62.     # samples, and other peaks appearing higher.
63.     # Should use a weighting function to de-emphasize the peaks at longer lags.
64.     start = first(diffs, lambda x: x > 0)
65.     peak = numpy.argmax(corr[start:]) + start
66.     return parabolic(corr, peak) * (FRAMERATE / len(sig))
67. # --------------------------------------------------------------------------
68.
69. # These are the wrong keys (ie it is detecting middle C as an A), but I'm far too lazy to figure out why.
70. # Anyway, these are what are detected from the Wikipedia .ogg file:
71. notes = [73,          66,           64,       66,         68,       69,        71,          73,       66,     68,          69,         71,         66,        68,         69,        71      ]
72. words = ["Twinkle, ", "twinkle, ", "little ", "star,\n",  "How I ", "wonder ", "what you ", "are.\n", "Up a", "bove the ", "world so ", "high,\n", "Like a ", "diamond ", "in the ", "sky.\n"]
73. notes += notes[:8]
74. words += words[:8]
75.
76. pa = pyaudio.PyAudio()
77. stream = pa.open(format=pyaudio.paInt16, channels = 1, rate = FRAMERATE, input = True, frames_per_buffer = 4096)
78. idx = 0
79.
80. # Note how I removed braces after while and if
81. while idx < len(notes):