-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAudioSpectrumAnalysis.py
More file actions
122 lines (95 loc) · 3.91 KB
/
AudioSpectrumAnalysis.py
File metadata and controls
122 lines (95 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import matplotlib.pyplot as plt
import numpy as np
import os
import librosa
import soundfile as sf
# defines path to desktop files
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
audio_dir = os.path.join(desktop_path, 'AudioFiles')
audio_files = os.listdir(audio_dir)
for file in audio_files:
if file.endswith(".wav"):
audio_file_name = file
# audio_file_name = audio_files[2] # temp fix, find alternative
print(audio_files)
audio_file_path = os.path.join(audio_dir, audio_file_name)
out_dir = os.path.join(audio_dir, audio_file_name[0:-4] + "_segments")
file, sr = librosa.load(audio_file_path)
# mean frequency calculation
def find_average_frequency(signal, sr=sr):
ft = np.fft.fft(signal)
magnitude_spectrum = np.abs(ft)
frequency = np.linspace(0, sr, len(magnitude_spectrum))
num_frequency_bins = int(len(frequency) * 0.5)
if num_frequency_bins == 0:
num_frequency_bins = 1
temp = 0
for i in range(len(frequency[:num_frequency_bins])):
temp = temp + (i * magnitude_spectrum[i])
temp = temp / num_frequency_bins
return frequency[int(temp)]
# PLOTTING MAGNITUDE SPECTRUM (not used in current script)
def plot_magnitude_spectrum(signal, title, sr, f_ratio=1):
ft = np.fft.fft(signal)
magnitude_spectrum = np.abs(ft)
# plot magnitude spectrum
plt.figure(figsize=(18, 5))
frequency = np.linspace(0, sr, len(magnitude_spectrum))
num_frequency_bins = int(len(frequency) * f_ratio)
plt.plot(frequency[:num_frequency_bins], magnitude_spectrum[:num_frequency_bins])
plt.xlabel('Frequency (Hz)')
plt.title(title)
plt.show()
averages = []
intervalStart = 0
intervalEnd = 0.01
segment_length = 5000
print("AVERAGES BY S:")
for i in range(int(segment_length)):
currentInterval = file[int(intervalStart * sr): int(intervalEnd * sr)]
currentAverage = find_average_frequency(currentInterval, sr)
averages.append(currentAverage)
print(intervalStart, ", ", intervalEnd, ": ", int(currentAverage))
intervalStart = intervalEnd
intervalEnd = intervalEnd + 0.01
# Code for identifying golden point (start of the first glide vocal exercise, aka trial 3)
# goldenPoint = 0
# for i in range(3100, 3400):
# currentAverage = averages[i]
# if averages[i] <= 100:
# if (averages[i-1] <= 100) and (averages[i+1] <= 100) and (averages[i+2] <= 100) and (averages[i+3] <= 100):
# goldenPoint = i / 100 - 0.01
# break
goldenPoint = 32.8
approvedGolden = input(f"The start point is {goldenPoint}. Is this correct? (Y/N)")
# CODE FOR SPLITTING INTO INTERVALS; only when golden point is correct
if(approvedGolden.lower()=="y"):
# make output folder
if not os.path.exists(out_dir):
os.mkdir(out_dir)
newSegLength = 4
newSegments = []
# e=EE/high vowels, o = AH/back vowels, g = glide, r = rest
intervalOrder = "groegrgeorgoereogrgeorgoerogergeorogeregoreogroegrogeroegrogergoergeoreogr"
print(len(intervalOrder))
for i in range(148): # 148 number is number of remaining trials doubled, for two four second intervals per trial
t = file[int(sr * (goldenPoint + (i * newSegLength))): int(sr * (goldenPoint + ((i + 1) * newSegLength)))]
newSegments.append(t)
# calculates type of vocal exercise and stores in vType to be appended to the file name
vType = ""
for i in range(74):
match intervalOrder[i]:
case "e":
vType = "highv"
case "o":
vType = "backv"
case "g":
vType = "glide"
case "r":
vType = "rest"
# assembles new file name from old file name, with segment/trial number and vType
recording_name = os.path.basename(audio_file_path[:-4])
out_file = f"{recording_name}_T{str(i+3)}_{vType}.wav"
print(out_file)
if vType != "rest":
sf.write(os.path.join(out_dir, out_file), newSegments[i*2], int(sr))