Exemple #1
0
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.")
Exemple #2
0
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('')