Chris@0: /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ Chris@0: Chris@0: /* Chris@0: A waveform viewer and audio annotation editor. Chris@2: Chris Cannam, Queen Mary University of London, 2005-2006 Chris@0: Chris@0: This is experimental software. Not for distribution. Chris@0: */ Chris@0: Chris@0: #include "ViewManager.h" Chris@0: #include "AudioPlaySource.h" Chris@0: #include "PlayParameters.h" Chris@0: #include "Model.h" Chris@0: Chris@0: #include Chris@0: Chris@0: //#define DEBUG_VIEW_MANAGER 1 Chris@0: Chris@0: ViewManager::ViewManager() : Chris@0: m_playSource(0), Chris@0: m_globalCentreFrame(0), Chris@0: m_globalZoom(1024), Chris@0: m_lastLeft(0), Chris@8: m_lastRight(0), Chris@8: m_inProgressExclusive(true), Chris@8: m_toolMode(NavigateMode) Chris@0: { Chris@0: connect(this, Chris@0: SIGNAL(centreFrameChanged(void *, unsigned long, bool)), Chris@0: SLOT(considerSeek(void *, unsigned long, bool))); Chris@0: Chris@0: connect(this, Chris@0: SIGNAL(zoomLevelChanged(void *, unsigned long, bool)), Chris@0: SLOT(considerZoomChange(void *, unsigned long, bool))); Chris@0: } Chris@0: Chris@0: unsigned long Chris@0: ViewManager::getGlobalCentreFrame() const Chris@0: { Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: std::cout << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << std::endl; Chris@0: #endif Chris@0: return m_globalCentreFrame; Chris@0: } Chris@0: Chris@0: unsigned long Chris@0: ViewManager::getGlobalZoom() const Chris@0: { Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl; Chris@0: #endif Chris@0: return m_globalZoom; Chris@0: } Chris@0: Chris@8: bool Chris@8: ViewManager::haveInProgressSelection() const Chris@8: { Chris@8: return !m_inProgressSelection.isEmpty(); Chris@8: } Chris@8: Chris@8: const Selection & Chris@8: ViewManager::getInProgressSelection(bool &exclusive) const Chris@8: { Chris@8: exclusive = m_inProgressExclusive; Chris@8: return m_inProgressSelection; Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::setInProgressSelection(const Selection &selection, bool exclusive) Chris@8: { Chris@8: m_inProgressExclusive = exclusive; Chris@8: m_inProgressSelection = selection; Chris@8: if (exclusive) clearSelections(); Chris@8: emit selectionChanged(); Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::clearInProgressSelection() Chris@8: { Chris@8: m_inProgressSelection = Selection(); Chris@8: emit selectionChanged(); Chris@8: } Chris@8: Chris@8: const ViewManager::SelectionList & Chris@8: ViewManager::getSelections() const Chris@8: { Chris@8: return m_selections; Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::setSelection(const Selection &selection) Chris@8: { Chris@8: clearSelections(); Chris@8: addSelection(selection); Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::addSelection(const Selection &selection) Chris@8: { Chris@8: m_selections.insert(selection); Chris@8: Chris@8: // Cope with a sitation where the new selection overlaps one or Chris@8: // more existing ones. This is a terribly inefficient way to do Chris@8: // this, but that probably isn't significant in real life. Chris@8: Chris@8: for (SelectionList::iterator i = m_selections.begin(); Chris@8: i != m_selections.end(); ) { Chris@8: Chris@8: SelectionList::iterator j = i; Chris@8: if (++j == m_selections.end()) break; Chris@8: Chris@8: if (i->getEndFrame() >= j->getStartFrame()) { Chris@8: Selection merged(i->getStartFrame(), Chris@8: std::max(i->getEndFrame(), j->getEndFrame())); Chris@8: m_selections.erase(i); Chris@8: m_selections.erase(j); Chris@8: m_selections.insert(merged); Chris@8: i = m_selections.begin(); Chris@8: } else { Chris@8: ++i; Chris@8: } Chris@8: } Chris@8: Chris@8: emit selectionChanged(); Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::removeSelection(const Selection &selection) Chris@8: { Chris@8: //!!! Likewise this needs to cope correctly with the situation Chris@8: //where selection is not one of the original selection set but Chris@8: //simply overlaps one of them (cutting down the original selection Chris@8: //appropriately) Chris@8: Chris@8: m_selections.erase(selection); Chris@8: Chris@8: emit selectionChanged(); Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::clearSelections() Chris@8: { Chris@8: m_selections.clear(); Chris@8: Chris@8: emit selectionChanged(); Chris@8: } Chris@8: Chris@8: void Chris@8: ViewManager::setToolMode(ToolMode mode) Chris@8: { Chris@8: m_toolMode = mode; Chris@8: Chris@8: emit toolModeChanged(); Chris@8: } Chris@8: Chris@0: void Chris@0: ViewManager::setAudioPlaySource(AudioPlaySource *source) Chris@0: { Chris@0: if (!m_playSource) { Chris@0: QTimer::singleShot(100, this, SLOT(checkPlayStatus())); Chris@0: } Chris@0: m_playSource = source; Chris@0: } Chris@0: Chris@0: PlayParameters * Chris@0: ViewManager::getPlayParameters(const Model *model) Chris@0: { Chris@0: if (m_playParameters.find(model) == m_playParameters.end()) { Chris@0: // Give all models the same type of play parameters for the moment Chris@0: m_playParameters[model] = new PlayParameters; Chris@0: } Chris@0: Chris@0: return m_playParameters[model]; Chris@0: } Chris@0: Chris@0: void Chris@0: ViewManager::clearPlayParameters() Chris@0: { Chris@0: while (!m_playParameters.empty()) { Chris@0: delete m_playParameters.begin()->second; Chris@0: m_playParameters.erase(m_playParameters.begin()); Chris@0: } Chris@0: } Chris@0: Chris@0: void Chris@0: ViewManager::checkPlayStatus() Chris@0: { Chris@0: if (m_playSource && m_playSource->isPlaying()) { Chris@0: Chris@0: float left = 0, right = 0; Chris@0: if (m_playSource->getOutputLevels(left, right)) { Chris@0: if (left != m_lastLeft || right != m_lastRight) { Chris@0: emit outputLevelsChanged(left, right); Chris@0: m_lastLeft = left; Chris@0: m_lastRight = right; Chris@0: } Chris@0: } Chris@0: Chris@0: m_globalCentreFrame = m_playSource->getCurrentPlayingFrame(); Chris@0: Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_globalCentreFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl; Chris@0: #endif Chris@0: Chris@0: emit playbackFrameChanged(m_globalCentreFrame); Chris@0: Chris@0: QTimer::singleShot(20, this, SLOT(checkPlayStatus())); Chris@0: Chris@0: } else { Chris@0: Chris@0: QTimer::singleShot(100, this, SLOT(checkPlayStatus())); Chris@0: Chris@0: if (m_lastLeft != 0.0 || m_lastRight != 0.0) { Chris@0: emit outputLevelsChanged(0.0, 0.0); Chris@0: m_lastLeft = 0.0; Chris@0: m_lastRight = 0.0; Chris@0: } Chris@0: Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: // std::cout << "ViewManager::checkPlayStatus: Not playing" << std::endl; Chris@0: #endif Chris@0: } Chris@0: } Chris@0: Chris@8: bool Chris@8: ViewManager::isPlaying() const Chris@8: { Chris@8: return m_playSource && m_playSource->isPlaying(); Chris@8: } Chris@8: Chris@0: void Chris@0: ViewManager::considerSeek(void *p, unsigned long f, bool locked) Chris@0: { Chris@0: if (locked) { Chris@0: m_globalCentreFrame = f; Chris@0: } Chris@0: Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: std::cout << "ViewManager::considerSeek(" << p << ", " << f << ", " << locked << ")" << std::endl; Chris@0: #endif Chris@0: Chris@0: if (p == this || !locked) return; Chris@0: Chris@0: if (m_playSource && m_playSource->isPlaying()) { Chris@0: unsigned long playFrame = m_playSource->getCurrentPlayingFrame(); Chris@0: unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame); Chris@0: if (diff > 20000) { Chris@0: m_playSource->play(f); Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl; Chris@0: #endif Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: void Chris@0: ViewManager::considerZoomChange(void *p, unsigned long z, bool locked) Chris@0: { Chris@0: if (locked) { Chris@0: m_globalZoom = z; Chris@0: } Chris@0: Chris@0: #ifdef DEBUG_VIEW_MANAGER Chris@0: std::cout << "ViewManager::considerZoomChange(" << p << ", " << z << ", " << locked << ")" << std::endl; Chris@0: #endif Chris@0: } Chris@0: Chris@0: #ifdef INCLUDE_MOCFILES Chris@0: #include "ViewManager.moc.cpp" Chris@0: #endif Chris@0: