class Window(QMainWindow): isStart = False #프로그램 Midi 로딩을 완료했는가? isPlaying = False #음악이 실행되어 있는가? isWorking = True #프로그램이 일하는 중인가? isControl = False #사용자가 슬라이더를 컨트롤 중인가? a_point = None b_point = None def __init__(self): super().__init__() self.data_file = SaveData(SAVE_DATA_FILENAME) self.UI() def UI(self): self.resize(WINDOW_WIDTH, WINDOW_HEIGHT) self.setWindowTitle('MIDI Data Generator') self.setMaximumSize(WINDOW_WIDTH, WINDOW_HEIGHT) self.setMinimumSize(WINDOW_WIDTH, WINDOW_HEIGHT) self.cb_midi_list = QComboBox(self) self.cb_midi_list.move(650, 1) self.cb_midi_list.activated[str].connect(self.select) self.UI_Button() self.UI_Label() self.timeslider = QSlider(Qt.Horizontal, self) self.timeslider.move(30, 25) self.timeslider.setRange(0, 100) self.timeslider.resize(740, 50) self.timeslider.sliderPressed.connect(self.slider_control) self.timeslider.sliderReleased.connect(self.slider_release) def keyPressEvent(self, e): if e.key() == Qt.Key_Space: self.music_play() if e.key() == Qt.Key_P: self.music_stop() if e.key() == Qt.Key_A: self.select_a() if e.key() == Qt.Key_B: self.select_b() if e.key() == Qt.Key_S: self.save() if e.key() == Qt.Key_C: self.clear() if e.key() == Qt.Key_Tab: self.next_midi() if e.key() == Qt.Key_1: self.play_a() if e.key() == Qt.Key_2: self.play_b() if e.key() == Qt.Key_Right: if self.isStart: self.audio.player.setPosition( int(self.audio.player.position()) + 3000) if e.key() == Qt.Key_Left: if self.isStart: self.audio.player.setPosition( int(self.audio.player.position()) - 3000) def UI_Button(self): bt_open = QPushButton('Open', self) bt_open.move(30, 0) bt_open.clicked.connect(self.open_file) bt_prev = QPushButton('Prev', self) bt_prev.resize(100, 70) bt_prev.move(30, 100) bt_prev.clicked.connect(self.prev_midi) bt_next = QPushButton('Next', self) bt_next.resize(100, 70) bt_next.move(130, 100) bt_next.clicked.connect(self.next_midi) bt_play = QPushButton('Play', self) bt_play.resize(70, 70) bt_play.move(250, 100) bt_play.clicked.connect(self.music_play) bt_stop = QPushButton('Stop', self) bt_stop.resize(70, 70) bt_stop.move(320, 100) bt_stop.clicked.connect(self.music_stop) bt_a = QPushButton('A', self) bt_a.resize(120, 70) bt_a.move(410, 100) bt_a.clicked.connect(self.select_a) bt_b = QPushButton('B', self) bt_b.resize(120, 70) bt_b.move(530, 100) bt_b.clicked.connect(self.select_b) bt_clear = QPushButton('Clear', self) bt_clear.resize(120, 70) bt_clear.move(650, 100) bt_clear.clicked.connect(self.clear) bt_play_a = QPushButton('Play A', self) bt_play_a.resize(190, 70) bt_play_a.move(30, 170) bt_play_a.clicked.connect(self.play_a) bt_play_b = QPushButton('Play B', self) bt_play_b.resize(190, 70) bt_play_b.move(215, 170) bt_play_b.clicked.connect(self.play_b) bt_clear_a = QPushButton('Clear A', self) bt_clear_a.resize(185, 70) bt_clear_a.move(400, 170) bt_clear_a.clicked.connect(self.clear_a) bt_clear_b = QPushButton('Clear B', self) bt_clear_b.resize(190, 70) bt_clear_b.move(580, 170) bt_clear_b.clicked.connect(self.clear_b) bt_save = QPushButton('Save', self) bt_save.resize(740, 60) bt_save.move(30, 300) bt_save.clicked.connect(self.save) def UI_Label(self): self.lb_status = QLabel('Status:Free', self) self.lb_status.move(160, 0) self.lb_status.resize(300, 30) self.lb_timer = QLabel('0.00', self) self.lb_timer.move(500, 0) self.lb_current_bpm = QLabel('Current BPM:', self) self.lb_current_bpm.move(30, 60) self.lb_current_bpm.resize(200, 30) self.lb_current_midi_index = QLabel('Index: /', self) self.lb_current_midi_index.move(600, 60) self.lb_current_midi_index.resize(200, 30) self.lb_file_name = QLabel('File Name:', self) self.lb_file_name.move(30, 240) self.lb_file_name.resize(200, 30) self.lb_a_point = QLabel('A point:', self) self.lb_a_point.move(390, 240) self.lb_a_point.resize(200, 30) self.lb_b_point = QLabel('B point:', self) self.lb_b_point.move(590, 240) self.lb_b_point.resize(200, 30) self.lb_length = QLabel('Length:', self) self.lb_length.move(30, 270) self.lb_length.resize(200, 30) self.lb_bpm = QLabel('BPM:', self) self.lb_bpm.move(390, 270) self.lb_bpm.resize(200, 30) self.lb_total_data = QLabel( 'Total Data: ' + str(self.data_file.total()), self) self.lb_total_data.move(30, 360) self.lb_total_data.resize(200, 30) def open_file(self): self.loc_folder = QFileDialog.getExistingDirectory(self) if self.loc_folder: self.isStart = True self.isWorking = True self.lb_status.setText("Status: Working") self.cb_midi_list.clear() self.cb_midi_list.clearFocus() files = [ f for f in listdir(self.loc_folder) if isfile(join(self.loc_folder, f)) ] self.midi_filename_list = [ file for file in files if file.endswith('.mid') or file.endswith('.MID') ] self.midi_filename_list.sort() self.cb_midi_list.addItems(self.midi_filename_list) self.current_index = 0 self.midi_total_index = len(self.midi_filename_list) self.lb_current_midi_index.setText('Index: 0/' + str(self.midi_total_index)) th_load = Thread(target=self.load, args=(self.midi_filename_list[0], )) th_load.start() def select(self, text): self.lb_status.setText("Status: Working") self.current_index = self.midi_filename_list.index(text) th_load = Thread(target=self.load, args=(text, )) th_load.start() def load(self, text): self.isWorking = True if self.isPlaying: self.audio.stop() self.isPlaying = False self.current_midi_name = text self.current_midi_file = music21.converter.parse(self.loc_folder + '/' + text) self.current_midi_bpm = get_bpm(self.current_midi_file) self.lb_current_midi_index.setText('Index: ' + str(self.current_index + 1) + '/' + str(self.midi_total_index)) self.lb_current_bpm.setText('Current BPM: ' + str(self.current_midi_bpm)) self.lb_bpm.setText('BPM: ' + str(self.current_midi_bpm)) self.lb_file_name.setText('Filename: ' + self.current_midi_name) if self.current_midi_bpm != None: QApplication.processEvents() midi_to_audio(self.loc_folder + '/' + self.current_midi_name, 'tmp.wav') self.audio = Player('tmp.wav') self.lb_length.setText('length: ' + str(int(self.audio.length)) + ' s') self.clear() self.lb_status.setText('Status: Free') else: self.lb_status.setText('Status: Can\'t read BPM!') self.isWorking = False def next_midi(self): if self.isStart: QApplication.processEvents() if self.current_index < self.midi_total_index: self.lb_status.setText("Status: Working") self.current_index += 1 self.cb_midi_list.setCurrentIndex(self.current_index) th_load = Thread( target=self.load, args=(self.midi_filename_list[self.current_index], )) th_load.start() else: QMessageBox.about(self, "Error", "Please load MIDI file.") def prev_midi(self): if self.isStart: QApplication.processEvents() if self.current_index > 0: self.lb_status.setText("Status: Working") self.current_index -= 1 self.cb_midi_list.setCurrentIndex(self.current_index) th_load = Thread( target=self.load, args=(self.midi_filename_list[self.current_index], )) th_load.start() else: QMessageBox.about(self, "Error", "Please load MIDI file.") def music_play(self): if self.isStart: if self.isWorking == False: if self.isPlaying: self.audio.pause() self.isPlaying = False else: self.isPlaying = True th_updater = Thread(target=self.audio_ui_update) th_updater.start() try: self.audio.play() except: self.isPlaying = False QMessageBox.about(self, 'Error', 'Can\'t read BPM!') else: QMessageBox.about(self, "Error", "Process is working...") else: QMessageBox.about(self, "Error", "Please load MIDI file.") def music_stop(self): if self.isStart: if self.isWorking == False: if self.isPlaying: self.audio.stop() self.timeslider.setValue(0) self.lb_timer.setText('0.00') self.isPlaying = False else: QMessageBox.about(self, "Error", "Process is working...") else: QMessageBox.about(self, "Error", "Please load MIDI file.") def audio_ui_update(self): QApplication.processEvents() while self.isPlaying: self.lb_timer.setText('%.2f' % (self.audio.player.position() * 0.001)) if self.isControl == False and self.isPlaying == True: self.timeslider.setValue(self.audio.player.position() * 0.001 / int(self.audio.length) * 100) def slider_control(self): self.isControl = True def slider_release(self): if self.isStart: self.audio.player.setPosition( int(self.timeslider.value() * 10 * self.audio.length)) self.isControl = False def select_a(self): QApplication.processEvents() if self.isStart: if self.isWorking == False: self.a_point = round(self.audio.player.position() * 0.001, 2) self.lb_a_point.setText('A point: ' + str(self.a_point)) else: QMessageBox.about(self, "Error", "Process is working...") else: QMessageBox.about(self, "Error", "Please load MIDI file.") def select_b(self): QApplication.processEvents() if self.isStart: if self.isWorking == False: self.b_point = round(self.audio.player.position() * 0.001, 2) self.lb_b_point.setText('B point: ' + str(self.b_point)) else: QMessageBox.about(self, "Error", "Process is working...") else: QMessageBox.about(self, "Error", "Please load MIDI file.") def play_a(self): QApplication.processEvents() if self.isStart: if self.b_point != None: self.audio.player.setPosition(self.a_point * 1000) if self.isPlaying == False: self.music_play() else: QMessageBox.about(self, "Error", "Please set the point.") else: QMessageBox.about(self, "Error", "Please load MIDI file.") def play_b(self): QApplication.processEvents() if self.isStart: if self.b_point != None: self.audio.player.setPosition(self.b_point * 1000) if self.isPlaying == False: self.music_play() else: QMessageBox.about(self, "Error", "Please set the point.") else: QMessageBox.about(self, "Error", "Please load MIDI file.") def clear(self): QApplication.processEvents() self.a_point = None self.b_point = None self.lb_a_point.setText('A point: ') self.lb_b_point.setText('B point: ') self.timeslider.setValue(0) self.lb_timer.setText('0.00') def clear_a(self): QApplication.processEvents() self.a_point = None self.lb_a_point.setText('A point: ') def clear_b(self): QApplication.processEvents() self.b_point = None self.lb_b_point.setText('B point: ') def save(self): if self.isStart: if self.isWorking == False: if self.current_midi_name and self.audio.length and self.current_midi_bpm and self.a_point and self.b_point: QApplication.processEvents() self.data_file.write_data([ self.loc_folder + self.current_midi_name, int(self.audio.length), self.current_midi_bpm, self.a_point, self.b_point ]) self.lb_total_data.setText('Total Data: ' + str(self.data_file.total())) QMessageBox.about(self, "Complete", "Save complete!") else: QMessageBox.about(self, "Error", "Please enter the data.") else: QMessageBox.about(self, "Error", "Process is working...") else: QMessageBox.about(self, "Error", "Please load MIDI file.")
class Window(QMainWindow): def __init__(self): super().__init__() self.data_file = SaveData(SAVE_DATA_FILENAME) if os.path.isfile('datafile0.csv'): self.names = [] f = open('datafile0.csv', encoding='utf-8') rdr = csv.reader(f) for line in rdr: self.names += [line[0]] f.close() self.UI() def UI(self): self.resize(WINDOW_WIDTH, WINDOW_HEIGHT) self.setWindowTitle('Manual MIDI Data Generator') self.setMaximumSize(WINDOW_WIDTH, WINDOW_HEIGHT) self.setMinimumSize(WINDOW_WIDTH, WINDOW_HEIGHT) self.lb_filename = QLabel('Filename', self) self.lb_filename.move(10, 0) self.lb_filename.resize(300, 30) self.te_filename = QTextEdit(self) self.te_filename.move(10, 30) self.te_filename.resize(380, 30) self.lb_length = QLabel('Length', self) self.lb_length.move(10, 60) self.lb_length.resize(300, 30) self.te_length = QTextEdit(self) self.te_length.move(10, 90) self.te_length.resize(380, 30) self.lb_bpm = QLabel('BPM', self) self.lb_bpm.move(10, 120) self.lb_bpm.resize(300, 30) self.te_bpm = QTextEdit(self) self.te_bpm.move(10, 150) self.te_bpm.resize(380, 30) self.lb_a_point = QLabel('A Point', self) self.lb_a_point.move(10, 180) self.lb_a_point.resize(300, 30) self.te_a_point = QTextEdit(self) self.te_a_point.move(10, 210) self.te_a_point.resize(380, 30) self.lb_b_point = QLabel('B Point', self) self.lb_b_point.move(10, 240) self.lb_b_point.resize(300, 30) self.te_b_point = QTextEdit(self) self.te_b_point.move(10, 270) self.te_b_point.resize(380, 30) self.bt_save = QPushButton(self) self.bt_save.setText('Save') self.bt_save.move(5, 310) self.bt_save.resize(390, 50) self.bt_save.clicked.connect(self.save) self.lb_count = QLabel( 'Number of Data : ' + str(self.data_file.total()), self) self.lb_count.move(10, 360) self.lb_count.resize(300, 30) self.bt_clear = QPushButton(self) self.bt_clear.move(190, 360) self.bt_clear.resize(200, 30) self.bt_clear.setText('Clear') self.bt_clear.clicked.connect(self.clear) def save(self): if self.te_filename.toPlainText() and self.te_a_point.toPlainText( ) and self.te_b_point.toPlainText() and self.te_bpm.toPlainText( ) and self.te_length: if self.te_filename.toPlainText( ) + '.mid' in self.names or self.te_filename.toPlainText( ) + '.MID' in self.names: QMessageBox(self, 'Error', 'Data exists!') else: self.names += [self.te_filename.toPlainText()] self.data_file.write_data([ self.te_filename.toPlainText(), self.te_length.toPlainText(), self.te_bpm.toPlainText(), self.te_a_point.toPlainText(), self.te_b_point.toPlainText() ]) self.lb_count.setText('Number of Data : ' + str(self.data_file.total())) self.clear() QMessageBox.about(self, 'Save', 'Complete!') else: QMessageBox.about(self, 'Alert', 'Type all data!') def clear(self): QApplication.processEvents() self.te_a_point.setPlainText('') self.te_b_point.setPlainText('') self.te_bpm.setPlainText('') self.te_length.setPlainText('') self.te_filename.setPlainText('')