[SCM] giada/master: Imported Upstream version 0.11.2~dfsg

umlaeute at users.alioth.debian.org umlaeute at users.alioth.debian.org
Tue Feb 16 14:46:50 UTC 2016


The following commit has been merged in the master branch:
commit cbdcb5a762dee91569ed2cc007fc93209871f6ce
Author: IOhannes m zmölnig <zmoelnig at umlautQ.umlaeute.mur.at>
Date:   Tue Feb 16 14:40:38 2016 +0100

    Imported Upstream version 0.11.2~dfsg

diff --git a/.travis.yml b/.travis.yml
index f254f19..e34326a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,7 @@
+sudo: required
+
+dist: trusty
+
 language: cpp
 
 compiler: gcc
@@ -14,16 +18,38 @@ before_install:
   - sudo apt-get install -y libsndfile1-dev libsamplerate0-dev libfltk1.3-dev libasound2-dev libxpm-dev libpulse-dev libjack-dev
 
 before_script:
+
+  # Download and build latest version of RtMidi
+
   - wget http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-2.1.0.tar.gz
   - tar -xvf rtmidi-2.1.0.tar.gz
   - cd rtmidi-2.1.0 && ./configure --with-jack --with-alsa && make && sudo make install || true
   - cd ..
+
+  # Download and install latest version of Jansson
+
   - wget http://www.digip.org/jansson/releases/jansson-2.7.tar.gz
   - tar -xvf jansson-2.7.tar.gz
   - cd jansson-2.7 && ./configure && make && sudo make install || true
   - sudo ldconfig
   - cd ..
+
+  # Download wav file for testing purposes
+
+  - wget http://download.wavetlan.com/SVV/Media/HTTP/WAV/Media-Convert/Media-Convert_test3_PCM_Stereo_VBR_16SS_11025Hz.wav -O test.wav
+
+  # Download midimaps package for testing purposes
+
+  - wget https://github.com/monocasual/giada-midimaps/archive/master.zip -O giada-midimaps-master.zip
+  - unzip giada-midimaps-master.zip
+  - mkdir -p $HOME/.giada/midimaps
+  - cp giada-midimaps-master/midimaps/* $HOME/.giada/midimaps
+
+  # Build Giada
+
   - ./autogen.sh
   - ./configure --target=linux --enable-vst
 
 script: make && make check
+
+after_failure: cat $TRAVIS_BUILD_DIR/test-suite.log
diff --git a/ChangeLog b/ChangeLog
index 466f6df..20f01c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,8 +12,31 @@
 --------------------------------------------------------------------------------
 
 
-
-0.11.0 --- 2015 . 12 .02
+0.11.2 --- 2016 . 01 . 16
+- New JSON-based midimap files
+- Add new channel by right-clicking anywhere on a column
+- Show warning if patch is using the deprecated file format
+- Do not force 32 bit compilation on OS X
+- Fix warnings and errors on GCC 5.3
+- Fix a bug that prevented MIDI Jack from being selected on Linux
+
+
+0.11.1 --- 2015 . 12 . 22
+- Ability to clone channels
+- New JSON-based configuration file
+- Port all vectors from old gVector to std::vector
+- Deactivate all other MIDI fields when changing MIDI system in Config window
+- Minor optimizations in configuration panel, Audio tab
+- Assume 'none' as default sound system
+- Include Catch header file in source package
+- Update Travis CI environment to Ubuntu Trusty
+- Fix missing sanitization after reading configuration file
+- Fix garbage text in device info window
+- Fix wrong config value if no midimaps are available
+- Fix garbage text while printing device and port names
+
+
+0.11.0 --- 2015 . 12 . 02
 - New JSON-based patch system
 - Properly store column width in patch
 - Port all const char* strings to std::string in patch/project glue layer
diff --git a/Makefile.am b/Makefile.am
index 84b2f4e..1e9a2ae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-AUTOMAKE_OPTIONS = foreign
+channelAUTOMAKOPTIONS = foreign
 
 AM_CXXFLAGS = -Wall -pedantic -Werror
 
@@ -53,6 +53,8 @@ src/glue/glue.h                        \
 src/glue/glue.cpp                      \
 src/glue/storage.h                     \
 src/glue/storage.cpp                   \
+src/glue/channel.h                     \
+src/glue/channel.cpp                   \
 src/gui/dialogs/gd_keyGrabber.h        \
 src/gui/dialogs/gd_keyGrabber.cpp      \
 src/gui/dialogs/gd_about.h             \
@@ -150,11 +152,13 @@ giada_LDFLAGS = -mwindows -static
 giada_SOURCES += resource.rc
 endif
 if OSX
+# for 32 bit compilation: 
+# export CXXFLAGS="-m32"
+# export LDFLAGS="-m32"
 giada_LDADD    = -lsndfile -lm -lpthread -lfltk -lrtmidi -lrtaudio \
 								 -lsamplerate -ljansson
-giada_CXXFLAGS = -m32
-giada_LDFLAGS  = -m32 -framework CoreAudio -framework Cocoa -framework Carbon \
-                -framework CoreMIDI -framework CoreFoundation
+giada_LDFLAGS  = -framework CoreAudio -framework Cocoa -framework Carbon \
+                 -framework CoreMIDI -framework CoreFoundation
 endif
 
 # used only under MinGW to compile the resource.rc file (program icon)
@@ -176,22 +180,22 @@ check_PROGRAMS = giada_tests
 giada_tests_SOURCES =        \
 tests/main.cpp               \
 tests/conf.cpp               \
+tests/wave.cpp               \
 tests/patch.cpp              \
+tests/midiMapConf.cpp        \
 tests/utils.cpp              \
 src/core/conf.cpp            \
+src/core/wave.cpp            \
+src/core/midiMapConf.cpp     \
 src/core/patch.cpp           \
 src/core/dataStorageIni.cpp  \
 src/core/dataStorageJson.cpp \
 src/utils/utils.cpp          \
 src/utils/log.cpp
 
-giada_tests_LDADD = -ljansson
+giada_tests_LDADD = -ljansson -lsndfile -lsamplerate
 
-# Ancient gcc on Travis complains about missing parentheses.
-# Catch also goes crazy with GCC 5.x (https://github.com/philsquared/Catch/issues/487)
-# --std=c++11
-
-giada_tests_CXXFLAGS = -Wno-parentheses -std=c++0x
+giada_tests_CXXFLAGS = -std=c++11
 
 # make rename ------------------------------------------------------------------
 
diff --git a/README.md b/README.md
index 59f1044..a35a25d 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,11 @@ Official website: http://www.giadamusic.com | Travis CI status: [![Build Status]
 
 Giada is a free, minimal, hardcore audio tool for DJs, live performers and electronic musicians. How does it work? Just pick up your channel, fill it with samples or MIDI events and start the show by using this tiny piece of software as a loop machine, drum machine, sequencer, live sampler or yet as a plugin/effect host. Giada aims to be a compact and portable virtual device for Linux, Mac OS X and Windows for production use and live sets.
 
+➔➔➔ [See Giada in action!](http://www.youtube.com/user/GiadaLoopMachine)
+
 ![Giada Loop Machine screenshot](http://giadamusic.com/public/img/screenshots/giada-loop-machine-screenshot-14-carousel.jpg)
 
-## Features
+## Main features
 
 * Ultra-lightweight internal design;
 * multi-thread/multi-core support;
@@ -24,8 +26,9 @@ Giada is a free, minimal, hardcore audio tool for DJs, live performers and elect
 * live sampler from external inputs;
 * live action recorder with automatic quantizer;
 * piano Roll editor;
-* portable patch storage system;
+* portable patch storage system, based on super-hackable JSON files;
 * support for all major uncompressed file formats;
+* test-driven development style supported by [Travis CI](https://travis-ci.org/monocasual/giada) and [Catch](https://github.com/philsquared/Catch)
 * under a constant stage of development;
 * 100% open-source GPL v3.
 
@@ -40,6 +43,12 @@ Docs are available online on the official website:
 
 http://www.giadamusic.com/documentation
 
+Found a typo or a terrible mistake? Feel free to clone the [website repository](https://github.com/monocasual/giada-www) and send us your pull requests.
+
+## Build Giada from source
+
+We do our best to make the compilation process as simple as possible. You can find all the information in the [official docs page](http://giadamusic.com/documentation/show/compiling-from-source).
+
 ## Bugs, requests and questions for non-developers
 
 Feel free to ask anything on our end-user forum:
@@ -48,18 +57,10 @@ http://www.giadamusic.com/forum
 
 ## Copyright
 
-Giada is Copyright (C) 2010-2015 by Giovanni A. Zuliani | Monocasual
+Giada is Copyright (C) 2010-2016 by Giovanni A. Zuliani | Monocasual
 
-Giada - Your Hardcore Loopmachine 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 3 of the License, or (at your option) any later version.
+Giada - Your Hardcore Loopmachine 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 3 of the License, or (at your option) any later version.
 
-Giada - Your Hardcore Loopmachine is distributed in the hope that it
-will be useful, but WITHOUT ANY WARRANTY; without even the implied
-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
+Giada - Your Hardcore Loopmachine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with Giada - Your Hardcore Loopmachine. If not, see
-<http://www.gnu.org/licenses/>.
+You should have received a copy of the GNU General Public License along with Giada - Your Hardcore Loopmachine. If not, see <http://www.gnu.org/licenses/>.
diff --git a/src/core/channel.cpp b/src/core/channel.cpp
index 762ba0d..e75a0f0 100644
--- a/src/core/channel.cpp
+++ b/src/core/channel.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -54,38 +54,38 @@ extern PluginHost  G_PluginHost;
 
 
 Channel::Channel(int type, int status, int bufferSize)
-	: bufferSize(bufferSize),
-	  type      (type),
-		status    (status),
-		key       (0),
-	  volume    (DEFAULT_VOL),
-	  volume_i  (1.0f),
-	  volume_d  (0.0f),
-	  panLeft   (1.0f),
-	  panRight  (1.0f),
-	  mute_i    (false),
-	  mute_s    (false),
-	  mute      (false),
-	  solo      (false),
-	  hasActions(false),
-	  recStatus (REC_STOPPED),
-	  vChan     (NULL),
-	  guiChannel(NULL),
-	  midiIn         (true),
-	  midiInKeyPress (0x0),
-	  midiInKeyRel   (0x0),
-	  midiInKill     (0x0),
-	  midiInVolume   (0x0),
-	  midiInMute     (0x0),
-	  midiInSolo     (0x0),
-	  midiOutL       (false),
-	  midiOutLplaying(0x0),
-	  midiOutLmute   (0x0),
-	  midiOutLsolo   (0x0)
+: bufferSize(bufferSize),
+  type      (type),
+	status    (status),
+	key       (0),
+  volume    (DEFAULT_VOL),
+  volume_i  (1.0f),
+  volume_d  (0.0f),
+  panLeft   (1.0f),
+  panRight  (1.0f),
+  mute_i    (false),
+  mute_s    (false),
+  mute      (false),
+  solo      (false),
+  hasActions(false),
+  recStatus (REC_STOPPED),
+  vChan     (NULL),
+  guiChannel(NULL),
+  midiIn         (true),
+  midiInKeyPress (0x0),
+  midiInKeyRel   (0x0),
+  midiInKill     (0x0),
+  midiInVolume   (0x0),
+  midiInMute     (0x0),
+  midiInSolo     (0x0),
+  midiOutL       (false),
+  midiOutLplaying(0x0),
+  midiOutLmute   (0x0),
+  midiOutLsolo   (0x0)
 {
-	vChan = (float *) malloc(bufferSize * sizeof(float));
+  vChan = (float *) malloc(bufferSize * sizeof(float));
 	if (!vChan)
-		gLog("[Channel] unable to alloc memory for vChan\n");
+		gLog("[Channel::allocVchan] unable to alloc memory for vChan\n");
 	memset(vChan, 0, bufferSize * sizeof(float));
 }
 
@@ -104,22 +104,68 @@ Channel::~Channel()
 /* -------------------------------------------------------------------------- */
 
 
-void Channel::sendMidiLmessage(uint32_t learn, int chan, uint32_t msg, int offset)
+void Channel::copy(const Channel *src)
 {
-	gLog("[channel::sendMidiLmessage] learn=%#X, chan=%d, msg=%#X, offset=%d\n",
-		learn, chan, msg, offset);
+  key             = src->key;
+  volume          = src->volume;
+  volume_i        = src->volume_i;
+  volume_d        = src->volume_d;
+  panLeft         = src->panLeft;
+  panRight        = src->panRight;
+  mute_i          = src->mute_i;
+  mute_s          = src->mute_s;
+  mute            = src->mute;
+  solo            = src->solo;
+  hasActions      = src->hasActions;
+  recStatus       = src->recStatus;
+  midiIn          = src->midiIn;
+  midiInKeyPress  = src->midiInKeyPress;
+  midiInKeyRel    = src->midiInKeyRel;
+  midiInKill      = src->midiInKill;
+  midiInVolume    = src->midiInVolume;
+  midiInMute      = src->midiInMute;
+  midiInSolo      = src->midiInSolo;
+  midiOutL        = src->midiOutL;
+  midiOutLplaying = src->midiOutLplaying;
+  midiOutLmute    = src->midiOutLmute;
+  midiOutLsolo    = src->midiOutLsolo;
+
+  /* clone plugins */
+
+#ifdef WITH_VST
+  for (unsigned i=0; i<src->plugins.size(); i++)
+    G_PluginHost.clonePlugin(*src->plugins.at(i), PluginHost::CHANNEL, this);
+#endif
+
+  /* clone actions */
+
+  for (unsigned i=0; i<recorder::global.size(); i++) {
+    for (unsigned k=0; k<recorder::global.at(i).size(); k++) {
+      recorder::action *a = recorder::global.at(i).at(k);
+      if (a->chan == src->index)
+        recorder::rec(index, a->type, a->frame, a->iValue, a->fValue);
+    }
+  }
+}
 
-	uint32_t out;
+
+/* -------------------------------------------------------------------------- */
+
+
+void Channel::sendMidiLmessage(uint32_t learn, const MidiMapConf::message_t &msg)
+{
+	gLog("[channel::sendMidiLmessage] learn=%#X, chan=%d, msg=%#X, offset=%d\n",
+		learn, msg.channel, msg.value, msg.offset);
 
 	/* isolate 'channel' from learnt message and offset it as requested by 'nn'
 	 * in the midimap configuration file. */
 
-	out  = ((learn & 0x00FF0000) >> 16) << offset;
+		uint32_t out = ((learn & 0x00FF0000) >> 16) << msg.offset;
 
 	/* merge the previously prepared channel into final message, and finally
 	 * send it. */
 
-	out |= msg | (chan << 24);
+	out |= msg.value | (msg.channel << 24);
 	kernelMidi::send(out);
 }
 
@@ -184,8 +230,8 @@ int Channel::writePatch(int i, bool isProject)
 	pch.midiOutLmute    = midiOutLmute;
 	pch.midiOutLsolo    = midiOutLsolo;
 
-	for (unsigned i=0; i<recorder::global.size; i++) {
-		for (unsigned k=0; k<recorder::global.at(i).size; k++) {
+	for (unsigned i=0; i<recorder::global.size(); i++) {
+		for (unsigned k=0; k<recorder::global.at(i).size(); k++) {
 			recorder::action *action = recorder::global.at(i).at(k);
 			if (action->chan == index) {
 				Patch::action_t pac;
@@ -193,7 +239,7 @@ int Channel::writePatch(int i, bool isProject)
 		    pac.frame  = action->frame;
 		    pac.fValue = action->fValue;
 		    pac.iValue = action->iValue;
-				pch.actions.add(pac);
+				pch.actions.push_back(pac);
 			}
 		}
 	}
@@ -201,23 +247,23 @@ int Channel::writePatch(int i, bool isProject)
 #ifdef WITH_VST
 
 	unsigned numPlugs = G_PluginHost.countPlugins(PluginHost::CHANNEL, this);
-	for (int i=0; i<numPlugs; i++) {
+	for (unsigned i=0; i<numPlugs; i++) {
 		Plugin *pPlugin = G_PluginHost.getPluginByIndex(i, PluginHost::CHANNEL, this);
 		if (pPlugin->status) {
 			Patch::plugin_t pp;
 			pp.path   = pPlugin->pathfile;
 	    pp.bypass = pPlugin->bypass;
 			for (int k=0; k<pPlugin->getNumParams(); k++)
-				pp.params.add(pPlugin->getParam(k));
-			pch.plugins.add(pp);
+				pp.params.push_back(pPlugin->getParam(k));
+			pch.plugins.push_back(pp);
 		}
 	}
 
 #endif
 
-	G_Patch.channels.add(pch);
+	G_Patch.channels.push_back(pch);
 
-	return G_Patch.channels.size - 1;
+	return G_Patch.channels.size() - 1;
 }
 
 
@@ -249,19 +295,19 @@ int Channel::readPatch(const string &path, int i)
 	midiOutLmute    = pch->midiOutLmute;
 	midiOutLsolo    = pch->midiOutLsolo;
 
-	for (unsigned k=0; k<pch->actions.size; k++) {
+	for (unsigned k=0; k<pch->actions.size(); k++) {
 		Patch::action_t *ac = &pch->actions.at(k);
 		recorder::rec(index, ac->type, ac->frame, ac->iValue, ac->fValue);
 	}
 
 #ifdef WITH_VST
 
-	for (unsigned k=0; k<pch->plugins.size; k++) {
+	for (unsigned k=0; k<pch->plugins.size(); k++) {
 		Patch::plugin_t *ppl = &pch->plugins.at(k);
 		Plugin *plugin = G_PluginHost.addPlugin(ppl->path.c_str(), PluginHost::CHANNEL, this);
 		if (plugin != NULL) {
 			plugin->bypass = ppl->bypass;
-			for (unsigned j=0; j<ppl->params.size; j++)
+			for (unsigned j=0; j<ppl->params.size(); j++)
 				plugin->setParam(j, ppl->params.at(j));
 			ret &= 1;
 		}
@@ -283,9 +329,9 @@ void Channel::sendMidiLmute()
 	if (!midiOutL || midiOutLmute == 0x0)
 		return;
 	if (mute)
-		sendMidiLmessage(midiOutLsolo, G_MidiMap.muteOnChan, G_MidiMap.muteOnMsg, G_MidiMap.muteOnOffset);
+		sendMidiLmessage(midiOutLsolo, G_MidiMap.muteOn);
 	else
-		sendMidiLmessage(midiOutLsolo, G_MidiMap.muteOffChan, G_MidiMap.muteOffMsg, G_MidiMap.muteOffOffset);
+		sendMidiLmessage(midiOutLsolo, G_MidiMap.muteOff);
 }
 
 
@@ -297,9 +343,9 @@ void Channel::sendMidiLsolo()
 	if (!midiOutL || midiOutLsolo == 0x0)
 		return;
 	if (solo)
-		sendMidiLmessage(midiOutLsolo, G_MidiMap.soloOnChan, G_MidiMap.soloOnMsg, G_MidiMap.soloOnOffset);
+		sendMidiLmessage(midiOutLsolo, G_MidiMap.soloOn);
 	else
-		sendMidiLmessage(midiOutLsolo, G_MidiMap.soloOffChan, G_MidiMap.soloOffMsg, G_MidiMap.soloOffOffset);
+		sendMidiLmessage(midiOutLsolo, G_MidiMap.soloOff);
 }
 
 
@@ -312,15 +358,15 @@ void Channel::sendMidiLplay()
 		return;
 	switch (status) {
 		case STATUS_OFF:
-			sendMidiLmessage(midiOutLplaying, G_MidiMap.stoppedChan, G_MidiMap.stoppedMsg, G_MidiMap.stoppedOffset);
+			sendMidiLmessage(midiOutLplaying, G_MidiMap.stopped);
 			break;
 		case STATUS_PLAY:
-			sendMidiLmessage(midiOutLplaying, G_MidiMap.playingChan, G_MidiMap.playingMsg, G_MidiMap.playingOffset);
+			sendMidiLmessage(midiOutLplaying, G_MidiMap.playing);
 			break;
 		case STATUS_WAIT:
-			sendMidiLmessage(midiOutLplaying, G_MidiMap.waitingChan, G_MidiMap.waitingMsg, G_MidiMap.waitingOffset);
+			sendMidiLmessage(midiOutLplaying, G_MidiMap.waiting);
 			break;
 		case STATUS_ENDING:
-			sendMidiLmessage(midiOutLplaying, G_MidiMap.stoppingChan, G_MidiMap.stoppingMsg, G_MidiMap.stoppingOffset);
+			sendMidiLmessage(midiOutLplaying, G_MidiMap.stopping);
 	}
 }
diff --git a/src/core/channel.h b/src/core/channel.h
index 0a50284..409eea7 100644
--- a/src/core/channel.h
+++ b/src/core/channel.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,11 +31,16 @@
 #define CHANNEL_H
 
 
+#include <vector>
 #include "../utils/utils.h"
+#include "midiMapConf.h"
 #include "const.h"
 #include "recorder.h"
 
 
+using std::vector;
+
+
 #ifdef WITH_VST
 
 /* before including aeffetx(x).h we must define __cdecl, otherwise VST
@@ -55,8 +60,8 @@
 using std::string;
 
 
-class Channel {
-
+class Channel
+{
 protected:
 
 	/* bufferSize
@@ -68,13 +73,19 @@ protected:
 	 * compose a MIDI message by merging bytes from MidiMap conf class, and send
 	 * it to KernelMidi. */
 
-	void sendMidiLmessage(uint32_t learn, int chan, uint32_t msg, int offset);
+	void sendMidiLmessage(uint32_t learn, const MidiMapConf::message_t &msg);
 
 public:
 
 	Channel(int type, int status, int bufferSize);
+
 	virtual ~Channel();
 
+	/* copy
+	 * Make a shallow copy (no vChan/pChan allocation) of another channel. */
+
+	virtual void copy(const Channel *src) = 0;
+
 	/* writePatch
 	 * Fill a patch with channel values. Returns the index of the last
 	 * Patch::channel_t added. */
@@ -196,7 +207,7 @@ public:
   uint32_t midiOutLsolo;
 
 #ifdef WITH_VST
-  gVector <class Plugin *> plugins;
+  vector <class Plugin *> plugins;
 #endif
 
 
diff --git a/src/core/conf.cpp b/src/core/conf.cpp
index 06c86da..4d33ddc 100644
--- a/src/core/conf.cpp
+++ b/src/core/conf.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -27,97 +27,70 @@
  * -------------------------------------------------------------------------- */
 
 
-#include <stdlib.h>
+#include <string>
 #include "conf.h"
 #include "const.h"
 #include "../utils/utils.h"
 #include "../utils/log.h"
 
 
-int Conf::openFileForReading()
-{
-	std::string path = gGetHomePath() + "/" + CONF_FILENAME;
-	fp = fopen(path.c_str(), "r");
-	if (fp == NULL) {
-		gLog("[Conf::openFile] unable to open conf file for reading\n");
-		return 0;
-	}
-	return 1;
-}
+using std::string;
 
 
-/* -------------------------------------------------------------------------- */
+Conf::Conf()
+{
+	/* Initialize confFilePath, i.e. the configuration file. In windows it is in
+	 * the same dir of the .exe, while in Linux and OS X in ~/.giada */
 
+#if defined(__linux__) || defined(__APPLE__)
 
-int Conf::createConfigFolder(const char *path)
-{
-	if (gDirExists(path))
-		return 1;
+	confFilePath = gGetHomePath() + gGetSlash() + CONF_FILENAME;
+	confDirPath  = gGetHomePath() + gGetSlash();
 
-	gLog("[Conf] .giada folder not present. Updating...\n");
+#elif defined(_WIN32)
 
-	if (gMkdir(path)) {
-		gLog("[Conf] status: ok\n");
-		return 1;
-	}
-	else {
-		gLog("[Conf] status: error!\n");
-		return 0;
-	}
+	confFilePath = CONF_FILENAME;
+	confDirPath  = "";
+
+#endif
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int Conf::openFileForWriting()
+int Conf::createConfigFolder()
 {
-	/* writing config file. In windows is in the same dir of the .exe,
-	 * in Linux and OS X in home */
-
-#if defined(__linux__)
-
-	char giadaPath[PATH_MAX];
-	sprintf(giadaPath, "%s/.giada", getenv("HOME"));
-
-	if (!createConfigFolder(giadaPath))
-		return 0;
+#if defined(__linux__) || defined(__APPLE__)
 
-	char path[PATH_MAX];
-	sprintf(path, "%s/%s", giadaPath, CONF_FILENAME);
-
-#elif defined(_WIN32)
-
-	const char *path = CONF_FILENAME;
-
-#elif defined(__APPLE__)
+	if (gDirExists(confDirPath))
+		return 1;
 
-	struct passwd *p = getpwuid(getuid());
-	const char *home = p->pw_dir;
-	char giadaPath[PATH_MAX];
-	snprintf(giadaPath, PATH_MAX, "%s/Library/Application Support/Giada", home);
+	gLog("[Conf::createConfigFolder] .giada folder not present. Updating...\n");
 
-	if (!createConfigFolder(giadaPath))
+	if (gMkdir(confDirPath)) {
+		gLog("[Conf::createConfigFolder] status: ok\n");
+		return 1;
+	}
+	else {
+		gLog("[Conf::createConfigFolder] status: error!\n");
 		return 0;
+	}
 
-	char path[PATH_MAX];
-	sprintf(path, "%s/%s", giadaPath, CONF_FILENAME);
+#else // windows
 
-#endif
-
-	fp = fopen(path, "w");
-	if (fp == NULL)
-		return 0;
 	return 1;
 
+#endif
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void Conf::setDefault()
+void Conf::init()
 {
+	header  = "GIADACFG";
 	logMode = LOG_MODE_MUTE;
 
 	soundSystem    = DEFAULT_SOUNDSYS;
@@ -131,7 +104,7 @@ void Conf::setDefault()
 
 	midiPortIn     = DEFAULT_MIDI_PORT_IN;
 	noNoteOff      = false;
-	midiMapPath[0] = '\0';
+	midiMapPath    = "";
 	midiPortOut    = DEFAULT_MIDI_PORT_OUT;
 	midiSync       = MIDI_SYNC_NONE;
 	midiTCfps      = 25.0f;
@@ -146,9 +119,9 @@ void Conf::setDefault()
 	midiInBeatHalf   = 0x0;
 	midiInMetronome  = 0x0;
 
-	pluginPath[0]  = '\0';
-	patchPath [0]  = '\0';
-	samplePath[0]  = '\0';
+	pluginPath  = "";
+	patchPath   = "";
+	samplePath  = "";
 
 	recsStopOnChanHalt = false;
 	chansStopOnSeqHalt = false;
@@ -170,298 +143,234 @@ void Conf::setDefault()
 }
 
 
-
 /* -------------------------------------------------------------------------- */
 
 
 int Conf::read()
 {
-	setDefault();
+	init();
 
-	if (!openFileForReading()) {
-		gLog("[Conf] unreadable .conf file, using default parameters\n");
-		return 0;
-	}
+	jRoot = json_load_file(confFilePath.c_str(), 0, &jError);
+  if (!jRoot) {
+    gLog("[Conf::read] unable to read configuration file! Error on line %d: %s\n", jError.line, jError.text);
+    return 0;
+  }
 
-	if (getValue("header") != "GIADACFG") {
-		gLog("[Conf] corrupted .conf file, using default parameters\n");
-		return -1;
+  if (!checkObject(jRoot, "root element")) {
+		json_decref(jRoot);
+    return 0;
 	}
 
-	logMode = atoi(getValue("logMode").c_str());
+	if (!setString(jRoot, CONF_KEY_HEADER, header)) return 0;
+	if (!setInt(jRoot, CONF_KEY_LOG_MODE, logMode)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SOUND_SYSTEM, soundSystem)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SOUND_DEVICE_OUT, soundDeviceOut)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SOUND_DEVICE_IN, soundDeviceIn)) return 0;
+	if (!setInt(jRoot, CONF_KEY_CHANNELS_OUT, channelsOut)) return 0;
+	if (!setInt(jRoot, CONF_KEY_CHANNELS_IN, channelsIn)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLERATE, samplerate)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BUFFER_SIZE, buffersize)) return 0;
+	if (!setInt(jRoot, CONF_KEY_DELAY_COMPENSATION, delayComp)) return 0;
+	if (!setBool(jRoot, CONF_KEY_LIMIT_OUTPUT, limitOutput)) return 0;
+	if (!setInt(jRoot, CONF_KEY_RESAMPLE_QUALITY, rsmpQuality)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MIDI_SYSTEM, midiSystem)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MIDI_PORT_OUT, midiPortOut)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MIDI_PORT_IN, midiPortIn)) return 0;
+	if (!setBool(jRoot, CONF_KEY_NO_NOTE_OFF, noNoteOff)) return 0;
+	if (!setString(jRoot, CONF_KEY_MIDIMAP_PATH, midiMapPath)) return 0;
+	if (!setString(jRoot, CONF_KEY_LAST_MIDIMAP, lastFileMap)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MIDI_SYNC, midiSync)) return 0;
+	if (!setFloat(jRoot, CONF_KEY_MIDI_TC_FPS, midiTCfps)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_REWIND, midiInRewind)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_START_STOP, midiInStartStop)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_ACTION_REC, midiInActionRec)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_INPUT_REC, midiInInputRec)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_METRONOME, midiInMetronome)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_VOLUME_IN, midiInVolumeIn)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_VOLUME_OUT, midiInVolumeOut)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_BEAT_DOUBLE, midiInBeatDouble)) return 0;
+	if (!setUint32(jRoot, CONF_KEY_MIDI_IN_BEAT_HALF, midiInBeatHalf)) return 0;
+	if (!setBool(jRoot, CONF_KEY_RECS_STOP_ON_CHAN_HALT, recsStopOnChanHalt)) return 0;
+	if (!setBool(jRoot, CONF_KEY_CHANS_STOP_ON_SEQ_HALT, chansStopOnSeqHalt)) return 0;
+	if (!setBool(jRoot, CONF_KEY_TREAT_RECS_AS_LOOPS, treatRecsAsLoops)) return 0;
+	if (!setBool(jRoot, CONF_KEY_RESIZE_RECORDINGS, resizeRecordings)) return 0;
+	if (!setString(jRoot, CONF_KEY_PLUGINS_PATH, pluginPath)) return 0;
+	if (!setString(jRoot, CONF_KEY_PATCHES_PATH, patchPath)) return 0;
+	if (!setString(jRoot, CONF_KEY_SAMPLES_PATH, samplePath)) return 0;
+
+	if (!setInt(jRoot, CONF_KEY_MAIN_WINDOW_X, mainWindowX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MAIN_WINDOW_Y, mainWindowY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MAIN_WINDOW_W, mainWindowW)) return 0;
+	if (!setInt(jRoot, CONF_KEY_MAIN_WINDOW_H, mainWindowH)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BROWSER_X, browserX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BROWSER_Y, browserY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BROWSER_W, browserW)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BROWSER_H, browserH)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_X, actionEditorX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_Y, actionEditorY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_W, actionEditorW)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_H, actionEditorH)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_ZOOM, actionEditorZoom)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_GRID_VAL, actionEditorGridVal)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ACTION_EDITOR_GRID_ON, actionEditorGridOn)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLE_EDITOR_X, sampleEditorX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLE_EDITOR_Y, sampleEditorY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLE_EDITOR_W, sampleEditorW)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLE_EDITOR_H, sampleEditorH)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLE_EDITOR_GRID_VAL, sampleEditorGridVal)) return 0;
+	if (!setInt(jRoot, CONF_KEY_SAMPLE_EDITOR_GRID_ON, sampleEditorGridOn)) return 0;
+	if (!setInt(jRoot, CONF_KEY_PIANO_ROLL_Y, pianoRollY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_PIANO_ROLL_H, pianoRollH)) return 0;
+	if (!setInt(jRoot, CONF_KEY_PLUGIN_LIST_X, pluginListX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_PLUGIN_LIST_Y, pluginListY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_CONFIG_X, configX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_CONFIG_Y, configY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BPM_X, bpmX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BPM_Y, bpmY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BEATS_X, beatsX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_BEATS_Y, beatsY)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ABOUT_X, aboutX)) return 0;
+	if (!setInt(jRoot, CONF_KEY_ABOUT_Y, aboutY)) return 0;
+
+	json_decref(jRoot);
+
+	sanitize();
 
-	soundSystem = atoi(getValue("soundSystem").c_str());
-	if (!(soundSystem & SYS_API_ANY)) soundSystem = DEFAULT_SOUNDSYS;
+	return 1;
+}
 
-	soundDeviceOut = atoi(getValue("soundDeviceOut").c_str());
-	if (soundDeviceOut < 0) soundDeviceOut = DEFAULT_SOUNDDEV_OUT;
 
-	soundDeviceIn = atoi(getValue("soundDeviceIn").c_str());
-	if (soundDeviceIn < -1) soundDeviceIn = DEFAULT_SOUNDDEV_IN;
+/* -------------------------------------------------------------------------- */
 
-	channelsOut = atoi(getValue("channelsOut").c_str());
-	channelsIn  = atoi(getValue("channelsIn").c_str());
-	if (channelsOut < 0) channelsOut = 0;
-	if (channelsIn < 0)  channelsIn  = 0;
 
-	buffersize = atoi(getValue("buffersize").c_str());
-	if (buffersize < 8) buffersize = DEFAULT_BUFSIZE;
+int Conf::write()
+{
+	if (!createConfigFolder())
+		return 0;
 
-	delayComp = atoi(getValue("delayComp").c_str());
-	if (delayComp < 0) delayComp = DEFAULT_DELAYCOMP;
+	jRoot = json_object();
+
+	json_object_set_new(jRoot, CONF_KEY_HEADER,                    json_string(header.c_str()));
+	json_object_set_new(jRoot, CONF_KEY_LOG_MODE,                  json_integer(logMode));
+	json_object_set_new(jRoot, CONF_KEY_SOUND_SYSTEM,              json_integer(soundSystem));
+	json_object_set_new(jRoot, CONF_KEY_SOUND_DEVICE_OUT,          json_integer(soundDeviceOut));
+	json_object_set_new(jRoot, CONF_KEY_SOUND_DEVICE_IN,           json_integer(soundDeviceIn));
+	json_object_set_new(jRoot, CONF_KEY_CHANNELS_OUT,              json_integer(channelsOut));
+	json_object_set_new(jRoot, CONF_KEY_CHANNELS_IN,               json_integer(channelsIn));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLERATE,                json_integer(samplerate));
+	json_object_set_new(jRoot, CONF_KEY_BUFFER_SIZE,               json_integer(buffersize));
+	json_object_set_new(jRoot, CONF_KEY_DELAY_COMPENSATION,        json_integer(delayComp));
+	json_object_set_new(jRoot, CONF_KEY_LIMIT_OUTPUT,              json_boolean(limitOutput));
+	json_object_set_new(jRoot, CONF_KEY_RESAMPLE_QUALITY,          json_integer(rsmpQuality));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_SYSTEM,               json_integer(midiSystem));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_PORT_OUT,             json_integer(midiPortOut));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_PORT_IN,              json_integer(midiPortIn));
+	json_object_set_new(jRoot, CONF_KEY_NO_NOTE_OFF,               json_boolean(noNoteOff));
+	json_object_set_new(jRoot, CONF_KEY_MIDIMAP_PATH,              json_string(midiMapPath.c_str()));
+	json_object_set_new(jRoot, CONF_KEY_LAST_MIDIMAP,              json_string(lastFileMap.c_str()));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_SYNC,                 json_integer(midiSync));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_TC_FPS,               json_real(midiTCfps));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_REWIND,            json_integer(midiInRewind));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_START_STOP,        json_integer(midiInStartStop));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_ACTION_REC,   	   json_integer(midiInActionRec));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_INPUT_REC,  	     json_integer(midiInInputRec));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_METRONOME,   	     json_integer(midiInMetronome));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_VOLUME_IN,  	     json_integer(midiInVolumeIn));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_VOLUME_OUT,  	     json_integer(midiInVolumeOut));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_BEAT_DOUBLE,   	   json_integer(midiInBeatDouble));
+	json_object_set_new(jRoot, CONF_KEY_MIDI_IN_BEAT_HALF,  	     json_integer(midiInBeatHalf));
+	json_object_set_new(jRoot, CONF_KEY_RECS_STOP_ON_CHAN_HALT,    json_boolean(recsStopOnChanHalt));
+	json_object_set_new(jRoot, CONF_KEY_CHANS_STOP_ON_SEQ_HALT,    json_boolean(chansStopOnSeqHalt));
+	json_object_set_new(jRoot, CONF_KEY_TREAT_RECS_AS_LOOPS,       json_boolean(treatRecsAsLoops));
+	json_object_set_new(jRoot, CONF_KEY_RESIZE_RECORDINGS,         json_boolean(resizeRecordings));
+	json_object_set_new(jRoot, CONF_KEY_PLUGINS_PATH,              json_string(pluginPath.c_str()));
+	json_object_set_new(jRoot, CONF_KEY_PATCHES_PATH,              json_string(patchPath.c_str()));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLES_PATH,              json_string(samplePath.c_str()));
+	json_object_set_new(jRoot, CONF_KEY_MAIN_WINDOW_X,             json_integer(mainWindowX));
+	json_object_set_new(jRoot, CONF_KEY_MAIN_WINDOW_Y,             json_integer(mainWindowY));
+	json_object_set_new(jRoot, CONF_KEY_MAIN_WINDOW_W,             json_integer(mainWindowW));
+	json_object_set_new(jRoot, CONF_KEY_MAIN_WINDOW_H,             json_integer(mainWindowH));
+	json_object_set_new(jRoot, CONF_KEY_BROWSER_X,                 json_integer(browserX));
+	json_object_set_new(jRoot, CONF_KEY_BROWSER_Y,                 json_integer(browserY));
+	json_object_set_new(jRoot, CONF_KEY_BROWSER_W,                 json_integer(browserW));
+	json_object_set_new(jRoot, CONF_KEY_BROWSER_H,                 json_integer(browserH));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_X,           json_integer(actionEditorX));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_Y,           json_integer(actionEditorY));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_W,           json_integer(actionEditorW));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_H,           json_integer(actionEditorH));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_ZOOM,        json_integer(actionEditorZoom));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_GRID_VAL,    json_integer(actionEditorGridVal));
+	json_object_set_new(jRoot, CONF_KEY_ACTION_EDITOR_GRID_ON,     json_integer(actionEditorGridOn));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLE_EDITOR_X,           json_integer(sampleEditorX));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLE_EDITOR_Y,           json_integer(sampleEditorY));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLE_EDITOR_W,           json_integer(sampleEditorW));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLE_EDITOR_H,           json_integer(sampleEditorH));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLE_EDITOR_GRID_VAL,    json_integer(sampleEditorGridVal));
+	json_object_set_new(jRoot, CONF_KEY_SAMPLE_EDITOR_GRID_ON,     json_integer(sampleEditorGridOn));
+	json_object_set_new(jRoot, CONF_KEY_PIANO_ROLL_Y,              json_integer(pianoRollY));
+	json_object_set_new(jRoot, CONF_KEY_PIANO_ROLL_H,              json_integer(pianoRollH));
+	json_object_set_new(jRoot, CONF_KEY_PLUGIN_LIST_X,             json_integer(pluginListX));
+	json_object_set_new(jRoot, CONF_KEY_PLUGIN_LIST_Y,             json_integer(pluginListY));
+	json_object_set_new(jRoot, CONF_KEY_CONFIG_X,                  json_integer(configX));
+	json_object_set_new(jRoot, CONF_KEY_CONFIG_Y,                  json_integer(configY));
+	json_object_set_new(jRoot, CONF_KEY_BPM_X,                     json_integer(bpmX));
+	json_object_set_new(jRoot, CONF_KEY_BPM_Y,                     json_integer(bpmY));
+	json_object_set_new(jRoot, CONF_KEY_BEATS_X,                   json_integer(beatsX));
+	json_object_set_new(jRoot, CONF_KEY_BEATS_Y,                   json_integer(beatsY));
+	json_object_set_new(jRoot, CONF_KEY_ABOUT_X,                   json_integer(aboutX));
+	json_object_set_new(jRoot, CONF_KEY_ABOUT_Y,                   json_integer(aboutY));
+
+  if (json_dump_file(jRoot, confFilePath.c_str(), JSON_INDENT(2)) != 0) {
+    gLog("[Conf::write] unable to write configuration file!\n");
+    return 0;
+  }
+  return 1;
+}
 
-	midiSystem  = atoi(getValue("midiSystem").c_str());
-	if (midiPortOut < -1) midiPortOut = DEFAULT_MIDI_SYSTEM;
 
-	midiPortOut = atoi(getValue("midiPortOut").c_str());
-	if (midiPortOut < -1) midiPortOut = DEFAULT_MIDI_PORT_OUT;
+/* -------------------------------------------------------------------------- */
 
-	midiPortIn = atoi(getValue("midiPortIn").c_str());
-	if (midiPortIn < -1) midiPortIn = DEFAULT_MIDI_PORT_IN;
 
-	noNoteOff = atoi(getValue("noNoteOff").c_str());
-
-	std::string tmpMidiMapPath = getValue("midiMapPath");
-	strncpy(midiMapPath, tmpMidiMapPath.c_str(), tmpMidiMapPath.size());
-	midiMapPath[tmpMidiMapPath.size()] = '\0';	// strncpy doesn't add '\0'
-
-	std::string tmplastFileMap = getValue("lastFileMap");
-	strncpy(lastFileMap, tmplastFileMap.c_str(), tmplastFileMap.size());
-	lastFileMap[tmplastFileMap.size()] = '\0';	// strncpy doesn't add '\0'
-
-	midiSync  = atoi(getValue("midiSync").c_str());
-	midiTCfps = atof(getValue("midiTCfps").c_str());
-
-	midiInRewind     = strtoul(getValue("midiInRewind").c_str(), NULL, 10);
-  midiInStartStop  = strtoul(getValue("midiInStartStop").c_str(), NULL, 10);
-  midiInActionRec  = strtoul(getValue("midiInActionRec").c_str(), NULL, 10);
-  midiInInputRec   = strtoul(getValue("midiInInputRec").c_str(), NULL, 10);
-  midiInMetronome  = strtoul(getValue("midiInMetronome").c_str(), NULL, 10);
-  midiInVolumeIn   = strtoul(getValue("midiInVolumeIn").c_str(), NULL, 10);
-  midiInVolumeOut  = strtoul(getValue("midiInVolumeOut").c_str(), NULL, 10);
-  midiInBeatDouble = strtoul(getValue("midiInBeatDouble").c_str(), NULL, 10);
-  midiInBeatHalf   = strtoul(getValue("midiInBeatHalf").c_str(), NULL, 10);
-
-	mainWindowX = atoi(getValue("mainWindowX").c_str());
-	mainWindowY = atoi(getValue("mainWindowY").c_str());
-	mainWindowW = atoi(getValue("mainWindowW").c_str());
-	mainWindowH = atoi(getValue("mainWindowH").c_str());
-
-	browserX = atoi(getValue("browserX").c_str());
-	browserY = atoi(getValue("browserY").c_str());
-	browserW = atoi(getValue("browserW").c_str());
-	browserH = atoi(getValue("browserH").c_str());
+void Conf::sanitize()
+{
+	if (!(soundSystem & SYS_API_ANY)) soundSystem = DEFAULT_SOUNDSYS;
+	if (soundDeviceOut < 0) soundDeviceOut = DEFAULT_SOUNDDEV_OUT;
+	if (soundDeviceIn < -1) soundDeviceIn = DEFAULT_SOUNDDEV_IN;
+	if (channelsOut < 0) channelsOut = 0;
+	if (channelsIn < 0)  channelsIn  = 0;
+	if (buffersize < 8 || buffersize > 4096) buffersize = DEFAULT_BUFSIZE;
+	if (delayComp < 0) delayComp = DEFAULT_DELAYCOMP;
+	if (midiPortOut < -1) midiPortOut = DEFAULT_MIDI_SYSTEM;
+	if (midiPortOut < -1) midiPortOut = DEFAULT_MIDI_PORT_OUT;
+	if (midiPortIn < -1) midiPortIn = DEFAULT_MIDI_PORT_IN;
 	if (browserX < 0) browserX = 0;
 	if (browserY < 0) browserY = 0;
 	if (browserW < 396) browserW = 396;
 	if (browserH < 302) browserH = 302;
-
-	actionEditorX    = atoi(getValue("actionEditorX").c_str());
-	actionEditorY    = atoi(getValue("actionEditorY").c_str());
-	actionEditorW    = atoi(getValue("actionEditorW").c_str());
-	actionEditorH    = atoi(getValue("actionEditorH").c_str());
-	actionEditorZoom = atoi(getValue("actionEditorZoom").c_str());
-	actionEditorGridVal = atoi(getValue("actionEditorGridVal").c_str());
-	actionEditorGridOn  = atoi(getValue("actionEditorGridOn").c_str());
-	if (actionEditorX < 0)      actionEditorX = 0;
-	if (actionEditorY < 0)      actionEditorY = 0;
-	if (actionEditorW < 640)    actionEditorW = 640;
-	if (actionEditorH < 176)    actionEditorH = 176;
+	if (actionEditorX < 0) actionEditorX = 0;
+	if (actionEditorY < 0) actionEditorY = 0;
+	if (actionEditorW < 640) actionEditorW = 640;
+	if (actionEditorH < 176) actionEditorH = 176;
 	if (actionEditorZoom < 100) actionEditorZoom = 100;
 	if (actionEditorGridVal < 0) actionEditorGridVal = 0;
-	if (actionEditorGridOn < 0)  actionEditorGridOn = 0;
-
-	pianoRollY = atoi(getValue("pianoRollY").c_str());
-	pianoRollH = atoi(getValue("pianoRollH").c_str());
-	if (pianoRollH <= 0)
-		pianoRollH = 422;
-
-	sampleEditorX    = atoi(getValue("sampleEditorX").c_str());
-	sampleEditorY    = atoi(getValue("sampleEditorY").c_str());
-	sampleEditorW    = atoi(getValue("sampleEditorW").c_str());
-	sampleEditorH    = atoi(getValue("sampleEditorH").c_str());
-	sampleEditorGridVal = atoi(getValue("sampleEditorGridVal").c_str());
-	sampleEditorGridOn  = atoi(getValue("sampleEditorGridOn").c_str());
-  if (sampleEditorX < 0)   sampleEditorX = 0;
-	if (sampleEditorY < 0)   sampleEditorY = 0;
+	if (actionEditorGridOn < 0) actionEditorGridOn = 0;
+	if (pianoRollH <= 0) pianoRollH = 422;
+  if (sampleEditorX < 0) sampleEditorX = 0;
+	if (sampleEditorY < 0) sampleEditorY = 0;
 	if (sampleEditorW < 500) sampleEditorW = 500;
 	if (sampleEditorH < 292) sampleEditorH = 292;
 	if (sampleEditorGridVal < 0) sampleEditorGridVal = 0;
-	if (sampleEditorGridOn < 0)  sampleEditorGridOn = 0;
-
-	configX = atoi(getValue("configX").c_str());
-	configY = atoi(getValue("configY").c_str());
+	if (sampleEditorGridOn < 0) sampleEditorGridOn = 0;
 	if (configX < 0) configX = 0;
 	if (configY < 0) configY = 0;
-
-	pluginListX = atoi(getValue("pluginListX").c_str());
-	pluginListY = atoi(getValue("pluginListY").c_str());
 	if (pluginListX < 0) pluginListX = 0;
 	if (pluginListY < 0) pluginListY = 0;
-
-	bpmX = atoi(getValue("bpmX").c_str());
-	bpmY = atoi(getValue("bpmY").c_str());
 	if (bpmX < 0) bpmX = 0;
 	if (bpmY < 0) bpmY = 0;
-
-	beatsX = atoi(getValue("beatsX").c_str());
-	beatsY = atoi(getValue("beatsY").c_str());
 	if (beatsX < 0) beatsX = 0;
 	if (beatsY < 0) beatsY = 0;
-
-	aboutX = atoi(getValue("aboutX").c_str());
-	aboutY = atoi(getValue("aboutY").c_str());
 	if (aboutX < 0) aboutX = 0;
 	if (aboutY < 0) aboutY = 0;
-
-	samplerate = atoi(getValue("samplerate").c_str());
 	if (samplerate < 8000) samplerate = DEFAULT_SAMPLERATE;
-
-	limitOutput = atoi(getValue("limitOutput").c_str());
-	rsmpQuality = atoi(getValue("rsmpQuality").c_str());
-
-	std::string p = getValue("pluginPath");
-	strncpy(pluginPath, p.c_str(), p.size());
-	pluginPath[p.size()] = '\0';	// strncpy doesn't add '\0'
-
-	p = getValue("patchPath");
-	strncpy(patchPath, p.c_str(), p.size());
-	patchPath[p.size()] = '\0';	// strncpy doesn't add '\0'
-
-	p = getValue("samplePath");
-	strncpy(samplePath, p.c_str(), p.size());
-	samplePath[p.size()] = '\0';	// strncpy doesn't add '\0'
-
-	recsStopOnChanHalt = atoi(getValue("recsStopOnChanHalt").c_str());
-	chansStopOnSeqHalt = atoi(getValue("chansStopOnSeqHalt").c_str());
-	treatRecsAsLoops   = atoi(getValue("treatRecsAsLoops").c_str());
-
-	resizeRecordings = atoi(getValue("resizeRecordings").c_str());
-
-	close();
-	return 1;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-int Conf::write()
-{
-	if (!openFileForWriting())
-		return 0;
-
-	fprintf(fp, "# --- Giada configuration file --- \n");
-	fprintf(fp, "header=GIADACFG\n");
-	fprintf(fp, "version=%s\n", G_VERSION_STR);
-
-	fprintf(fp, "logMode=%d\n",    logMode);
-
-	fprintf(fp, "soundSystem=%d\n",    soundSystem);
-	fprintf(fp, "soundDeviceOut=%d\n", soundDeviceOut);
-	fprintf(fp, "soundDeviceIn=%d\n",  soundDeviceIn);
-	fprintf(fp, "channelsOut=%d\n",    channelsOut);
-	fprintf(fp, "channelsIn=%d\n",     channelsIn);
-	fprintf(fp, "buffersize=%d\n",     buffersize);
-	fprintf(fp, "delayComp=%d\n",      delayComp);
-	fprintf(fp, "samplerate=%d\n",     samplerate);
-	fprintf(fp, "limitOutput=%d\n",    limitOutput);
-	fprintf(fp, "rsmpQuality=%d\n",    rsmpQuality);
-
-	fprintf(fp, "midiSystem=%d\n",  midiSystem);
-	fprintf(fp, "midiPortOut=%d\n", midiPortOut);
-	fprintf(fp, "midiPortIn=%d\n",  midiPortIn);
-	fprintf(fp, "noNoteOff=%d\n",   noNoteOff);
-	fprintf(fp, "midiMapPath=%s\n", midiMapPath);
-	fprintf(fp, "lastFileMap=%s\n", lastFileMap);
-	fprintf(fp, "midiSync=%d\n",    midiSync);
-	fprintf(fp, "midiTCfps=%f\n",   midiTCfps);
-
-	fprintf(fp, "midiInRewind=%u\n",     midiInRewind);
-	fprintf(fp, "midiInStartStop=%u\n",  midiInStartStop);
-	fprintf(fp, "midiInActionRec=%u\n",  midiInActionRec);
-	fprintf(fp, "midiInInputRec=%u\n",   midiInInputRec);
-	fprintf(fp, "midiInMetronome=%u\n",  midiInMetronome);
-	fprintf(fp, "midiInVolumeIn=%u\n",   midiInVolumeIn);
-	fprintf(fp, "midiInVolumeOut=%u\n",  midiInVolumeOut);
-	fprintf(fp, "midiInBeatDouble=%u\n", midiInBeatDouble);
-	fprintf(fp, "midiInBeatHalf=%u\n",   midiInBeatHalf);
-
-	fprintf(fp, "pluginPath=%s\n", pluginPath);
-	fprintf(fp, "patchPath=%s\n",  patchPath);
-	fprintf(fp, "samplePath=%s\n", samplePath);
-
-	fprintf(fp, "mainWindowX=%d\n", mainWindowX);
-	fprintf(fp, "mainWindowY=%d\n", mainWindowY);
-	fprintf(fp, "mainWindowW=%d\n", mainWindowW);
-	fprintf(fp, "mainWindowH=%d\n", mainWindowH);
-
-	fprintf(fp, "browserX=%d\n", browserX);
-	fprintf(fp, "browserY=%d\n", browserY);
-	fprintf(fp, "browserW=%d\n", browserW);
-	fprintf(fp, "browserH=%d\n", browserH);
-
-	fprintf(fp, "actionEditorX=%d\n",       actionEditorX);
-	fprintf(fp, "actionEditorY=%d\n",       actionEditorY);
-	fprintf(fp, "actionEditorW=%d\n",       actionEditorW);
-	fprintf(fp, "actionEditorH=%d\n",       actionEditorH);
-	fprintf(fp, "actionEditorZoom=%d\n",    actionEditorZoom);
-	fprintf(fp, "actionEditorGridOn=%d\n",  actionEditorGridOn);
-	fprintf(fp, "actionEditorGridVal=%d\n", actionEditorGridVal);
-
-	fprintf(fp, "pianoRollY=%d\n", pianoRollY);
-	fprintf(fp, "pianoRollH=%d\n", pianoRollH);
-
-	fprintf(fp, "sampleEditorX=%d\n", sampleEditorX);
-	fprintf(fp, "sampleEditorY=%d\n", sampleEditorY);
-	fprintf(fp, "sampleEditorW=%d\n", sampleEditorW);
-	fprintf(fp, "sampleEditorH=%d\n", sampleEditorH);
-	fprintf(fp, "sampleEditorGridOn=%d\n",  sampleEditorGridOn);
-	fprintf(fp, "sampleEditorGridVal=%d\n", sampleEditorGridVal);
-
-	fprintf(fp, "configX=%d\n", configX);
-	fprintf(fp, "configY=%d\n", configY);
-
-	fprintf(fp, "pluginListX=%d\n", pluginListX);
-	fprintf(fp, "pluginListY=%d\n", pluginListY);
-
-	fprintf(fp, "bpmX=%d\n", bpmX);
-	fprintf(fp, "bpmY=%d\n", bpmY);
-
-	fprintf(fp, "beatsX=%d\n", beatsX);
-	fprintf(fp, "beatsY=%d\n", beatsY);
-
-	fprintf(fp, "aboutX=%d\n", aboutX);
-	fprintf(fp, "aboutY=%d\n", aboutY);
-
-	fprintf(fp, "recsStopOnChanHalt=%d\n", recsStopOnChanHalt);
-	fprintf(fp, "chansStopOnSeqHalt=%d\n", chansStopOnSeqHalt);
-	fprintf(fp, "treatRecsAsLoops=%d\n",   treatRecsAsLoops);
-
-	fprintf(fp, "resizeRecordings=%d\n", resizeRecordings);
-
-	close();
-	return 1;
-}
-
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void Conf::close()
-{
-	if (fp != NULL)
-		fclose(fp);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void Conf::setPath(char *path, const char *p)
-{
-	path[0] = '\0';
-	strncpy(path, p, strlen(p));
-	path[strlen(p)] = '\0';
+	if (rsmpQuality < 0 || rsmpQuality > 4) rsmpQuality = 0;
 }
diff --git a/src/core/conf.h b/src/core/conf.h
index 0c4a3e1..236aad8 100644
--- a/src/core/conf.h
+++ b/src/core/conf.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,28 +31,44 @@
 #define __CONF_H__
 
 
-#include <limits.h>
-#include <stdint.h>
-#include "dataStorageIni.h"
+#include <string>
+#include <cstdio>
+#include "dataStorageJson.h"
 
 
-#if defined(__APPLE__)
-	#include <pwd.h>
-#endif
+using std::string;
 
 
-class Conf : public DataStorageIni
+class Conf : public DataStorageJson
 {
 private:
 
-	int openFileForReading();
-	int openFileForWriting();
-	int createConfigFolder(const char *path);
+	string confFilePath;
+	string confDirPath;
+
+	/* init
+   * Init Conf with default values. */
+
+  void init();
+
+	/* sanitize
+	 * Avoid funky values from config file. */
+
+	void sanitize();
+
+	/* createConfigFolder
+	 * Create local folder where to put the configuration file. Path differs from
+	 * OS to OS. */
+	 
+	int createConfigFolder();
 
 public:
 
-	int logMode;
+	Conf();
 
+	string header;
+
+	int  logMode;
 	int  soundSystem;
 	int  soundDeviceOut;
 	int  soundDeviceIn;
@@ -64,14 +80,14 @@ public:
 	bool limitOutput;
 	int  rsmpQuality;
 
-	int   midiSystem;
-	int   midiPortOut;
-	int   midiPortIn;
-	bool  noNoteOff;
-	char  midiMapPath[FILENAME_MAX];
-	char  lastFileMap[FILENAME_MAX];
-	int   midiSync;  // see const.h
-	float midiTCfps;
+	int      midiSystem;
+	int      midiPortOut;
+	int      midiPortIn;
+	bool     noNoteOff;
+	string   midiMapPath;
+	string   lastFileMap;
+	int      midiSync;  // see const.h
+	float    midiTCfps;
 
 	uint32_t midiInRewind;
 	uint32_t midiInStartStop;
@@ -86,12 +102,11 @@ public:
 	bool recsStopOnChanHalt;
 	bool chansStopOnSeqHalt;
 	bool treatRecsAsLoops;
-
 	bool resizeRecordings;
 
-	char pluginPath[FILENAME_MAX];
-	char patchPath [FILENAME_MAX];
-	char samplePath[FILENAME_MAX];
+	string pluginPath;
+	string patchPath;
+	string samplePath;
 
 	int  mainWindowX, mainWindowY, mainWindowW, mainWindowH;
 	int  browserX, browserY, browserW, browserH;
@@ -110,15 +125,6 @@ public:
 
 	int  read();
 	int  write();
-	void setDefault();
-
-	/* setPath
-	 * updates one of the following values: plugin, patch or sample.
-	 * Pass it a pointer to one of these (path) and the string to save (p). */
-
-	void setPath(char *path, const char *p);
-
-	void close();
 };
 
 #endif
diff --git a/src/core/const.h b/src/core/const.h
index 4cf0af3..e8be397 100644
--- a/src/core/const.h
+++ b/src/core/const.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -16,7 +16,7 @@
  * version 3 of the License, or (at your option) any later version.
  *
  * Giada - Your Hardcore Loopmachine is distributed in the hope that it
- * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * will be useful, but WITHOUT ANY WARRANTY without even the implied
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
  *
@@ -32,11 +32,11 @@
 
 
 /* -- version --------------------------------------------------------------- */
-#define G_VERSION_STR   "0.11.0"
+#define G_VERSION_STR   "0.11.2"
 #define G_APP_NAME      "Giada"
 #define G_VERSION_MAJOR 0
 #define G_VERSION_MINOR 11
-#define G_VERSION_PATCH 0
+#define G_VERSION_PATCH 2
 
 #define CONF_FILENAME		"giada.conf"
 
@@ -77,6 +77,7 @@
 
 
 /* -- kernel audio ---------------------------------------------------------- */
+#define SYS_API_NONE		0x00  // 0000 0000
 #define SYS_API_JACK		0x01  // 0000 0001
 #define SYS_API_ALSA		0x02  // 0000 0010
 #define SYS_API_DS			0x04  // 0000 0100
@@ -99,7 +100,7 @@
 
 /* -- default system -------------------------------------------------------- */
 #if defined(__linux__)
-	#define DEFAULT_SOUNDSYS	SYS_API_ALSA
+	#define DEFAULT_SOUNDSYS	SYS_API_NONE
 #elif defined(_WIN32)
 	#define DEFAULT_SOUNDSYS 	SYS_API_DS
 #elif defined(__APPLE__)
@@ -236,6 +237,14 @@
 
 
 
+/* -- midimap signals ------------------------------------------------------- */
+#define MIDIMAP_NOT_SPECIFIED 0x00
+#define MIDIMAP_UNREADABLE    0x01
+#define MIDIMAP_INVALID       0x02
+#define MIDIMAP_READ_OK       0x04
+
+
+
 /* -- MIDI signals -------------------------------------------------------------
  * all signals are set to channel 0 (where channels are considered).
  * It's up to the caller to bitmask them with the proper channel number. */
@@ -360,4 +369,92 @@ const int MIDI_CHANS[16] = {
 #define PATCH_KEY_COLUMN_WIDTH                 "width"
 #define PATCH_KEY_COLUMN_CHANNELS              "channels"
 
+/* JSON config keys */
+
+#define CONF_KEY_HEADER                   "header"
+#define CONF_KEY_LOG_MODE                 "log_mode"
+#define CONF_KEY_SOUND_SYSTEM             "sound_system"
+#define CONF_KEY_SOUND_DEVICE_IN          "sound_device_in"
+#define CONF_KEY_SOUND_DEVICE_OUT         "sound_device_out"
+#define CONF_KEY_CHANNELS_IN              "channels_in"
+#define CONF_KEY_CHANNELS_OUT             "channels_out"
+#define CONF_KEY_SAMPLERATE               "samplerate"
+#define CONF_KEY_BUFFER_SIZE              "buffer_size"
+#define CONF_KEY_DELAY_COMPENSATION       "delay_compensation"
+#define CONF_KEY_LIMIT_OUTPUT             "limit_output"
+#define CONF_KEY_RESAMPLE_QUALITY         "resample_quality"
+#define CONF_KEY_MIDI_SYSTEM              "midi_system"
+#define CONF_KEY_MIDI_PORT_OUT            "midi_port_out"
+#define CONF_KEY_MIDI_PORT_IN             "midi_port_in"
+#define CONF_KEY_NO_NOTE_OFF              "no_note_off"
+#define CONF_KEY_MIDIMAP_PATH             "midimap_path"
+#define CONF_KEY_LAST_MIDIMAP             "last_midimap"
+#define CONF_KEY_MIDI_SYNC                "midi_sync"
+#define CONF_KEY_MIDI_TC_FPS              "midi_tc_fps"
+#define CONF_KEY_MIDI_IN_REWIND           "midi_in_rewind"
+#define CONF_KEY_MIDI_IN_START_STOP       "midi_in_start_stop"
+#define CONF_KEY_MIDI_IN_ACTION_REC       "midi_in_action_rec"
+#define CONF_KEY_MIDI_IN_INPUT_REC        "midi_in_input_rec"
+#define CONF_KEY_MIDI_IN_METRONOME        "midi_in_metronome"
+#define CONF_KEY_MIDI_IN_VOLUME_IN        "midi_in_volume_in"
+#define CONF_KEY_MIDI_IN_VOLUME_OUT       "midi_in_volume_out"
+#define CONF_KEY_MIDI_IN_BEAT_DOUBLE      "midi_in_beat_doble"
+#define CONF_KEY_MIDI_IN_BEAT_HALF        "midi_in_beat_half"
+#define CONF_KEY_RECS_STOP_ON_CHAN_HALT   "recs_stop_on_chan_halt"
+#define CONF_KEY_CHANS_STOP_ON_SEQ_HALT   "chans_stop_on_seq_halt"
+#define CONF_KEY_TREAT_RECS_AS_LOOPS      "treat_recs_as_loops"
+#define CONF_KEY_RESIZE_RECORDINGS        "resize_recordings"
+#define CONF_KEY_PLUGINS_PATH             "plugins_path"
+#define CONF_KEY_PATCHES_PATH             "patches_path"
+#define CONF_KEY_SAMPLES_PATH             "samples_path"
+#define CONF_KEY_MAIN_WINDOW_X            "main_window_x"
+#define CONF_KEY_MAIN_WINDOW_Y            "main_window_y"
+#define CONF_KEY_MAIN_WINDOW_W            "main_window_w"
+#define CONF_KEY_MAIN_WINDOW_H            "main_window_h"
+#define CONF_KEY_BROWSER_X                "browser_x"
+#define CONF_KEY_BROWSER_Y                "browser_y"
+#define CONF_KEY_BROWSER_W                "browser_w"
+#define CONF_KEY_BROWSER_H                "browser_h"
+#define CONF_KEY_ACTION_EDITOR_X          "action_editor_x"
+#define CONF_KEY_ACTION_EDITOR_Y          "action_editor_y"
+#define CONF_KEY_ACTION_EDITOR_W          "action_editor_w"
+#define CONF_KEY_ACTION_EDITOR_H          "action_editor_h"
+#define CONF_KEY_ACTION_EDITOR_ZOOM       "action_editor_zoom"
+#define CONF_KEY_ACTION_EDITOR_GRID_VAL   "action_editor_grid_val"
+#define CONF_KEY_ACTION_EDITOR_GRID_ON    "action_editor_grid_on"
+#define CONF_KEY_SAMPLE_EDITOR_X          "sample_editor_x"
+#define CONF_KEY_SAMPLE_EDITOR_Y          "sample_editor_y"
+#define CONF_KEY_SAMPLE_EDITOR_W          "sample_editor_w"
+#define CONF_KEY_SAMPLE_EDITOR_H          "sample_editor_h"
+#define CONF_KEY_SAMPLE_EDITOR_GRID_VAL   "sample_editor_grid_val"
+#define CONF_KEY_SAMPLE_EDITOR_GRID_ON    "sample_editor_grid_on"
+#define CONF_KEY_PIANO_ROLL_Y             "piano_roll_y"
+#define CONF_KEY_PIANO_ROLL_H             "piano_roll_h"
+#define CONF_KEY_PLUGIN_LIST_X            "plugin_list_x"
+#define CONF_KEY_PLUGIN_LIST_Y            "plugin_list_y"
+#define CONF_KEY_CONFIG_X                 "config_x"
+#define CONF_KEY_CONFIG_Y                 "config_y"
+#define CONF_KEY_BPM_X                    "bpm_x"
+#define CONF_KEY_BPM_Y                    "bpm_y"
+#define CONF_KEY_BEATS_X                  "beats_x"
+#define CONF_KEY_BEATS_Y                  "beats_y"
+#define CONF_KEY_ABOUT_X                  "about_x"
+#define CONF_KEY_ABOUT_Y                  "about_y"
+
+/* JSON midimaps keys */
+
+#define MIDIMAP_KEY_BRAND          "brand"
+#define MIDIMAP_KEY_DEVICE         "device"
+#define MIDIMAP_KEY_INIT_COMMANDS  "init_commands"
+#define MIDIMAP_KEY_MUTE_ON        "mute_on"
+#define MIDIMAP_KEY_MUTE_OFF       "mute_off"
+#define MIDIMAP_KEY_SOLO_ON        "solo_on"
+#define MIDIMAP_KEY_SOLO_OFF       "solo_off"
+#define MIDIMAP_KEY_WAITING        "waiting"
+#define MIDIMAP_KEY_PLAYING        "playing"
+#define MIDIMAP_KEY_STOPPING       "stopping"
+#define MIDIMAP_KEY_STOPPED        "stopped"
+#define MIDIMAP_KEY_CHANNEL        "channel"
+#define MIDIMAP_KEY_MESSAGE        "message"
+
 #endif
diff --git a/src/core/dataStorageIni.cpp b/src/core/dataStorageIni.cpp
index abf374b..5b4a5ec 100644
--- a/src/core/dataStorageIni.cpp
+++ b/src/core/dataStorageIni.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/dataStorageIni.h b/src/core/dataStorageIni.h
index 17b65a9..9dbf947 100644
--- a/src/core/dataStorageIni.h
+++ b/src/core/dataStorageIni.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/dataStorageJson.cpp b/src/core/dataStorageJson.cpp
index d8ffb86..0a48542 100644
--- a/src/core/dataStorageJson.cpp
+++ b/src/core/dataStorageJson.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/dataStorageJson.h b/src/core/dataStorageJson.h
index ad3cdea..eb43ef3 100644
--- a/src/core/dataStorageJson.h
+++ b/src/core/dataStorageJson.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/graphics.cpp b/src/core/graphics.cpp
index 7bed054..19865b6 100644
--- a/src/core/graphics.cpp
+++ b/src/core/graphics.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/graphics.h b/src/core/graphics.h
index c8d9073..39fde45 100644
--- a/src/core/graphics.h
+++ b/src/core/graphics.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/init.cpp b/src/core/init.cpp
index 473ecac..f3a5a39 100644
--- a/src/core/init.cpp
+++ b/src/core/init.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -63,14 +63,17 @@ extern PluginHost	   G_PluginHost;
 
 void init_prepareParser()
 {
+	time_t t;
+  time (&t);
+	gLog("[init] Giada " G_VERSION_STR " - %s", ctime(&t));
+
 	G_Conf.read();
 	G_Patch_DEPR_.setDefault();
 	G_Patch.init();
+
 	if (!gLog_init(G_Conf.logMode))
 		gLog("[init] log init failed! Using default stdout\n");
-  time_t t;
-  time (&t);
-	gLog("[init] Giada " G_VERSION_STR " - %s", ctime(&t));
+
 	gLog("[init] configuration file ready\n");
 }
 
@@ -110,8 +113,17 @@ void init_prepareKernelMIDI()
 void init_prepareMidiMap()
 {
 	G_MidiMap.init();
+	G_MidiMap.setDefault_DEPR_();
 	G_MidiMap.setDefault();
-	G_MidiMap.readMap(G_Conf.midiMapPath);
+
+	/* read with deprecated method first. If it fails, try with the new one. */
+	// TODO - do the opposite: if json fails, go with deprecated one
+
+	if (G_MidiMap.read(G_Conf.midiMapPath) != MIDIMAP_READ_OK) {
+		gLog("[init_prepareMidiMap] JSON-based midimap read failed, trying with the deprecated one...\n");
+		if (G_MidiMap.readMap_DEPR_(G_Conf.midiMapPath) == MIDIMAP_INVALID)
+			gLog("[init_prepareMidiMap] unable to read deprecated midimap. Nothing to do\n");
+		}
 }
 
 
diff --git a/src/core/init.h b/src/core/init.h
index 0824f65..7d631bc 100644
--- a/src/core/init.h
+++ b/src/core/init.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/kernelAudio.cpp b/src/core/kernelAudio.cpp
index c31d507..a9a4df0 100644
--- a/src/core/kernelAudio.cpp
+++ b/src/core/kernelAudio.cpp
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * KernelAudio
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,10 +24,11 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <vector>
+#include <cstring>
 #include "../utils/log.h"
 #include "../glue/glue.h"
 #include "kernelAudio.h"
@@ -41,8 +42,8 @@ extern Conf  G_Conf;
 extern bool	 G_audio_status;
 
 
-namespace kernelAudio {
-
+namespace kernelAudio
+{
 RtAudio  *system       = NULL;
 unsigned  numDevs      = 0;
 bool 		  inputEnabled = 0;
@@ -101,7 +102,7 @@ int openDevice(
 	else {
 		gLog("[KA] %d device(s) found\n", numDevs);
 		for (unsigned i=0; i<numDevs; i++)
-			gLog("  %d) %s\n", i, getDeviceName(i));
+			gLog("  %d) %s\n", i, getDeviceName(i).c_str());
 	}
 
 
@@ -142,28 +143,15 @@ int openDevice(
 #endif
 
 	try {
-		if (inDev != -1) {
-			system->openStream(
-				&outParams, 					// output params
-				&inParams, 			  		// input params
-				RTAUDIO_FLOAT32,			// audio format
-				samplerate, 					// sample rate
-				&realBufsize, 				// buffer size in byte
-				&G_Mixer.masterPlay,  // audio callback
-				NULL,									// user data (unused)
-				&options);
-		}
-		else {
-			system->openStream(
-				&outParams, 					// output params
-				NULL, 	     		  		// input params
-				RTAUDIO_FLOAT32,			// audio format
-				samplerate, 					// sample rate
-				&realBufsize, 				// buffer size in byte
-				&G_Mixer.masterPlay,  // audio callback
-				NULL,									// user data (unused)
-				&options);
-		}
+		system->openStream(
+			&outParams, 					          // output params
+			inDev != -1 ? &inParams : NULL, // input params if inDevice is selected
+			RTAUDIO_FLOAT32,			          // audio format
+			samplerate, 					          // sample rate
+			&realBufsize, 				          // buffer size in byte
+			&G_Mixer.masterPlay,            // audio callback
+			NULL,									          // user data (unused)
+			&options);
 		G_audio_status = true;
 
 #if defined(__linux__)
@@ -182,10 +170,11 @@ int openDevice(
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int startStream() {
+int startStream()
+{
 	try {
 		system->startStream();
 		gLog("[KA] latency = %lu\n", system->getStreamLatency());
@@ -198,10 +187,11 @@ int startStream() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int stopStream() {
+int stopStream()
+{
 	try {
 		system->stopStream();
 		return 1;
@@ -213,24 +203,26 @@ int stopStream() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-const char *getDeviceName(unsigned dev) {
+string getDeviceName(unsigned dev)
+{
 	try {
-		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).name.c_str();
+		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).name;
 	}
 	catch (RtAudioError &e) {
 		gLog("[KA] invalid device ID = %d\n", dev);
-		return NULL;
+		return "";
 	}
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int closeDevice() {
+int closeDevice()
+{
 	if (system->isStreamOpen()) {
 #if defined(__linux__) || defined(__APPLE__)
 		system->abortStream(); // stopStream seems to lock the thread
@@ -245,11 +237,11 @@ int closeDevice() {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-unsigned getMaxInChans(int dev) {
 
+unsigned getMaxInChans(int dev)
+{
 	if (dev == -1) return 0;
 
 	try {
@@ -262,10 +254,11 @@ unsigned getMaxInChans(int dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-unsigned getMaxOutChans(unsigned dev) {
+unsigned getMaxOutChans(unsigned dev)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).outputChannels;
 	}
@@ -276,10 +269,11 @@ unsigned getMaxOutChans(unsigned dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-bool isProbed(unsigned dev) {
+bool isProbed(unsigned dev)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).probed;
 	}
@@ -289,10 +283,11 @@ bool isProbed(unsigned dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-unsigned getDuplexChans(unsigned dev) {
+unsigned getDuplexChans(unsigned dev)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).duplexChannels;
 	}
@@ -302,10 +297,11 @@ unsigned getDuplexChans(unsigned dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-bool isDefaultIn(unsigned dev) {
+bool isDefaultIn(unsigned dev)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).isDefaultInput;
 	}
@@ -315,10 +311,11 @@ bool isDefaultIn(unsigned dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-bool isDefaultOut(unsigned dev) {
+bool isDefaultOut(unsigned dev)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).isDefaultOutput;
 	}
@@ -328,10 +325,11 @@ bool isDefaultOut(unsigned dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int getTotalFreqs(unsigned dev) {
+int getTotalFreqs(unsigned dev)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).sampleRates.size();
 	}
@@ -341,10 +339,11 @@ int getTotalFreqs(unsigned dev) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int	getFreq(unsigned dev, int i) {
+int	getFreq(unsigned dev, int i)
+{
 	try {
 		return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).sampleRates.at(i);
 	}
@@ -354,33 +353,37 @@ int	getFreq(unsigned dev, int i) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int getDefaultIn() {
+int getDefaultIn()
+{
 	return system->getDefaultInputDevice();
 }
 
-int getDefaultOut() {
+int getDefaultOut()
+{
 	return system->getDefaultOutputDevice();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int	getDeviceByName(const char *name) {
+int	getDeviceByName(const char *name)
+{
 	for (unsigned i=0; i<numDevs; i++)
-		if (strcmp(name, getDeviceName(i))==0)
+		if (name == getDeviceName(i))
 			return i;
 	return -1;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-bool hasAPI(int API) {
+bool hasAPI(int API)
+{
 	std::vector<RtAudio::Api> APIs;
 	RtAudio::getCompiledApi(APIs);
 	for (unsigned i=0; i<APIs.size(); i++)
@@ -390,15 +393,16 @@ bool hasAPI(int API) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-std::string getRtAudioVersion() {
+std::string getRtAudioVersion()
+{
 	return RtAudio::getVersion();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 #ifdef __linux__
@@ -406,11 +410,13 @@ std::string getRtAudioVersion() {
 #include <jack/intclient.h>
 #include <jack/transport.h>
 
-jack_client_t *jackGetHandle() {
+jack_client_t *jackGetHandle()
+{
 	return (jack_client_t*) system->rtapi_->__HACK__getJackClient();
 }
 
-void jackStart() {
+void jackStart()
+{
 	if (api == SYS_API_JACK) {
 		jack_client_t *client = jackGetHandle();
 		jack_transport_start(client);
@@ -418,7 +424,8 @@ void jackStart() {
 }
 
 
-void jackStop() {
+void jackStop()
+{
 	if (api == SYS_API_JACK) {
 		jack_client_t *client = jackGetHandle();
 		jack_transport_stop(client);
@@ -426,7 +433,8 @@ void jackStop() {
 }
 
 
-void jackSetSyncCb() {
+void jackSetSyncCb()
+{
 	jack_client_t *client = jackGetHandle();
 	jack_set_sync_callback(client, jackSyncCb, NULL);
 	//jack_set_sync_timeout(client, 8);
@@ -464,5 +472,3 @@ int jackSyncCb(jack_transport_state_t state, jack_position_t *pos,
 #endif
 
 }
-
-
diff --git a/src/core/kernelAudio.h b/src/core/kernelAudio.h
index a4673f2..2ab1e12 100644
--- a/src/core/kernelAudio.h
+++ b/src/core/kernelAudio.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -39,6 +39,9 @@
 #endif
 
 
+using std::string;
+
+
 namespace kernelAudio {
 
 	int openDevice(
@@ -54,21 +57,20 @@ namespace kernelAudio {
 	int startStream();
 	int stopStream();
 
-	bool			  isProbed       (unsigned dev);
-	bool		    isDefaultIn    (unsigned dev);
-	bool			  isDefaultOut   (unsigned dev);
-	const char *getDeviceName  (unsigned dev);
-	unsigned    getMaxInChans  (int dev);
-	unsigned    getMaxOutChans (unsigned dev);
-	unsigned    getDuplexChans (unsigned dev);
-	int         getTotalFreqs  (unsigned dev);
-	int					getFreq        (unsigned dev, int i);
-	int					getDeviceByName(const char *name);
-	int         getDefaultOut  ();
-	int         getDefaultIn   ();
-	bool        hasAPI         (int API);
-
-	std::string getRtAudioVersion();
+	bool			  isProbed         (unsigned dev);
+	bool		    isDefaultIn      (unsigned dev);
+	bool			  isDefaultOut     (unsigned dev);
+	string      getDeviceName    (unsigned dev);
+	unsigned    getMaxInChans    (int dev);
+	unsigned    getMaxOutChans   (unsigned dev);
+	unsigned    getDuplexChans   (unsigned dev);
+	int         getTotalFreqs    (unsigned dev);
+	int					getFreq          (unsigned dev, int i);
+	int					getDeviceByName  (const char *name);
+	int         getDefaultOut    ();
+	int         getDefaultIn     ();
+	bool        hasAPI           (int API);
+	string      getRtAudioVersion();
 
 #ifdef __linux__
 	jack_client_t *jackGetHandle();
diff --git a/src/core/kernelMidi.cpp b/src/core/kernelMidi.cpp
index d695ef8..402e88d 100644
--- a/src/core/kernelMidi.cpp
+++ b/src/core/kernelMidi.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -49,9 +49,11 @@ extern PluginHost  G_PluginHost;
 #endif
 
 
+using std::string;
+
+
 namespace kernelMidi
 {
-
 int        api         = 0;      // one api for both in & out
 RtMidiOut *midiOut     = NULL;
 RtMidiIn  *midiIn      = NULL;
@@ -62,6 +64,18 @@ cb_midiLearn *cb_learn = NULL;
 void         *cb_data  = NULL;
 
 
+void __sendMidiLightningInitMsgs__()
+{
+	for(unsigned i=0; i<G_MidiMap.initCommands.size(); i++) {
+		MidiMapConf::message_t msg = G_MidiMap.initCommands.at(i);
+		if (msg.value != 0x0 && msg.channel != -1) {
+			gLog("[KM] MIDI send (init) - Channel %x - Event 0x%X\n", msg.channel, msg.value);
+			send(msg.value | MIDI_CHANS[msg.channel]);
+		}
+	}
+}
+
+
 /* -------------------------------------------------------------------------- */
 
 
@@ -87,7 +101,7 @@ void stopMidiLearn()
 
 void setApi(int _api)
 {
-	api = api;
+	api = _api;
 	gLog("[KM] using system 0x%x\n", api);
 }
 
@@ -112,7 +126,7 @@ int openOutDevice(int port)
 	numOutPorts = midiOut->getPortCount();
   gLog("[KM] %d output MIDI ports found\n", numOutPorts);
   for (unsigned i=0; i<numOutPorts; i++)
-		gLog("  %d) %s\n", i, getOutPortName(i));
+		gLog("  %d) %s\n", i, getOutPortName(i).c_str());
 
 	/* try to open a port, if enabled */
 
@@ -121,18 +135,10 @@ int openOutDevice(int port)
 			midiOut->openPort(port, getOutPortName(port));
 			gLog("[KM] MIDI out port %d open\n", port);
 
-			/* for each init command of MidiMap, send the init commands to the
-			external world. TODO 1 - we shold do that only if there is a map loaded
-			and available in MidiMap.
-			TODO 2 - move the map initialization to another function */
-
-			for(int i=0; i<G_MidiMap.MAX_INIT_COMMANDS; i++) {
-				if (G_MidiMap.init_messages[i] != 0x0 && G_MidiMap.init_channels[i] != -1) {
-					gLog("[KM] MIDI send (init) - Channel %x - Event 0x%X\n", G_MidiMap.init_channels[i], G_MidiMap.init_messages[i]);
-					send(G_MidiMap.init_messages[i] | MIDI_CHANS[G_MidiMap.init_channels[i]]);
-				}
-			}
+			/* TODO - it shold send midiLightning message only if there is a map loaded
+			and available in G_MidiMap. */
 
+			__sendMidiLightningInitMsgs__();
 			return 1;
 		}
 		catch (RtMidiError &error) {
@@ -166,7 +172,7 @@ int openInDevice(int port)
 	numInPorts = midiIn->getPortCount();
   gLog("[KM] %d input MIDI ports found\n", numInPorts);
   for (unsigned i=0; i<numInPorts; i++)
-		gLog("  %d) %s\n", i, getInPortName(i));
+		gLog("  %d) %s\n", i, getInPortName(i).c_str());
 
 	/* try to open a port, if enabled */
 
@@ -206,16 +212,16 @@ bool hasAPI(int API)
 /* -------------------------------------------------------------------------- */
 
 
-const char *getOutPortName(unsigned p)
+string getOutPortName(unsigned p)
 {
-	try { return midiOut->getPortName(p).c_str(); }
-	catch (RtMidiError &error) { return NULL; }
+	try { return midiOut->getPortName(p); }
+	catch (RtMidiError &error) { return ""; }
 }
 
-const char *getInPortName(unsigned p)
+string getInPortName(unsigned p)
 {
-	try { return midiIn->getPortName(p).c_str(); }
-	catch (RtMidiError &error) { return NULL; }
+	try { return midiIn->getPortName(p); }
+	catch (RtMidiError &error) { return ""; }
 }
 
 
@@ -341,7 +347,7 @@ void callback(double t, std::vector<unsigned char> *msg, void *data)
 
 		/* process channels */
 
-		for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+		for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 
 			Channel *ch = (Channel*) G_Mixer.channels.at(i);
 
@@ -392,4 +398,7 @@ std::string getRtMidiVersion()
 }
 
 
+/* -------------------------------------------------------------------------- */
+
+
 }  // namespace
diff --git a/src/core/kernelMidi.h b/src/core/kernelMidi.h
index d446995..161a953 100644
--- a/src/core/kernelMidi.h
+++ b/src/core/kernelMidi.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,6 +36,9 @@
 #include "channel.h"
 
 
+using std::string;
+
+
 namespace kernelMidi {
 
 	extern int      api;      // one api for both in & out
@@ -88,8 +91,8 @@ namespace kernelMidi {
 	/* getIn/OutPortName
 	 * return the name of the port 'p'. */
 
-	const char *getInPortName(unsigned p);
-	const char *getOutPortName(unsigned p);
+	string getInPortName(unsigned p);
+	string getOutPortName(unsigned p);
 
 	bool hasAPI(int API);
 
@@ -98,7 +101,7 @@ namespace kernelMidi {
 
 	void callback(double t, std::vector<unsigned char> *msg, void *data);
 
-	std::string getRtMidiVersion();
+	string getRtMidiVersion();
 }
 
 #endif
diff --git a/src/core/midiChannel.cpp b/src/core/midiChannel.cpp
index a890f38..a5d3cc7 100644
--- a/src/core/midiChannel.cpp
+++ b/src/core/midiChannel.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -66,6 +66,18 @@ MidiChannel::~MidiChannel() {}
 /* -------------------------------------------------------------------------- */
 
 
+void MidiChannel::copy(const Channel *_src)
+{
+	Channel::copy(_src);
+	MidiChannel *src = (MidiChannel *) _src;
+	midiOut     = src->midiOut;
+	midiOutChan = src->midiOutChan;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
 #ifdef WITH_VST
 
 void MidiChannel::freeVstMidiEvents(bool init)
@@ -307,7 +319,7 @@ int MidiChannel::readPatch(const string &basePath, int i)
 
 	midiOut     = pch->midiOut;
 	midiOutChan = pch->midiOutChan;
-	
+
 	return SAMPLE_LOADED_OK;  /// TODO - change name, it's meaningless here
 }
 
diff --git a/src/core/midiChannel.h b/src/core/midiChannel.h
index cd26ad9..01f197b 100644
--- a/src/core/midiChannel.h
+++ b/src/core/midiChannel.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -60,6 +60,7 @@ public:
   bool    midiOut;           // enable midi output
   uint8_t midiOutChan;       // midi output channel
 
+	void copy       (const Channel *src);
 	void process    (float *buffer);
 	void start      (int frame, bool doQuantize);
 	void kill       (int frame);
diff --git a/src/core/midiMapConf.cpp b/src/core/midiMapConf.cpp
index 9a0dfc5..bba90bd 100644
--- a/src/core/midiMapConf.cpp
+++ b/src/core/midiMapConf.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -28,6 +28,7 @@
 
 
 #include <stdlib.h>
+#include <vector>
 #include <iostream>
 #include <string>
 #include <sstream>
@@ -39,11 +40,13 @@
 
 
 using std::string;
+using std::vector;
+
 
 
 void MidiMapConf::init()
 {
-	midimapsPath = gGetHomePath() + "/midimaps/";
+	midimapsPath = gGetHomePath() + gGetSlash() + "midimaps" + gGetSlash();
 
 	/* scan dir of midi maps and load the filenames into <>maps. */
 
@@ -66,9 +69,10 @@ void MidiMapConf::init()
 
 		gLog("[MidiMapConf::init] found midimap '%s'\n", ep->d_name);
 
-		maps.add(ep->d_name);
+		maps.push_back(ep->d_name);
 	}
 
+	gLog("[MidiMapConf::init] total midimaps found: %d\n", maps.size());
 	closedir(dp);
 }
 
@@ -80,6 +84,172 @@ void MidiMapConf::setDefault()
 {
 	brand  = "";
 	device = "";
+	muteOn.channel    = 0;
+	muteOn.valueStr   = "";
+	muteOn.offset     = -1;
+	muteOn.value      = 0;
+	muteOff.channel   = 0;
+	muteOff.valueStr  = "";
+	muteOff.offset    = -1;
+	muteOff.value     = 0;
+	soloOn.channel    = 0;
+	soloOn.valueStr   = "";
+	soloOn.offset     = -1;
+	soloOn.value      = 0;
+	soloOff.channel   = 0;
+	soloOff.valueStr  = "";
+	soloOff.offset    = -1;
+	soloOff.value     = 0;
+	waiting.channel   = 0;
+	waiting.valueStr  = "";
+	waiting.offset    = -1;
+	waiting.value     = 0;
+	playing.channel   = 0;
+	playing.valueStr  = "";
+	playing.offset    = -1;
+	playing.value     = 0;
+	stopping.channel  = 0;
+	stopping.valueStr = "";
+	stopping.offset   = -1;
+	stopping.value    = 0;
+	stopped.channel   = 0;
+	stopped.valueStr  = "";
+	stopped.offset    = -1;
+	stopped.value     = 0;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int MidiMapConf::read(const string &file)
+{
+	if (file.empty()) {
+		gLog("[MidiMapConf::read] midimap not specified, nothing to do\n");
+		return MIDIMAP_NOT_SPECIFIED;
+	}
+
+	gLog("[MidiMapConf::read] reading midimap file '%s'\n", file.c_str());
+
+	string path = midimapsPath + file;
+	jRoot = json_load_file(path.c_str(), 0, &jError);
+	if (!jRoot) {
+    gLog("[MidiMapConf::read] unreadable midimap file. Error on line %d: %s\n", jError.line, jError.text);
+    return MIDIMAP_UNREADABLE;
+  }
+
+	if (!setString(jRoot, MIDIMAP_KEY_BRAND, brand))   return MIDIMAP_UNREADABLE;
+  if (!setString(jRoot, MIDIMAP_KEY_DEVICE, device)) return MIDIMAP_UNREADABLE;
+	if (!readInitCommands(jRoot)) return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &muteOn,   MIDIMAP_KEY_MUTE_ON))  return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &muteOff,  MIDIMAP_KEY_MUTE_OFF)) return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &soloOn,   MIDIMAP_KEY_SOLO_ON))  return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &soloOff,  MIDIMAP_KEY_SOLO_OFF)) return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &waiting,  MIDIMAP_KEY_WAITING))  return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &playing,  MIDIMAP_KEY_PLAYING))  return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &stopping, MIDIMAP_KEY_STOPPING)) return MIDIMAP_UNREADABLE;
+	if (!readCommand(jRoot, &stopped,  MIDIMAP_KEY_STOPPED))  return MIDIMAP_UNREADABLE;
+
+	/* parse messages */
+
+	parse(&muteOn);
+	parse(&muteOff);
+	parse(&soloOn);
+	parse(&soloOff);
+	parse(&waiting);
+	parse(&playing);
+	parse(&stopping);
+	parse(&stopped);
+
+	return MIDIMAP_READ_OK;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool MidiMapConf::readInitCommands(json_t *jContainer)
+{
+	json_t *jInitCommands = json_object_get(jContainer, MIDIMAP_KEY_INIT_COMMANDS);
+  if (!checkArray(jInitCommands, MIDIMAP_KEY_INIT_COMMANDS))
+    return 0;
+
+	size_t commandIndex;
+	json_t *jInitCommand;
+	json_array_foreach(jInitCommands, commandIndex, jInitCommand) {
+
+		string indexStr = "init command " + gItoa(commandIndex);
+		if (!checkObject(jInitCommand, indexStr.c_str()))
+			return 0;
+
+		message_t message;
+    if (!setInt(jInitCommand, MIDIMAP_KEY_CHANNEL, message.channel)) return 0;
+    if (!setString(jInitCommand, MIDIMAP_KEY_MESSAGE, message.valueStr)) return 0;
+		message.value = strtoul(message.valueStr.c_str(), NULL, 16);
+
+    initCommands.push_back(message);
+	}
+
+	return 1;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool MidiMapConf::readCommand(json_t *jContainer, message_t *msg, const string &key)
+{
+	json_t *jCommand = json_object_get(jContainer, key.c_str());
+  if (!checkObject(jCommand, key.c_str()))
+    return 0;
+
+  if (!setInt(jCommand, MIDIMAP_KEY_CHANNEL, msg->channel)) return 0;
+  if (!setString(jCommand, MIDIMAP_KEY_MESSAGE, msg->valueStr)) return 0;
+
+	return 1;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void MidiMapConf::parse(message_t *message)
+{
+	/* Remove '0x' part from the original string. */
+
+	string input = message->valueStr.replace(0, 2, "");
+
+	/* Then transform string value into the actual uint32_t value, by parsing
+	 * each char (i.e. nibble) in the original string. Substitute 'n' with
+	 * zeros. */
+
+	string output;
+	for (unsigned i=0, p=24; i<input.length(); i++, p-=4) {
+		if (input[i] == 'n') {
+			output += '0';
+			if (message->offset == -1) // do it once
+				message->offset = p;
+		}
+		else
+			output += input[i];
+	}
+
+	/* from string to uint32_t */
+
+	message->value = strtoul(output.c_str(), NULL, 16);
+
+	gLog("[MidiMapConf::parse] parsed chan=%d valueStr=%s value=%#x, offset=%d\n",
+			message->channel, message->valueStr.c_str(), message->value, message->offset);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void MidiMapConf::setDefault_DEPR_()
+{
+	brand  = "";
+	device = "";
 
 	for (int i=0; i<MAX_INIT_COMMANDS; i++) {
 		init_channels[i] = -1;
@@ -123,58 +293,97 @@ void MidiMapConf::setDefault()
 /* -------------------------------------------------------------------------- */
 
 
-int MidiMapConf::readMap(string file)
+int MidiMapConf::readMap_DEPR_(string file)
 {
 	if (file.empty()) {
-		gLog("[MidiMapConf::readFromFile] midimap not specified, nothing to do\n");
-		return 0;
+		gLog("[MidiMapConf::readMap_DEPR_] midimap not specified, nothing to do\n");
+		return MIDIMAP_NOT_SPECIFIED;
 	}
 
-	gLog("[MidiMapConf::readFromFile] reading midimap file '%s'\n", file.c_str());
+	gLog("[MidiMapConf::readMap_DEPR_] reading midimap file '%s'\n", file.c_str());
 
 	string path = midimapsPath + file;
 	fp = fopen(path.c_str(), "r");
 	if (!fp) {
-		gLog("[MidiMapConf::readFromFile] unreadable midimap file\n");
-		return 0;
+		gLog("[MidiMapConf::readMap_DEPR_] unreadable midimap file\n");
+		return MIDIMAP_UNREADABLE;
 	}
 
 	brand  = getValue("brand");
 	device = getValue("device");
 
-	gLog("[MidiMapConf::readFromFile] reading midimap for %s %s\n",
+	if (brand.empty() || device.empty()) {
+		gLog("[MidiMapConf::readMap_DEPR_] invalid midimap file\n");
+		return MIDIMAP_INVALID;
+	}
+
+	gLog("[MidiMapConf::readMap_DEPR_] reading midimap for %s %s\n",
 			brand.c_str(), device.c_str());
 
 	/* parse init commands */
 
-	gVector<string> ic;
+	vector<string> ic;
 	gSplit(getValue("init_commands"), ";", &ic);
-	for (unsigned i=0; i<(unsigned)MAX_INIT_COMMANDS && i<ic.size; i++) {
+	for (unsigned i=0; i<(unsigned)MAX_INIT_COMMANDS && i<ic.size(); i++) {
 		sscanf(ic.at(i).c_str(), "%d:%x", &init_channels[i], &init_messages[i]);
-		gLog("[MidiMapConf::readFromFile] init command %d - channel %d - message 0x%X\n",
+		gLog("[MidiMapConf::readMap_DEPR_] init command %d - channel %d - message 0x%X\n",
 				i, init_channels[i], init_messages[i]);
+
+		/* forward compatibility */
+		message_t message;
+		message.channel = init_channels[i];
+		message.value   = init_messages[i];
+		initCommands.push_back(message);
 	}
 
 	/* parse messages */
 
-	parse("mute_on",  &muteOnChan,   &muteOnMsg,   &muteOnOffset);
-	parse("mute_off", &muteOffChan,  &muteOffMsg,  &muteOffOffset);
-	parse("solo_on",  &soloOnChan,   &soloOnMsg,   &soloOnOffset);
-	parse("solo_off", &soloOffChan,  &soloOffMsg,  &soloOffOffset);
-	parse("waiting",  &waitingChan,  &waitingMsg,  &waitingOffset);
-	parse("playing",  &playingChan,  &playingMsg,  &playingOffset);
-	parse("stopping", &stoppingChan, &stoppingMsg, &stoppingOffset);
-	parse("stopped",  &stoppedChan,  &stoppedMsg,  &stoppedOffset);
-
-	close();
-	return 1;
+	parse_DEPR_("mute_on",  &muteOnChan,   &muteOnMsg,   &muteOnOffset);
+	parse_DEPR_("mute_off", &muteOffChan,  &muteOffMsg,  &muteOffOffset);
+	parse_DEPR_("solo_on",  &soloOnChan,   &soloOnMsg,   &soloOnOffset);
+	parse_DEPR_("solo_off", &soloOffChan,  &soloOffMsg,  &soloOffOffset);
+	parse_DEPR_("waiting",  &waitingChan,  &waitingMsg,  &waitingOffset);
+	parse_DEPR_("playing",  &playingChan,  &playingMsg,  &playingOffset);
+	parse_DEPR_("stopping", &stoppingChan, &stoppingMsg, &stoppingOffset);
+	parse_DEPR_("stopped",  &stoppedChan,  &stoppedMsg,  &stoppedOffset);
+
+	/* forward compatibility with new JSON-based midimaps. This stuff will be
+	wiped out soon. */
+
+	muteOn.channel   = muteOnChan;
+	muteOn.offset    = muteOnOffset;
+	muteOn.value     = muteOnMsg;
+	muteOff.channel  = muteOffChan;
+	muteOff.offset   = muteOffOffset;
+	muteOff.value    = muteOffMsg;
+	soloOn.channel   = soloOnChan;
+	soloOn.offset    = soloOnOffset;
+	soloOn.value     = soloOnMsg;
+	soloOff.channel  = soloOffChan;
+	soloOff.offset   = soloOffOffset;
+	soloOff.value    = soloOffMsg;
+	waiting.channel  = waitingChan;
+	waiting.offset   = waitingOffset;
+	waiting.value    = waitingMsg;
+	playing.channel  = playingChan;
+	playing.offset   = playingOffset;
+	playing.value    = playingMsg;
+	stopping.channel = stoppingChan;
+	stopping.offset  = stoppingOffset;
+	stopping.value   = stoppingMsg;
+	stopped.channel  = stoppedChan;
+	stopped.offset   = stoppedOffset;
+	stopped.value    = stoppedMsg;
+
+	close_DEPR_();
+	return MIDIMAP_READ_OK;
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void MidiMapConf::close()
+void MidiMapConf::close_DEPR_()
 {
 	if (fp != NULL)
 		fclose(fp);
@@ -185,9 +394,9 @@ void MidiMapConf::close()
 /* -------------------------------------------------------------------------- */
 
 
-void MidiMapConf::parse(string key, int *chan, uint32_t *msg, int *offset)
+void MidiMapConf::parse_DEPR_(string key, int *chan, uint32_t *msg, int *offset)
 {
-	gLog("[MidiMapConf::parse2] command %s - ", key.c_str());
+	gLog("[MidiMapConf::parse_DEPR_] command %s - ", key.c_str());
 	string value = getValue(key.c_str());
 
 	/* grab channel part, i.e. [channel]:*/
diff --git a/src/core/midiMapConf.h b/src/core/midiMapConf.h
index 3f397be..fd07358 100644
--- a/src/core/midiMapConf.h
+++ b/src/core/midiMapConf.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -33,7 +33,9 @@
 
 #include <limits.h>
 #include <stdint.h>
+#include <vector>
 #include "dataStorageIni.h"
+#include "dataStorageJson.h"
 #include "../utils/utils.h"
 #if defined(__APPLE__)
 #include <pwd.h>
@@ -41,20 +43,32 @@
 
 
 using std::string;
+using std::vector;
 
 
-class MidiMapConf : public DataStorageIni
+class MidiMapConf : public DataStorageIni, public DataStorageJson
 {
-private:
-
-	void close();
-	void parse(string key, int *chan, uint32_t *msg, int *offset);
-
 public:
 
-	static const int MAX_INIT_COMMANDS = 32;
-	static const int MAX_MIDI_BYTES = 4;
-	static const int MAX_MIDI_NIBBLES = 8;
+	struct message_t
+  {
+    int      channel;
+    string   valueStr;
+		int      offset;
+		uint32_t value;
+  };
+
+	string brand;
+  string device;
+	vector<message_t> initCommands;
+	message_t muteOn;
+	message_t muteOff;
+	message_t soloOn;
+	message_t soloOff;
+	message_t waiting;
+	message_t playing;
+	message_t stopping;
+	message_t stopped;
 
 	/* midimapsPath
 	 * path of midimap files, different between OSes. */
@@ -65,10 +79,30 @@ public:
 	 * Maps are the available .giadamap files. Each element of the vector
 	 * represents a .giadamap filename. */
 
-	gVector<string> maps;
+	vector<string> maps;
 
-	string brand;
-	string device;
+	/* init
+	Parse the midi maps folders and find the available maps. */
+
+	void init();
+
+	/* setDefault
+	Set default values in case no maps are available/choosen. */
+
+	void setDefault();
+
+	/* read
+	Read a midi map from file 'file'. */
+
+	int read(const string &file);
+
+	/* --- DEPRECATED STUFF --------------------------------------------------- */
+	/* --- DEPRECATED STUFF --------------------------------------------------- */
+	/* --- DEPRECATED STUFF --------------------------------------------------- */
+
+	static const int MAX_INIT_COMMANDS = 32;
+	static const int MAX_MIDI_BYTES = 4;
+	static const int MAX_MIDI_NIBBLES = 8;
 
 	/* init_*
 	 * init_commands. These messages are sent to the physical device as a wake up
@@ -114,20 +148,30 @@ public:
 	int      stoppedOffset;
 	uint32_t stoppedMsg;
 
-	/* init
-	Parse the midi maps folders and find the available maps. */
-
-	void init();
-
 	/* setDefault
 	Set default values in case no maps are available/choosen. */
 
-	void setDefault();
+	void setDefault_DEPR_();
 
 	/* readMap
 	Read a midi map from file 'file'. */
 
-	int readMap(string file);
+	int readMap_DEPR_(string file);
+
+private:
+
+	bool readInitCommands(json_t *jContainer);
+
+	bool readCommand(json_t *jContainer, message_t *msg, const string &key);
+
+	void parse(message_t *message);
+
+	/* --- DEPRECATED STUFF --------------------------------------------------- */
+	/* --- DEPRECATED STUFF --------------------------------------------------- */
+	/* --- DEPRECATED STUFF --------------------------------------------------- */
+
+	void close_DEPR_();
+	void parse_DEPR_(string key, int *chan, uint32_t *msg, int *offset);
 };
 
 #endif
diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp
index 24a9b25..1fa4fdd 100644
--- a/src/core/mixer.cpp
+++ b/src/core/mixer.cpp
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * mixer
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <math.h>
@@ -55,9 +55,7 @@ extern PluginHost  G_PluginHost;
 Mixer::Mixer()
 	: vChanInput(NULL),
 		vChanInToOut(NULL)
-{
-	gLog("[mixer] construct\n");
-}
+{}
 
 
 /* -------------------------------------------------------------------------- */
@@ -94,7 +92,7 @@ float Mixer::tick[TICKSIZE] = {
 };
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void Mixer::init()
@@ -149,7 +147,7 @@ void Mixer::init()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 Channel *Mixer::addChannel(int type)
@@ -165,30 +163,30 @@ Channel *Mixer::addChannel(int type)
 	while (true) {
 		int lockStatus = pthread_mutex_trylock(&mutex_chans);
 		if (lockStatus == 0) {
-			channels.add(ch);
+			channels.push_back(ch);
 			pthread_mutex_unlock(&mutex_chans);
 			break;
 		}
 	}
 
 	ch->index = getNewIndex();
-	gLog("[mixer] channel index=%d added, type=%d, total=%d\n", ch->index, ch->type, channels.size);
+	gLog("[mixer] channel index=%d added, type=%d, total=%d\n", ch->index, ch->type, channels.size());
 	return ch;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Mixer::getNewIndex()
 {
 	/* always skip last channel: it's the last one just added */
 
-	if (channels.size == 1)
+	if (channels.size() == 1)
 		return 0;
 
 	int index = 0;
-	for (unsigned i=0; i<channels.size-1; i++) {
+	for (unsigned i=0; i<channels.size()-1; i++) {
 		if (channels.at(i)->index > index)
 			index = channels.at(i)->index;
 		}
@@ -197,16 +195,29 @@ int Mixer::getNewIndex()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Mixer::deleteChannel(Channel *ch)
 {
+	int index = -1;
+	for (unsigned i=0; i<channels.size(); i++) {
+		if (channels.at(i) == ch) {
+			index = i;
+			break;
+		}
+	}
+
+	if (index == -1) {
+		gLog("[Mixer::deleteChannel] unable to find Channel %d for deletion!\n", ch->index);
+		return 0;
+	}
+
 	int lockStatus;
 	while (true) {
 		lockStatus = pthread_mutex_trylock(&mutex_chans);
 		if (lockStatus == 0) {
-			channels.del(ch);
+			channels.erase(channels.begin() + index);
 			delete ch;
 			pthread_mutex_unlock(&mutex_chans);
 			return 1;
@@ -217,12 +228,12 @@ int Mixer::deleteChannel(Channel *ch)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 Channel *Mixer::getChannelByIndex(int index)
 {
-	for (unsigned i=0; i<channels.size; i++)
+	for (unsigned i=0; i<channels.size(); i++)
 		if (channels.at(i)->index == index)
 			return channels.at(i);
 	gLog("[mixer::getChannelByIndex] channel at index %d not found!\n", index);
@@ -230,7 +241,7 @@ Channel *Mixer::getChannelByIndex(int index)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void Mixer::sendMIDIsync()
@@ -296,7 +307,7 @@ void Mixer::sendMIDIsync()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void Mixer::sendMIDIrewind()
@@ -319,7 +330,7 @@ void Mixer::sendMIDIrewind()
 	}
 }
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Mixer::masterPlay(
@@ -330,7 +341,7 @@ int Mixer::masterPlay(
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
@@ -350,7 +361,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 	memset(vChanInToOut, 0, sizeof(float) * bufferFrames);   // inToOut vChan
 
 	pthread_mutex_lock(&mutex_chans);
-	for (unsigned i=0; i<channels.size; i++)
+	for (unsigned i=0; i<channels.size(); i++)
 		if (channels.at(i)->type == CHANNEL_SAMPLE)
 			((SampleChannel*)channels.at(i))->clear();
 	pthread_mutex_unlock(&mutex_chans);
@@ -409,7 +420,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 						rewind();
 					}
 					pthread_mutex_lock(&mutex_chans);
-					for (unsigned k=0; k<channels.size; k++)
+					for (unsigned k=0; k<channels.size(); k++)
 						channels.at(k)->quantize(k, j, actualFrame);  // j == localFrame
 					pthread_mutex_unlock(&mutex_chans);
 				}
@@ -422,7 +433,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 					tickPlay = true;
 
 				pthread_mutex_lock(&mutex_chans);
-				for (unsigned k=0; k<channels.size; k++)
+				for (unsigned k=0; k<channels.size(); k++)
 					channels.at(k)->onBar(j);
 				pthread_mutex_unlock(&mutex_chans);
 			}
@@ -431,7 +442,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 
 			if (actualFrame == 0) {
 				pthread_mutex_lock(&mutex_chans);
-				for (unsigned k=0; k<channels.size; k++)
+				for (unsigned k=0; k<channels.size(); k++)
 					channels.at(k)->onZero(j);
 				pthread_mutex_unlock(&mutex_chans);
 			}
@@ -439,9 +450,9 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 			/* reading all actions recorded */
 
 			pthread_mutex_lock(&mutex_recs);
-			for (unsigned y=0; y<recorder::frames.size; y++) {
+			for (unsigned y=0; y<recorder::frames.size(); y++) {
 				if (recorder::frames.at(y) == actualFrame) {
-					for (unsigned z=0; z<recorder::global.at(y).size; z++) {
+					for (unsigned z=0; z<recorder::global.at(y).size(); z++) {
 						int index   = recorder::global.at(y).at(z)->chan;
 						Channel *ch = getChannelByIndex(index);
 						ch->parseAction(recorder::global.at(y).at(z), j, actualFrame);
@@ -480,7 +491,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 		/* sum channels, CHANNEL_SAMPLE only */
 
 		pthread_mutex_lock(&mutex_chans);
-		for (unsigned k=0; k<channels.size; k++) {
+		for (unsigned k=0; k<channels.size(); k++) {
 			if (channels.at(k)->type == CHANNEL_SAMPLE)
 				((SampleChannel*)channels.at(k))->sum(j, running);
 		}
@@ -513,7 +524,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 	/* final loop: sum virtual channels and process plugins. */
 
 	pthread_mutex_lock(&mutex_chans);
-	for (unsigned k=0; k<channels.size; k++)
+	for (unsigned k=0; k<channels.size(); k++)
 		channels.at(k)->process(outBuf);
 	pthread_mutex_unlock(&mutex_chans);
 
@@ -562,7 +573,7 @@ int Mixer::__masterPlay(void *out_buf, void *in_buf, unsigned bufferFrames)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void Mixer::updateFrameBars()
@@ -601,13 +612,13 @@ void Mixer::updateFrameBars()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Mixer::close()
 {
 	running = false;
-	while (channels.size > 0)
+	while (channels.size() > 0)
 		deleteChannel(channels.at(0));
 
 	if (vChanInput) {
@@ -622,19 +633,19 @@ int Mixer::close()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 bool Mixer::isSilent()
 {
-	for (unsigned i=0; i<channels.size; i++)
+	for (unsigned i=0; i<channels.size(); i++)
 		if (channels.at(i)->status == STATUS_PLAY)
 			return false;
 	return true;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void Mixer::rewind()
@@ -643,14 +654,14 @@ void Mixer::rewind()
 	actualBeat  = 0;
 
 	if (running)
-		for (unsigned i=0; i<channels.size; i++)
+		for (unsigned i=0; i<channels.size(); i++)
 			channels.at(i)->rewind();
 
 	sendMIDIrewind();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 void Mixer::updateQuanto()
@@ -664,12 +675,12 @@ void Mixer::updateQuanto()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 bool Mixer::hasLogicalSamples()
 {
-	for (unsigned i=0; i<channels.size; i++)
+	for (unsigned i=0; i<channels.size(); i++)
 		if (channels.at(i)->type == CHANNEL_SAMPLE)
 			if (((SampleChannel*)channels.at(i))->wave)
 				if (((SampleChannel*)channels.at(i))->wave->isLogical)
@@ -678,12 +689,12 @@ bool Mixer::hasLogicalSamples()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 bool Mixer::hasEditedSamples()
 {
-	for (unsigned i=0; i<channels.size; i++)
+	for (unsigned i=0; i<channels.size(); i++)
 		if (channels.at(i)->type == CHANNEL_SAMPLE)
 			if (((SampleChannel*)channels.at(i))->wave)
 				if (((SampleChannel*)channels.at(i))->wave->isEdited)
@@ -692,7 +703,7 @@ bool Mixer::hasEditedSamples()
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 bool Mixer::mergeVirtualInput()
diff --git a/src/core/mixer.h b/src/core/mixer.h
index 02eafd4..8387efd 100644
--- a/src/core/mixer.h
+++ b/src/core/mixer.h
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * mixer
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #ifndef MIXER_H
@@ -32,13 +32,17 @@
 
 #include <stdlib.h>
 #include <pthread.h>
+#include <vector>
 #include "const.h"
 #include "kernelAudio.h"
 #include "../utils/utils.h"
 
 
-class Mixer {
+using std::vector;
 
+
+class Mixer
+{
 public:
 
 	Mixer();
@@ -107,7 +111,10 @@ public:
 
 	Channel *getChannelByIndex(int i);
 
-	inline Channel* getLastChannel() { return channels.at(channels.size-1); }
+	/* getLastChannel
+	 * Return last channel in the stack. */
+
+	inline Channel* getLastChannel() { return channels.back(); }
 
 
 	/* ---------------------------------------------------------------- */
@@ -124,7 +131,7 @@ public:
 		XFADE   = 0x02
 	};
 
-	gVector<class Channel*> channels;
+	vector<class Channel*> channels;
 
 	bool   running;
 	bool   ready;
@@ -179,7 +186,6 @@ public:
 	pthread_mutex_t mutex_chans;
 	pthread_mutex_t mutex_plugins;
 
-
 private:
 
 	int midiTCstep;      // part of MTC to send (0 to 7)
diff --git a/src/core/mixerHandler.cpp b/src/core/mixerHandler.cpp
index b03b154..c565971 100644
--- a/src/core/mixerHandler.cpp
+++ b/src/core/mixerHandler.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -33,9 +33,11 @@
 	#include <jack/transport.h>
 #endif
 
+#include <vector>
 #include "../utils/utils.h"
 #include "../utils/log.h"
 #include "../glue/glue.h"
+#include "../glue/channel.h"
 #include "mixerHandler.h"
 #include "kernelMidi.h"
 #include "mixer.h"
@@ -63,10 +65,39 @@ extern PluginHost  G_PluginHost;
 #endif
 
 
+using std::vector;
+
+
+#ifdef WITH_VST
+
+static int __mh_readPatchPlugins__(vector<Patch::plugin_t> *list, int type)
+{
+	int ret = 1;
+	for (unsigned i=0; i<list->size(); i++) {
+		Patch::plugin_t *ppl = &list->at(i);
+		Plugin *plugin = G_PluginHost.addPlugin(ppl->path.c_str(), type, NULL);
+		if (plugin != NULL) {
+			plugin->bypass = ppl->bypass;
+			for (unsigned j=0; j<ppl->params.size(); j++)
+				plugin->setParam(j, ppl->params.at(j));
+			ret &= 1;
+		}
+		else
+			ret &= 0;
+	}
+	return ret;
+}
+
+#endif
+
+
+/* -------------------------------------------------------------------------- */
+
+
 void mh_stopSequencer()
 {
 	G_Mixer.running = false;
-	for (unsigned i=0; i<G_Mixer.channels.size; i++)
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++)
 		G_Mixer.channels.at(i)->stopBySeq();
 }
 
@@ -77,7 +108,7 @@ void mh_stopSequencer()
 bool mh_uniqueSolo(Channel *ch)
 {
 	int solos = 0;
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		Channel *ch = G_Mixer.channels.at(i);
 		if (ch->solo) solos++;
 		if (solos > 1) return false;
@@ -172,7 +203,7 @@ SampleChannel *mh_startInputRec()
 	/* search for the next available channel */
 
 	SampleChannel *chan = NULL;
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE)
 			if (((SampleChannel*) G_Mixer.channels.at(i))->canInputRec()) {
 			chan = (SampleChannel*) G_Mixer.channels.at(i);
@@ -186,7 +217,7 @@ SampleChannel *mh_startInputRec()
 		return NULL;
 
 	Wave *w = new Wave();
-	if (!w->allocEmpty(G_Mixer.totalFrames))
+	if (!w->allocEmpty(G_Mixer.totalFrames, G_Conf.samplerate))
 		return NULL;
 
 	/* increase lastTakeId until the sample name TAKE-[n] is unique */
@@ -235,7 +266,7 @@ SampleChannel *mh_stopInputRec()
 
 bool mh_uniqueSamplename(SampleChannel *ch, const char *name)
 {
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		if (ch != G_Mixer.channels.at(i)) {
 			if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE) {
 				SampleChannel *other = (SampleChannel*) G_Mixer.channels.at(i);
@@ -247,29 +278,3 @@ bool mh_uniqueSamplename(SampleChannel *ch, const char *name)
 	}
 	return true;
 }
-
-
-/* -------------------------------------------------------------------------- */
-
-
-#ifdef WITH_VST
-
-int __mh_readPatchPlugins__(gVector<Patch::plugin_t> *list, int type)
-{
-	int ret = 1;
-	for (unsigned i=0; i<list->size; i++) {
-		Patch::plugin_t *ppl = &list->at(i);
-		Plugin *plugin = G_PluginHost.addPlugin(ppl->path.c_str(), type, NULL);
-		if (plugin != NULL) {
-			plugin->bypass = ppl->bypass;
-			for (unsigned j=0; j<ppl->params.size; j++)
-				plugin->setParam(j, ppl->params.at(j));
-			ret &= 1;
-		}
-		else
-			ret &= 0;
-	}
-	return ret;
-}
-
-#endif
diff --git a/src/core/mixerHandler.h b/src/core/mixerHandler.h
index 8785e35..c624d26 100644
--- a/src/core/mixerHandler.h
+++ b/src/core/mixerHandler.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,10 +31,14 @@
 #define MIXERHANDLER_H
 
 
+#include <vector>
 #include "recorder.h"
 #include "patch.h"
 
 
+using std::vector;
+
+
 /* stopSequencer
  * stop the sequencer, with special case if samplesStopOnSeqHalt is
  * true. */
@@ -70,10 +74,4 @@ SampleChannel *mh_stopInputRec();
 
 bool mh_uniqueSamplename(class SampleChannel *ch, const char *name);
 
-#ifdef WITH_VST
-
-static int __mh_readPatchPlugins__(gVector<Patch::plugin_t> *list, int type);
-
-#endif
-
 #endif
diff --git a/src/core/patch.cpp b/src/core/patch.cpp
index 5bc84c9..d140a84 100644
--- a/src/core/patch.cpp
+++ b/src/core/patch.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -125,10 +125,10 @@ int Patch::read(const string &file)
 
 #ifdef WITH_VST
 
-void Patch::writePlugins(json_t *jContainer, gVector<plugin_t> *plugins, const char *key)
+void Patch::writePlugins(json_t *jContainer, vector<plugin_t> *plugins, const char *key)
 {
   json_t *jPlugins = json_array();
-  for (unsigned j=0; j<plugins->size; j++) {
+  for (unsigned j=0; j<plugins->size(); j++) {
     json_t   *jPlugin = json_object();
     plugin_t  plugin  = plugins->at(j);
     json_object_set_new(jPlugin, PATCH_KEY_PLUGIN_PATH,     json_string(plugin.path.c_str()));
@@ -138,7 +138,7 @@ void Patch::writePlugins(json_t *jContainer, gVector<plugin_t> *plugins, const c
     /* plugin params */
 
     json_t *jPluginParams = json_array();
-    for (unsigned z=0; z<plugin.params.size; z++) {
+    for (unsigned z=0; z<plugin.params.size(); z++) {
       json_array_append_new(jPluginParams, json_real(plugin.params.at(z)));
     }
     json_object_set_new(jPlugin, PATCH_KEY_PLUGIN_PARAMS, jPluginParams);
@@ -152,10 +152,10 @@ void Patch::writePlugins(json_t *jContainer, gVector<plugin_t> *plugins, const c
 /* -------------------------------------------------------------------------- */
 
 
-void Patch::writeColumns(json_t *jContainer, gVector<column_t> *columns)
+void Patch::writeColumns(json_t *jContainer, vector<column_t> *columns)
 {
   json_t *jColumns = json_array();
-  for (unsigned i=0; i<columns->size; i++) {
+  for (unsigned i=0; i<columns->size(); i++) {
     json_t   *jColumn = json_object();
     column_t  column  = columns->at(i);
     json_object_set_new(jColumn, PATCH_KEY_COLUMN_INDEX, json_integer(column.index));
@@ -169,10 +169,10 @@ void Patch::writeColumns(json_t *jContainer, gVector<column_t> *columns)
 /* -------------------------------------------------------------------------- */
 
 
-void Patch::writeActions(json_t *jContainer, gVector<action_t> *actions)
+void Patch::writeActions(json_t *jContainer, vector<action_t> *actions)
 {
   json_t *jActions = json_array();
-  for (unsigned k=0; k<actions->size; k++) {
+  for (unsigned k=0; k<actions->size(); k++) {
     json_t   *jAction = json_object();
     action_t  action  = actions->at(k);
     json_object_set_new(jAction, PATCH_KEY_ACTION_TYPE,    json_integer(action.type));
@@ -211,10 +211,10 @@ void Patch::writeCommons(json_t *jContainer)
 /* -------------------------------------------------------------------------- */
 
 
-void Patch::writeChannels(json_t *jContainer, gVector<channel_t> *channels)
+void Patch::writeChannels(json_t *jContainer, vector<channel_t> *channels)
 {
   json_t *jChannels = json_array();
-  for (unsigned i=0; i<channels->size; i++) {
+  for (unsigned i=0; i<channels->size(); i++) {
     json_t    *jChannel = json_object();
     channel_t  channel  = channels->at(i);
     json_object_set_new(jChannel, PATCH_KEY_CHANNEL_TYPE,                 json_integer(channel.type));
@@ -308,7 +308,7 @@ bool Patch::readColumns(json_t *jContainer)
     if (!setInt(jColumn, PATCH_KEY_COLUMN_INDEX, column.index)) return 0;
     if (!setInt(jColumn, PATCH_KEY_COLUMN_WIDTH, column.width)) return 0;
 
-    columns.add(column);
+    columns.push_back(column);
   }
   return 1;
 }
@@ -371,7 +371,7 @@ bool Patch::readChannels(json_t *jContainer)
 #ifdef WITH_VST
     readPlugins(jChannel, &channel.plugins, PATCH_KEY_CHANNEL_PLUGINS);
 #endif
-    channels.add(channel);
+    channels.push_back(channel);
   }
   return 1;
 }
@@ -398,7 +398,7 @@ bool Patch::readActions(json_t *jContainer, channel_t *channel)
     if (!setInt   (jAction, PATCH_KEY_ACTION_FRAME,   action.frame)) return 0;
     if (!setFloat (jAction, PATCH_KEY_ACTION_F_VALUE, action.fValue)) return 0;
     if (!setUint32(jAction, PATCH_KEY_ACTION_I_VALUE, action.iValue)) return 0;
-    channel->actions.add(action);
+    channel->actions.push_back(action);
   }
   return 1;
 }
@@ -409,7 +409,7 @@ bool Patch::readActions(json_t *jContainer, channel_t *channel)
 
 #ifdef WITH_VST
 
-bool Patch::readPlugins(json_t *jContainer, gVector<plugin_t> *container, const char *key)
+bool Patch::readPlugins(json_t *jContainer, vector<plugin_t> *container, const char *key)
 {
   json_t *jPlugins = json_object_get(jContainer, key);
   if (!checkArray(jPlugins, key))
@@ -434,9 +434,9 @@ bool Patch::readPlugins(json_t *jContainer, gVector<plugin_t> *container, const
     size_t paramIndex;
     json_t *jParam;
     json_array_foreach(jParams, paramIndex, jParam)
-      plugin.params.add(json_real_value(jParam));
+      plugin.params.push_back(json_real_value(jParam));
 
-    container->add(plugin);
+    container->push_back(plugin);
   }
   return 1;
 }
@@ -457,13 +457,13 @@ void Patch::sanitize()
   masterVolOut = masterVolOut < 0.0f || masterVolOut > 1.0f ? DEFAULT_VOL : masterVolOut;
   samplerate   = samplerate <= 0 ? DEFAULT_SAMPLERATE : samplerate;
 
-  for (unsigned i=0; i<columns.size; i++) {
+  for (unsigned i=0; i<columns.size(); i++) {
     column_t *col = &columns.at(i);
     col->index = col->index < 0 ? 0 : col->index;
     col->width = col->width < MIN_COLUMN_WIDTH ? MIN_COLUMN_WIDTH : col->width;
   }
 
-  for (unsigned i=0; i<channels.size; i++) {
+  for (unsigned i=0; i<channels.size(); i++) {
     channel_t *ch = &channels.at(i);
     ch->volume   = ch->volume < 0.0f || ch->volume > 1.0f ? DEFAULT_VOL : ch->volume;
     ch->panLeft  = ch->panLeft < 0.0f || ch->panLeft > 1.0f ? 1.0f : ch->panLeft;
diff --git a/src/core/patch.h b/src/core/patch.h
index 5d07f0c..ba1cd33 100644
--- a/src/core/patch.h
+++ b/src/core/patch.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,6 +32,7 @@
 
 
 #include <string>
+#include <vector>
 #include <stdint.h>
 #include "../utils/utils.h"
 #include "dataStorageJson.h"
@@ -39,6 +40,7 @@
 
 
 using std::string;
+using std::vector;
 
 
 class Patch : public DataStorageJson
@@ -56,9 +58,9 @@ public:
 #ifdef WITH_VST
   struct plugin_t
   {
-    string         path;
-    bool           bypass;
-    gVector<float> params;
+    string        path;
+    bool          bypass;
+    vector<float> params;
   };
 #endif
 
@@ -99,10 +101,10 @@ public:
     uint32_t    midiOut;
     uint32_t    midiOutChan;
 
-    gVector<action_t> actions;
+    vector<action_t> actions;
 
 #ifdef WITH_VST
-    gVector<plugin_t> plugins;
+    vector<plugin_t> plugins;
 #endif
   };
 
@@ -110,7 +112,7 @@ public:
   {
     int index;
     int width;
-    gVector<int> channels;
+    vector<int> channels;
   };
 
   string header;
@@ -129,12 +131,12 @@ public:
   int    lastTakeId;
   int    samplerate;   // original samplerate when the patch was saved
 
-  gVector<column_t>  columns;
-  gVector<channel_t> channels;
+  vector<column_t>  columns;
+  vector<channel_t> channels;
 
 #ifdef WITH_VST
-  gVector<plugin_t> masterInPlugins;
-  gVector<plugin_t> masterOutPlugins;
+  vector<plugin_t> masterInPlugins;
+  vector<plugin_t> masterOutPlugins;
 #endif
 
   /* init
@@ -165,7 +167,7 @@ private:
   bool readCommons (json_t *jContainer);
   bool readChannels(json_t *jContainer);
 #ifdef WITH_VST
-  bool readPlugins (json_t *jContainer, gVector<plugin_t> *container, const char* key);
+  bool readPlugins (json_t *jContainer, vector<plugin_t> *container, const char* key);
 #endif
   bool readActions (json_t *jContainer, channel_t *channel);
   bool readColumns (json_t *jContainer);
@@ -173,12 +175,12 @@ private:
   /* writers */
 
   void writeCommons (json_t *jContainer);
-  void writeChannels(json_t *jContainer, gVector<channel_t> *channels);
+  void writeChannels(json_t *jContainer, vector<channel_t> *channels);
 #ifdef WITH_VST
-  void writePlugins (json_t *jContainer, gVector<plugin_t> *plugins, const char* key);
+  void writePlugins (json_t *jContainer, vector<plugin_t> *plugins, const char* key);
 #endif
-  void writeActions (json_t *jContainer, gVector<action_t> *actions);
-  void writeColumns (json_t *jContainer, gVector<column_t> *columns);
+  void writeActions (json_t *jContainer, vector<action_t> *actions);
+  void writeColumns (json_t *jContainer, vector<column_t> *columns);
 };
 
 #endif
diff --git a/src/core/patch_DEPR_.cpp b/src/core/patch_DEPR_.cpp
index 0113591..a820e91 100644
--- a/src/core/patch_DEPR_.cpp
+++ b/src/core/patch_DEPR_.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -43,7 +43,7 @@
 
 
 extern Mixer 		     G_Mixer;
-extern Conf 		     G_Conf;
+extern Conf    G_Conf;
 #ifdef WITH_VST
 extern PluginHost    G_PluginHost;
 #endif
@@ -536,7 +536,7 @@ int Patch_DEPR_::readPlugins()
 
 	/* channel plugins */
 
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		Channel *ch = G_Mixer.channels.at(i);
 
 		char tmp[MAX_LINE_LEN];
diff --git a/src/core/patch_DEPR_.h b/src/core/patch_DEPR_.h
index 9c08bd8..0f01167 100644
--- a/src/core/patch_DEPR_.h
+++ b/src/core/patch_DEPR_.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp
index d54c7df..fe60eb6 100644
--- a/src/core/plugin.cpp
+++ b/src/core/plugin.cpp
@@ -1,10 +1,10 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -22,7 +22,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #ifdef WITH_VST
@@ -35,33 +35,34 @@
 int Plugin::id_generator = 0;
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 Plugin::Plugin()
-	: module    (NULL),
-	  entryPoint(NULL),
-	  plugin    (NULL),
-	  id        (id_generator++),
-	  program   (-1),
-	  bypass    (false),
-	  suspended (false)
+: module    (NULL),
+  entryPoint(NULL),
+  plugin    (NULL),
+  id        (id_generator++),
+  program   (-1),
+  bypass    (false),
+  suspended (false)
 {}
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-Plugin::~Plugin() {
+Plugin::~Plugin()
+{
 	unload();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Plugin::unload() {
-
+int Plugin::unload()
+{
 	if (module == NULL)
 		return 1;
 
@@ -96,11 +97,11 @@ int Plugin::unload() {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-int Plugin::load(const char *fname) {
 
+int Plugin::load(const char *fname)
+{
 	strcpy(pathfile, fname);
 
 #if defined(_WIN32)
@@ -163,11 +164,11 @@ int Plugin::load(const char *fname) {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-int Plugin::init(VstIntPtr VSTCALLBACK (*HostCallback) (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt)) {
 
+int Plugin::init(VstIntPtr VSTCALLBACK (*HostCallback) (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt))
+{
 #if defined(_WIN32)
 
 	entryPoint = (vstPluginFuncPtr) GetProcAddress((HMODULE)module, "VSTPluginMain");
@@ -241,11 +242,11 @@ int Plugin::init(VstIntPtr VSTCALLBACK (*HostCallback) (AEffect* effect, VstInt3
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Plugin::setup(int samplerate, int frames) {
-
+int Plugin::setup(int samplerate, int frames)
+{
   /* init plugin through the dispatcher with some basic infos */
 
   plugin->dispatcher(plugin, effOpen, 0, 0, 0, 0);
@@ -261,31 +262,35 @@ int Plugin::setup(int samplerate, int frames) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-AEffect *Plugin::getPlugin() {
+AEffect *Plugin::getPlugin()
+{
 	return plugin;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Plugin::getId() { return id; }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
+
 
-int Plugin::getSDKVersion() {
+int Plugin::getSDKVersion()
+{
 	return plugin->dispatcher(plugin, effGetVstVersion, 0, 0, 0, 0);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getName(char *out) {
+void Plugin::getName(char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetEffectName, 0, 0, tmp, 0);
 	tmp[kVstMaxEffectNameLen-1] = '\0';
@@ -293,10 +298,11 @@ void Plugin::getName(char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getVendor(char *out) {
+void Plugin::getVendor(char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetVendorString, 0, 0, tmp, 0);
 	tmp[kVstMaxVendorStrLen-1] = '\0';
@@ -304,10 +310,11 @@ void Plugin::getVendor(char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getProduct(char *out) {
+void Plugin::getProduct(char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetProductString, 0, 0, tmp, 0);
 	tmp[kVstMaxProductStrLen-1] = '\0';
@@ -315,16 +322,17 @@ void Plugin::getProduct(char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Plugin::getNumPrograms() { return plugin->numPrograms; }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Plugin::setProgram(int index) {
+int Plugin::setProgram(int index)
+{
 	plugin->dispatcher(plugin, effBeginSetProgram, 0, 0, 0, 0);
 	plugin->dispatcher(plugin, effSetProgram, 0, index, 0, 0);
 	gLog("[plugin] program changed, index %d\n", index);
@@ -333,28 +341,29 @@ int Plugin::setProgram(int index) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Plugin::getNumParams() { return plugin->numParams; }
+int Plugin::getNumParams() const { return plugin->numParams; }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Plugin::getNumInputs() { return plugin->numInputs; }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 int Plugin::getNumOutputs() {	return plugin->numOutputs; }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getProgramName(int index, char *out) {
+void Plugin::getProgramName(int index, char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetProgramNameIndexed, index, 0, tmp, 0);
 	tmp[kVstMaxProgNameLen-1] = '\0';
@@ -362,10 +371,11 @@ void Plugin::getProgramName(int index, char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getParamName(int index, char *out) {
+void Plugin::getParamName(int index, char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetParamName, index, 0, tmp, 0);
 	tmp[kVstMaxParamStrLen-1] = '\0';
@@ -373,10 +383,11 @@ void Plugin::getParamName(int index, char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getParamLabel(int index, char *out) {
+void Plugin::getParamLabel(int index, char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetParamLabel, index, 0, tmp, 0);
 	tmp[kVstMaxParamStrLen-1] = '\0';
@@ -384,10 +395,11 @@ void Plugin::getParamLabel(int index, char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getParamDisplay(int index, char *out) {
+void Plugin::getParamDisplay(int index, char *out)
+{
 	char tmp[128] = "\0";
 	plugin->dispatcher(plugin, effGetParamDisplay, index, 0, tmp, 0);
 	tmp[kVstMaxParamStrLen-1] = '\0';
@@ -395,34 +407,38 @@ void Plugin::getParamDisplay(int index, char *out) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-float Plugin::getParam(int index) {
+float Plugin::getParam(int index) const
+{
 	return plugin->getParameter(plugin, index);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::setParam(int index, float value) {
+void Plugin::setParam(int index, float value)
+{
 	plugin->setParameter(plugin, index, value);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-bool Plugin::hasGui() {
+bool Plugin::hasGui()
+{
 	return plugin->flags & effFlagsHasEditor;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::openGui(void *w) {
+void Plugin::openGui(void *w)
+{
 	long val = 0;
 #ifdef __linux__
   val = (long) w;
@@ -431,88 +447,98 @@ void Plugin::openGui(void *w) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::closeGui() {
+void Plugin::closeGui()
+{
 	plugin->dispatcher(plugin, effEditClose, 0, 0, 0, 0);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Plugin::getGuiWidth() {
+int Plugin::getGuiWidth()
+{
 	ERect *pErect = NULL;
 	plugin->dispatcher(plugin, effEditGetRect, 0, 0, &pErect, 0);
 	return pErect->top + pErect->right;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Plugin::getGuiHeight() {
+int Plugin::getGuiHeight()
+{
 	ERect *pErect = NULL;
 	plugin->dispatcher(plugin, effEditGetRect, 0, 0, &pErect, 0);
 	return pErect->top + pErect->bottom;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::idle() {
+void Plugin::idle()
+{
 	plugin->dispatcher(plugin, effEditIdle, 0, 0, NULL, 0);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::processAudio(float **in, float **out, long frames) {
+void Plugin::processAudio(float **in, float **out, long frames)
+{
 	plugin->processReplacing(plugin, in, out, frames);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::processEvents(VstEvents *events) {
+void Plugin::processEvents(VstEvents *events)
+{
 	plugin->dispatcher(plugin, effProcessEvents, 0, 0, events, 0.0);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::resume() {
+void Plugin::resume()
+{
 	plugin->dispatcher(plugin, effMainsChanged, 0, 1, 0, 0);
 	suspended = false;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::suspend() {
+void Plugin::suspend()
+{
 	plugin->dispatcher(plugin, effMainsChanged, 0, 0, 0, 0);
 	suspended = true;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::close() {
+void Plugin::close()
+{
 	plugin->dispatcher(plugin, effClose, 0, 0, 0, 0);
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Plugin::getRect(ERect **out) {
+void Plugin::getRect(ERect **out)
+{
 	plugin->dispatcher(plugin, effEditGetRect, 0, 0, out, 0);
 }
 
diff --git a/src/core/plugin.h b/src/core/plugin.h
index b03c343..22bb6d7 100644
--- a/src/core/plugin.h
+++ b/src/core/plugin.h
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * plugin
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 #ifdef WITH_VST
 
@@ -61,8 +61,8 @@
 typedef AEffect* (*vstPluginFuncPtr)(audioMasterCallback host);
 
 
-class Plugin {
-
+class Plugin
+{
 private:
 
 #if defined(_WIN32) || defined(__linux__)
@@ -90,6 +90,7 @@ private:
 	int unload();
 
 public:
+
 	Plugin();
 	~Plugin();
 
@@ -109,14 +110,14 @@ public:
 	void  getProduct(char *out);
 	int   getNumPrograms();        // list all programs
 	int   setProgram(int index);   // load a program
-	int   getNumParams();
+	int   getNumParams() const;
 	int   getNumInputs();
 	int   getNumOutputs();
 	void  getProgramName(int index, char *out);  // program = preset
 	void  getParamName(int index, char *out);
 	void  getParamLabel(int index, char *out);   // parameter's value(0, -39, ...)
 	void  getParamDisplay(int index, char *out); // parameter's unit measurement (dB, Pan, ...)
-	float getParam(int index);
+	float getParam(int index) const;
 	void  getRect(ERect **out);
 	void  setParam(int index, float value);
 
diff --git a/src/core/pluginHost.cpp b/src/core/pluginHost.cpp
index 6b02b89..7886804 100644
--- a/src/core/pluginHost.cpp
+++ b/src/core/pluginHost.cpp
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * pluginHost
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,12 +24,13 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #ifdef WITH_VST
 
 
+#include <vector>
 #include "../gui/dialogs/gd_mainWindow.h"
 #include "../utils/log.h"
 #include "pluginHost.h"
@@ -49,8 +50,11 @@ extern unsigned      G_beats;
 extern gdMainWindow *mainWin;
 
 
-PluginHost::PluginHost() {
+using std::vector;
 
+
+PluginHost::PluginHost()
+{
 	/* initially we fill vstTimeInfo with trash. Only when the plugin requests
 	 * the opcode we load the right infos from G_Mixer. */
 
@@ -71,17 +75,34 @@ PluginHost::PluginHost() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 PluginHost::~PluginHost() {}
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
+
+
+int PluginHost::clonePlugin(const Plugin &src, int stackType, Channel *ch)
+{
+	Plugin *p = addPlugin(src.pathfile, stackType, ch);
+	if (!p) {
+		gLog("[PluginHost::clonePlugin] unable to add new plugin to stack!\n");
+		return 0;
+	}
+	for (int k=0; k<src.getNumParams(); k++) {
+		p->setParam(k, src.getParam(k));
+	}
+	return 1;
+}
 
 
-int PluginHost::allocBuffers() {
+/* -------------------------------------------------------------------------- */
 
+
+int PluginHost::allocBuffers()
+{
 	/** FIXME - ERROR CHECKING! */
 
 	/* never, ever use G_Conf.buffersize to alloc these chunks of memory.
@@ -111,19 +132,20 @@ int PluginHost::allocBuffers() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-VstIntPtr VSTCALLBACK PluginHost::HostCallback(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt) {
+VstIntPtr VSTCALLBACK PluginHost::HostCallback(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt)
+{
 	return G_PluginHost.gHostCallback(effect, opcode, index, value, ptr, opt);
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-VstIntPtr PluginHost::gHostCallback(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt) {
 
+VstIntPtr PluginHost::gHostCallback(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt)
+{
 	/* warning: VST headers compiled with DECLARE_VST_DEPRECATED. */
 
 	switch (opcode) {
@@ -184,17 +206,17 @@ VstIntPtr PluginHost::gHostCallback(AEffect *effect, VstInt32 opcode, VstInt32 i
 
 		case audioMasterSizeWindow: {
 			gWindow *window = NULL;
-			for (unsigned i=0; i<masterOut.size && !window; i++)
+			for (unsigned i=0; i<masterOut.size() && !window; i++)
 				if (masterOut.at(i)->getPlugin() == effect)
 					window = masterOut.at(i)->window;
 
-			for (unsigned i=0; i<masterIn.size && !window; i++)
+			for (unsigned i=0; i<masterIn.size() && !window; i++)
 				if (masterIn.at(i)->getPlugin() == effect)
 					window = masterIn.at(i)->window;
 
-			for (unsigned i=0; i<G_Mixer.channels.size && !window; i++) {
+			for (unsigned i=0; i<G_Mixer.channels.size() && !window; i++) {
 				Channel *ch = G_Mixer.channels.at(i);
-				for (unsigned j=0; j<ch->plugins.size && !window; j++)
+				for (unsigned j=0; j<ch->plugins.size() && !window; j++)
 					if (ch->plugins.at(j)->getPlugin() == effect)
 						window = ch->plugins.at(j)->window;
 			}
@@ -305,15 +327,15 @@ VstIntPtr PluginHost::gHostCallback(AEffect *effect, VstInt32 opcode, VstInt32 i
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-Plugin *PluginHost::addPlugin(const char *fname, int stackType, Channel *ch) {
 
+Plugin *PluginHost::addPlugin(const char *fname, int stackType, Channel *ch)
+{
 	Plugin *p    = new Plugin();
 	bool success = true;
 
-	gVector <Plugin *> *pStack;
+	vector <Plugin *> *pStack;
 	pStack = getStack(stackType, ch);
 
 	if (!p->load(fname)) {
@@ -326,7 +348,7 @@ Plugin *PluginHost::addPlugin(const char *fname, int stackType, Channel *ch) {
 	 * useful to report a missing plugin. */
 
 	if (!success) {
-		pStack->add(p);
+		pStack->push_back(p);
 		return NULL;
 	}
 
@@ -351,14 +373,15 @@ Plugin *PluginHost::addPlugin(const char *fname, int stackType, Channel *ch) {
 		while (true) {
 			lockStatus = pthread_mutex_trylock(&G_Mixer.mutex_plugins);
 			if (lockStatus == 0) {
-				pStack->add(p);
+				pStack->push_back(p);
 				pthread_mutex_unlock(&G_Mixer.mutex_plugins);
 				break;
 			}
 		}
 
 		char name[256]; p->getName(name);
-		gLog("[pluginHost] plugin id=%d loaded (%s), stack type=%d, stack size=%d\n", p->getId(), name, stackType, pStack->size);
+		gLog("[pluginHost] plugin id=%d loaded (%s), stack type=%d, stack size=%d\n",
+			p->getId(), name, stackType, pStack->size());
 
 		/* p->resume() is suggested. Who knows... */
 
@@ -369,12 +392,12 @@ Plugin *PluginHost::addPlugin(const char *fname, int stackType, Channel *ch) {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-void PluginHost::processStack(float *buffer, int stackType, Channel *ch) {
 
-	gVector <Plugin *> *pStack = getStack(stackType, ch);
+void PluginHost::processStack(float *buffer, int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack = getStack(stackType, ch);
 
 	/* empty stack, stack not found or mixer not ready: do nothing */
 	/// TODO - join evaluation
@@ -383,7 +406,7 @@ void PluginHost::processStack(float *buffer, int stackType, Channel *ch) {
 		return;
 	if (pStack == NULL)
 		return;
-	if (pStack->size == 0)
+	if (pStack->size() == 0)
 		return;
 
 	/* converting buffer from Giada to VST */
@@ -396,7 +419,7 @@ void PluginHost::processStack(float *buffer, int stackType, Channel *ch) {
 	/* hardcore processing. At the end we swap input and output, so that
 	 * the N-th plugin will process the result of the plugin N-1. */
 
-	for (unsigned i=0; i<pStack->size; i++) {
+	for (unsigned i=0; i<pStack->size(); i++) {
 		/// TODO - join evaluation
 
 		if (pStack->at(i)->status != 1)
@@ -425,11 +448,11 @@ void PluginHost::processStack(float *buffer, int stackType, Channel *ch) {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-void PluginHost::processStackOffline(float *buffer, int stackType, Channel *ch, int size) {
 
+void PluginHost::processStackOffline(float *buffer, int stackType, Channel *ch, int size)
+{
 	/* call processStack on the entire size of the buffer. How many cycles?
 	 * size / (kernelAudio::realBufsize*2) (ie. internal bufsize) */
 
@@ -456,12 +479,13 @@ void PluginHost::processStackOffline(float *buffer, int stackType, Channel *ch,
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-Plugin *PluginHost::getPluginById(int id, int stackType, Channel *ch) {
-	gVector <Plugin *> *pStack = getStack(stackType, ch);
-	for (unsigned i=0; i<pStack->size; i++) {
+Plugin *PluginHost::getPluginById(int id, int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack = getStack(stackType, ch);
+	for (unsigned i=0; i<pStack->size(); i++) {
 		if (pStack->at(i)->getId() == id)
 			return pStack->at(i);
 	}
@@ -469,35 +493,36 @@ Plugin *PluginHost::getPluginById(int id, int stackType, Channel *ch) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-Plugin *PluginHost::getPluginByIndex(int index, int stackType, Channel *ch) {
-	gVector <Plugin *> *pStack = getStack(stackType, ch);
-	if (pStack->size == 0)
+Plugin *PluginHost::getPluginByIndex(int index, int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack = getStack(stackType, ch);
+	if (pStack->size() == 0)
 		return NULL;
-	if ((unsigned) index >= pStack->size)
+	if ((unsigned) index >= pStack->size())
 		return NULL;
 	return pStack->at(index);
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-void PluginHost::freeStack(int stackType, Channel *ch) {
 
-	gVector <Plugin *> *pStack;
+void PluginHost::freeStack(int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack;
 	pStack = getStack(stackType, ch);
 
-	if (pStack->size == 0)
+	if (pStack->size() == 0)
 		return;
 
 	int lockStatus;
 	while (true) {
 		lockStatus = pthread_mutex_trylock(&G_Mixer.mutex_plugins);
 		if (lockStatus == 0) {
-			for (unsigned i=0; i<pStack->size; i++) {
+			for (unsigned i=0; i<pStack->size(); i++) {
 				if (pStack->at(i)->status == 1) {  // only if plugin is ok
 					pStack->at(i)->suspend();
 					pStack->at(i)->close();
@@ -513,33 +538,34 @@ void PluginHost::freeStack(int stackType, Channel *ch) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void PluginHost::freeAllStacks() {
+void PluginHost::freeAllStacks()
+{
 	freeStack(PluginHost::MASTER_OUT);
 	freeStack(PluginHost::MASTER_IN);
-	for (unsigned i=0; i<G_Mixer.channels.size; i++)
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++)
 		freeStack(PluginHost::CHANNEL, G_Mixer.channels.at(i));
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void PluginHost::freePlugin(int id, int stackType, Channel *ch) {
-
-	gVector <Plugin *> *pStack;
+void PluginHost::freePlugin(int id, int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack;
 	pStack = getStack(stackType, ch);
 
 	/* try to delete the plugin until succeed. G_Mixer has priority. */
 
-	for (unsigned i=0; i<pStack->size; i++)
+	for (unsigned i=0; i<pStack->size(); i++)
 		if (pStack->at(i)->getId() == id) {
 
 			if (pStack->at(i)->status == 0) { // no frills if plugin is missing
 				delete pStack->at(i);
-				pStack->del(i);
+				pStack->erase(pStack->begin() + i);
 				return;
 			}
 			else {
@@ -550,7 +576,7 @@ void PluginHost::freePlugin(int id, int stackType, Channel *ch) {
 						pStack->at(i)->suspend();
 						pStack->at(i)->close();
 						delete pStack->at(i);
-						pStack->del(i);
+						pStack->erase(pStack->begin() + i);
 						pthread_mutex_unlock(&G_Mixer.mutex_plugins);
 						gLog("[pluginHost] plugin id=%d removed\n", id);
 						return;
@@ -564,18 +590,19 @@ void PluginHost::freePlugin(int id, int stackType, Channel *ch) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void PluginHost::swapPlugin(unsigned indexA, unsigned indexB, int stackType, Channel *ch) {
-
-	gVector <Plugin *> *pStack = getStack(stackType, ch);
+void PluginHost::swapPlugin(unsigned indexA, unsigned indexB, int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack = getStack(stackType, ch);
 
 	int lockStatus;
 	while (true) {
 		lockStatus = pthread_mutex_trylock(&G_Mixer.mutex_plugins);
 		if (lockStatus == 0) {
-			pStack->swap(indexA, indexB);
+			//pStack->swap(indexA, indexB);
+			std::swap(pStack->at(indexA), pStack->at(indexB)); // FIXME - will it work???
 			pthread_mutex_unlock(&G_Mixer.mutex_plugins);
 			gLog("[pluginHost] plugin at index %d and %d swapped\n", indexA, indexB);
 			return;
@@ -586,24 +613,25 @@ void PluginHost::swapPlugin(unsigned indexA, unsigned indexB, int stackType, Cha
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int PluginHost::getPluginIndex(int id, int stackType, Channel *ch) {
-
-	gVector <Plugin *> *pStack = getStack(stackType, ch);
+int PluginHost::getPluginIndex(int id, int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack = getStack(stackType, ch);
 
-	for (unsigned i=0; i<pStack->size; i++)
+	for (unsigned i=0; i<pStack->size(); i++)
 		if (pStack->at(i)->getId() == id)
 			return i;
 	return -1;
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-gVector <Plugin *> *PluginHost::getStack(int stackType, Channel *ch) {
+vector <Plugin *> *PluginHost::getStack(int stackType, Channel *ch)
+{
 	switch(stackType) {
 		case MASTER_OUT:
 			return &masterOut;
@@ -617,7 +645,7 @@ gVector <Plugin *> *PluginHost::getStack(int stackType, Channel *ch) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
 VstMidiEvent *PluginHost::createVstMidiEvent(uint32_t msg)
@@ -667,12 +695,13 @@ VstMidiEvent *PluginHost::createVstMidiEvent(uint32_t msg)
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-unsigned PluginHost::countPlugins(int stackType, Channel *ch) {
-	gVector <Plugin *> *pStack = getStack(stackType, ch);
-	return pStack->size;
+unsigned PluginHost::countPlugins(int stackType, Channel *ch)
+{
+	vector <Plugin *> *pStack = getStack(stackType, ch);
+	return pStack->size();
 }
 
 
diff --git a/src/core/pluginHost.h b/src/core/pluginHost.h
index 71d4d84..6be0a0d 100644
--- a/src/core/pluginHost.h
+++ b/src/core/pluginHost.h
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * pluginHost
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,13 +24,14 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 #ifdef WITH_VST
 
 #ifndef __PLUGIN_HOST_
 #define __PLUGIN_HOST_
 
+#include <vector>
 #include "../utils/utils.h"
 #include "../gui/elems/ge_window.h"
 #include "plugin.h"
@@ -38,8 +39,11 @@
 #include "const.h"
 
 
-class PluginHost {
+using std::vector;
 
+
+class PluginHost
+{
 private:
 
 	/* VSTs have a different buffer model:
@@ -69,12 +73,14 @@ public:
 
 	/* stack of Plugins */
 
-	gVector <Plugin *> masterOut;
-	gVector <Plugin *> masterIn;
+	vector <Plugin *> masterOut;
+	vector <Plugin *> masterIn;
 
 	PluginHost();
 	~PluginHost();
 
+	int clonePlugin(const Plugin &src, int stackType, class Channel *ch);
+
 	int allocBuffers();
 
 	/* The plugin can ask the host if it supports a given capability,
@@ -113,7 +119,7 @@ public:
 
 	VstMidiEvent *createVstMidiEvent(uint32_t msg);
 
-	gVector <Plugin *> *getStack(int stackType, class Channel *ch=NULL);
+	vector <Plugin *> *getStack(int stackType, class Channel *ch=NULL);
 
 	Plugin *getPluginById(int id, int stackType, class Channel *ch=NULL);
 
diff --git a/src/core/recorder.cpp b/src/core/recorder.cpp
index 58324f2..bff1a2a 100644
--- a/src/core/recorder.cpp
+++ b/src/core/recorder.cpp
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -56,9 +56,9 @@ extern Conf	       G_Conf;
 
 namespace recorder
 {
-gVector<int> frames;
-gVector< gVector<action*> > global;
-gVector<action*>  actions;
+vector<int> frames;
+vector< vector<action*> > global;
+vector<action*>  actions;
 
 bool active = false;
 bool sortedActions = false;
@@ -116,7 +116,7 @@ void rec(int index, int type, int frame, uint32_t iValue, float fValue)
 	/* check if the frame exists in the stack. If it exists, we don't extend
 	 * the stack, but we add (or push) a new action to it. */
 
-	int frameToExpand = frames.size;
+	int frameToExpand = frames.size();
 	for (int i=0; i<frameToExpand; i++)
 		if (frames.at(i) == frame) {
 			frameToExpand = i;
@@ -124,22 +124,22 @@ void rec(int index, int type, int frame, uint32_t iValue, float fValue)
 		}
 
 	/* espansione dello stack frames nel caso l'azione ricada in frame
-	 * non precedentemente memorizzati (frameToExpand == frames.size).
+	 * non precedentemente memorizzati (frameToExpand == frames.size()).
 	 * Espandere frames è facile, basta aggiungere un frame in coda.
 	 * Espandere global è più complesso: bisogna prima allocare una
 	 * cella in global (per renderlo parallelo a frames) e poi
 	 * inizializzare il suo sub-stack (di action). */
 
-	if (frameToExpand == (int) frames.size) {
-		frames.add(frame);
-		global.add(actions);							// array of actions added
-		global.at(global.size-1).add(a);	// action added
+	if (frameToExpand == (int) frames.size()) {
+		frames.push_back(frame);
+		global.push_back(actions);               // array of actions added
+		global.at(global.size()-1).push_back(a); // action added
 	}
 	else {
 
 		/* no duplicates, please */
 
-		for (unsigned t=0; t<global.at(frameToExpand).size; t++) {
+		for (unsigned t=0; t<global.at(frameToExpand).size(); t++) {
 			action *ac = global.at(frameToExpand).at(t);
 			if (ac->chan   == index  &&
 			    ac->type   == type   &&
@@ -149,7 +149,7 @@ void rec(int index, int type, int frame, uint32_t iValue, float fValue)
 				return;
 		}
 
-		global.at(frameToExpand).add(a);		// expand array
+		global.at(frameToExpand).push_back(a);		// expand array
 	}
 
 	/* if WITH_VST create a new VST event and attach it to our action.
@@ -182,10 +182,10 @@ void clearChan(int index)
 {
 	gLog("[REC] clearing chan %d...\n", index);
 
-	for (unsigned i=0; i<global.size; i++) {	// for each frame i
+	for (unsigned i=0; i<global.size(); i++) {	// for each frame i
 		unsigned j=0;
 		while (true) {
-			if (j == global.at(i).size) break; 	  // for each action j of frame i
+			if (j == global.at(i).size()) break; 	  // for each action j of frame i
 			action *a = global.at(i).at(j);
 			if (a->chan == index)	{
 #ifdef WITH_VST
@@ -193,7 +193,7 @@ void clearChan(int index)
 					free(a->event);
 #endif
 				free(a);
-				global.at(i).del(j);
+				global.at(i).erase(global.at(i).begin() + j);
 			}
 			else
 				j++;
@@ -213,15 +213,15 @@ void clearChan(int index)
 void clearAction(int index, char act)
 {
 	gLog("[REC] clearing action %d from chan %d...\n", act, index);
-	for (unsigned i=0; i<global.size; i++) {						// for each frame i
+	for (unsigned i=0; i<global.size(); i++) {						// for each frame i
 		unsigned j=0;
 		while (true) {                                   // for each action j of frame i
-			if (j == global.at(i).size)
+			if (j == global.at(i).size())
 				break;
 			action *a = global.at(i).at(j);
 			if (a->chan == index && (act & a->type) == a->type)	{ // bitmask
 				free(a);
-				global.at(i).del(j);
+				global.at(i).erase(global.at(i).begin() + j);
 			}
 			else
 				j++;
@@ -244,16 +244,16 @@ void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iVa
 
 	if (frame % 2 != 0)
 		frame++;
-		
+
 	/* find the frame 'frame' */
 
 	bool found = false;
-	for (unsigned i=0; i<frames.size && !found; i++) {
+	for (unsigned i=0; i<frames.size() && !found; i++) {
 		if (frames.at(i) == frame) {
 
 			/* find the action in frame i */
 
-			for (unsigned j=0; j<global.at(i).size; j++) {
+			for (unsigned j=0; j<global.at(i).size(); j++) {
 				action *a = global.at(i).at(j);
 
 				/* action comparison logic */
@@ -272,7 +272,7 @@ void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iVa
 								free(a->event);
 #endif
 							free(a);
-							global.at(i).del(j);
+							global.at(i).erase(global.at(i).begin() + j);
 							pthread_mutex_unlock(&G_Mixer.mutex_recs);
 							found = true;
 							break;
@@ -302,13 +302,13 @@ void deleteAction(int chan, int frame, char type, bool checkValues, uint32_t iVa
 void deleteActions(int chan, int frame_a, int frame_b, char type)
 {
 	sortActions();
-	gVector<int> dels;
+	vector<int> dels;
 
-	for (unsigned i=0; i<frames.size; i++)
+	for (unsigned i=0; i<frames.size(); i++)
 		if (frames.at(i) > frame_a && frames.at(i) < frame_b)
-			dels.add(frames.at(i));
+			dels.push_back(frames.at(i));
 
-	for (unsigned i=0; i<dels.size; i++)
+	for (unsigned i=0; i<dels.size(); i++)
 		deleteAction(chan, dels.at(i), type, false); // false == don't check values
 }
 
@@ -318,9 +318,9 @@ void deleteActions(int chan, int frame_a, int frame_b, char type)
 
 void clearAll()
 {
-	while (global.size > 0) {
-		for (unsigned i=0; i<global.size; i++) {
-			for (unsigned k=0; k<global.at(i).size; k++) {
+	while (global.size() > 0) {
+		for (unsigned i=0; i<global.size(); i++) {
+			for (unsigned k=0; k<global.at(i).size(); k++) {
 #ifdef WITH_VST
 				if (global.at(i).at(k)->type == ACTION_MIDI)
 					free(global.at(i).at(k)->event);
@@ -328,11 +328,11 @@ void clearAll()
 				free(global.at(i).at(k));									// free action
 			}
 			global.at(i).clear();												// free action container
-			global.del(i);
+			global.erase(global.begin() + i);
 		}
 	}
 
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		G_Mixer.channels.at(i)->hasActions  = false;
 		if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE)
 			((SampleChannel*)G_Mixer.channels.at(i))->readActions = false;
@@ -352,10 +352,10 @@ void optimize()
 
 	unsigned i = 0;
 	while (true) {
-		if (i == global.size) return;
-		if (global.at(i).size == 0) {
-			global.del(i);
-			frames.del(i);
+		if (i == global.size()) return;
+		if (global.at(i).size() == 0) {
+			global.erase(global.begin() + i);
+			frames.erase(frames.begin() + i);
 		}
 		else
 			i++;
@@ -372,11 +372,11 @@ void sortActions()
 {
 	if (sortedActions)
 		return;
-	for (unsigned i=0; i<frames.size; i++)
-		for (unsigned j=0; j<frames.size; j++)
+	for (unsigned i=0; i<frames.size(); i++)
+		for (unsigned j=0; j<frames.size(); j++)
 			if (frames.at(j) > frames.at(i)) {
-				frames.swap(j, i);
-				global.swap(j, i);
+				std::swap(frames.at(j), frames.at(i));
+				std::swap(global.at(j), global.at(i));
 			}
 	sortedActions = true;
 	//print();
@@ -388,7 +388,7 @@ void sortActions()
 
 void updateBpm(float oldval, float newval, int oldquanto)
 {
-	for (unsigned i=0; i<frames.size; i++) {
+	for (unsigned i=0; i<frames.size(); i++) {
 
 		float frame  = ((float) frames.at(i)/newval) * oldval;
 		frames.at(i) = (int) frame;
@@ -413,8 +413,8 @@ void updateBpm(float oldval, float newval, int oldquanto)
 
 	/* update structs */
 
-	for (unsigned i=0; i<frames.size; i++) {
-		for (unsigned j=0; j<global.at(i).size; j++) {
+	for (unsigned i=0; i<frames.size(); i++) {
+		for (unsigned j=0; j<global.at(i).size(); j++) {
 			action *a = global.at(i).at(j);
 			a->frame = frames.at(i);
 		}
@@ -438,7 +438,7 @@ void updateSamplerate(int systemRate, int patchRate)
 	gLog("[REC] systemRate (%d) != patchRate (%d), converting...\n", systemRate, patchRate);
 
 	float ratio = systemRate / (float) patchRate;
-	for (unsigned i=0; i<frames.size; i++) {
+	for (unsigned i=0; i<frames.size(); i++) {
 
 		gLog("[REC]    oldFrame = %d", frames.at(i));
 
@@ -455,8 +455,8 @@ void updateSamplerate(int systemRate, int patchRate)
 
 	/* update structs */
 
-	for (unsigned i=0; i<frames.size; i++) {
-		for (unsigned j=0; j<global.at(i).size; j++) {
+	for (unsigned i=0; i<frames.size(); i++) {
+		for (unsigned j=0; j<global.at(i).size(); j++) {
 			action *a = global.at(i).at(j);
 			a->frame = frames.at(i);
 		}
@@ -477,14 +477,14 @@ void expand(int old_fpb, int new_fpb)
 	unsigned pass = (int) (new_fpb / old_fpb) - 1;
 	if (pass == 0) pass = 1;
 
-	unsigned init_fs = frames.size;
+	unsigned init_fs = frames.size();
 
 	for (unsigned z=1; z<=pass; z++) {
 		for (unsigned i=0; i<init_fs; i++) {
 			unsigned newframe = frames.at(i) + (old_fpb*z);
-			frames.add(newframe);
-			global.add(actions);
-			for (unsigned k=0; k<global.at(i).size; k++) {
+			frames.push_back(newframe);
+			global.push_back(actions);
+			for (unsigned k=0; k<global.at(i).size(); k++) {
 				action *a = global.at(i).at(k);
 				rec(a->chan, a->type, newframe, a->iValue, a->fValue);
 			}
@@ -504,14 +504,14 @@ void shrink(int new_fpb)
 
 	unsigned i=0;
 	while (true) {
-		if (i == frames.size) break;
+		if (i == frames.size()) break;
 
 		if (frames.at(i) >= new_fpb) {
-			for (unsigned k=0; k<global.at(i).size; k++)
-				free(global.at(i).at(k));			// free action
+			for (unsigned k=0; k<global.at(i).size(); k++)
+				free(global.at(i).at(k));		      // free action
 			global.at(i).clear();								// free action container
-			global.del(i);											// shrink global
-			frames.del(i);											// shrink frames
+			global.erase(global.begin() + i);   // shrink global
+			frames.erase(frames.begin() + i);   // shrink frames
 		}
 		else
 			i++;
@@ -528,12 +528,12 @@ void shrink(int new_fpb)
 void chanHasActions(int index)
 {
 	Channel *ch = G_Mixer.getChannelByIndex(index);
-	if (global.size == 0) {
+	if (global.size() == 0) {
 		ch->hasActions = false;
 		return;
 	}
-	for (unsigned i=0; i<global.size && !ch->hasActions; i++) {
-		for (unsigned j=0; j<global.at(i).size && !ch->hasActions; j++) {
+	for (unsigned i=0; i<global.size() && !ch->hasActions; i++) {
+		for (unsigned j=0; j<global.at(i).size() && !ch->hasActions; j++) {
 			if (global.at(i).at(j)->chan == index)
 				ch->hasActions = true;
 		}
@@ -549,13 +549,13 @@ int getNextAction(int chan, char type, int frame, action **out, uint32_t iValue)
 	sortActions();  // mandatory
 
 	unsigned i=0;
-	while (i < frames.size && frames.at(i) <= frame) i++;
+	while (i < frames.size() && frames.at(i) <= frame) i++;
 
-	if (i == frames.size)   // no further actions past 'frame'
+	if (i == frames.size())   // no further actions past 'frame'
 		return -1;
 
-	for (; i<global.size; i++)
-		for (unsigned j=0; j<global.at(i).size; j++) {
+	for (; i<global.size(); i++)
+		for (unsigned j=0; j<global.at(i).size(); j++) {
 			action *a = global.at(i).at(j);
 			if (a->chan == chan && (type & a->type) == a->type) {
 				if (iValue == 0 || (iValue != 0 && a->iValue == iValue)) {
@@ -574,8 +574,8 @@ int getNextAction(int chan, char type, int frame, action **out, uint32_t iValue)
 
 int getAction(int chan, char action, int frame, struct action **out)
 {
-	for (unsigned i=0; i<global.size; i++)
-		for (unsigned j=0; j<global.at(i).size; j++)
+	for (unsigned i=0; i<global.size(); i++)
+		for (unsigned j=0; j<global.at(i).size(); j++)
 			if (frame  == global.at(i).at(j)->frame &&
 					action == global.at(i).at(j)->type &&
 					chan   == global.at(i).at(j)->chan)
@@ -686,9 +686,9 @@ void stopOverdub(int frame)
 void print()
 {
 	gLog("[REC] ** print debug **\n");
-	for (unsigned i=0; i<global.size; i++) {
+	for (unsigned i=0; i<global.size(); i++) {
 		gLog("  frame %d\n", frames.at(i));
-		for (unsigned j=0; j<global.at(i).size; j++) {
+		for (unsigned j=0; j<global.at(i).size(); j++) {
 			gLog("    action %d | chan %d | frame %d\n", global.at(i).at(j)->type, global.at(i).at(j)->chan, global.at(i).at(j)->frame);
 		}
 	}
diff --git a/src/core/recorder.h b/src/core/recorder.h
index 6c9c65e..9e456bf 100644
--- a/src/core/recorder.h
+++ b/src/core/recorder.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,6 +31,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <vector>
 #include "../utils/utils.h"
 #include "const.h"
 #include "mixer.h"
@@ -49,11 +50,15 @@
 	#include "../deps/vst/aeffectx.h"
 #endif
 
+
+using std::vector;
+
+
 /*
- * [global0]-->[gVector<_action*>0]-->[a0][a1][a2]				0[frames1]
- * [global1]-->[gVector<_action*>1]-->[a0][a1][a2]				1[frames2]
- * [global2]-->[gVector<_action*>2]-->[a0][a1][a2]				2[frames3]
- * [global3]-->[gVector<_action*>3]-->[a0][a1][a2]				3[frames4]
+ * [global0]-->[vector<_action*>0]-->[a0][a1][a2]				0[frames1]
+ * [global1]-->[vector<_action*>1]-->[a0][a1][a2]				1[frames2]
+ * [global2]-->[vector<_action*>2]-->[a0][a1][a2]				2[frames3]
+ * [global3]-->[vector<_action*>3]-->[a0][a1][a2]				3[frames4]
  * */
 
 namespace recorder {
@@ -86,9 +91,9 @@ struct composite {
 	action a2;
 };
 
-extern gVector<int>  frames;					      // frame counter (sentinel) frames.size == global.size
-extern gVector< gVector<action*> > global;	// container of containers of actions
-extern gVector<action*>  actions;				    // container of actions
+extern vector<int>  frames;					      // frame counter (sentinel) frames.size == global.size
+extern vector< vector<action*> > global;	// container of containers of actions
+extern vector<action*>  actions;				    // container of actions
 
 extern bool active;
 extern bool sortedActions;                  // are actions sorted via sortActions()?
diff --git a/src/core/sampleChannel.cpp b/src/core/sampleChannel.cpp
index ad5866f..3e4e50a 100644
--- a/src/core/sampleChannel.cpp
+++ b/src/core/sampleChannel.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -49,6 +49,9 @@ extern PluginHost  G_PluginHost;
 #endif
 
 
+using std::string;
+
+
 SampleChannel::SampleChannel(int bufferSize)
 	: Channel          (CHANNEL_SAMPLE, STATUS_EMPTY, bufferSize),
 		frameRewind      (-1),
@@ -90,6 +93,51 @@ SampleChannel::~SampleChannel()
 /* -------------------------------------------------------------------------- */
 
 
+void SampleChannel::copy(const Channel *_src)
+{
+	Channel::copy(_src);
+	SampleChannel *src = (SampleChannel *) _src;
+	tracker         = src->tracker;
+	begin           = src->begin;
+	end             = src->end;
+	boost           = src->boost;
+	mode            = src->mode;
+	qWait           = src->qWait;
+	fadeinOn        = src->fadeinOn;
+	fadeinVol       = src->fadeinVol;
+	fadeoutOn       = src->fadeoutOn;
+	fadeoutVol      = src->fadeoutVol;
+	fadeoutTracker  = src->fadeoutTracker;
+	fadeoutStep     = src->fadeoutStep;
+	fadeoutType     = src->fadeoutType;
+	fadeoutEnd      = src->fadeoutEnd;
+	setPitch(src->pitch);
+
+	if (src->wave) {
+		Wave *w = new Wave(*src->wave); // invoke Wave's copy constructor
+		pushWave(w);
+		generateUniqueSampleName();
+	}
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void SampleChannel::generateUniqueSampleName()
+{
+	string oldName = wave->name;
+	int k = 1; // Start from k = 1, zero is too nerdy
+	while (!mh_uniqueSamplename(this, wave->name.c_str())) {
+		wave->updateName((oldName + "-" + gItoa(k)).c_str());
+		k++;
+	}
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
 void SampleChannel::clear()
 {
 	/** TODO - these memsets can be done only if status PLAY (if below),
@@ -669,7 +717,7 @@ void SampleChannel::pushWave(Wave *w)
 bool SampleChannel::allocEmpty(int frames, int takeId)
 {
 	Wave *w = new Wave();
-	if (!w->allocEmpty(frames))
+	if (!w->allocEmpty(frames, G_Conf.samplerate))
 		return false;
 
 	char wname[32];
@@ -808,15 +856,7 @@ int SampleChannel::load(const char *file)
 	}
 
 	pushWave(w);
-
-	/* sample name must be unique. Start from k = 1, zero is too nerdy */
-
-	std::string oldName = wave->name;
-	int k = 1;
-	while (!mh_uniqueSamplename(this, wave->name.c_str())) {
-		wave->updateName((oldName + "-" + gItoa(k)).c_str());
-		k++;
-	}
+	generateUniqueSampleName();
 
 	gLog("[SampleChannel] %s loaded in channel %d\n", file, index);
 	return SAMPLE_LOADED_OK;
diff --git a/src/core/sampleChannel.h b/src/core/sampleChannel.h
index 228a1b5..d7362ba 100644
--- a/src/core/sampleChannel.h
+++ b/src/core/sampleChannel.h
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * sampleChannel
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #ifndef SAMPLE_CHANNEL_H
@@ -35,8 +35,8 @@
 #include "channel.h"
 
 
-class SampleChannel : public Channel {
-
+class SampleChannel : public Channel
+{
 private:
 
 	/* rsmp_state, rsmp_data
@@ -78,11 +78,18 @@ private:
 
 	void calcVolumeEnv(int frame);
 
+	/* generateUniqueSampleName
+	 * Sample name must be unique. Generate a new samplename with the "-[n]"
+	 * suffix. */
+	 
+	void generateUniqueSampleName();
+
 public:
 
 	SampleChannel(int bufferSize);
 	~SampleChannel();
 
+	void copy       (const Channel *src);
 	void clear      ();
 	void process    (float *buffer);
 	void start      (int frame, bool doQuantize);
diff --git a/src/core/wave.cpp b/src/core/wave.cpp
index ee81c6d..28b3a42 100644
--- a/src/core/wave.cpp
+++ b/src/core/wave.cpp
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * wave
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #include <stdio.h>
@@ -34,33 +34,48 @@
 #include "../utils/utils.h"
 #include "../utils/log.h"
 #include "wave.h"
-#include "conf.h"
 #include "init.h"
 
 
-extern Conf G_Conf;
-
-
 Wave::Wave()
-	: data     (NULL),
-		size     (0),
-		isLogical(0),
-		isEdited (0) {}
+: data     (NULL),
+	size     (0),
+	isLogical(0),
+	isEdited (0) {}
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-Wave::~Wave() {
+Wave::~Wave()
+{
 	clear();
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
+
 
+Wave::Wave(const Wave &other)
+: data     (NULL),
+	size     (0),
+	isLogical(false),
+	isEdited (false)
+{
+	size = other.size;
+	data = new float[size];
+	memcpy(data, other.data, size * sizeof(float));
+	memcpy(&inHeader, &other.inHeader, sizeof(other.inHeader));
+	pathfile = other.pathfile;
+	name = other.name;
+	isLogical = true;
+}
 
-int Wave::open(const char *f) {
+/* -------------------------------------------------------------------------- */
 
+
+int Wave::open(const char *f)
+{
 	pathfile = f;
 	name     = gStripExt(gBasename(f).c_str());
 	fileIn   = sf_open(f, SFM_READ, &inHeader);
@@ -79,7 +94,7 @@ int Wave::open(const char *f) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 /* how to read and write with libsndfile:
  *
@@ -95,7 +110,8 @@ int Wave::open(const char *f) {
  * 	...
  */
 
-int Wave::readData() {
+int Wave::readData()
+{
 	size = inHeader.frames * inHeader.channels;
 	data = (float *) malloc(size * sizeof(float));
 	if (data == NULL) {
@@ -111,11 +127,11 @@ int Wave::readData() {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-int Wave::writeData(const char *f) {
 
+int Wave::writeData(const char *f)
+{
 	/* prepare the header for output file */
 
 	outHeader.samplerate = inHeader.samplerate;
@@ -141,10 +157,11 @@ int Wave::writeData(const char *f) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Wave::clear() {
+void Wave::clear()
+{
 	if (data != NULL) {
 		free(data);
 		data     = NULL;
@@ -154,11 +171,11 @@ void Wave::clear() {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-int Wave::allocEmpty(unsigned __size) {
-
+int Wave::allocEmpty(unsigned __size, unsigned samplerate)
+{
 	/* the caller must pass a __size for stereo values */
 
 	/// FIXME - this way if malloc fails size becomes wrong
@@ -171,7 +188,7 @@ int Wave::allocEmpty(unsigned __size) {
 
 	memset(data, 0, sizeof(float) * size); /// FIXME - is it useful?
 
-	inHeader.samplerate = G_Conf.samplerate;
+	inHeader.samplerate = samplerate;
 	inHeader.channels   = 2;
 	inHeader.format     = SF_FORMAT_WAV | SF_FORMAT_FLOAT; // wave only
 
@@ -180,11 +197,11 @@ int Wave::allocEmpty(unsigned __size) {
 }
 
 
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
 
-int Wave::resample(int quality, int newRate) {
 
+int Wave::resample(int quality, int newRate)
+{
 	float ratio = newRate / (float) inHeader.samplerate;
 	int newSize = ceil(size * ratio);
 	if (newSize % 2 != 0)   // libsndfile goes crazy with odd size in case of saving
@@ -219,22 +236,25 @@ int Wave::resample(int quality, int newRate) {
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-std::string Wave::basename() {
+std::string Wave::basename() const
+{
 	return gStripExt(gBasename(pathfile.c_str()).c_str());
 }
 
-std::string Wave::extension() {
+std::string Wave::extension() const
+{
 	return gGetExt(pathfile.c_str());
 }
 
 
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
 
 
-void Wave::updateName(const char *n) {
+void Wave::updateName(const char *n)
+{
 	std::string ext = gGetExt(pathfile.c_str());
 	name      = gStripExt(gBasename(n).c_str());
 	pathfile  = gDirname(pathfile.c_str()) + gGetSlash() + name + "." + ext;
diff --git a/src/core/wave.h b/src/core/wave.h
index 9ce81df..237e52f 100644
--- a/src/core/wave.h
+++ b/src/core/wave.h
@@ -1,12 +1,12 @@
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
  *
  * Giada - Your Hardcore Loopmachine
  *
  * wave
  *
- * ---------------------------------------------------------------------
+ * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -24,7 +24,7 @@
  * along with Giada - Your Hardcore Loopmachine. If not, see
  * <http://www.gnu.org/licenses/>.
  *
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
 
 
 #ifndef WAVE_H
@@ -36,8 +36,8 @@
 #include <string>
 
 
-class Wave {
-
+class Wave
+{
 private:
 
 	SNDFILE   *fileIn;
@@ -45,10 +45,12 @@ private:
 	SF_INFO    inHeader;
 	SF_INFO    outHeader;
 
+
 public:
 
 	Wave();
 	~Wave();
+	Wave(const Wave &other);
 
 	std::string pathfile; // full path + sample name
 	std::string name;			// sample name (changeable)
@@ -65,8 +67,8 @@ public:
 	inline void channels(int v) { inHeader.channels = v; }
 	inline void frames  (int v) { inHeader.frames = v; }
 
-	std::string basename ();
-	std::string extension();
+	std::string basename () const;
+	std::string extension() const;
 
 	void updateName(const char *n);
 	int  open      (const char *f);
@@ -77,7 +79,7 @@ public:
 	/* allocEmpty
 	 * alloc an empty waveform. */
 
-	int allocEmpty(unsigned size);
+	int allocEmpty(unsigned size, unsigned samplerate);
 
 	/* resample
 	 * simple algorithm for one-shot resampling. */
diff --git a/src/core/waveFx.cpp b/src/core/waveFx.cpp
index 368bd79..52b6f1c 100644
--- a/src/core/waveFx.cpp
+++ b/src/core/waveFx.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/waveFx.h b/src/core/waveFx.h
index ebdef4a..491b1af 100644
--- a/src/core/waveFx.h
+++ b/src/core/waveFx.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/deps/vst/aeffect.h b/src/deps/vst/aeffect.h
deleted file mode 100644
index f5f01c8..0000000
--- a/src/deps/vst/aeffect.h
+++ /dev/null
@@ -1,351 +0,0 @@
-//-------------------------------------------------------------------------------------------------------
-// VST Plug-Ins SDK
-// Version 2.4		$Date: 2006/06/20 17:22:55 $
-//
-// Category     : VST 2.x Interfaces
-// Filename     : aeffect.h
-// Created by   : Steinberg Media Technologies
-// Description  : Definition of AEffect structure
-//
-// © 2006, Steinberg Media Technologies, All Rights Reserved
-//-------------------------------------------------------------------------------------------------------
-
-#ifndef __aeffect__
-#define __aeffect__
-
-// gcc based compiler, or CodeWarrior on Mac OS X
-#if ((defined(__GNUC__) && (defined(__APPLE_CPP__) || defined(__APPLE_CC__))) || (defined (__MWERKS__) && defined (__MACH__)))
-	#ifndef TARGET_API_MAC_CARBON
-		#define TARGET_API_MAC_CARBON 1
-	#endif
-	#if __ppc__
-		#ifndef VST_FORCE_DEPRECATED
-			#define VST_FORCE_DEPRECATED 0
-		#endif
-	#endif
-#endif
-
-#if TARGET_API_MAC_CARBON
-	#ifdef __LP64__
-		#pragma options align=power
-	#else
-		#pragma options align=mac68k
-	#endif
-	#define VSTCALLBACK
-#elif defined __BORLANDC__
-	#pragma -a8
-#elif defined(__GNUC__)
-    #pragma pack(push,8)
-    #define VSTCALLBACK __cdecl
-#elif defined(WIN32) || defined(__FLAT__) || defined CBUILDER
-	#pragma pack(push)
-	#pragma pack(8)
-	#define VSTCALLBACK __cdecl
-#else
-	#define VSTCALLBACK
-#endif
-//-------------------------------------------------------------------------------------------------------
-
-#include <string.h>	// for strncpy
-
-//-------------------------------------------------------------------------------------------------------
-// VST Version
-//-------------------------------------------------------------------------------------------------------
-
-/** Define SDK Version (you can generate different versions (from 2.0 to 2.4) of this SDK by setting the unwanted extensions to 0). */
-#define VST_2_1_EXTENSIONS 1 ///< Version 2.1 extensions (08-06-2000)
-#define VST_2_2_EXTENSIONS 1 ///< Version 2.2 extensions (08-06-2001)
-#define VST_2_3_EXTENSIONS 1 ///< Version 2.3 extensions (20-05-2003)
-#ifndef VST_2_4_EXTENSIONS
-#define VST_2_4_EXTENSIONS 1 ///< Version 2.4 extensions (01-01-2006)
-#endif
-
-/** Current VST Version */
-#if VST_2_4_EXTENSIONS
-	#define kVstVersion 2400
-#elif VST_2_3_EXTENSIONS
-	#define kVstVersion 2300
-#elif VST_2_2_EXTENSIONS
-	#define kVstVersion 2200
-#elif VST_2_1_EXTENSIONS
-	#define kVstVersion 2100
-#else
-	#define kVstVersion 2
-#endif
-
-/** Disable for Hosts to serve Plug-ins below VST 2.4 */
-#ifndef VST_FORCE_DEPRECATED
-#define VST_FORCE_DEPRECATED VST_2_4_EXTENSIONS 
-#endif
-
-/** Declares identifier as deprecated. */
-#if VST_FORCE_DEPRECATED
-#define DECLARE_VST_DEPRECATED(identifier) __##identifier##Deprecated
-#else
-#define DECLARE_VST_DEPRECATED(identifier) identifier
-#endif
-
-/** Define for 64 Bit Platform. */
-#ifndef VST_64BIT_PLATFORM
-#define VST_64BIT_PLATFORM _WIN64 || __LP64__
-#endif
-
-//-------------------------------------------------------------------------------------------------------
-// Integral Types
-//-------------------------------------------------------------------------------------------------------
-
-#ifdef WIN32
-typedef short VstInt16;				///< 16 bit integer type
-typedef int VstInt32;				///< 32 bit integer type
-typedef __int64 VstInt64;			///< 64 bit integer type
-#else
-#include <stdint.h>
-typedef int16_t VstInt16;			///< 16 bit integer type
-typedef int32_t VstInt32;			///< 32 bit integer type
-typedef int64_t VstInt64;			///< 64 bit integer type
-#endif
-
-//-------------------------------------------------------------------------------------------------------
-// Generic Types
-//-------------------------------------------------------------------------------------------------------
-
-#if VST_64BIT_PLATFORM
-typedef VstInt64 VstIntPtr;			///< platform-dependent integer type, same size as pointer
-#else
-typedef VstInt32 VstIntPtr;			///< platform-dependent integer type, same size as pointer
-#endif
-
-//-------------------------------------------------------------------------------------------------------
-// Misc. Definition
-//-------------------------------------------------------------------------------------------------------
-#undef CCONST
-struct AEffect;
-
-/// @cond ignore
-typedef	VstIntPtr (VSTCALLBACK *audioMasterCallback) (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);
-typedef VstIntPtr (VSTCALLBACK *AEffectDispatcherProc) (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);
-typedef void (VSTCALLBACK *AEffectProcessProc) (AEffect* effect, float** inputs, float** outputs, VstInt32 sampleFrames);
-typedef void (VSTCALLBACK *AEffectProcessDoubleProc) (AEffect* effect, double** inputs, double** outputs, VstInt32 sampleFrames);
-typedef void (VSTCALLBACK *AEffectSetParameterProc) (AEffect* effect, VstInt32 index, float parameter);
-typedef float (VSTCALLBACK *AEffectGetParameterProc) (AEffect* effect, VstInt32 index);
-/// @endcond
-
-/** Four Character Constant (for AEffect->uniqueID) */
-#define CCONST(a, b, c, d) \
-	 ((((VstInt32)a) << 24) | (((VstInt32)b) << 16) | (((VstInt32)c) << 8) | (((VstInt32)d) << 0))
-
-/** AEffect magic number */
-#define kEffectMagic CCONST ('V', 's', 't', 'P')
-
-//-------------------------------------------------------------------------------------------------------
-/** Basic VST Effect "C" Interface. */
-//-------------------------------------------------------------------------------------------------------
-struct AEffect
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 magic;			///< must be #kEffectMagic ('VstP')
-
-	/** Host to Plug-in dispatcher @see AudioEffect::dispatcher */
-	AEffectDispatcherProc dispatcher;
-	
-	/** \deprecated Accumulating process mode is deprecated in VST 2.4! Use AEffect::processReplacing instead! */
-	AEffectProcessProc DECLARE_VST_DEPRECATED (process);
-	
-	/** Set new value of automatable parameter @see AudioEffect::setParameter */
-	AEffectSetParameterProc setParameter;
-
-	/** Returns current value of automatable parameter @see AudioEffect::getParameter*/
-	AEffectGetParameterProc getParameter;
-
-	VstInt32 numPrograms;   ///< number of programs
-	VstInt32 numParams;		///< all programs are assumed to have numParams parameters
-	VstInt32 numInputs;		///< number of audio inputs
-	VstInt32 numOutputs;	///< number of audio outputs
-
-	VstInt32 flags;			///< @see VstAEffectFlags
-	
-	VstIntPtr resvd1;		///< reserved for Host, must be 0
-	VstIntPtr resvd2;		///< reserved for Host, must be 0
-	
-	VstInt32 initialDelay;	///< for algorithms which need input in the first place (Group delay or latency in Samples). This value should be initialized in a resume state.
-	
-	VstInt32 DECLARE_VST_DEPRECATED (realQualities);	///< \deprecated unused member
-	VstInt32 DECLARE_VST_DEPRECATED (offQualities);		///< \deprecated unused member
-	float    DECLARE_VST_DEPRECATED (ioRatio);			///< \deprecated unused member
-
-	void* object;			///< #AudioEffect class pointer
-	void* user;				///< user-defined pointer
-
-	VstInt32 uniqueID;		///< registered unique identifier (register it at Steinberg 3rd party support Web). This is used to identify a plug-in during save+load of preset and project.
-	VstInt32 version;		///< plug-in version (example 1100 for version 1.1.0.0)
-
-	/** Process audio samples in replacing mode @see AudioEffect::processReplacing */
-	AEffectProcessProc processReplacing;
-
-#if VST_2_4_EXTENSIONS
-	/** Process double-precision audio samples in replacing mode @see AudioEffect::processDoubleReplacing */
-	AEffectProcessDoubleProc processDoubleReplacing;
-	
-	char future[56];		///< reserved for future use (please zero)
-#else
-	char future[60];		///< reserved for future use (please zero)
-#endif
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** AEffect flags */
-//-------------------------------------------------------------------------------------------------------
-enum VstAEffectFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	effFlagsHasEditor     = 1 << 0,			///< set if the plug-in provides a custom editor
-	effFlagsCanReplacing  = 1 << 4,			///< supports replacing process mode (which should the default mode in VST 2.4)
-	effFlagsProgramChunks = 1 << 5,			///< program data is handled in formatless chunks
-	effFlagsIsSynth       = 1 << 8,			///< plug-in is a synth (VSTi), Host may assign mixer channels for its outputs
-	effFlagsNoSoundInStop = 1 << 9,			///< plug-in does not produce sound when input is all silence
-
-#if VST_2_4_EXTENSIONS
-	effFlagsCanDoubleReplacing = 1 << 12,	///< plug-in supports double precision processing
-#endif
-
-	DECLARE_VST_DEPRECATED (effFlagsHasClip) = 1 << 1,			///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effFlagsHasVu)   = 1 << 2,			///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effFlagsCanMono) = 1 << 3,			///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effFlagsExtIsAsync)   = 1 << 10,	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effFlagsExtHasBuffer) = 1 << 11		///< \deprecated deprecated in VST 2.4
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Basic dispatcher Opcodes (Host to Plug-in) */
-//-------------------------------------------------------------------------------------------------------
-enum AEffectOpcodes
-{
-	effOpen = 0,		///< no arguments  @see AudioEffect::open
-	effClose,			///< no arguments  @see AudioEffect::close
-
-	effSetProgram,		///< [value]: new program number  @see AudioEffect::setProgram
-	effGetProgram,		///< [return value]: current program number  @see AudioEffect::getProgram
-	effSetProgramName,	///< [ptr]: char* with new program name, limited to #kVstMaxProgNameLen  @see AudioEffect::setProgramName
-	effGetProgramName,	///< [ptr]: char buffer for current program name, limited to #kVstMaxProgNameLen  @see AudioEffect::getProgramName
-	
-	effGetParamLabel,	///< [ptr]: char buffer for parameter label, limited to #kVstMaxParamStrLen  @see AudioEffect::getParameterLabel
-	effGetParamDisplay,	///< [ptr]: char buffer for parameter display, limited to #kVstMaxParamStrLen  @see AudioEffect::getParameterDisplay
-	effGetParamName,	///< [ptr]: char buffer for parameter name, limited to #kVstMaxParamStrLen  @see AudioEffect::getParameterName
-	
-	DECLARE_VST_DEPRECATED (effGetVu),	///< \deprecated deprecated in VST 2.4
-
-	effSetSampleRate,	///< [opt]: new sample rate for audio processing  @see AudioEffect::setSampleRate
-	effSetBlockSize,	///< [value]: new maximum block size for audio processing  @see AudioEffect::setBlockSize
-	effMainsChanged,	///< [value]: 0 means "turn off", 1 means "turn on"  @see AudioEffect::suspend @see AudioEffect::resume
-
-	effEditGetRect,		///< [ptr]: #ERect** receiving pointer to editor size  @see ERect @see AEffEditor::getRect
-	effEditOpen,		///< [ptr]: system dependent Window pointer, e.g. HWND on Windows  @see AEffEditor::open
-	effEditClose,		///< no arguments @see AEffEditor::close
-
-	DECLARE_VST_DEPRECATED (effEditDraw),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effEditMouse),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effEditKey),	///< \deprecated deprecated in VST 2.4
-
-	effEditIdle,		///< no arguments @see AEffEditor::idle
-	
-	DECLARE_VST_DEPRECATED (effEditTop),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effEditSleep),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (effIdentify),	///< \deprecated deprecated in VST 2.4
-	
-	effGetChunk,		///< [ptr]: void** for chunk data address [index]: 0 for bank, 1 for program  @see AudioEffect::getChunk
-	effSetChunk,		///< [ptr]: chunk data [value]: byte size [index]: 0 for bank, 1 for program  @see AudioEffect::setChunk
- 
-	effNumOpcodes		
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Basic dispatcher Opcodes (Plug-in to Host) */
-//-------------------------------------------------------------------------------------------------------
-enum AudioMasterOpcodes
-{
-//-------------------------------------------------------------------------------------------------------
-	audioMasterAutomate = 0,	///< [index]: parameter index [opt]: parameter value  @see AudioEffect::setParameterAutomated
-	audioMasterVersion,			///< [return value]: Host VST version (for example 2400 for VST 2.4) @see AudioEffect::getMasterVersion
-	audioMasterCurrentId,		///< [return value]: current unique identifier on shell plug-in  @see AudioEffect::getCurrentUniqueId
-	audioMasterIdle,			///< no arguments  @see AudioEffect::masterIdle
-	DECLARE_VST_DEPRECATED (audioMasterPinConnected) ///< \deprecated deprecated in VST 2.4 r2
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** String length limits (in characters excl. 0 byte) */
-//-------------------------------------------------------------------------------------------------------
-enum VstStringConstants
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstMaxProgNameLen   = 24,	///< used for #effGetProgramName, #effSetProgramName, #effGetProgramNameIndexed
-	kVstMaxParamStrLen   = 8,	///< used for #effGetParamLabel, #effGetParamDisplay, #effGetParamName
-	kVstMaxVendorStrLen  = 64,	///< used for #effGetVendorString, #audioMasterGetVendorString
-	kVstMaxProductStrLen = 64,	///< used for #effGetProductString, #audioMasterGetProductString
-	kVstMaxEffectNameLen = 32	///< used for #effGetEffectName
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** String copy taking care of null terminator. */
-//-------------------------------------------------------------------------------------------------------
-inline char* vst_strncpy (char* dst, const char* src, size_t maxLen)
-{
-	char* result = strncpy (dst, src, maxLen);
-	dst[maxLen] = 0;
-	return result;
-}
-
-//-------------------------------------------------------------------------------------------------------
-/** String concatenation taking care of null terminator. */
-//-------------------------------------------------------------------------------------------------------
-inline char* vst_strncat (char* dst, const char* src, size_t maxLen)
-{
-	char* result = strncat (dst, src, maxLen);
-	dst[maxLen] = 0;
-	return result;
-}
-
-//-------------------------------------------------------------------------------------------------------
-/** Cast #VstIntPtr to pointer. */
-//-------------------------------------------------------------------------------------------------------
-template <class T> inline T* FromVstPtr (VstIntPtr& arg)
-{
-	T** address = (T**)&arg;
-	return *address;
-}
-
-//-------------------------------------------------------------------------------------------------------
-/** Cast pointer to #VstIntPtr. */
-//-------------------------------------------------------------------------------------------------------
-template <class T> inline VstIntPtr ToVstPtr (T* ptr)
-{
-	VstIntPtr* address = (VstIntPtr*)&ptr;
-	return *address;
-}
-
-//-------------------------------------------------------------------------------------------------------
-/** Structure used for #effEditGetRect. */
-//-------------------------------------------------------------------------------------------------------
-struct ERect
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt16 top;		///< top coordinate
-	VstInt16 left;		///< left coordinate
-	VstInt16 bottom;	///< bottom coordinate
-	VstInt16 right;		///< right coordinate
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-#if TARGET_API_MAC_CARBON
-	#pragma options align=reset
-#elif defined(WIN32) || defined(__FLAT__) || defined(__GNUC__)
-	#pragma pack(pop)
-#elif defined __BORLANDC__
-	#pragma -a-
-#endif
-
-#endif	// __aeffect__
diff --git a/src/deps/vst/aeffectx.h b/src/deps/vst/aeffectx.h
deleted file mode 100644
index 8bf7043..0000000
--- a/src/deps/vst/aeffectx.h
+++ /dev/null
@@ -1,1143 +0,0 @@
-//-------------------------------------------------------------------------------------------------------
-// VST Plug-Ins SDK
-// Version 2.4		$Date: 2006/06/20 12:43:42 $
-//
-// Category     : VST 2.x Interfaces
-// Filename     : aeffectx.h
-// Created by   : Steinberg Media Technologies
-// Description  : Definition of auxiliary structures, extensions from VST 1.0 to VST 2.4
-//
-// © 2006, Steinberg Media Technologies, All Rights Reserved
-//-------------------------------------------------------------------------------------------------------
-
-#ifndef __aeffectx__
-#define __aeffectx__
-
-#ifndef __aeffect__
-#include "aeffect.h"
-#endif
-
-//-------------------------------------------------------------------------------------------------------
-#if TARGET_API_MAC_CARBON
-	#ifdef __LP64__
-	#pragma options align=power
-	#else
-	#pragma options align=mac68k
-	#endif
-#elif defined __BORLANDC__
-	#pragma -a8
-#elif defined(__GNUC__)
-    #pragma pack(push,8)
-#elif defined(WIN32) || defined(__FLAT__)
-	#pragma pack(push)
-	#pragma pack(8)
-#endif
-//-------------------------------------------------------------------------------------------------------
-
-//-------------------------------------------------------------------------------------------------------
-/** String length limits (in characters excl. 0 byte). */
-//-------------------------------------------------------------------------------------------------------
-enum Vst2StringConstants
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstMaxNameLen       = 64,	///< used for #MidiProgramName, #MidiProgramCategory, #MidiKeyName, #VstSpeakerProperties, #VstPinProperties
-	kVstMaxLabelLen      = 64,	///< used for #VstParameterProperties->label, #VstPinProperties->label
-	kVstMaxShortLabelLen = 8,	///< used for #VstParameterProperties->shortLabel, #VstPinProperties->shortLabel
-	kVstMaxCategLabelLen = 24,	///< used for #VstParameterProperties->label
-	kVstMaxFileNameLen   = 100	///< used for #VstAudioFile->name
-//-------------------------------------------------------------------------------------------------------
-};
-//-------------------------------------------------------------------------------------------------------
-// VstEvent
-//-------------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------------
-/** A generic timestamped event. */
-//-------------------------------------------------------------------------------------------------------
-struct VstEvent
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 type;			///< @see VstEventTypes
-	VstInt32 byteSize;		///< size of this event, excl. type and byteSize
-	VstInt32 deltaFrames;	///< sample frames related to the current block start sample position
-	VstInt32 flags;			///< generic flags, none defined yet
-
-	char data[16];			///< data size may vary, depending on event type
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** VstEvent Types used by #VstEvent. */
-//-------------------------------------------------------------------------------------------------------
-enum VstEventTypes
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstMidiType = 1,		///< MIDI event  @see VstMidiEvent
-	DECLARE_VST_DEPRECATED (kVstAudioType),		///< \deprecated unused event type
-	DECLARE_VST_DEPRECATED (kVstVideoType),		///< \deprecated unused event type
-	DECLARE_VST_DEPRECATED (kVstParameterType),	///< \deprecated unused event type
-	DECLARE_VST_DEPRECATED (kVstTriggerType),	///< \deprecated unused event type
-	kVstSysExType			///< MIDI system exclusive  @see VstMidiSysexEvent
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** A block of events for the current processed audio block. */
-//-------------------------------------------------------------------------------------------------------
-struct VstEvents
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 numEvents;		///< number of Events in array
-	VstIntPtr reserved;		///< zero (Reserved for future use)
-	VstEvent* events[2];	///< event pointer array, variable size
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** MIDI Event (to be casted from VstEvent). */
-//-------------------------------------------------------------------------------------------------------
-struct VstMidiEvent
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 type;			///< #kVstMidiType
-	VstInt32 byteSize;		///< sizeof (VstMidiEvent)
-	VstInt32 deltaFrames;	///< sample frames related to the current block start sample position
-	VstInt32 flags;			///< @see VstMidiEventFlags
-	VstInt32 noteLength;	///< (in sample frames) of entire note, if available, else 0
-	VstInt32 noteOffset;	///< offset (in sample frames) into note from note start if available, else 0
-	char midiData[4];		///< 1 to 3 MIDI bytes; midiData[3] is reserved (zero)
-	char detune;			///< -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')
-	char noteOffVelocity;	///< Note Off Velocity [0, 127]
-	char reserved1;			///< zero (Reserved for future use)
-	char reserved2;			///< zero (Reserved for future use)
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in #VstMidiEvent. */
-//-------------------------------------------------------------------------------------------------------
-enum VstMidiEventFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstMidiEventIsRealtime = 1 << 0	///< means that this event is played life (not in playback from a sequencer track).\n This allows the Plug-In to handle these flagged events with higher priority, especially when the Plug-In has a big latency (AEffect::initialDelay)
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** MIDI Sysex Event (to be casted from #VstEvent). */
-//-------------------------------------------------------------------------------------------------------
-struct VstMidiSysexEvent
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 type;			///< #kVstSysexType
-	VstInt32 byteSize;		///< sizeof (VstMidiSysexEvent)
-	VstInt32 deltaFrames;	///< sample frames related to the current block start sample position
-	VstInt32 flags;			///< none defined yet (should be zero)
-	VstInt32 dumpBytes;		///< byte size of sysexDump
-	VstIntPtr resvd1;		///< zero (Reserved for future use)
-	char* sysexDump;		///< sysex dump
-	VstIntPtr resvd2;		///< zero (Reserved for future use)
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-// VstTimeInfo
-//-------------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------------
-/** VstTimeInfo requested via #audioMasterGetTime.  @see AudioEffectX::getTimeInfo 
-
-\note VstTimeInfo::samplePos :Current Position. It must always be valid, and should not cost a lot to ask for. The sample position is ahead of the time displayed to the user. In sequencer stop mode, its value does not change. A 32 bit integer is too small for sample positions, and it's a double to make it easier to convert between ppq and samples.
-\note VstTimeInfo::ppqPos : At tempo 120, 1 quarter makes 1/2 second, so 2.0 ppq translates to 48000 samples at 48kHz sample rate.
-.25 ppq is one sixteenth note then. if you need something like 480ppq, you simply multiply ppq by that scaler.
-\note VstTimeInfo::barStartPos : Say we're at bars/beats readout 3.3.3. That's 2 bars + 2 q + 2 sixteenth, makes 2 * 4 + 2 + .25 = 10.25 ppq. at tempo 120, that's 10.25 * .5 = 5.125 seconds, times 48000 = 246000 samples (if my calculator servers me well :-). 
-\note VstTimeInfo::samplesToNextClock : MIDI Clock Resolution (24 per Quarter Note), can be negative the distance to the next midi clock (24 ppq, pulses per quarter) in samples. unless samplePos falls precicely on a midi clock, this will either be negative such that the previous MIDI clock is addressed, or positive when referencing the following (future) MIDI clock.
-*/
-//-------------------------------------------------------------------------------------------------------
-struct VstTimeInfo
-{
-//-------------------------------------------------------------------------------------------------------
-	double samplePos;				///< current Position in audio samples (always valid)
-	double sampleRate;				///< current Sample Rate in Herz (always valid)
-	double nanoSeconds;				///< System Time in nanoseconds (10^-9 second)
-	double ppqPos;					///< Musical Position, in Quarter Note (1.0 equals 1 Quarter Note)
-	double tempo;					///< current Tempo in BPM (Beats Per Minute)
-	double barStartPos;				///< last Bar Start Position, in Quarter Note
-	double cycleStartPos;			///< Cycle Start (left locator), in Quarter Note
-	double cycleEndPos;				///< Cycle End (right locator), in Quarter Note
-	VstInt32 timeSigNumerator;		///< Time Signature Numerator (e.g. 3 for 3/4)
-	VstInt32 timeSigDenominator;	///< Time Signature Denominator (e.g. 4 for 3/4)
-	VstInt32 smpteOffset;			///< SMPTE offset (in SMPTE subframes (bits; 1/80 of a frame)). The current SMPTE position can be calculated using #samplePos, #sampleRate, and #smpteFrameRate.
-	VstInt32 smpteFrameRate;		///< @see VstSmpteFrameRate
-	VstInt32 samplesToNextClock;	///< MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest clock)
-	VstInt32 flags;					///< @see VstTimeInfoFlags
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in #VstTimeInfo. */
-//-------------------------------------------------------------------------------------------------------
-enum VstTimeInfoFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstTransportChanged     = 1,		///< indicates that play, cycle or record state has changed
-	kVstTransportPlaying     = 1 << 1,	///< set if Host sequencer is currently playing
-	kVstTransportCycleActive = 1 << 2,	///< set if Host sequencer is in cycle mode
-	kVstTransportRecording   = 1 << 3,	///< set if Host sequencer is in record mode
-	kVstAutomationWriting    = 1 << 6,	///< set if automation write mode active (record parameter changes)
-	kVstAutomationReading    = 1 << 7,	///< set if automation read mode active (play parameter changes)
-	kVstNanosValid           = 1 << 8,	///< VstTimeInfo::nanoSeconds valid
-	kVstPpqPosValid          = 1 << 9,	///< VstTimeInfo::ppqPos valid
-	kVstTempoValid           = 1 << 10,	///< VstTimeInfo::tempo valid
-	kVstBarsValid            = 1 << 11,	///< VstTimeInfo::barStartPos valid
-	kVstCyclePosValid        = 1 << 12,	///< VstTimeInfo::cycleStartPos and VstTimeInfo::cycleEndPos valid
-	kVstTimeSigValid         = 1 << 13,	///< VstTimeInfo::timeSigNumerator and VstTimeInfo::timeSigDenominator valid
-	kVstSmpteValid           = 1 << 14,	///< VstTimeInfo::smpteOffset and VstTimeInfo::smpteFrameRate valid
-	kVstClockValid           = 1 << 15	///< VstTimeInfo::samplesToNextClock valid
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** SMPTE Frame Rates. */
-//-------------------------------------------------------------------------------------------------------
-enum VstSmpteFrameRate
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstSmpte24fps    = 0,		///< 24 fps
-	kVstSmpte25fps    = 1,		///< 25 fps
-	kVstSmpte2997fps  = 2,		///< 29.97 fps
-	kVstSmpte30fps    = 3,		///< 30 fps
-	kVstSmpte2997dfps = 4,		///< 29.97 drop
-	kVstSmpte30dfps   = 5,		///< 30 drop
-
-	kVstSmpteFilm16mm = 6, 		///< Film 16mm
-	kVstSmpteFilm35mm = 7, 		///< Film 35mm
-	kVstSmpte239fps   = 10,		///< HDTV: 23.976 fps
-	kVstSmpte249fps   = 11,		///< HDTV: 24.976 fps
-	kVstSmpte599fps   = 12,		///< HDTV: 59.94 fps
-	kVstSmpte60fps    = 13		///< HDTV: 60 fps
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Variable IO for Offline Processing. */
-//-------------------------------------------------------------------------------------------------------
-struct VstVariableIo
-{
-//-------------------------------------------------------------------------------------------------------
-	float** inputs;								///< input audio buffers
-	float** outputs;							///< output audio buffers
-	VstInt32 numSamplesInput;					///< number of incoming samples
-	VstInt32 numSamplesOutput;					///< number of outgoing samples
-	VstInt32* numSamplesInputProcessed;			///< number of samples actually processed of input
-	VstInt32* numSamplesOutputProcessed;		///< number of samples actually processed of output
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Language code returned by audioMasterGetLanguage. */
-//-------------------------------------------------------------------------------------------------------
-enum VstHostLanguage
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstLangEnglish = 1,	///< English
-	kVstLangGerman,			///< German
-	kVstLangFrench,			///< French
-	kVstLangItalian,		///< Italian
-	kVstLangSpanish,		///< Spanish
-	kVstLangJapanese		///< Japanese
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** VST 2.x dispatcher Opcodes (Plug-in to Host). Extension of #AudioMasterOpcodes */
-//-------------------------------------------------------------------------------------------------------
-enum AudioMasterOpcodesX
-{
-//-------------------------------------------------------------------------------------------------------
-	DECLARE_VST_DEPRECATED (audioMasterWantMidi) = DECLARE_VST_DEPRECATED (audioMasterPinConnected) + 2,	///< \deprecated deprecated in VST 2.4
-
-	audioMasterGetTime,				///< [return value]: #VstTimeInfo* or null if not supported [value]: request mask  @see VstTimeInfoFlags @see AudioEffectX::getTimeInfo
-	audioMasterProcessEvents,		///< [ptr]: pointer to #VstEvents  @see VstEvents @see AudioEffectX::sendVstEventsToHost
-
-	DECLARE_VST_DEPRECATED (audioMasterSetTime),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterTempoAt),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterGetNumAutomatableParameters),	///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterGetParameterQuantization),		///< \deprecated deprecated in VST 2.4
-
-	audioMasterIOChanged,			///< [return value]: 1 if supported  @see AudioEffectX::ioChanged
-
-	DECLARE_VST_DEPRECATED (audioMasterNeedIdle),	///< \deprecated deprecated in VST 2.4
-	
-	audioMasterSizeWindow,			///< [index]: new width [value]: new height [return value]: 1 if supported  @see AudioEffectX::sizeWindow
-	audioMasterGetSampleRate,		///< [return value]: current sample rate  @see AudioEffectX::updateSampleRate
-	audioMasterGetBlockSize,		///< [return value]: current block size  @see AudioEffectX::updateBlockSize
-	audioMasterGetInputLatency,		///< [return value]: input latency in audio samples  @see AudioEffectX::getInputLatency
-	audioMasterGetOutputLatency,	///< [return value]: output latency in audio samples  @see AudioEffectX::getOutputLatency
-
-	DECLARE_VST_DEPRECATED (audioMasterGetPreviousPlug),			///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterGetNextPlug),				///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterWillReplaceOrAccumulate),	///< \deprecated deprecated in VST 2.4
-
-	audioMasterGetCurrentProcessLevel,	///< [return value]: current process level  @see VstProcessLevels
-	audioMasterGetAutomationState,		///< [return value]: current automation state  @see VstAutomationStates
-
-	audioMasterOfflineStart,			///< [index]: numNewAudioFiles [value]: numAudioFiles [ptr]: #VstAudioFile*  @see AudioEffectX::offlineStart
-	audioMasterOfflineRead,				///< [index]: bool readSource [value]: #VstOfflineOption* @see VstOfflineOption [ptr]: #VstOfflineTask*  @see VstOfflineTask @see AudioEffectX::offlineRead
-	audioMasterOfflineWrite,			///< @see audioMasterOfflineRead @see AudioEffectX::offlineRead
-	audioMasterOfflineGetCurrentPass,	///< @see AudioEffectX::offlineGetCurrentPass
-	audioMasterOfflineGetCurrentMetaPass,	///< @see AudioEffectX::offlineGetCurrentMetaPass
-
-	DECLARE_VST_DEPRECATED (audioMasterSetOutputSampleRate),			///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterGetOutputSpeakerArrangement),	///< \deprecated deprecated in VST 2.4
-
-	audioMasterGetVendorString,			///< [ptr]: char buffer for vendor string, limited to #kVstMaxVendorStrLen  @see AudioEffectX::getHostVendorString
-	audioMasterGetProductString,		///< [ptr]: char buffer for vendor string, limited to #kVstMaxProductStrLen  @see AudioEffectX::getHostProductString
-	audioMasterGetVendorVersion,		///< [return value]: vendor-specific version  @see AudioEffectX::getHostVendorVersion
-	audioMasterVendorSpecific,			///< no definition, vendor specific handling  @see AudioEffectX::hostVendorSpecific
-	
-	DECLARE_VST_DEPRECATED (audioMasterSetIcon),		///< \deprecated deprecated in VST 2.4
-	
-	audioMasterCanDo,					///< [ptr]: "can do" string [return value]: 1 for supported
-	audioMasterGetLanguage,				///< [return value]: language code  @see VstHostLanguage
-
-	DECLARE_VST_DEPRECATED (audioMasterOpenWindow),		///< \deprecated deprecated in VST 2.4
-	DECLARE_VST_DEPRECATED (audioMasterCloseWindow),	///< \deprecated deprecated in VST 2.4
-
-	audioMasterGetDirectory,			///< [return value]: FSSpec on MAC, else char*  @see AudioEffectX::getDirectory
-	audioMasterUpdateDisplay,			///< no arguments	
-	audioMasterBeginEdit,               ///< [index]: parameter index  @see AudioEffectX::beginEdit
-	audioMasterEndEdit,                 ///< [index]: parameter index  @see AudioEffectX::endEdit
-	audioMasterOpenFileSelector,		///< [ptr]: VstFileSelect* [return value]: 1 if supported  @see AudioEffectX::openFileSelector
-	audioMasterCloseFileSelector,		///< [ptr]: VstFileSelect*  @see AudioEffectX::closeFileSelector
-	
-	DECLARE_VST_DEPRECATED (audioMasterEditFile),		///< \deprecated deprecated in VST 2.4
-	
-	DECLARE_VST_DEPRECATED (audioMasterGetChunkFile),	///< \deprecated deprecated in VST 2.4 [ptr]: char[2048] or sizeof (FSSpec) [return value]: 1 if supported  @see AudioEffectX::getChunkFile
-
-	DECLARE_VST_DEPRECATED (audioMasterGetInputSpeakerArrangement)	///< \deprecated deprecated in VST 2.4
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** VST 2.x dispatcher Opcodes (Host to Plug-in). Extension of #AEffectOpcodes */
-//-------------------------------------------------------------------------------------------------------
-enum AEffectXOpcodes
-{
-//-------------------------------------------------------------------------------------------------------
-	effProcessEvents = effSetChunk + 1		///< [ptr]: #VstEvents*  @see AudioEffectX::processEvents
-
-	, effCanBeAutomated						///< [index]: parameter index [return value]: 1=true, 0=false  @see AudioEffectX::canParameterBeAutomated
-	, effString2Parameter					///< [index]: parameter index [ptr]: parameter string [return value]: true for success  @see AudioEffectX::string2parameter
-
-	, DECLARE_VST_DEPRECATED (effGetNumProgramCategories)	///< \deprecated deprecated in VST 2.4
-
-	, effGetProgramNameIndexed				///< [index]: program index [ptr]: buffer for program name, limited to #kVstMaxProgNameLen [return value]: true for success  @see AudioEffectX::getProgramNameIndexed
-	
-	, DECLARE_VST_DEPRECATED (effCopyProgram)	///< \deprecated deprecated in VST 2.4
-	, DECLARE_VST_DEPRECATED (effConnectInput)	///< \deprecated deprecated in VST 2.4
-	, DECLARE_VST_DEPRECATED (effConnectOutput)	///< \deprecated deprecated in VST 2.4
-	
-	, effGetInputProperties					///< [index]: input index [ptr]: #VstPinProperties* [return value]: 1 if supported  @see AudioEffectX::getInputProperties
-	, effGetOutputProperties				///< [index]: output index [ptr]: #VstPinProperties* [return value]: 1 if supported  @see AudioEffectX::getOutputProperties
-	, effGetPlugCategory					///< [return value]: category  @see VstPlugCategory @see AudioEffectX::getPlugCategory
-
-	, DECLARE_VST_DEPRECATED (effGetCurrentPosition)	///< \deprecated deprecated in VST 2.4
-	, DECLARE_VST_DEPRECATED (effGetDestinationBuffer)	///< \deprecated deprecated in VST 2.4
-
-	, effOfflineNotify						///< [ptr]: #VstAudioFile array [value]: count [index]: start flag  @see AudioEffectX::offlineNotify
-	, effOfflinePrepare						///< [ptr]: #VstOfflineTask array [value]: count  @see AudioEffectX::offlinePrepare
-	, effOfflineRun							///< [ptr]: #VstOfflineTask array [value]: count  @see AudioEffectX::offlineRun
-
-	, effProcessVarIo						///< [ptr]: #VstVariableIo*  @see AudioEffectX::processVariableIo
-	, effSetSpeakerArrangement				///< [value]: input #VstSpeakerArrangement* [ptr]: output #VstSpeakerArrangement*  @see AudioEffectX::setSpeakerArrangement
-
-	, DECLARE_VST_DEPRECATED (effSetBlockSizeAndSampleRate)	///< \deprecated deprecated in VST 2.4
-
-	, effSetBypass							///< [value]: 1 = bypass, 0 = no bypass  @see AudioEffectX::setBypass
-	, effGetEffectName						///< [ptr]: buffer for effect name, limited to #kVstMaxEffectNameLen  @see AudioEffectX::getEffectName
-
-	, DECLARE_VST_DEPRECATED (effGetErrorText)	///< \deprecated deprecated in VST 2.4
-
-	, effGetVendorString					///< [ptr]: buffer for effect vendor string, limited to #kVstMaxVendorStrLen  @see AudioEffectX::getVendorString
-	, effGetProductString					///< [ptr]: buffer for effect vendor string, limited to #kVstMaxProductStrLen  @see AudioEffectX::getProductString
-	, effGetVendorVersion					///< [return value]: vendor-specific version  @see AudioEffectX::getVendorVersion
-	, effVendorSpecific						///< no definition, vendor specific handling  @see AudioEffectX::vendorSpecific
-	, effCanDo								///< [ptr]: "can do" string [return value]: 0: "don't know" -1: "no" 1: "yes"  @see AudioEffectX::canDo
-	, effGetTailSize						///< [return value]: tail size (for example the reverb time of a reverb plug-in); 0 is default (return 1 for 'no tail')
-
-	, DECLARE_VST_DEPRECATED (effIdle)				///< \deprecated deprecated in VST 2.4
-	, DECLARE_VST_DEPRECATED (effGetIcon)			///< \deprecated deprecated in VST 2.4
-	, DECLARE_VST_DEPRECATED (effSetViewPosition)	///< \deprecated deprecated in VST 2.4
-
-	, effGetParameterProperties				///< [index]: parameter index [ptr]: #VstParameterProperties* [return value]: 1 if supported  @see AudioEffectX::getParameterProperties
-
-	, DECLARE_VST_DEPRECATED (effKeysRequired)	///< \deprecated deprecated in VST 2.4
-
-	, effGetVstVersion						///< [return value]: VST version  @see AudioEffectX::getVstVersion
-
-#if VST_2_1_EXTENSIONS
-	, effEditKeyDown						///< [index]: ASCII character [value]: virtual key [opt]: modifiers [return value]: 1 if key used  @see AEffEditor::onKeyDown
-	, effEditKeyUp							///< [index]: ASCII character [value]: virtual key [opt]: modifiers [return value]: 1 if key used  @see AEffEditor::onKeyUp
-	, effSetEditKnobMode					///< [value]: knob mode 0: circular, 1: circular relativ, 2: linear (CKnobMode in VSTGUI)  @see AEffEditor::setKnobMode
-
-	, effGetMidiProgramName					///< [index]: MIDI channel [ptr]: #MidiProgramName* [return value]: number of used programs, 0 if unsupported  @see AudioEffectX::getMidiProgramName
-	, effGetCurrentMidiProgram				///< [index]: MIDI channel [ptr]: #MidiProgramName* [return value]: index of current program  @see AudioEffectX::getCurrentMidiProgram
-	, effGetMidiProgramCategory				///< [index]: MIDI channel [ptr]: #MidiProgramCategory* [return value]: number of used categories, 0 if unsupported  @see AudioEffectX::getMidiProgramCategory
-	, effHasMidiProgramsChanged				///< [index]: MIDI channel [return value]: 1 if the #MidiProgramName(s) or #MidiKeyName(s) have changed  @see AudioEffectX::hasMidiProgramsChanged
-	, effGetMidiKeyName						///< [index]: MIDI channel [ptr]: #MidiKeyName* [return value]: true if supported, false otherwise  @see AudioEffectX::getMidiKeyName
-	
-	, effBeginSetProgram					///< no arguments  @see AudioEffectX::beginSetProgram
-	, effEndSetProgram						///< no arguments  @see AudioEffectX::endSetProgram
-#endif // VST_2_1_EXTENSIONS
-
-#if VST_2_3_EXTENSIONS
-	, effGetSpeakerArrangement				///< [value]: input #VstSpeakerArrangement* [ptr]: output #VstSpeakerArrangement*  @see AudioEffectX::getSpeakerArrangement
-	, effShellGetNextPlugin					///< [ptr]: buffer for plug-in name, limited to #kVstMaxProductStrLen [return value]: next plugin's uniqueID  @see AudioEffectX::getNextShellPlugin
-
-	, effStartProcess						///< no arguments  @see AudioEffectX::startProcess
-	, effStopProcess						///< no arguments  @see AudioEffectX::stopProcess
-	, effSetTotalSampleToProcess		    ///< [value]: number of samples to process, offline only!  @see AudioEffectX::setTotalSampleToProcess
-	, effSetPanLaw							///< [value]: pan law [opt]: gain  @see VstPanLawType @see AudioEffectX::setPanLaw
-	
-	, effBeginLoadBank						///< [ptr]: #VstPatchChunkInfo* [return value]: -1: bank can't be loaded, 1: bank can be loaded, 0: unsupported  @see AudioEffectX::beginLoadBank
-	, effBeginLoadProgram					///< [ptr]: #VstPatchChunkInfo* [return value]: -1: prog can't be loaded, 1: prog can be loaded, 0: unsupported  @see AudioEffectX::beginLoadProgram
-#endif // VST_2_3_EXTENSIONS
-
-#if VST_2_4_EXTENSIONS
-	, effSetProcessPrecision				///< [value]: @see VstProcessPrecision  @see AudioEffectX::setProcessPrecision
-	, effGetNumMidiInputChannels			///< [return value]: number of used MIDI input channels (1-15)  @see AudioEffectX::getNumMidiInputChannels
-	, effGetNumMidiOutputChannels			///< [return value]: number of used MIDI output channels (1-15)  @see AudioEffectX::getNumMidiOutputChannels
-#endif // VST_2_4_EXTENSIONS
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Symbolic precision constants used for effSetProcessPrecision. */
-//-------------------------------------------------------------------------------------------------------
-enum VstProcessPrecision
-{
-	kVstProcessPrecision32 = 0,		///< single precision float (32bits)
-	kVstProcessPrecision64			///< double precision (64bits)
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Parameter Properties used in #effGetParameterProperties. */
-//-------------------------------------------------------------------------------------------------------
-struct VstParameterProperties
-{
-//-------------------------------------------------------------------------------------------------------
-	float stepFloat;			///< float step
-	float smallStepFloat;		///< small float step
-	float largeStepFloat;		///< large float step
-	char label[kVstMaxLabelLen];///< parameter label
-	VstInt32 flags;				///< @see VstParameterFlags
-	VstInt32 minInteger;		///< integer minimum
-	VstInt32 maxInteger;		///< integer maximum
-	VstInt32 stepInteger;		///< integer step
-	VstInt32 largeStepInteger;	///< large integer step
-	char shortLabel[kVstMaxShortLabelLen];	///< short label, recommended: 6 + delimiter
-
-	// The following are for remote controller display purposes.
-	// Note that the kVstParameterSupportsDisplayIndex flag must be set.
-	// Host can scan all parameters, and find out in what order
-	// to display them:
-
-	VstInt16 displayIndex;		///< index where this parameter should be displayed (starting with 0)
-
-	// Host can also possibly display the parameter group (category), such as...
-	// ---------------------------
-	// Osc 1
-	// Wave  Detune  Octave  Mod
-	// ---------------------------
-	// ...if the plug-in supports it (flag #kVstParameterSupportsDisplayCategory)
-
-	VstInt16 category;			///< 0: no category, else group index + 1
-	VstInt16 numParametersInCategory;			///< number of parameters in category
-	VstInt16 reserved;			///< zero
-	char categoryLabel[kVstMaxCategLabelLen];	///< category label, e.g. "Osc 1" 
-
-	char future[16];			///< reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in #VstParameterProperties. */
-//-------------------------------------------------------------------------------------------------------
-enum VstParameterFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstParameterIsSwitch				 = 1 << 0,	///< parameter is a switch (on/off)
-	kVstParameterUsesIntegerMinMax		 = 1 << 1,	///< minInteger, maxInteger valid
-	kVstParameterUsesFloatStep			 = 1 << 2,	///< stepFloat, smallStepFloat, largeStepFloat valid
-	kVstParameterUsesIntStep			 = 1 << 3,	///< stepInteger, largeStepInteger valid
-	kVstParameterSupportsDisplayIndex 	 = 1 << 4,	///< displayIndex valid
-	kVstParameterSupportsDisplayCategory = 1 << 5,	///< category, etc. valid
-	kVstParameterCanRamp				 = 1 << 6	///< set if parameter value can ramp up/down
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Pin Properties used in #effGetInputProperties and #effGetOutputProperties. */
-//-------------------------------------------------------------------------------------------------------
-struct VstPinProperties
-{
-//-------------------------------------------------------------------------------------------------------
-	char label[kVstMaxLabelLen];	///< pin name
-	VstInt32 flags;					///< @see VstPinPropertiesFlags
-	VstInt32 arrangementType;		///< @see VstSpeakerArrangementType
-	char shortLabel[kVstMaxShortLabelLen];	///< short name (recommended: 6 + delimiter)
-
-	char future[48];				///< reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in #VstPinProperties. */
-//-------------------------------------------------------------------------------------------------------
-enum VstPinPropertiesFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstPinIsActive   = 1 << 0,		///< pin is active, ignored by Host
-	kVstPinIsStereo   = 1 << 1,		///< pin is first of a stereo pair
-	kVstPinUseSpeaker = 1 << 2		///< #VstPinProperties::arrangementType is valid and can be used to get the wanted arrangement
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Plug-in Categories. */
-//-------------------------------------------------------------------------------------------------------
-enum VstPlugCategory
-{
-//-------------------------------------------------------------------------------------------------------
-    kPlugCategUnknown = 0,		///< Unknown, category not implemented
-    kPlugCategEffect,			///< Simple Effect
-    kPlugCategSynth,			///< VST Instrument (Synths, samplers,...)
-    kPlugCategAnalysis,			///< Scope, Tuner, ...
-    kPlugCategMastering,		///< Dynamics, ...
-	kPlugCategSpacializer,		///< Panners, ...
-	kPlugCategRoomFx,			///< Delays and Reverbs
-	kPlugSurroundFx,			///< Dedicated surround processor
-	kPlugCategRestoration,		///< Denoiser, ...
-	kPlugCategOfflineProcess,	///< Offline Process
-	kPlugCategShell,			///< Plug-in is container of other plug-ins  @see effShellGetNextPlugin
-	kPlugCategGenerator,		///< ToneGenerator, ...
-
-	kPlugCategMaxCount			///< Marker to count the categories
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-// MIDI Programs
-//-------------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------------
-/** MIDI Program Description. */
-//-------------------------------------------------------------------------------------------------------
-struct MidiProgramName 
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 thisProgramIndex;		///< 0 or greater: fill struct for this program index
-	char name[kVstMaxNameLen];		///< program name
-	char midiProgram;				///< -1:off, 0-127
-	char midiBankMsb;				///< -1:off, 0-127
-	char midiBankLsb;				///< -1:off, 0-127
-	char reserved;					///< zero
-	VstInt32 parentCategoryIndex;	///< -1:no parent category
-	VstInt32 flags;					///< omni etc. @see VstMidiProgramNameFlags
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in MidiProgramName. */
-//-------------------------------------------------------------------------------------------------------
-enum VstMidiProgramNameFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kMidiIsOmni = 1	///< default is multi. for omni mode, channel 0 is used for inquiries and program changes
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** MIDI Program Category. */
-//-------------------------------------------------------------------------------------------------------
-struct MidiProgramCategory 
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 thisCategoryIndex;		///< 0 or greater:  fill struct for this category index.
-	char name[kVstMaxNameLen];		///< name
-	VstInt32 parentCategoryIndex;	///< -1:no parent category
-	VstInt32 flags;					///< reserved, none defined yet, zero.
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** MIDI Key Description. */
-//-------------------------------------------------------------------------------------------------------
-struct MidiKeyName 
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 thisProgramIndex;		///< 0 or greater:  fill struct for this program index.
-	VstInt32 thisKeyNumber;			///< 0 - 127. fill struct for this key number.
-	char keyName[kVstMaxNameLen];	///< key name, empty means regular key names
-	VstInt32 reserved;				///< zero
-	VstInt32 flags;					///< reserved, none defined yet, zero.
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-// Surround Setup
-//-------------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------------
-/** Speaker Properties.
-	The origin for azimuth is right (as by math conventions dealing with radians).
-	The elevation origin is also right, visualizing a rotation of a circle across the
-	-pi/pi axis of the horizontal circle. Thus, an elevation of -pi/2 corresponds
-	to bottom, and a speaker standing on the left, and 'beaming' upwards would have
-	an azimuth of -pi, and an elevation of pi/2.
-	For user interface representation, grads are more likely to be used, and the
-	origins will obviously 'shift' accordingly. */
-//-------------------------------------------------------------------------------------------------------
-struct VstSpeakerProperties
-{
-//-------------------------------------------------------------------------------------------------------
-	float azimuth;		///< unit: rad, range: -PI...PI, exception: 10.f for LFE channel
-	float elevation;	///< unit: rad, range: -PI/2...PI/2, exception: 10.f for LFE channel
-	float radius;		///< unit: meter, exception: 0.f for LFE channel
-	float reserved;		///< zero (reserved for future use)
-	char name[kVstMaxNameLen];	///< for new setups, new names should be given (L/R/C... won't do)
-	VstInt32 type;		///< @see VstSpeakerType
-
-	char future[28];	///< reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Speaker Arrangement. */
-//-------------------------------------------------------------------------------------------------------
-struct VstSpeakerArrangement
-{	
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 type;						///< e.g. #kSpeakerArr51 for 5.1  @see VstSpeakerArrangementType
-	VstInt32 numChannels;				///< number of channels in this speaker arrangement
-	VstSpeakerProperties speakers[8];	///< variable sized speaker array
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Speaker Types. */
-//-------------------------------------------------------------------------------------------------------
-enum VstSpeakerType
-{
-//-------------------------------------------------------------------------------------------------------
-	kSpeakerUndefined = 0x7fffffff,	///< Undefined
-	kSpeakerM = 0,					///< Mono (M)
-	kSpeakerL,						///< Left (L)
-	kSpeakerR,						///< Right (R)
-	kSpeakerC,						///< Center (C)
-	kSpeakerLfe,					///< Subbass (Lfe)
-	kSpeakerLs,						///< Left Surround (Ls)
-	kSpeakerRs,						///< Right Surround (Rs)
-	kSpeakerLc,						///< Left of Center (Lc)
-	kSpeakerRc,						///< Right of Center (Rc)
-	kSpeakerS,						///< Surround (S)
-	kSpeakerCs = kSpeakerS,			///< Center of Surround (Cs) = Surround (S)
-	kSpeakerSl,						///< Side Left (Sl)
-	kSpeakerSr,						///< Side Right (Sr)
-	kSpeakerTm,						///< Top Middle (Tm)
-	kSpeakerTfl,					///< Top Front Left (Tfl)
-	kSpeakerTfc,					///< Top Front Center (Tfc)
-	kSpeakerTfr,					///< Top Front Right (Tfr)
-	kSpeakerTrl,					///< Top Rear Left (Trl)
-	kSpeakerTrc,					///< Top Rear Center (Trc)
-	kSpeakerTrr,					///< Top Rear Right (Trr)
-	kSpeakerLfe2					///< Subbass 2 (Lfe2)
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** User-defined speaker types, to be extended in the negative range.
-	Will be handled as their corresponding speaker types with abs values:
-	e.g abs(#kSpeakerU1) == #kSpeakerL, abs(#kSpeakerU2) == #kSpeakerR) */
-//-------------------------------------------------------------------------------------------------------
-enum VstUserSpeakerType
-{
-//-------------------------------------------------------------------------------------------------------
-	kSpeakerU32 = -32,	
-	kSpeakerU31,			
-	kSpeakerU30,			
-	kSpeakerU29,			
-	kSpeakerU28,			
-	kSpeakerU27,			
-	kSpeakerU26,			
-	kSpeakerU25,			
-	kSpeakerU24,			
-	kSpeakerU23,			
-	kSpeakerU22,			
-	kSpeakerU21,			
-	kSpeakerU20,			///< == #kSpeakerLfe2
-	kSpeakerU19,			///< == #kSpeakerTrr
-	kSpeakerU18,			///< == #kSpeakerTrc
-	kSpeakerU17,			///< == #kSpeakerTrl
-	kSpeakerU16,			///< == #kSpeakerTfr
-	kSpeakerU15,			///< == #kSpeakerTfc
-	kSpeakerU14,			///< == #kSpeakerTfl
-	kSpeakerU13,			///< == #kSpeakerTm
-	kSpeakerU12,			///< == #kSpeakerSr
-	kSpeakerU11,			///< == #kSpeakerSl
-	kSpeakerU10,			///< == #kSpeakerCs
-	kSpeakerU9,				///< == #kSpeakerS
-	kSpeakerU8,				///< == #kSpeakerRc
-	kSpeakerU7,				///< == #kSpeakerLc
-	kSpeakerU6,				///< == #kSpeakerRs
-	kSpeakerU5,				///< == #kSpeakerLs
-	kSpeakerU4,				///< == #kSpeakerLfe
-	kSpeakerU3,				///< == #kSpeakerC
-	kSpeakerU2,				///< == #kSpeakerR
-	kSpeakerU1				///< == #kSpeakerL
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Speaker Arrangement Types*/
-//-------------------------------------------------------------------------------------------------------
-enum VstSpeakerArrangementType
-{
-//-------------------------------------------------------------------------------------------------------
-	kSpeakerArrUserDefined = -2,///< user defined
-	kSpeakerArrEmpty = -1,		///< empty arrangement
-	kSpeakerArrMono  =  0,		///< M
-	kSpeakerArrStereo,			///< L R
-	kSpeakerArrStereoSurround,	///< Ls Rs
-	kSpeakerArrStereoCenter,	///< Lc Rc
-	kSpeakerArrStereoSide,		///< Sl Sr
-	kSpeakerArrStereoCLfe,		///< C Lfe
-	kSpeakerArr30Cine,			///< L R C
-	kSpeakerArr30Music,			///< L R S
-	kSpeakerArr31Cine,			///< L R C Lfe
-	kSpeakerArr31Music,			///< L R Lfe S
-	kSpeakerArr40Cine,			///< L R C   S (LCRS)
-	kSpeakerArr40Music,			///< L R Ls  Rs (Quadro)
-	kSpeakerArr41Cine,			///< L R C   Lfe S (LCRS+Lfe)
-	kSpeakerArr41Music,			///< L R Lfe Ls Rs (Quadro+Lfe)
-	kSpeakerArr50,				///< L R C Ls  Rs 
-	kSpeakerArr51,				///< L R C Lfe Ls Rs
-	kSpeakerArr60Cine,			///< L R C   Ls  Rs Cs
-	kSpeakerArr60Music,			///< L R Ls  Rs  Sl Sr 
-	kSpeakerArr61Cine,			///< L R C   Lfe Ls Rs Cs
-	kSpeakerArr61Music,			///< L R Lfe Ls  Rs Sl Sr 
-	kSpeakerArr70Cine,			///< L R C Ls  Rs Lc Rc 
-	kSpeakerArr70Music,			///< L R C Ls  Rs Sl Sr
-	kSpeakerArr71Cine,			///< L R C Lfe Ls Rs Lc Rc
-	kSpeakerArr71Music,			///< L R C Lfe Ls Rs Sl Sr
-	kSpeakerArr80Cine,			///< L R C Ls  Rs Lc Rc Cs
-	kSpeakerArr80Music,			///< L R C Ls  Rs Cs Sl Sr
-	kSpeakerArr81Cine,			///< L R C Lfe Ls Rs Lc Rc Cs
-	kSpeakerArr81Music,			///< L R C Lfe Ls Rs Cs Sl Sr 
-	kSpeakerArr102,				///< L R C Lfe Ls Rs Tfl Tfc Tfr Trl Trr Lfe2
-	kNumSpeakerArr
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-// Offline Processing
-//-------------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------------
-/** Offline Task Description. */
-//-------------------------------------------------------------------------------------------------------
-struct VstOfflineTask
-{
-//-------------------------------------------------------------------------------------------------------
-	char processName[96];			///< set by plug-in
-
-	// audio access
-	double readPosition;			///< set by plug-in/Host
-	double writePosition;			///< set by plug-in/Host
-	VstInt32 readCount;				///< set by plug-in/Host
-	VstInt32 writeCount;			///< set by plug-in
-	VstInt32 sizeInputBuffer;		///< set by Host
-	VstInt32 sizeOutputBuffer;		///< set by Host
-	void* inputBuffer;				///< set by Host
-	void* outputBuffer;				///< set by Host
-	double positionToProcessFrom;	///< set by Host
-	double numFramesToProcess;		///< set by Host
-	double maxFramesToWrite;		///< set by plug-in
-
-	// other data access
-	void* extraBuffer;				///< set by plug-in
-	VstInt32 value;					///< set by Host or plug-in
-	VstInt32 index;					///< set by Host or plug-in
-
-	// file attributes
-	double numFramesInSourceFile;	///< set by Host
-	double sourceSampleRate;		///< set by Host or plug-in
-	double destinationSampleRate;	///< set by Host or plug-in
-	VstInt32 numSourceChannels;		///< set by Host or plug-in
-	VstInt32 numDestinationChannels;///< set by Host or plug-in
-	VstInt32 sourceFormat;			///< set by Host
-	VstInt32 destinationFormat;		///< set by plug-in
-	char outputText[512];			///< set by plug-in or Host
-
-	// progress notification
-	double progress;				///< set by plug-in
-	VstInt32 progressMode;			///< Reserved for future use
-	char progressText[100];			///< set by plug-in
-
-	VstInt32 flags;					///< set by Host and plug-in; see enum #VstOfflineTaskFlags
-	VstInt32 returnValue;			///< Reserved for future use
-	void* hostOwned;				///< set by Host
-	void* plugOwned;				///< set by plug-in
-
-	char future[1024];				///< Reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in #VstOfflineTask. */
-//-------------------------------------------------------------------------------------------------------
-enum VstOfflineTaskFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstOfflineUnvalidParameter	= 1 << 0,	///< set by Host
-	kVstOfflineNewFile			= 1 << 1,	///< set by Host
-
-	kVstOfflinePlugError		= 1 << 10,	///< set by plug-in
-	kVstOfflineInterleavedAudio	= 1 << 11,	///< set by plug-in
-	kVstOfflineTempOutputFile	= 1 << 12,	///< set by plug-in
-	kVstOfflineFloatOutputFile	= 1 << 13,	///< set by plug-in
-	kVstOfflineRandomWrite		= 1 << 14,	///< set by plug-in
-	kVstOfflineStretch			= 1 << 15,	///< set by plug-in
-	kVstOfflineNoThread			= 1 << 16	///< set by plug-in
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Option passed to #offlineRead/#offlineWrite. */
-//-------------------------------------------------------------------------------------------------------
-enum VstOfflineOption
-{
-//-------------------------------------------------------------------------------------------------------
-   kVstOfflineAudio,		///< reading/writing audio samples
-   kVstOfflinePeaks,		///< reading graphic representation
-   kVstOfflineParameter,	///< reading/writing parameters
-   kVstOfflineMarker,		///< reading/writing marker
-   kVstOfflineCursor,		///< reading/moving edit cursor
-   kVstOfflineSelection,	///< reading/changing selection
-   kVstOfflineQueryFiles	///< to request the Host to call asynchronously #offlineNotify
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Structure passed to #offlineNotify and #offlineStart */
-//-------------------------------------------------------------------------------------------------------
-struct VstAudioFile
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 flags;					///< see enum #VstAudioFileFlags
-	void* hostOwned;				///< any data private to Host
-	void* plugOwned;				///< any data private to plug-in
-	char name[kVstMaxFileNameLen];	///< file title
-	VstInt32 uniqueId;				///< uniquely identify a file during a session
-	double sampleRate;				///< file sample rate
-	VstInt32 numChannels;			///< number of channels (1 for mono, 2 for stereo...)
-	double numFrames;				///< number of frames in the audio file
-	VstInt32 format;				///< Reserved for future use
-	double editCursorPosition;		///< -1 if no such cursor
-	double selectionStart;			///< frame index of first selected frame, or -1
-	double selectionSize;			///< number of frames in selection, or 0
-	VstInt32 selectedChannelsMask;	///< 1 bit per channel
-	VstInt32 numMarkers;			///< number of markers in the file
-	VstInt32 timeRulerUnit;			///< see doc for possible values
-	double timeRulerOffset;			///< offset in time ruler (positive or negative)
-	double tempo;					///< as BPM (Beats Per Minute)
-	VstInt32 timeSigNumerator;		///< time signature numerator
-	VstInt32 timeSigDenominator;	///< time signature denominator
-	VstInt32 ticksPerBlackNote;		///< resolution
-	VstInt32 smpteFrameRate;		///< SMPTE rate (set as in #VstTimeInfo)
-
-	char future[64];				///< Reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Flags used in #VstAudioFile. */
-//-------------------------------------------------------------------------------------------------------
-enum VstAudioFileFlags
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstOfflineReadOnly				= 1 << 0,	///< set by Host (in call #offlineNotify)
-	kVstOfflineNoRateConversion		= 1 << 1,	///< set by Host (in call #offlineNotify)
-	kVstOfflineNoChannelChange		= 1 << 2,	///< set by Host (in call #offlineNotify)
-
-	kVstOfflineCanProcessSelection	= 1 << 10,	///< set by plug-in (in call #offlineStart)
-	kVstOfflineNoCrossfade			= 1 << 11,	///< set by plug-in (in call #offlineStart)
-	kVstOfflineWantRead				= 1 << 12,	///< set by plug-in (in call #offlineStart)
-	kVstOfflineWantWrite			= 1 << 13,	///< set by plug-in (in call #offlineStart)
-	kVstOfflineWantWriteMarker		= 1 << 14,	///< set by plug-in (in call #offlineStart)
-	kVstOfflineWantMoveCursor		= 1 << 15,	///< set by plug-in (in call #offlineStart)
-	kVstOfflineWantSelect			= 1 << 16	///< set by plug-in (in call #offlineStart)
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Audio file marker. */
-//-------------------------------------------------------------------------------------------------------
-struct VstAudioFileMarker
-{
-//-------------------------------------------------------------------------------------------------------
-	double position;		///< marker position
-	char name[32];			///< marker name
-	VstInt32 type;			///< marker type
-	VstInt32 id;			///< marker identifier
-	VstInt32 reserved;		///< reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-// Others
-//-------------------------------------------------------------------------------------------------------
-
-//-------------------------------------------------------------------------------------------------------
-/** \deprecated Structure used for #openWindow and #closeWindow (deprecated in VST 2.4). */
-//-------------------------------------------------------------------------------------------------------
-struct DECLARE_VST_DEPRECATED (VstWindow)
-{
-//-------------------------------------------------------------------------------------------------------
-	char title[128];
-	VstInt16 xPos;
-	VstInt16 yPos;
-	VstInt16 width;
-	VstInt16 height;
-	VstInt32 style;
-	void* parent;
-	void* userHandle;
-	void* winHandle;
-
-	char future[104];
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Structure used for keyUp/keyDown. */
-//-------------------------------------------------------------------------------------------------------
-struct VstKeyCode
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 character;		///< ASCII character
-	unsigned char virt;     ///< @see VstVirtualKey
-	unsigned char modifier; ///< @see VstModifierKey
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Platform-independent definition of Virtual Keys (used in #VstKeyCode). */
-//-------------------------------------------------------------------------------------------------------
-enum VstVirtualKey 
-{
-//-------------------------------------------------------------------------------------------------------
-	VKEY_BACK = 1, 
-	VKEY_TAB, 
-	VKEY_CLEAR, 
-	VKEY_RETURN, 
-	VKEY_PAUSE, 
-	VKEY_ESCAPE, 
-	VKEY_SPACE, 
-	VKEY_NEXT, 
-	VKEY_END, 
-	VKEY_HOME, 
-	VKEY_LEFT, 
-	VKEY_UP, 
-	VKEY_RIGHT, 
-	VKEY_DOWN, 
-	VKEY_PAGEUP, 
-	VKEY_PAGEDOWN, 
-	VKEY_SELECT, 
-	VKEY_PRINT, 
-	VKEY_ENTER, 
-	VKEY_SNAPSHOT, 
-	VKEY_INSERT, 
-	VKEY_DELETE, 
-	VKEY_HELP, 
-	VKEY_NUMPAD0, 
-	VKEY_NUMPAD1, 
-	VKEY_NUMPAD2, 
-	VKEY_NUMPAD3, 
-	VKEY_NUMPAD4, 
-	VKEY_NUMPAD5, 
-	VKEY_NUMPAD6, 
-	VKEY_NUMPAD7, 
-	VKEY_NUMPAD8, 
-	VKEY_NUMPAD9, 
-	VKEY_MULTIPLY, 
-	VKEY_ADD, 
-	VKEY_SEPARATOR, 
-	VKEY_SUBTRACT, 
-	VKEY_DECIMAL, 
-	VKEY_DIVIDE, 
-	VKEY_F1, 
-	VKEY_F2, 
-	VKEY_F3, 
-	VKEY_F4, 
-	VKEY_F5, 
-	VKEY_F6, 
-	VKEY_F7, 
-	VKEY_F8, 
-	VKEY_F9, 
-	VKEY_F10, 
-	VKEY_F11, 
-	VKEY_F12, 
-	VKEY_NUMLOCK, 
-	VKEY_SCROLL,
-	VKEY_SHIFT,
-	VKEY_CONTROL,
-	VKEY_ALT,
-	VKEY_EQUALS
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Modifier flags used in #VstKeyCode. */
-//-------------------------------------------------------------------------------------------------------
-enum VstModifierKey
-{
-//-------------------------------------------------------------------------------------------------------
-	MODIFIER_SHIFT     = 1<<0, ///< Shift
-	MODIFIER_ALTERNATE = 1<<1, ///< Alt
-	MODIFIER_COMMAND   = 1<<2, ///< Control on Mac
-	MODIFIER_CONTROL   = 1<<3  ///< Ctrl on PC, Apple on Mac
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** File filter used in #VstFileSelect. */
-//-------------------------------------------------------------------------------------------------------
-struct VstFileType
-{
-//-------------------------------------------------------------------------------------------------------
-	char name[128];				///< display name
-	char macType[8];			///< MacOS type
-	char dosType[8];			///< Windows file extension
-	char unixType[8];			///< Unix file extension
-	char mimeType1[128];		///< MIME type
-	char mimeType2[128];		///< additional MIME type
-
-	VstFileType (const char* _name = 0, const char* _macType = 0, const char* _dosType = 0,
-				 const char* _unixType = 0, const char* _mimeType1 = 0, const char* _mimeType2 = 0)
-	{
-		vst_strncpy (name, _name ? _name : "", 127);
-		vst_strncpy (macType, _macType ? _macType : "", 7);
-		vst_strncpy (dosType, _dosType ? _dosType : "", 7);
-		vst_strncpy (unixType, _unixType ? _unixType : "", 7);
-		vst_strncpy (mimeType1, _mimeType1 ? _mimeType1 : "", 127);
-		vst_strncpy (mimeType2, _mimeType2 ? _mimeType2 : "", 127);
-	}
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** File Selector Description used in #audioMasterOpenFileSelector. */
-//-------------------------------------------------------------------------------------------------------
-struct VstFileSelect
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 command;           ///< @see VstFileSelectCommand
-	VstInt32 type;              ///< @see VstFileSelectType
-	VstInt32 macCreator;        ///< optional: 0 = no creator
-	VstInt32 nbFileTypes;       ///< number of fileTypes
-	VstFileType* fileTypes;		///< list of fileTypes  @see VstFileType
-	char title[1024];			///< text to display in file selector's title
-	char* initialPath;			///< initial path
-	char* returnPath;			///< use with #kVstFileLoad and #kVstDirectorySelect. null: Host allocates memory, plug-in must call #closeOpenFileSelector!
-	VstInt32 sizeReturnPath;	///< size of allocated memory for return paths
-	char** returnMultiplePaths; ///< use with kVstMultipleFilesLoad. Host allocates memory, plug-in must call #closeOpenFileSelector!
-	VstInt32 nbReturnPath;		///< number of selected paths
-	VstIntPtr reserved;			///< reserved for Host application
-
-	char future[116];			///< reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Command constants used in #VstFileSelect structure. */
-//-------------------------------------------------------------------------------------------------------
-enum VstFileSelectCommand
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstFileLoad = 0,		///< for loading a file
-	kVstFileSave,			///< for saving a file
-	kVstMultipleFilesLoad,	///< for loading multiple files
-	kVstDirectorySelect		///< for selecting a directory/folder
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Types used in #VstFileSelect structure. */
-//-------------------------------------------------------------------------------------------------------
-enum VstFileSelectType
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstFileType = 0		///< regular file selector
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Structure used for #effBeginLoadBank/#effBeginLoadProgram. */
-//-------------------------------------------------------------------------------------------------------
-struct VstPatchChunkInfo
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 version;			///< Format Version (should be 1)
-	VstInt32 pluginUniqueID;	///< UniqueID of the plug-in
-	VstInt32 pluginVersion;		///< Plug-in Version
-	VstInt32 numElements;		///< Number of Programs (Bank) or Parameters (Program)
-
-	char future[48];			///< Reserved for future use
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** PanLaw Type. */
-//-------------------------------------------------------------------------------------------------------
-enum VstPanLawType
-{
-//-------------------------------------------------------------------------------------------------------
-	kLinearPanLaw = 0,	///< L = pan * M; R = (1 - pan) * M;
-	kEqualPowerPanLaw	///< L = pow (pan, 0.5) * M; R = pow ((1 - pan), 0.5) * M;
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Process Levels returned by #audioMasterGetCurrentProcessLevel. */
-//-------------------------------------------------------------------------------------------------------
-enum VstProcessLevels
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstProcessLevelUnknown = 0,	///< not supported by Host
-	kVstProcessLevelUser,			///< 1: currently in user thread (GUI)
-	kVstProcessLevelRealtime,		///< 2: currently in audio thread (where process is called)
-	kVstProcessLevelPrefetch,		///< 3: currently in 'sequencer' thread (MIDI, timer etc)
-	kVstProcessLevelOffline			///< 4: currently offline processing and thus in user thread
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Automation States returned by #audioMasterGetAutomationState. */
-//-------------------------------------------------------------------------------------------------------
-enum VstAutomationStates
-{
-//-------------------------------------------------------------------------------------------------------
-	kVstAutomationUnsupported = 0,	///< not supported by Host
-	kVstAutomationOff,				///< off
-	kVstAutomationRead,				///< read
-	kVstAutomationWrite,			///< write
-	kVstAutomationReadWrite			///< read and write
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-#if TARGET_API_MAC_CARBON
-	#pragma options align=reset
-#elif defined(WIN32) || defined(__FLAT__) || defined(__GNUC__)
-	#pragma pack(pop)
-#elif defined __BORLANDC__
-	#pragma -a-
-#endif
-//-------------------------------------------------------------------------------------------------------
-
-#endif //__aeffectx__
diff --git a/src/deps/vst/vstfxstore.h b/src/deps/vst/vstfxstore.h
deleted file mode 100644
index d7d60f4..0000000
--- a/src/deps/vst/vstfxstore.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//-------------------------------------------------------------------------------------------------------
-// VST Plug-Ins SDK
-// Version 2.4		$Date: 2006/02/09 11:05:51 $
-//
-// Category     : VST 2.x Interfaces
-// Filename     : vstfxstore.h
-// Created by   : Steinberg Media Technologies
-// Description  : Definition of Program (fxp) and Bank (fxb) structures
-//
-// © 2006, Steinberg Media Technologies, All Rights Reserved
-//-------------------------------------------------------------------------------------------------------
-
-#ifndef __vstfxstore__
-#define __vstfxstore__
-
-#ifndef __aeffect__
-#include "aeffect.h"
-#endif
-
-//-------------------------------------------------------------------------------------------------------
-/** Root chunk identifier for Programs (fxp) and Banks (fxb). */
-#define cMagic				'CcnK'
-
-/** Regular Program (fxp) identifier. */
-#define fMagic				'FxCk'
-
-/** Regular Bank (fxb) identifier. */
-#define bankMagic			'FxBk'
-
-/** Program (fxp) identifier for opaque chunk data. */
-#define chunkPresetMagic	'FPCh'
-
-/** Bank (fxb) identifier for opaque chunk data. */
-#define chunkBankMagic		'FBCh'
-
-/* 
-	Note: The C data structures below are for illustration only. You can not read/write them directly.
-	The byte order on disk of fxp and fxb files is Big Endian. You have to swap integer
-	and floating-point values on Little Endian platforms (Windows, MacIntel)!
-*/
-
-//-------------------------------------------------------------------------------------------------------
-/** Program (fxp) structure. */
-//-------------------------------------------------------------------------------------------------------
-struct fxProgram
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 chunkMagic;		///< 'CcnK'
-	VstInt32 byteSize;			///< size of this chunk, excl. magic + byteSize
-
-	VstInt32 fxMagic;			///< 'FxCk' (regular) or 'FPCh' (opaque chunk)
-	VstInt32 version;			///< format version (currently 1)
-	VstInt32 fxID;				///< fx unique ID
-	VstInt32 fxVersion;			///< fx version
-
-	VstInt32 numParams;			///< number of parameters
-	char prgName[28];			///< program name (null-terminated ASCII string)
-
-	union
-	{
-		float params[1];		///< variable sized array with parameter values
-		struct 
-		{
-			VstInt32 size;		///< size of program data
-			char chunk[1];		///< variable sized array with opaque program data
-		} data;					///< program chunk data
-	} content;					///< program content depending on fxMagic
-//-------------------------------------------------------------------------------------------------------
-};
-
-//-------------------------------------------------------------------------------------------------------
-/** Bank (fxb) structure. */
-//-------------------------------------------------------------------------------------------------------
-struct fxBank
-{
-//-------------------------------------------------------------------------------------------------------
-	VstInt32 chunkMagic;		///< 'CcnK'
-	VstInt32 byteSize;			///< size of this chunk, excl. magic + byteSize
-
-	VstInt32 fxMagic;			///< 'FxBk' (regular) or 'FBCh' (opaque chunk)
-	VstInt32 version;			///< format version (1 or 2)
-	VstInt32 fxID;				///< fx unique ID
-	VstInt32 fxVersion;			///< fx version
-
-	VstInt32 numPrograms;		///< number of programs
-
-#if VST_2_4_EXTENSIONS
-	VstInt32 currentProgram;	///< version 2: current program number
-	char future[124];			///< reserved, should be zero
-#else
-	char future[128];			///< reserved, should be zero
-#endif
-
-	union
-	{
-		fxProgram programs[1];	///< variable number of programs
-		struct
-		{
-			VstInt32 size;		///< size of bank data
-			char chunk[1];		///< variable sized array with opaque bank data
-		} data;					///< bank chunk data
-	} content;					///< bank content depending on fxMagic
-//-------------------------------------------------------------------------------------------------------
-};
-
-#endif // __vstfxstore__
diff --git a/src/glue/channel.cpp b/src/glue/channel.cpp
new file mode 100644
index 0000000..a86dddb
--- /dev/null
+++ b/src/glue/channel.cpp
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * glue
+ * Intermediate layer GUI <-> CORE.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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 3 of the License, or (at your option) any later version.
+ *
+ * Giada - Your Hardcore Loopmachine is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/elems/ge_keyboard.h"
+#include "../gui/elems/ge_channel.h"
+#include "../utils/gui_utils.h"
+#include "../core/mixerHandler.h"
+#include "../core/mixer.h"
+#include "../core/conf.h"
+#include "../core/channel.h"
+#include "../core/sampleChannel.h"
+#include "../core/midiChannel.h"
+#include "glue.h"
+#include "channel.h"
+
+
+extern gdMainWindow *mainWin;
+extern Conf          G_Conf;
+extern Mixer	   		 G_Mixer;
+
+
+using std::string;
+
+
+int glue_loadChannel(SampleChannel *ch, const char *fname)
+{
+	/* save the patch and take the last browser's dir in order to re-use it
+	 * the next time */
+
+	G_Conf.samplePath = gDirname(fname);
+
+	int result = ch->load(fname);
+
+	if (result == SAMPLE_LOADED_OK)
+		mainWin->keyboard->updateChannel(ch->guiChannel);
+
+	return result;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+Channel *glue_addChannel(int column, int type)
+{
+	Channel *ch    = G_Mixer.addChannel(type);
+	gChannel *gch  = mainWin->keyboard->addChannel(column, ch);
+	ch->guiChannel = gch;
+	glue_setChanVol(ch, 1.0, false); // false = not from gui click
+	return ch;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void glue_deleteChannel(Channel *ch)
+{
+	int index = ch->index;
+	recorder::clearChan(index);
+	Fl::lock();
+	mainWin->keyboard->deleteChannel(ch->guiChannel);
+	Fl::unlock();
+	G_Mixer.deleteChannel(ch);
+	gu_closeAllSubwindows();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void glue_freeChannel(Channel *ch)
+{
+	mainWin->keyboard->freeChannel(ch->guiChannel);
+	recorder::clearChan(ch->index);
+	ch->empty();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int glue_cloneChannel(Channel *src)
+{
+	Channel *ch    = G_Mixer.addChannel(src->type);
+	gChannel *gch  = mainWin->keyboard->addChannel(src->guiChannel->getColumnIndex(), ch);
+
+	ch->guiChannel = gch;
+	ch->copy(src);
+
+	mainWin->keyboard->updateChannel(ch->guiChannel);
+	return true;
+}
diff --git a/src/gui/elems/ge_channelButton.h b/src/glue/channel.h
similarity index 59%
copy from src/gui/elems/ge_channelButton.h
copy to src/glue/channel.h
index 86f6736..2da2bf1 100644
--- a/src/gui/elems/ge_channelButton.h
+++ b/src/glue/channel.h
@@ -2,11 +2,12 @@
  *
  * Giada - Your Hardcore Loopmachine
  *
- * ge_channelButton
+ * glue
+ * Intermediate layer GUI <-> CORE.
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -27,37 +28,40 @@
  * -------------------------------------------------------------------------- */
 
 
-#ifndef GE_CHANNEL_BUTTON_H
-#define GE_CHANNEL_BUTTON_H
+#ifndef GLUE_CHANNEL_H
+#define GLUE_CHANNEL_H
 
 
-#include "ge_mixed.h"
+#include "../core/patch.h"
 
 
 using std::string;
 
 
-class gChannelButton : public gClick
-{
-private:
+/* addChannel
+ * add an empty new channel to the stack. Returns the new channel. */
 
-	string key;
+class Channel *glue_addChannel(int column, int type);
 
-public:
+/* loadChannel
+ * fill an existing channel with a wave. */
 
-	gChannelButton(int x, int y, int w, int h, const char *l=0);
+int glue_loadChannel(class SampleChannel *ch, const char *fname);
 
-	virtual int handle(int e) = 0;
+/* deleteChannel
+ * Remove a channel from Mixer. */
 
-	void draw();
-	void setKey(const string &k);
-	void setKey(int k);
-	void setPlayMode();
-	void setEndingMode();
-	void setDefaultMode(const char *l=0);
-	void setInputRecordMode();
-	void setActionRecordMode();
-};
+void glue_deleteChannel(class Channel *ch);
+
+/* freeChannel
+ * Unload the sample from a sample channel. */
+
+void glue_freeChannel(class Channel *ch);
+
+/* cloneChannel
+ * Make an exact copy of Channel *ch. */
+ 
+int glue_cloneChannel(class Channel *ch);
 
 
 #endif
diff --git a/src/glue/glue.cpp b/src/glue/glue.cpp
index d7db772..f2879f2 100644
--- a/src/glue/glue.cpp
+++ b/src/glue/glue.cpp
@@ -11,7 +11,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -71,67 +71,6 @@ extern PluginHost		 G_PluginHost;
 static bool __soloSession__ = false;
 
 
-/* -------------------------------------------------------------------------- */
-
-
-int glue_loadChannel(SampleChannel *ch, const char *fname)
-{
-	/* save the patch and take the last browser's dir in order to re-use it
-	 * the next time */
-
-	G_Conf.setPath(G_Conf.samplePath, gDirname(fname).c_str());
-
-	int result = ch->load(fname);
-
-	if (result == SAMPLE_LOADED_OK)
-		mainWin->keyboard->updateChannel(ch->guiChannel);
-
-	return result;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-Channel *glue_addChannel(int column, int type)
-{
-	Channel *ch    = G_Mixer.addChannel(type);
-	gChannel *gch  = mainWin->keyboard->addChannel(column, ch);
-	ch->guiChannel = gch;
-	glue_setChanVol(ch, 1.0, false); // false = not from gui click
-	return ch;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void glue_deleteChannel(Channel *ch)
-{
-	int index = ch->index;
-	recorder::clearChan(index);
-	Fl::lock();
-	mainWin->keyboard->deleteChannel(ch->guiChannel);
-	Fl::unlock();
-	G_Mixer.deleteChannel(ch);
-	gu_closeAllSubwindows();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void glue_freeChannel(Channel *ch)
-{
-	mainWin->keyboard->freeChannel(ch->guiChannel);
-	recorder::clearChan(ch->index);
-	ch->empty();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
 void glue_setBpm(const char *v1, const char *v2)
 {
 	char  buf[6];
@@ -328,7 +267,7 @@ void glue_stopActionRec() {
 	recorder::active = false;
 	recorder::sortActions();
 
-	for (unsigned i=0; i<G_Mixer.channels.size; i++)
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++)
 		if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE) {
 			SampleChannel *ch = (SampleChannel*) G_Mixer.channels.at(i);
 			if (ch->hasActions)
@@ -468,7 +407,7 @@ void glue_setInVol(float v, bool gui)
 void glue_clearAllSamples()
 {
 	G_Mixer.running = false;
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		G_Mixer.channels.at(i)->empty();
 		G_Mixer.channels.at(i)->guiChannel->reset();
 	}
@@ -680,7 +619,7 @@ void glue_setSoloOn(Channel *ch, bool gui)
 	 * and start the session */
 
 	if (!__soloSession__) {
-		for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+		for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 			Channel *och = G_Mixer.channels.at(i);
 			och->mute_s  = och->mute;
 		}
@@ -692,7 +631,7 @@ void glue_setSoloOn(Channel *ch, bool gui)
 
 	/* mute all other channels and unmute this (if muted) */
 
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		Channel *och = G_Mixer.channels.at(i);
 		if (!och->solo && !och->mute) {
 			och->setMute(false);
@@ -727,7 +666,7 @@ void glue_setSoloOff(Channel *ch, bool gui)
 
 	if (mh_uniqueSolo(ch)) {
 		__soloSession__ = false;
-		for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+		for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 			Channel *och = G_Mixer.channels.at(i);
 			if (och->mute_s) {
 				och->setMute(false);
diff --git a/src/glue/glue.h b/src/glue/glue.h
index 8f085de..ef7076f 100644
--- a/src/glue/glue.h
+++ b/src/glue/glue.h
@@ -11,7 +11,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -35,19 +35,6 @@
 #ifndef GLUE_H
 #define GLUE_H
 
-/* addChannel
- * add an empty new channel to the stack. Returns the new channel. */
-
-class Channel *glue_addChannel(int column, int type);
-
-/* loadChannel
- * fill an existing channel with a wave. */
-
-int glue_loadChannel(class SampleChannel *ch, const char *fname);
-
-void glue_deleteChannel(class Channel *ch);
-
-void glue_freeChannel(class Channel *ch);
 
 /* keyPress / keyRelease
  * handle the key pressure, either via mouse/keyboard or MIDI. If gui
diff --git a/src/glue/storage.cpp b/src/glue/storage.cpp
index 5837227..fdf5e23 100644
--- a/src/glue/storage.cpp
+++ b/src/glue/storage.cpp
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -44,6 +44,7 @@
 #include "../core/wave.h"
 #include "../utils/gui_utils.h"
 #include "glue.h" // TODO - remove, used only for DEPR calls
+#include "channel.h"
 #include "storage.h"
 
 
@@ -60,6 +61,102 @@ extern PluginHost		 G_PluginHost;
 #endif
 
 
+static void __glue_setProgressBar__(class gProgress *status, float v)
+{
+	status->value(status->value() + v);
+	//Fl::check();
+	Fl::wait(0);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+#ifdef WITH_VST
+
+static void __glue_fillPatchGlobalsPlugins__(vector <Plugin *> *host, vector<Patch::plugin_t> *patch)
+{
+	for (unsigned i=0; i<host->size(); i++) {
+		Plugin *pl = host->at(i);
+		Patch::plugin_t ppl;
+		ppl.path = pl->pathfile;
+		ppl.bypass = pl->bypass;
+		int numParams = pl->getNumParams();
+		for (int k=0; k<numParams; k++)
+			ppl.params.push_back(pl->getParam(k));
+		patch->push_back(ppl);
+	}
+}
+
+#endif
+
+
+/* -------------------------------------------------------------------------- */
+
+
+static void __glue_fillPatchColumns__()
+{
+	for (unsigned i=0; i<mainWin->keyboard->getTotalColumns(); i++) {
+		gColumn *gCol = mainWin->keyboard->getColumn(i);
+		Patch::column_t pCol;
+		pCol.index = gCol->getIndex();
+		pCol.width = gCol->w();
+		for (int k=0; k<gCol->countChannels(); k++) {
+			Channel *colChannel = gCol->getChannel(k);
+			for (unsigned j=0; j<G_Mixer.channels.size(); j++) {
+				Channel *mixerChannel = G_Mixer.channels.at(j);
+				if (colChannel == mixerChannel) {
+					pCol.channels.push_back(mixerChannel->index);
+					break;
+				}
+			}
+		}
+		G_Patch.columns.push_back(pCol);
+	}
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+static void __glue_fillPatchChannels__(bool isProject)
+{
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
+		G_Mixer.channels.at(i)->writePatch(i, isProject);
+	}
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+static void __glue_fillPatchGlobals__(const string &name)
+{
+	G_Patch.version      = G_VERSION_STR;
+	G_Patch.versionMajor = G_VERSION_MAJOR;
+	G_Patch.versionMinor = G_VERSION_MINOR;
+	G_Patch.versionPatch = G_VERSION_PATCH;
+	G_Patch.name         = name;
+	G_Patch.bpm          = G_Mixer.bpm;
+	G_Patch.bars         = G_Mixer.bars;
+	G_Patch.beats        = G_Mixer.beats;
+	G_Patch.quantize     = G_Mixer.quantize;
+	G_Patch.masterVolIn  = G_Mixer.inVol;
+  G_Patch.masterVolOut = G_Mixer.outVol;
+  G_Patch.metronome    = G_Mixer.metronome;
+
+#ifdef WITH_VST
+
+	__glue_fillPatchGlobalsPlugins__(&G_PluginHost.masterIn, &G_Patch.masterInPlugins);
+	__glue_fillPatchGlobalsPlugins__(&G_PluginHost.masterOut, &G_Patch.masterOutPlugins);
+
+#endif
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
 int glue_savePatch(const string &fullPath, const string &name, bool isProject)
 {
 	G_Patch.init();
@@ -113,21 +210,21 @@ int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProje
 
 	glue_resetToInitState(false, false);
 
-	__setProgressBar__(status, 0.1f);
+	__glue_setProgressBar__(status, 0.1f);
 
 	/* Add common stuff, columns and channels. Also increment the progress bar
 	 * by 0.8 / total_channels steps.  */
 
-	float steps = 0.8 / G_Patch.channels.size;
-	for (unsigned i=0; i<G_Patch.columns.size; i++) {
+	float steps = 0.8 / G_Patch.channels.size();
+	for (unsigned i=0; i<G_Patch.columns.size(); i++) {
 		Patch::column_t *col = &G_Patch.columns.at(i);
 		mainWin->keyboard->addColumn(col->width);
-		for (unsigned k=0; k<G_Patch.channels.size; k++) {
+		for (unsigned k=0; k<G_Patch.channels.size(); k++) {
 			if (G_Patch.channels.at(k).column == col->index) {
 				Channel *ch = glue_addChannel(G_Patch.channels.at(k).column, G_Patch.channels.at(k).type);
 				ch->readPatch(basePath, k);
 			}
-			__setProgressBar__(status, steps);
+			__glue_setProgressBar__(status, steps);
 		}
 	}
 
@@ -143,14 +240,14 @@ int glue_loadPatch(const string &fullPath, class gProgress *status, bool isProje
 	/* save patchPath by taking the last dir of the broswer, in order to
 	 * reuse it the next time */
 
-	G_Conf.setPath(G_Conf.patchPath, gDirname(fullPath.c_str()).c_str());
+	G_Conf.patchPath = gDirname(fullPath.c_str());
 
 	/* refresh GUI */
 
 	gu_updateControls();
 	gu_update_win_label(G_Patch.name.c_str());
 
-	__setProgressBar__(status, 1.0f);
+	__glue_setProgressBar__(status, 1.0f);
 
 	gLog("[glue] patch loaded successfully\n");
 
@@ -232,7 +329,7 @@ int glue_loadPatch__DEPR__(const char *fname, const char *fpath, gProgress *stat
 	/* save patchPath by taking the last dir of the broswer, in order to
 	 * reuse it the next time */
 
-	G_Conf.setPath(G_Conf.patchPath, gDirname(fpath).c_str());
+	G_Conf.patchPath = gDirname(fpath).c_str();
 
 	gLog("[glue] patch %s loaded\n", fname);
 
@@ -241,103 +338,9 @@ int glue_loadPatch__DEPR__(const char *fname, const char *fpath, gProgress *stat
 		gdAlert("Some VST plugins were not loaded successfully.");
 #endif
 
-	return res;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void __glue_fillPatchGlobals__(const string &name)
-{
-	G_Patch.version      = G_VERSION_STR;
-	G_Patch.versionMajor = G_VERSION_MAJOR;
-	G_Patch.versionMinor = G_VERSION_MINOR;
-	G_Patch.versionPatch = G_VERSION_PATCH;
-	G_Patch.name         = name;
-	G_Patch.bpm          = G_Mixer.bpm;
-	G_Patch.bars         = G_Mixer.bars;
-	G_Patch.beats        = G_Mixer.beats;
-	G_Patch.quantize     = G_Mixer.quantize;
-	G_Patch.masterVolIn  = G_Mixer.inVol;
-  G_Patch.masterVolOut = G_Mixer.outVol;
-  G_Patch.metronome    = G_Mixer.metronome;
-
-#ifdef WITH_VST
-
-	__glue_fillPatchGlobalsPlugins__(&G_PluginHost.masterIn, &G_Patch.masterInPlugins);
-	__glue_fillPatchGlobalsPlugins__(&G_PluginHost.masterOut, &G_Patch.masterOutPlugins);
-
-#endif
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-#ifdef WITH_VST
-
-void __glue_fillPatchGlobalsPlugins__(gVector <Plugin *> *host, gVector<Patch::plugin_t> *patch)
-{
-	for (unsigned i=0; i<host->size; i++) {
-		Plugin *pl = host->at(i);
-		Patch::plugin_t ppl;
-		ppl.path = pl->pathfile;
-		ppl.bypass = pl->bypass;
-		int numParams = pl->getNumParams();
-		for (unsigned k=0; k<numParams; k++)
-			ppl.params.add(pl->getParam(k));
-		patch->add(ppl);
-	}
-}
-
-#endif
-
-
-/* -------------------------------------------------------------------------- */
+	gdAlert("This patch is using a deprecated format.\nPlease save it again to store it properly.");
 
-
-void __glue_fillPatchChannels__(bool isProject)
-{
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
-		G_Mixer.channels.at(i)->writePatch(i, isProject);
-	}
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void __glue_fillPatchColumns__()
-{
-	for (unsigned i=0; i<mainWin->keyboard->getTotalColumns(); i++) {
-		gColumn *gCol = mainWin->keyboard->getColumn(i);
-		Patch::column_t pCol;
-		pCol.index = gCol->getIndex();
-		pCol.width = gCol->w();
-		for (unsigned k=0; k<gCol->countChannels(); k++) {
-			Channel *colChannel = gCol->getChannel(k);
-			for (unsigned j=0; j<G_Mixer.channels.size; j++) {
-				Channel *mixerChannel = G_Mixer.channels.at(j);
-				if (colChannel == mixerChannel) {
-					pCol.channels.add(mixerChannel->index);
-					break;
-				}
-			}
-		}
-		G_Patch.columns.add(pCol);
-	}
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void __setProgressBar__(class gProgress *status, float v)
-{
-	status->value(status->value() + v);
-	//Fl::check();
-	Fl::wait(0);
+	return res;
 }
 
 
@@ -354,7 +357,7 @@ int glue_saveProject(const string &folderPath, const string &projName)
 	/* copy all samples inside the folder. Takes and logical ones are saved
 	 * via glue_saveSample() */
 
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 
 		if (G_Mixer.channels.at(i)->type == CHANNEL_MIDI)
 			continue;
diff --git a/src/glue/storage.h b/src/glue/storage.h
index 23aee4e..f7d05c1 100644
--- a/src/glue/storage.h
+++ b/src/glue/storage.h
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,10 +32,12 @@
 #define GLUE_STORAGE_H
 
 
+#include <vector>
 #include "../core/patch.h"
 
 
 using std::string;
+using std::vector;
 
 
 int glue_loadPatch  (const string &fullPath, class gProgress *status, bool isProject);
@@ -43,14 +45,4 @@ int glue_loadPatch__DEPR__(const char *fname, const char *fpath, class gProgress
 int glue_savePatch  (const string &fullPath, const string &name, bool isProject);
 int glue_saveProject(const string &folderPath, const string &projName);
 
-static void __glue_fillPatchGlobals__(const string &name);
-static void __glue_fillPatchChannels__(bool isProject);
-static void __glue_fillPatchColumns__();
-
-#ifdef WITH_VST
-static void __glue_fillPatchGlobalsPlugins__(gVector <Plugin *> *host, gVector<Patch::plugin_t> *patch);
-#endif
-
-static void __setProgressBar__(class gProgress *status, float v);
-
 #endif
diff --git a/src/gui/dialogs/gd_about.cpp b/src/gui/dialogs/gd_about.cpp
index 2194bd3..adff5af 100644
--- a/src/gui/dialogs/gd_about.cpp
+++ b/src/gui/dialogs/gd_about.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_about.h b/src/gui/dialogs/gd_about.h
index 91f5065..2416740 100644
--- a/src/gui/dialogs/gd_about.h
+++ b/src/gui/dialogs/gd_about.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_actionEditor.cpp b/src/gui/dialogs/gd_actionEditor.cpp
index 5d5edc2..544e83f 100644
--- a/src/gui/dialogs/gd_actionEditor.cpp
+++ b/src/gui/dialogs/gd_actionEditor.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -392,13 +392,13 @@ void gGridTool::calc() {
 		int step = parent->zoom*i;
 		while (j < step && j < G_Mixer.totalFrames) {
 			if (j % fpgc == 0) {
-				points.add(i);
-				frames.add(j);
+				points.push_back(i);
+				frames.push_back(j);
 			}
 			if (j % G_Mixer.framesPerBeat == 0)
-				beats.add(i);
+				beats.push_back(i);
 			if (j % G_Mixer.framesPerBar == 0 && i != 1)
-				bars.add(i);
+				bars.push_back(i);
 			if (j == G_Mixer.totalFrames-1)
 				parent->coverX = i;
 			j++;
@@ -420,9 +420,9 @@ int gGridTool::getSnapPoint(int v) {
 
 	if (v == 0) return 0;
 
-	for (int i=0; i<(int)points.size; i++) {
+	for (int i=0; i<(int)points.size(); i++) {
 
-		if (i == (int) points.size-1)
+		if (i == (int) points.size()-1)
 			return points.at(i);
 
 		int gp  = points.at(i);
@@ -442,9 +442,9 @@ int gGridTool::getSnapFrame(int v) {
 
 	v *= parent->zoom;  // transformation pixel -> frame
 
-	for (int i=0; i<(int)frames.size; i++) {
+	for (int i=0; i<(int)frames.size(); i++) {
 
-		if (i == (int) frames.size-1)
+		if (i == (int) frames.size()-1)
 			return frames.at(i);
 
 		int gf  = frames.at(i);     // grid frame
diff --git a/src/gui/dialogs/gd_actionEditor.h b/src/gui/dialogs/gd_actionEditor.h
index 1c38e7e..1f7eb40 100644
--- a/src/gui/dialogs/gd_actionEditor.h
+++ b/src/gui/dialogs/gd_actionEditor.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -30,12 +30,16 @@
 #ifndef GD_ACTIONEDITOR_H
 #define GD_ACTIONEDITOR_H
 
+#include <vector>
 #include <FL/Fl.H>
 #include <FL/Fl_Double_Window.H>
 #include <FL/Fl_Scroll.H>
 #include "../elems/ge_window.h"
 
 
+using std::vector;
+
+
 /* gActionEditor
  * main window which contains the tools for dealing with actions.
  * This class calculates chan, zoom, frames per beat, and so on. Each
@@ -75,7 +79,7 @@ public:
 	class gEnvelopeChannel    *vc;
 	class gPianoRollContainer *pr;
 
-	gVector <class gActionWidget*> widgets;
+	vector <class gActionWidget*> widgets;
 
 	class Channel *chan;
 
@@ -120,11 +124,11 @@ public:
 
 	int getCellSize();
 
-	gVector<int> points;   // points of the grid
-	gVector<int> frames;   // frames of the grid
+	vector<int> points;   // points of the grid
+	vector<int> frames;   // frames of the grid
 
-	gVector<int> bars;
-	gVector<int> beats;
+	vector<int> bars;
+	vector<int> beats;
 };
 
 
diff --git a/src/gui/dialogs/gd_beatsInput.cpp b/src/gui/dialogs/gd_beatsInput.cpp
index fb3aeba..36599eb 100644
--- a/src/gui/dialogs/gd_beatsInput.cpp
+++ b/src/gui/dialogs/gd_beatsInput.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_beatsInput.h b/src/gui/dialogs/gd_beatsInput.h
index 2818c72..a20fc4a 100644
--- a/src/gui/dialogs/gd_beatsInput.h
+++ b/src/gui/dialogs/gd_beatsInput.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_bpmInput.cpp b/src/gui/dialogs/gd_bpmInput.cpp
index a10e35c..d0186bf 100644
--- a/src/gui/dialogs/gd_bpmInput.cpp
+++ b/src/gui/dialogs/gd_bpmInput.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_bpmInput.h b/src/gui/dialogs/gd_bpmInput.h
index 8a6a945..cfca7d8 100644
--- a/src/gui/dialogs/gd_bpmInput.h
+++ b/src/gui/dialogs/gd_bpmInput.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_browser.cpp b/src/gui/dialogs/gd_browser.cpp
index c3eec4a..7a5704d 100644
--- a/src/gui/dialogs/gd_browser.cpp
+++ b/src/gui/dialogs/gd_browser.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -37,6 +37,7 @@
 #include "../../core/patch.h"
 #include "../../core/conf.h"
 #include "../../glue/glue.h"
+#include "../../glue/channel.h"
 #include "../../glue/storage.h"
 #include "../elems/ge_browser.h"
 #include "../elems/ge_channel.h"
@@ -348,7 +349,7 @@ void gdBrowser::__cb_loadPlugin() {
 	/* store the folder path inside G_Conf, in order to reuse it the
 	 * next time. */
 
-	G_Conf.setPath(G_Conf.pluginPath, where->value());
+	G_Conf.pluginPath = where->value();
 
 	if (p != NULL)
 		do_callback();
diff --git a/src/gui/dialogs/gd_browser.h b/src/gui/dialogs/gd_browser.h
index 51bd0c5..e638cec 100644
--- a/src/gui/dialogs/gd_browser.h
+++ b/src/gui/dialogs/gd_browser.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_config.cpp b/src/gui/dialogs/gd_config.cpp
index 7e9c213..40292af 100644
--- a/src/gui/dialogs/gd_config.cpp
+++ b/src/gui/dialogs/gd_config.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -47,7 +47,7 @@ extern bool        G_audio_status;
 extern MidiMapConf G_MidiMap;
 
 
-/* -------------------------------------------------------------------------- */
+using std::string;
 
 
 gTabMisc::gTabMisc(int X, int Y, int W, int H)
@@ -117,10 +117,13 @@ gTabAudio::gTabAudio(int X, int Y, int W, int H)
 	channelsIn  = new gChoice(x()+92,  y()+149, 55,  20, "Input channels");
 	delayComp   = new gInput (x()+290, y()+149, 55,  20, "Rec delay comp.");
 	rsmpQuality = new gChoice(x()+92, y()+177, 253, 20, "Resampling");
-                new gBox(x(), rsmpQuality->y()+rsmpQuality->h()+8, w(), 92, "Restart Giada for the changes to take effect.");
+                new gBox(x(), rsmpQuality->y()+rsmpQuality->h()+8, w(), 92,
+										"Restart Giada for the changes to take effect.");
 	end();
 	labelsize(11);
 
+	soundsys->add("(none)");
+
 #if defined(__linux__)
 
 	if (kernelAudio::hasAPI(RtAudio::LINUX_ALSA))
@@ -131,19 +134,21 @@ gTabAudio::gTabAudio(int X, int Y, int W, int H)
 		soundsys->add("PulseAudio");
 
 	switch (G_Conf.soundSystem) {
+		case SYS_API_NONE:
+			soundsys->showItem("(none)");
+			break;
 		case SYS_API_ALSA:
-			soundsys->show("ALSA");
+			soundsys->showItem("ALSA");
 			break;
 		case SYS_API_JACK:
-			soundsys->show("Jack");
+			soundsys->showItem("Jack");
 			buffersize->deactivate();
 			samplerate->deactivate();
 			break;
 		case SYS_API_PULSE:
-			soundsys->show("PulseAudio");
+			soundsys->showItem("PulseAudio");
 			break;
 	}
-	soundsysInitValue = soundsys->value();
 
 #elif defined(_WIN32)
 
@@ -151,28 +156,70 @@ gTabAudio::gTabAudio(int X, int Y, int W, int H)
 		soundsys->add("DirectSound");
 	if (kernelAudio::hasAPI(RtAudio::WINDOWS_ASIO))
 		soundsys->add("ASIO");
-	soundsys->show(G_Conf.soundSystem == SYS_API_DS ? "DirectSound" : "ASIO");
-	soundsysInitValue = soundsys->value();
+
+	switch (G_Conf.soundSystem) {
+		case SYS_API_NONE:
+			soundsys->showItem("(none)");
+			break;
+		case SYS_API_DS:
+			soundsys->showItem("DirectSound");
+			break;
+		case SYS_API_ASIO:
+			soundsys->showItem("ASIO");
+			break;
+	}
 
 #elif defined (__APPLE__)
 
 	if (kernelAudio::hasAPI(RtAudio::MACOSX_CORE))
 		soundsys->add("CoreAudio");
-	soundsys->show("CoreAudio");
-	soundsysInitValue = soundsys->value();
+
+	switch (G_Conf.soundSystem) {
+		case SYS_API_NONE:
+			soundsys->showItem("(none)");
+			break;
+		case SYS_API_CORE:
+			soundsys->showItem("CoreAudio");
+			break;
+	}
 
 #endif
 
+	soundsysInitValue = soundsys->value();
+
+	soundsys->callback(cb_deactivate_sounddev, (void*)this);
+
 	sounddevIn->callback(cb_fetchInChans, this);
 	sounddevOut->callback(cb_fetchOutChans, this);
 
 	devOutInfo->callback(cb_showOutputInfo, this);
 	devInInfo->callback(cb_showInputInfo, this);
 
-	fetchSoundDevs();
+	if (G_Conf.soundSystem != SYS_API_NONE) {
+		fetchSoundDevs();
+		fetchOutChans(sounddevOut->value());
+		fetchInChans(sounddevIn->value());
 
-	fetchOutChans(sounddevOut->value());
-	fetchInChans(sounddevIn->value());
+		/* fill frequency dropdown menu */
+		/* TODO - add fetchFrequencies() */
+
+		int nfreq = kernelAudio::getTotalFreqs(sounddevOut->value());
+		for (int i=0; i<nfreq; i++) {
+			int freq = kernelAudio::getFreq(sounddevOut->value(), i);
+			samplerate->add(gItoa(freq).c_str());
+			if (freq == G_Conf.samplerate)
+				samplerate->value(i);
+		}
+	}
+	else {
+		sounddevIn->deactivate();
+		sounddevOut->deactivate();
+		channelsIn->deactivate();
+		channelsOut->deactivate();
+		devOutInfo->deactivate();
+		devInInfo->deactivate();
+		samplerate->deactivate();
+	}
 
 	buffersize->add("8");
 	buffersize->add("16");
@@ -184,22 +231,7 @@ gTabAudio::gTabAudio(int X, int Y, int W, int H)
 	buffersize->add("1024");
 	buffersize->add("2048");
 	buffersize->add("4096");
-
-	char buf[8];
-	sprintf(buf, "%d", G_Conf.buffersize);
-	buffersize->show(buf);
-
-	/* fill frequency dropdown menu */
-
-	int nfreq = kernelAudio::getTotalFreqs(sounddevOut->value());
-	for (int i=0; i<nfreq; i++) {
-		char buf[16];
-		int  freq = kernelAudio::getFreq(sounddevOut->value(), i);
-		sprintf(buf, "%d", freq);
-		samplerate->add(buf);
-		if (freq == G_Conf.samplerate)
-			samplerate->value(i);
-	}
+	buffersize->showItem(gItoa(G_Conf.buffersize).c_str());
 
 	rsmpQuality->add("Sinc best quality (very slow)");
 	rsmpQuality->add("Sinc medium quality (slow)");
@@ -208,14 +240,11 @@ gTabAudio::gTabAudio(int X, int Y, int W, int H)
 	rsmpQuality->add("Linear (very fast)");
 	rsmpQuality->value(G_Conf.rsmpQuality);
 
-	buf[0] = '\0';
-	sprintf(buf, "%d", G_Conf.delayComp);
-	delayComp->value(buf);
+	delayComp->value(gItoa(G_Conf.delayComp).c_str());
 	delayComp->type(FL_INT_INPUT);
 	delayComp->maximum_size(5);
 
 	limitOutput->value(G_Conf.limitOutput);
-	soundsys->callback(cb_deactivate_sounddev, (void*)this);
 }
 
 
@@ -276,9 +305,10 @@ void gTabAudio::__cb_deactivate_sounddev()
 {
 	/* if the user changes sound system (eg ALSA->JACK) device menu deactivates.
 	 * If it returns to the original sound system, we re-fill the list by
-	 * querying kernelAudio. */
+	 * querying kernelAudio. Watch out if soundsysInitValue == 0: you don't want
+	 * to query kernelAudio for '(none)' soundsystem! */
 
-	if (soundsysInitValue == soundsys->value()) {
+	if (soundsysInitValue == soundsys->value() && soundsysInitValue != 0) {
 		sounddevOut->clear();
 		sounddevIn->clear();
 
@@ -294,6 +324,7 @@ void gTabAudio::__cb_deactivate_sounddev()
 
 		fetchInChans(sounddevIn->value());
 		sounddevIn->activate();
+		samplerate->activate();
 	}
 	else {
 		sounddevOut->deactivate();
@@ -302,6 +333,7 @@ void gTabAudio::__cb_deactivate_sounddev()
 		sounddevOut->value(0);
 		channelsOut->deactivate();
 		devOutInfo->deactivate();
+		samplerate->deactivate();
 
 		sounddevIn->deactivate();
 		sounddevIn->clear();
@@ -385,11 +417,11 @@ int gTabAudio::findMenuDevice(gChoice *m, int device)
 		return 0;
 
 	for (int i=0; i<m->size(); i++) {
-		if (kernelAudio::getDeviceName(device) == NULL)
+		if (kernelAudio::getDeviceName(device) == "")
 			continue;
 		if (m->text(i) == NULL)
 			continue;
-		if (strcmp(m->text(i), kernelAudio::getDeviceName(device))==0)
+		if (m->text(i) == kernelAudio::getDeviceName(device))
 			return i;
 	}
 
@@ -424,7 +456,7 @@ void gTabAudio::fetchSoundDevs()
 
 			/* escaping '/', very dangerous in FLTK (it creates a submenu) */
 
-			std::string tmp = kernelAudio::getDeviceName(i);
+			string tmp = kernelAudio::getDeviceName(i);
 			for (unsigned k=0; k<tmp.size(); k++)
 				if (tmp[k] == '/' || tmp[k] == '|' || tmp[k] == '&' || tmp[k] == '_')
 					tmp[k] = '-';
@@ -470,17 +502,34 @@ void gTabAudio::fetchSoundDevs()
 
 void gTabAudio::save()
 {
-	/** FIXME - wrong, if API is missing! Right way in gTabMidi::save */
-
-#ifdef __linux__
-	if      (soundsys->value() == 0)	G_Conf.soundSystem = SYS_API_ALSA;
-	else if (soundsys->value() == 1)	G_Conf.soundSystem = SYS_API_JACK;
-	else if (soundsys->value() == 2)	G_Conf.soundSystem = SYS_API_PULSE;
-#else
-#ifdef _WIN32
-	if 			(soundsys->value() == 0)	G_Conf.soundSystem = SYS_API_DS;
-	else if (soundsys->value() == 1)  G_Conf.soundSystem = SYS_API_ASIO;
-#endif
+	string text = soundsys->text(soundsys->value());
+
+	if (text == "(none)") {
+		G_Conf.soundSystem = SYS_API_NONE;
+		return;
+	}
+
+#if defined(__linux__)
+
+	else if (text == "ALSA")
+		G_Conf.soundSystem = SYS_API_ALSA;
+	else if (text == "Jack")
+		G_Conf.soundSystem = SYS_API_JACK;
+	else if (text == "PulseAudio")
+		G_Conf.soundSystem = SYS_API_PULSE;
+
+#elif defined(_WIN32)
+
+	else if (text == "DirectSound")
+		G_Conf.soundSystem = SYS_API_DS;
+	else if (text == "ASIO")
+		G_Conf.soundSystem = SYS_API_ASIO;
+
+#elif defined (__APPLE__)
+
+	else if (text == "CoreAudio")
+		G_Conf.soundSystem = SYS_API_CORE;
+
 #endif
 
 	/* use the device name to search into the drop down menu's */
@@ -509,9 +558,7 @@ void gTabAudio::save()
 	if (i)
 		G_Conf.samplerate = atoi(i->label());
 
-	int _delayComp = atoi(delayComp->value());
-	if (_delayComp < 0) _delayComp = 0;
-	G_Conf.delayComp = _delayComp;
+	G_Conf.delayComp = atoi(delayComp->value());
 }
 
 
@@ -572,13 +619,8 @@ void gTabMidi::fetchOutPorts() {
 
 		portOut->add("(disabled)");
 
-		for (unsigned i=0; i<kernelMidi::numOutPorts; i++) {
-			char *t = (char*) kernelMidi::getOutPortName(i);
-			for (int k=0; t[k] != '\0'; k++)
-				if (t[k] == '/' || t[k] == '|' || t[k] == '&' || t[k] == '_')
-					t[k] = '-';
-			portOut->add(t);
-		}
+		for (unsigned i=0; i<kernelMidi::numOutPorts; i++)
+			portOut->add(gu_removeFltkChars(kernelMidi::getOutPortName(i)).c_str());
 
 		portOut->value(G_Conf.midiPortOut+1);    // +1 because midiPortOut=-1 is '(disabled)'
 	}
@@ -598,13 +640,8 @@ void gTabMidi::fetchInPorts()
 
 		portIn->add("(disabled)");
 
-		for (unsigned i=0; i<kernelMidi::numInPorts; i++) {
-			char *t = (char*) kernelMidi::getInPortName(i);
-			for (int k=0; t[k] != '\0'; k++)
-				if (t[k] == '/' || t[k] == '|' || t[k] == '&' || t[k] == '_')
-					t[k] = '-';
-			portIn->add(t);
-		}
+		for (unsigned i=0; i<kernelMidi::numInPorts; i++)
+			portIn->add(gu_removeFltkChars(kernelMidi::getInPortName(i)).c_str());
 
 		portIn->value(G_Conf.midiPortIn+1);    // +1 because midiPortIn=-1 is '(disabled)'
 	}
@@ -616,16 +653,16 @@ void gTabMidi::fetchInPorts()
 
 void gTabMidi::fetchMidiMaps()
 {
-	if (G_MidiMap.maps.size == 0) {
+	if (G_MidiMap.maps.size() == 0) {
 		midiMap->add("(no MIDI maps available)");
 		midiMap->value(0);
 		midiMap->deactivate();
 		return;
 	}
-	for (unsigned i=0; i<G_MidiMap.maps.size; i++) {
+	for (unsigned i=0; i<G_MidiMap.maps.size(); i++) {
 		const char *imap = G_MidiMap.maps.at(i).c_str();
 		midiMap->add(imap);
-		if (strcmp(G_Conf.midiMapPath, imap) == 0)
+		if (G_Conf.midiMapPath == imap)
 			midiMap->value(i);
 	}
 }
@@ -636,21 +673,22 @@ void gTabMidi::fetchMidiMaps()
 
 void gTabMidi::save()
 {
-	if      (!strcmp("ALSA", system->text(system->value())))
+	string text = system->text(system->value());
+
+	if      (text == "ALSA")
 		G_Conf.midiSystem = RtMidi::LINUX_ALSA;
-	else if (!strcmp("Jack", system->text(system->value())))
+	else if (text == "Jack")
 		G_Conf.midiSystem = RtMidi::UNIX_JACK;
-	else if (!strcmp("Multimedia MIDI", system->text(system->value())))
+	else if (text == "Multimedia MIDI")
 		G_Conf.midiSystem = RtMidi::WINDOWS_MM;
-	else if (!strcmp("OSX Core MIDI", system->text(system->value())))
+	else if (text == "OSX Core MIDI")
 		G_Conf.midiSystem = RtMidi::MACOSX_CORE;
 
 	G_Conf.midiPortOut = portOut->value()-1;   // -1 because midiPortOut=-1 is '(disabled)'
 	G_Conf.midiPortIn  = portIn->value()-1;    // -1 because midiPortIn=-1 is '(disabled)'
 
 	G_Conf.noNoteOff   = noNoteOff->value();
-
-	G_Conf.setPath(G_Conf.midiMapPath, midiMap->text(midiMap->value()));
+	G_Conf.midiMapPath = G_MidiMap.maps.size() == 0 ? "" : midiMap->text(midiMap->value());
 
 	if      (sync->value() == 0)
 		G_Conf.midiSync = MIDI_SYNC_NONE;
@@ -685,10 +723,10 @@ void gTabMidi::fetchSystems()
 #endif
 
 	switch (G_Conf.midiSystem) {
-		case RtMidi::LINUX_ALSA:  system->show("ALSA"); break;
-		case RtMidi::UNIX_JACK:   system->show("Jack"); break;
-		case RtMidi::WINDOWS_MM:  system->show("Multimedia MIDI"); break;
-		case RtMidi::MACOSX_CORE: system->show("OSX Core MIDI"); break;
+		case RtMidi::LINUX_ALSA:  system->showItem("ALSA"); break;
+		case RtMidi::UNIX_JACK:   system->showItem("Jack"); break;
+		case RtMidi::WINDOWS_MM:  system->showItem("Multimedia MIDI"); break;
+		case RtMidi::MACOSX_CORE: system->showItem("OSX Core MIDI"); break;
 		default: system->value(0); break;
 	}
 }
@@ -713,12 +751,23 @@ void gTabMidi::__cb_changeSystem()
 		portOut->clear();
 		fetchOutPorts();
 		portOut->activate();
+		portIn->clear();
+		fetchInPorts();
+		portIn->activate();
+		noNoteOff->activate();
+		sync->activate();
 	}
 	else {
 		portOut->deactivate();
 		portOut->clear();
 		portOut->add("-- restart to fetch device(s) --");
 		portOut->value(0);
+		portIn->deactivate();
+		portIn->clear();
+		portIn->add("-- restart to fetch device(s) --");
+		portIn->value(0);
+		noNoteOff->deactivate();
+		sync->deactivate();
 	}
 
 }
diff --git a/src/gui/dialogs/gd_config.h b/src/gui/dialogs/gd_config.h
index 64d06d4..3331e44 100644
--- a/src/gui/dialogs/gd_config.h
+++ b/src/gui/dialogs/gd_config.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -35,6 +35,9 @@
 #include "../elems/ge_window.h"
 
 
+using std::string;
+
+
 class gdConfig : public gWindow
 {
 private:
@@ -74,7 +77,7 @@ private:
 	int systemInitValue;
 
 public:
-	
+
 	class gChoice *system;
 	class gChoice *portOut;
 	class gChoice *portIn;
diff --git a/src/gui/dialogs/gd_devInfo.cpp b/src/gui/dialogs/gd_devInfo.cpp
index efdc064..5055928 100644
--- a/src/gui/dialogs/gd_devInfo.cpp
+++ b/src/gui/dialogs/gd_devInfo.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,10 +29,14 @@
 
 #include "../../core/kernelAudio.h"
 #include "../../utils/gui_utils.h"
+#include "../../utils/utils.h"
 #include "../elems/ge_mixed.h"
 #include "gd_devInfo.h"
 
 
+using std::string;
+
+
 gdDevInfo::gdDevInfo(unsigned dev)
 : Fl_Window(340, 300, "Device information") {
 	set_modal();
@@ -41,62 +45,34 @@ gdDevInfo::gdDevInfo(unsigned dev)
 	close = new gClick(252, h()-28, 80, 20, "Close");
 	end();
 
-	std::string bufTxt;
-	char bufNum[128];
-	int  lines = 0;
-
-	bufTxt  = "Device name: ";
-	bufTxt += +kernelAudio::getDeviceName(dev);
-	bufTxt += "\n";
-	lines++;
-
-	bufTxt += "Total output(s): ";
-	sprintf(bufNum, "%d\n", kernelAudio::getMaxOutChans(dev));
-	bufTxt += bufNum;
-	lines++;
-
-	bufTxt += "Total intput(s): ";
-	sprintf(bufNum, "%d\n", kernelAudio::getMaxInChans(dev));
-	bufTxt += bufNum;
-	lines++;
-
-	bufTxt += "Duplex channel(s): ";
-	sprintf(bufNum, "%d\n", kernelAudio::getDuplexChans(dev));
-	bufTxt += bufNum;
-	lines++;
-
-	bufTxt += "Default output: ";
-	sprintf(bufNum, "%s\n", kernelAudio::isDefaultOut(dev) ? "yes" : "no");
-	bufTxt += bufNum;
-	lines++;
+	string body  = "";
+	int    lines = 7;
 
-	bufTxt += "Default input: ";
-	sprintf(bufNum, "%s\n", kernelAudio::isDefaultIn(dev) ? "yes" : "no");
-	bufTxt += bufNum;
-	lines++;
+	body  = "Device name: " + kernelAudio::getDeviceName(dev) + "\n";
+	body += "Total output(s): " + gItoa(kernelAudio::getMaxOutChans(dev)) + "\n";
+	body += "Total intput(s): " + gItoa(kernelAudio::getMaxInChans(dev)) + "\n";
+	body += "Duplex channel(s): " + gItoa(kernelAudio::getDuplexChans(dev)) + "\n";
+	body += "Default output: " + string(kernelAudio::isDefaultOut(dev) ? "yes" : "no") + "\n";
+	body += "Default input: " + string(kernelAudio::isDefaultIn(dev) ? "yes" : "no") + "\n";
 
 	int totalFreq = kernelAudio::getTotalFreqs(dev);
-	bufTxt += "Supported frequencies: ";
-	sprintf(bufNum, "%d", totalFreq);
-	bufTxt += bufNum;
-	lines++;
+	body += "Supported frequencies: " + gItoa(totalFreq);
 
 	for (int i=0; i<totalFreq; i++) {
-		sprintf(bufNum, "%d  ", kernelAudio::getFreq(dev, i));
-		if (i%6 == 0) {    // new line each X printed freqs AND on the first line (i%0 != 0)
-			bufTxt += "\n    ";
+		if (i % 6 == 0) {
+			body += "\n    ";  // add new line each 6 printed freqs AND on the first line (i % 0 != 0)
 			lines++;
 		}
-		bufTxt += bufNum;
+		body += gItoa( kernelAudio::getFreq(dev, i)) + "  ";
 	}
 
-	text->copy_label(bufTxt.c_str());
+	text->copy_label(body.c_str());
 
 	/* resize the window to fit the content. fl_height() returns the height
 	 * of a line. fl_height() * total lines + margins + button size */
 
-	resize(x(), y(), w(), lines*fl_height() + 8 + 8 + 8 + 20);
-	close->position(close->x(), lines*fl_height() + 8 + 8);
+	resize(x(), y(), w(), (lines * fl_height()) + 8 + 8 + 8 + 20);
+	close->position(close->x(), (lines * fl_height()) + 8 + 8);
 
 	close->callback(__cb_window_closer, (void*)this);
 	gu_setFavicon(this);
diff --git a/src/gui/dialogs/gd_devInfo.h b/src/gui/dialogs/gd_devInfo.h
index c5a06ca..79a4ad2 100644
--- a/src/gui/dialogs/gd_devInfo.h
+++ b/src/gui/dialogs/gd_devInfo.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_editor.cpp b/src/gui/dialogs/gd_editor.cpp
index 231bdec..4a15bf8 100644
--- a/src/gui/dialogs/gd_editor.cpp
+++ b/src/gui/dialogs/gd_editor.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_editor.h b/src/gui/dialogs/gd_editor.h
index 54a8f79..cd7b9ae 100644
--- a/src/gui/dialogs/gd_editor.h
+++ b/src/gui/dialogs/gd_editor.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_keyGrabber.cpp b/src/gui/dialogs/gd_keyGrabber.cpp
index 6b4527f..47a8a54 100644
--- a/src/gui/dialogs/gd_keyGrabber.cpp
+++ b/src/gui/dialogs/gd_keyGrabber.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_keyGrabber.h b/src/gui/dialogs/gd_keyGrabber.h
index 02bbe85..ddee3a6 100644
--- a/src/gui/dialogs/gd_keyGrabber.h
+++ b/src/gui/dialogs/gd_keyGrabber.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_mainWindow.cpp b/src/gui/dialogs/gd_mainWindow.cpp
index 1fc0c67..5185668 100644
--- a/src/gui/dialogs/gd_mainWindow.cpp
+++ b/src/gui/dialogs/gd_mainWindow.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -325,7 +325,7 @@ void gMenu::__cb_file()
 
 
 	if (strcmp(m->label(), "Open patch or project...") == 0) {
-		gWindow *childWin = new gdBrowser("Load Patch", G_Conf.patchPath, 0, BROWSER_LOAD_PATCH);
+		gWindow *childWin = new gdBrowser("Load Patch", G_Conf.patchPath.c_str(), 0, BROWSER_LOAD_PATCH);
 		gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
 		return;
 	}
@@ -333,12 +333,12 @@ void gMenu::__cb_file()
 		if (G_Mixer.hasLogicalSamples() || G_Mixer.hasEditedSamples())
 			if (!gdConfirmWin("Warning", "You should save a project in order to store\nyour takes and/or processed samples."))
 				return;
-		gWindow *childWin = new gdBrowser("Save Patch", G_Conf.patchPath, 0, BROWSER_SAVE_PATCH);
+		gWindow *childWin = new gdBrowser("Save Patch", G_Conf.patchPath.c_str(), 0, BROWSER_SAVE_PATCH);
 		gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
 		return;
 	}
 	if (strcmp(m->label(), "Save project...") == 0) {
-		gWindow *childWin = new gdBrowser("Save Project", G_Conf.patchPath, 0, BROWSER_SAVE_PROJECT);
+		gWindow *childWin = new gdBrowser("Save Project", G_Conf.patchPath.c_str(), 0, BROWSER_SAVE_PROJECT);
 		gu_openSubWindow(mainWin, childWin, WID_FILE_BROWSER);
 		return;
 	}
@@ -368,12 +368,12 @@ void gMenu::__cb_edit()
 
 	menu[1].deactivate();
 
-	for (unsigned i=0; i<G_Mixer.channels.size; i++)
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++)
 		if (G_Mixer.channels.at(i)->hasActions) {
 			menu[1].activate();
 			break;
 		}
-	for (unsigned i=0; i<G_Mixer.channels.size; i++)
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++)
 		if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE)
 			if (((SampleChannel*)G_Mixer.channels.at(i))->wave != NULL) {
 				menu[0].activate();
diff --git a/src/gui/dialogs/gd_mainWindow.h b/src/gui/dialogs/gd_mainWindow.h
index df2c911..7adc52d 100644
--- a/src/gui/dialogs/gd_mainWindow.h
+++ b/src/gui/dialogs/gd_mainWindow.h
@@ -5,7 +5,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -69,7 +69,6 @@ private:
 
 	class gSoundMeter *outMeter;
 	class gSoundMeter *inMeter;
-	class gBeatMeter  *beatMeter;
 	class gDial				*outVol;
 	class gDial				*inVol;
 #ifdef WITH_VST
diff --git a/src/gui/dialogs/gd_midiInput.cpp b/src/gui/dialogs/gd_midiInput.cpp
index 27a7d67..ce7f468 100644
--- a/src/gui/dialogs/gd_midiInput.cpp
+++ b/src/gui/dialogs/gd_midiInput.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_midiInput.h b/src/gui/dialogs/gd_midiInput.h
index e5d31f5..0ade193 100644
--- a/src/gui/dialogs/gd_midiInput.h
+++ b/src/gui/dialogs/gd_midiInput.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_midiOutput.cpp b/src/gui/dialogs/gd_midiOutput.cpp
index 991b68a..69aea2c 100644
--- a/src/gui/dialogs/gd_midiOutput.cpp
+++ b/src/gui/dialogs/gd_midiOutput.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_midiOutput.h b/src/gui/dialogs/gd_midiOutput.h
index 911a253..03cc32a 100644
--- a/src/gui/dialogs/gd_midiOutput.h
+++ b/src/gui/dialogs/gd_midiOutput.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_pluginList.cpp b/src/gui/dialogs/gd_pluginList.cpp
index 6ef967d..21ee645 100644
--- a/src/gui/dialogs/gd_pluginList.cpp
+++ b/src/gui/dialogs/gd_pluginList.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -138,7 +138,7 @@ void gdPluginList::__cb_addPlugin() {
 	 * must be redrawn. We have a special callback, cb_refreshList, which
 	 * we add to gdBrowser. It does exactly what we need. */
 
-	gdBrowser *b = new gdBrowser("Browse Plugin", G_Conf.pluginPath, ch, BROWSER_LOAD_PLUGIN, stackType);
+	gdBrowser *b = new gdBrowser("Browse Plugin", G_Conf.pluginPath.c_str(), ch, BROWSER_LOAD_PLUGIN, stackType);
 	addSubWindow(b);
 	b->callback(cb_refreshList, (void*)this);	// 'this' refers to gdPluginList
 
@@ -185,7 +185,7 @@ void gdPluginList::refreshList() {
 	redraw();
 
   /* set 'full' flag to FX button */
-  
+
   /* TODO - awful stuff... we should subclass into gdPluginListChannel and
   gdPluginListMaster */
 
@@ -310,7 +310,7 @@ void gdPlugin::__cb_shiftDown() {
 		return;
 
 	unsigned pluginIndex = G_PluginHost.getPluginIndex(pPlugin->getId(), pParent->stackType, pParent->ch);
-	unsigned stackSize   = (G_PluginHost.getStack(pParent->stackType, pParent->ch))->size;
+	unsigned stackSize   = (G_PluginHost.getStack(pParent->stackType, pParent->ch))->size();
 
 	if (pluginIndex == stackSize-1)  // last one in the stack, do nothing
 		return;
diff --git a/src/gui/dialogs/gd_pluginList.h b/src/gui/dialogs/gd_pluginList.h
index 5f96e89..ee5e455 100644
--- a/src/gui/dialogs/gd_pluginList.h
+++ b/src/gui/dialogs/gd_pluginList.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_pluginWindow.cpp b/src/gui/dialogs/gd_pluginWindow.cpp
index a60ebe5..e4144a2 100644
--- a/src/gui/dialogs/gd_pluginWindow.cpp
+++ b/src/gui/dialogs/gd_pluginWindow.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_pluginWindow.h b/src/gui/dialogs/gd_pluginWindow.h
index 0f50529..5e4cb12 100644
--- a/src/gui/dialogs/gd_pluginWindow.h
+++ b/src/gui/dialogs/gd_pluginWindow.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_pluginWindowGUI.cpp b/src/gui/dialogs/gd_pluginWindowGUI.cpp
index 7b6ff31..a86c717 100644
--- a/src/gui/dialogs/gd_pluginWindowGUI.cpp
+++ b/src/gui/dialogs/gd_pluginWindowGUI.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_pluginWindowGUI.h b/src/gui/dialogs/gd_pluginWindowGUI.h
index 516b879..83506d8 100644
--- a/src/gui/dialogs/gd_pluginWindowGUI.h
+++ b/src/gui/dialogs/gd_pluginWindowGUI.h
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_warnings.cpp b/src/gui/dialogs/gd_warnings.cpp
index 31a5dbc..6edb2ea 100644
--- a/src/gui/dialogs/gd_warnings.cpp
+++ b/src/gui/dialogs/gd_warnings.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/gd_warnings.h b/src/gui/dialogs/gd_warnings.h
index 791d236..c2350cf 100644
--- a/src/gui/dialogs/gd_warnings.h
+++ b/src/gui/dialogs/gd_warnings.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_actionChannel.cpp b/src/gui/elems/ge_actionChannel.cpp
index b744ac3..fdedf08 100644
--- a/src/gui/elems/ge_actionChannel.cpp
+++ b/src/gui/elems/ge_actionChannel.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -55,8 +55,8 @@ gActionChannel::gActionChannel(int x, int y, gdActionEditor *pParent, SampleChan
 	/* add actions when the window opens. Their position is zoom-based;
 	 * each frame is / 2 because we don't care about stereo infos. */
 
-	for (unsigned i=0; i<recorder::frames.size; i++) {
-		for (unsigned j=0; j<recorder::global.at(i).size; j++) {
+	for (unsigned i=0; i<recorder::frames.size(); i++) {
+		for (unsigned j=0; j<recorder::global.at(i).size(); j++) {
 
 			recorder::action *ra = recorder::global.at(i).at(j);
 
@@ -284,7 +284,7 @@ int gActionChannel::handle(int e) {
 							y()+4,                                // y
 							h()-8,                                // h
 							fx,																		// frame_a
-							recorder::frames.size-1,              // n. of actions recorded
+							recorder::frames.size()-1,            // n. of actions recorded
 							pParent,                              // pParent window pointer
 							ch,                                   // pointer to SampleChannel
 							true,                                 // record = true: record it!
diff --git a/src/gui/elems/ge_actionChannel.h b/src/gui/elems/ge_actionChannel.h
index 67413fd..38bc8d8 100644
--- a/src/gui/elems/ge_actionChannel.h
+++ b/src/gui/elems/ge_actionChannel.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_actionWidget.cpp b/src/gui/elems/ge_actionWidget.cpp
index 05b4db0..562a591 100644
--- a/src/gui/elems/ge_actionWidget.cpp
+++ b/src/gui/elems/ge_actionWidget.cpp
@@ -8,7 +8,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -71,7 +71,7 @@ void gActionWidget::baseDraw(bool clear) {
 		fl_color(fl_rgb_color(54, 54, 54));
 		fl_line_style(FL_DASH, 0, NULL);
 
-		for (int i=0; i<(int) pParent->gridTool->points.size; i++) {
+		for (int i=0; i<(int) pParent->gridTool->points.size(); i++) {
 			int px = pParent->gridTool->points.at(i)+x()-1;
 			fl_line(px, y()+1, px, y()+h()-2);
 		}
@@ -81,13 +81,13 @@ void gActionWidget::baseDraw(bool clear) {
 	/* bars and beats drawing */
 
 	fl_color(COLOR_BD_0);
-	for (int i=0; i<(int) pParent->gridTool->beats.size; i++) {
+	for (int i=0; i<(int) pParent->gridTool->beats.size(); i++) {
 		int px = pParent->gridTool->beats.at(i)+x()-1;
 		fl_line(px, y()+1, px, y()+h()-2);
 	}
 
 	fl_color(COLOR_BG_2);
-	for (int i=0; i<(int) pParent->gridTool->bars.size; i++) {
+	for (int i=0; i<(int) pParent->gridTool->bars.size(); i++) {
 		int px = pParent->gridTool->bars.at(i)+x()-1;
 		fl_line(px, y()+1, px, y()+h()-2);
 	}
diff --git a/src/gui/elems/ge_actionWidget.h b/src/gui/elems/ge_actionWidget.h
index b02f8d7..1536b29 100644
--- a/src/gui/elems/ge_actionWidget.h
+++ b/src/gui/elems/ge_actionWidget.h
@@ -8,7 +8,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_browser.cpp b/src/gui/elems/ge_browser.cpp
index fd70dcc..7e2de58 100644
--- a/src/gui/elems/ge_browser.cpp
+++ b/src/gui/elems/ge_browser.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_browser.h b/src/gui/elems/ge_browser.h
index 8445319..0fbc1b7 100644
--- a/src/gui/elems/ge_browser.h
+++ b/src/gui/elems/ge_browser.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_channel.cpp b/src/gui/elems/ge_channel.cpp
index a9a37d5..6f93aec 100644
--- a/src/gui/elems/ge_channel.cpp
+++ b/src/gui/elems/ge_channel.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_channel.h b/src/gui/elems/ge_channel.h
index 5af2d64..e0c99ac 100644
--- a/src/gui/elems/ge_channel.h
+++ b/src/gui/elems/ge_channel.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_channelButton.cpp b/src/gui/elems/ge_channelButton.cpp
index 1480b54..ab6e306 100644
--- a/src/gui/elems/ge_channelButton.cpp
+++ b/src/gui/elems/ge_channelButton.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_channelButton.h b/src/gui/elems/ge_channelButton.h
index 86f6736..9a1718d 100644
--- a/src/gui/elems/ge_channelButton.h
+++ b/src/gui/elems/ge_channelButton.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_column.cpp b/src/gui/elems/ge_column.cpp
index de10451..5c15e42 100644
--- a/src/gui/elems/ge_column.cpp
+++ b/src/gui/elems/ge_column.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -34,6 +34,7 @@
 #include "../../core/sampleChannel.h"
 #include "../../core/midiChannel.h"
 #include "../../glue/glue.h"
+#include "../../glue/channel.h"
 #include "../../utils/log.h"
 #include "../dialogs/gd_mainWindow.h"
 #include "../dialogs/gd_warnings.h"
@@ -97,17 +98,23 @@ gColumn::~gColumn()
 int gColumn::handle(int e)
 {
 	switch (e) {
+		case FL_RELEASE: {
+			if (Fl::event_button() == FL_RIGHT_MOUSE) {
+				__cb_addChannel();
+				return 1;
+			}
+		}
 		case FL_DND_ENTER:           	// return(1) for these events to 'accept' dnd
 		case FL_DND_DRAG:
 		case FL_DND_RELEASE: {
 			return 1;
 		}
 		case FL_PASTE: {              // handle actual drop (paste) operation
-			gVector<std::string> paths;
+			vector<std::string> paths;
 			gSplit(Fl::event_text(), "\n", &paths);
 			bool fails = false;
 			int result = 0;
-			for (unsigned i=0; i<paths.size; i++) {
+			for (unsigned i=0; i<paths.size(); i++) {
 				gLog("[gColumn::handle] loading %s...\n", paths.at(i).c_str());
 				SampleChannel *c = (SampleChannel*) glue_addChannel(index, CHANNEL_SAMPLE);
 				result = glue_loadChannel(c, gStripFileUrl(paths.at(i).c_str()).c_str());
@@ -117,7 +124,7 @@ int gColumn::handle(int e)
 				}
 			}
 			if (fails) {
-				if (paths.size > 1)
+				if (paths.size() > 1)
 					gdAlert("Some files were not loaded successfully.");
 				else
 					parent->printChannelMessage(result);
diff --git a/src/gui/elems/ge_column.h b/src/gui/elems/ge_column.h
index f0e0c9c..93e8a1c 100644
--- a/src/gui/elems/ge_column.h
+++ b/src/gui/elems/ge_column.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_controller.cpp b/src/gui/elems/ge_controller.cpp
index 2557ae6..ed9f738 100644
--- a/src/gui/elems/ge_controller.cpp
+++ b/src/gui/elems/ge_controller.cpp
@@ -5,7 +5,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_controller.h b/src/gui/elems/ge_controller.h
index 7056948..4c4aa6c 100644
--- a/src/gui/elems/ge_controller.h
+++ b/src/gui/elems/ge_controller.h
@@ -5,7 +5,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_envelopeChannel.cpp b/src/gui/elems/ge_envelopeChannel.cpp
index d340375..b6be16e 100644
--- a/src/gui/elems/ge_envelopeChannel.cpp
+++ b/src/gui/elems/ge_envelopeChannel.cpp
@@ -9,7 +9,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -70,7 +70,7 @@ void gEnvelopeChannel::addPoint(int frame, int iValue, float fValue, int px, int
 	p.fValue = fValue;
 	p.x = px;
 	p.y = py;
-	points.add(p);
+	points.push_back(p);
 }
 
 
@@ -78,7 +78,7 @@ void gEnvelopeChannel::addPoint(int frame, int iValue, float fValue, int px, int
 
 
 void gEnvelopeChannel::updateActions() {
-	for (unsigned i=0; i<points.size; i++)
+	for (unsigned i=0; i<points.size(); i++)
 		points.at(i).x = points.at(i).frame / pParent->zoom;
 }
 
@@ -103,7 +103,7 @@ void gEnvelopeChannel::draw() {
 
 	fl_color(COLOR_BG_2);
 
-	for (unsigned i=0; i<points.size; i++) {
+	for (unsigned i=0; i<points.size(); i++) {
 
 		pxNew = points.at(i).x+x()-3;
 		pyNew = points.at(i).y+y();
@@ -183,7 +183,7 @@ int gEnvelopeChannel::handle(int e) {
 						/* if this is the first point ever, add other two points at the beginning
 						 * and the end of the range */
 
-						if (points.size == 0) {
+						if (points.size() == 0) {
 							addPoint(0, 0, 1.0f, 0, 1);
 							recorder::rec(pParent->chan->index, type, 0, 0, 1.0f);
 							addPoint(G_Mixer.totalFrames, 0, 1.0f, pParent->coverX, 1);
@@ -211,14 +211,14 @@ int gEnvelopeChannel::handle(int e) {
 				/* right click on point 0 or point size-1 deletes the entire envelope */
 
 				if (selectedPoint != -1) {
-					if (selectedPoint == 0 || (unsigned) selectedPoint == points.size-1) {
+					if (selectedPoint == 0 || (unsigned) selectedPoint == points.size()-1) {
 						recorder::clearAction(pParent->chan->index, type);
 						points.clear();
 					}
 					else {
 						recorder::deleteAction(pParent->chan->index, points.at(selectedPoint).frame, type, false);
 						recorder::sortActions();
-						points.del(selectedPoint);
+						points.erase(points.begin() + selectedPoint);
 					}
 					mainWin->keyboard->setChannelWithActions((gSampleChannel*)pParent->chan->guiChannel); // update mainWindow
 					redraw();
@@ -294,7 +294,7 @@ int gEnvelopeChannel::handle(int e) {
 				if (draggedPoint == 0)
 					points.at(draggedPoint).x = x()-8;
 				else
-				if ((unsigned) draggedPoint == points.size-1)
+				if ((unsigned) draggedPoint == points.size()-1)
 					points.at(draggedPoint).x = pParent->coverX;
 				else {
 					int prevPoint = points.at(draggedPoint-1).x;
@@ -329,9 +329,9 @@ int gEnvelopeChannel::handle(int e) {
 
 
 int gEnvelopeChannel::verticalPoint(const point &p) {
-	for (unsigned i=0; i<points.size; i++) {
+	for (unsigned i=0; i<points.size(); i++) {
 		if (&p == &points.at(i)) {
-			if (i == 0 || i == points.size-1)  // first or last point
+			if (i == 0 || i == points.size()-1)  // first or last point
 				return 0;
 			else {
 				if (points.at(i-1).x == p.x)    // vertical with point[i-1]
@@ -351,10 +351,10 @@ int gEnvelopeChannel::verticalPoint(const point &p) {
 
 
 void gEnvelopeChannel::sortPoints() {
-	for (unsigned i=0; i<points.size; i++)
-		for (unsigned j=0; j<points.size; j++)
+	for (unsigned i=0; i<points.size(); i++)
+		for (unsigned j=0; j<points.size(); j++)
 			if (points.at(j).x > points.at(i).x)
-				points.swap(j, i);
+				std::swap(points.at(j), points.at(i));
 }
 
 
@@ -365,7 +365,7 @@ int gEnvelopeChannel::getSelectedPoint() {
 
 	/* point is a 7x7 dot */
 
-	for (unsigned i=0; i<points.size; i++) {
+	for (unsigned i=0; i<points.size(); i++) {
 		if (Fl::event_x() >= points.at(i).x+x()-4  &&
 				Fl::event_x() <= points.at(i).x+x()+4  &&
 				Fl::event_y() >= points.at(i).y+y()    &&
@@ -381,8 +381,8 @@ int gEnvelopeChannel::getSelectedPoint() {
 
 void gEnvelopeChannel::fill() {
 	points.clear();
-	for (unsigned i=0; i<recorder::global.size; i++)
-		for (unsigned j=0; j<recorder::global.at(i).size; j++) {
+	for (unsigned i=0; i<recorder::global.size(); i++)
+		for (unsigned j=0; j<recorder::global.at(i).size(); j++) {
 			recorder::action *a = recorder::global.at(i).at(j);
 			if (a->type == type && a->chan == pParent->chan->index) {
 				if (range == RANGE_FLOAT)
diff --git a/src/gui/elems/ge_envelopeChannel.h b/src/gui/elems/ge_envelopeChannel.h
index 0bb7039..8afe11b 100644
--- a/src/gui/elems/ge_envelopeChannel.h
+++ b/src/gui/elems/ge_envelopeChannel.h
@@ -9,7 +9,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,14 +32,19 @@
 #ifndef __GE_ENVELOPECHANNEL_H__
 #define __GE_ENVELOPECHANNEL_H__
 
+
+#include <vector>
 #include <FL/Fl.H>
 #include <FL/Fl_Group.H>
 #include "../../utils/utils.h"
 #include "ge_actionWidget.h"
 
 
-class gEnvelopeChannel : public gActionWidget {
+using std::vector;
+
 
+class gEnvelopeChannel : public gActionWidget
+{
 	const char *l;      // internal label
 	int         type;   // type of action
 	int         range;
@@ -58,7 +63,7 @@ class gEnvelopeChannel : public gActionWidget {
 	/* points
 	 * array of points, filled by fillPoints() */
 
-	gVector<point> points;
+	vector<point> points;
 
 	/* selectedPoint
 	 * which point we are selecting? */
diff --git a/src/gui/elems/ge_keyboard.cpp b/src/gui/elems/ge_keyboard.cpp
index bf0e1bd..5d5fd37 100644
--- a/src/gui/elems/ge_keyboard.cpp
+++ b/src/gui/elems/ge_keyboard.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -112,7 +112,7 @@ void gKeyboard::freeChannel(gChannel *gch)
 
 void gKeyboard::deleteChannel(gChannel *gch)
 {
-	for (unsigned i=0; i<columns.size; i++) {
+	for (unsigned i=0; i<columns.size(); i++) {
 		int k = columns.at(i)->find(gch);
 		if (k != columns.at(i)->children()) {
 			columns.at(i)->deleteChannel(gch);
@@ -139,26 +139,26 @@ void gKeyboard::organizeColumns()
 	/* if only one column exists don't cleanup: the initial column must
 	 * stay here. */
 
-	if (columns.size == 1)
+	if (columns.size() == 1)
 		return;
 
 	/* otherwise delete all empty columns */
 	/** FIXME - this for loop might not work correctly! */
 
-	for (unsigned i=columns.size-1; i>=1; i--) {
+	for (unsigned i=columns.size()-1; i>=1; i--) {
 		if (columns.at(i)->isEmpty()) {
 			//Fl::delete_widget(columns.at(i));
 			delete columns.at(i);
-			columns.del(i);
+			columns.erase(columns.begin() + i);
 		}
 	}
 
 	/* compact column, avoid empty spaces */
 
-	for (unsigned i=1; i<columns.size; i++)
+	for (unsigned i=1; i<columns.size(); i++)
 		columns.at(i)->position(columns.at(i-1)->x() + columns.at(i-1)->w() + 16, y());
 
-	addColumnBtn->position(columns.last()->x() + columns.last()->w() + 16, y());
+	addColumnBtn->position(columns.back()->x() + columns.back()->w() + 16, y());
 
 	/* recompute col indexes */
 
@@ -189,7 +189,7 @@ gChannel *gKeyboard::addChannel(int colIndex, Channel *ch, bool build)
 
 	if (!col) {
 		__cb_addColumn();
-		col = columns.last();
+		col = columns.back();
 		col->setIndex(colIndex);
 		gLog("[gKeyboard::addChannel] created new column with index=%d\n", colIndex);
 	}
@@ -204,7 +204,7 @@ gChannel *gKeyboard::addChannel(int colIndex, Channel *ch, bool build)
 
 void gKeyboard::refreshColumns()
 {
-	for (unsigned i=0; i<columns.size; i++)
+	for (unsigned i=0; i<columns.size(); i++)
 		columns.at(i)->refreshChannels();
 }
 
@@ -214,7 +214,7 @@ void gKeyboard::refreshColumns()
 
 gColumn *gKeyboard::getColumnByIndex(int index)
 {
-	for (unsigned i=0; i<columns.size; i++)
+	for (unsigned i=0; i<columns.size(); i++)
 		if (columns.at(i)->getIndex() == index)
 			return columns.at(i);
 	return NULL;
@@ -280,7 +280,7 @@ int gKeyboard::handle(int e)
 			 * If found, set that button's value() based on up/down event,
 			 * and invoke that button's callback() */
 
-			for (unsigned i=0; i<columns.size; i++)
+			for (unsigned i=0; i<columns.size(); i++)
 				for (int k=1; k<columns.at(i)->children(); k++)
 					ret &= ((gChannel*)columns.at(i)->child(k))->keyPress(e);
 			break;
@@ -295,7 +295,7 @@ int gKeyboard::handle(int e)
 
 void gKeyboard::clear()
 {
-	for (unsigned i=0; i<columns.size; i++)
+	for (unsigned i=0; i<columns.size(); i++)
 		delete columns.at(i);
 	columns.clear();
 	indexColumn = 0;     // new columns will start from index=0
@@ -347,12 +347,12 @@ void gKeyboard::__cb_addColumn(int width)
 	int colx;
 	int colxw;
 	int gap = 16;
-	if (columns.size == 0) {
+	if (columns.size() == 0) {
 		colx  = x() - xposition();  // mind the offset with xposition()
 		colxw = colx + width;
 	}
 	else {
-		gColumn *prev = columns.last();
+		gColumn *prev = columns.back();
 		colx  = prev->x()+prev->w() + gap;
 		colxw = colx + width;
 	}
@@ -361,7 +361,7 @@ void gKeyboard::__cb_addColumn(int width)
 
 	gColumn *gc = new gColumn(colx, y(), width, 2000, indexColumn, this);
   add(gc);
-	columns.add(gc);
+	columns.push_back(gc);
 	indexColumn++;
 
 	/* move addColumn button */
@@ -370,7 +370,7 @@ void gKeyboard::__cb_addColumn(int width)
 	redraw();
 
 	gLog("[gKeyboard::__cb_addColumn] new column added (index=%d, w=%d), total count=%d, addColumn(x)=%d\n",
-		gc->getIndex(), width, columns.size, addColumnBtn->x());
+		gc->getIndex(), width, columns.size(), addColumnBtn->x());
 
 	/* recompute col indexes */
 
@@ -392,6 +392,6 @@ void gKeyboard::addColumn(int width)
 
 void gKeyboard::refreshColIndexes()
 {
-	for (unsigned i=0; i<columns.size; i++)
+	for (unsigned i=0; i<columns.size(); i++)
 		columns.at(i)->setIndex(i);
 }
diff --git a/src/gui/elems/ge_keyboard.h b/src/gui/elems/ge_keyboard.h
index 47575b1..967758c 100644
--- a/src/gui/elems/ge_keyboard.h
+++ b/src/gui/elems/ge_keyboard.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,11 +36,15 @@
 #include <FL/Fl_Group.H>
 #include <FL/Fl_Box.H>
 #include <FL/Fl_Menu_Button.H>
+#include <vector>
 #include "../elems/ge_column.h"
 #include "../../core/const.h"
 #include "../../utils/utils.h"
 
 
+using std::vector;
+
+
 class gKeyboard : public Fl_Scroll
 {
 private:
@@ -48,7 +52,7 @@ private:
 	/* refreshColIndexes
 	 * Recompute all column indexes in order to avoid any gaps between them.
 	 * Indexes must always be contiguous! */
-	 
+
 	void refreshColIndexes();
 
 	static void cb_addColumn  (Fl_Widget *v, void *p);
@@ -69,7 +73,7 @@ private:
 	/* columns
 	 * a vector of columns which in turn contain channels. */
 
-	gVector<gColumn*> columns;
+	vector<gColumn*> columns;
 
 public:
 
@@ -150,7 +154,7 @@ public:
 
 	/* getTotalColumns */
 
-	inline unsigned getTotalColumns() { return columns.size; }
+	inline unsigned getTotalColumns() { return columns.size(); }
 
 	/* getColumnWidth
 	 * return the width in pixel of i-th column. Warning: 'i' is the i-th column
diff --git a/src/gui/elems/ge_midiChannel.cpp b/src/gui/elems/ge_midiChannel.cpp
index 7a372ba..9d3850a 100644
--- a/src/gui/elems/ge_midiChannel.cpp
+++ b/src/gui/elems/ge_midiChannel.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,6 +36,7 @@
 #include "../../core/wave.h"
 #include "../../core/sampleChannel.h"
 #include "../../core/midiChannel.h"
+#include "../../glue/channel.h"
 #include "../../glue/glue.h"
 #include "../../utils/gui_utils.h"
 #include "../dialogs/gd_mainWindow.h"
@@ -185,7 +186,8 @@ void gMidiChannel::__cb_openMenu()
 		{"Setup keyboard input..."},                // 5
 		{"Setup MIDI input..."},                    // 6
 		{"Setup MIDI output..."},                   // 7
-		{"Delete channel"},                         // 8
+		{"Clone channel"},                          // 8
+		{"Delete channel"},                         // 9
 		{0}
 	};
 
@@ -210,6 +212,11 @@ void gMidiChannel::__cb_openMenu()
 		return;
 	}
 
+	if (strcmp(m->label(), "Clone channel") == 0) {
+		glue_cloneChannel(ch);
+		return;
+	}
+
 	if (strcmp(m->label(), "Setup keyboard input...") == 0) {
 		gu_openSubWindow(mainWin, new gdKeyGrabber(ch),	0);
 		//new gdKeyGrabber(ch);
@@ -282,7 +289,7 @@ void gMidiChannel::update()
 	mainButton->setKey(ch->key);
 
 #ifdef WITH_VST
-	fx->full = ch->plugins.size > 0;
+	fx->full = ch->plugins.size() > 0;
 #endif
 }
 
diff --git a/src/gui/elems/ge_midiChannel.h b/src/gui/elems/ge_midiChannel.h
index d08669d..ac1141a 100644
--- a/src/gui/elems/ge_midiChannel.h
+++ b/src/gui/elems/ge_midiChannel.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_midiIoTools.cpp b/src/gui/elems/ge_midiIoTools.cpp
index da9b873..9057f3f 100644
--- a/src/gui/elems/ge_midiIoTools.cpp
+++ b/src/gui/elems/ge_midiIoTools.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_midiIoTools.h b/src/gui/elems/ge_midiIoTools.h
index abec2df..2a795e1 100644
--- a/src/gui/elems/ge_midiIoTools.h
+++ b/src/gui/elems/ge_midiIoTools.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_mixed.cpp b/src/gui/elems/ge_mixed.cpp
index ef166a6..d6d3399 100644
--- a/src/gui/elems/ge_mixed.cpp
+++ b/src/gui/elems/ge_mixed.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -205,7 +205,7 @@ void gCheck::draw()
 
   fl_rectf(x()+20, y(), w(), h(), FL_BACKGROUND_COLOR);  // clearer
   fl_font(FL_HELVETICA, 11);
-  fl_color(COLOR_TEXT_0);
+  fl_color(!active() ? FL_INACTIVE_COLOR : COLOR_TEXT_0);
   fl_draw(label(), x()+20, y(), w(), h(), (Fl_Align) (FL_ALIGN_LEFT | FL_ALIGN_TOP));
 }
 
@@ -255,7 +255,6 @@ gSoundMeter::gSoundMeter(int x, int y, int w, int h, const char *L)
     clip(false),
     mixerPeak(0.0f),
     peak(0.0f),
-    peak_old(0.0f),
     db_level(0.0f),
     db_level_old(0.0f) {}
 
diff --git a/src/gui/elems/ge_mixed.h b/src/gui/elems/ge_mixed.h
index 26942d5..b41be44 100644
--- a/src/gui/elems/ge_mixed.h
+++ b/src/gui/elems/ge_mixed.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -205,7 +205,6 @@ public:
 	float mixerPeak;	// peak from mixer
 private:
 	float peak;
-	float peak_old;
 	float db_level;
 	float db_level_old;
 };
@@ -232,7 +231,7 @@ public:
 	gChoice(int X,int Y,int W,int H,const char *L=0, bool angle=true);
 	void draw();
 
-	inline void show(const char *c) {value(find_index(c)); }
+	inline void showItem(const char *c) {value(find_index(c)); }
 
 	bool angle;
 	int  id;
diff --git a/src/gui/elems/ge_modeBox.cpp b/src/gui/elems/ge_modeBox.cpp
index a4c13f5..299aee1 100644
--- a/src/gui/elems/ge_modeBox.cpp
+++ b/src/gui/elems/ge_modeBox.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_modeBox.h b/src/gui/elems/ge_modeBox.h
index f6c661b..2e82cd3 100644
--- a/src/gui/elems/ge_modeBox.h
+++ b/src/gui/elems/ge_modeBox.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_muteChannel.cpp b/src/gui/elems/ge_muteChannel.cpp
index 96f8cc8..7b996b8 100644
--- a/src/gui/elems/ge_muteChannel.cpp
+++ b/src/gui/elems/ge_muteChannel.cpp
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -82,7 +82,7 @@ void gMuteChannel::draw() {
 	int py    = y()+h()-5;
 	int pyDot = py-6;
 
-	for (unsigned i=0; i<points.size; i++) {
+	for (unsigned i=0; i<points.size(); i++) {
 
 		/* next px */
 
@@ -126,15 +126,15 @@ void gMuteChannel::extractPoints() {
 
 	/* actions are already sorted by recorder::sortActions() */
 
-	for (unsigned i=0; i<recorder::frames.size; i++) {
-		for (unsigned j=0; j<recorder::global.at(i).size; j++) {
+	for (unsigned i=0; i<recorder::frames.size(); i++) {
+		for (unsigned j=0; j<recorder::global.at(i).size(); j++) {
 			if (recorder::global.at(i).at(j)->chan == pParent->chan->index) {
 				if (recorder::global.at(i).at(j)->type & (ACTION_MUTEON | ACTION_MUTEOFF)) {
 					point p;
 					p.frame = recorder::frames.at(i);
 					p.type  = recorder::global.at(i).at(j)->type;
 					p.x     = p.frame / pParent->zoom;
-					points.add(p);
+					points.push_back(p);
 					//gLog("[gMuteChannel::extractPoints] point found, type=%d, frame=%d\n", p.type, p.frame);
 				}
 			}
@@ -147,7 +147,7 @@ void gMuteChannel::extractPoints() {
 
 
 void gMuteChannel::updateActions() {
-	for (unsigned i=0; i<points.size; i++)
+	for (unsigned i=0; i<points.size(); i++)
 		points.at(i).x = points.at(i).frame / pParent->zoom;
 }
 
@@ -207,8 +207,8 @@ int gMuteChannel::handle(int e) {
 					 * must be added in reverse: first mute_off then mute_on. Let's find the
 					 * next point from here. */
 
-					unsigned nextPoint = points.size;
-					for (unsigned i=0; i<points.size; i++) {
+					unsigned nextPoint = points.size();
+					for (unsigned i=0; i<points.size(); i++) {
 						if (mouseX < points.at(i).x) {
 							nextPoint = i;
 							break;
@@ -346,7 +346,7 @@ int gMuteChannel::handle(int e) {
 						nextPoint -= pParent->gridTool->getCellSize();
 				}
 				else
-				if ((unsigned) draggedPoint == points.size-1) {
+				if ((unsigned) draggedPoint == points.size()-1) {
 					prevPoint = points.at(draggedPoint-1).x + 1;
 					nextPoint = pParent->coverX-x();
 					if (pParent->gridTool->isOn())
@@ -388,7 +388,7 @@ int gMuteChannel::handle(int e) {
 
 
 bool gMuteChannel::pointCollides(int frame) {
-	for (unsigned i=0; i<points.size; i++)
+	for (unsigned i=0; i<points.size(); i++)
 		if (frame == points.at(i).frame)
 			return true;
 	return false;
@@ -402,7 +402,7 @@ int gMuteChannel::getSelectedPoint() {
 
 	/* point is a 7x7 dot */
 
-	for (unsigned i=0; i<points.size; i++) {
+	for (unsigned i=0; i<points.size(); i++) {
 		if (Fl::event_x() >= points.at(i).x+x()-3 &&
 				Fl::event_x() <= points.at(i).x+x()+3)
 		return i;
diff --git a/src/gui/elems/ge_muteChannel.h b/src/gui/elems/ge_muteChannel.h
index e1835cb..2e74453 100644
--- a/src/gui/elems/ge_muteChannel.h
+++ b/src/gui/elems/ge_muteChannel.h
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,6 +31,8 @@
 #ifndef GE_MUTECHANNEL_H
 #define GE_MUTECHANNEL_H
 
+
+#include <vector>
 #include <FL/Fl.H>
 #include <FL/Fl_Widget.H>
 #include <FL/fl_draw.H>
@@ -38,8 +40,11 @@
 #include "ge_actionWidget.h"
 
 
-class gMuteChannel : public gActionWidget {
+using std::vector;
+
 
+class gMuteChannel : public gActionWidget
+{
 private:
 
 	/* point
@@ -54,7 +59,7 @@ private:
 	/* points
 	 * array of on/off points, in frames */
 
-	gVector<point> points;
+	vector<point> points;
 
 	/* draggedPoint
 	 * which point we are dragging? */
@@ -73,7 +78,7 @@ private:
 
 	/* extractPoints
 	 * va a leggere l'array di azioni di Recorder ed estrae tutti i punti
-	 * interessanti mute_on o mute_off. Li mette poi nel gVector points. */
+	 * interessanti mute_on o mute_off. Li mette poi nel vector points. */
 	void extractPoints();
 
 	/* getSelectedPoint
diff --git a/src/gui/elems/ge_pianoRoll.cpp b/src/gui/elems/ge_pianoRoll.cpp
index c10e653..bd3dd5b 100644
--- a/src/gui/elems/ge_pianoRoll.cpp
+++ b/src/gui/elems/ge_pianoRoll.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -120,8 +120,8 @@ gPianoRoll::gPianoRoll(int X, int Y, int W, class gdActionEditor *pParent)
 	recorder::action *a2   = NULL;
 	recorder::action *prev = NULL;
 
-	for (unsigned i=0; i<recorder::frames.size; i++) {
-		for (unsigned j=0; j<recorder::global.at(i).size; j++) {
+	for (unsigned i=0; i<recorder::frames.size(); i++) {
+		for (unsigned j=0; j<recorder::global.at(i).size(); j++) {
 
 			/* don't show actions > than the grey area */
 			/** FIXME - can we move this to the outer cycle? */
@@ -461,10 +461,10 @@ bool gPianoRoll::onItem(int rel_x, int rel_y) {
 /* ------------------------------------------------------------------ */
 
 
-gPianoItem::gPianoItem(int X, int Y, int rel_x, int rel_y, recorder::action *a, recorder::action *b, gdActionEditor *pParent)
+gPianoItem::gPianoItem(int X, int Y, int rel_x, int rel_y, recorder::action *_a, recorder::action *_b, gdActionEditor *pParent)
 	: Fl_Box  (X, Y, 20, gPianoRoll::CELL_H-5),
-	  a       (a),
-	  b       (b),
+	  a       (_a),
+	  b       (_b),
 		pParent (pParent),
 		selected(false),
 		event_a (0x00),
diff --git a/src/gui/elems/ge_pianoRoll.h b/src/gui/elems/ge_pianoRoll.h
index aad0618..509fd32 100644
--- a/src/gui/elems/ge_pianoRoll.h
+++ b/src/gui/elems/ge_pianoRoll.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_sampleChannel.cpp b/src/gui/elems/ge_sampleChannel.cpp
index a68f3df..23a0646 100644
--- a/src/gui/elems/ge_sampleChannel.cpp
+++ b/src/gui/elems/ge_sampleChannel.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -37,6 +37,7 @@
 #include "../../core/sampleChannel.h"
 #include "../../core/midiChannel.h"
 #include "../../glue/glue.h"
+#include "../../glue/channel.h"
 #include "../../utils/gui_utils.h"
 #include "../dialogs/gd_mainWindow.h"
 #include "../dialogs/gd_keyGrabber.h"
@@ -208,15 +209,16 @@ void gSampleChannel::__cb_openMenu()
 			{"Volume"},                               // 10
 			{"Start/Stop"},                           // 11
 			{0},                                      // 12
-		{"Free channel"},                           // 13
-		{"Delete channel"},                         // 14
+			{"Clone channel"},                        // 13
+		{"Free channel"},                           // 14
+		{"Delete channel"},                         // 15
 		{0}
 	};
 
 	if (ch->status & (STATUS_EMPTY | STATUS_MISSING)) {
 		rclick_menu[1].deactivate();
 		rclick_menu[5].deactivate();
-		rclick_menu[13].deactivate();
+		rclick_menu[14].deactivate();
 	}
 
 	/* no 'clear actions' if there are no actions */
@@ -298,6 +300,11 @@ void gSampleChannel::__cb_openMenu()
 		return;
 	}
 
+	if (strcmp(m->label(), "Clone channel") == 0) {
+		glue_cloneChannel(ch);
+		return;
+	}
+
 	if (strcmp(m->label(), "Mute") == 0) {
 		if (!gdConfirmWin("Warning", "Clear all mute actions: are you sure?"))
 			return;
@@ -373,7 +380,7 @@ void gSampleChannel::openBrowser(int type)
 			title = "Edit Sample";
 			break;
 	}
-	gWindow *childWin = new gdBrowser(title, G_Conf.samplePath, ch, type);
+	gWindow *childWin = new gdBrowser(title, G_Conf.samplePath.c_str(), ch, type);
 	gu_openSubWindow(mainWin, childWin,	WID_FILE_BROWSER);
 }
 
@@ -456,7 +463,7 @@ void gSampleChannel::update()
 	mainButton->setKey(ch->key);
 
 #ifdef WITH_VST
-	fx->full = ch->plugins.size > 0;
+	fx->full = ch->plugins.size() > 0;
 	fx->redraw();
 #endif
 }
diff --git a/src/gui/elems/ge_sampleChannel.h b/src/gui/elems/ge_sampleChannel.h
index 9ba701a..db5beb2 100644
--- a/src/gui/elems/ge_sampleChannel.h
+++ b/src/gui/elems/ge_sampleChannel.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_status.cpp b/src/gui/elems/ge_status.cpp
index 564b9ab..8acaf0f 100644
--- a/src/gui/elems/ge_status.cpp
+++ b/src/gui/elems/ge_status.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_status.h b/src/gui/elems/ge_status.h
index 07e9b28..e75d919 100644
--- a/src/gui/elems/ge_status.h
+++ b/src/gui/elems/ge_status.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_waveTools.cpp b/src/gui/elems/ge_waveTools.cpp
index d7712c1..49f9735 100644
--- a/src/gui/elems/ge_waveTools.cpp
+++ b/src/gui/elems/ge_waveTools.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_waveTools.h b/src/gui/elems/ge_waveTools.h
index 51cbc65..051dca2 100644
--- a/src/gui/elems/ge_waveTools.h
+++ b/src/gui/elems/ge_waveTools.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/ge_waveform.cpp b/src/gui/elems/ge_waveform.cpp
index 52cf539..2bac3e6 100644
--- a/src/gui/elems/ge_waveform.cpp
+++ b/src/gui/elems/ge_waveform.cpp
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -68,7 +68,7 @@ gWaveform::gWaveform(int x, int y, int w, int h, class SampleChannel *ch, const
 
   grid.snap  = G_Conf.sampleEditorGridOn;
   grid.level = G_Conf.sampleEditorGridVal;
-  
+
   stretchToWindow();
 }
 
@@ -76,7 +76,7 @@ gWaveform::gWaveform(int x, int y, int w, int h, class SampleChannel *ch, const
 /* ------------------------------------------------------------------ */
 
 
-gWaveform::~gWaveform() 
+gWaveform::~gWaveform()
 {
   freeData();
 }
@@ -85,7 +85,7 @@ gWaveform::~gWaveform()
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::freeData() 
+void gWaveform::freeData()
 {
   if (data.sup != NULL) {
     free(data.sup);
@@ -122,7 +122,7 @@ int gWaveform::alloc(int datasize)
 
   int gridFreq = 0;
   if (grid.level != 0) {
-    gridFreq = chan->wave->size / grid.level; 
+    gridFreq = chan->wave->size / grid.level;
     if (gridFreq % 2 != 0)
       gridFreq--;
   }
@@ -164,8 +164,8 @@ int gWaveform::alloc(int datasize)
 
       if (gridFreq != 0)
         if (k % gridFreq == 0 && k != 0)
-          grid.points.add(i);
-      
+          grid.points.push_back(i);
+
       k += 2;
     }
 
@@ -186,7 +186,7 @@ int gWaveform::alloc(int datasize)
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::recalcPoints() 
+void gWaveform::recalcPoints()
 {
   selectionA = relativePoint(selectionA_abs);
   selectionB = relativePoint(selectionB_abs);
@@ -205,7 +205,7 @@ void gWaveform::recalcPoints()
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::draw() 
+void gWaveform::draw()
 {
   /* blank canvas */
 
@@ -245,10 +245,10 @@ void gWaveform::draw()
   for (int i=wx1; i<wx2; i++) {
     fl_line(i+x(), zero, i+x(), data.sup[i]);
     fl_line(i+x(), zero, i+x(), data.inf[i]);
-    
+
     /* print grid */
 
-    for (unsigned k=0; k<grid.points.size; k++) {
+    for (unsigned k=0; k<grid.points.size(); k++) {
       if (grid.points.at(k) == i) {
         //gLog("draw grid line at %d\n", i);
         fl_color(fl_rgb_color(54, 54, 54));
@@ -307,7 +307,7 @@ void gWaveform::draw()
 /* ------------------------------------------------------------------ */
 
 
-int gWaveform::handle(int e) 
+int gWaveform::handle(int e)
 {
   int ret = 0;
 
@@ -433,8 +433,8 @@ int gWaveform::handle(int e)
       if (chanStartLit && pushed) {
 
         chanStart = Fl::event_x() - x();
-      
-        if (grid.snap) 
+
+        if (grid.snap)
           chanStart = applySnap(chanStart);
 
         if (chanStart < 0)
@@ -442,7 +442,7 @@ int gWaveform::handle(int e)
         else
         if (chanStart >= chanEnd)
           chanStart = chanEnd-2;
-        
+
         redraw();
       }
       else
@@ -450,7 +450,7 @@ int gWaveform::handle(int e)
 
         chanEnd = Fl::event_x() - x();
 
-        if (grid.snap) 
+        if (grid.snap)
           chanEnd = applySnap(chanEnd);
 
         if (chanEnd >= data.size - 2)
@@ -474,7 +474,7 @@ int gWaveform::handle(int e)
 
         if (selectionB <= 0)
           selectionB = 0;
-       
+
         if (grid.snap)
           selectionB = applySnap(selectionB);
 
@@ -483,7 +483,7 @@ int gWaveform::handle(int e)
       }
 
       /* here the mouse is on a selection boundary i.e. resize */
-      
+
       else
       if (resized) {
         int pos = Fl::event_x() - x();
@@ -509,13 +509,13 @@ int gWaveform::handle(int e)
 
 /* ------------------------------------------------------------------ */
 
-/* pixel snap disances (10px) must be equal to those defined in 
+/* pixel snap disances (10px) must be equal to those defined in
  * gWaveform::mouseOnSelectionA() and gWaverfrom::mouseOnSelectionB() */
 /* TODO - use constant for 10px */
 
 int gWaveform::applySnap(int pos)
 {
-  for (unsigned i=0; i<grid.points.size; i++) {
+  for (unsigned i=0; i<grid.points.size(); i++) {
     if (pos >= grid.points.at(i) - 10 &&
         pos <= grid.points.at(i) + 10)
     {
@@ -529,7 +529,7 @@ int gWaveform::applySnap(int pos)
 /* ------------------------------------------------------------------ */
 
 
-bool gWaveform::mouseOnStart() 
+bool gWaveform::mouseOnStart()
 {
   return mouseX-10 >  chanStart + x() - BORDER              &&
          mouseX-10 <= chanStart + x() - BORDER + FLAG_WIDTH &&
@@ -540,7 +540,7 @@ bool gWaveform::mouseOnStart()
 /* ------------------------------------------------------------------ */
 
 
-bool gWaveform::mouseOnEnd() 
+bool gWaveform::mouseOnEnd()
 {
   return mouseX-10 >= chanEnd + x() - BORDER - FLAG_WIDTH &&
          mouseX-10 <= chanEnd + x() - BORDER              &&
@@ -553,7 +553,7 @@ bool gWaveform::mouseOnEnd()
 /* pixel boundaries (10px) must be equal to the snap factor distance
  * defined in gWaveform::applySnap() */
 
-bool gWaveform::mouseOnSelectionA() 
+bool gWaveform::mouseOnSelectionA()
 {
   if (selectionA == selectionB)
     return false;
@@ -561,7 +561,7 @@ bool gWaveform::mouseOnSelectionA()
 }
 
 
-bool gWaveform::mouseOnSelectionB() 
+bool gWaveform::mouseOnSelectionB()
 {
   if (selectionA == selectionB)
     return false;
@@ -572,7 +572,7 @@ bool gWaveform::mouseOnSelectionB()
 /* ------------------------------------------------------------------ */
 
 
-int gWaveform::absolutePoint(int p) 
+int gWaveform::absolutePoint(int p)
 {
   if (p <= 0)
     return 0;
@@ -587,7 +587,7 @@ int gWaveform::absolutePoint(int p)
 /* ------------------------------------------------------------------ */
 
 
-int gWaveform::relativePoint(int p) 
+int gWaveform::relativePoint(int p)
 {
   return (ceilf(p / ratio)) * 2;
 }
@@ -596,7 +596,7 @@ int gWaveform::relativePoint(int p)
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::openEditMenu() 
+void gWaveform::openEditMenu()
 {
   if (selectionA == selectionB)
     return;
@@ -745,7 +745,7 @@ void gWaveform::openEditMenu()
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::straightSel() 
+void gWaveform::straightSel()
 {
   if (selectionA > selectionB) {
     unsigned tmp = selectionB;
@@ -758,7 +758,7 @@ void gWaveform::straightSel()
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::setZoom(int type) 
+void gWaveform::setZoom(int type)
 {
   int newSize;
   if (type == -1) newSize = data.size*2;  // zoom in
@@ -808,7 +808,7 @@ void gWaveform::setZoom(int type)
 /* ------------------------------------------------------------------ */
 
 
-void gWaveform::stretchToWindow() 
+void gWaveform::stretchToWindow()
 {
   int s = ((gWaveTools*)parent())->w();
   alloc(s);
@@ -820,7 +820,7 @@ void gWaveform::stretchToWindow()
 /* ------------------------------------------------------------------ */
 
 
-bool gWaveform::smaller() 
+bool gWaveform::smaller()
 {
   return w() < ((gWaveTools*)parent())->w();
 }
@@ -831,7 +831,7 @@ bool gWaveform::smaller()
 
 void gWaveform::setGridLevel(int l)
 {
-  grid.points.clear();  
+  grid.points.clear();
   grid.level = l;
   alloc(data.size);
   redraw();
diff --git a/src/gui/elems/ge_waveform.h b/src/gui/elems/ge_waveform.h
index 45abd5b..143464a 100644
--- a/src/gui/elems/ge_waveform.h
+++ b/src/gui/elems/ge_waveform.h
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,6 +31,8 @@
 #ifndef GE_WAVEFORM_H
 #define GE_WAVEFORM_H
 
+
+#include <vector>
 #include <FL/Fl.H>
 #include <FL/Fl_Widget.H>
 #include <FL/fl_draw.H>
@@ -38,6 +40,9 @@
 #include "../../utils/utils.h"
 
 
+using std::vector;
+
+
 #define  FLAG_WIDTH  14
 #define  FLAG_HEIGHT 12
 #define  BORDER      8				// window border <-> widget border
@@ -49,7 +54,7 @@ private:
 
 	/* data
 	 * real graphic stuff from the underlying waveform */
-	
+
 	struct data {
 		int *sup;
 		int *inf;
@@ -61,7 +66,7 @@ private:
 	struct grid {
 		bool snap;
 		int  level;
-		gVector<int> points;
+		vector<int> points;
 	} grid;
 
 	/* chan
@@ -138,7 +143,7 @@ public:
 
 	/* openEditMenu
 	 * show edit menu on right-click */
-	
+
 	void openEditMenu();
 
 	/* displayRatio
@@ -155,7 +160,7 @@ public:
 	 * shrink or enlarge the waveform to match parent's width (gWaveTools) */
 
 	void stretchToWindow();
-	
+
 	/* setGridLevel
 	 * set a new frequency level for the grid. 0 means disabled. */
 
@@ -163,7 +168,7 @@ public:
 
   inline void setSnap(bool v) { grid.snap = v; }
   inline bool getSnap()       { return grid.snap; }
-    
+
 	inline int getSize() { return data.size; }
 
 	int  chanStart;
@@ -175,7 +180,7 @@ public:
 	bool resized;
 
 	float ratio;
-  
+
   /* TODO - useless! use Fl::mouse_x() and Fl::mouse_y() instead */
 	int  mouseX;					 // mouse pos for drag.n.drop
 	int  mouseY;
diff --git a/src/gui/elems/ge_window.cpp b/src/gui/elems/ge_window.cpp
index 5d4763b..30c26cb 100644
--- a/src/gui/elems/ge_window.cpp
+++ b/src/gui/elems/ge_window.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -49,7 +49,7 @@ gWindow::~gWindow() {
 
 	/* delete all subwindows in order to empty the stack */
 
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		delete subWindows.at(i);
 	subWindows.clear();
 }
@@ -73,7 +73,7 @@ void gWindow::cb_closeChild(Fl_Widget *v, void *p) {
 void gWindow::addSubWindow(gWindow *w) {
 
 	/** TODO - useless: delete ---------------------------------------- */
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		if (w->getId() == subWindows.at(i)->getId()) {
 			//gLog("[gWindow] window %p (id=%d) exists, not added (and deleted)\n", (void*)w, w->getId());
 			delete w;
@@ -83,7 +83,7 @@ void gWindow::addSubWindow(gWindow *w) {
 
 	w->setParent(this);
 	w->callback(cb_closeChild); // you can pass params: w->callback(cb_closeChild, (void*)params)
-	subWindows.add(w);
+	subWindows.push_back(w);
 	//debug();
 }
 
@@ -92,10 +92,10 @@ void gWindow::addSubWindow(gWindow *w) {
 
 
 void gWindow::delSubWindow(gWindow *w) {
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		if (w->getId() == subWindows.at(i)->getId()) {
 			delete subWindows.at(i);
-			subWindows.del(i);
+			subWindows.erase(subWindows.begin() + i);
 			//debug();
 			return;
 		}
@@ -107,10 +107,10 @@ void gWindow::delSubWindow(gWindow *w) {
 
 
 void gWindow::delSubWindow(int id) {
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		if (subWindows.at(i)->getId() == id) {
 			delete subWindows.at(i);
-			subWindows.del(i);
+			subWindows.erase(subWindows.begin() + i);
 			//debug();
 			return;
 		}
@@ -139,7 +139,7 @@ void gWindow::setId(int id) {
 
 void gWindow::debug() {
 	gLog("---- window stack (id=%d): ----\n", getId());
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		gLog("[gWindow] %p (id=%d)\n", (void*)subWindows.at(i), subWindows.at(i)->getId());
 	gLog("----\n");
 }
@@ -165,7 +165,7 @@ void gWindow::setParent(gWindow *w) {
 
 
 bool gWindow::hasWindow(int id) {
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		if (id == subWindows.at(i)->getId())
 			return true;
 	return false;
@@ -176,7 +176,7 @@ bool gWindow::hasWindow(int id) {
 
 
 gWindow *gWindow::getChild(int id) {
-	for (unsigned i=0; i<subWindows.size; i++)
+	for (unsigned i=0; i<subWindows.size(); i++)
 		if (id == subWindows.at(i)->getId())
 			return subWindows.at(i);
 	return NULL;
diff --git a/src/gui/elems/ge_window.h b/src/gui/elems/ge_window.h
index 74b5254..4991b0f 100644
--- a/src/gui/elems/ge_window.h
+++ b/src/gui/elems/ge_window.h
@@ -7,7 +7,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,14 +32,18 @@
 #define __GE_WINDOW_H__
 
 
+#include <vector>
 #include <FL/Fl_Double_Window.H>
 #include "../../utils/utils.h"
 
 
+using std::vector;
+
+
 class gWindow : public Fl_Double_Window {
 
 protected:
-	gVector <gWindow *> subWindows;
+	vector <gWindow *> subWindows;
 	int id;
 	gWindow *parent;
 
diff --git a/src/main.cpp b/src/main.cpp
index d7829df..2b8480d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/utils/gui_utils.cpp b/src/utils/gui_utils.cpp
index 872aee5..3480cda 100644
--- a/src/utils/gui_utils.cpp
+++ b/src/utils/gui_utils.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -98,15 +98,15 @@ int gu_getBlinker()
 
 void gu_updateControls()
 {
-	for (unsigned i=0; i<G_Mixer.channels.size; i++) {
+	for (unsigned i=0; i<G_Mixer.channels.size(); i++) {
 		G_Mixer.channels.at(i)->guiChannel->update();
 	}
 
 	mainWin->inOut->setOutVol(G_Mixer.outVol);
 	mainWin->inOut->setInVol(G_Mixer.inVol);
 #ifdef WITH_VST
-	mainWin->inOut->setMasterFxOutFull(G_PluginHost.masterOut.size > 0);
-	mainWin->inOut->setMasterFxInFull(G_PluginHost.masterIn.size > 0);
+	mainWin->inOut->setMasterFxOutFull(G_PluginHost.masterOut.size() > 0);
+	mainWin->inOut->setMasterFxInFull(G_PluginHost.masterIn.size() > 0);
 #endif
 
 	mainWin->timing->setMeter(G_Mixer.beats, G_Mixer.bars);
@@ -209,3 +209,16 @@ void gu_closeAllSubwindows()
 	mainWin->delSubWindow(WID_FX_LIST);
 	mainWin->delSubWindow(WID_FX);
 }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+string gu_removeFltkChars(const string &s)
+{
+	string out = gReplace(s, "/", "-");
+	out = gReplace(out, "|", "-");
+	out = gReplace(out, "&", "-");
+	out = gReplace(out, "_", "-");
+	return out;
+}
diff --git a/src/utils/gui_utils.h b/src/utils/gui_utils.h
index 66156ce..605b196 100644
--- a/src/utils/gui_utils.h
+++ b/src/utils/gui_utils.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -46,6 +46,9 @@
 #endif
 
 
+using std::string;
+
+
 /* refresh
  * refresh all GUI elements. */
 
@@ -90,4 +93,9 @@ void gu_closeAllSubwindows();
 
 gWindow *gu_getSubwindow(class gWindow *parent, int id);
 
+/* removeFltkChars
+ * Strip special chars used by FLTK to split menus into sub-menus. */
+
+string gu_removeFltkChars(const string &s);
+
 #endif
diff --git a/src/utils/gvector.h b/src/utils/gvector.h
deleted file mode 100644
index e36ef90..0000000
--- a/src/utils/gvector.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * gvector
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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 3 of the License, or (at your option) any later version.
- *
- * Giada - Your Hardcore Loopmachine is distributed in the hope that it
- * will be useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GVECTOR_H
-#define GVECTOR_H
-
-
-#include "log.h"
-
-
-/* gVector
- * lightweight template class. */
-
-template <class T> class gVector
-{
-public:
-
-	/* gVector()
-	 * default constructor, no parameters */
-
-	gVector() : size(0), s(NULL) {}
-
-	/* gVector(const &)
-	 * copy-constructor, when gVector a = b (where b is another gVector).
-	 * Default constructor doesn't copy referenced objects, so we need
-	 * to re-allocate the internal stack for the copied object */
-
-	gVector(const gVector &other)
-	{
-		s = new T[other.size];
-		for (unsigned i=0; i<other.size; i++)
-			s[i] = other.s[i];
-		size = other.size;
-	}
-
-
-	~gVector()
-	{
-		/// FIXME empty s with clear()?!?
-	}
-
-
-	void add(const T &item)
-	{
-		T *tmp = new T[size+1];  /// TODO: chunk increment (size+N), N ~= 16
-		for (unsigned i=0; i<size; i++)
-			tmp[i] = s[i];
-		tmp[size] = item;
-		delete[] s;
-		s = tmp;
-		size++;
-	}
-
-
-	int del(const T &item)
-	{
-		for (unsigned i=0; i<size; i++)
-			if (s[i] == item)
-				return del(i);
-		return -1;
-	}
-
-
-	int del(unsigned p)
-	{
-		if (p > size-1) gLog("[vector] del() outside! requested=%d, size=%d\n", p, size);
-		T *tmp = new T[size-1];
-		unsigned i=0;
-		unsigned j=0;
-		while (i<size) {
-			if (i != p) {
-				tmp[j] = s[i];
-				j++;
-			}
-			i++;
-		}
-		delete[] s;
-		s = tmp;
-		size -= 1;
-		return size;
-	}
-
-
-	void clear()
-	{
-		if (size > 0) {
-			delete [] s;
-			s = NULL;
-			size = 0;
-		}
-	}
-
-
-	void swap(unsigned x, unsigned y)
-	{
-		T tmp = s[x];
-		s[x] = s[y];
-		s[y] = tmp;
-	}
-
-
-	T &at(unsigned p)
-	{
-		if (p > size-1)	gLog("[vector] at() outside! requested=%d, size=%d\n", p, size);
-		return s[p];
-	}
-
-
-	T &last()
-	{
-		return s[size-1];
-	}
-
-
-	unsigned size;
-	T *s;  				// stack (array of T)
-};
-
-
-#endif
diff --git a/src/utils/log.cpp b/src/utils/log.cpp
index 9b2182d..0834d63 100644
--- a/src/utils/log.cpp
+++ b/src/utils/log.cpp
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/utils/log.h b/src/utils/log.h
index c53f9c7..285a7d6 100644
--- a/src/utils/log.h
+++ b/src/utils/log.h
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index a45199d..1f7a117 100644
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -51,6 +51,7 @@
 
 
 using std::string;
+using std::vector;
 
 
 bool gFileExists(const char *filename) {
@@ -122,6 +123,12 @@ bool gDirExists(const char *path)
 }
 
 
+bool gDirExists(const string &path)
+{
+	return gDirExists(path.c_str());
+}
+
+
 /* -------------------------------------------------------------------------- */
 
 
@@ -137,6 +144,12 @@ bool gMkdir(const char *path)
 }
 
 
+bool gMkdir(const string &path)
+{
+	return gMkdir(path.c_str());
+}
+
+
 /* -------------------------------------------------------------------------- */
 
 /* TODO - avoid this shit, just wrap the other call */
@@ -377,7 +390,7 @@ string gGetHomePath()
 /* -------------------------------------------------------------------------- */
 
 
-void gSplit(string in, string sep, gVector<string> *v)
+void gSplit(string in, string sep, vector<string> *v)
 {
 	string full  = in;
 	string token = "";
@@ -388,7 +401,7 @@ void gSplit(string in, string sep, gVector<string> *v)
 	  next  = full.find_first_of(sep, curr);
 		token = full.substr(curr, next - curr);
 		if (token != "")
-			v->add(token);
+			v->push_back(token);
 	}
 	while (next != string::npos);
 }
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 6316577..c8da493 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2015 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -33,16 +33,18 @@
 
 #include <string>
 #include <cstdio>
+#include <vector>
 #include "log.h"
-#include "gvector.h"
 
 
 using std::string;
+using std::vector;
 
 
 bool gFileExists(const char *path);
 
 bool gDirExists(const char *path);
+bool gDirExists(const string &path);
 
 bool gIsDir(const char *path);
 
@@ -51,6 +53,7 @@ bool gIsProject(const char *path);
 bool gIsPatch(const char *path);
 
 bool gMkdir(const char *path);
+bool gMkdir(const string &path);
 
 string gBasename(const char *path);
 string gBasename(const string &s);
@@ -79,6 +82,6 @@ string gGetSlash();
 
 string gItoa(int i);
 
-void gSplit(string in, string sep, gVector<string> *v);
+void gSplit(string in, string sep, vector<string> *v);
 
 #endif
diff --git a/tests/conf.cpp b/tests/conf.cpp
index 098ee09..ce575fc 100644
--- a/tests/conf.cpp
+++ b/tests/conf.cpp
@@ -1,13 +1,161 @@
+#include "../src/core/const.h"
 #include "../src/core/conf.h"
 #include "catch.hpp"
 
 
-Conf c;
-  
-TEST_CASE("Write conf file") 
+using std::string;
+
+
+TEST_CASE("Test Conf class")
 {
-  c.setDefault();
-  REQUIRE(c.write() == 1);
-  REQUIRE(c.read() == 1);
-}
+  Conf conf;
 
+  SECTION("test write")
+  {
+    conf.header = "GIADACONFTEST";
+    conf.logMode = 1;
+    conf.soundSystem = 2;
+    conf.soundDeviceOut = 3;
+    conf.soundDeviceIn = 4;
+    conf.channelsOut = 5;
+    conf.channelsIn = 6;
+    conf.samplerate = 7;
+    conf.buffersize = 8;
+    conf.delayComp = 9;
+    conf.limitOutput = true;
+    conf.rsmpQuality = 10;
+    conf.midiSystem = 11;
+    conf.midiPortOut = 12;
+    conf.midiPortIn = 13;
+    conf.noNoteOff = false;
+    conf.midiMapPath = "path/to/midi/map";
+    conf.lastFileMap = "path/to/last/midi/map";
+    conf.midiSync = 14;
+    conf.midiTCfps = 15.1f;
+    conf.midiInRewind = 16;
+    conf.midiInStartStop = 17;
+    conf.midiInActionRec = 18;
+    conf.midiInInputRec = 19;
+    conf.midiInMetronome = 20;
+    conf.midiInVolumeIn = 21;
+    conf.midiInVolumeOut = 22;
+    conf.midiInBeatDouble = 23;
+    conf.midiInBeatHalf = 24;
+    conf.recsStopOnChanHalt = true;
+    conf.chansStopOnSeqHalt = false;
+    conf.treatRecsAsLoops = true;
+    conf.resizeRecordings = false;
+    conf.pluginPath = "path/to/plugins";
+    conf.patchPath = "path/to/patches";
+    conf.samplePath = "path/to/samples";
+    conf.mainWindowX = 0;
+    conf.mainWindowY = 0;
+    conf.mainWindowW = 800;
+    conf.mainWindowH = 600;
+    conf.browserX = 0;
+    conf.browserY = 0;
+    conf.browserW = 800;
+    conf.browserH = 600;
+    conf.actionEditorX = 0;
+    conf.actionEditorY = 0;
+    conf.actionEditorW = 800;
+    conf.actionEditorH = 600;
+    conf.actionEditorZoom = 1;
+    conf.actionEditorGridVal = 10;
+    conf.actionEditorGridOn = 1;
+    conf.sampleEditorX = 0;
+    conf.sampleEditorY = 0;
+    conf.sampleEditorW = 800;
+    conf.sampleEditorH = 600;
+    conf.sampleEditorGridVal = 4;
+    conf.sampleEditorGridOn = 0;
+    conf.pianoRollY = 0;
+    conf.pianoRollH = 900;
+    conf.pluginListX = 0;
+    conf.pluginListY = 50;
+    conf.configX = 20;
+    conf.configY = 20;
+    conf.bpmX = 30;
+    conf.bpmY = 36;
+    conf.beatsX = 1;
+    conf.beatsY = 1;
+    conf.aboutX = 2;
+    conf.aboutY = 2;
+
+    REQUIRE(conf.write() == 1);
+  }
+
+  SECTION("test read")
+  {
+    REQUIRE(conf.read() == 1);
+    REQUIRE(conf.header == "GIADACONFTEST");
+    REQUIRE(conf.logMode == 1);
+    REQUIRE(conf.soundSystem == 2);
+    REQUIRE(conf.soundDeviceOut == 3);
+    REQUIRE(conf.soundDeviceIn == 4);
+    REQUIRE(conf.channelsOut == 5);
+    REQUIRE(conf.channelsIn == 6);
+    REQUIRE(conf.samplerate == 44100);  // sanitized
+    REQUIRE(conf.buffersize == 8);
+    REQUIRE(conf.delayComp == 9);
+    REQUIRE(conf.limitOutput == true);
+    REQUIRE(conf.rsmpQuality == 0); // sanitized
+    REQUIRE(conf.midiSystem == 11);
+    REQUIRE(conf.midiPortOut == 12);
+    REQUIRE(conf.midiPortIn == 13);
+    REQUIRE(conf.noNoteOff == false);
+    REQUIRE(conf.midiMapPath == "path/to/midi/map");
+    REQUIRE(conf.lastFileMap == "path/to/last/midi/map");
+    REQUIRE(conf.midiSync == 14);
+    REQUIRE(conf.midiTCfps == Approx(15.1));
+    REQUIRE(conf.midiInRewind == 16);
+    REQUIRE(conf.midiInStartStop == 17);
+    REQUIRE(conf.midiInActionRec == 18);
+    REQUIRE(conf.midiInInputRec == 19);
+    REQUIRE(conf.midiInMetronome == 20);
+    REQUIRE(conf.midiInVolumeIn == 21);
+    REQUIRE(conf.midiInVolumeOut == 22);
+    REQUIRE(conf.midiInBeatDouble == 23);
+    REQUIRE(conf.midiInBeatHalf == 24);
+    REQUIRE(conf.recsStopOnChanHalt == true);
+    REQUIRE(conf.chansStopOnSeqHalt == false);
+    REQUIRE(conf.treatRecsAsLoops == true);
+    REQUIRE(conf.resizeRecordings == false);
+    REQUIRE(conf.pluginPath == "path/to/plugins");
+    REQUIRE(conf.patchPath == "path/to/patches");
+    REQUIRE(conf.samplePath == "path/to/samples");
+    REQUIRE(conf.mainWindowX == 0);
+    REQUIRE(conf.mainWindowY == 0);
+    REQUIRE(conf.mainWindowW == 800);
+    REQUIRE(conf.mainWindowH == 600);
+    REQUIRE(conf.browserX == 0);
+    REQUIRE(conf.browserY == 0);
+    REQUIRE(conf.browserW == 800);
+    REQUIRE(conf.browserH == 600);
+    REQUIRE(conf.actionEditorX == 0);
+    REQUIRE(conf.actionEditorY == 0);
+    REQUIRE(conf.actionEditorW == 800);
+    REQUIRE(conf.actionEditorH == 600);
+    REQUIRE(conf.actionEditorZoom == 100);  // sanitized
+    REQUIRE(conf.actionEditorGridVal == 10);
+    REQUIRE(conf.actionEditorGridOn == 1);
+    REQUIRE(conf.sampleEditorX == 0);
+    REQUIRE(conf.sampleEditorY == 0);
+    REQUIRE(conf.sampleEditorW == 800);
+    REQUIRE(conf.sampleEditorH == 600);
+    REQUIRE(conf.sampleEditorGridVal == 4);
+    REQUIRE(conf.sampleEditorGridOn == 0);
+    REQUIRE(conf.pianoRollY == 0);
+    REQUIRE(conf.pianoRollH == 900);
+    REQUIRE(conf.pluginListX == 0);
+    REQUIRE(conf.pluginListY == 50);
+    REQUIRE(conf.configX == 20);
+    REQUIRE(conf.configY == 20);
+    REQUIRE(conf.bpmX == 30);
+    REQUIRE(conf.bpmY == 36);
+    REQUIRE(conf.beatsX == 1);
+    REQUIRE(conf.beatsY == 1);
+    REQUIRE(conf.aboutX == 2);
+    REQUIRE(conf.aboutY == 2);
+  }
+}
diff --git a/tests/midiMapConf.cpp b/tests/midiMapConf.cpp
new file mode 100644
index 0000000..7783822
--- /dev/null
+++ b/tests/midiMapConf.cpp
@@ -0,0 +1,120 @@
+#include "../src/core/const.h"
+#include "../src/core/midiMapConf.h"
+#include "catch.hpp"
+
+
+using std::string;
+
+
+TEST_CASE("Test MidiMapConf class")
+{
+  MidiMapConf midimap;
+
+  SECTION("test default values")
+  {
+    midimap.setDefault();
+    REQUIRE(midimap.brand  == "");
+  	REQUIRE(midimap.device == "");
+  	REQUIRE(midimap.muteOn.channel    == 0);
+  	REQUIRE(midimap.muteOn.valueStr   == "");
+  	REQUIRE(midimap.muteOn.offset     == -1);
+  	REQUIRE(midimap.muteOn.value      == 0);
+  	REQUIRE(midimap.muteOff.channel   == 0);
+  	REQUIRE(midimap.muteOff.valueStr  == "");
+  	REQUIRE(midimap.muteOff.offset    == -1);
+  	REQUIRE(midimap.muteOff.value     == 0);
+  	REQUIRE(midimap.soloOn.channel    == 0);
+  	REQUIRE(midimap.soloOn.valueStr   == "");
+  	REQUIRE(midimap.soloOn.offset     == -1);
+  	REQUIRE(midimap.soloOn.value      == 0);
+  	REQUIRE(midimap.soloOff.channel   == 0);
+  	REQUIRE(midimap.soloOff.valueStr  == "");
+  	REQUIRE(midimap.soloOff.offset    == -1);
+  	REQUIRE(midimap.soloOff.value     == 0);
+  	REQUIRE(midimap.waiting.channel   == 0);
+  	REQUIRE(midimap.waiting.valueStr  == "");
+  	REQUIRE(midimap.waiting.offset    == -1);
+  	REQUIRE(midimap.waiting.value     == 0);
+  	REQUIRE(midimap.playing.channel   == 0);
+  	REQUIRE(midimap.playing.valueStr  == "");
+  	REQUIRE(midimap.playing.offset    == -1);
+  	REQUIRE(midimap.playing.value     == 0);
+  	REQUIRE(midimap.stopping.channel  == 0);
+  	REQUIRE(midimap.stopping.valueStr == "");
+  	REQUIRE(midimap.stopping.offset   == -1);
+  	REQUIRE(midimap.stopping.value    == 0);
+  	REQUIRE(midimap.stopped.channel   == 0);
+  	REQUIRE(midimap.stopped.valueStr  == "");
+  	REQUIRE(midimap.stopped.offset    == -1);
+  	REQUIRE(midimap.stopped.value     == 0);
+  }
+
+  SECTION("test read")
+  {
+    midimap.init();
+    midimap.setDefault();
+
+    /* expect more than 2 midifiles */
+
+    REQUIRE(midimap.maps.size() >= 2);
+
+    /* try with deprecated mode */
+
+    int res = midimap.read("akai-lpd8.giadamap");
+    if (res != MIDIMAP_READ_OK)
+      res = midimap.readMap_DEPR_("akai-lpd8.giadamap");
+
+    REQUIRE(res == MIDIMAP_READ_OK);
+
+    REQUIRE(midimap.brand == "AKAI");
+    REQUIRE(midimap.device == "LPD8");
+
+    REQUIRE(midimap.initCommands.size() == 2);
+    REQUIRE(midimap.initCommands[0].channel == 0);
+    REQUIRE(midimap.initCommands[0].value == 0xB0000000);
+    REQUIRE(midimap.initCommands[1].channel == 0);
+    REQUIRE(midimap.initCommands[1].value == 0xB0002800);
+
+    /* TODO - can't check 'valueStr' until deprecated methods are alive */
+
+    REQUIRE(midimap.muteOn.channel == 0);
+    //REQUIRE(midimap.muteOn.valueStr == "90nn3F00");
+    REQUIRE(midimap.muteOn.offset == 16);
+    REQUIRE(midimap.muteOn.value == 0x90003F00);
+
+    REQUIRE(midimap.muteOff.channel == 0);
+    //REQUIRE(midimap.muteOff.valueStr == "90nn0C00");
+    REQUIRE(midimap.muteOff.offset == 16);
+    REQUIRE(midimap.muteOff.value == 0x90000C00);
+
+    REQUIRE(midimap.soloOn.channel == 0);
+    //REQUIRE(midimap.soloOn.valueStr == "90nn0F00");
+    REQUIRE(midimap.soloOn.offset == 16);
+    REQUIRE(midimap.soloOn.value == 0x90000F00);
+
+    REQUIRE(midimap.soloOff.channel == 0);
+    //REQUIRE(midimap.soloOff.valueStr == "90nn0C00");
+    REQUIRE(midimap.soloOff.offset == 16);
+    REQUIRE(midimap.soloOff.value == 0x90000C00);
+
+    REQUIRE(midimap.waiting.channel == 0);
+    //REQUIRE(midimap.waiting.valueStr == "90nn7f00");
+    REQUIRE(midimap.waiting.offset == 16);
+    REQUIRE(midimap.waiting.value == 0x90007f00);
+
+    REQUIRE(midimap.playing.channel == 0);
+    //REQUIRE(midimap.playing.valueStr == "90nn7f00");
+    REQUIRE(midimap.playing.offset == 16);
+    REQUIRE(midimap.playing.value == 0x90007f00);
+
+    REQUIRE(midimap.stopping.channel == 0);
+    //REQUIRE(midimap.stopping.valueStr == "90nn7f00");
+    REQUIRE(midimap.stopping.offset == 16);
+    REQUIRE(midimap.stopping.value == 0x90007f00);
+
+    REQUIRE(midimap.stopped.channel == 0);
+    //REQUIRE(midimap.stopped.valueStr == "80nn7f00");
+    REQUIRE(midimap.stopped.offset == 16);
+    REQUIRE(midimap.stopped.value == 0x80007f00);
+  }
+}
diff --git a/tests/patch.cpp b/tests/patch.cpp
index a36decf..8ff9942 100644
--- a/tests/patch.cpp
+++ b/tests/patch.cpp
@@ -4,6 +4,7 @@
 
 
 using std::string;
+using std::vector;
 
 
 TEST_CASE("Test Patch class")
@@ -32,27 +33,27 @@ TEST_CASE("Test Patch class")
     action2.frame  = 589;
     action2.fValue = 1.0f;
     action2.iValue = 130;
-    channel1.actions.add(action1);
-    channel1.actions.add(action2);
+    channel1.actions.push_back(action1);
+    channel1.actions.push_back(action2);
 
 #ifdef WITH_VST
     plugin1.path   = "/path/to/plugin1";
     plugin1.bypass = false;
-    plugin1.params.add(0.0f);
-    plugin1.params.add(0.1f);
-    plugin1.params.add(0.2f);
-    channel1.plugins.add(plugin1);
+    plugin1.params.push_back(0.0f);
+    plugin1.params.push_back(0.1f);
+    plugin1.params.push_back(0.2f);
+    channel1.plugins.push_back(plugin1);
 
     plugin2.path   = "/another/path/to/plugin2";
     plugin2.bypass = true;
-    plugin2.params.add(0.6f);
-    plugin2.params.add(0.6f);
-    plugin2.params.add(0.6f);
-    plugin2.params.add(0.0f);
-    plugin2.params.add(1.0f);
-    plugin2.params.add(1.0f);
-    plugin2.params.add(0.333f);
-    channel1.plugins.add(plugin2);
+    plugin2.params.push_back(0.6f);
+    plugin2.params.push_back(0.6f);
+    plugin2.params.push_back(0.6f);
+    plugin2.params.push_back(0.0f);
+    plugin2.params.push_back(1.0f);
+    plugin2.params.push_back(1.0f);
+    plugin2.params.push_back(0.333f);
+    channel1.plugins.push_back(plugin2);
 #endif
 
     channel1.type              = CHANNEL_SAMPLE;
@@ -87,11 +88,11 @@ TEST_CASE("Test Patch class")
     channel1.midiInPitch       = 0;
     channel1.midiOut           = 0;
     channel1.midiOutChan       = 5;
-    patch.channels.add(channel1);
+    patch.channels.push_back(channel1);
 
     column.index = 0;
     column.width = 500;
-    patch.columns.add(column);
+    patch.columns.push_back(column);
 
     patch.header       = "GPTCH";
     patch.version      = "1.0";
@@ -111,8 +112,8 @@ TEST_CASE("Test Patch class")
 
 #ifdef WITH_VST
 
-    patch.masterInPlugins.add(plugin1);
-    patch.masterOutPlugins.add(plugin2);
+    patch.masterInPlugins.push_back(plugin1);
+    patch.masterOutPlugins.push_back(plugin2);
 
 #endif
 
diff --git a/tests/utils.cpp b/tests/utils.cpp
index bac06c6..b7c88b3 100644
--- a/tests/utils.cpp
+++ b/tests/utils.cpp
@@ -2,36 +2,7 @@
 #include "catch.hpp"
 
 
-TEST_CASE("Test gVector template") 
-{
-  gVector<int> v;
-  v.add(0);
-  v.add(1);
-  v.add(2);
-  REQUIRE(v.size == 3);
-  
-  v.del(0);
-  REQUIRE(v.size == 2);
-  
-  v.swap(0, 1);
-  REQUIRE(v.at(0) == 2);
-  
-  REQUIRE(v.last() == 1);
-  
-  v.clear();
-  REQUIRE(v.size == 0);
-  
-  /* test copy constructor */
-  
-  gVector<int> v1;
-  v1.add(0);
-  v1.add(1);
-  v1.add(2);
-  gVector<int> v2;
-  v2 = v1;
-  REQUIRE(v2.size == 3);
-  REQUIRE(v2.at(2) == 2); 
-}
+using std::vector;
 
 
 TEST_CASE("Test filesystem utils")
@@ -55,11 +26,10 @@ TEST_CASE("Test string utils")
   REQUIRE(gTrim("   Giada is cool       ") == "Giada is cool");
   REQUIRE(gItoa(666) == "666");
 
-  gVector<std::string> v;
+  vector<std::string> v;
   gSplit("Giada is cool", " ", &v);
-  REQUIRE(v.size == 3);
+  REQUIRE(v.size() == 3);
   REQUIRE(v.at(0) == "Giada");
   REQUIRE(v.at(1) == "is");
   REQUIRE(v.at(2) == "cool");
 }
-
diff --git a/tests/wave.cpp b/tests/wave.cpp
new file mode 100644
index 0000000..a28e946
--- /dev/null
+++ b/tests/wave.cpp
@@ -0,0 +1,45 @@
+#include "../src/core/wave.h"
+#include "catch.hpp"
+
+
+using std::string;
+
+
+#define G_SAMPLE_RATE 44100
+#define G_BUFFER_SIZE 4096
+
+
+TEST_CASE("Test Wave class")
+{
+  Wave w1;
+
+  SECTION("test read & write")
+  {
+    REQUIRE(w1.open("test.wav") == 1);
+    REQUIRE(w1.readData() == 1);
+    REQUIRE(w1.rate() == 11025);
+    REQUIRE(w1.channels() == 2);
+    REQUIRE(w1.basename() == "test");
+    REQUIRE(w1.extension() == "wav");
+    REQUIRE(w1.writeData("test-write.wav") == true);
+  }
+
+  SECTION("test copy constructor")
+  {
+    Wave w2(w1);
+    REQUIRE(w2.size == w1.size);
+    REQUIRE(w2.isLogical == true);
+    REQUIRE(w2.rate() == 11025);
+    REQUIRE(w2.channels() == 2);
+    REQUIRE(w2.writeData("test-write.wav") == true);
+  }
+
+  SECTION("test rec")
+  {
+    Wave w3;
+    REQUIRE(w3.allocEmpty(G_BUFFER_SIZE, G_SAMPLE_RATE) == 1);
+    REQUIRE(w3.rate() == G_SAMPLE_RATE);
+    REQUIRE(w3.channels() == 2);
+    REQUIRE(w3.writeData("test-write.wav") == true);
+  }
+}

-- 
giada packaging



More information about the pkg-multimedia-commits mailing list