j-tobias commited on
Commit
81de4d2
·
1 Parent(s): ee7c3ab

added comparison

Browse files
Files changed (1) hide show
  1. app.py +146 -14
app.py CHANGED
@@ -2,11 +2,32 @@ from plotly.subplots import make_subplots
2
  import plotly.graph_objects as go
3
  import gradio as gr
4
  import numpy as np
 
5
  import librosa
6
  import os
7
 
8
  example_dir = "Examples"
9
  example_files = [os.path.join(example_dir, f) for f in os.listdir(example_dir) if f.endswith(('.wav', '.mp3', '.ogg'))]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  # HELPER FUNCTIONS FOR SINGLE AUDIO ANALYSIS
12
  def getBeats(audiodata:np.ndarray, sr:int):
@@ -45,31 +66,51 @@ def plotCombined(audiodata, sr):
45
  row=2, col=1
46
  )
47
 
 
48
  # Update layout
49
  fig.update_layout(
50
  height=800, width=900,
51
  title_text="Audio Analysis",
52
  )
 
53
  fig.update_xaxes(title_text="Time (s)", row=2, col=1)
54
  fig.update_yaxes(title_text="Amplitude", row=1, col=1)
55
  fig.update_yaxes(title_text="Frequency (Hz)", type="log", row=2, col=1)
56
 
57
  return fig
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  def analyze_single(audio:gr.Audio):
60
  # Extract audio data and sample rate
61
- sr, audiodata = audio
62
-
63
- # Ensure audiodata is a numpy array
64
- if not isinstance(audiodata, np.ndarray):
65
- audiodata = np.array(audiodata)
66
 
67
- # Check if audio is mono or stereo
68
- if len(audiodata.shape) > 1:
69
- # If stereo, convert to mono by averaging channels
70
- audiodata = np.mean(audiodata, axis=1)
71
-
72
- audiodata = np.astype(audiodata, np.float16)
73
 
74
  # Now you have:
75
  # - audiodata: a 1D numpy array containing the audio samples
@@ -89,6 +130,7 @@ def analyze_single(audio:gr.Audio):
89
 
90
  tempo, beattimes = getBeats(audiodata, sr)
91
  spectogram_wave = plotCombined(audiodata, sr)
 
92
 
93
  # Return your analysis results
94
  results = f"""
@@ -96,14 +138,88 @@ def analyze_single(audio:gr.Audio):
96
  - Sample rate: {sr} Hz
97
  - Mean Zero Crossing Rate: {np.mean(zcr):.4f}
98
  - Mean RMS Energy: {np.mean(rms):.4f}
99
- - Tempo: {tempo}
100
  - Beats: {beattimes}
 
 
101
  """
102
- return results, spectogram_wave
103
  #-----------------------------------------------
104
  #-----------------------------------------------
105
 
106
  # HELPER FUNCTIONS FOR DUAL AUDIO ANALYSIS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
 
109
 
@@ -129,8 +245,9 @@ with gr.Blocks() as app:
129
 
130
  results = gr.Markdown()
131
  spectogram_wave = gr.Plot()
 
132
 
133
- analyzebtn.click(analyze_single, audiofile, [results, spectogram_wave])
134
 
135
  gr.Examples(
136
  examples=example_files,
@@ -140,6 +257,11 @@ with gr.Blocks() as app:
140
  cache_examples=False
141
  )
142
 
 
 
 
 
 
143
  with gr.Tab("Two Audios"):
144
 
145
  with gr.Row():
@@ -157,6 +279,16 @@ with gr.Blocks() as app:
157
  results2 = gr.Markdown()
158
  spectogram_wave2 = gr.Plot()
159
 
 
 
 
 
 
 
 
 
 
 
160
 
161
  if __name__ == "__main__":
162
  app.launch()
 
2
  import plotly.graph_objects as go
3
  import gradio as gr
4
  import numpy as np
5
+ import itertools
6
  import librosa
7
  import os
8
 
9
  example_dir = "Examples"
10
  example_files = [os.path.join(example_dir, f) for f in os.listdir(example_dir) if f.endswith(('.wav', '.mp3', '.ogg'))]
