- Add support for adding the base folder to PATH. - Only display one pop up window at a time in order to avoid confusion. - Add automatic updates feature: - Windows and Linux versions will be shipped with an updater program used to update both Artemis and the updater itself. - MacOs versions will not have the updater. Instead the user will be asked to download the new software version (if present) via browser.
175 lines
5.8 KiB
Python
175 lines
5.8 KiB
Python
import os
|
|
from pygame import mixer
|
|
from PyQt5.QtCore import QTimer, pyqtSlot, QObject
|
|
|
|
import qtawesome as qta
|
|
from constants import Constants
|
|
|
|
|
|
class AudioPlayer(QObject):
|
|
"""Subclass QObject. Audio player widget for the audio samples.
|
|
|
|
The only public methods are the __init__
|
|
method, set_audio_player, which loads the current file and refresh.
|
|
Everything else is managed internally."""
|
|
|
|
_TIME_STEP = 500 # Milliseconds.
|
|
|
|
def __init__(self, play,
|
|
pause,
|
|
stop,
|
|
volume,
|
|
loop,
|
|
audio_progress,
|
|
active_color,
|
|
inactive_color):
|
|
"""Initialize the player."""
|
|
super().__init__()
|
|
self._active_color = active_color
|
|
self._inactive_color = inactive_color
|
|
self._paused = False
|
|
self._first_call = True
|
|
self._play = play
|
|
self._pause = pause
|
|
self._stop = stop
|
|
self._volume = volume
|
|
self._loop = loop
|
|
self._audio_progress = audio_progress
|
|
self._audio_file = None
|
|
self._timer = QTimer()
|
|
self._timer.timeout.connect(self._update_bar)
|
|
self._play.clicked.connect(self._play_audio)
|
|
self._pause.clicked.connect(self._pause_audio)
|
|
self._stop.clicked.connect(self._stop_audio)
|
|
self._volume.valueChanged.connect(self._set_volume)
|
|
self._loop.clicked.connect(self._set_loop_icon)
|
|
self._play.setIconSize(self._play.size())
|
|
self._pause.setIconSize(self._pause.size())
|
|
self._stop.setIconSize(self._stop.size())
|
|
self._loop.setIconSize(self._loop.size())
|
|
self.refresh(active_color, inactive_color)
|
|
|
|
@pyqtSlot()
|
|
def _set_loop_icon(self):
|
|
"""Set the icon for the loop audio button."""
|
|
if self._loop.isChecked():
|
|
loop_icon = qta.icon(
|
|
'fa5s.redo-alt',
|
|
color=self._active_color,
|
|
color_disabled=self._inactive_color,
|
|
animation=qta.Spin(self._loop)
|
|
)
|
|
else:
|
|
loop_icon = qta.icon(
|
|
'fa5s.redo-alt',
|
|
color=self._active_color,
|
|
color_disabled=self._inactive_color
|
|
)
|
|
self._loop.setIcon(loop_icon)
|
|
|
|
def refresh(self, active_color, inactive_color):
|
|
"""Repaint the buttons of the widgetd after the theme has changed."""
|
|
self._active_color = active_color
|
|
self._inactive_color = inactive_color
|
|
self._play.setIcon(qta.icon('fa5s.play',
|
|
color=active_color,
|
|
color_disabled=inactive_color))
|
|
self._pause.setIcon(qta.icon('fa5s.pause',
|
|
color=active_color,
|
|
color_disabled=inactive_color))
|
|
self._stop.setIcon(qta.icon('fa5s.stop',
|
|
color=active_color,
|
|
color_disabled=inactive_color))
|
|
self._set_loop_icon()
|
|
|
|
@pyqtSlot()
|
|
def _set_volume(self):
|
|
"""Set the volume of the audio samples."""
|
|
if mixer.get_init():
|
|
mixer.music.set_volume(
|
|
self._volume.value() / self._volume.maximum()
|
|
)
|
|
|
|
def _reset_audio_widget(self):
|
|
"""Reset the widget. Stop all playing samples."""
|
|
self._first_call = True
|
|
self._paused = False
|
|
if mixer.get_init():
|
|
if mixer.music.get_busy():
|
|
mixer.music.stop()
|
|
self._timer.stop()
|
|
mixer.quit()
|
|
self._audio_progress.reset()
|
|
self._enable_buttons(False, False, False)
|
|
|
|
@pyqtSlot()
|
|
def _update_bar(self):
|
|
"""Update the progress bar."""
|
|
pos = mixer.music.get_pos()
|
|
if pos == -1:
|
|
self._timer.stop()
|
|
self._audio_progress.reset()
|
|
if self._loop.isChecked():
|
|
self._play_audio()
|
|
self._enable_buttons(False, True, True)
|
|
else:
|
|
self._enable_buttons(True, False, False)
|
|
else:
|
|
self._audio_progress.setValue(pos)
|
|
|
|
def _set_max_progress_bar(self):
|
|
"""Set the maximum value of the progress bar."""
|
|
self._audio_progress.setMaximum(
|
|
mixer.Sound(self._audio_file).get_length() * 1000
|
|
)
|
|
|
|
def set_audio_player(self, fname=""):
|
|
"""Set the current audio sample."""
|
|
self._reset_audio_widget()
|
|
full_name = os.path.join(
|
|
Constants.AUDIO_FOLDER,
|
|
fname + '.ogg'
|
|
)
|
|
if os.path.exists(full_name):
|
|
self._play.setEnabled(True)
|
|
self._audio_file = full_name
|
|
|
|
@pyqtSlot()
|
|
def _play_audio(self):
|
|
"""Play the audio sample."""
|
|
if not self._paused:
|
|
if self._first_call:
|
|
self._first_call = False
|
|
mixer.init(48000, -16, 1, 1024)
|
|
mixer.music.load(self._audio_file)
|
|
self._set_volume()
|
|
self._set_max_progress_bar()
|
|
mixer.music.play()
|
|
else:
|
|
mixer.music.unpause()
|
|
self._paused = False
|
|
self._timer.start(self._TIME_STEP)
|
|
self._enable_buttons(False, True, True)
|
|
|
|
@pyqtSlot()
|
|
def _stop_audio(self):
|
|
"""Stop the audio sample."""
|
|
mixer.music.stop()
|
|
self._audio_progress.reset()
|
|
self._timer.stop()
|
|
self._enable_buttons(True, False, False)
|
|
|
|
@pyqtSlot()
|
|
def _pause_audio(self):
|
|
"""Pause the audio sample."""
|
|
mixer.music.pause()
|
|
self._timer.stop()
|
|
self._paused = True
|
|
self._enable_buttons(True, False, False)
|
|
|
|
def _enable_buttons(self, play_en, pause_en, stop_en):
|
|
"""Set the three buttons status."""
|
|
self._play.setEnabled(play_en)
|
|
self._pause.setEnabled(pause_en)
|
|
self._stop.setEnabled(stop_en)
|