changeset 27:61259228d029

* More to do with passing around step/blocksize etc from plugin dialog to plugins. Still some puzzling unresolved details.
author Chris Cannam
date Tue, 19 Sep 2006 14:37:06 +0000
parents d88d117e0c34
children b5f55ea61bb8
files document/Document.cpp document/Document.h main/MainWindow.cpp sv.pro transform/FeatureExtractionPluginTransform.cpp transform/FeatureExtractionPluginTransform.h transform/PluginTransform.cpp transform/PluginTransform.h transform/RealTimePluginTransform.cpp transform/RealTimePluginTransform.h transform/TransformFactory.cpp transform/TransformFactory.h
diffstat 12 files changed, 250 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/document/Document.cpp	Mon Sep 18 16:43:17 2006 +0000
+++ b/document/Document.cpp	Tue Sep 19 14:37:06 2006 +0000
@@ -161,11 +161,11 @@
 Layer *
 Document::createDerivedLayer(TransformName transform,
                              Model *inputModel, 
-                             int channel,
+                             const PluginTransform::ExecutionContext &context,
                              QString configurationXml)
 {
     Model *newModel = createModelForTransform(transform, inputModel,
-                                              channel, configurationXml);
+                                              context, configurationXml);
     if (!newModel) {
         // error already printed to stderr by createModelForTransform
         emit modelGenerationFailed(transform);
@@ -252,12 +252,12 @@
 	    // model: regenerate it.
 	    
 	    TransformName transform = m_models[model].transform;
-            int channel = m_models[model].channel;
+            PluginTransform::ExecutionContext context = m_models[model].context;
 	    
 	    Model *replacementModel =
                 createModelForTransform(transform,
                                         m_mainModel,
-                                        channel,
+                                        context,
                                         m_models[model].configurationXml);
 	    
 	    if (!replacementModel) {
@@ -288,7 +288,7 @@
 void
 Document::addDerivedModel(TransformName transform,
                           Model *inputModel,
-                          int channel,
+                          const PluginTransform::ExecutionContext &context,
                           Model *outputModelToAdd,
                           QString configurationXml)
 {
@@ -301,7 +301,7 @@
     ModelRecord rec;
     rec.source = inputModel;
     rec.transform = transform;
-    rec.channel = channel;
+    rec.context = context;
     rec.configurationXml = configurationXml;
     rec.refcount = 0;
 
@@ -323,7 +323,6 @@
     ModelRecord rec;
     rec.source = 0;
     rec.transform = "";
-    rec.channel = -1;
     rec.refcount = 0;
 
     m_models[model] = rec;
@@ -334,7 +333,7 @@
 Model *
 Document::createModelForTransform(TransformName transform,
                                   Model *inputModel,
-                                  int channel,
+                                  const PluginTransform::ExecutionContext &context,
                                   QString configurationXml)
 {
     Model *model = 0;
@@ -342,19 +341,19 @@
     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
 	if (i->second.transform == transform &&
 	    i->second.source == inputModel && 
-            i->second.channel == channel &&
+            i->second.context == context &&
             i->second.configurationXml == configurationXml) {
 	    return i->first;
 	}
     }
 
     model = TransformFactory::getInstance()->transform
-	(transform, inputModel, channel, configurationXml);
+	(transform, inputModel, context, configurationXml);
 
     if (!model) {
 	std::cerr << "WARNING: Document::createModelForTransform: no output model for transform " << transform.toStdString() << std::endl;
     } else {
-	addDerivedModel(transform, inputModel, channel, model, configurationXml);
+	addDerivedModel(transform, inputModel, context, model, configurationXml);
     }
 
     return model;
@@ -696,11 +695,13 @@
 
 	if (rec.source && rec.transform != "") {
 	    
+            //!!! stream the rest of the execution context in both directions (i.e. not just channel)
+
 	    out << indent;
 	    out << QString("  <derivation source=\"%1\" model=\"%2\" channel=\"%3\" transform=\"%4\"")
 		.arg(XmlExportable::getObjectExportId(rec.source))
 		.arg(XmlExportable::getObjectExportId(i->first))
-                .arg(rec.channel)
+                .arg(rec.context.channel)
 		.arg(XmlExportable::encodeEntities(rec.transform));
 
             if (rec.configurationXml != "") {
--- a/document/Document.h	Mon Sep 18 16:43:17 2006 +0000
+++ b/document/Document.h	Tue Sep 19 14:37:06 2006 +0000
@@ -18,6 +18,7 @@
 
 #include "layer/LayerFactory.h"
 #include "transform/Transform.h"
+#include "transform/PluginTransform.h"
 #include "base/Command.h"
 
 #include <map>
@@ -113,7 +114,7 @@
      */
     Layer *createDerivedLayer(TransformName,
                               Model *inputModel, 
-                              int inputChannel, // -1 -> all
+                              const PluginTransform::ExecutionContext &context,
                               QString configurationXml);
 
     /**
@@ -136,7 +137,7 @@
      */
     void addDerivedModel(TransformName,
                          Model *inputModel,
-                         int inputChannel, // -1 -> all
+                         const PluginTransform::ExecutionContext &context,
                          Model *outputModelToAdd,
                          QString configurationXml);
 
@@ -194,7 +195,7 @@
 protected:
     Model *createModelForTransform(TransformName transform,
                                    Model *inputModel,
-                                   int channel,
+                                   const PluginTransform::ExecutionContext &context,
                                    QString configurationXml);
     void releaseModel(Model *model);
 
@@ -230,7 +231,7 @@
 	// since being generated from it.
 	const Model *source;
 	TransformName transform;
-        int channel;
+        PluginTransform::ExecutionContext context;
         QString configurationXml;
 
 	// Count of the number of layers using this model.
--- a/main/MainWindow.cpp	Mon Sep 18 16:43:17 2006 +0000
+++ b/main/MainWindow.cpp	Tue Sep 19 14:37:06 2006 +0000
@@ -2790,6 +2790,9 @@
 
     bool needConfiguration = false;
 
+    //!!! actually we should probably always ask for configuration
+    //because we need the execution context
+
     if (factory->isTransformConfigurable(transform)) {
         needConfiguration = true;
     } else {
@@ -2803,21 +2806,23 @@
         }
     }
 
+    PluginTransform::ExecutionContext context(channel);
+
     if (needConfiguration) {
         bool ok =
             factory->getConfigurationForTransform
-            (transform, m_document->getMainModel(), channel, configurationXml);
+            (transform, m_document->getMainModel(), context, configurationXml);
         if (!ok) return;
     }
 
     Layer *newLayer = m_document->createDerivedLayer(transform,
                                                      m_document->getMainModel(),
-                                                     channel,
+                                                     context,
                                                      configurationXml);
 
     if (newLayer) {
         m_document->addLayerToView(pane, newLayer);
-        m_document->setChannel(newLayer, channel);
+        m_document->setChannel(newLayer, context.channel);
     }
 
     updateMenuStates();
--- a/sv.pro	Mon Sep 18 16:43:17 2006 +0000
+++ b/sv.pro	Tue Sep 19 14:37:06 2006 +0000
@@ -42,6 +42,7 @@
            main/MainWindow.h \
            main/PreferencesDialog.h \
            transform/FeatureExtractionPluginTransform.h \
+           transform/PluginTransform.h \
            transform/RealTimePluginTransform.h \
            transform/Transform.h \
            transform/TransformFactory.h
@@ -59,6 +60,7 @@
            main/MainWindow.cpp \
            main/PreferencesDialog.cpp \
            transform/FeatureExtractionPluginTransform.cpp \
+           transform/PluginTransform.cpp \
            transform/RealTimePluginTransform.cpp \
            transform/Transform.cpp \
            transform/TransformFactory.cpp
--- a/transform/FeatureExtractionPluginTransform.cpp	Mon Sep 18 16:43:17 2006 +0000
+++ b/transform/FeatureExtractionPluginTransform.cpp	Tue Sep 19 14:37:06 2006 +0000
@@ -34,18 +34,11 @@
 
 FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel,
 								   QString pluginId,
-                                                                   int channel,
+                                                                   const ExecutionContext &context,
                                                                    QString configurationXml,
-								   QString outputName,
-                                                                   size_t stepSize,
-                                                                   size_t blockSize,
-                                                                   WindowType windowType) :
-    Transform(inputModel),
+								   QString outputName) :
+    PluginTransform(inputModel, context),
     m_plugin(0),
-    m_channel(channel),
-    m_stepSize(0),
-    m_blockSize(0),
-    m_windowType(windowType),
     m_descriptor(0),
     m_outputFeatureNo(0)
 {
@@ -72,18 +65,6 @@
         PluginXml(m_plugin).setParametersFromXml(configurationXml);
     }
 
-    if (m_blockSize == 0) m_blockSize = m_plugin->getPreferredBlockSize();
-    if (m_stepSize == 0) m_stepSize = m_plugin->getPreferredStepSize();
-
-    if (m_blockSize == 0) m_blockSize = 1024;
-    if (m_stepSize == 0) {
-        if (m_plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) {
-            m_stepSize = m_blockSize / 2;
-        } else {
-            m_stepSize = m_blockSize;
-        }
-    }
-
     DenseTimeValueModel *input = getInput();
     if (!input) return;
 
@@ -100,7 +81,13 @@
 	return;
     }
 
-    if (!m_plugin->initialise(channelCount, m_stepSize, m_blockSize)) {
+    std::cerr << "Initialising feature extraction plugin with channels = "
+              << channelCount << ", step = " << m_context.stepSize
+              << ", block = " << m_context.blockSize << std::endl;
+
+    if (!m_plugin->initialise(channelCount,
+                              m_context.stepSize,
+                              m_context.blockSize)) {
         std::cerr << "FeatureExtractionPluginTransform: Plugin "
                   << m_plugin->getName() << " failed to initialise!" << std::endl;
         return;
@@ -160,7 +147,7 @@
 	break;
 
     case Vamp::Plugin::OutputDescriptor::OneSamplePerStep:
-	modelResolution = m_stepSize;
+	modelResolution = m_context.stepSize;
 	break;
 
     case Vamp::Plugin::OutputDescriptor::FixedSampleRate:
@@ -248,7 +235,7 @@
 
     float **buffers = new float*[channelCount];
     for (size_t ch = 0; ch < channelCount; ++ch) {
-	buffers[ch] = new float[m_blockSize];
+	buffers[ch] = new float[m_context.blockSize];
     }
 
     bool frequencyDomain = (m_plugin->getInputDomain() ==
@@ -259,11 +246,11 @@
         for (size_t ch = 0; ch < channelCount; ++ch) {
             fftModels.push_back(new FFTModel
                                   (getInput(),
-                                   channelCount == 1 ? m_channel : ch,
-                                   m_windowType,
-                                   m_blockSize,
-                                   m_stepSize,
-                                   m_blockSize,
+                                   channelCount == 1 ? m_context.channel : ch,
+                                   m_context.windowType,
+                                   m_context.blockSize,
+                                   m_context.stepSize,
+                                   m_context.blockSize,
                                    false));
         }
     }
@@ -277,7 +264,7 @@
     while (1) {
 
         if (frequencyDomain) {
-            if (blockFrame - int(m_blockSize)/2 > endFrame) break;
+            if (blockFrame - int(m_context.blockSize)/2 > endFrame) break;
         } else {
             if (blockFrame >= endFrame) break;
         }
@@ -286,21 +273,21 @@
 //		  << blockFrame << std::endl;
 
 	long completion =
-	    (((blockFrame - startFrame) / m_stepSize) * 99) /
-	    (   (endFrame - startFrame) / m_stepSize);
+	    (((blockFrame - startFrame) / m_context.stepSize) * 99) /
+	    (   (endFrame - startFrame) / m_context.stepSize);
 
 	// channelCount is either m_input->channelCount or 1
 
         for (size_t ch = 0; ch < channelCount; ++ch) {
             if (frequencyDomain) {
-                int column = (blockFrame - startFrame) / m_stepSize;
-                for (size_t i = 0; i < m_blockSize/2; ++i) {
+                int column = (blockFrame - startFrame) / m_context.stepSize;
+                for (size_t i = 0; i < m_context.blockSize/2; ++i) {
                     fftModels[ch]->getValuesAt
                         (column, i, buffers[ch][i*2], buffers[ch][i*2+1]);
                 }
 /*!!!
                 float sum = 0.0;
-                for (size_t i = 0; i < m_blockSize/2; ++i) {
+                for (size_t i = 0; i < m_context.blockSize/2; ++i) {
                     sum += buffers[ch][i*2];
                 }
                 if (fabs(sum) < 0.0001) {
@@ -309,7 +296,7 @@
 */
             } else {
                 getFrames(ch, channelCount, 
-                          blockFrame, m_blockSize, buffers[ch]);
+                          blockFrame, m_context.blockSize, buffers[ch]);
             }                
         }
 
@@ -327,7 +314,7 @@
 	    prevCompletion = completion;
 	}
 
-	blockFrame += m_stepSize;
+	blockFrame += m_context.stepSize;
     }
 
     Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures();
@@ -365,7 +352,7 @@
     }
 
     long got = getInput()->getValues
-        ((channelCount == 1 ? m_channel : channel),
+        ((channelCount == 1 ? m_context.channel : channel),
          startFrame, startFrame + size, buffer + offset);
 
     while (got < size) {
@@ -373,7 +360,7 @@
         ++got;
     }
 
-    if (m_channel == -1 && channelCount == 1 &&
+    if (m_context.channel == -1 && channelCount == 1 &&
         getInput()->getChannelCount() > 1) {
         // use mean instead of sum, as plugin input
         int cc = getInput()->getChannelCount();
--- a/transform/FeatureExtractionPluginTransform.h	Mon Sep 18 16:43:17 2006 +0000
+++ b/transform/FeatureExtractionPluginTransform.h	Tue Sep 19 14:37:06 2006 +0000
@@ -16,35 +16,24 @@
 #ifndef _FEATURE_EXTRACTION_PLUGIN_TRANSFORM_H_
 #define _FEATURE_EXTRACTION_PLUGIN_TRANSFORM_H_
 
-#include "Transform.h"
-
-#include "base/Window.h"
-
-#include "vamp-sdk/Plugin.h"
+#include "PluginTransform.h"
 
 class DenseTimeValueModel;
 
-class FeatureExtractionPluginTransform : public Transform
+class FeatureExtractionPluginTransform : public PluginTransform
 {
 public:
     FeatureExtractionPluginTransform(Model *inputModel,
 				     QString plugin,
-                                     int channel,
+                                     const ExecutionContext &context,
                                      QString configurationXml = "",
-				     QString outputName = "",
-                                     size_t stepSize = 0,
-                                     size_t blockSize = 0,
-                                     WindowType windowType = HanningWindow);
+				     QString outputName = "");
     virtual ~FeatureExtractionPluginTransform();
 
 protected:
     virtual void run();
 
     Vamp::Plugin *m_plugin;
-    int m_channel;
-    size_t m_stepSize;
-    size_t m_blockSize;
-    WindowType m_windowType;
     Vamp::Plugin::OutputDescriptor *m_descriptor;
     int m_outputFeatureNo;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/transform/PluginTransform.cpp	Tue Sep 19 14:37:06 2006 +0000
@@ -0,0 +1,93 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+   
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "PluginTransform.h"
+
+PluginTransform::PluginTransform(Model *inputModel,
+				 const ExecutionContext &context) :
+    Transform(inputModel),
+    m_context(context)
+{
+}
+
+PluginTransform::ExecutionContext::ExecutionContext(int _c, size_t _bs) :
+    channel(_c),
+    domain(Vamp::Plugin::TimeDomain),
+    stepSize(_bs ? _bs : 1024),
+    blockSize(_bs ? _bs : 1024),
+    windowType(HanningWindow)
+{
+}
+
+PluginTransform::ExecutionContext::ExecutionContext(int _c, size_t _ss,
+                                                    size_t _bs, WindowType _wt) :
+    channel(_c),
+    domain(Vamp::Plugin::FrequencyDomain),
+    stepSize(_ss ? _ss : (_bs ? _bs / 2 : 512)),
+    blockSize(_bs ? _bs : 1024),
+    windowType(_wt)
+{
+}
+
+PluginTransform::ExecutionContext::ExecutionContext(int _c,
+                                                    const Vamp::PluginBase *_plugin) :
+    channel(_c),
+    domain(Vamp::Plugin::TimeDomain),
+    stepSize(0),
+    blockSize(0),
+    windowType(HanningWindow)
+{
+    makeConsistentWithPlugin(_plugin);
+}
+
+bool
+PluginTransform::ExecutionContext::operator==(const ExecutionContext &c)
+{
+    return (c.channel == channel &&
+            c.domain == domain &&
+            c.stepSize == stepSize &&
+            c.blockSize == blockSize &&
+            c.windowType == windowType);
+}
+
+void
+PluginTransform::ExecutionContext::makeConsistentWithPlugin(const Vamp::PluginBase *_plugin)
+{
+    const Vamp::Plugin *vp = dynamic_cast<const Vamp::Plugin *>(_plugin);
+
+    if (!vp) {
+        domain = Vamp::Plugin::TimeDomain;
+        if (!stepSize) {
+            if (!blockSize) blockSize = 1024;
+            stepSize = blockSize;
+        } else {
+            if (!blockSize) blockSize = stepSize;
+        }
+    } else {
+        domain = vp->getInputDomain();
+        if (!stepSize) stepSize = vp->getPreferredStepSize();
+        if (!blockSize) blockSize = vp->getPreferredBlockSize();
+        if (!blockSize) blockSize = 1024;
+        if (!stepSize) {
+            if (domain == Vamp::Plugin::FrequencyDomain) {
+                stepSize = blockSize/2;
+            } else {
+                stepSize = blockSize;
+            }
+        }
+    }
+}
+    
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/transform/PluginTransform.h	Tue Sep 19 14:37:06 2006 +0000
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+   
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef _PLUGIN_TRANSFORM_H_
+#define _PLUGIN_TRANSFORM_H_
+
+#include "Transform.h"
+
+#include "base/Window.h"
+
+#include "vamp-sdk/Plugin.h"
+
+//!!! should this just move back up to Transform? It is after all used
+//directly in all sorts of generic places, like Document
+
+class PluginTransform : public Transform
+{
+public:
+    class ExecutionContext {
+    public:
+        // Time domain:
+        ExecutionContext(int _c = -1, size_t _bs = 0);
+        
+        // Frequency domain:
+        ExecutionContext(int _c, size_t _ss, size_t _bs, WindowType _wt);
+
+        // From plugin defaults:
+        ExecutionContext(int _c, const Vamp::PluginBase *_plugin);
+
+        bool operator==(const ExecutionContext &);
+
+        void makeConsistentWithPlugin(const Vamp::PluginBase *_plugin);
+
+        int channel;
+        Vamp::Plugin::InputDomain domain;
+        size_t stepSize;
+        size_t blockSize;
+        WindowType windowType;
+    };
+
+protected:
+    PluginTransform(Model *inputModel,
+                    const ExecutionContext &context);
+
+    ExecutionContext m_context;
+};
+
+#endif
--- a/transform/RealTimePluginTransform.cpp	Mon Sep 18 16:43:17 2006 +0000
+++ b/transform/RealTimePluginTransform.cpp	Tue Sep 19 14:37:06 2006 +0000
@@ -28,18 +28,15 @@
 
 RealTimePluginTransform::RealTimePluginTransform(Model *inputModel,
                                                  QString pluginId,
-                                                 int channel,
+                                                 const ExecutionContext &context,
                                                  QString configurationXml,
                                                  QString units,
-                                                 int output,
-                                                 size_t blockSize) :
-    Transform(inputModel),
+                                                 int output) :
+    PluginTransform(inputModel, context),
     m_plugin(0),
-    m_channel(channel),
-    m_outputNo(output),
-    m_blockSize(blockSize)
+    m_outputNo(output)
 {
-    if (!m_blockSize) m_blockSize = 1024;
+    if (!m_context.blockSize) m_context.blockSize = 1024;
 
     std::cerr << "RealTimePluginTransform::RealTimePluginTransform: plugin " << pluginId.toStdString() << ", output " << output << std::endl;
 
@@ -56,7 +53,7 @@
     if (!input) return;
 
     m_plugin = factory->instantiatePlugin(pluginId, 0, 0, m_input->getSampleRate(),
-                                          m_blockSize,
+                                          m_context.blockSize,
                                           input->getChannelCount());
 
     if (!m_plugin) {
@@ -75,7 +72,7 @@
     }
 	
     SparseTimeValueModel *model = new SparseTimeValueModel
-        (input->getSampleRate(), m_blockSize, 0.0, 0.0, false);
+        (input->getSampleRate(), m_context.blockSize, 0.0, 0.0, false);
 
     if (units != "") model->setScaleUnits(units);
 
@@ -111,7 +108,7 @@
 
     size_t sampleRate = input->getSampleRate();
     int channelCount = input->getChannelCount();
-    if (m_channel != -1) channelCount = 1;
+    if (m_context.channel != -1) channelCount = 1;
 
     size_t blockSize = m_plugin->getBufferSize();
 
@@ -135,11 +132,11 @@
 
 	if (channelCount == 1) {
 	    got = input->getValues
-		(m_channel, blockFrame, blockFrame + blockSize, buffers[0]);
+		(m_context.channel, blockFrame, blockFrame + blockSize, buffers[0]);
 	    while (got < blockSize) {
 		buffers[0][got++] = 0.0;
 	    }
-            if (m_channel == -1 && channelCount > 1) {
+            if (m_context.channel == -1 && channelCount > 1) {
                 // use mean instead of sum, as plugin input
                 for (size_t i = 0; i < got; ++i) {
                     buffers[0][i] /= channelCount;
--- a/transform/RealTimePluginTransform.h	Mon Sep 18 16:43:17 2006 +0000
+++ b/transform/RealTimePluginTransform.h	Tue Sep 19 14:37:06 2006 +0000
@@ -16,30 +16,27 @@
 #ifndef _REAL_TIME_PLUGIN_TRANSFORM_H_
 #define _REAL_TIME_PLUGIN_TRANSFORM_H_
 
-#include "Transform.h"
+#include "PluginTransform.h"
 #include "plugin/RealTimePluginInstance.h"
 
 class DenseTimeValueModel;
 
-class RealTimePluginTransform : public Transform
+class RealTimePluginTransform : public PluginTransform
 {
 public:
     RealTimePluginTransform(Model *inputModel,
 			    QString plugin,
-                            int channel,
+                            const ExecutionContext &context,
 			    QString configurationXml = "",
                             QString units = "",
-			    int output = 0,
-                            size_t blockSize = 0);
+			    int output = 0);
     virtual ~RealTimePluginTransform();
 
 protected:
     virtual void run();
 
     RealTimePluginInstance *m_plugin;
-    int m_channel;
     int m_outputNo;
-    size_t m_blockSize;
 
     // just casts
     DenseTimeValueModel *getInput();
--- a/transform/TransformFactory.cpp	Mon Sep 18 16:43:17 2006 +0000
+++ b/transform/TransformFactory.cpp	Tue Sep 19 14:37:06 2006 +0000
@@ -350,7 +350,7 @@
 bool
 TransformFactory::getConfigurationForTransform(TransformName name,
                                                Model *inputModel,
-                                               int &channel,
+                                               PluginTransform::ExecutionContext &context,
                                                QString &configurationXml)
 {
     QString id = name.section(':', 0, 2);
@@ -382,6 +382,9 @@
     }
 
     if (plugin) {
+
+        context = PluginTransform::ExecutionContext(context.channel, plugin);
+
         if (configurationXml != "") {
             PluginXml(plugin).setParametersFromXml(configurationXml);
         }
@@ -399,7 +402,7 @@
         if (sourceChannels < minChannels) targetChannels = minChannels;
         if (sourceChannels > maxChannels) targetChannels = maxChannels;
 
-        int defaultChannel = channel;
+        int defaultChannel = context.channel;
 
         PluginParameterDialog *dialog = new PluginParameterDialog(plugin,
                                                                   sourceChannels,
@@ -412,10 +415,13 @@
             ok = true;
         }
         configurationXml = PluginXml(plugin).toXmlString();
-        channel = dialog->getChannel();
+        context.channel = dialog->getChannel();
 
-        //!!! where now for step size, block size, etc?
-//        dialog->getProcessingParameters(stepSize, blockSize, windowType);
+        dialog->getProcessingParameters(context.stepSize,
+                                        context.blockSize,
+                                        context.windowType);
+
+        context.makeConsistentWithPlugin(plugin);
 
         delete dialog;
         delete plugin;
@@ -428,25 +434,24 @@
 
 Transform *
 TransformFactory::createTransform(TransformName name, Model *inputModel,
-                                  int channel, QString configurationXml, bool start)
+                                  const PluginTransform::ExecutionContext &context,
+                                  QString configurationXml, bool start)
 {
     Transform *transform = 0;
 
-    //!!! use channel
-    
     QString id = name.section(':', 0, 2);
     QString output = name.section(':', 3);
 
     if (FeatureExtractionPluginFactory::instanceFor(id)) {
         transform = new FeatureExtractionPluginTransform(inputModel,
                                                          id,
-                                                         channel,
+                                                         context,
                                                          configurationXml,
                                                          output);
     } else if (RealTimePluginFactory::instanceFor(id)) {
         transform = new RealTimePluginTransform(inputModel,
                                                 id,
-                                                channel,
+                                                context,
                                                 configurationXml,
                                                 getTransformUnits(name),
                                                 output.toInt());
@@ -463,9 +468,10 @@
 
 Model *
 TransformFactory::transform(TransformName name, Model *inputModel,
-                            int channel, QString configurationXml)
+                            const PluginTransform::ExecutionContext &context,
+                            QString configurationXml)
 {
-    Transform *t = createTransform(name, inputModel, channel,
+    Transform *t = createTransform(name, inputModel, context,
                                    configurationXml, false);
 
     if (!t) return 0;
--- a/transform/TransformFactory.h	Mon Sep 18 16:43:17 2006 +0000
+++ b/transform/TransformFactory.h	Tue Sep 19 14:37:06 2006 +0000
@@ -17,6 +17,7 @@
 #define _TRANSFORM_FACTORY_H_
 
 #include "Transform.h"
+#include "PluginTransform.h"
 
 #include <map>
 
@@ -68,7 +69,7 @@
      */
     bool getConfigurationForTransform(TransformName name,
                                       Model *inputModel,
-                                      int &channel,
+                                      PluginTransform::ExecutionContext &context,
                                       QString &configurationXml);
 
     /**
@@ -85,7 +86,8 @@
      * when no longer needed.
      */
     Model *transform(TransformName name, Model *inputModel,
-                     int channel, QString configurationXml = "");
+                     const PluginTransform::ExecutionContext &context,
+                     QString configurationXml = "");
 
     /**
      * Full description of a transform, suitable for putting on a menu.
@@ -128,7 +130,8 @@
 
 protected:
     Transform *createTransform(TransformName name, Model *inputModel,
-                               int channel, QString configurationXml, bool start);
+                               const PluginTransform::ExecutionContext &context,
+                               QString configurationXml, bool start);
 
     struct TransformIdent
     {