11
+ example_pairs = [list(pair) for pair in itertools.combinations(example_files, 2)][:25] # Limit to 5 pairs
12
+ print("Example Pairs: ", example_pairs)
13
+ # GENERAL HELPER FUNCTIONS
14
+ def getaudiodata(audio:gr.Audio)->tuple[int,np.ndarray]:
15
+ # Extract audio data and sample rate
16
+ sr, audiodata = audio
17
+
18
+ # Ensure audiodata is a numpy array
19
+ if not isinstance(audiodata, np.ndarray):
20
+ audiodata = np.array(audiodata)
21
+
22
+ # Check if audio is mono or stereo
23
+ if len(audiodata.shape) > 1:
24
+ # If stereo, convert to mono by averaging channels
25
+ audiodata = np.mean(audiodata, axis=1)
26
+
27
+ audiodata = np.astype(audiodata, np.float16)
28
+
29
+ return sr, audiodata
30
+
31
 
32
  # HELPER FUNCTIONS FOR SINGLE AUDIO ANALYSIS
33
  def getBeats(audiodata:np.ndarray, sr:int):
 
66
  row=2, col=1
67
  )
68
 
69
+
70
  # Update layout
71
  fig.update_layout(
72
  height=800, width=900,
73
  title_text="Audio Analysis",
74
  )
75
+
76
  fig.update_xaxes(title_text="Time (s)", row=2, col=1)
77
  fig.update_yaxes(title_text="Amplitude", row=1, col=1)
78
  fig.update_yaxes(title_text="Frequency (Hz)", type="log", row=2, col=1)
79
 
80
  return fig
81
 
82
+ def plotbeatshist(tempo, beattimes):
83
+ # Calculate beat durations
84
+ beat_durations = np.diff(beattimes)
85
+
86
+ # Create histogram
87
+ fig = go.Figure()
88
+ fig.add_trace(go.Histogram(
89
+ x=beat_durations,
90
+ nbinsx=60, # You can adjust the number of bins as needed
91
+ name='Beat Durations'
92
+ ))
93
+
94
+ # Add vertical line for average beat duration
95
+ avg_duration = 60 / tempo # Convert tempo (BPM) to seconds
96
+ fig.add_vline(x=avg_duration, line_dash="dash", line_color="red",
97
+ annotation_text=f"Average: {avg_duration:.2f}s",
98
+ annotation_position="top right")
99
+
100
+ # Update layout
101
+ fig.update_layout(
102
+ title_text='Histogram of Beat Durations',
103
+ xaxis_title_text='Beat Duration (seconds)',
104
+ yaxis_title_text='Count',
105
+ bargap=0.05, # gap between bars
106
+ )
107
+
108
+ return fig
109
+
110
  def analyze_single(audio:gr.Audio):
111
  # Extract audio data and sample rate
112
+ sr, audiodata = getaudiodata(audio)
 
 
 
 
113
 
 
 
 
 
 
 
114
 
115
  # Now you have:
116
  # - audiodata: a 1D numpy array containing the audio samples
 
130
 
131
  tempo, beattimes = getBeats(audiodata, sr)
132
  spectogram_wave = plotCombined(audiodata, sr)
133
+ beats_histogram = plotbeatshist(tempo, beattimes)
134
 
135
  # Return your analysis results
136
  results = f"""
 
138
  - Sample rate: {sr} Hz
139
  - Mean Zero Crossing Rate: {np.mean(zcr):.4f}
140
  - Mean RMS Energy: {np.mean(rms):.4f}
141
+ - Tempo: {tempo:.4f}
142
  - Beats: {beattimes}
143
+ - Beat durations: {np.diff(beattimes)}
144
+ - Mean Beat Duration: {np.mean(np.diff(beattimes)):.4f}
145
  """
146
+ return results, spectogram_wave, beats_histogram
147
  #-----------------------------------------------
148
  #-----------------------------------------------
149
 
150
  # HELPER FUNCTIONS FOR DUAL AUDIO ANALYSIS
