Audio Frequencies in Python
I'm writing a code to analyse a single audio frequency sung by a voice. I need a way to analyse the frequency of the note. Currently I am using PyAudio to record the audio file, which is stored as a .wav
, and then immediately play it back.
import numpy as np
import pyaudio
import wave
# open up a wave
wf = wave.open('file.wav', 'rb')
swidth = wf.getsampwidth()
RATE = wf.getframerate()
# use a Blackman window
window = np.blackman(chunk)
# open stream
p = pyaudio.PyAudio()
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = RATE,
output = True)
# read some data
data = wf.readframes(chunk)
print(len(data))
print(chunk*swidth)
# play stream and find the frequency of each chunk
while len(data) == chunk*swidth:
# write data out to the audio stream
stream.write(data)
# unpack the data and times by the hamming window
indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),
data))*window
# Take the fft and square each value
fftData=abs(np.fft.rfft(indata))**2
# find the maximum
which = fftData[1:].argmax() + 1
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/chunk
print("The freq is %f Hz." % (thefreq))
else:
thefreq = which*RATE/chunk
print("The freq is %f Hz." % (thefreq))
# read some more data
data = wf.readframes(chunk)
if data:
stream.write(data)
stream.close()
p.terminate()
The problem is with the while loop. The condition is never true for some reason. I printed out the two values (len(data) and (chunk*swidth)), and they were 8192 and 4096 respectively. I then tried using 2*chunk*swidth in the while loop, which threw this error:
File "C:UsersOllieDocumentsComputing A Level CApyaudio test.py", line 102, in <module>
data))*window
ValueError: operands could not be broadcast together with shapes (4096,) (2048,)
python numpy audio pyaudio wave
add a comment |
I'm writing a code to analyse a single audio frequency sung by a voice. I need a way to analyse the frequency of the note. Currently I am using PyAudio to record the audio file, which is stored as a .wav
, and then immediately play it back.
import numpy as np
import pyaudio
import wave
# open up a wave
wf = wave.open('file.wav', 'rb')
swidth = wf.getsampwidth()
RATE = wf.getframerate()
# use a Blackman window
window = np.blackman(chunk)
# open stream
p = pyaudio.PyAudio()
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = RATE,
output = True)
# read some data
data = wf.readframes(chunk)
print(len(data))
print(chunk*swidth)
# play stream and find the frequency of each chunk
while len(data) == chunk*swidth:
# write data out to the audio stream
stream.write(data)
# unpack the data and times by the hamming window
indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),
data))*window
# Take the fft and square each value
fftData=abs(np.fft.rfft(indata))**2
# find the maximum
which = fftData[1:].argmax() + 1
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/chunk
print("The freq is %f Hz." % (thefreq))
else:
thefreq = which*RATE/chunk
print("The freq is %f Hz." % (thefreq))
# read some more data
data = wf.readframes(chunk)
if data:
stream.write(data)
stream.close()
p.terminate()
The problem is with the while loop. The condition is never true for some reason. I printed out the two values (len(data) and (chunk*swidth)), and they were 8192 and 4096 respectively. I then tried using 2*chunk*swidth in the while loop, which threw this error:
File "C:UsersOllieDocumentsComputing A Level CApyaudio test.py", line 102, in <module>
data))*window
ValueError: operands could not be broadcast together with shapes (4096,) (2048,)
python numpy audio pyaudio wave
Scipy has signal processing, and this answer discusses other possibilities
– G. Anderson
Nov 14 '18 at 21:09
Binary, hex and decimal all represent the same thing.0xA
=10
=1010
. Just running your data through an FFT won't give you the fundamental frequency. The voice produces multiple frequencies and, as such, you need to do more processing and analysis to get the frequency.
– Adam Mitchell
Nov 14 '18 at 21:14
add a comment |
I'm writing a code to analyse a single audio frequency sung by a voice. I need a way to analyse the frequency of the note. Currently I am using PyAudio to record the audio file, which is stored as a .wav
, and then immediately play it back.
import numpy as np
import pyaudio
import wave
# open up a wave
wf = wave.open('file.wav', 'rb')
swidth = wf.getsampwidth()
RATE = wf.getframerate()
# use a Blackman window
window = np.blackman(chunk)
# open stream
p = pyaudio.PyAudio()
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = RATE,
output = True)
# read some data
data = wf.readframes(chunk)
print(len(data))
print(chunk*swidth)
# play stream and find the frequency of each chunk
while len(data) == chunk*swidth:
# write data out to the audio stream
stream.write(data)
# unpack the data and times by the hamming window
indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),
data))*window
# Take the fft and square each value
fftData=abs(np.fft.rfft(indata))**2
# find the maximum
which = fftData[1:].argmax() + 1
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/chunk
print("The freq is %f Hz." % (thefreq))
else:
thefreq = which*RATE/chunk
print("The freq is %f Hz." % (thefreq))
# read some more data
data = wf.readframes(chunk)
if data:
stream.write(data)
stream.close()
p.terminate()
The problem is with the while loop. The condition is never true for some reason. I printed out the two values (len(data) and (chunk*swidth)), and they were 8192 and 4096 respectively. I then tried using 2*chunk*swidth in the while loop, which threw this error:
File "C:UsersOllieDocumentsComputing A Level CApyaudio test.py", line 102, in <module>
data))*window
ValueError: operands could not be broadcast together with shapes (4096,) (2048,)
python numpy audio pyaudio wave
I'm writing a code to analyse a single audio frequency sung by a voice. I need a way to analyse the frequency of the note. Currently I am using PyAudio to record the audio file, which is stored as a .wav
, and then immediately play it back.
import numpy as np
import pyaudio
import wave
# open up a wave
wf = wave.open('file.wav', 'rb')
swidth = wf.getsampwidth()
RATE = wf.getframerate()
# use a Blackman window
window = np.blackman(chunk)
# open stream
p = pyaudio.PyAudio()
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = RATE,
output = True)
# read some data
data = wf.readframes(chunk)
print(len(data))
print(chunk*swidth)
# play stream and find the frequency of each chunk
while len(data) == chunk*swidth:
# write data out to the audio stream
stream.write(data)
# unpack the data and times by the hamming window
indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),
data))*window
# Take the fft and square each value
fftData=abs(np.fft.rfft(indata))**2
# find the maximum
which = fftData[1:].argmax() + 1
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/chunk
print("The freq is %f Hz." % (thefreq))
else:
thefreq = which*RATE/chunk
print("The freq is %f Hz." % (thefreq))
# read some more data
data = wf.readframes(chunk)
if data:
stream.write(data)
stream.close()
p.terminate()
The problem is with the while loop. The condition is never true for some reason. I printed out the two values (len(data) and (chunk*swidth)), and they were 8192 and 4096 respectively. I then tried using 2*chunk*swidth in the while loop, which threw this error:
File "C:UsersOllieDocumentsComputing A Level CApyaudio test.py", line 102, in <module>
data))*window
ValueError: operands could not be broadcast together with shapes (4096,) (2048,)
python numpy audio pyaudio wave
python numpy audio pyaudio wave
edited Nov 14 '18 at 21:29
Ollie
asked Nov 14 '18 at 21:03
OllieOllie
186
186
Scipy has signal processing, and this answer discusses other possibilities
– G. Anderson
Nov 14 '18 at 21:09
Binary, hex and decimal all represent the same thing.0xA
=10
=1010
. Just running your data through an FFT won't give you the fundamental frequency. The voice produces multiple frequencies and, as such, you need to do more processing and analysis to get the frequency.
– Adam Mitchell
Nov 14 '18 at 21:14
add a comment |
Scipy has signal processing, and this answer discusses other possibilities
– G. Anderson
Nov 14 '18 at 21:09
Binary, hex and decimal all represent the same thing.0xA
=10
=1010
. Just running your data through an FFT won't give you the fundamental frequency. The voice produces multiple frequencies and, as such, you need to do more processing and analysis to get the frequency.
– Adam Mitchell
Nov 14 '18 at 21:14
Scipy has signal processing, and this answer discusses other possibilities
– G. Anderson
Nov 14 '18 at 21:09
Scipy has signal processing, and this answer discusses other possibilities
– G. Anderson
Nov 14 '18 at 21:09
Binary, hex and decimal all represent the same thing.
0xA
=10
=1010
. Just running your data through an FFT won't give you the fundamental frequency. The voice produces multiple frequencies and, as such, you need to do more processing and analysis to get the frequency.– Adam Mitchell
Nov 14 '18 at 21:14
Binary, hex and decimal all represent the same thing.
0xA
=10
=1010
. Just running your data through an FFT won't give you the fundamental frequency. The voice produces multiple frequencies and, as such, you need to do more processing and analysis to get the frequency.– Adam Mitchell
Nov 14 '18 at 21:14
add a comment |
1 Answer
1
active
oldest
votes
This function finds the frequency spectrum. I have also included a sine signal and a WAV file sample application:
from scipy import fft, arange
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
import os
def frequency_sepectrum(x, sf):
"""
Derive frequency spectrum of a signal from time domain
:param x: signal in the time domain
:param sf: sampling frequency
:returns frequencies and their content distribution
"""
x = x - np.average(x) # zero-centering
n = len(x)
print(n)
k = arange(n)
tarr = n / float(sf)
frqarr = k / float(tarr) # two sides frequency range
frqarr = frqarr[range(n // 2)] # one side frequency range
x = fft(x) / n # fft computing and normalization
x = x[range(n // 2)]
return frqarr, abs(x)
# Sine sample with a frequency of 1hz and add some noise
sr = 32 # sampling rate
y = np.linspace(0, 2*np.pi, sr)
y = np.tile(np.sin(y), 5)
y += np.random.normal(0, 1, y.shape)
t = np.arange(len(y)) / float(sr)
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
# wav sample from https://freewavesamples.com/files/Alesis-Sanctuary-QCard-Crickets.wav
here_path = os.path.dirname(os.path.realpath(__file__))
wav_file_name = 'Alesis-Sanctuary-QCard-Crickets.wav'
wave_file_path = os.path.join(here_path, wav_file_name)
sr, signal = wavfile.read(wave_file_path)
y = signal[:, 0] # use the first channel (or take their average, alternatively)
t = np.arange(len(y)) / float(sr)
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
plt.show()
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
1
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308674%2faudio-frequencies-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This function finds the frequency spectrum. I have also included a sine signal and a WAV file sample application:
from scipy import fft, arange
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
import os
def frequency_sepectrum(x, sf):
"""
Derive frequency spectrum of a signal from time domain
:param x: signal in the time domain
:param sf: sampling frequency
:returns frequencies and their content distribution
"""
x = x - np.average(x) # zero-centering
n = len(x)
print(n)
k = arange(n)
tarr = n / float(sf)
frqarr = k / float(tarr) # two sides frequency range
frqarr = frqarr[range(n // 2)] # one side frequency range
x = fft(x) / n # fft computing and normalization
x = x[range(n // 2)]
return frqarr, abs(x)
# Sine sample with a frequency of 1hz and add some noise
sr = 32 # sampling rate
y = np.linspace(0, 2*np.pi, sr)
y = np.tile(np.sin(y), 5)
y += np.random.normal(0, 1, y.shape)
t = np.arange(len(y)) / float(sr)
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
# wav sample from https://freewavesamples.com/files/Alesis-Sanctuary-QCard-Crickets.wav
here_path = os.path.dirname(os.path.realpath(__file__))
wav_file_name = 'Alesis-Sanctuary-QCard-Crickets.wav'
wave_file_path = os.path.join(here_path, wav_file_name)
sr, signal = wavfile.read(wave_file_path)
y = signal[:, 0] # use the first channel (or take their average, alternatively)
t = np.arange(len(y)) / float(sr)
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
plt.show()
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
1
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
add a comment |
This function finds the frequency spectrum. I have also included a sine signal and a WAV file sample application:
from scipy import fft, arange
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
import os
def frequency_sepectrum(x, sf):
"""
Derive frequency spectrum of a signal from time domain
:param x: signal in the time domain
:param sf: sampling frequency
:returns frequencies and their content distribution
"""
x = x - np.average(x) # zero-centering
n = len(x)
print(n)
k = arange(n)
tarr = n / float(sf)
frqarr = k / float(tarr) # two sides frequency range
frqarr = frqarr[range(n // 2)] # one side frequency range
x = fft(x) / n # fft computing and normalization
x = x[range(n // 2)]
return frqarr, abs(x)
# Sine sample with a frequency of 1hz and add some noise
sr = 32 # sampling rate
y = np.linspace(0, 2*np.pi, sr)
y = np.tile(np.sin(y), 5)
y += np.random.normal(0, 1, y.shape)
t = np.arange(len(y)) / float(sr)
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
# wav sample from https://freewavesamples.com/files/Alesis-Sanctuary-QCard-Crickets.wav
here_path = os.path.dirname(os.path.realpath(__file__))
wav_file_name = 'Alesis-Sanctuary-QCard-Crickets.wav'
wave_file_path = os.path.join(here_path, wav_file_name)
sr, signal = wavfile.read(wave_file_path)
y = signal[:, 0] # use the first channel (or take their average, alternatively)
t = np.arange(len(y)) / float(sr)
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
plt.show()
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
1
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
add a comment |
This function finds the frequency spectrum. I have also included a sine signal and a WAV file sample application:
from scipy import fft, arange
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
import os
def frequency_sepectrum(x, sf):
"""
Derive frequency spectrum of a signal from time domain
:param x: signal in the time domain
:param sf: sampling frequency
:returns frequencies and their content distribution
"""
x = x - np.average(x) # zero-centering
n = len(x)
print(n)
k = arange(n)
tarr = n / float(sf)
frqarr = k / float(tarr) # two sides frequency range
frqarr = frqarr[range(n // 2)] # one side frequency range
x = fft(x) / n # fft computing and normalization
x = x[range(n // 2)]
return frqarr, abs(x)
# Sine sample with a frequency of 1hz and add some noise
sr = 32 # sampling rate
y = np.linspace(0, 2*np.pi, sr)
y = np.tile(np.sin(y), 5)
y += np.random.normal(0, 1, y.shape)
t = np.arange(len(y)) / float(sr)
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
# wav sample from https://freewavesamples.com/files/Alesis-Sanctuary-QCard-Crickets.wav
here_path = os.path.dirname(os.path.realpath(__file__))
wav_file_name = 'Alesis-Sanctuary-QCard-Crickets.wav'
wave_file_path = os.path.join(here_path, wav_file_name)
sr, signal = wavfile.read(wave_file_path)
y = signal[:, 0] # use the first channel (or take their average, alternatively)
t = np.arange(len(y)) / float(sr)
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
plt.show()
This function finds the frequency spectrum. I have also included a sine signal and a WAV file sample application:
from scipy import fft, arange
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
import os
def frequency_sepectrum(x, sf):
"""
Derive frequency spectrum of a signal from time domain
:param x: signal in the time domain
:param sf: sampling frequency
:returns frequencies and their content distribution
"""
x = x - np.average(x) # zero-centering
n = len(x)
print(n)
k = arange(n)
tarr = n / float(sf)
frqarr = k / float(tarr) # two sides frequency range
frqarr = frqarr[range(n // 2)] # one side frequency range
x = fft(x) / n # fft computing and normalization
x = x[range(n // 2)]
return frqarr, abs(x)
# Sine sample with a frequency of 1hz and add some noise
sr = 32 # sampling rate
y = np.linspace(0, 2*np.pi, sr)
y = np.tile(np.sin(y), 5)
y += np.random.normal(0, 1, y.shape)
t = np.arange(len(y)) / float(sr)
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
# wav sample from https://freewavesamples.com/files/Alesis-Sanctuary-QCard-Crickets.wav
here_path = os.path.dirname(os.path.realpath(__file__))
wav_file_name = 'Alesis-Sanctuary-QCard-Crickets.wav'
wave_file_path = os.path.join(here_path, wav_file_name)
sr, signal = wavfile.read(wave_file_path)
y = signal[:, 0] # use the first channel (or take their average, alternatively)
t = np.arange(len(y)) / float(sr)
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(t, y)
plt.xlabel('t')
plt.ylabel('y')
frq, X = frequency_sepectrum(y, sr)
plt.subplot(2, 1, 2)
plt.plot(frq, X, 'b')
plt.xlabel('Freq (Hz)')
plt.ylabel('|X(freq)|')
plt.tight_layout()
plt.show()
edited Nov 17 '18 at 20:15
answered Nov 14 '18 at 21:45
HapalopHapalop
437614
437614
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
1
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
add a comment |
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
1
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
Hi, this works really well for the sine waves, but what do I need to change to change the input to be a wav file? I've tried just replacing y with the array of data, but it doesn't seem to work.
– Ollie
Nov 15 '18 at 10:27
1
1
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
Did you set your array's mean to 0 first? I went ahead and moved this step to the function itself. I have the wav to array converter code somewhere too; will add here soon.
– Hapalop
Nov 16 '18 at 12:37
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
added a wav example.
– Hapalop
Nov 19 '18 at 12:20
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
Thank you, it works really well. If you want to print out the frequency, you need to find the maximum value in X, then use the same index from the frq array.
– Ollie
Nov 21 '18 at 10:15
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308674%2faudio-frequencies-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Scipy has signal processing, and this answer discusses other possibilities
– G. Anderson
Nov 14 '18 at 21:09
Binary, hex and decimal all represent the same thing.
0xA
=10
=1010
. Just running your data through an FFT won't give you the fundamental frequency. The voice produces multiple frequencies and, as such, you need to do more processing and analysis to get the frequency.– Adam Mitchell
Nov 14 '18 at 21:14