OSCHandler.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006-2007 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "MainWindow.h"
00017 #include "data/osc/OSCQueue.h"
00018 
00019 #include "layer/WaveformLayer.h"
00020 #include "view/ViewManager.h"
00021 #include "view/Pane.h"
00022 #include "view/PaneStack.h"
00023 #include "data/model/WaveFileModel.h"
00024 #include "base/CommandHistory.h"
00025 #include "audioio/AudioCallbackPlaySource.h"
00026 #include "audioio/AudioCallbackPlayTarget.h"
00027 #include "framework/Document.h"
00028 #include "data/fileio/WavFileWriter.h"
00029 #include "plugin/transform/TransformFactory.h"
00030 #include "widgets/Fader.h"
00031 #include "widgets/AudioDial.h"
00032 
00033 #include <QFileInfo>
00034 
00035 void
00036 MainWindow::handleOSCMessage(const OSCMessage &message)
00037 {
00038     std::cerr << "MainWindow::handleOSCMessage: thread id = " 
00039               << QThread::currentThreadId() << std::endl;
00040 
00041     // This large function should really be abstracted out.
00042 
00043     if (message.getMethod() == "open") {
00044 
00045         if (message.getArgCount() == 1 &&
00046             message.getArg(0).canConvert(QVariant::String)) {
00047             QString path = message.getArg(0).toString();
00048             if (open(path, ReplaceMainModel) != FileOpenSucceeded) {
00049                 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \""
00050                           << path.toStdString() << "\"" << std::endl;
00051             }
00053             // file has been completely decoded...
00054         }
00055 
00056     } else if (message.getMethod() == "openadditional") {
00057 
00058         if (message.getArgCount() == 1 &&
00059             message.getArg(0).canConvert(QVariant::String)) {
00060             QString path = message.getArg(0).toString();
00061             if (open(path, CreateAdditionalModel) != FileOpenSucceeded) {
00062                 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \""
00063                           << path.toStdString() << "\"" << std::endl;
00064             }
00065         }
00066 
00067     } else if (message.getMethod() == "recent" ||
00068                message.getMethod() == "last") {
00069 
00070         int n = 0;
00071         if (message.getMethod() == "recent" &&
00072             message.getArgCount() == 1 &&
00073             message.getArg(0).canConvert(QVariant::Int)) {
00074             n = message.getArg(0).toInt() - 1;
00075         }
00076         std::vector<QString> recent = m_recentFiles.getRecent();
00077         if (n >= 0 && n < int(recent.size())) {
00078             if (open(recent[n], ReplaceMainModel) != FileOpenSucceeded) {
00079                 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \""
00080                           << recent[n].toStdString() << "\"" << std::endl;
00081             }
00082         }
00083 
00084     } else if (message.getMethod() == "save") {
00085 
00086         QString path;
00087         if (message.getArgCount() == 1 &&
00088             message.getArg(0).canConvert(QVariant::String)) {
00089             path = message.getArg(0).toString();
00090             if (QFileInfo(path).exists()) {
00091                 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in save" << std::endl;
00092             } else {
00093                 saveSessionFile(path);
00094             }
00095         }
00096 
00097     } else if (message.getMethod() == "export") {
00098 
00099         QString path;
00100         if (getMainModel()) {
00101             if (message.getArgCount() == 1 &&
00102                 message.getArg(0).canConvert(QVariant::String)) {
00103                 path = message.getArg(0).toString();
00104                 if (QFileInfo(path).exists()) {
00105                     std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in export" << std::endl;
00106                 } else {
00107                     WavFileWriter writer(path,
00108                                          getMainModel()->getSampleRate(),
00109                                          getMainModel()->getChannelCount());
00110                     MultiSelection ms = m_viewManager->getSelection();
00111                     if (!ms.getSelections().empty()) {
00112                         writer.writeModel(getMainModel(), &ms);
00113                     } else {
00114                         writer.writeModel(getMainModel());
00115                     }
00116                 }
00117             }
00118         }
00119 
00120     } else if (message.getMethod() == "jump" ||
00121                message.getMethod() == "play") {
00122 
00123         if (getMainModel()) {
00124 
00125             unsigned long frame = m_viewManager->getPlaybackFrame();
00126             bool selection = false;
00127             bool play = (message.getMethod() == "play");
00128 
00129             if (message.getArgCount() == 1) {
00130 
00131                 if (message.getArg(0).canConvert(QVariant::String) &&
00132                     message.getArg(0).toString() == "selection") {
00133 
00134                     selection = true;
00135 
00136                 } else if (message.getArg(0).canConvert(QVariant::String) &&
00137                            message.getArg(0).toString() == "end") {
00138 
00139                     frame = getMainModel()->getEndFrame();
00140 
00141                 } else if (message.getArg(0).canConvert(QVariant::Double)) {
00142 
00143                     double time = message.getArg(0).toDouble();
00144                     if (time < 0.0) time = 0.0;
00145 
00146                     frame = lrint(time * getMainModel()->getSampleRate());
00147                 }
00148             }
00149 
00150             if (frame > getMainModel()->getEndFrame()) {
00151                 frame = getMainModel()->getEndFrame();
00152             }
00153 
00154             if (play) {
00155                 m_viewManager->setPlaySelectionMode(selection);
00156             } 
00157 
00158             if (selection) {
00159                 MultiSelection::SelectionList sl = m_viewManager->getSelections();
00160                 if (!sl.empty()) {
00161                     frame = sl.begin()->getStartFrame();
00162                 }
00163             }
00164 
00165             m_viewManager->setPlaybackFrame(frame);
00166 
00167             if (play && !m_playSource->isPlaying()) {
00168                 m_playSource->play(frame);
00169             }
00170         }
00171 
00172     } else if (message.getMethod() == "stop") {
00173             
00174         if (m_playSource->isPlaying()) m_playSource->stop();
00175 
00176     } else if (message.getMethod() == "loop") {
00177 
00178         if (message.getArgCount() == 1 &&
00179             message.getArg(0).canConvert(QVariant::String)) {
00180 
00181             QString str = message.getArg(0).toString();
00182             if (str == "on") {
00183                 m_viewManager->setPlayLoopMode(true);
00184             } else if (str == "off") {
00185                 m_viewManager->setPlayLoopMode(false);
00186             }
00187         }
00188 
00189     } else if (message.getMethod() == "solo") {
00190 
00191         if (message.getArgCount() == 1 &&
00192             message.getArg(0).canConvert(QVariant::String)) {
00193 
00194             QString str = message.getArg(0).toString();
00195             if (str == "on") {
00196                 m_viewManager->setPlaySoloMode(true);
00197             } else if (str == "off") {
00198                 m_viewManager->setPlaySoloMode(false);
00199             }
00200         }
00201 
00202     } else if (message.getMethod() == "select" ||
00203                message.getMethod() == "addselect") {
00204 
00205         if (getMainModel()) {
00206 
00207             int f0 = getMainModel()->getStartFrame();
00208             int f1 = getMainModel()->getEndFrame();
00209 
00210             bool done = false;
00211 
00212             if (message.getArgCount() == 2 &&
00213                 message.getArg(0).canConvert(QVariant::Double) &&
00214                 message.getArg(1).canConvert(QVariant::Double)) {
00215                 
00216                 double t0 = message.getArg(0).toDouble();
00217                 double t1 = message.getArg(1).toDouble();
00218                 if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; }
00219                 if (t0 < 0.0) t0 = 0.0;
00220                 if (t1 < 0.0) t1 = 0.0;
00221 
00222                 f0 = lrint(t0 * getMainModel()->getSampleRate());
00223                 f1 = lrint(t1 * getMainModel()->getSampleRate());
00224                 
00225                 Pane *pane = m_paneStack->getCurrentPane();
00226                 Layer *layer = 0;
00227                 if (pane) layer = pane->getSelectedLayer();
00228                 if (layer) {
00229                     size_t resolution;
00230                     layer->snapToFeatureFrame(pane, f0, resolution,
00231                                               Layer::SnapLeft);
00232                     layer->snapToFeatureFrame(pane, f1, resolution,
00233                                               Layer::SnapRight);
00234                 }
00235 
00236             } else if (message.getArgCount() == 1 &&
00237                        message.getArg(0).canConvert(QVariant::String)) {
00238 
00239                 QString str = message.getArg(0).toString();
00240                 if (str == "none") {
00241                     m_viewManager->clearSelections();
00242                     done = true;
00243                 }
00244             }
00245 
00246             if (!done) {
00247                 if (message.getMethod() == "select") {
00248                     m_viewManager->setSelection(Selection(f0, f1));
00249                 } else {
00250                     m_viewManager->addSelection(Selection(f0, f1));
00251                 }
00252             }
00253         }
00254 
00255     } else if (message.getMethod() == "add") {
00256 
00257         if (getMainModel()) {
00258 
00259             if (message.getArgCount() >= 1 &&
00260                 message.getArg(0).canConvert(QVariant::String)) {
00261 
00262                 int channel = -1;
00263                 if (message.getArgCount() == 2 &&
00264                     message.getArg(0).canConvert(QVariant::Int)) {
00265                     channel = message.getArg(0).toInt();
00266                     if (channel < -1 ||
00267                         channel > int(getMainModel()->getChannelCount())) {
00268                         std::cerr << "WARNING: MainWindow::handleOSCMessage: channel "
00269                                   << channel << " out of range" << std::endl;
00270                         channel = -1;
00271                     }
00272                 }
00273 
00274                 QString str = message.getArg(0).toString();
00275                 
00276                 LayerFactory::LayerType type =
00277                     LayerFactory::getInstance()->getLayerTypeForName(str);
00278 
00279                 if (type == LayerFactory::UnknownLayer) {
00280                     std::cerr << "WARNING: MainWindow::handleOSCMessage: unknown layer "
00281                               << "type " << str.toStdString() << std::endl;
00282                 } else {
00283 
00284                     LayerConfiguration configuration(type,
00285                                                      getMainModel(),
00286                                                      channel);
00287                     
00288                     addPane(configuration,
00289                             tr("Add %1 Pane")
00290                             .arg(LayerFactory::getInstance()->
00291                                  getLayerPresentationName(type)));
00292                 }
00293             }
00294         }
00295 
00296     } else if (message.getMethod() == "undo") {
00297 
00298         CommandHistory::getInstance()->undo();
00299 
00300     } else if (message.getMethod() == "redo") {
00301 
00302         CommandHistory::getInstance()->redo();
00303 
00304     } else if (message.getMethod() == "set") {
00305 
00306         if (message.getArgCount() == 2 &&
00307             message.getArg(0).canConvert(QVariant::String) &&
00308             message.getArg(1).canConvert(QVariant::Double)) {
00309 
00310             QString property = message.getArg(0).toString();
00311             float value = (float)message.getArg(1).toDouble();
00312 
00313             if (property == "gain") {
00314                 if (value < 0.0) value = 0.0;
00315                 m_fader->setValue(value);
00316                 if (m_playTarget) m_playTarget->setOutputGain(value);
00317             } else if (property == "speedup") {
00318                 m_playSpeed->setMappedValue(value);
00319             } else if (property == "overlays") {
00320                 if (value < 0.5) {
00321                     m_viewManager->setOverlayMode(ViewManager::NoOverlays);
00322                 } else if (value < 1.5) {
00323                     m_viewManager->setOverlayMode(ViewManager::MinimalOverlays);
00324                 } else if (value < 2.5) {
00325                     m_viewManager->setOverlayMode(ViewManager::StandardOverlays);
00326                 } else {
00327                     m_viewManager->setOverlayMode(ViewManager::AllOverlays);
00328                 }                    
00329             } else if (property == "zoomwheels") {
00330                 m_viewManager->setZoomWheelsEnabled(value > 0.5);
00331             } else if (property == "propertyboxes") {
00332                 bool toggle = ((value < 0.5) !=
00333                                (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks));
00334                 if (toggle) togglePropertyBoxes();
00335             }
00336                 
00337         } else {
00338             PropertyContainer *container = 0;
00339             Pane *pane = m_paneStack->getCurrentPane();
00340             if (pane &&
00341                 message.getArgCount() == 3 &&
00342                 message.getArg(0).canConvert(QVariant::String) &&
00343                 message.getArg(1).canConvert(QVariant::String) &&
00344                 message.getArg(2).canConvert(QVariant::String)) {
00345                 if (message.getArg(0).toString() == "pane") {
00346                     container = pane->getPropertyContainer(0);
00347                 } else if (message.getArg(0).toString() == "layer") {
00348                     container = pane->getSelectedLayer();
00349                 }
00350             }
00351             if (container) {
00352                 QString nameString = message.getArg(1).toString();
00353                 QString valueString = message.getArg(2).toString();
00354                 container->setPropertyWithCommand(nameString, valueString);
00355             }
00356         }
00357 
00358     } else if (message.getMethod() == "setcurrent") {
00359 
00360         int paneIndex = -1, layerIndex = -1;
00361         bool wantLayer = false;
00362 
00363         if (message.getArgCount() >= 1 &&
00364             message.getArg(0).canConvert(QVariant::Int)) {
00365 
00366             paneIndex = message.getArg(0).toInt() - 1;
00367 
00368             if (message.getArgCount() >= 2 &&
00369                 message.getArg(1).canConvert(QVariant::Int)) {
00370                 wantLayer = true;
00371                 layerIndex = message.getArg(1).toInt() - 1;
00372             }
00373         }
00374 
00375         if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) {
00376             Pane *pane = m_paneStack->getPane(paneIndex);
00377             m_paneStack->setCurrentPane(pane);
00378             if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) {
00379                 Layer *layer = pane->getLayer(layerIndex);
00380                 m_paneStack->setCurrentLayer(pane, layer);
00381             } else if (wantLayer && layerIndex == -1) {
00382                 m_paneStack->setCurrentLayer(pane, 0);
00383             }
00384         }
00385 
00386     } else if (message.getMethod() == "delete") {
00387 
00388         if (message.getArgCount() == 1 &&
00389             message.getArg(0).canConvert(QVariant::String)) {
00390             
00391             QString target = message.getArg(0).toString();
00392 
00393             if (target == "pane") {
00394 
00395                 deleteCurrentPane();
00396 
00397             } else if (target == "layer") {
00398 
00399                 deleteCurrentLayer();
00400 
00401             } else {
00402                 
00403                 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown delete target " << target.toStdString() << std::endl;
00404             }
00405         }
00406 
00407     } else if (message.getMethod() == "zoom") {
00408 
00409         if (message.getArgCount() == 1) {
00410             if (message.getArg(0).canConvert(QVariant::String) &&
00411                 message.getArg(0).toString() == "in") {
00412                 zoomIn();
00413             } else if (message.getArg(0).canConvert(QVariant::String) &&
00414                        message.getArg(0).toString() == "out") {
00415                 zoomOut();
00416             } else if (message.getArg(0).canConvert(QVariant::String) &&
00417                        message.getArg(0).toString() == "default") {
00418                 zoomDefault();
00419             } else if (message.getArg(0).canConvert(QVariant::Double)) {
00420                 double level = message.getArg(0).toDouble();
00421                 Pane *currentPane = m_paneStack->getCurrentPane();
00422                 if (level < 1.0) level = 1.0;
00423                 if (currentPane) currentPane->setZoomLevel(lrint(level));
00424             }
00425         }
00426 
00427     } else if (message.getMethod() == "zoomvertical") {
00428 
00429         Pane *pane = m_paneStack->getCurrentPane();
00430         Layer *layer = 0;
00431         if (pane && pane->getLayerCount() > 0) {
00432             layer = pane->getLayer(pane->getLayerCount() - 1);
00433         }
00434         int defaultStep = 0;
00435         int steps = 0;
00436         if (layer) {
00437             steps = layer->getVerticalZoomSteps(defaultStep);
00438             if (message.getArgCount() == 1 && steps > 0) {
00439                 if (message.getArg(0).canConvert(QVariant::String) &&
00440                     message.getArg(0).toString() == "in") {
00441                     int step = layer->getCurrentVerticalZoomStep() + 1;
00442                     if (step < steps) layer->setVerticalZoomStep(step);
00443                 } else if (message.getArg(0).canConvert(QVariant::String) &&
00444                            message.getArg(0).toString() == "out") {
00445                     int step = layer->getCurrentVerticalZoomStep() - 1;
00446                     if (step >= 0) layer->setVerticalZoomStep(step);
00447                 } else if (message.getArg(0).canConvert(QVariant::String) &&
00448                            message.getArg(0).toString() == "default") {
00449                     layer->setVerticalZoomStep(defaultStep);
00450                 }
00451             } else if (message.getArgCount() == 2) {
00452                 if (message.getArg(0).canConvert(QVariant::Double) &&
00453                     message.getArg(1).canConvert(QVariant::Double)) {
00454                     double min = message.getArg(0).toDouble();
00455                     double max = message.getArg(1).toDouble();
00456                     layer->setDisplayExtents(min, max);
00457                 }
00458             }
00459         }
00460 
00461     } else if (message.getMethod() == "quit") {
00462         
00463         m_abandoning = true;
00464         close();
00465 
00466     } else if (message.getMethod() == "resize") {
00467         
00468         if (message.getArgCount() == 2) {
00469 
00470             int width = 0, height = 0;
00471 
00472             if (message.getArg(1).canConvert(QVariant::Int)) {
00473 
00474                 height = message.getArg(1).toInt();
00475 
00476                 if (message.getArg(0).canConvert(QVariant::String) &&
00477                     message.getArg(0).toString() == "pane") {
00478 
00479                     Pane *pane = m_paneStack->getCurrentPane();
00480                     if (pane) pane->resize(pane->width(), height);
00481 
00482                 } else if (message.getArg(0).canConvert(QVariant::Int)) {
00483 
00484                     width = message.getArg(0).toInt();
00485                     resize(width, height);
00486                 }
00487             }
00488         }
00489 
00490     } else if (message.getMethod() == "transform") {
00491 
00492         Pane *pane = m_paneStack->getCurrentPane();
00493 
00494         if (getMainModel() &&
00495             pane &&
00496             message.getArgCount() == 1 &&
00497             message.getArg(0).canConvert(QVariant::String)) {
00498 
00499             TransformId transformId = message.getArg(0).toString();
00500 
00501             Transform transform = TransformFactory::getInstance()->
00502                 getDefaultTransformFor(transformId);
00503             
00504             Layer *newLayer = m_document->createDerivedLayer
00505                 (transform, getMainModel());
00506 
00507             if (newLayer) {
00508                 m_document->addLayerToView(pane, newLayer);
00509                 m_recentTransforms.add(transformId);
00510                 m_paneStack->setCurrentLayer(pane, newLayer);
00511             }
00512         }
00513 
00514     } else {
00515         std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported "
00516                   << "method \"" << message.getMethod().toStdString()
00517                   << "\"" << std::endl;
00518     }
00519             
00520 }

Generated on Wed Feb 20 15:45:27 2008 for SonicVisualiser by  doxygen 1.5.1