diff --git a/toonz/sources/include/toonzqt/flipconsole.h b/toonz/sources/include/toonzqt/flipconsole.h index 5e7c32a..93e493f 100644 --- a/toonz/sources/include/toonzqt/flipconsole.h +++ b/toonz/sources/include/toonzqt/flipconsole.h @@ -250,6 +250,7 @@ public: void enableButton(UINT button, bool enable, bool doShowHide = true); void showCurrentFrame(); int getCurrentFrame() const { return m_currentFrame; } + int getCurrentFps() const { return m_fps; } void setChecked(UINT button, bool state); bool isChecked(UINT button) const; void setCurrentFrame(int frame, bool forceResetting = false); diff --git a/toonz/sources/toonz/viewerpane.cpp b/toonz/sources/toonz/viewerpane.cpp index 33e3434..deae824 100644 --- a/toonz/sources/toonz/viewerpane.cpp +++ b/toonz/sources/toonz/viewerpane.cpp @@ -120,7 +120,7 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) int buttons = FlipConsole::cFullConsole; - buttons &= (~FlipConsole::eSound); + // buttons &= (~FlipConsole::eSound); buttons &= (~FlipConsole::eFilledRaster); buttons &= (~FlipConsole::eDefineLoadBox); buttons &= (~FlipConsole::eUseLoadBox); @@ -150,6 +150,10 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)), m_sceneViewer, SLOT(onButtonPressed(FlipConsole::EGadget))); + ret = + ret && connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)), + this, SLOT(onButtonPressed(FlipConsole::EGadget))); + ret = ret && connect(m_sceneViewer, SIGNAL(previewStatusChanged()), this, SLOT(update())); @@ -157,7 +161,8 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) SLOT(onSceneSwitched())); assert(ret); - + m_flipConsole->setChecked(FlipConsole::eSound, true); + m_playSound = m_flipConsole->isChecked(FlipConsole::eSound); m_flipConsole->setFrameRate(app->getCurrentScene() ->getScene() ->getProperties() @@ -474,6 +479,12 @@ void SceneViewerPanel::onXshLevelSwitched(TXshLevel *) { changeWindowTitle(); } //----------------------------------------------------------------------------- void SceneViewerPanel::onPlayingStatusChanged(bool playing) { + if (playing) { + m_playing = true; + } else { + m_playing = false; + m_first = true; + } if (Preferences::instance()->getOnionSkinDuringPlayback()) return; OnionSkinMask osm = TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask(); @@ -578,7 +589,6 @@ void SceneViewerPanel::onSceneChanged() { updateFrameRange(); updateFrameMarkers(); changeWindowTitle(); - TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); assert(scene); @@ -588,6 +598,7 @@ void SceneViewerPanel::onSceneChanged() { int frameIndex = TApp::instance()->getCurrentFrame()->getFrameIndex(); if (m_keyFrameButton->getCurrentFrame() != frameIndex) m_keyFrameButton->setCurrentFrame(frameIndex); + hasSoundtrack(); } //----------------------------------------------------------------------------- @@ -615,6 +626,14 @@ void SceneViewerPanel::onFrameSwitched() { m_flipConsole->setCurrentFrame(frameIndex + 1); if (m_keyFrameButton->getCurrentFrame() != frameIndex) m_keyFrameButton->setCurrentFrame(frameIndex); + + if (m_playing && m_playSound) { + if (m_first == true && hasSoundtrack()) { + playAudioFrame(frameIndex); + } else if (m_hasSoundtrack) { + playAudioFrame(frameIndex); + } + } } //----------------------------------------------------------------------------- @@ -638,3 +657,50 @@ void SceneViewerPanel::onFrameTypeChanged() { updateFrameRange(); updateFrameMarkers(); } + +void SceneViewerPanel::playAudioFrame(int frame) { + if (m_first) { + m_first = false; + m_fps = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProperties() + ->getOutputProperties() + ->getFrameRate(); + m_samplesPerFrame = m_sound->getSampleRate() / abs(m_fps); + } + if (!m_sound) return; + m_viewerFps = m_flipConsole->getCurrentFps(); + double s0 = frame * m_samplesPerFrame, s1 = s0 + m_samplesPerFrame; + + // make the sound stop if the viewerfps is higher so the next sound can play + // on time. + if (m_fps < m_viewerFps) + TApp::instance()->getCurrentXsheet()->getXsheet()->stopScrub(); + TApp::instance()->getCurrentXsheet()->getXsheet()->play(m_sound, s0, s1, + false); +} + +bool SceneViewerPanel::hasSoundtrack() { + if (m_sound != NULL) { + m_sound = NULL; + m_hasSoundtrack = false; + m_first = true; + } + TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet(); + TXsheet::SoundProperties *prop = new TXsheet::SoundProperties(); + m_sound = xsheetHandle->getXsheet()->makeSound(prop); + if (m_sound == NULL) { + m_hasSoundtrack = false; + return false; + } else { + m_hasSoundtrack = true; + return true; + } +} + +void SceneViewerPanel::onButtonPressed(FlipConsole::EGadget button) { + if (button == FlipConsole::eSound) { + m_playSound = !m_playSound; + } +} \ No newline at end of file diff --git a/toonz/sources/toonz/viewerpane.h b/toonz/sources/toonz/viewerpane.h index d308604..b398fe4 100644 --- a/toonz/sources/toonz/viewerpane.h +++ b/toonz/sources/toonz/viewerpane.h @@ -37,6 +37,14 @@ class SceneViewerPanel final : public TPanel, public FlipConsoleOwner { TPanelTitleBarButton *m_previewButton; TPanelTitleBarButton *m_subcameraPreviewButton; bool m_onionSkinActive = false; + bool m_playSound = true; + bool m_hasSoundtrack = false; + bool m_playing = false; + double m_fps; + int m_viewerFps; + double m_samplesPerFrame; + bool m_first = true; + TSoundTrack *m_sound = NULL; public: #if QT_VERSION >= 0x050500 @@ -58,6 +66,8 @@ protected: void createPlayToolBar(); void addColorMaskButton(QWidget *parent, const char *iconSVGName, int id); void enableFlipConsoleForCamerastand(bool on); + void playAudioFrame(int frame); + bool hasSoundtrack(); public slots: @@ -66,6 +76,7 @@ public slots: void onXshLevelSwitched(TXshLevel *); void updateFrameRange(); void updateFrameMarkers(); + void onButtonPressed(FlipConsole::EGadget button); protected slots: