changeset 45:5c0b1f24bdf9 website

* Update wiki from live site
author cannam
date Tue, 01 Feb 2011 10:54:35 +0000
parents 8477a35e1e06
children bcb5a0818120
files wiki/data/media/mtp2-new-project-from.png wiki/data/media/mtp2-project-location.png wiki/data/media/mtp2-project-type.png wiki/data/media/mtp2-sdk-folder.png wiki/data/media/mtp2-skeleton-copy.png wiki/data/media/mtp2-skeleton-rename.png wiki/data/media/mtp2-tester.png wiki/data/pages/mtp1.txt wiki/data/pages/mtp2.txt wiki/data/pages/start.txt wiki/data/pages/wiki/dokuwiki.txt wiki/data/pages/wiki/syntax.txt wiki/lib/tpl/default/design.css wiki/lib/tpl/default/detail.php wiki/lib/tpl/default/images/button-php.gif wiki/lib/tpl/default/layout.css wiki/lib/tpl/default/main.php wiki/lib/tpl/default/media.css wiki/lib/tpl/default/print.css wiki/lib/tpl/default/rtl.css wiki/lib/tpl/default/style.ini
diffstat 21 files changed, 721 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
Binary file wiki/data/media/mtp2-new-project-from.png has changed
Binary file wiki/data/media/mtp2-project-location.png has changed
Binary file wiki/data/media/mtp2-project-type.png has changed
Binary file wiki/data/media/mtp2-sdk-folder.png has changed
Binary file wiki/data/media/mtp2-skeleton-copy.png has changed
Binary file wiki/data/media/mtp2-skeleton-rename.png has changed
Binary file wiki/data/media/mtp2-tester.png has changed
--- a/wiki/data/pages/mtp1.txt	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/data/pages/mtp1.txt	Tue Feb 01 10:54:35 2011 +0000
@@ -1,6 +1,6 @@
 ====== From Method to Plugin: Building a new plugin on OS/X with make ======
 
-[**Note:** This tutorial is specific to OS/X.  A second tutorial which uses Visual Studio on Windows is in preparation.]
+**Note:** This tutorial is specific to **OS/X**.  Go [[mtp2|here]] for a version that uses Windows and Visual C++.
 
 We're going to walk through the process of making, and compiling, a new Vamp plugin based on the skeleton files included with the Vamp plugin SDK.
 
@@ -12,15 +12,16 @@
 
 **Before you begin:** Make sure you have the Xcode tools (the OS/X developer SDK) installed!  You can't compile anything without it.
 
+**Note on build architectures:** Before OS/X 10.6, the default for the Xcode tools was to build 32-bit Intel binaries (known as "i386") when running on an Intel Mac, and 32-bit PowerPC ("ppc") when running on a PowerPC.  This was changed in 10.6 so as to build 64-bit Intel binaries ("x86_64") by default.  Unfortunately, plugins that are 64-bit only cannot be loaded into 32-bit hosts, such as the commonly distributed versions of all current Vamp hosts.  OS/X does support building for more than one architecture at once (storing the results in a fat file or "universal binary"), and that is the approach we take in this tutorial.  If we were to build for only a single architecture, i386 would currently be the more useful choice.
 ==== 1. Download and build the SDK ====
 
-Download the Vamp plugin SDK version 2.1 from http://vamp-plugins.org/develop.html, save it into your home directory, open a terminal window, and unpack it.  We'll also rename its directory from ''vamp-plugin-sdk-2.1'' to ''vamp-plugin-sdk'' for easier reference later on.
+Download the Vamp plugin SDK version 2.2 from the "development headers and source code" link on the developer page at http://vamp-plugins.org/develop.html -- the file you want is ''vamp-plugin-sdk-2.2.tar.gz''.  Save it into your home directory, open a terminal window, and unpack it.  We'll also rename its directory from ''vamp-plugin-sdk-2.2'' to ''vamp-plugin-sdk'' for easier reference later on.
 <code>
 mac:~ chris$ ls vamp*
-vamp-plugin-sdk-2.1.tar.gz
-mac:~ chris$ tar xvzf vamp-plugin-sdk-2.1.tar.gz
+vamp-plugin-sdk-2.2.tar.gz
+mac:~ chris$ tar xvzf vamp-plugin-sdk-2.2.tar.gz
  ... lots of output ...
-mac:~ chris$ mv vamp-plugin-sdk-2.1 vamp-plugin-sdk
+mac:~ chris$ mv vamp-plugin-sdk-2.2 vamp-plugin-sdk
 mac:~ chris$
 </code>
 
@@ -63,7 +64,6 @@
 The file ''plugins.cpp'' contains the entry point for the plugin library.  A library can hold more than one plugin, and the job of ''plugins.cpp'' is to provide a single known public function (''vampGetPluginDescriptor'') which the host can use to find out what plugins are available in the library.  The skeleton version of ''plugins.cpp'' just returns the single MyPlugin plugin class.
 
 Note that it makes absolutely no difference to the operation of the plugin what its class is called, or what any of these files is called; MyPlugin is (in purely technical terms) as good a name as any.  It also shouldn't matter if two different libraries happen to use the same class name.  But if you have more than one plugin in the same library, they'll need to have different class names then!
-
 ==== 3. Get the skeleton build working ====
 
 The first thing we'll do with this skeleton project is build it into a "working" (although pointless) plugin.
@@ -74,20 +74,20 @@
 <code>
 mac:~/tutorial chris$ cp Makefile.skeleton Makefile
 </code>
-Now, open the Makefile in the text editor; we need to edit it to suit our new project.  We haven't changed the names of any of the skeleton source files, so we don't need to edit those, but we do need to uncomment the lines that are specific to compiling on OS/X.  These appear in the skeleton file as:
+Now, open the Makefile in the text editor; we need to edit it to suit our new project.  We haven't changed the names of any of the skeleton source files, so we don't need to edit those, but we do need to uncomment the lines that are specific to compiling on OS/X.  We want to make a universal binary (32- and 64-bit) rather than a native build, so we look for:
 <code>
-##  Uncomment these for an OS/X native build using command-line tools:
+##  Uncomment these for an OS/X universal binary (PPC, 32- and 64-bit Intel) using command-line tools:
 
-# CXXFLAGS = -I$(VAMP_SDK_DIR) -Wall -fPIC
+# CXXFLAGS = -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch x86_64 -arch ppc -I$(VAMP_SDK_DIR) -Wall -fPIC
 # PLUGIN_EXT = .dylib
 # PLUGIN = $(PLUGIN_LIBRARY_NAME)$(PLUGIN_EXT)
 # LDFLAGS = -dynamiclib -install_name $(PLUGIN) $(VAMP_SDK_DIR)/libvamp-sdk.a -exported_symbols_list vamp-plugin.list
 </code>
 Remove the ''#'' characters from the starts of the four lines in that block:
 <code>
-##  Uncomment these for an OS/X native build using command-line tools:
+##  Uncomment these for an OS/X universal binary (PPC, 32- and 64-bit Intel) using command-line tools:
 
-CXXFLAGS = -I$(VAMP_SDK_DIR) -Wall -fPIC
+CXXFLAGS = -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch x86_64 -arch ppc -I$(VAMP_SDK_DIR) -Wall -fPIC
 PLUGIN_EXT = .dylib
 PLUGIN = $(PLUGIN_LIBRARY_NAME)$(PLUGIN_EXT)
 LDFLAGS = -dynamiclib -install_name $(PLUGIN) $(VAMP_SDK_DIR)/libvamp-sdk.a -exported_symbols_list vamp-plugin.list
@@ -95,9 +95,9 @@
 Then, without changing anything else, save the file and run ''make''.
 
 <code>
-mac:~/tutorial chris$ 
-g++ -I../vamp-plugin-sdk -Wall -fPIC   -c -o MyPlugin.o MyPlugin.cpp
-g++ -I../vamp-plugin-sdk -Wall -fPIC   -c -o plugins.o plugins.cpp
+mac:~/tutorial chris$ make
+g++ -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch x86_64 -arch ppc -I../vamp-plugin-sdk -Wall -fPIC -c -o MyPlugin.o MyPlugin.cpp
+g++ -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch x86_64 -arch ppc -I../vamp-plugin-sdk -Wall -fPIC -c -o plugins.o plugins.cpp
 g++ -o myplugins.dylib MyPlugin.o plugins.o -dynamiclib -install_name myplugins.dylib ../vamp-plugin-sdk/libvamp-sdk.a -exported_symbols_list vamp-plugin.list
 mac:~/tutorial chris$ 
 </code>
@@ -334,6 +334,7 @@
     while (i < m_blockSize) {
         float sample = inputBuffers[0][i];
         sumOfSquares += sample * sample;
+        ++i;
     }
 
     float meanPower = sumOfSquares / m_blockSize;
@@ -463,5 +464,4 @@
 {
     return "Freely redistributable (tutorial example code)";
 }
-</code>
-
+</code>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wiki/data/pages/mtp2.txt	Tue Feb 01 10:54:35 2011 +0000
@@ -0,0 +1,406 @@
+====== From Method to Plugin: Building a new plugin on Windows using Visual C++ ======
+
+**Note:** This tutorial is specific to **Windows with Visual C++**.  Go [[mtp1|here]] for a version that uses Mac OS/X.
+
+We're going to walk through the process of making, and compiling, a new Vamp plugin based on the skeleton files included with the Vamp plugin SDK.
+
+After downloading the various bits and pieces of code we'll need, we will start by setting up a new Visual C++ project in which we just get the skeleton plugin to compile without it doing any actual work, and then we'll add some substance to it afterwards.
+
+This tutorial assumes the use of Microsoft Visual C++ 2008 Express Edition (free with registration from http://www.microsoft.com/Express/VC/), though it should generally apply to other versions as well.
+
+The focus here is on the practical details of what you need to put in a plugin and how to get it to build and run -- not on the real mathematical or signal-processing aspect.  We will pick a very simple method (time-domain signal power, block by block) for this example.  Please refer to the [[http://vamp-plugins.org/guide.pdf|Vamp plugin API programmer's guide]] for further reading, with information about returning more sophisticated features.
+==== 1. Download and unpack the SDK headers and pre-built libraries ====
+
+Download the Vamp plugin SDK version 2.2 from the "development headers and source code" link on the developer page at http://vamp-plugins.org/develop.html -- the file you want is called ''vamp-plugin-sdk-2.2.zip''.  Unpack this into your Visual Studio projects folder, which by default is found in your ''Documents'' folder, at ''Documents\Visual Studio 2008\Projects''.  You should now have a new folder in this location called ''vamp-plugin-sdk-2.2''.  This picture shows the older version 2.1, but the principle is the same.
+
+{{:mtp2-sdk-folder.png|Newly unpacked SDK folder in the Projects folder}}
+
+We're not going to compile the SDK, only draw the header files from it.  To go with them, download the file ''vamp-plugin-sdk-2.1-staticlibs-win32-msvc.zip'' from the same location, which contains some pre-compiled SDK libraries, and unpack it in the ''Projects'' folder as well.  Note that, although the binaries file is marked as version 2.1, the binaries are unchanged between 2.1 and 2.2 (so there is no separate release marked 2.2).
+
+==== 2. Make a new project based on the skeleton files ====
+
+We're going to build our plugin in a new project called ''tutorial'', which initially will contain the skeleton plugin code from the SDK.
+
+There are various ways to accomplish this; here's one.
+
+Drag-copy the ''skeleton'' folder from within ''vamp-plugin-sdk-2.2'' directly into the ''Projects'' folder...
+
+{{:mtp2-skeleton-copy.png|Copy the skeleton files to a new project folder}}
+
+... and then rename ''skeleton'' to ''tutorial'' ...
+
+{{:mtp2-skeleton-rename.png|Rename skeleton project to tutorial}}
+
+Now open Visual Studio, select ''File'' -> ''New'' -> ''Project From Existing Code...''...
+
+{{:mtp2-new-project-from.png|New Project From Existing Code}}
+
+... and in the new-project wizard do the following:
+  * On the first page, choose the //Visual C++ Project// type
+  * On the next page, under //Specify Project Location and Source Files//, navigate to the new ''tutorial'' folder in your ''Projects'' directory and //Select Folder//
+            {{:mtp2-project-location.png|Setting the project location and name}}
+  * Under //Project Name// enter ''Tutorial''
+  * **Important:** In the //Project Settings// page under //How do you want to build the project?//, select ''Use Visual Studio'' and ''Dynamically linked library (DLL) project''
+            {{:mtp2-project-type.png|Setting the project target type}}
+  * **Important:** In the //Configuration Settings// page under //Include search paths (/I)//, type ''..\vamp-plugin-sdk-2.2''
+  * Finish
+
+Now save the project (Ctrl+S or equivalent).  Once the project has been created, we still have a couple more properties to set.  These are found in the ''Project'' -> ''Properties'' window:
+
+  * Under ''Configuration Properties'' -> ''Linker'' -> ''General'' -> ''Additional Library Directories'', navigate to the directory containing the **Debug** versions of the pre-compiled libraries you downloaded earlier (e.g. in my case this would be ''C:\Users\cannam\Documents\Visual Studio 2008\Projects\vamp-plugin-sdk-2.1-staticlibs-win32-msvc\debug'') and add it to the list
+  * Under ''Configuration Properties'' -> ''Linker'' -> ''Input'' -> ''Additional Dependencies'', add ''VampPluginSDK.lib''
+  * Under ''Configuration Properties'' -> ''Linker'' -> ''Command Line'' -> ''Additional options'', add ''/EXPORT:vampGetPluginDescriptor''
+
+You should now be able to build the project (press F7).
+
+In the above, it's critically important that the Debug configuration of your project uses the Debug version of the pre-compiled library folder, and the Release configuration (when you come to that) uses the Release version.  If you get this wrong, your plugin will build but will crash when you try to use it!
+
+The bulk of the skeleton plugin code is contained in the files ''MyPlugin.cpp'' and ''MyPlugin.h''.  These two files implement a single C++ class, called ''MyPlugin''.  For the sake of brevity in the tutorial we'll leave these names unchanged, but you might prefer to change them!  To do so, rename the two files as you wish, and replace every occurrence of the text ''MyPlugin'' in both of them, and in ''plugins.cpp'', with your preferred plugin class name.
+
+The file ''plugins.cpp'' contains the entry point for the plugin library.  A library can hold more than one plugin, and the job of ''plugins.cpp'' is to provide a single known public function (''vampGetPluginDescriptor'') which the host can use to find out what plugins are available in the library.  The skeleton version of ''plugins.cpp'' just returns the single MyPlugin plugin class.
+
+Note that it makes absolutely no difference to the operation of the plugin what its class is called, or what any of these files is called; MyPlugin is (in purely technical terms) as good a name as any.  It also shouldn't matter if two different libraries happen to use the same class name.  But if you have more than one plugin in the same library, they'll need to have different class names then!
+
+==== 3. Check that the plugin works with some test programs ====
+
+The next thing to do is gather some programs we can use to test our plugin, so that we can check it built correctly, and so that we'll be well placed to test it properly when it actually does something.
+
+=== vamp-plugin-tester ===
+
+One host worth setting up at the start is ''vamp-plugin-tester'', a program that tests your plugin for a number of possible problems and pitfalls.  You can download this from http://vamp-plugins.org/develop.html as well; you're looking for the file ''vamp-plugin-tester-1.0-win32.zip''.  Unpack it somewhere convenient, and (for now) copy the ''vamp-plugin-tester.exe'' program into the ''tutorial'' project folder for easy reference.
+
+We can then run the tester from the command prompt (go to the Start menu and type ''cmd'' to get the command prompt up).
+
+First go to the ''tutorial\Debug'' folder which is where our newly built plugin lives:
+
+<code>
+C:\Users\cannam>cd "Documents\Visual Studio 2008\Projects\tutorial\Debug"
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>
+</code>
+
+If you type ''dir *.dll'', you should see ''Tutorial.dll'', the plugin library we just built.
+
+Like all Vamp hosts, ''vamp-plugin-tester'' understands the ''VAMP_PATH'' environment variable to tell it where to look for Vamp plugins.  We need to set that, at least temporarily, to point to our new plugin in the current directory:
+
+<code>
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>set VAMP_PATH=.
+</code>
+
+And run the tester:
+
+<code>
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>..\vamp-plugin-tester.exe -a
+</code>
+
+{{:mtp2-tester.png|Running the Vamp plugin tester}}
+
+As you see, ''vamp-plugin-tester'' runs quite a number of tests -- see its ''README'' file for more details about the error and warning messages it might give.  It's a good idea to use the tester right from the start of plugin development.
+
+=== vamp-simple-host ===
+
+The tester gives some instant feedback, but the simplest way to run a plugin and see what happens is to use ''vamp-simple-host''.  This is also part of the Vamp SDK, and is available as a binary executable in the ''vamp-plugin-sdk-2.1-binaries-win32-mingw.zip'' package (the "Pre-compiled library and host binaries" link on the [[http://vamp-plugins.org/develop.html|developer page]]).  Extract only the ''vamp-simple-host.exe'' program from this package, and drop it into the ''tutorial'' folder as before.
+
+We set the ''VAMP_PATH'' environment variable already when using ''vamp-plugin-tester.exe'' above, but if you skipped that part:
+
+<code>
+C:\Users\cannam>cd "Documents\Visual Studio 2008\Projects\tutorial\Debug"
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>set VAMP_PATH=.
+</code>
+
+Now, with the ''-l'' option, we can ask the host to list the plugins it finds there.
+
+<code>
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>..\vamp-simple-host.exe -l
+Vamp plugin search path: [.]
+
+Vamp plugin libraries found in search path:
+
+  ./tutorial.dll:
+    [A] [v2] My Plugin, "myplugin" []
+
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>
+</code>
+
+Huzzah.  We can use this host to run the plugin on some test audio files, not just list it -- but there isn't much point yet.
+
+==== 4. Now, the code! ====
+
+Right, let's make the plugin do something.  We're going to calculate the mean power for each processing block.  The work we do in this section will involve making a few edits to the ''MyPlugin.cpp'' file (and at one point also ''MyPlugins.h'') and rebuilding the project.
+
+The calculation we want is ''sum(x[i]^2) / N'', where ''x[i]'' is audio sample number ''i'', for ''i'' in the range 0 to ''N-1'', with ''N'' the number of samples in the processing block.
+
+=== Describing the input and output formats ===
+
+Our calculation is a time-domain one (working directly from the PCM audio data), which means we don't need to change this function (found at line 63 of MyPlugin.cpp):
+
+<code cpp>
+MyPlugin::InputDomain
+MyPlugin::getInputDomain() const
+{
+    return TimeDomain;
+}
+</code>
+
+We are going to write code to handle a single audio channel only, and leave it to the host to decide what to do if more than one channel is provided (most hosts will mix-down the input for us).  So that means we don't need to change these functions either:
+
+<code cpp>
+size_t
+MyPlugin::getMinChannelCount() const
+{
+    return 1;
+}
+
+size_t
+MyPlugin::getMaxChannelCount() const
+{
+    return 1;
+}
+</code>
+
+Nothing about our calculation requires us to constrain the processing block size -- we can handle any block size.  So we can leave this function unchanged as well:
+
+<code cpp>
+size_t
+MyPlugin::getPreferredBlockSize() const
+{
+    return 0; // 0 means "I can handle any block size"
+}
+</code>
+
+The function ''getOutputDescriptors'' describes what sort of features we intend to return.  As it happens, the skeleton already contains pretty much the description we are going to need: a single feature, with a single value, returned for each processing block.  We should probably change the name of the output, at least:
+
+<code cpp>
+MyPlugin::OutputList
+MyPlugin::getOutputDescriptors() const
+{
+    OutputList list;
+
+    OutputDescriptor d;
+    d.identifier = "power";
+    d.name = "Power";
+    d.description = "";
+    d.unit = "";
+    d.hasFixedBinCount = true;
+    d.binCount = 1;
+    d.hasKnownExtents = false;
+    d.isQuantized = false;
+    d.sampleType = OutputDescriptor::OneSamplePerStep;
+    d.hasDuration = false;
+    list.push_back(d);
+
+    return list;
+}
+</code>
+
+=== Initialisation ===
+
+We said that we can **accept** any block size -- but we do need to know what the block size is.
+
+This is told to us in the ''initialise'' function.  Looking at that function, we can see the argument is ''size_t blockSize''.  It's our job to remember the value of this.
+
+We need to add a class data member for this.  In ''MyPlugin.h'', look for this line at line 54 (near the bottom of the file):
+
+<code cpp>
+    // plugin-specific data and methods go here
+</code>
+
+and add a line after it:
+
+<code cpp>
+    // plugin-specific data and methods go here
+    size_t m_blockSize;
+</code>
+
+Then, back in ''MyPlugin.cpp'', find this line at line 187 in the ''initialise'' function:
+
+<code cpp>
+    // Real initialisation work goes here!
+</code>
+
+and add a line to set the data member:
+
+<code cpp>
+    // Real initialisation work goes here!
+    m_blockSize = blockSize;
+</code>
+
+Also it's very good practice to make sure the data member is initialised to zero in the class constructor.  That, at line 10 of ''MyPlugin.cpp'', initially reads:
+
+<code cpp>
+MyPlugin::MyPlugin(float inputSampleRate) :
+    Plugin(inputSampleRate)
+{
+}
+</code>
+
+and we want it to read:
+
+<code cpp>
+MyPlugin::MyPlugin(float inputSampleRate) :
+    Plugin(inputSampleRate),
+    m_blockSize(0)
+{
+}
+</code>
+
+At this point it's a good idea to try rebuilding the project and make sure it still compiles.
+
+=== Processing ===
+
+The core of our calculation happens in the ''process'' method:
+
+<code cpp>
+MyPlugin::FeatureSet
+MyPlugin::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
+{
+    // Do actual work!
+    return FeatureSet();
+}
+</code>
+
+Here ''inputBuffers'' is effectively an array of arrays -- to retrieve a single audio sample, we index it first by audio channel number (we know that we only have one channel, so the only valid index is 0) and then by audio sample number (from 0 to the processing block size less 1).
+
+What we want to do is add up the squares of the audio sample values, and divide by the number of samples.
+
+<code cpp>
+MyPlugin::FeatureSet
+MyPlugin::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
+{
+    float sumOfSquares = 0.0f;
+
+    size_t i = 0; // note: same type as m_blockSize
+
+    while (i < m_blockSize) {
+        float sample = inputBuffers[0][i];
+        sumOfSquares += sample * sample;
+        ++i;
+    }
+
+    float meanPower = sumOfSquares / m_blockSize;
+
+    // now what?
+
+    return FeatureSet();
+}
+</code>
+
+So we've calculated the mean power value -- now how to return it?
+
+In Vamp plugin terms, what we have is a plugin that has a single output, on which is returned a single audio feature for each process block, with one value.  We need to construct a ''Feature'' object, give it a single value, and then push it as the only feature in output 0 (the first) of a new ''FeatureSet'' object.  See the [[http://vamp-plugins.org/guide.pdf|Vamp plugin API programmer's guide]] for more information about feature representation.
+
+Here's the code:
+
+<code cpp>
+MyPlugin::FeatureSet
+MyPlugin::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
+{
+    float sumOfSquares = 0.0f;
+
+    size_t i = 0;
+
+    while (i < m_blockSize) {
+        float sample = inputBuffers[0][i];
+        sumOfSquares += sample * sample;
+        ++i;
+    }
+
+    float meanPower = sumOfSquares / m_blockSize;
+
+    Feature f;
+    f.hasTimestamp = false;
+    f.values.push_back(meanPower);
+
+    FeatureSet fs;
+    fs[0].push_back(f);
+    return fs;
+}
+</code>
+
+After making this change and rebuilding the project, we now have a plugin that actually does something.
+
+Returning to our command prompt, and with the aid of a suitable input file (''.wav'' or a similar uncompressed format that ''vamp-simple-host'' understands) in the ''tutorial'' folder, we can now run it.  For example:
+
+<code>
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>..\vamp-simple-host.exe Tutorial:myplugin ..\my-song.wav
+vamp-simple-host: Running...
+Reading file: "C:/Users/cannam/Documents/Visual Studio 2008/Projects/tutorial/my-song.wav", writing to standard output
+Running plugin: "myplugin"...                                        
+Using block size = 1024, step size = 1024                            
+Plugin accepts 1 -> 1 channel(s)                                     
+Sound file has 2 (will mix/augment if necessary)                     
+Output is: "output"                                                  
+ 0.000000000: 0
+ 0.023219954: 0
+ 0.046439909: 0
+ 0.069659863: 0
+ 0.092879818: 0
+ 0.116099773: 0
+ 0.139319727: 0
+ 0.162539682: 1.56888e-11
+ 0.185759637: 4.90218e-09
+ 0.208979591: 2.135e-07
+ 0.232199546: 0.00666197
+ ... and lots and lots and lots and lots more output ...
+C:\Users\cannam\Documents\Visual Studio 2008\Projects\tutorial\Debug>
+</code>
+
+Try using the ''vamp-plugin-tester'' again as well.
+
+
+==== 5. Fill in descriptions and other metadata ====
+
+Now we have a working plugin, but it still has the rather awkward name of ''MyPlugin''.  There are several functions at the top of ''MyPlugin.cpp'' which we can use to give it a more sensible name and description.
+
+For example:
+
+<code cpp>
+string
+MyPlugin::getIdentifier() const
+{
+    return "myplugin";
+}
+</code>
+
+The identifier is a string that is not normally used by people (for example, it never appears when plugins are listed in a menu of a graphical application), but that uniquely identifies the plugin within its library.  Something like ''"power"'' is perfectly appropriate here.
+
+You should fill in all of ''getIdentifier'', ''getName'', ''getDescription'', ''getMaker'', ''getPluginVersion'', and ''getCopyright'' for every plugin you write.
+
+In my case, I would need something like:
+
+<code cpp>
+string
+MyPlugin::getIdentifier() const
+{
+    return "power";
+}
+
+string
+MyPlugin::getName() const
+{
+    return "Signal power level";
+}
+
+string
+MyPlugin::getDescription() const
+{
+    return "Calculate the mean signal power for each processing block";
+}
+
+string
+MyPlugin::getMaker() const
+{
+    return "Chris Cannam";
+}
+
+int
+MyPlugin::getPluginVersion() const
+{
+    return 1;
+}
+
+string
+MyPlugin::getCopyright() const
+{
+    return "Freely redistributable (tutorial example code)";
+}
+</code>
\ No newline at end of file
--- a/wiki/data/pages/start.txt	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/data/pages/start.txt	Tue Feb 01 10:54:35 2011 +0000
@@ -7,4 +7,6 @@
 
 If you have something you'd like to add, please, sign up and get editing!
 
-  * **New**: A [[mtp1|tutorial for prospective plugin developers]], covering how to get a new plugin compiled and working.  Using OS/X command-line tools (Windows version to follow).
+  * **New**: A tutorial for prospective plugin developers, covering how to get a new plugin compiled and working.  This tutorial comes in two versions:
+    * Using [[mtp1|OS/X and command-line tools]]
+    * Using [[mtp2|Windows and Visual C++]]
--- a/wiki/data/pages/wiki/dokuwiki.txt	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/data/pages/wiki/dokuwiki.txt	Tue Feb 01 10:54:35 2011 +0000
@@ -46,7 +46,8 @@
 
 **DokuWiki Feedback and Community**
 
-  * [[doku>mailinglist|Join the mailing list]] :!:
+  * [[doku>newsletter|Subscribe to the newsletter]] :!:
+  * [[doku>mailinglist|Join the mailing list]]
   * [[http://forum.dokuwiki.org|Check out the user forum]]
   * [[doku>irc|Talk to other users in the IRC channel]]
   * [[http://bugs.splitbrain.org/index.php?project=1|Submit bugs and feature wishes]]
@@ -56,12 +57,8 @@
 
 ===== Copyright =====
 
-2004-2009 (c) Andreas Gohr <andi@splitbrain.org>((Please do not contact me for help and support -- use the [[doku>mailinglist]] or [[http://forum.dokuwiki.org|forum]] instead))
+2004-2010 (c) Andreas Gohr <andi@splitbrain.org>((Please do not contact me for help and support -- use the [[doku>mailinglist]] or [[http://forum.dokuwiki.org|forum]] instead)) and the DokuWiki Community
 
 The DokuWiki engine is licensed under [[http://www.gnu.org/licenses/gpl.html|GNU General Public License]] Version 2. If you use DokuWiki in your company, consider [[doku>donate|donating]] a few bucks ;-).
 
-The content published in the DokuWiki at http://www.dokuwiki.org/ is licensed under the [[http://creativecommons.org/licenses/by-nc-sa/2.0/|Creative Commons Attribution-NonCommercial-ShareAlike License]] Version 2.0.
-
-An exception is made for the content which distributed in the download tarball((files inside the ''data'' directory -- eg: ''dokuwiki.txt'', ''syntax.txt'', ''dokuwiki-128.png'')) which is, for compatibility reasons, licensed under the GNU General Public License Version 2 as well.
-
 Not sure what this means? See the [[doku>faq:license|FAQ on the Licenses]].
--- a/wiki/data/pages/wiki/syntax.txt	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/data/pages/wiki/syntax.txt	Tue Feb 01 10:54:35 2011 +0000
@@ -2,7 +2,7 @@
 
 [[doku>DokuWiki]] supports some simple markup language, which tries to make the datafiles to be as readable as possible. This page contains all possible syntax you may use when editing the pages. Simply have a look at the source of this page by pressing the //Edit this page// button at the top or bottom of the page. If you want to try something, just use the [[playground:playground|playground]] page. The simpler markup is easily accessible via [[doku>toolbar|quickbuttons]], too.
 
-===== Basic text formatting =====
+===== Basic Text Formatting =====
 
 DokuWiki supports **bold**, //italic//, __underlined__ and ''monospaced'' texts. Of course you can **__//''combine''//__** all these.
 
@@ -49,7 +49,7 @@
   Internal links are created by using square brackets. You can either just give
   a [[pagename]] or use an additional [[pagename|link text]].
 
-[[doku>pagename|Wiki pagenames]] are converted to lowercase automatically, special characters are not allowed. 
+[[doku>pagename|Wiki pagenames]] are converted to lowercase automatically, special characters are not allowed.
 
 You can use [[some:namespaces]] by using a colon in the pagename.
 
@@ -74,7 +74,6 @@
   DokuWiki supports [[doku>Interwiki]] links. These are quick links to other Wikis.
   For example this is a link to Wikipedia's page about Wikis: [[wp>Wiki]].
 
-
 ==== Windows Shares ====
 
 Windows shares like [[\\server\share|this]] are recognized, too. Please note that these only make sense in a homogeneous user group like a corporate [[wp>Intranet]].
@@ -84,8 +83,9 @@
 Notes:
 
   * For security reasons direct browsing of windows shares only works in Microsoft Internet Explorer per default (and only in the "local zone").
-  * For Mozilla and Firefox it can be enabled through the config option [[http://www.mozilla.org/quality/networking/docs/netprefs.html#file|security.checkloaduri]] but this is not recommended.
-  * See [[dokubug>151]] for more info.
+  * For Mozilla and Firefox it can be enabled through different workaround mentioned in the [[http://kb.mozillazine.org/Links_to_local_pages_do_not_work|Mozilla Knowledge Base]]. However, there will still be a JavaScript warning about trying to open a Windows Share. To remove this warning (for all users), put the following line in ''conf/local.protected.php'':
+
+  $lang['js']['nosmblinks'] = '';
 
 ==== Image Links ====
 
@@ -121,7 +121,7 @@
 
 ----
 
-===== Images and other files =====
+===== Images and Other Files =====
 
 You can include external and internal [[doku>images]] with curly brackets. Optionally you can specify the size of them.
 
@@ -187,15 +187,22 @@
   - That's it
 </code>
 
-===== Smileys =====
+Also take a look at the [[doku>faq:lists|FAQ on list items]].
 
-DokuWiki converts commonly used [[wp>emoticon]]s to their graphical equivalents. More smileys can be placed in the ''smiley'' directory and configured in the ''conf/smileys.conf'' file. Here is an overview of Smileys included in DokuWiki.
+===== Text Conversions =====
+
+DokuWiki can convert certain pre-defined characters or strings into images or other text or HTML.
+
+The text to image conversion is mainly done for smileys. And the text to HTML conversion is used for typography replacements, but can be configured to use other HTML as well.
+
+==== Text to Image Conversions ====
+
+DokuWiki converts commonly used [[wp>emoticon]]s to their graphical equivalents. Those [[doku>Smileys]] and other images can be configured and extended. Here is an overview of Smileys included in DokuWiki:
 
   * 8-) %%  8-)  %%
   * 8-O %%  8-O  %%
   * :-( %%  :-(  %%
   * :-) %%  :-)  %%
-
   * =)  %%  =)   %%
   * :-/ %%  :-/  %%
   * :-\ %%  :-\  %%
@@ -213,9 +220,9 @@
   * FIXME %%  FIXME %%
   * DELETEME %% DELETEME %%
 
-===== Typography =====
+==== Text to HTML Conversions ====
 
-[[DokuWiki]] can convert simple text characters to their typographically correct entities. Here is an example of recognized characters.
+Typography: [[DokuWiki]] can convert simple text characters to their typographically correct entities. Here is an example of recognized characters.
 
 -> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
 "He thought 'It's a man's world'..."
@@ -225,7 +232,9 @@
 "He thought 'It's a man's world'..."
 </code>
 
-Please note: These conversions can be turned off through a [[doku>config:typography|config option]] and a [[doku>entities|pattern file]].
+The same can be done to produce any kind of HTML, it just needs to be added to the [[doku>entities|pattern file]].
+
+There are three exceptions which do not come from that pattern file: multiplication entity (640x480), 'single' and "double quotes". They can be turned off through a [[doku>config:typography|config option]].
 
 ===== Quoting =====
 
@@ -257,19 +266,19 @@
 
 ===== Tables =====
 
-DokuWiki supports a simple syntax to create tables. 
+DokuWiki supports a simple syntax to create tables.
 
 ^ Heading 1      ^ Heading 2       ^ Heading 3          ^
 | Row 1 Col 1    | Row 1 Col 2     | Row 1 Col 3        |
 | Row 2 Col 1    | some colspan (note the double pipe) ||
-| Row 3 Col 1    | Row 2 Col 2     | Row 2 Col 3        |
+| Row 3 Col 1    | Row 3 Col 2     | Row 3 Col 3        |
 
 Table rows have to start and end with a ''|'' for normal rows or a ''^'' for headers.
 
   ^ Heading 1      ^ Heading 2       ^ Heading 3          ^
   | Row 1 Col 1    | Row 1 Col 2     | Row 1 Col 3        |
   | Row 2 Col 1    | some colspan (note the double pipe) ||
-  | Row 3 Col 1    | Row 2 Col 2     | Row 2 Col 3        |
+  | Row 3 Col 1    | Row 3 Col 2     | Row 3 Col 3        |
 
 To connect cells horizontally, just make the next cell completely empty as shown above. Be sure to have always the same amount of cell separators!
 
@@ -287,7 +296,19 @@
   ^ Heading 4    | no colspan this time |                    |
   ^ Heading 5    | Row 2 Col 2          | Row 2 Col 3        |
 
-Note: Vertical spans (rowspan) are not possible.
+You can have rowspans (vertically connected cells) by adding '':::'' into the cells below the one to which they should connect.
+
+^ Heading 1      ^ Heading 2                  ^ Heading 3          ^
+| Row 1 Col 1    | this cell spans vertically | Row 1 Col 3        |
+| Row 2 Col 1    | :::                        | Row 2 Col 3        |
+| Row 3 Col 1    | :::                        | Row 2 Col 3        |
+
+Apart from the rowspan syntax those cells should not contain anything else.
+
+  ^ Heading 1      ^ Heading 2                  ^ Heading 3          ^
+  | Row 1 Col 1    | this cell spans vertically | Row 1 Col 3        |
+  | Row 2 Col 1    | :::                        | Row 2 Col 3        |
+  | Row 3 Col 1    | :::                        | Row 2 Col 3        |
 
 You can align the table contents, too. Just add at least two whitespaces at the opposite end of your text: Add two spaces on the left to align right, two spaces on the right to align left and two spaces at least at both ends for centered text.
 
@@ -303,32 +324,54 @@
   |left          |         right|    center    |
   | xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
 
-===== Non-parsed Blocks =====
+Note: Vertical alignment is not supported.
 
-You can include non-parsed blocks into your documents by either indenting them by at least two spaces (like used for the previous examples) or by using the tags ''code'' or ''file''.
+===== No Formatting =====
+
+If you need to display text exactly like it is typed (without any formatting), enclose the area either with ''%%<nowiki>%%'' tags or even simpler, with double percent signs ''<nowiki>%%</nowiki>''.
+
+<nowiki>
+This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
+</nowiki>
+The same is true for %%//__this__ text// with a smiley ;-)%%.
+
+  <nowiki>
+  This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
+  </nowiki>
+  The same is true for %%//__this__ text// with a smiley ;-)%%.
+
+===== Code Blocks =====
+
+You can include code blocks into your documents by either indenting them by at least two spaces (like used for the previous examples) or by using the tags ''%%<code>%%'' or ''%%<file>%%''.
+
+  This is text is indented by two spaces.
 
 <code>
 This is preformatted code all spaces are preserved: like              <-this
 </code>
 
 <file>
-This is pretty much the same, but you could use it to show that you quoted a file.  
+This is pretty much the same, but you could use it to show that you quoted a file.
 </file>
 
-To let the parser ignore an area completely (ie. do no formatting on it), enclose the area either with ''nowiki'' tags or even simpler, with double percent signs ''<nowiki>%%</nowiki>''.
+Those blocks were created by this source:
 
-<nowiki>
-This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
-</nowiki>
+    This is text is indented by two spaces.
 
-See the source of this page to see how to use these blocks.
+  <code>
+  This is preformatted code all spaces are preserved: like              <-this
+  </code>
 
-===== Syntax Highlighting =====
+  <file>
+  This is pretty much the same, but you could use it to show that you quoted a file.
+  </file>
 
-[[wiki:DokuWiki]] can highlight sourcecode, which makes it easier to read. It uses the [[http://qbnz.com/highlighter/|GeSHi]] Generic Syntax Highlighter -- so any language supported by GeSHi is supported. The syntax is the same like in the code block in the previous section, but this time the name of the used language is inserted inside the tag. Eg. ''<nowiki><code java></nowiki>''.
+==== Syntax Highlighting ====
+
+[[wiki:DokuWiki]] can highlight sourcecode, which makes it easier to read. It uses the [[http://qbnz.com/highlighter/|GeSHi]] Generic Syntax Highlighter -- so any language supported by GeSHi is supported. The syntax is the same like in the code and file blocks in the previous section, but this time the name of the used language is inserted inside the tag. Eg. ''<nowiki><code java></nowiki>'' or ''<nowiki><file java></nowiki>''.
 
 <code java>
-/** 
+/**
  * The HelloWorldApp class implements an application that
  * simply displays "Hello World!" to the standard output.
  */
@@ -339,32 +382,31 @@
 }
 </code>
 
-The following language strings are currently recognized: //abap, actionscript-french, actionscript, actionscript3, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, boo, c, c_mac, caddcl, cadlisp, cfdg, cfm, cil, cobol, cpp, cpp-qt, csharp, css, delphi, diff, div, dos, dot, d, eiffel, fortran, freebasic, genero, glsl, gml, gnuplot, groovy, gettext, haskell, html, idl, ini, inno, io, java5, java, javascript, kixtart, klonec, klonecpp, latex, lisp, lotusformulas, lotusscript, lua, m68k, matlab, mirc, mpasm, mxml, mysql, nsis, objc, ocaml-brief, ocaml, oobas, oracle8, pascal, perl, per, php-brief, php, pic16, plsql, povray, powershell, progress, python, qbasic, rails, reg, robots, ruby, sas, scala, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, typoscript, vbnet, vb, verilog, vhdl, visualfoxpro, winbatch, xml, xorg_conf, xpp, z80//
+The following language strings are currently recognized: //4cs, abap, actionscript-french, actionscript, actionscript3, ada, apache, applescript, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, ecmascript, eiffel, email, erlang, fo, fortran, freebasic, fsharp, gambas, genero, genie, gdb, glsl, gml, gnuplot, groovy, gettext, gwbasic, haskell, hicest, hq9plus, html, icon, idl, ini, inno, intercal, io, j, java5, java, javascript, jquery, kixtart, klonec, klonecpp, latex, lisp, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, modula2, modula3, mmix, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, ocaml-brief, ocaml, oobas, oracle8, oracle11, oxygene, oz, pascal, pcre, perl, perl6, per, pf, php-brief, php, pike, pic16, pixelbender, plsql, postgresql, povray, powerbuilder, powershell, progress, prolog, properties, providex, purebasic, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, vala, vbnet, vb, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, winbatch, whois, xbasic, xml, xorg_conf, xpp, z80//
 
+==== Downloadable Code Blocks ====
 
-===== RSS/ATOM Feed Aggregation =====
-[[DokuWiki]] can integrate data from external XML feeds. For parsing the XML feeds, [[http://simplepie.org/|SimplePie]] is used. All formats understood by SimplePie can be used in DokuWiki as well. You can influence the rendering by multiple additional space separated parameters:
+When you use the ''%%<code>%%'' or ''%%<file>%%'' syntax as above, you might want to make the shown code available for download as well. You can to this by specifying a file name after language code like this:
 
-^ Parameter  ^ Description ^
-| any number | will be used as maximum number items to show, defaults to 8 |
-| reverse    | display the last items in the feed first |
-| author     | show item authors names |
-| date       | show item dates |
-| description| show the item description. If [[doku>config:htmlok|HTML]] is disabled all tags will be stripped |
-| //n//[dhm] | refresh period, where d=days, h=hours, m=minutes. (e.g. 12h = 12 hours). |
+<code>
+<file php myexample.php>
+<?php echo "hello world!"; ?>
+</file>
+</code>
 
-The refresh period defaults to 4 hours. Any value below 10 minutes will be treated as 10 minutes. [[wiki:DokuWiki]] will generally try to supply a cached version of a page, obviously this is inappropriate when the page contains dynamic external content. The parameter tells [[wiki:DokuWiki]] to re-render the page if it is more than //refresh period// since the page was last rendered.
+<file php myexample.php>
+<?php echo "hello world!"; ?>
+</file>
 
-**Example:**
-
-  {{rss>http://slashdot.org/index.rss 5 author date 1h }}
-
-{{rss>http://slashdot.org/index.rss 5 author date 1h }}
+If you don't want any highlighting but want a downloadable file, specify a dash (''-'') as the language code: ''%%<code - myfile.foo>%%''.
 
 
 ===== Embedding HTML and PHP =====
 
-You can embed raw HTML or PHP code into your documents by using the ''html'' or ''php'' tags like this:
+You can embed raw HTML or PHP code into your documents by using the ''%%<html>%%'' or ''%%<php>%%'' tags. (Use uppercase tags if you need to enclose block level elements.)
+
+HTML example:
+
 <code>
 <html>
 This is some <span style="color:red;font-size:150%;">inline HTML</span>
@@ -381,6 +423,8 @@
 <p style="border:2px dashed red;">And this is some block HTML</p>
 </HTML>
 
+PHP example:
+
 <code>
 <php>
 echo 'A logo generated by PHP:';
@@ -407,6 +451,26 @@
 
 **Please Note**: HTML and PHP embedding is disabled by default in the configuration. If disabled, the code is displayed instead of executed.
 
+===== RSS/ATOM Feed Aggregation =====
+[[DokuWiki]] can integrate data from external XML feeds. For parsing the XML feeds, [[http://simplepie.org/|SimplePie]] is used. All formats understood by SimplePie can be used in DokuWiki as well. You can influence the rendering by multiple additional space separated parameters:
+
+^ Parameter  ^ Description ^
+| any number | will be used as maximum number items to show, defaults to 8 |
+| reverse    | display the last items in the feed first |
+| author     | show item authors names |
+| date       | show item dates |
+| description| show the item description. If [[doku>config:htmlok|HTML]] is disabled all tags will be stripped |
+| //n//[dhm] | refresh period, where d=days, h=hours, m=minutes. (e.g. 12h = 12 hours). |
+
+The refresh period defaults to 4 hours. Any value below 10 minutes will be treated as 10 minutes. [[wiki:DokuWiki]] will generally try to supply a cached version of a page, obviously this is inappropriate when the page contains dynamic external content. The parameter tells [[wiki:DokuWiki]] to re-render the page if it is more than //refresh period// since the page was last rendered.
+
+**Example:**
+
+  {{rss>http://slashdot.org/index.rss 5 author date 1h }}
+
+{{rss>http://slashdot.org/index.rss 5 author date 1h }}
+
+
 ===== Control Macros =====
 
 Some syntax influences how DokuWiki renders a page without creating any output it self. The following control macros are availble:
--- a/wiki/lib/tpl/default/design.css	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/design.css	Tue Feb 01 10:54:35 2011 +0000
@@ -91,7 +91,10 @@
   background-color: __background__;
   border: 1px solid __border__;
   padding: 0.3em 0 0 0.3em;
-  width: 100%;
+  /* should just be "width: 100%", but IE8 doesn't like it, see FS#1910 + FS#1667 */
+  width: 700px;
+  min-width: 100%;
+  max-width: 100%;
 }
 
 /* nice alphatransparency background except for IE <7 */
@@ -137,6 +140,7 @@
 div.dokuwiki textarea.edit[readonly],
 div.dokuwiki input.edit[disabled],
 div.dokuwiki input.edit[readonly],
+div.dokuwiki input.button[disabled],
 div.dokuwiki select.edit[disabled] {
   background-color: __background_neu__!important;
   color: __text_neu__!important;
@@ -404,11 +408,11 @@
 div.dokuwiki h5 {font-size: 100%; margin-left: 80px; border-bottom: none; font-weight: bold;}
 
 /* indent different sections */
-div.dokuwiki div.level1 {margin-left: 3px;}
-div.dokuwiki div.level2 {margin-left: 23px;}
-div.dokuwiki div.level3 {margin-left: 43px;}
-div.dokuwiki div.level4 {margin-left: 63px;}
-div.dokuwiki div.level5 {margin-left: 83px;}
+div.dokuwiki div.level1 { margin-left: 3px; }
+div.dokuwiki div.level2 { margin-left: 23px; }
+div.dokuwiki div.level3 { margin-left: 43px; }
+div.dokuwiki div.level4 { margin-left: 63px; }
+div.dokuwiki div.level5 { margin-left: 83px; }
 
 /* unordered lists */
 div.dokuwiki ul {
@@ -428,12 +432,10 @@
   font-weight: bold;
 }
 
-/* no gap in between nested lists */
-div.dokuwiki li ul {
-  margin-bottom: 0;
-}
+/* no bottom gap in between and smaller left margin for nested lists */
+div.dokuwiki li ul,
 div.dokuwiki li ol {
-  margin-bottom: 0;
+  margin: 0 0 0 1.5em;
 }
 
 /* the list items overriding the ul/ol definition */
@@ -442,10 +444,10 @@
   font-weight: normal;
 }
 
-div.dokuwiki ol {list-style-type: decimal}
-div.dokuwiki ol ol {list-style-type: upper-roman}
-div.dokuwiki ol ol ol {list-style-type: lower-alpha}
-div.dokuwiki ol ol ol ol {list-style-type: lower-greek}
+div.dokuwiki ol { list-style-type: decimal; }
+div.dokuwiki ol ol { list-style-type: upper-roman; }
+div.dokuwiki ol ol ol { list-style-type: lower-alpha; }
+div.dokuwiki ol ol ol ol { list-style-type: lower-greek; }
 
 div.dokuwiki li.open {
   list-style-image: url(images/open.gif);
@@ -463,6 +465,7 @@
 }
 
 div.dokuwiki pre {
+  font-family: monospace;
   font-size: 120%;
   padding: 0.5em;
   border: 1px dashed __border__;
@@ -480,16 +483,47 @@
   background-color: __background_other__;
 }
 
+/* code blocks by file tag */
+div.dokuwiki pre.file {
+  background-color: __background_alt__;
+}
+
+/* filenames for file and code blocks */
+div.dokuwiki dl.file,
+div.dokuwiki dl.code {
+    margin-top: 2em;
+    margin-bottom: 2.5em;
+}
+
+div.dokuwiki dl.file dt,
+div.dokuwiki dl.code dt {
+    border: 1px dashed __border__;
+    display: inline;
+    padding: 0.1em 1em;
+    margin-left: 2em;
+}
+
+div.dokuwiki dl.code dt a,
+div.dokuwiki dl.file dt a {
+    color: __text__;
+}
+
+div.dokuwiki dl.code dt {
+    background-color: __background_other__;
+    border-bottom: 1px solid __background_other__;
+}
+
+div.dokuwiki dl.file dt {
+    background-color: __background_alt__;
+    border-bottom: 1px solid __background_alt__;
+}
+
+
 /* inline code words */
 div.dokuwiki code {
   font-size: 120%;
 }
 
-/* code blocks by file tag */
-div.dokuwiki pre.file {
-  background-color: __background_alt__;
-}
-
 /* inline tables */
 div.dokuwiki table.inline {
   background-color: __background__;
@@ -658,6 +692,7 @@
   text-align: left;
   padding: 4px;
   max-width: 40%;    /* IE's width is handled in javascript */
+  min-width: 5em;
 }
 
 /* overcome IE issue with one line code or file boxes which require h. scrolling */
@@ -707,10 +742,14 @@
 
 div.dokuwiki ul.search_quickhits li {
   margin: 0 1.0em 0 1.0em;
-  float:left;
+  float: left;
   width: 30%;
 }
 
+div.dokuwiki .section_highlight {
+  background-color: __background_alt__ !important;
+}
+
 /* ------------------ Additional ---------------------- */
 
 div.footerinc {
@@ -761,6 +800,10 @@
   background-color: __background_alt__;
 }
 
+div.pk_hl {
+  width: 125px;
+}
+
 button.pickerbutton {
   padding: 0px;
   margin: 0 1px 1px 0;
@@ -792,6 +835,7 @@
 }
 
 div.dokuwiki div.imagemeta img.thumb {
-  float:left;
+  float: left;
   margin-right: 0.1em;
 }
+
--- a/wiki/lib/tpl/default/detail.php	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/detail.php	Tue Feb 01 10:54:35 2011 +0000
@@ -53,7 +53,7 @@
       <dl class="img_tags">
         <?php
           $t = tpl_img_getTag('Date.EarliestTime');
-          if($t) print '<dt>'.$lang['img_date'].':</dt><dd>'.strftime($conf['dformat'],$t).'</dd>';
+          if($t) print '<dt>'.$lang['img_date'].':</dt><dd>'.dformat($t).'</dd>';
 
           $t = tpl_img_getTag('File.Name');
           if($t) print '<dt>'.$lang['img_fname'].':</dt><dd>'.hsc($t).'</dd>';
Binary file wiki/lib/tpl/default/images/button-php.gif has changed
--- a/wiki/lib/tpl/default/layout.css	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/layout.css	Tue Feb 01 10:54:35 2011 +0000
@@ -30,13 +30,9 @@
   font-weight: bolder;
   text-align: right;
   vertical-align: middle;
-  width: 476px;
-  height: 29px;
-  background: url(/images/vamp-title.png) no-repeat;
 }
 
 div.dokuwiki .logo a {
-  display: none;
   color: __background_alt__ !important;
   text-decoration: none !important;
   font-variant: small-caps;
@@ -62,7 +58,7 @@
 }
 
 div.dokuwiki #bar__bottom {
-  margin-bottom:3px;
+  margin-bottom: 3px;
 }
 
 /* ------------- File Metadata ----------------------- */
--- a/wiki/lib/tpl/default/main.php	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/main.php	Tue Feb 01 10:54:35 2011 +0000
@@ -82,7 +82,7 @@
     <?php }?>
 
   </div>
-  <?php flush()?>
+  <?php tpl_flush()?>
 
   <?php /*old includehook*/ @include(dirname(__FILE__).'/pageheader.html')?>
 
@@ -94,7 +94,7 @@
 
   <div class="clearer">&nbsp;</div>
 
-  <?php flush()?>
+  <?php tpl_flush()?>
 
   <div class="stylefoot">
 
@@ -113,10 +113,10 @@
       <div class="bar-left" id="bar__bottomleft">
         <?php tpl_button('edit')?>
         <?php tpl_button('history')?>
+        <?php tpl_button('revert')?>
       </div>
       <div class="bar-right" id="bar__bottomright">
         <?php tpl_button('subscribe')?>
-        <?php tpl_button('subscribens')?>
         <?php tpl_button('admin')?>
         <?php tpl_button('profile')?>
         <?php tpl_button('login')?>
--- a/wiki/lib/tpl/default/media.css	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/media.css	Tue Feb 01 10:54:35 2011 +0000
@@ -1,5 +1,5 @@
 /**
- * The CSS in here cotrols the appearance of the media manager
+ * The CSS in here controls the appearance of the media manager
  */
 
 #media__manager {
@@ -35,7 +35,7 @@
 /* --- Tree formatting --- */
 
 #media__tree img {
-    float:left;
+    float: left;
     padding: 0.5em 0.3em 0 0;
 }
 
--- a/wiki/lib/tpl/default/print.css	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/print.css	Tue Feb 01 10:54:35 2011 +0000
@@ -7,26 +7,30 @@
 
 table {
   font-size: 100%;
-  padding:0;
-  margin:0;
+  padding: 0;
+  margin: 0;
 }
 
-tr,td,th {padding:0; margin:0;}
+tr,td,th { padding: 0; margin: 0; }
 
-img {border:0}
+img { border: 0; }
 
 a {
-  color:#000000;
-  text-decoration:none;
+  color: #000000;
+  text-decoration: none;
   background: none !important;
 }
 
+a.interwiki {
+  padding-left: 0px !important;
+}
+
 
 div.meta {
-  clear:both;
+  clear: both;
   margin-top: 1em;
-  font-size:70%;
-  text-align:right;
+  font-size: 70%;
+  text-align: right;
 }
 
 
@@ -36,7 +40,7 @@
 div.error,
 div.breadcrumbs,
 div.secedit {
-  display:none;
+  display: none;
 }
 
 /* --------------------- Text formating -------------------------------- */
@@ -60,7 +64,7 @@
 }
 
 /* existing wikilink */
-a.wikilink1    {text-decoration:underline }
+a.wikilink1    { text-decoration: underline; }
 
 /* the document */
 div.page {
@@ -83,15 +87,15 @@
     padding-top:    0.5em;
     padding-bottom: 0;
     border-bottom: 1px solid #000000;
-    clear:left;
+    clear: left;
 }
 
 /* special headlines */
-h1 {font-size: 160%; font-weight: bold;}
-h2 {font-size: 150%; }
-h3 {font-size: 140%; border-bottom: none; }
-h4 {font-size: 120%; border-bottom: none; }
-h5 {font-size: 100%; border-bottom: none; }
+h1 { font-size: 160%; font-weight: bold; }
+h2 { font-size: 150%; }
+h3 { font-size: 140%; border-bottom: none; }
+h4 { font-size: 120%; border-bottom: none; }
+h5 { font-size: 100%; border-bottom: none; }
 
 /* embedded images */
 img.media {
@@ -133,16 +137,20 @@
   margin-bottom: 0;
 }
 
-div.dokuwiki ol {list-style-type: decimal}
-div.dokuwiki ol ol {list-style-type: upper-roman}
-div.dokuwiki ol ol ol {list-style-type: lower-alpha}
-div.dokuwiki ol ol ol ol {list-style-type: lower-greek}
+div.dokuwiki ol { list-style-type: decimal; }
+div.dokuwiki ol ol { list-style-type: upper-roman; }
+div.dokuwiki ol ol ol { list-style-type: lower-alpha; }
+div.dokuwiki ol ol ol ol { list-style-type: lower-greek; }
 
 /* the list items overriding the ol definition */
 span.li {
     font-weight: normal;
 }
 
+pre {
+  font-family: monospace;
+}
+
 /* code blocks by indention */
 pre.pre {
   font-size: 8pt;
@@ -176,29 +184,29 @@
 }
 
 /* footnotes */
-div.footnotes{
-  clear:both;
+div.footnotes {
+  clear: both;
   border-top: 1px solid #000000;
   padding-left: 1em;
   margin-top: 1em;
 }
 
-div.fn{
-  font-size:90%;
+div.fn {
+  font-size: 90%;
 }
 
-a.fn_top{
-  vertical-align:super;
-  font-size:80%;
+a.fn_top {
+  vertical-align: super;
+  font-size: 80%;
 }
 
-a.fn_bot{
-  vertical-align:super;
-  font-size:80%;
-  font-weight:bold;
+a.fn_bot {
+  vertical-align: super;
+  font-size: 80%;
+  font-weight: bold;
 }
 
-acronym{
+acronym {
   border: 0;
 }
 
@@ -222,17 +230,17 @@
   border: 1px solid #000000;
 }
 
-.leftalign{
+.leftalign {
   text-align: left;
 }
 
-.centeralign{
+.centeralign {
   text-align: center;
 }
 
-.rightalign{
+.rightalign {
   text-align: right;
 }
 
-.toc, .footerinc, .header, .bar, .user {display:none}
+.toc, .footerinc, .header, .bar, .user { display: none; }
 
--- a/wiki/lib/tpl/default/rtl.css	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/rtl.css	Tue Feb 01 10:54:35 2011 +0000
@@ -1,5 +1,5 @@
 /**
- * Layout and dedsign corrections for right-to-left languages
+ * Layout and design corrections for right-to-left languages
  *
  * @author Andreas Gohr <andi@splitbrain.org>
  * @author Dotan Kamber <kamberd@yahoo.com>
@@ -34,7 +34,7 @@
 }
 
 div.meta div.user {
-  float: right
+  float: right;
 }
 
 div.meta div.doc {
@@ -45,6 +45,10 @@
 
 div.dokuwiki ul,
 div.dokuwiki ol {
+  margin: 0.5em 3.5em 0.5em 0;
+}
+div.dokuwiki li ul,
+div.dokuwiki li ol {
   margin: 0.5em 1.5em 0.5em 0;
 }
 
@@ -72,18 +76,18 @@
 }
 
 /* special headlines */
-div.dokuwiki h1 {margin-left: 0px; margin-right: 0px;}
-div.dokuwiki h2 {margin-left: 0px; margin-right: 20px;}
-div.dokuwiki h3 {margin-left: 0px; margin-right: 40px;}
-div.dokuwiki h4 {margin-left: 0px; margin-right: 60px;}
-div.dokuwiki h5 {margin-left: 0px; margin-right: 80px;}
+div.dokuwiki h1 { margin-left: 0px; margin-right: 0px; }
+div.dokuwiki h2 { margin-left: 0px; margin-right: 20px; }
+div.dokuwiki h3 { margin-left: 0px; margin-right: 40px; }
+div.dokuwiki h4 { margin-left: 0px; margin-right: 60px; }
+div.dokuwiki h5 { margin-left: 0px; margin-right: 80px; }
 
 /* indent different sections */
-div.dokuwiki div.level1 {margin-left: 0px; margin-right: 3px;}
-div.dokuwiki div.level2 {margin-left: 0px; margin-right: 23px;}
-div.dokuwiki div.level3 {margin-left: 0px; margin-right: 43px;}
-div.dokuwiki div.level4 {margin-left: 0px; margin-right: 63px;}
-div.dokuwiki div.level5 {margin-left: 0px; margin-right: 83px;}
+div.dokuwiki div.level1 { margin-left: 0px; margin-right: 3px; }
+div.dokuwiki div.level2 { margin-left: 0px; margin-right: 23px; }
+div.dokuwiki div.level3 { margin-left: 0px; margin-right: 43px; }
+div.dokuwiki div.level4 { margin-left: 0px; margin-right: 63px; }
+div.dokuwiki div.level5 { margin-left: 0px; margin-right: 83px; }
 
 /* TOC control */
 div.dokuwiki div.toc {
@@ -105,15 +109,47 @@
 
 div.dokuwiki ul.toc li {
   background-position: right 0.6em;
-  padding-right:0.4em;
+  padding-right: 0.4em;
   direction: rtl;
 }
 
 div.dokuwiki ul.toc li.clear {
-  padding-right:0.4em;
+  padding-right: 0.4em;
 }
 
-div.dokuwiki pre {
+div.dokuwiki .code {
+  direction: ltr;
   text-align: left;
 }
+div.dokuwiki blockquote {
+  border-left: 0;
+  padding-left: 0;
+  border-right: 2px solid  __border__;
+  padding-right: 3px;
+}
 
+/* Admin corrections */
+#admin__version {
+    clear: right;
+    float: left;
+}
+
+.dokuwiki ul.admin_tasks {
+    float: right;
+}
+
+.dokuwiki ul.admin_tasks li {
+    padding-left: 0px;
+    padding-right: 35px;
+    background: transparent none no-repeat scroll right 0;
+    text-align: right;
+}
+
+/* Search corrections */
+div.dokuwiki ul.search_quickhits li {
+    float: right;
+}
+
+div#qsearch__out {
+    text-align: right;
+}
--- a/wiki/lib/tpl/default/style.ini	Tue Oct 26 12:39:35 2010 +0000
+++ b/wiki/lib/tpl/default/style.ini	Tue Feb 01 10:54:35 2011 +0000
@@ -10,7 +10,11 @@
 design.css     = screen
 style.css      = screen
 
-media.css      = screen
+media.css         = screen
+_mediaoptions.css = screen
+_admin.css        = screen
+_linkwiz.css      = screen
+_subscription.css = screen
 
 rtl.css        = rtl
 print.css      = print
@@ -26,13 +30,13 @@
 __text__           = "#000"
 __background__     = "#fff"
 ; alternative text and background colors
-__text_alt__       = "#444"
-__background_alt__ = "#efcab0"
+__text_alt__       = "#638c9c"
+__background_alt__ = "#dee7ec"
 ; neutral text and background colors
 __text_neu__       = "#666"
 __background_neu__ = "#f5f5f5"
 ; border color
-__border__         = "#ef6a35"
+__border__         = "#8cacbb"
 ;--------------------------------------------------------------------------
 
 ; other text and background colors
@@ -40,8 +44,8 @@
 __background_other__ = "#f7f9fa"
 
 ; these are used for links
-__extern__    = "#ef6a35"
-__existing__  = "#ef6a35"
+__extern__    = "#436976"
+__existing__  = "#090"
 __missing__   = "#f30"
 
 ; highlighting search snippets
@@ -57,9 +61,9 @@
 __darkgray__   = "#666"
 __black__      = "#000"
 
-; these are the shades of orange
-__lighter__   = "#efcab0"
-__light__     = "#efbfad"
-__medium__    = "#ef8961"
-__dark__      = "#ef6a35"
-__darker__    = "#ef5011"
+; these are the shades of blue
+__lighter__   = "#f7f9fa"
+__light__     = "#eef3f8"
+__medium__    = "#dee7ec"
+__dark__      = "#8cacbb"
+__darker__    = "#638c9c"