changeset 391:5858cc462d0a

* Fix #1628781 changes to layer visibility and mute should use a command * Also use a command for changes to layer playback pan, gain, plugin settings * Refactor PlayParameterRepository to remove dependency on audioio from base * Fix failure to save play parameters for main model in session file
author Chris Cannam
date Thu, 13 Mar 2008 14:06:03 +0000
parents 21e79997e80f
children 183ee2a55fc7
files base/PlayParameterRepository.cpp base/PlayParameterRepository.h base/PlayParameters.cpp base/PlayParameters.h base/base.pro data/fileio/CSVFileReader.h data/model/DenseTimeValueModel.cpp data/model/DenseTimeValueModel.h data/model/Model.cpp data/model/Model.h data/model/NoteModel.h data/model/SparseOneDimensionalModel.h data/model/SparseTimeValueModel.h
diffstat 13 files changed, 267 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/base/PlayParameterRepository.cpp	Thu Mar 13 12:41:20 2008 +0000
+++ b/base/PlayParameterRepository.cpp	Thu Mar 13 14:06:03 2008 +0000
@@ -15,11 +15,7 @@
 
 #include "PlayParameterRepository.h"
 #include "PlayParameters.h"
-
-//!!! shouldn't be including this here -- restructure needed
-
-//!!! should the AudioGenerator actually implement all this stuff itself?  do we even want this class?
-#include "audioio/AudioGenerator.h"
+#include "Playable.h"
 
 #include <iostream>
 
@@ -37,73 +33,71 @@
 }
 
 void
