-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwaveformEditor.py
More file actions
102 lines (77 loc) · 3.25 KB
/
waveformEditor.py
File metadata and controls
102 lines (77 loc) · 3.25 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
import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
from mpl_draggable_line import DraggableVLine
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import os
class waveformEditor(tk.Frame):
def __init__(self, master, audio_path, audio_data, sample_rate, **kw):
super().__init__(master, **kw)
self.audio_path = audio_path
self.sample_rate = sample_rate
self.audio_data = audio_data
self.playback_start = 0 #define default behavior
self.playback_end = None
self.create_graph()
#function to callback x value from draggable line.
def start_callback(self, x: float):
frame_index = int(x * self.sample_rate) #convert time back into frame index
plt.suptitle(f"start pos: {x:0.2f}", x=-.01, y=-0.5, ha='center', va='bottom') #this is not showing up idk why
self.playback_start = frame_index #set index
def end_callback(self, x: float):
frame_index = int(x * self.sample_rate)
plt.suptitle(f"end pos: {x:0.2f}", x=0.01, y=-0.5, ha='center', va='bottom')
self.playback_end = frame_index
#updates the waveform editor when new file is dropped on the button
def update_waveform(self, new_file_path, audio_data, sample_rate,):
self.audio_path = new_file_path
self.sample_rate = sample_rate
self.audio_data = audio_data
self.playback_start = 0
self.playback_end = None
#delete previous widget and create new graph
for widget in self.winfo_children():
widget.destroy()
self.create_graph()
#graphs the associated waveform
def create_graph(self):
signal = self.audio_data
# gets the frame rate
self.playback_end = len(signal)
# to Plot the x-axis in seconds
# you need get the frame rate
# and divide by size of your signal
# to create a Time Vector
# spaced linearly with the size
# of the audio file
time = np.linspace(
0, # start
len(signal) / self.sample_rate,
num = len(signal)
)
fig, ax = plt.subplots()
ax.clear()
# title of the plot
file_name = os.path.basename(self.audio_path)
ax.set_title(f"{file_name}")
# label of x-axis
ax.set_xlabel("Time")
# actual plotting
ax.plot(time, signal)
#initialize starting draggable line
d_start = DraggableVLine(ax,0) #initialize draggable line
d_start.on_line_changed(self.start_callback)
#initalize ending draggable line
d_end = DraggableVLine(ax,time[-1])
d_end.on_line_changed(self.end_callback)
#embed into tkinter
canvas = FigureCanvasTkAgg(fig, self)
canvas.draw()
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
#ensure matplotlib receives events
canvas.mpl_connect("motion_notify_event", d_start._on_move)
canvas.mpl_connect("button_press_event", d_start._on_press)
canvas.mpl_connect("button_release_event", d_start._on_release)
self.canvas = canvas
self.d_start = d_start
self.d_end = d_end