<jupyter_start><jupyter_text>Computing the pitch of a speech frame with the autocorraltion method<jupyter_code>%pylab inline
from scipy.io import wavfile
from scipy.signal import correlate
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['figure.figsize'] = (16, 6)
# Read and plot a speech file from the FDA_UE database
name = "sb034.wav"
filename="../data/fda_ue/" + name
sfreq, data = wavfile.read(filename)
plt.plot(data)
plt.xlim(0, len(data))
plt.title(name)
# Pick a short segment
windowlength = 32 # 32ms
ns_windowlength = int(round((windowlength * sfreq) / 1000))
pos = 31000
frame_length = ns_windowlength

frame = data[pos:pos+frame_length]

plt.plot(frame, linewidth=1.0)
plt.xlim(0, frame_length)
plt.title("A frame")<jupyter_output><empty_output><jupyter_text>Calculate the autocorrelation using [scipy.signal.correlate](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.correlate.html)<jupyter_code>frame = frame.astype(np.float)
frame -= frame.mean()
amax = np.abs(frame).max()
frame /= amax
plt.xlim(-(frame_length-1), frame_length-1)
bcorr = correlate(frame, frame)
plt.plot(range(-(frame_length-1), frame_length), bcorr, linewidth=1.0)
plt.title("The complete autocorrelation")
# keep the positive indexes of the autocorrelation
corr = bcorr[len(bcorr)//2:]
plt.xlim(0, frame_length-1)
plt.plot(corr)
plt.title("The autocorrelation for nonnegative indexes")<jupyter_output><empty_output><jupyter_text>Caculate the first difference using [numpy.diff](https://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.html)<jupyter_code># Find the first minimum
dcorr = np.diff(corr)
plt.xlim(0, len(dcorr))
plt.plot(dcorr)
plt.title("The first difference of the autocorrelation (corr[n+1] - corr[n])")<jupyter_output><empty_output><jupyter_text>Find the index of the first sample with positive difference using [numpy.where](https://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html)<jupyter_code># Find the first minimum
rmin = np.where(dcorr > 0)[0]
if len(rmin) > 0:
    rmin1 = rmin[0]
plt.plot(range(rmin1,len(corr)), corr[rmin1:])
plt.title("Autocorrelation without the initial values up to the first minimum")<jupyter_output><empty_output><jupyter_text>Find the index of the sample with the maximum value using [numpy.argmax](https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html)<jupyter_code># Find the next peak
peak = np.argmax(corr[rmin1:]) + rmin1
rmax = corr[peak]/corr[0]
f0 = sfreq / peak
print("corr[peak]/corr[0] = {:.1f}".format(rmax))
print("Pitch frequency = {:.1f} Hz".format(f0))
print("Pitch period {:.1f} ms ({:d} samples)".format((1/f0)*1000, peak))<jupyter_output>corr[peak]/corr[0] = 0.7
Pitch frequency = 224.7 Hz
Pitch period 4.5 ms (89 samples)<jupyter_text>Calculate the magnitude difference function<jupyter_code>plt.xlim(-(frame_length-1), frame_length-1)

n = len(frame)
mdf = []
for k in range(0, n - 1):
    mdf.append(np.sum(np.absolute(frame - np.roll(frame, k))))
    
    
plt.plot(mdf, linewidth=1.0)
plt.xlim(0, len(mdf))
plt.title("The complete mdf")

print("We extract the minimum in the correct range")
print(20000 / np.min(mdf[int(20000 / 350):int(20000 / 100)]))<jupyter_output>We extract the minimum in the correct range
139.82721237712434<jupyter_text>Calculate the cepstrum<jupyter_code>from scipy.signal import hamming

# Normalize the frame to -1 to 1
frame = frame/np.max(frame)
N = len(frame)
noise = (np.random.random_sample(N)-.5)*.05
frame = frame+noise

# Apply a window to the frame
windowed_frame = frame*hamming(N)
# Compute ceptrsum
cepstrum = np.abs(np.fft.irfft(np.log(np.abs(np.fft.rfft(windowed_frame)))))
start = int(N/12)
end = int(N/2)

plt.plot(cepstrum, linewidth=1.0)
plt.xlim(0, len(cepstrum))
plt.title("The complete cepstrum")

# Find the highest peak and interpolate to get a more accurate result
peak = np.argmax(cepstrum[start:end])

# Convert to the corresponding frequency
f0 = 20000/(start+peak)
print(f0)<jupyter_output>215.05376344086022
{'fraction_non_alphanumeric': 0.1433216608304152, 'fraction_numerical': 0.03651825912956478, 'mean_word_length': 5.966898954703833, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 28, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '444163', 'license': 'MIT', 'n_tokens_mistral': 1651, 'n_tokens_neox': 1500, 'n_words': 328, 'path': 'notebook/Algorithms for pitch detection.ipynb', 'repo_name': 'CyberPanther/Pitch-Estimation-and-Voicing-Detection', 'size': '3998'}