You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
691 lines
18 KiB
691 lines
18 KiB
#!/usr/bin/env python3
|
|
|
|
# Copyright (C) 2020 Harry Sentonbury
|
|
# GNU General Public License v3.0
|
|
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
import os
|
|
import scipy.io.wavfile as wf
|
|
import sys
|
|
import threading
|
|
import time
|
|
|
|
import mido
|
|
import numpy as np
|
|
import simpleaudio as sa
|
|
from PyQt5 import QtGui
|
|
from PyQt5.QtWidgets import (QApplication, QWidget, QSlider, QPushButton,
|
|
QListWidget, QLabel, QVBoxLayout, QShortcut)
|
|
from PyQt5.Qt import Qt
|
|
from PyQt5.QtGui import QIcon, QPixmap, QKeySequence
|
|
|
|
|
|
class ChoosePort(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
midi_input_names = mido.get_input_names()
|
|
self.setGeometry(100, 520, 600, 200)
|
|
self.setWindowTitle('Choose Midi Input')
|
|
self.setWindowIcon(QIcon('images/knotperfect-icon.png'))
|
|
self.setObjectName("midi_win")
|
|
|
|
layout = QVBoxLayout()
|
|
self.setLayout(layout)
|
|
self.listwidget = QListWidget()
|
|
for i, s in enumerate(midi_input_names):
|
|
self.listwidget.insertItem(i, s)
|
|
self.listwidget.clicked.connect(self.clicked)
|
|
layout.addWidget(self.listwidget)
|
|
|
|
self.info_label = QLabel(self)
|
|
self.info_label.setText("""Select port and wait a few seconds.
|
|
port will be open until program is closed""")
|
|
layout.addWidget(self.info_label)
|
|
|
|
self.close_kp_button = QPushButton("Close", self)
|
|
self.close_kp_button.move(400, 140)
|
|
self.close_kp_button.clicked.connect(lambda: self.close())
|
|
layout.addWidget(self.close_kp_button)
|
|
|
|
def clicked(self, qmodelindex):
|
|
midi_on_flag[0] = True
|
|
item = self.listwidget.currentItem().text()
|
|
do_it_int16()
|
|
activate_midi(item)
|
|
self.close()
|
|
|
|
|
|
class CustomKeybinder(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def change_key_list():
|
|
self.is_e_list = not self.is_e_list
|
|
if self.is_e_list:
|
|
self.selection_label.setText("key of E")
|
|
else:
|
|
self.selection_label.setText("key of C")
|
|
|
|
|
|
self.custom_e_list = []
|
|
self.is_e_list = True
|
|
self.setGeometry(400, 450, 600, 200)
|
|
self.setWindowTitle('Set Custom Keybindings')
|
|
self.setWindowIcon(QtGui.QIcon('images/knotperfect-icon.png'))
|
|
self.setObjectName("ck_win")
|
|
|
|
self.blah_label = QLabel(self)
|
|
self.blah_label.setText("Type the keys in the order you want, to whatever scale\n"
|
|
"then go back and click the Change Key button")
|
|
self.blah_label.move(10, 10)
|
|
|
|
self.list_label = QLabel(self)
|
|
self.list_label.setText("")
|
|
self.list_label.resize(550, 25)
|
|
self.list_label.move(10, 50)
|
|
self.list_label.setObjectName("l_label")
|
|
|
|
|
|
self.key_button = QPushButton("Select Key", self)
|
|
self.key_button.move(11, 100)
|
|
self.key_button.clicked.connect(change_key_list)
|
|
|
|
self.selection_label = QLabel(self)
|
|
self.selection_label.setText("key of E")
|
|
self.selection_label.move(130, 105)
|
|
|
|
self.close_ckb_button = QPushButton("Close", self)
|
|
self.close_ckb_button.move(420, 150)
|
|
self.close_ckb_button.clicked.connect(lambda: self.close())
|
|
|
|
|
|
def keyPressEvent(self, event):
|
|
if midi_on_flag[0] is True:
|
|
return
|
|
else:
|
|
if len(self.custom_e_list) >= 18:
|
|
if self.is_e_list:
|
|
e_keys[:] = self.custom_e_list[:]
|
|
else:
|
|
c_keys[:] = self.custom_e_list[:]
|
|
self.close()
|
|
|
|
self.custom_e_list.append(event.text())
|
|
self.list_label.setText(str(self.custom_e_list))
|
|
|
|
|
|
class MainWindow(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def keyPressEvent(self, event):
|
|
if midi_on_flag[0] is True:
|
|
return
|
|
else:
|
|
if mono_flag is True:
|
|
sa.stop_all()
|
|
try:
|
|
sound = key_notes.get(event.text())
|
|
play_obj = sa.play_buffer(sound, 2, 2, sample_rate)
|
|
except TypeError:
|
|
return
|
|
|
|
|
|
def do_it_int16():
|
|
def wave_maker(a):
|
|
factor = 2**(a / 12.0)
|
|
waveform_mod = (sine_wave(octave_freq * (
|
|
factor)) * sm) + (triangle(freq3 * factor, detune_freq) * tm)
|
|
waveform = (sine_wave(
|
|
octave_freq * factor) * sm) + (triangle(freq3 * factor) * tm)
|
|
waveform_detune = (sine_wave(
|
|
octave_freq * factor, detune_freq) * sm) + (
|
|
triangle(freq3 * factor, detune_freq) * tm)
|
|
|
|
waveform = ((waveform + waveform_detune) *
|
|
(waveform_mod / 2 + 0.5)) * 0.12 * volume
|
|
|
|
waveform[:np.size(attak)] *= attak
|
|
waveform[-np.size(fade):] *= fade
|
|
waveform = np.int16(waveform * 32767)
|
|
waveform2 = np.roll(waveform, roll_amount, axis=None)
|
|
waveform3 = np.vstack((waveform2, waveform)).T
|
|
waveform3 = waveform3.copy(order='C')
|
|
return waveform3
|
|
|
|
def sine_wave(f, detune=0.0):
|
|
y = np.sin((f + detune) * x + ramp_0 *
|
|
np.sin(((f + detune) * 0.5) * x + (np.sin(((f + detune) * fm) * x) * 0.5)))
|
|
return y
|
|
|
|
def triangle(f, detune=0.0):
|
|
y = 2 / np.pi * np.arcsin(np.sin((f + detune) * x + ramp_0 *
|
|
np.sin(((f + detune) * 0.5) * x + (np.sin(((f + detune) * fm) * x) * 0.5))))
|
|
return y * 0.8
|
|
|
|
global notes
|
|
applying_sliders_flag[0] = True
|
|
label_apply.hide()
|
|
fm = 0.25
|
|
freq3 = 440.0
|
|
detune_freq = detune_slider.value()
|
|
duration = duration_slider.value() / 10
|
|
octave_freq = (2**octave_slider.value()) * 220
|
|
ramp_amount = ramp_slider.value() / 10
|
|
roll_amount = delay_slider.value()
|
|
st = shape_slider.value() / 20
|
|
volume = volume_slider.value() / 100
|
|
tm = st * 1.2
|
|
sm = 1 - st
|
|
attack_size = attack_slider.value() / 100
|
|
fade_size = fade_slider.value() / 100
|
|
if midi_on_flag[0] is True:
|
|
num_range = midi_range
|
|
keys[:] = note_nums[:]
|
|
else:
|
|
if key_change_bool[0] is True:
|
|
num_range = c_range
|
|
else:
|
|
num_range = e_range
|
|
|
|
|
|
x = np.linspace(0, 2 * np.pi * duration, int(duration * sample_rate))
|
|
ramp_0 = np.logspace(1, 0, np.size(x), base=10) * ramp_amount
|
|
fade_size = int(np.size(x) * fade_size)
|
|
attak = np.linspace(0, 1, int(np.size(x) * attack_size))
|
|
fade = np.linspace(1, 0, fade_size if fade_size >= 1 else 1)
|
|
|
|
notes = []
|
|
with ThreadPoolExecutor() as executer:
|
|
notes = list(executer.map(wave_maker, num_range))
|
|
|
|
global key_notes
|
|
key_notes = dict(zip(keys, notes))
|
|
applying_sliders_flag[0] = False
|
|
return key_notes
|
|
|
|
def changed_duration():
|
|
val = duration_slider.value() * 0.1
|
|
duration_val_label.setText(str('{:2.1f}'.format(val)))
|
|
duration_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def changed_detune():
|
|
val = detune_slider.value()
|
|
detune_val_label.setText(str('{:2.1f}'.format(val)))
|
|
detune_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def changed_octave():
|
|
"""update octave label"""
|
|
val = (2**octave_slider.value()) * 220
|
|
octave_val_label.setText(str(val))
|
|
octave_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def changed_ramp():
|
|
val = ramp_slider.value() * 0.1
|
|
ramp_val_label.setText(str('{:2.1f}'.format(val)))
|
|
ramp_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def changed_roll():
|
|
val = delay_slider.value()
|
|
delay_val_label.setText(str('{:4.3f}\nSeconds'.format(val / 48000)))
|
|
delay_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def changed_attack():
|
|
val = attack_slider.value() * 0.01
|
|
attack_val_label.setText(str('{:3.2f}'.format(val)))
|
|
attack_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def changed_fade():
|
|
val = fade_slider.value() * 0.01
|
|
fade_val_label.setText(str('{:3.2f}'.format(val)))
|
|
fade_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
def changed_vol():
|
|
val = volume_slider.value() * 0.01
|
|
vol_val_label.setText(str("{:3.2f}".format(val)))
|
|
vol_val_label.adjustSize()
|
|
show_apply()
|
|
|
|
|
|
def show_apply():
|
|
label_apply.show()
|
|
|
|
|
|
def flagger():
|
|
global mono_flag
|
|
mono_flag = not mono_flag
|
|
if mono_flag is True:
|
|
mono_button.setText('Mono')
|
|
else:
|
|
mono_button.setText('Poly')
|
|
|
|
|
|
def change_key():
|
|
if midi_on_flag[0] is True:
|
|
return
|
|
else:
|
|
key_change_bool[0] = not key_change_bool[0]
|
|
if key_change_bool[0] is True:
|
|
keys[:] = c_keys[:]
|
|
key_button.setText('C4')
|
|
else:
|
|
keys[:] = e_keys[:]
|
|
key_button.setText('E4')
|
|
do_it_int16()
|
|
|
|
|
|
def open_custom_kb_dialog():
|
|
if midi_on_flag[0] is True:
|
|
return
|
|
else:
|
|
custom_kb_dialog = CustomKeybinder()
|
|
custom_kb_dialog.show()
|
|
|
|
def open_midi_dialog():
|
|
if midi_on_flag[0] is True:
|
|
print("Close cutie-dead-synth to change midi")
|
|
else:
|
|
midi_dialog = ChoosePort()
|
|
midi_dialog.show()
|
|
|
|
|
|
def midi_stuff(port_arg):
|
|
def play_note(event):
|
|
global key_notes
|
|
if applying_sliders_flag[0] is True:
|
|
return
|
|
else:
|
|
if mono_flag is True:
|
|
sa.stop_all()
|
|
try:
|
|
sound = key_notes.get(event)
|
|
buffer_object = sa.play_buffer(sound, 2, 2, sample_rate)
|
|
except TypeError:
|
|
return
|
|
|
|
|
|
if len(port_arg) > 1:
|
|
portname = port_arg
|
|
else:
|
|
portname = None # Use default port
|
|
|
|
with mido.open_input(portname) as port:
|
|
print('Using {}'.format(port))
|
|
print('Waiting for messages...')
|
|
for message in port:
|
|
if message.type == 'note_on' and message.velocity > 0:
|
|
play_note(message.note)
|
|
|
|
|
|
def activate_midi(port_arg):
|
|
midi_thread = threading.Thread(target=midi_stuff, args=[port_arg], daemon=True)
|
|
midi_thread.start()
|
|
|
|
|
|
def save_wav():
|
|
print(str(sample_rate))
|
|
dir_name = "./audio{}-{}Hz".format(time.strftime("%d-%m-%Y-%H-%M-%S", time.gmtime()), sample_rate)
|
|
try:
|
|
print(f"Making directory{dir_name}")
|
|
os.mkdir(dir_name)
|
|
except FileExistsError:
|
|
print("Aborted. Directory already exists")
|
|
return
|
|
else:
|
|
for e, i in enumerate(notes, start=1):
|
|
if len(str(e)) < 2:
|
|
wf.write(f"{dir_name}/a0{e}.wav", sample_rate, i)
|
|
else:
|
|
wf.write(f"{dir_name}/a{e}.wav", sample_rate, i)
|
|
print(f"Wav files saved in directory{dir_name}")
|
|
|
|
|
|
QSS = """
|
|
/* Styling */
|
|
QSlider::groove:horizontal {
|
|
border-radius: 1px;
|
|
height: 3px;
|
|
margin: 0px;
|
|
background-color: #222610;
|
|
}
|
|
QSlider::groove:horizontal:hover {
|
|
background-color: #21e4e4;
|
|
}
|
|
QSlider::handle:horizontal {
|
|
background-color: #728C00;
|
|
border: none;
|
|
height: 40px;
|
|
width: 20px;
|
|
margin: -10px 0;
|
|
border-radius: 10px;
|
|
padding: -20px 0px;
|
|
}
|
|
|
|
QSlider::groove:vertical {
|
|
border-radius: 1px;
|
|
width: 3px;
|
|
margin: 0px;
|
|
background-color: #222610;
|
|
}
|
|
QSlider::groove:vertical:hover {
|
|
background-color: #21e4e4;
|
|
}
|
|
QSlider::handle:vertical {
|
|
background-color: #728C00;
|
|
border: none;
|
|
width: 40px;
|
|
height: 20px;
|
|
margin: 0px -10px;
|
|
border-radius: 10px;
|
|
padding: 0px -20px;
|
|
}
|
|
|
|
QSlider:focus {
|
|
background-color: #0ba4a4;
|
|
}
|
|
MainWindow, QWidget#ck_win, QWidget#midi_win {
|
|
background-color: #313734;
|
|
}
|
|
|
|
QWidget#l_label {
|
|
background-color: #0ba4a4;
|
|
color: #313734;
|
|
}
|
|
|
|
QLabel {
|
|
color: #82edd8;
|
|
font-size: 14px;
|
|
}
|
|
QPushButton {
|
|
background-color: #728C00;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #e7ff00;
|
|
}
|
|
QPushButton:focus {
|
|
border: 2px solid #0ba4a4;
|
|
border-radius: 3px;
|
|
}
|
|
"""
|
|
|
|
c_keys = ['a', 'w', 's', 'e', 'd', 'f', 't',
|
|
'g', 'y', 'h', 'u', 'j', 'k', 'o', 'l', 'p', ';', '\'']
|
|
|
|
e_keys = ['a', 's', 'e', 'd', 'r', 'f', 't',
|
|
'g', 'h', 'u', 'j', 'i', 'k', 'l', 'p', ';', '[', '\'']
|
|
|
|
note_nums = [i for i in range(36, 97)]
|
|
midi_on_flag = [False]
|
|
keys = []
|
|
keys[:] = e_keys[:]
|
|
c_range = range(-9, 9)
|
|
e_range = range(-5, 13)
|
|
midi_range = range(-33, 28)
|
|
key_change_bool = [False]
|
|
applying_sliders_flag = [True]
|
|
mono_flag = False
|
|
|
|
if len(sys.argv) < 2:
|
|
sample_rate = 48000
|
|
else:
|
|
if sys.argv[1] == "44100":
|
|
sample_rate = 44100
|
|
elif sys.argv[1] == "96000":
|
|
sample_rate = 96000
|
|
elif sys.argv[1] == "88200":
|
|
sample_rate = 88200
|
|
elif sys.argv[1] == "192000":
|
|
sample_rate = 192000
|
|
else:
|
|
sample_rate = 48000
|
|
print(f"Samplerate: {sample_rate}")
|
|
|
|
app = QApplication(sys.argv[:1])
|
|
app.setStyleSheet(QSS)
|
|
|
|
win = MainWindow()
|
|
win.setGeometry(20, 100, 700, 500)
|
|
win.setWindowIcon(QtGui.QIcon('images/knotperfect-icon.png'))
|
|
win.setWindowTitle('Not Perfect')
|
|
|
|
shortcut_quit = QShortcut(QKeySequence('Ctrl+Q'), win)
|
|
shortcut_quit.activated.connect(lambda: app.quit())
|
|
|
|
shortcut_apply = QShortcut(QKeySequence('Ctrl+A'), win)
|
|
shortcut_apply.activated.connect(do_it_int16)
|
|
|
|
apply_button = QPushButton('Apply Settings', win)
|
|
apply_button.move(10, 10)
|
|
apply_button.clicked.connect(do_it_int16)
|
|
|
|
shortcut_mono = QShortcut(QKeySequence('Ctrl+M'), win)
|
|
shortcut_mono.activated.connect(flagger)
|
|
|
|
mono_button = QPushButton('Poly', win)
|
|
mono_button.move(200, 10)
|
|
mono_button.clicked.connect(flagger)
|
|
|
|
shortcut_key = QShortcut(QKeySequence('Ctrl+K'), win)
|
|
shortcut_key.activated.connect(change_key)
|
|
|
|
key_button = QPushButton('E4', win)
|
|
key_button.move(10, 290)
|
|
key_button.clicked.connect(change_key)
|
|
|
|
midi_button = QPushButton('Open Midi Input', win)
|
|
midi_button.move(10, 340)
|
|
midi_button.clicked.connect(open_midi_dialog)
|
|
|
|
|
|
# duration
|
|
duration_label = QLabel(win)
|
|
duration_label.setText('Duration')
|
|
duration_label.move(10, 50)
|
|
|
|
set0 = 14
|
|
duration_slider = QSlider(Qt.Horizontal, win)
|
|
duration_slider.setMinimumWidth(200)
|
|
duration_slider.setMinimum(0)
|
|
duration_slider.setMaximum(50)
|
|
duration_slider.setValue(set0)
|
|
duration_slider.setSingleStep(2)
|
|
duration_slider.move(80, 50)
|
|
duration_slider.valueChanged.connect(changed_duration)
|
|
|
|
duration_val_label = QLabel(win)
|
|
duration_val_label.setText(str('{:2.1f}'.format(set0 * 0.1)))
|
|
duration_val_label.move(290, 50)
|
|
|
|
# detune
|
|
detune_label = QLabel(win)
|
|
detune_label.setText('Detune')
|
|
detune_label.move(10, 90)
|
|
|
|
set1 = 9
|
|
detune_slider = QSlider(Qt.Horizontal, win)
|
|
detune_slider.setMinimumWidth(200)
|
|
detune_slider.setMinimum(0)
|
|
detune_slider.setMaximum(13)
|
|
detune_slider.setSingleStep(1)
|
|
detune_slider.setValue(set1)
|
|
detune_slider.move(80, 90)
|
|
detune_slider.valueChanged.connect(changed_detune)
|
|
|
|
detune_val_label = QLabel(win)
|
|
detune_val_label.setText(str(set1))
|
|
detune_val_label.move(290, 90)
|
|
|
|
# octave
|
|
octave_label = QLabel(win)
|
|
octave_label.setText('Octave')
|
|
octave_label.move(10, 130)
|
|
|
|
set2 = 1
|
|
octave_slider = QSlider(Qt.Horizontal, win)
|
|
octave_slider.setMinimumWidth(13)
|
|
octave_slider.setMinimum(0)
|
|
octave_slider.setMaximum(4)
|
|
octave_slider.setValue(set2)
|
|
octave_slider.move(80, 130)
|
|
octave_slider.valueChanged.connect(changed_octave)
|
|
|
|
octave_val_label = QLabel(win)
|
|
octave_val_label.setText(str((2**set2) * 220))
|
|
octave_val_label.move(190, 130)
|
|
|
|
# ramp_0
|
|
ramp_label = QLabel(win)
|
|
ramp_label.setText('Ramp')
|
|
ramp_label.move(10, 170)
|
|
|
|
set3 = 5
|
|
ramp_slider = QSlider(Qt.Horizontal, win)
|
|
ramp_slider.setMinimumWidth(200)
|
|
ramp_slider.setMinimum(0)
|
|
ramp_slider.setMaximum(20)
|
|
ramp_slider.setSingleStep(1)
|
|
ramp_slider.setValue(set3)
|
|
ramp_slider.move(80, 170)
|
|
ramp_slider.valueChanged.connect(changed_ramp)
|
|
|
|
ramp_val_label = QLabel(win)
|
|
ramp_val_label.setText(str(set3 * 0.1))
|
|
ramp_val_label.move(290, 170)
|
|
|
|
# roll
|
|
delay_label = QLabel(win)
|
|
delay_label.setText('Delay')
|
|
delay_label.move(10, 210)
|
|
|
|
set4 = 4000
|
|
delay_slider = QSlider(Qt.Horizontal, win)
|
|
delay_slider.setMinimumWidth(200)
|
|
delay_slider.setMinimum(0)
|
|
delay_slider.setMaximum(4000)
|
|
delay_slider.setSingleStep(100)
|
|
delay_slider.setValue(set4)
|
|
delay_slider.move(80, 210)
|
|
delay_slider.valueChanged.connect(changed_roll)
|
|
|
|
delay_val_label = QLabel(win)
|
|
delay_val_label.setText(str('{:4.3f}\nSeconds'.format(set4 / 48000)))
|
|
delay_val_label.move(290, 204)
|
|
|
|
# shape
|
|
sine_label = QLabel(win)
|
|
sine_label.setText('Sine')
|
|
sine_label.move(10, 250)
|
|
|
|
shape_slider = QSlider(Qt.Horizontal, win)
|
|
shape_slider.setMinimumWidth(200)
|
|
shape_slider.setMinimum(0)
|
|
shape_slider.setMaximum(20)
|
|
shape_slider.setSingleStep(1)
|
|
shape_slider.setValue(0)
|
|
shape_slider.move(80, 250)
|
|
shape_slider.valueChanged.connect(show_apply)
|
|
|
|
# attack
|
|
attack_label = QLabel(win)
|
|
attack_label.setText("Attack")
|
|
attack_label.move(368, 20)
|
|
|
|
attack_slider = QSlider(Qt.Vertical, win)
|
|
attack_slider.setMinimumHeight(100)
|
|
attack_slider.setMinimum(0)
|
|
attack_slider.setMaximum(100)
|
|
attack_slider.setSingleStep(1)
|
|
attack_slider.setValue(0)
|
|
attack_slider.move(380, 50)
|
|
attack_slider.valueChanged.connect(changed_attack)
|
|
|
|
attack_val_label = QLabel(win)
|
|
attack_val_label.setText(str('{:3.2f}'.format(0)))
|
|
attack_val_label.move(377, 160)
|
|
|
|
# fade
|
|
fade_label = QLabel(win)
|
|
fade_label.setText("Fade")
|
|
fade_label.move(442, 20)
|
|
|
|
set_7 = 20
|
|
fade_slider = QSlider(Qt.Vertical, win)
|
|
fade_slider.setMinimumHeight(100)
|
|
fade_slider.setMinimum(0)
|
|
fade_slider.setMaximum(100)
|
|
fade_slider.setSingleStep(1)
|
|
fade_slider.setValue(set_7)
|
|
fade_slider.move(450, 50)
|
|
fade_slider.valueChanged.connect(changed_fade)
|
|
|
|
fade_val_label = QLabel(win)
|
|
fade_val_label.setText(str('{:3.2f}'.format(set_7 * 0.01)))
|
|
fade_val_label.move(447, 160)
|
|
|
|
# volume
|
|
volume_label = QLabel(win)
|
|
volume_label.setText("volume")
|
|
volume_label.move(526, 20)
|
|
|
|
set_vol = 70
|
|
volume_slider = QSlider(Qt.Vertical, win)
|
|
volume_slider.setMinimumHeight(100)
|
|
volume_slider.setMinimum(0)
|
|
volume_slider.setMaximum(100)
|
|
volume_slider.setSingleStep(1)
|
|
volume_slider.setValue(set_vol)
|
|
volume_slider.move(540, 50)
|
|
volume_slider.valueChanged.connect(changed_vol)
|
|
|
|
vol_val_label = QLabel(win)
|
|
vol_val_label.setText(str("{:3.2f}".format(set_vol * 0.01)))
|
|
vol_val_label.move(538, 160)
|
|
|
|
triangle_label = QLabel(win)
|
|
triangle_label.setText('Triangle')
|
|
triangle_label.move(290, 250)
|
|
|
|
keybind_button = QPushButton("Custom Keyboard", win)
|
|
keybind_button.move(200, 290)
|
|
keybind_button.clicked.connect(open_custom_kb_dialog)
|
|
|
|
wav_button = QPushButton("Save Notes as .wav Files", win)
|
|
wav_button.move(200, 390)
|
|
wav_button.clicked.connect(save_wav)
|
|
|
|
close_button = QPushButton('Close', win)
|
|
close_button.move(10, 390)
|
|
close_button.clicked.connect(lambda: app.quit())
|
|
|
|
label_pic = QLabel(win)
|
|
label_apply = QLabel(win)
|
|
# dce9e2
|
|
pixmap = QPixmap('images/knotpforQTsmall.png')
|
|
pixmap_1 = QPixmap('images/say_apply.png')
|
|
label_pic.setPixmap(pixmap)
|
|
label_pic.move(435, 180)
|
|
|
|
label_apply.setPixmap(pixmap_1)
|
|
label_apply.move(410, 181)
|
|
label_apply.hide()
|
|
|
|
do_it_int16()
|
|
|
|
win.show()
|
|
|
|
sys.exit(app.exec_())
|