151
+ def analyze_double(audio1:gr.Audio, audio2:gr.Audio):
152
+
153
+ sr1, audiodata1 = getaudiodata(audio1)
154
+ sr2, audiodata2 = getaudiodata(audio2)
155
+
156
+
157
+ combinedfig = plotCombineddouble(audiodata1, sr1, audiodata2, sr2)
158
+ return combinedfig
159
+
160
+ def plotCombineddouble(audiodata1, sr1, audiodata2, sr2):
161
+ # Create subplots
162
+ fig = make_subplots(rows=2, cols=2, shared_xaxes=True, vertical_spacing=0.1,
163
+ subplot_titles=('Audio Waveform', 'Spectrogram'))
164
+
165
+ # Waveform plot
166
+ time = (np.arange(0, len(audiodata1)) / sr1)*2
167
+ fig.add_trace(
168
+ go.Scatter(x=time, y=audiodata1, mode='lines', name='Waveform', line=dict(color='blue', width=1)),
169
+ row=1, col=1
170
+ )
171
+
172
+ # Spectrogram plot
173
+ D = librosa.stft(audiodata1)
174
+ S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
175
+ times = librosa.times_like(S_db)
176
+ freqs = librosa.fft_frequencies(sr=sr1)
177
+
178
+ fig.add_trace(
179
+ go.Heatmap(z=S_db, x=times, y=freqs, colorscale='Viridis',
180
+ zmin=S_db.min(), zmax=S_db.max(), colorbar=dict(title='Magnitude (dB)')),
181
+ row=2, col=1
182
+ )
183
+
184
+ # Waveform plot
185
+ time = (np.arange(0, len(audiodata2)) / sr2)*2
186
+ fig.add_trace(
187
+ go.Scatter(x=time, y=audiodata2, mode='lines', name='Waveform', line=dict(color='blue', width=1)),
188
+ row=1, col=2
189
+ )
190
+
191
+ # Spectrogram plot
192
+ D = librosa.stft(audiodata2)
193
+ S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
194
+ times = librosa.times_like(S_db)
195
+ freqs = librosa.fft_frequencies(sr=sr2)
196
+
197
+ fig.add_trace(
198
+ go.Heatmap(z=S_db, x=times, y=freqs, colorscale='Viridis',
199
+ zmin=S_db.min(), zmax=S_db.max(), colorbar=dict(title='Magnitude (dB)')),
200
+ row=2, col=2
201
+ )
202
+
203
+
204
+
205
+
206
+
207
+ # Update layout
208
+ fig.update_layout(
209
+ height=800, width=1200,
210
+ title_text="Audio Analysis",
211
+ )
212
+
213
+ fig.update_xaxes(title_text="Time (s)", row=2, col=1)
214
+ fig.update_yaxes(title_text="Amplitude", row=1, col=1)
215
+ fig.update_yaxes(title_text="Frequency (Hz)", type="log", row=2, col=1)
216
+
217
+ fig.update_xaxes(title_text="Time (s)", row=2, col=2)
218
+ fig.update_yaxes(title_text="Amplitude", row=1, col=2)
219
+ fig.update_yaxes(title_text="Frequency (Hz)", type="log", row=2, col=2)
220
+
221
+ return fig
222
+
223
 
224
 
225
 
 
245
 
246
  results = gr.Markdown()
247
  spectogram_wave = gr.Plot()
248
+ beats_histogram = gr.Plot()
249
 
250
+ analyzebtn.click(analyze_single, audiofile, [results, spectogram_wave, beats_histogram])
251
 
252
  gr.Examples(
253
  examples=example_files,
 
257
  cache_examples=False
258
  )
259
 
260
+ gr.Markdown("""### Open TODO's
261
+ - Create Histogram for Beat durations
262
+ - classify Beat's into S1 and S2
263
+ - synthesise the mean Beat S1 & S2""")
264
+
265
  with gr.Tab("Two Audios"):
266
 
267
  with gr.Row():
 
279
  results2 = gr.Markdown()
280
  spectogram_wave2 = gr.Plot()
281
 
282
+ analyzebtn2.click(analyze_double, inputs=[audioone,audiotwo], outputs=spectogram_wave2)
283
+
284
+ # Add gr.Examples for the Two Audios tab
285
+ gr.Examples(
286
+ examples=example_pairs, # Create pairs of the same file for demonstration
287
+ inputs=[audioone, audiotwo],
288
+ outputs=spectogram_wave2,
289
+ fn=analyze_double,
290
+ cache_examples=False
291
+ )
292
 
293
  if __name__ == "__main__":
294
  app.launch()