-PlayParameterRepository::addModel(const Model *model)
+PlayParameterRepository::addPlayable(const Playable *playable)
 {
-//    std::cerr << "PlayParameterRepository:addModel " << model <<  std::endl;
+//    std::cerr << "PlayParameterRepository:addPlayable " << playable <<  std::endl;
 
-    if (!getPlayParameters(model)) {
+    if (!getPlayParameters(playable)) {
 
-	// Give all models the same type of play parameters for the
-	// moment, provided they can be played at all
+	// Give all playables the same type of play parameters for the
+	// moment
 
-	if (AudioGenerator::canPlay(model)) {
+//	    std::cerr << "PlayParameterRepository: Adding play parameters for " << playable << std::endl;
 
-//	    std::cerr << "PlayParameterRepository: Adding play parameters for " << model << std::endl;
+        PlayParameters *params = new PlayParameters;
+        m_playParameters[playable] = params;
 
-            PlayParameters *params = new PlayParameters;
-	    m_playParameters[model] = params;
+        params->setPlayPluginId
+            (playable->getDefaultPlayPluginId());
+        
+        params->setPlayPluginConfiguration
+            (playable->getDefaultPlayPluginConfiguration());
+        
+        connect(params, SIGNAL(playParametersChanged()),
+                this, SLOT(playParametersChanged()));
+        
+        connect(params, SIGNAL(playPluginIdChanged(QString)),
+                this, SLOT(playPluginIdChanged(QString)));
 
-            params->setPlayPluginId
-                (AudioGenerator::getDefaultPlayPluginId(model));
+        connect(params, SIGNAL(playPluginConfigurationChanged(QString)),
+                this, SLOT(playPluginConfigurationChanged(QString)));
+        
+//            std::cerr << "Connected play parameters " << params << " for playable "
+//                      << playable << " to this " << this << std::endl;
 
-            params->setPlayPluginConfiguration
-                (AudioGenerator::getDefaultPlayPluginConfiguration(model));
-
-	    connect(params, SIGNAL(playParametersChanged()),
-		    this, SLOT(playParametersChanged()));
-
-	    connect(params, SIGNAL(playPluginIdChanged(QString)),
-		    this, SLOT(playPluginIdChanged(QString)));
-
-	    connect(params, SIGNAL(playPluginConfigurationChanged(QString)),
-		    this, SLOT(playPluginConfigurationChanged(QString)));
-
-//            std::cerr << "Connected play parameters " << params << " for model "
-//                      << model << " to this " << this << std::endl;
-
-	} else {
-
-//	    std::cerr << "PlayParameterRepository: Model " << model << " not playable" <<  std::endl;
-	}	    
     }
 }    
 
 void
-PlayParameterRepository::removeModel(const Model *model)
+PlayParameterRepository::removePlayable(const Playable *playable)
 {
-    delete m_playParameters[model];
-    m_playParameters.erase(model);
+    if (m_playParameters.find(playable) == m_playParameters.end()) {
+        std::cerr << "WARNING: PlayParameterRepository::removePlayable: unknown playable " << playable << std::endl;
+        return;
+    }
+    delete m_playParameters[playable];
+    m_playParameters.erase(playable);
 }
 
 void
-PlayParameterRepository::copyParameters(const Model *from, const Model *to)
+PlayParameterRepository::copyParameters(const Playable *from, const Playable *to)
 {
     if (!getPlayParameters(from)) {
-        std::cerr << "ERROR: PlayParameterRepository::copyParameters: source model unknown" << std::endl;
+        std::cerr << "ERROR: PlayParameterRepository::copyParameters: source playable unknown" << std::endl;
         return;
     }
     if (!getPlayParameters(to)) {
-        std::cerr << "WARNING: PlayParameterRepository::copyParameters: target model unknown, adding it now" << std::endl;
-        addModel(to);
+        std::cerr << "WARNING: PlayParameterRepository::copyParameters: target playable unknown, adding it now" << std::endl;
+        addPlayable(to);
     }
     getPlayParameters(to)->copyFrom(getPlayParameters(from));
 }
 
 PlayParameters *
-PlayParameterRepository::getPlayParameters(const Model *model) 
+PlayParameterRepository::getPlayParameters(const Playable *playable) 
 {
-    if (m_playParameters.find(model) == m_playParameters.end()) return 0;
-    return m_playParameters.find(model)->second;
+    if (m_playParameters.find(playable) == m_playParameters.end()) return 0;
+    return m_playParameters.find(playable)->second;
 }
 
 void
@@ -117,7 +111,7 @@
 PlayParameterRepository::playPluginIdChanged(QString id)
 {
     PlayParameters *params = dynamic_cast<PlayParameters *>(sender());
-    for (ModelParameterMap::iterator i = m_playParameters.begin();
+    for (PlayableParameterMap::iterator i = m_playParameters.begin();
          i != m_playParameters.end(); ++i) {
         if (i->second == params) {
             emit playPluginIdChanged(i->first, id);
@@ -131,7 +125,7 @@
 {
     PlayParameters *params = dynamic_cast<PlayParameters *>(sender());
 //    std::cerr << "PlayParameterRepository::playPluginConfigurationChanged" << std::endl;
-    for (ModelParameterMap::iterator i = m_playParameters.begin();
+    for (PlayableParameterMap::iterator i = m_playParameters.begin();
          i != m_playParameters.end(); ++i) {
         if (i->second == params) {
             emit playPluginConfigurationChanged(i->first, config);
@@ -150,3 +144,95 @@
     }
 }
 
+PlayParameterRepository::EditCommand::EditCommand(PlayParameters *params) :
+    m_params(params)
+{
+    m_from.copyFrom(m_params);
+    m_to.copyFrom(m_params);
+}
+
+void
+PlayParameterRepository::EditCommand::setPlayMuted(bool muted)
+{
+    m_to.setPlayMuted(muted);
+}
+
+void
+PlayParameterRepository::EditCommand::setPlayAudible(bool audible)
+{
+    m_to.setPlayAudible(audible);
+}
+
+void
+PlayParameterRepository::EditCommand::setPlayPan(float pan)
+{
+    m_to.setPlayPan(pan);
+}
+
+void
+PlayParameterRepository::EditCommand::setPlayGain(float gain)
+{
+    m_to.setPlayGain(gain);
+}
+
+void
+PlayParameterRepository::EditCommand::setPlayPluginId(QString id)
+{
+    m_to.setPlayPluginId(id);
+}
+
+void
+PlayParameterRepository::EditCommand::setPlayPluginConfiguration(QString conf)
+{
+    m_to.setPlayPluginConfiguration(conf);
+}
+
+void
+PlayParameterRepository::EditCommand::execute()
+{
+    m_params->copyFrom(&m_to);
+}
+
+void
+PlayParameterRepository::EditCommand::unexecute()
+{
+    m_params->copyFrom(&m_from);
+}
+    
+QString
+PlayParameterRepository::EditCommand::getName() const
+{
+    QString name;
+    QString multiname = tr("Adjust Playback Parameters");
+
+    int changed = 0;
+
+    if (m_to.isPlayAudible() != m_from.isPlayAudible()) {
+        name = tr("Change Playback Mute State");
+        if (++changed > 1) return multiname;
+    }
+
+    if (m_to.getPlayGain() != m_from.getPlayGain()) {
+        name = tr("Change Playback Gain");
+        if (++changed > 1) return multiname;
+    }
+
+    if (m_to.getPlayPan() != m_from.getPlayPan()) {
+        name = tr("Change Playback Pan");
+        if (++changed > 1) return multiname;
+    }
+
+    if (m_to.getPlayPluginId() != m_from.getPlayPluginId()) {
+        name = tr("Change Playback Plugin");
+        if (++changed > 1) return multiname;
+    }
+
+    if (m_to.getPlayPluginConfiguration() != m_from.getPlayPluginConfiguration()) {
+        name = tr("Configure Playback Plugin");
+        if (++changed > 1) return multiname;
+    }
+
+    if (name == "") return multiname;
+    return name;
+}
+
--- a/base/PlayParameterRepository.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/base/PlayParameterRepository.h	Thu Mar 13 14:06:03 2008 +0000
@@ -16,12 +16,15 @@
 #ifndef _PLAY_PARAMETER_REPOSITORY_H_
 #define _PLAY_PARAMETER_REPOSITORY_H_
 
-class PlayParameters;
-class Model;
+#include "PlayParameters.h"
+#include "Command.h"
+
+class Playable;
 
 #include <map>
 
 #include <QObject>
+#include <QString>
 
 class PlayParameterRepository : public QObject
 {
@@ -32,18 +35,38 @@
 
     virtual ~PlayParameterRepository();
 
-    void addModel(const Model *model);
-    void removeModel(const Model *model);
-    void copyParameters(const Model *from, const Model *to);
+    void addPlayable(const Playable *playable);
+    void removePlayable(const Playable *playable);
+    void copyParameters(const Playable *from, const Playable *to);
 
-    PlayParameters *getPlayParameters(const Model *model);
+    PlayParameters *getPlayParameters(const Playable *playable);
 
     void clear();
 
+    class EditCommand : public Command
+    {
+    public:
+        EditCommand(PlayParameters *params);
+        void setPlayMuted(bool);
+        void setPlayAudible(bool);
+        void setPlayPan(float);
+        void setPlayGain(float);
+        void setPlayPluginId(QString);
+        void setPlayPluginConfiguration(QString);
+        void execute();
+        void unexecute();
+        QString getName() const;
+
+    protected:
+        PlayParameters *m_params;
+        PlayParameters m_from;
+        PlayParameters m_to;
+    };
+
 signals:
     void playParametersChanged(PlayParameters *);
-    void playPluginIdChanged(const Model *, QString);
-    void playPluginConfigurationChanged(const Model *, QString);
+    void playPluginIdChanged(const Playable *, QString);
+    void playPluginConfigurationChanged(const Playable *, QString);
 
 protected slots:
     void playParametersChanged();
@@ -51,8 +74,8 @@
     void playPluginConfigurationChanged(QString);
 
 protected:
-    typedef std::map<const Model *, PlayParameters *> ModelParameterMap;
-    ModelParameterMap m_playParameters;
+    typedef std::map<const Playable *, PlayParameters *> PlayableParameterMap;
+    PlayableParameterMap m_playParameters;
 
     static PlayParameterRepository *m_instance;
 };
--- a/base/PlayParameters.cpp	Thu Mar 13 12:41:20 2008 +0000
+++ b/base/PlayParameters.cpp	Thu Mar 13 14:06:03 2008 +0000
@@ -22,11 +22,40 @@
 void
 PlayParameters::copyFrom(const PlayParameters *pp)
 {
-    m_playMuted = pp->isPlayMuted();
-    m_playPan = pp->getPlayPan();
-    m_playGain = pp->getPlayGain();
-    m_playPluginId = pp->getPlayPluginId();
-    m_playPluginConfiguration = pp->getPlayPluginConfiguration();
+    bool changed = false;
+
+    if (m_playMuted != pp->isPlayMuted()) {
+        m_playMuted = pp->isPlayMuted();
+        emit playMutedChanged(m_playMuted);
+        emit playAudibleChanged(!m_playMuted);
+        changed = true;
+    }
+
+    if (m_playPan != pp->getPlayPan()) {
+        m_playPan = pp->getPlayPan();
+        emit playPanChanged(m_playPan);
+        changed = true;
+    }
+
+    if (m_playGain != pp->getPlayGain()) {
+        m_playGain = pp->getPlayGain();
+        emit playGainChanged(m_playGain);
+        changed = true;
+    }
+
+    if (m_playPluginId != pp->getPlayPluginId()) {
+        m_playPluginId = pp->getPlayPluginId();
+        emit playPluginIdChanged(m_playPluginId);
+        changed = true;
+    }
+    
+    if (m_playPluginConfiguration != pp->getPlayPluginConfiguration()) {
+        m_playPluginConfiguration = pp->getPlayPluginConfiguration();
+        emit playPluginConfigurationChanged(m_playPluginConfiguration);
+        changed = true;
+    }
+
+    if (changed) emit playParametersChanged();
 }
 
 void
@@ -53,10 +82,12 @@
 PlayParameters::setPlayMuted(bool muted)
 {
 //    std::cerr << "PlayParameters: setPlayMuted(" << muted << ")" << std::endl;
-    m_playMuted = muted;
-    emit playMutedChanged(muted);
-    emit playAudibleChanged(!muted);
-    emit playParametersChanged();
+    if (m_playMuted != muted) {
+        m_playMuted = muted;
+        emit playMutedChanged(muted);
+        emit playAudibleChanged(!muted);
+        emit playParametersChanged();
+    }
 }
 
 void
--- a/base/PlayParameters.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/base/PlayParameters.h	Thu Mar 13 14:06:03 2008 +0000
@@ -28,6 +28,7 @@
     PlayParameters() : m_playMuted(false), m_playPan(0.0), m_playGain(1.0) { }
 
     virtual bool isPlayMuted() const { return m_playMuted; }
+    virtual bool isPlayAudible() const { return !m_playMuted; }
     virtual float getPlayPan() const { return m_playPan; } // -1.0 -> 1.0
     virtual float getPlayGain() const { return m_playGain; }
 
--- a/base/base.pro	Thu Mar 13 12:41:20 2008 +0000
+++ b/base/base.pro	Thu Mar 13 14:06:03 2008 +0000
@@ -21,6 +21,7 @@
            Exceptions.h \
            LogRange.h \
            Pitch.h \
+           Playable.h \
            PlayParameterRepository.h \
            PlayParameters.h \
            Preferences.h \
--- a/data/fileio/CSVFileReader.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/fileio/CSVFileReader.h	Thu Mar 13 14:06:03 2008 +0000
@@ -78,6 +78,8 @@
     size_t     getSampleRate()  const { return m_sampleRate;  }
     size_t     getWindowSize()  const { return m_windowSize;  }
 
+    QString::SplitBehavior getSplitBehaviour() const { return m_behaviour; }
+
 protected slots:
     void modelTypeChanged(int type);
     void timingTypeChanged(int type);
@@ -91,6 +93,8 @@
     QString    m_separator;
     size_t     m_sampleRate;
     size_t     m_windowSize;
+
+    QString::SplitBehavior m_behaviour;
     
     QList<QStringList> m_example;
     int m_maxExampleCols;
--- a/data/model/DenseTimeValueModel.cpp	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/DenseTimeValueModel.cpp	Thu Mar 13 14:06:03 2008 +0000
@@ -18,6 +18,11 @@
 
 DenseTimeValueModel::DenseTimeValueModel()
 {
-    PlayParameterRepository::getInstance()->addModel(this);
+    PlayParameterRepository::getInstance()->addPlayable(this);
+}
+
+DenseTimeValueModel::~DenseTimeValueModel()
+{
+    PlayParameterRepository::getInstance()->removePlayable(this);
 }
 	
--- a/data/model/DenseTimeValueModel.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/DenseTimeValueModel.h	Thu Mar 13 14:06:03 2008 +0000
@@ -32,6 +32,8 @@
 public:
     DenseTimeValueModel();
 
+    virtual ~DenseTimeValueModel();
+
     /**
      * Return the minimum possible value found in this model type.
      * (That is, the minimum that would be valid, not the minimum
@@ -80,6 +82,10 @@
                            size_t start, size_t count,
                            float **buffers) const = 0;
 
+    virtual bool canPlay() const { return true; }
+    virtual QString getDefaultPlayPluginId() const { return ""; }
+    virtual QString getDefaultPlayPluginConfiguration() const { return ""; }
+
     QString getTypeName() const { return tr("Dense Time-Value"); }
 };
 
--- a/data/model/Model.cpp	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/Model.cpp	Thu Mar 13 14:06:03 2008 +0000
@@ -15,7 +15,6 @@
 
 #include "Model.h"
 #include "AlignmentModel.h"
-#include "base/PlayParameterRepository.h"
 
 #include <QTextStream>
 
@@ -37,12 +36,6 @@
         m_alignment->aboutToDelete();
         delete m_alignment;
     }
-
-    // Subclasses have to handle adding themselves to the repository,
-    // if they want to be played.  We can't do it from here because
-    // the repository would be unable to tell whether we were playable
-    // or not (because dynamic_cast won't work from the base class ctor)
-    PlayParameterRepository::getInstance()->removeModel(this);
 }
 
 void
--- a/data/model/Model.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/Model.h	Thu Mar 13 14:06:03 2008 +0000
@@ -20,6 +20,7 @@
 #include <QObject>
 
 #include "base/XmlExportable.h"
+#include "base/Playable.h"
 
 typedef std::vector<float> SampleBlock;
 
@@ -32,7 +33,8 @@
  */
 
 class Model : public QObject,
-	      public XmlExportable
+	      public XmlExportable,
+              public Playable
 {
     Q_OBJECT
 
--- a/data/model/NoteModel.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/NoteModel.h	Thu Mar 13 14:06:03 2008 +0000
@@ -17,8 +17,8 @@
 #define _NOTE_MODEL_H_
 
 #include "SparseValueModel.h"
+#include "base/RealTime.h"
 #include "base/PlayParameterRepository.h"
-#include "base/RealTime.h"
 
 /**
  * Note type for use in a SparseModel or SparseValueModel.  All we
@@ -95,7 +95,7 @@
 			       notifyOnAdd),
 	m_valueQuantization(0)
     {
-	PlayParameterRepository::getInstance()->addModel(this);
+	PlayParameterRepository::getInstance()->addPlayable(this);
     }
 
     NoteModel(size_t sampleRate, size_t resolution,
@@ -106,7 +106,12 @@
 			       notifyOnAdd),
 	m_valueQuantization(0)
     {
-	PlayParameterRepository::getInstance()->addModel(this);
+	PlayParameterRepository::getInstance()->addPlayable(this);
+    }
+
+    virtual ~NoteModel()
+    {
+        PlayParameterRepository::getInstance()->removePlayable(this);
     }
 
     float getValueQuantization() const { return m_valueQuantization; }
@@ -129,6 +134,18 @@
 
     QString getTypeName() const { return tr("Note"); }
 
+    virtual bool canPlay() const { return true; }
+
+    virtual QString getDefaultPlayPluginId() const
+    {
+        return "dssi:_builtin:sample_player";
+    }
+
+    virtual QString getDefaultPlayPluginConfiguration() const
+    {
+        return "<plugin program=\"piano\"/>";
+    }
+
     virtual void toXml(QTextStream &out,
                        QString indent = "",
                        QString extraAttributes = "") const
--- a/data/model/SparseOneDimensionalModel.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/SparseOneDimensionalModel.h	Thu Mar 13 14:06:03 2008 +0000
@@ -75,7 +75,24 @@
 			      bool notifyOnAdd = true) :
 	SparseModel<OneDimensionalPoint>(sampleRate, resolution, notifyOnAdd)
     {
-	PlayParameterRepository::getInstance()->addModel(this);
+	PlayParameterRepository::getInstance()->addPlayable(this);
+    }
+
+    virtual ~SparseOneDimensionalModel()
+    {
+        PlayParameterRepository::getInstance()->removePlayable(this);
+    }
+
+    virtual bool canPlay() const { return true; }
+
+    virtual QString getDefaultPlayPluginId() const
+    {
+        return "dssi:_builtin:sample_player";
+    }
+
+    virtual QString getDefaultPlayPluginConfiguration() const
+    {
+        return "<plugin program=\"tap\"/>";
     }
 
     int getIndexOf(const Point &point) {
--- a/data/model/SparseTimeValueModel.h	Thu Mar 13 12:41:20 2008 +0000
+++ b/data/model/SparseTimeValueModel.h	Thu Mar 13 14:06:03 2008 +0000
@@ -83,7 +83,7 @@
 	SparseValueModel<TimeValuePoint>(sampleRate, resolution,
 					 notifyOnAdd)
     {
-	PlayParameterRepository::getInstance()->addModel(this);
+        // not yet playable
     }
 
     SparseTimeValueModel(size_t sampleRate, size_t resolution,
@@ -93,7 +93,7 @@
 					 valueMinimum, valueMaximum,
 					 notifyOnAdd)
     {
-	PlayParameterRepository::getInstance()->addModel(this);
+        // not yet playable
     }
 
     QString getTypeName() const { return tr("Sparse Time-Value"); }