+sudo: required
+
+dist: trusty
+
language: cpp
compiler: gcc
- 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
--------------------------------------------------------------------------------
-
-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
-AUTOMAKE_OPTIONS = foreign
+channelAUTOMAKOPTIONS = foreign
AM_CXXFLAGS = -Wall -pedantic -Werror
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 \
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)
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 ------------------------------------------------------------------
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)
+

-## Features
+## Main features
* Ultra-lightweight internal design;
* multi-thread/multi-core support;
* 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.
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:
## 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/>.
*
* -----------------------------------------------------------------------------
*
- * 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.
*
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));
}
/* -------------------------------------------------------------------------- */
-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);
}
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;
pac.frame = action->frame;
pac.fValue = action->fValue;
pac.iValue = action->iValue;
- pch.actions.add(pac);
+ pch.actions.push_back(pac);
}
}
}
#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;
}
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;
}
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);
}
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);
}
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);
}
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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
using std::string;
-class Channel {
-
+class Channel
+{
protected:
/* bufferSize
* 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. */
uint32_t midiOutLsolo;
#ifdef WITH_VST
- gVector <class Plugin *> plugins;
+ vector <class Plugin *> plugins;
#endif
*
* -----------------------------------------------------------------------------
*
- * 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.
*
* -------------------------------------------------------------------------- */
-#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;
midiPortIn = DEFAULT_MIDI_PORT_IN;
noNoteOff = false;
- midiMapPath[0] = '\0';
+ midiMapPath = "";
midiPortOut = DEFAULT_MIDI_PORT_OUT;
midiSync = MIDI_SYNC_NONE;
midiTCfps = 25.0f;
midiInBeatHalf = 0x0;
midiInMetronome = 0x0;
- pluginPath[0] = '\0';
- patchPath [0] = '\0';
- samplePath[0] = '\0';
+ pluginPath = "";
+ patchPath = "";
+ samplePath = "";
recsStopOnChanHalt = false;
chansStopOnSeqHalt = false;
}
-
/* -------------------------------------------------------------------------- */
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;
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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;
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;
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;
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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
* 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.
*
/* -- 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"
/* -- 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
/* -- 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__)
+/* -- 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. */
#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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
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");
}
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");
+ }
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* 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"
extern bool G_audio_status;
-namespace kernelAudio {
-
+namespace kernelAudio
+{
RtAudio *system = NULL;
unsigned numDevs = 0;
bool inputEnabled = 0;
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());
}
#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__)
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-int startStream() {
+int startStream()
+{
try {
system->startStream();
gLog("[KA] latency = %lu\n", system->getStreamLatency());
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-int stopStream() {
+int stopStream()
+{
try {
system->stopStream();
return 1;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-unsigned getMaxInChans(int dev) {
+unsigned getMaxInChans(int dev)
+{
if (dev == -1) return 0;
try {
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-unsigned getMaxOutChans(unsigned dev) {
+unsigned getMaxOutChans(unsigned dev)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).outputChannels;
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-bool isProbed(unsigned dev) {
+bool isProbed(unsigned dev)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).probed;
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-unsigned getDuplexChans(unsigned dev) {
+unsigned getDuplexChans(unsigned dev)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).duplexChannels;
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-bool isDefaultIn(unsigned dev) {
+bool isDefaultIn(unsigned dev)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).isDefaultInput;
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-bool isDefaultOut(unsigned dev) {
+bool isDefaultOut(unsigned dev)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).isDefaultOutput;
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-int getTotalFreqs(unsigned dev) {
+int getTotalFreqs(unsigned dev)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).sampleRates.size();
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-int getFreq(unsigned dev, int i) {
+int getFreq(unsigned dev, int i)
+{
try {
return ((RtAudio::DeviceInfo) system->getDeviceInfo(dev)).sampleRates.at(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++)
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-std::string getRtAudioVersion() {
+std::string getRtAudioVersion()
+{
return RtAudio::getVersion();
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
#ifdef __linux__
#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);
}
-void jackStop() {
+void jackStop()
+{
if (api == SYS_API_JACK) {
jack_client_t *client = jackGetHandle();
jack_transport_stop(client);
}
-void jackSetSyncCb() {
+void jackSetSyncCb()
+{
jack_client_t *client = jackGetHandle();
jack_set_sync_callback(client, jackSyncCb, NULL);
//jack_set_sync_timeout(client, 8);
#endif
}
-
-
*
* ---------------------------------------------------------------------
*
- * 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.
*
#endif
+using std::string;
+
+
namespace kernelAudio {
int openDevice(
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();
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#endif
+using std::string;
+
+
namespace kernelMidi
{
-
int api = 0; // one api for both in & out
RtMidiOut *midiOut = NULL;
RtMidiIn *midiIn = 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]);
+ }
+ }
+}
+
+
/* -------------------------------------------------------------------------- */
void setApi(int _api)
{
- api = api;
+ api = _api;
gLog("[KM] using system 0x%x\n", api);
}
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 */
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) {
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 */
/* -------------------------------------------------------------------------- */
-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 ""; }
}
/* 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);
}
+/* -------------------------------------------------------------------------- */
+
+
} // namespace
*
* ---------------------------------------------------------------------
*
- * 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.
*
#include "channel.h"
+using std::string;
+
+
namespace kernelMidi {
extern int api; // one api for both in & out
/* 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);
void callback(double t, std::vector<unsigned char> *msg, void *data);
- std::string getRtMidiVersion();
+ string getRtMidiVersion();
}
#endif
*
* -----------------------------------------------------------------------------
*
- * 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.
*
/* -------------------------------------------------------------------------- */
+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)
midiOut = pch->midiOut;
midiOutChan = pch->midiOutChan;
-
+
return SAMPLE_LOADED_OK; /// TODO - change name, it's meaningless here
}
*
* ---------------------------------------------------------------------
*
- * 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.
*
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);
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#include <stdlib.h>
+#include <vector>
#include <iostream>
#include <string>
#include <sstream>
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. */
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);
}
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 = "";
/* -------------------------------------------------------------------------- */
-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);
/* -------------------------------------------------------------------------- */
-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]:*/
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#include <limits.h>
#include <stdint.h>
+#include <vector>
#include "dataStorageIni.h"
+#include "dataStorageJson.h"
#include "../utils/utils.h"
#if defined(__APPLE__)
#include <pwd.h>
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. */
* 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
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
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#include <math.h>
Mixer::Mixer()
: vChanInput(NULL),
vChanInToOut(NULL)
-{
- gLog("[mixer] construct\n");
-}
+{}
/* -------------------------------------------------------------------------- */
};
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
void Mixer::init()
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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;
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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);
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
void Mixer::sendMIDIsync()
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
void Mixer::sendMIDIrewind()
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
int Mixer::masterPlay(
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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);
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);
}
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);
}
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);
}
/* 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);
/* 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);
}
/* 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);
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
void Mixer::updateFrameBars()
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
int Mixer::close()
{
running = false;
- while (channels.size > 0)
+ while (channels.size() > 0)
deleteChannel(channels.at(0));
if (vChanInput) {
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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()
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()
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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)
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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)
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
bool Mixer::mergeVirtualInput()
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#ifndef MIXER_H
#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();
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(); }
/* ---------------------------------------------------------------- */
XFADE = 0x02
};
- gVector<class Channel*> channels;
+ vector<class Channel*> channels;
bool running;
bool ready;
pthread_mutex_t mutex_chans;
pthread_mutex_t mutex_plugins;
-
private:
int midiTCstep; // part of MTC to send (0 to 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.
*
#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"
#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();
}
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;
/* 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);
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 */
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);
}
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
*
* ---------------------------------------------------------------------
*
- * 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.
*
#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. */
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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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()));
/* 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);
/* -------------------------------------------------------------------------- */
-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));
/* -------------------------------------------------------------------------- */
-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));
/* -------------------------------------------------------------------------- */
-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));
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;
}
#ifdef WITH_VST
readPlugins(jChannel, &channel.plugins, PATCH_KEY_CHANNEL_PLUGINS);
#endif
- channels.add(channel);
+ channels.push_back(channel);
}
return 1;
}
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;
}
#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))
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;
}
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;
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#include <string>
+#include <vector>
#include <stdint.h>
#include "../utils/utils.h"
#include "dataStorageJson.h"
using std::string;
+using std::vector;
class Patch : public DataStorageJson
#ifdef WITH_VST
struct plugin_t
{
- string path;
- bool bypass;
- gVector<float> params;
+ string path;
+ bool bypass;
+ vector<float> params;
};
#endif
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
};
{
int index;
int width;
- gVector<int> channels;
+ vector<int> channels;
};
string header;
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
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);
/* 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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
extern Mixer G_Mixer;
-extern Conf G_Conf;
+extern Conf G_Conf;
#ifdef WITH_VST
extern PluginHost G_PluginHost;
#endif
/* 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];
*
* -----------------------------------------------------------------------------
*
- * 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.
*
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#ifdef WITH_VST
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;
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-int Plugin::load(const char *fname) {
+int Plugin::load(const char *fname)
+{
strcpy(pathfile, fname);
#if defined(_WIN32)
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-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");
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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);
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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);
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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';
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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);
}
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#ifdef WITH_VST
typedef AEffect* (*vstPluginFuncPtr)(audioMasterCallback host);
-class Plugin {
-
+class Plugin
+{
private:
#if defined(_WIN32) || defined(__linux__)
int unload();
public:
+
Plugin();
~Plugin();
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);
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* 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"
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. */
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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.
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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) {
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;
}
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-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)) {
* useful to report a missing plugin. */
if (!success) {
- pStack->add(p);
+ pStack->push_back(p);
return NULL;
}
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... */
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-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
return;
if (pStack == NULL)
return;
- if (pStack->size == 0)
+ if (pStack->size() == 0)
return;
/* converting buffer from Giada to VST */
/* 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)
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-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) */
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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);
}
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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();
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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 {
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;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
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();
}
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* 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"
#include "const.h"
-class PluginHost {
+using std::vector;
+
+class PluginHost
+{
private:
/* VSTs have a different buffer model:
/* 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,
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);
*
* ---------------------------------------------------------------------
*
- * 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.
*
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;
/* 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;
}
/* 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 &&
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.
{
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
free(a->event);
#endif
free(a);
- global.at(i).del(j);
+ global.at(i).erase(global.at(i).begin() + j);
}
else
j++;
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++;
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 */
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;
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
}
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);
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;
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++;
{
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();
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;
/* 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);
}
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));
/* 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);
}
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);
}
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++;
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;
}
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)) {
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)
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);
}
}
*
* ---------------------------------------------------------------------
*
- * 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.
*
#include <stdio.h>
#include <stdlib.h>
+#include <vector>
#include "../utils/utils.h"
#include "const.h"
#include "mixer.h"
#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 {
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()?
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#endif
+using std::string;
+
+
SampleChannel::SampleChannel(int bufferSize)
: Channel (CHANNEL_SAMPLE, STATUS_EMPTY, bufferSize),
frameRewind (-1),
/* -------------------------------------------------------------------------- */
+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),
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];
}
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;
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#ifndef SAMPLE_CHANNEL_H
#include "channel.h"
-class SampleChannel : public Channel {
-
+class SampleChannel : public Channel
+{
private:
/* rsmp_state, rsmp_data
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);
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#include <stdio.h>
#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);
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
/* how to read and write with libsndfile:
*
* ...
*/
-int Wave::readData() {
+int Wave::readData()
+{
size = inHeader.frames * inHeader.channels;
data = (float *) malloc(size * sizeof(float));
if (data == NULL) {
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-int Wave::writeData(const char *f) {
+int Wave::writeData(const char *f)
+{
/* prepare the header for output file */
outHeader.samplerate = inHeader.samplerate;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-void Wave::clear() {
+void Wave::clear()
+{
if (data != NULL) {
free(data);
data = NULL;
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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
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
}
-/* ------------------------------------------------------------------ */
-
+/* -------------------------------------------------------------------------- */
-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
}
-/* ------------------------------------------------------------------ */
+/* -------------------------------------------------------------------------- */
-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;
-/* ---------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
*
* 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.
*
* along with Giada - Your Hardcore Loopmachine. If not, see
* <http://www.gnu.org/licenses/>.
*
- * ------------------------------------------------------------------ */
+ * -------------------------------------------------------------------------- */
#ifndef WAVE_H
#include <string>
-class Wave {
-
+class Wave
+{
private:
SNDFILE *fileIn;
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)
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);
/* allocEmpty
* alloc an empty waveform. */
- int allocEmpty(unsigned size);
+ int allocEmpty(unsigned size, unsigned samplerate);
/* resample
* simple algorithm for one-shot resampling. */
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
+++ /dev/null
-//-------------------------------------------------------------------------------------------------------\r
-// VST Plug-Ins SDK\r
-// Version 2.4 $Date: 2006/06/20 17:22:55 $\r
-//\r
-// Category : VST 2.x Interfaces\r
-// Filename : aeffect.h\r
-// Created by : Steinberg Media Technologies\r
-// Description : Definition of AEffect structure\r
-//\r
-// © 2006, Steinberg Media Technologies, All Rights Reserved\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#ifndef __aeffect__\r
-#define __aeffect__\r
-\r
-// gcc based compiler, or CodeWarrior on Mac OS X\r
-#if ((defined(__GNUC__) && (defined(__APPLE_CPP__) || defined(__APPLE_CC__))) || (defined (__MWERKS__) && defined (__MACH__)))\r
- #ifndef TARGET_API_MAC_CARBON\r
- #define TARGET_API_MAC_CARBON 1\r
- #endif\r
- #if __ppc__\r
- #ifndef VST_FORCE_DEPRECATED\r
- #define VST_FORCE_DEPRECATED 0\r
- #endif\r
- #endif\r
-#endif\r
-\r
-#if TARGET_API_MAC_CARBON\r
- #ifdef __LP64__\r
- #pragma options align=power\r
- #else\r
- #pragma options align=mac68k\r
- #endif\r
- #define VSTCALLBACK\r
-#elif defined __BORLANDC__\r
- #pragma -a8\r
-#elif defined(__GNUC__)\r
- #pragma pack(push,8)\r
- #define VSTCALLBACK __cdecl\r
-#elif defined(WIN32) || defined(__FLAT__) || defined CBUILDER\r
- #pragma pack(push)\r
- #pragma pack(8)\r
- #define VSTCALLBACK __cdecl\r
-#else\r
- #define VSTCALLBACK\r
-#endif\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#include <string.h> // for strncpy\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// VST Version\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-/** Define SDK Version (you can generate different versions (from 2.0 to 2.4) of this SDK by setting the unwanted extensions to 0). */\r
-#define VST_2_1_EXTENSIONS 1 ///< Version 2.1 extensions (08-06-2000)\r
-#define VST_2_2_EXTENSIONS 1 ///< Version 2.2 extensions (08-06-2001)\r
-#define VST_2_3_EXTENSIONS 1 ///< Version 2.3 extensions (20-05-2003)\r
-#ifndef VST_2_4_EXTENSIONS\r
-#define VST_2_4_EXTENSIONS 1 ///< Version 2.4 extensions (01-01-2006)\r
-#endif\r
-\r
-/** Current VST Version */\r
-#if VST_2_4_EXTENSIONS\r
- #define kVstVersion 2400\r
-#elif VST_2_3_EXTENSIONS\r
- #define kVstVersion 2300\r
-#elif VST_2_2_EXTENSIONS\r
- #define kVstVersion 2200\r
-#elif VST_2_1_EXTENSIONS\r
- #define kVstVersion 2100\r
-#else\r
- #define kVstVersion 2\r
-#endif\r
-\r
-/** Disable for Hosts to serve Plug-ins below VST 2.4 */\r
-#ifndef VST_FORCE_DEPRECATED\r
-#define VST_FORCE_DEPRECATED VST_2_4_EXTENSIONS \r
-#endif\r
-\r
-/** Declares identifier as deprecated. */\r
-#if VST_FORCE_DEPRECATED\r
-#define DECLARE_VST_DEPRECATED(identifier) __##identifier##Deprecated\r
-#else\r
-#define DECLARE_VST_DEPRECATED(identifier) identifier\r
-#endif\r
-\r
-/** Define for 64 Bit Platform. */\r
-#ifndef VST_64BIT_PLATFORM\r
-#define VST_64BIT_PLATFORM _WIN64 || __LP64__\r
-#endif\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// Integral Types\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#ifdef WIN32\r
-typedef short VstInt16; ///< 16 bit integer type\r
-typedef int VstInt32; ///< 32 bit integer type\r
-typedef __int64 VstInt64; ///< 64 bit integer type\r
-#else\r
-#include <stdint.h>\r
-typedef int16_t VstInt16; ///< 16 bit integer type\r
-typedef int32_t VstInt32; ///< 32 bit integer type\r
-typedef int64_t VstInt64; ///< 64 bit integer type\r
-#endif\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// Generic Types\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#if VST_64BIT_PLATFORM\r
-typedef VstInt64 VstIntPtr; ///< platform-dependent integer type, same size as pointer\r
-#else\r
-typedef VstInt32 VstIntPtr; ///< platform-dependent integer type, same size as pointer\r
-#endif\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// Misc. Definition\r
-//-------------------------------------------------------------------------------------------------------\r
-#undef CCONST\r
-struct AEffect;\r
-\r
-/// @cond ignore\r
-typedef VstIntPtr (VSTCALLBACK *audioMasterCallback) (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);\r
-typedef VstIntPtr (VSTCALLBACK *AEffectDispatcherProc) (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);\r
-typedef void (VSTCALLBACK *AEffectProcessProc) (AEffect* effect, float** inputs, float** outputs, VstInt32 sampleFrames);\r
-typedef void (VSTCALLBACK *AEffectProcessDoubleProc) (AEffect* effect, double** inputs, double** outputs, VstInt32 sampleFrames);\r
-typedef void (VSTCALLBACK *AEffectSetParameterProc) (AEffect* effect, VstInt32 index, float parameter);\r
-typedef float (VSTCALLBACK *AEffectGetParameterProc) (AEffect* effect, VstInt32 index);\r
-/// @endcond\r
-\r
-/** Four Character Constant (for AEffect->uniqueID) */\r
-#define CCONST(a, b, c, d) \\r
- ((((VstInt32)a) << 24) | (((VstInt32)b) << 16) | (((VstInt32)c) << 8) | (((VstInt32)d) << 0))\r
-\r
-/** AEffect magic number */\r
-#define kEffectMagic CCONST ('V', 's', 't', 'P')\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Basic VST Effect "C" Interface. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct AEffect\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 magic; ///< must be #kEffectMagic ('VstP')\r
-\r
- /** Host to Plug-in dispatcher @see AudioEffect::dispatcher */\r
- AEffectDispatcherProc dispatcher;\r
- \r
- /** \deprecated Accumulating process mode is deprecated in VST 2.4! Use AEffect::processReplacing instead! */\r
- AEffectProcessProc DECLARE_VST_DEPRECATED (process);\r
- \r
- /** Set new value of automatable parameter @see AudioEffect::setParameter */\r
- AEffectSetParameterProc setParameter;\r
-\r
- /** Returns current value of automatable parameter @see AudioEffect::getParameter*/\r
- AEffectGetParameterProc getParameter;\r
-\r
- VstInt32 numPrograms; ///< number of programs\r
- VstInt32 numParams; ///< all programs are assumed to have numParams parameters\r
- VstInt32 numInputs; ///< number of audio inputs\r
- VstInt32 numOutputs; ///< number of audio outputs\r
-\r
- VstInt32 flags; ///< @see VstAEffectFlags\r
- \r
- VstIntPtr resvd1; ///< reserved for Host, must be 0\r
- VstIntPtr resvd2; ///< reserved for Host, must be 0\r
- \r
- 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.\r
- \r
- VstInt32 DECLARE_VST_DEPRECATED (realQualities); ///< \deprecated unused member\r
- VstInt32 DECLARE_VST_DEPRECATED (offQualities); ///< \deprecated unused member\r
- float DECLARE_VST_DEPRECATED (ioRatio); ///< \deprecated unused member\r
-\r
- void* object; ///< #AudioEffect class pointer\r
- void* user; ///< user-defined pointer\r
-\r
- 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.\r
- VstInt32 version; ///< plug-in version (example 1100 for version 1.1.0.0)\r
-\r
- /** Process audio samples in replacing mode @see AudioEffect::processReplacing */\r
- AEffectProcessProc processReplacing;\r
-\r
-#if VST_2_4_EXTENSIONS\r
- /** Process double-precision audio samples in replacing mode @see AudioEffect::processDoubleReplacing */\r
- AEffectProcessDoubleProc processDoubleReplacing;\r
- \r
- char future[56]; ///< reserved for future use (please zero)\r
-#else\r
- char future[60]; ///< reserved for future use (please zero)\r
-#endif\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** AEffect flags */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstAEffectFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- effFlagsHasEditor = 1 << 0, ///< set if the plug-in provides a custom editor\r
- effFlagsCanReplacing = 1 << 4, ///< supports replacing process mode (which should the default mode in VST 2.4)\r
- effFlagsProgramChunks = 1 << 5, ///< program data is handled in formatless chunks\r
- effFlagsIsSynth = 1 << 8, ///< plug-in is a synth (VSTi), Host may assign mixer channels for its outputs\r
- effFlagsNoSoundInStop = 1 << 9, ///< plug-in does not produce sound when input is all silence\r
-\r
-#if VST_2_4_EXTENSIONS\r
- effFlagsCanDoubleReplacing = 1 << 12, ///< plug-in supports double precision processing\r
-#endif\r
-\r
- DECLARE_VST_DEPRECATED (effFlagsHasClip) = 1 << 1, ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effFlagsHasVu) = 1 << 2, ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effFlagsCanMono) = 1 << 3, ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effFlagsExtIsAsync) = 1 << 10, ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effFlagsExtHasBuffer) = 1 << 11 ///< \deprecated deprecated in VST 2.4\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Basic dispatcher Opcodes (Host to Plug-in) */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum AEffectOpcodes\r
-{\r
- effOpen = 0, ///< no arguments @see AudioEffect::open\r
- effClose, ///< no arguments @see AudioEffect::close\r
-\r
- effSetProgram, ///< [value]: new program number @see AudioEffect::setProgram\r
- effGetProgram, ///< [return value]: current program number @see AudioEffect::getProgram\r
- effSetProgramName, ///< [ptr]: char* with new program name, limited to #kVstMaxProgNameLen @see AudioEffect::setProgramName\r
- effGetProgramName, ///< [ptr]: char buffer for current program name, limited to #kVstMaxProgNameLen @see AudioEffect::getProgramName\r
- \r
- effGetParamLabel, ///< [ptr]: char buffer for parameter label, limited to #kVstMaxParamStrLen @see AudioEffect::getParameterLabel\r
- effGetParamDisplay, ///< [ptr]: char buffer for parameter display, limited to #kVstMaxParamStrLen @see AudioEffect::getParameterDisplay\r
- effGetParamName, ///< [ptr]: char buffer for parameter name, limited to #kVstMaxParamStrLen @see AudioEffect::getParameterName\r
- \r
- DECLARE_VST_DEPRECATED (effGetVu), ///< \deprecated deprecated in VST 2.4\r
-\r
- effSetSampleRate, ///< [opt]: new sample rate for audio processing @see AudioEffect::setSampleRate\r
- effSetBlockSize, ///< [value]: new maximum block size for audio processing @see AudioEffect::setBlockSize\r
- effMainsChanged, ///< [value]: 0 means "turn off", 1 means "turn on" @see AudioEffect::suspend @see AudioEffect::resume\r
-\r
- effEditGetRect, ///< [ptr]: #ERect** receiving pointer to editor size @see ERect @see AEffEditor::getRect\r
- effEditOpen, ///< [ptr]: system dependent Window pointer, e.g. HWND on Windows @see AEffEditor::open\r
- effEditClose, ///< no arguments @see AEffEditor::close\r
-\r
- DECLARE_VST_DEPRECATED (effEditDraw), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effEditMouse), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effEditKey), ///< \deprecated deprecated in VST 2.4\r
-\r
- effEditIdle, ///< no arguments @see AEffEditor::idle\r
- \r
- DECLARE_VST_DEPRECATED (effEditTop), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effEditSleep), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (effIdentify), ///< \deprecated deprecated in VST 2.4\r
- \r
- effGetChunk, ///< [ptr]: void** for chunk data address [index]: 0 for bank, 1 for program @see AudioEffect::getChunk\r
- effSetChunk, ///< [ptr]: chunk data [value]: byte size [index]: 0 for bank, 1 for program @see AudioEffect::setChunk\r
- \r
- effNumOpcodes \r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Basic dispatcher Opcodes (Plug-in to Host) */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum AudioMasterOpcodes\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- audioMasterAutomate = 0, ///< [index]: parameter index [opt]: parameter value @see AudioEffect::setParameterAutomated\r
- audioMasterVersion, ///< [return value]: Host VST version (for example 2400 for VST 2.4) @see AudioEffect::getMasterVersion\r
- audioMasterCurrentId, ///< [return value]: current unique identifier on shell plug-in @see AudioEffect::getCurrentUniqueId\r
- audioMasterIdle, ///< no arguments @see AudioEffect::masterIdle\r
- DECLARE_VST_DEPRECATED (audioMasterPinConnected) ///< \deprecated deprecated in VST 2.4 r2\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** String length limits (in characters excl. 0 byte) */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstStringConstants\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstMaxProgNameLen = 24, ///< used for #effGetProgramName, #effSetProgramName, #effGetProgramNameIndexed\r
- kVstMaxParamStrLen = 8, ///< used for #effGetParamLabel, #effGetParamDisplay, #effGetParamName\r
- kVstMaxVendorStrLen = 64, ///< used for #effGetVendorString, #audioMasterGetVendorString\r
- kVstMaxProductStrLen = 64, ///< used for #effGetProductString, #audioMasterGetProductString\r
- kVstMaxEffectNameLen = 32 ///< used for #effGetEffectName\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** String copy taking care of null terminator. */\r
-//-------------------------------------------------------------------------------------------------------\r
-inline char* vst_strncpy (char* dst, const char* src, size_t maxLen)\r
-{\r
- char* result = strncpy (dst, src, maxLen);\r
- dst[maxLen] = 0;\r
- return result;\r
-}\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** String concatenation taking care of null terminator. */\r
-//-------------------------------------------------------------------------------------------------------\r
-inline char* vst_strncat (char* dst, const char* src, size_t maxLen)\r
-{\r
- char* result = strncat (dst, src, maxLen);\r
- dst[maxLen] = 0;\r
- return result;\r
-}\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Cast #VstIntPtr to pointer. */\r
-//-------------------------------------------------------------------------------------------------------\r
-template <class T> inline T* FromVstPtr (VstIntPtr& arg)\r
-{\r
- T** address = (T**)&arg;\r
- return *address;\r
-}\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Cast pointer to #VstIntPtr. */\r
-//-------------------------------------------------------------------------------------------------------\r
-template <class T> inline VstIntPtr ToVstPtr (T* ptr)\r
-{\r
- VstIntPtr* address = (VstIntPtr*)&ptr;\r
- return *address;\r
-}\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Structure used for #effEditGetRect. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct ERect\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt16 top; ///< top coordinate\r
- VstInt16 left; ///< left coordinate\r
- VstInt16 bottom; ///< bottom coordinate\r
- VstInt16 right; ///< right coordinate\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-#if TARGET_API_MAC_CARBON\r
- #pragma options align=reset\r
-#elif defined(WIN32) || defined(__FLAT__) || defined(__GNUC__)\r
- #pragma pack(pop)\r
-#elif defined __BORLANDC__\r
- #pragma -a-\r
-#endif\r
-\r
-#endif // __aeffect__\r
+++ /dev/null
-//-------------------------------------------------------------------------------------------------------\r
-// VST Plug-Ins SDK\r
-// Version 2.4 $Date: 2006/06/20 12:43:42 $\r
-//\r
-// Category : VST 2.x Interfaces\r
-// Filename : aeffectx.h\r
-// Created by : Steinberg Media Technologies\r
-// Description : Definition of auxiliary structures, extensions from VST 1.0 to VST 2.4\r
-//\r
-// © 2006, Steinberg Media Technologies, All Rights Reserved\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#ifndef __aeffectx__\r
-#define __aeffectx__\r
-\r
-#ifndef __aeffect__\r
-#include "aeffect.h"\r
-#endif\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-#if TARGET_API_MAC_CARBON\r
- #ifdef __LP64__\r
- #pragma options align=power\r
- #else\r
- #pragma options align=mac68k\r
- #endif\r
-#elif defined __BORLANDC__\r
- #pragma -a8\r
-#elif defined(__GNUC__)\r
- #pragma pack(push,8)\r
-#elif defined(WIN32) || defined(__FLAT__)\r
- #pragma pack(push)\r
- #pragma pack(8)\r
-#endif\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** String length limits (in characters excl. 0 byte). */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum Vst2StringConstants\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstMaxNameLen = 64, ///< used for #MidiProgramName, #MidiProgramCategory, #MidiKeyName, #VstSpeakerProperties, #VstPinProperties\r
- kVstMaxLabelLen = 64, ///< used for #VstParameterProperties->label, #VstPinProperties->label\r
- kVstMaxShortLabelLen = 8, ///< used for #VstParameterProperties->shortLabel, #VstPinProperties->shortLabel\r
- kVstMaxCategLabelLen = 24, ///< used for #VstParameterProperties->label\r
- kVstMaxFileNameLen = 100 ///< used for #VstAudioFile->name\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-//-------------------------------------------------------------------------------------------------------\r
-// VstEvent\r
-//-------------------------------------------------------------------------------------------------------\r
-//-------------------------------------------------------------------------------------------------------\r
-/** A generic timestamped event. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstEvent\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 type; ///< @see VstEventTypes\r
- VstInt32 byteSize; ///< size of this event, excl. type and byteSize\r
- VstInt32 deltaFrames; ///< sample frames related to the current block start sample position\r
- VstInt32 flags; ///< generic flags, none defined yet\r
-\r
- char data[16]; ///< data size may vary, depending on event type\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** VstEvent Types used by #VstEvent. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstEventTypes\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstMidiType = 1, ///< MIDI event @see VstMidiEvent\r
- DECLARE_VST_DEPRECATED (kVstAudioType), ///< \deprecated unused event type\r
- DECLARE_VST_DEPRECATED (kVstVideoType), ///< \deprecated unused event type\r
- DECLARE_VST_DEPRECATED (kVstParameterType), ///< \deprecated unused event type\r
- DECLARE_VST_DEPRECATED (kVstTriggerType), ///< \deprecated unused event type\r
- kVstSysExType ///< MIDI system exclusive @see VstMidiSysexEvent\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** A block of events for the current processed audio block. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstEvents\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 numEvents; ///< number of Events in array\r
- VstIntPtr reserved; ///< zero (Reserved for future use)\r
- VstEvent* events[2]; ///< event pointer array, variable size\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** MIDI Event (to be casted from VstEvent). */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstMidiEvent\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 type; ///< #kVstMidiType\r
- VstInt32 byteSize; ///< sizeof (VstMidiEvent)\r
- VstInt32 deltaFrames; ///< sample frames related to the current block start sample position\r
- VstInt32 flags; ///< @see VstMidiEventFlags\r
- VstInt32 noteLength; ///< (in sample frames) of entire note, if available, else 0\r
- VstInt32 noteOffset; ///< offset (in sample frames) into note from note start if available, else 0\r
- char midiData[4]; ///< 1 to 3 MIDI bytes; midiData[3] is reserved (zero)\r
- char detune; ///< -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')\r
- char noteOffVelocity; ///< Note Off Velocity [0, 127]\r
- char reserved1; ///< zero (Reserved for future use)\r
- char reserved2; ///< zero (Reserved for future use)\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in #VstMidiEvent. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstMidiEventFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- 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)\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** MIDI Sysex Event (to be casted from #VstEvent). */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstMidiSysexEvent\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 type; ///< #kVstSysexType\r
- VstInt32 byteSize; ///< sizeof (VstMidiSysexEvent)\r
- VstInt32 deltaFrames; ///< sample frames related to the current block start sample position\r
- VstInt32 flags; ///< none defined yet (should be zero)\r
- VstInt32 dumpBytes; ///< byte size of sysexDump\r
- VstIntPtr resvd1; ///< zero (Reserved for future use)\r
- char* sysexDump; ///< sysex dump\r
- VstIntPtr resvd2; ///< zero (Reserved for future use)\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// VstTimeInfo\r
-//-------------------------------------------------------------------------------------------------------\r
-//-------------------------------------------------------------------------------------------------------\r
-/** VstTimeInfo requested via #audioMasterGetTime. @see AudioEffectX::getTimeInfo \r
-\r
-\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.\r
-\note VstTimeInfo::ppqPos : At tempo 120, 1 quarter makes 1/2 second, so 2.0 ppq translates to 48000 samples at 48kHz sample rate.\r
-.25 ppq is one sixteenth note then. if you need something like 480ppq, you simply multiply ppq by that scaler.\r
-\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 :-). \r
-\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.\r
-*/\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstTimeInfo\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- double samplePos; ///< current Position in audio samples (always valid)\r
- double sampleRate; ///< current Sample Rate in Herz (always valid)\r
- double nanoSeconds; ///< System Time in nanoseconds (10^-9 second)\r
- double ppqPos; ///< Musical Position, in Quarter Note (1.0 equals 1 Quarter Note)\r
- double tempo; ///< current Tempo in BPM (Beats Per Minute)\r
- double barStartPos; ///< last Bar Start Position, in Quarter Note\r
- double cycleStartPos; ///< Cycle Start (left locator), in Quarter Note\r
- double cycleEndPos; ///< Cycle End (right locator), in Quarter Note\r
- VstInt32 timeSigNumerator; ///< Time Signature Numerator (e.g. 3 for 3/4)\r
- VstInt32 timeSigDenominator; ///< Time Signature Denominator (e.g. 4 for 3/4)\r
- 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.\r
- VstInt32 smpteFrameRate; ///< @see VstSmpteFrameRate\r
- VstInt32 samplesToNextClock; ///< MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest clock)\r
- VstInt32 flags; ///< @see VstTimeInfoFlags\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in #VstTimeInfo. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstTimeInfoFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstTransportChanged = 1, ///< indicates that play, cycle or record state has changed\r
- kVstTransportPlaying = 1 << 1, ///< set if Host sequencer is currently playing\r
- kVstTransportCycleActive = 1 << 2, ///< set if Host sequencer is in cycle mode\r
- kVstTransportRecording = 1 << 3, ///< set if Host sequencer is in record mode\r
- kVstAutomationWriting = 1 << 6, ///< set if automation write mode active (record parameter changes)\r
- kVstAutomationReading = 1 << 7, ///< set if automation read mode active (play parameter changes)\r
- kVstNanosValid = 1 << 8, ///< VstTimeInfo::nanoSeconds valid\r
- kVstPpqPosValid = 1 << 9, ///< VstTimeInfo::ppqPos valid\r
- kVstTempoValid = 1 << 10, ///< VstTimeInfo::tempo valid\r
- kVstBarsValid = 1 << 11, ///< VstTimeInfo::barStartPos valid\r
- kVstCyclePosValid = 1 << 12, ///< VstTimeInfo::cycleStartPos and VstTimeInfo::cycleEndPos valid\r
- kVstTimeSigValid = 1 << 13, ///< VstTimeInfo::timeSigNumerator and VstTimeInfo::timeSigDenominator valid\r
- kVstSmpteValid = 1 << 14, ///< VstTimeInfo::smpteOffset and VstTimeInfo::smpteFrameRate valid\r
- kVstClockValid = 1 << 15 ///< VstTimeInfo::samplesToNextClock valid\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** SMPTE Frame Rates. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstSmpteFrameRate\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstSmpte24fps = 0, ///< 24 fps\r
- kVstSmpte25fps = 1, ///< 25 fps\r
- kVstSmpte2997fps = 2, ///< 29.97 fps\r
- kVstSmpte30fps = 3, ///< 30 fps\r
- kVstSmpte2997dfps = 4, ///< 29.97 drop\r
- kVstSmpte30dfps = 5, ///< 30 drop\r
-\r
- kVstSmpteFilm16mm = 6, ///< Film 16mm\r
- kVstSmpteFilm35mm = 7, ///< Film 35mm\r
- kVstSmpte239fps = 10, ///< HDTV: 23.976 fps\r
- kVstSmpte249fps = 11, ///< HDTV: 24.976 fps\r
- kVstSmpte599fps = 12, ///< HDTV: 59.94 fps\r
- kVstSmpte60fps = 13 ///< HDTV: 60 fps\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Variable IO for Offline Processing. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstVariableIo\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- float** inputs; ///< input audio buffers\r
- float** outputs; ///< output audio buffers\r
- VstInt32 numSamplesInput; ///< number of incoming samples\r
- VstInt32 numSamplesOutput; ///< number of outgoing samples\r
- VstInt32* numSamplesInputProcessed; ///< number of samples actually processed of input\r
- VstInt32* numSamplesOutputProcessed; ///< number of samples actually processed of output\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Language code returned by audioMasterGetLanguage. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstHostLanguage\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstLangEnglish = 1, ///< English\r
- kVstLangGerman, ///< German\r
- kVstLangFrench, ///< French\r
- kVstLangItalian, ///< Italian\r
- kVstLangSpanish, ///< Spanish\r
- kVstLangJapanese ///< Japanese\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** VST 2.x dispatcher Opcodes (Plug-in to Host). Extension of #AudioMasterOpcodes */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum AudioMasterOpcodesX\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- DECLARE_VST_DEPRECATED (audioMasterWantMidi) = DECLARE_VST_DEPRECATED (audioMasterPinConnected) + 2, ///< \deprecated deprecated in VST 2.4\r
-\r
- audioMasterGetTime, ///< [return value]: #VstTimeInfo* or null if not supported [value]: request mask @see VstTimeInfoFlags @see AudioEffectX::getTimeInfo\r
- audioMasterProcessEvents, ///< [ptr]: pointer to #VstEvents @see VstEvents @see AudioEffectX::sendVstEventsToHost\r
-\r
- DECLARE_VST_DEPRECATED (audioMasterSetTime), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterTempoAt), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterGetNumAutomatableParameters), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterGetParameterQuantization), ///< \deprecated deprecated in VST 2.4\r
-\r
- audioMasterIOChanged, ///< [return value]: 1 if supported @see AudioEffectX::ioChanged\r
-\r
- DECLARE_VST_DEPRECATED (audioMasterNeedIdle), ///< \deprecated deprecated in VST 2.4\r
- \r
- audioMasterSizeWindow, ///< [index]: new width [value]: new height [return value]: 1 if supported @see AudioEffectX::sizeWindow\r
- audioMasterGetSampleRate, ///< [return value]: current sample rate @see AudioEffectX::updateSampleRate\r
- audioMasterGetBlockSize, ///< [return value]: current block size @see AudioEffectX::updateBlockSize\r
- audioMasterGetInputLatency, ///< [return value]: input latency in audio samples @see AudioEffectX::getInputLatency\r
- audioMasterGetOutputLatency, ///< [return value]: output latency in audio samples @see AudioEffectX::getOutputLatency\r
-\r
- DECLARE_VST_DEPRECATED (audioMasterGetPreviousPlug), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterGetNextPlug), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterWillReplaceOrAccumulate), ///< \deprecated deprecated in VST 2.4\r
-\r
- audioMasterGetCurrentProcessLevel, ///< [return value]: current process level @see VstProcessLevels\r
- audioMasterGetAutomationState, ///< [return value]: current automation state @see VstAutomationStates\r
-\r
- audioMasterOfflineStart, ///< [index]: numNewAudioFiles [value]: numAudioFiles [ptr]: #VstAudioFile* @see AudioEffectX::offlineStart\r
- audioMasterOfflineRead, ///< [index]: bool readSource [value]: #VstOfflineOption* @see VstOfflineOption [ptr]: #VstOfflineTask* @see VstOfflineTask @see AudioEffectX::offlineRead\r
- audioMasterOfflineWrite, ///< @see audioMasterOfflineRead @see AudioEffectX::offlineRead\r
- audioMasterOfflineGetCurrentPass, ///< @see AudioEffectX::offlineGetCurrentPass\r
- audioMasterOfflineGetCurrentMetaPass, ///< @see AudioEffectX::offlineGetCurrentMetaPass\r
-\r
- DECLARE_VST_DEPRECATED (audioMasterSetOutputSampleRate), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterGetOutputSpeakerArrangement), ///< \deprecated deprecated in VST 2.4\r
-\r
- audioMasterGetVendorString, ///< [ptr]: char buffer for vendor string, limited to #kVstMaxVendorStrLen @see AudioEffectX::getHostVendorString\r
- audioMasterGetProductString, ///< [ptr]: char buffer for vendor string, limited to #kVstMaxProductStrLen @see AudioEffectX::getHostProductString\r
- audioMasterGetVendorVersion, ///< [return value]: vendor-specific version @see AudioEffectX::getHostVendorVersion\r
- audioMasterVendorSpecific, ///< no definition, vendor specific handling @see AudioEffectX::hostVendorSpecific\r
- \r
- DECLARE_VST_DEPRECATED (audioMasterSetIcon), ///< \deprecated deprecated in VST 2.4\r
- \r
- audioMasterCanDo, ///< [ptr]: "can do" string [return value]: 1 for supported\r
- audioMasterGetLanguage, ///< [return value]: language code @see VstHostLanguage\r
-\r
- DECLARE_VST_DEPRECATED (audioMasterOpenWindow), ///< \deprecated deprecated in VST 2.4\r
- DECLARE_VST_DEPRECATED (audioMasterCloseWindow), ///< \deprecated deprecated in VST 2.4\r
-\r
- audioMasterGetDirectory, ///< [return value]: FSSpec on MAC, else char* @see AudioEffectX::getDirectory\r
- audioMasterUpdateDisplay, ///< no arguments \r
- audioMasterBeginEdit, ///< [index]: parameter index @see AudioEffectX::beginEdit\r
- audioMasterEndEdit, ///< [index]: parameter index @see AudioEffectX::endEdit\r
- audioMasterOpenFileSelector, ///< [ptr]: VstFileSelect* [return value]: 1 if supported @see AudioEffectX::openFileSelector\r
- audioMasterCloseFileSelector, ///< [ptr]: VstFileSelect* @see AudioEffectX::closeFileSelector\r
- \r
- DECLARE_VST_DEPRECATED (audioMasterEditFile), ///< \deprecated deprecated in VST 2.4\r
- \r
- DECLARE_VST_DEPRECATED (audioMasterGetChunkFile), ///< \deprecated deprecated in VST 2.4 [ptr]: char[2048] or sizeof (FSSpec) [return value]: 1 if supported @see AudioEffectX::getChunkFile\r
-\r
- DECLARE_VST_DEPRECATED (audioMasterGetInputSpeakerArrangement) ///< \deprecated deprecated in VST 2.4\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** VST 2.x dispatcher Opcodes (Host to Plug-in). Extension of #AEffectOpcodes */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum AEffectXOpcodes\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- effProcessEvents = effSetChunk + 1 ///< [ptr]: #VstEvents* @see AudioEffectX::processEvents\r
-\r
- , effCanBeAutomated ///< [index]: parameter index [return value]: 1=true, 0=false @see AudioEffectX::canParameterBeAutomated\r
- , effString2Parameter ///< [index]: parameter index [ptr]: parameter string [return value]: true for success @see AudioEffectX::string2parameter\r
-\r
- , DECLARE_VST_DEPRECATED (effGetNumProgramCategories) ///< \deprecated deprecated in VST 2.4\r
-\r
- , effGetProgramNameIndexed ///< [index]: program index [ptr]: buffer for program name, limited to #kVstMaxProgNameLen [return value]: true for success @see AudioEffectX::getProgramNameIndexed\r
- \r
- , DECLARE_VST_DEPRECATED (effCopyProgram) ///< \deprecated deprecated in VST 2.4\r
- , DECLARE_VST_DEPRECATED (effConnectInput) ///< \deprecated deprecated in VST 2.4\r
- , DECLARE_VST_DEPRECATED (effConnectOutput) ///< \deprecated deprecated in VST 2.4\r
- \r
- , effGetInputProperties ///< [index]: input index [ptr]: #VstPinProperties* [return value]: 1 if supported @see AudioEffectX::getInputProperties\r
- , effGetOutputProperties ///< [index]: output index [ptr]: #VstPinProperties* [return value]: 1 if supported @see AudioEffectX::getOutputProperties\r
- , effGetPlugCategory ///< [return value]: category @see VstPlugCategory @see AudioEffectX::getPlugCategory\r
-\r
- , DECLARE_VST_DEPRECATED (effGetCurrentPosition) ///< \deprecated deprecated in VST 2.4\r
- , DECLARE_VST_DEPRECATED (effGetDestinationBuffer) ///< \deprecated deprecated in VST 2.4\r
-\r
- , effOfflineNotify ///< [ptr]: #VstAudioFile array [value]: count [index]: start flag @see AudioEffectX::offlineNotify\r
- , effOfflinePrepare ///< [ptr]: #VstOfflineTask array [value]: count @see AudioEffectX::offlinePrepare\r
- , effOfflineRun ///< [ptr]: #VstOfflineTask array [value]: count @see AudioEffectX::offlineRun\r
-\r
- , effProcessVarIo ///< [ptr]: #VstVariableIo* @see AudioEffectX::processVariableIo\r
- , effSetSpeakerArrangement ///< [value]: input #VstSpeakerArrangement* [ptr]: output #VstSpeakerArrangement* @see AudioEffectX::setSpeakerArrangement\r
-\r
- , DECLARE_VST_DEPRECATED (effSetBlockSizeAndSampleRate) ///< \deprecated deprecated in VST 2.4\r
-\r
- , effSetBypass ///< [value]: 1 = bypass, 0 = no bypass @see AudioEffectX::setBypass\r
- , effGetEffectName ///< [ptr]: buffer for effect name, limited to #kVstMaxEffectNameLen @see AudioEffectX::getEffectName\r
-\r
- , DECLARE_VST_DEPRECATED (effGetErrorText) ///< \deprecated deprecated in VST 2.4\r
-\r
- , effGetVendorString ///< [ptr]: buffer for effect vendor string, limited to #kVstMaxVendorStrLen @see AudioEffectX::getVendorString\r
- , effGetProductString ///< [ptr]: buffer for effect vendor string, limited to #kVstMaxProductStrLen @see AudioEffectX::getProductString\r
- , effGetVendorVersion ///< [return value]: vendor-specific version @see AudioEffectX::getVendorVersion\r
- , effVendorSpecific ///< no definition, vendor specific handling @see AudioEffectX::vendorSpecific\r
- , effCanDo ///< [ptr]: "can do" string [return value]: 0: "don't know" -1: "no" 1: "yes" @see AudioEffectX::canDo\r
- , effGetTailSize ///< [return value]: tail size (for example the reverb time of a reverb plug-in); 0 is default (return 1 for 'no tail')\r
-\r
- , DECLARE_VST_DEPRECATED (effIdle) ///< \deprecated deprecated in VST 2.4\r
- , DECLARE_VST_DEPRECATED (effGetIcon) ///< \deprecated deprecated in VST 2.4\r
- , DECLARE_VST_DEPRECATED (effSetViewPosition) ///< \deprecated deprecated in VST 2.4\r
-\r
- , effGetParameterProperties ///< [index]: parameter index [ptr]: #VstParameterProperties* [return value]: 1 if supported @see AudioEffectX::getParameterProperties\r
-\r
- , DECLARE_VST_DEPRECATED (effKeysRequired) ///< \deprecated deprecated in VST 2.4\r
-\r
- , effGetVstVersion ///< [return value]: VST version @see AudioEffectX::getVstVersion\r
-\r
-#if VST_2_1_EXTENSIONS\r
- , effEditKeyDown ///< [index]: ASCII character [value]: virtual key [opt]: modifiers [return value]: 1 if key used @see AEffEditor::onKeyDown\r
- , effEditKeyUp ///< [index]: ASCII character [value]: virtual key [opt]: modifiers [return value]: 1 if key used @see AEffEditor::onKeyUp\r
- , effSetEditKnobMode ///< [value]: knob mode 0: circular, 1: circular relativ, 2: linear (CKnobMode in VSTGUI) @see AEffEditor::setKnobMode\r
-\r
- , effGetMidiProgramName ///< [index]: MIDI channel [ptr]: #MidiProgramName* [return value]: number of used programs, 0 if unsupported @see AudioEffectX::getMidiProgramName\r
- , effGetCurrentMidiProgram ///< [index]: MIDI channel [ptr]: #MidiProgramName* [return value]: index of current program @see AudioEffectX::getCurrentMidiProgram\r
- , effGetMidiProgramCategory ///< [index]: MIDI channel [ptr]: #MidiProgramCategory* [return value]: number of used categories, 0 if unsupported @see AudioEffectX::getMidiProgramCategory\r
- , effHasMidiProgramsChanged ///< [index]: MIDI channel [return value]: 1 if the #MidiProgramName(s) or #MidiKeyName(s) have changed @see AudioEffectX::hasMidiProgramsChanged\r
- , effGetMidiKeyName ///< [index]: MIDI channel [ptr]: #MidiKeyName* [return value]: true if supported, false otherwise @see AudioEffectX::getMidiKeyName\r
- \r
- , effBeginSetProgram ///< no arguments @see AudioEffectX::beginSetProgram\r
- , effEndSetProgram ///< no arguments @see AudioEffectX::endSetProgram\r
-#endif // VST_2_1_EXTENSIONS\r
-\r
-#if VST_2_3_EXTENSIONS\r
- , effGetSpeakerArrangement ///< [value]: input #VstSpeakerArrangement* [ptr]: output #VstSpeakerArrangement* @see AudioEffectX::getSpeakerArrangement\r
- , effShellGetNextPlugin ///< [ptr]: buffer for plug-in name, limited to #kVstMaxProductStrLen [return value]: next plugin's uniqueID @see AudioEffectX::getNextShellPlugin\r
-\r
- , effStartProcess ///< no arguments @see AudioEffectX::startProcess\r
- , effStopProcess ///< no arguments @see AudioEffectX::stopProcess\r
- , effSetTotalSampleToProcess ///< [value]: number of samples to process, offline only! @see AudioEffectX::setTotalSampleToProcess\r
- , effSetPanLaw ///< [value]: pan law [opt]: gain @see VstPanLawType @see AudioEffectX::setPanLaw\r
- \r
- , effBeginLoadBank ///< [ptr]: #VstPatchChunkInfo* [return value]: -1: bank can't be loaded, 1: bank can be loaded, 0: unsupported @see AudioEffectX::beginLoadBank\r
- , effBeginLoadProgram ///< [ptr]: #VstPatchChunkInfo* [return value]: -1: prog can't be loaded, 1: prog can be loaded, 0: unsupported @see AudioEffectX::beginLoadProgram\r
-#endif // VST_2_3_EXTENSIONS\r
-\r
-#if VST_2_4_EXTENSIONS\r
- , effSetProcessPrecision ///< [value]: @see VstProcessPrecision @see AudioEffectX::setProcessPrecision\r
- , effGetNumMidiInputChannels ///< [return value]: number of used MIDI input channels (1-15) @see AudioEffectX::getNumMidiInputChannels\r
- , effGetNumMidiOutputChannels ///< [return value]: number of used MIDI output channels (1-15) @see AudioEffectX::getNumMidiOutputChannels\r
-#endif // VST_2_4_EXTENSIONS\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Symbolic precision constants used for effSetProcessPrecision. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstProcessPrecision\r
-{\r
- kVstProcessPrecision32 = 0, ///< single precision float (32bits)\r
- kVstProcessPrecision64 ///< double precision (64bits)\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Parameter Properties used in #effGetParameterProperties. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstParameterProperties\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- float stepFloat; ///< float step\r
- float smallStepFloat; ///< small float step\r
- float largeStepFloat; ///< large float step\r
- char label[kVstMaxLabelLen];///< parameter label\r
- VstInt32 flags; ///< @see VstParameterFlags\r
- VstInt32 minInteger; ///< integer minimum\r
- VstInt32 maxInteger; ///< integer maximum\r
- VstInt32 stepInteger; ///< integer step\r
- VstInt32 largeStepInteger; ///< large integer step\r
- char shortLabel[kVstMaxShortLabelLen]; ///< short label, recommended: 6 + delimiter\r
-\r
- // The following are for remote controller display purposes.\r
- // Note that the kVstParameterSupportsDisplayIndex flag must be set.\r
- // Host can scan all parameters, and find out in what order\r
- // to display them:\r
-\r
- VstInt16 displayIndex; ///< index where this parameter should be displayed (starting with 0)\r
-\r
- // Host can also possibly display the parameter group (category), such as...\r
- // ---------------------------\r
- // Osc 1\r
- // Wave Detune Octave Mod\r
- // ---------------------------\r
- // ...if the plug-in supports it (flag #kVstParameterSupportsDisplayCategory)\r
-\r
- VstInt16 category; ///< 0: no category, else group index + 1\r
- VstInt16 numParametersInCategory; ///< number of parameters in category\r
- VstInt16 reserved; ///< zero\r
- char categoryLabel[kVstMaxCategLabelLen]; ///< category label, e.g. "Osc 1" \r
-\r
- char future[16]; ///< reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in #VstParameterProperties. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstParameterFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstParameterIsSwitch = 1 << 0, ///< parameter is a switch (on/off)\r
- kVstParameterUsesIntegerMinMax = 1 << 1, ///< minInteger, maxInteger valid\r
- kVstParameterUsesFloatStep = 1 << 2, ///< stepFloat, smallStepFloat, largeStepFloat valid\r
- kVstParameterUsesIntStep = 1 << 3, ///< stepInteger, largeStepInteger valid\r
- kVstParameterSupportsDisplayIndex = 1 << 4, ///< displayIndex valid\r
- kVstParameterSupportsDisplayCategory = 1 << 5, ///< category, etc. valid\r
- kVstParameterCanRamp = 1 << 6 ///< set if parameter value can ramp up/down\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Pin Properties used in #effGetInputProperties and #effGetOutputProperties. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstPinProperties\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- char label[kVstMaxLabelLen]; ///< pin name\r
- VstInt32 flags; ///< @see VstPinPropertiesFlags\r
- VstInt32 arrangementType; ///< @see VstSpeakerArrangementType\r
- char shortLabel[kVstMaxShortLabelLen]; ///< short name (recommended: 6 + delimiter)\r
-\r
- char future[48]; ///< reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in #VstPinProperties. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstPinPropertiesFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstPinIsActive = 1 << 0, ///< pin is active, ignored by Host\r
- kVstPinIsStereo = 1 << 1, ///< pin is first of a stereo pair\r
- kVstPinUseSpeaker = 1 << 2 ///< #VstPinProperties::arrangementType is valid and can be used to get the wanted arrangement\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Plug-in Categories. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstPlugCategory\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kPlugCategUnknown = 0, ///< Unknown, category not implemented\r
- kPlugCategEffect, ///< Simple Effect\r
- kPlugCategSynth, ///< VST Instrument (Synths, samplers,...)\r
- kPlugCategAnalysis, ///< Scope, Tuner, ...\r
- kPlugCategMastering, ///< Dynamics, ...\r
- kPlugCategSpacializer, ///< Panners, ...\r
- kPlugCategRoomFx, ///< Delays and Reverbs\r
- kPlugSurroundFx, ///< Dedicated surround processor\r
- kPlugCategRestoration, ///< Denoiser, ...\r
- kPlugCategOfflineProcess, ///< Offline Process\r
- kPlugCategShell, ///< Plug-in is container of other plug-ins @see effShellGetNextPlugin\r
- kPlugCategGenerator, ///< ToneGenerator, ...\r
-\r
- kPlugCategMaxCount ///< Marker to count the categories\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// MIDI Programs\r
-//-------------------------------------------------------------------------------------------------------\r
-//-------------------------------------------------------------------------------------------------------\r
-/** MIDI Program Description. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct MidiProgramName \r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 thisProgramIndex; ///< 0 or greater: fill struct for this program index\r
- char name[kVstMaxNameLen]; ///< program name\r
- char midiProgram; ///< -1:off, 0-127\r
- char midiBankMsb; ///< -1:off, 0-127\r
- char midiBankLsb; ///< -1:off, 0-127\r
- char reserved; ///< zero\r
- VstInt32 parentCategoryIndex; ///< -1:no parent category\r
- VstInt32 flags; ///< omni etc. @see VstMidiProgramNameFlags\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in MidiProgramName. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstMidiProgramNameFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kMidiIsOmni = 1 ///< default is multi. for omni mode, channel 0 is used for inquiries and program changes\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** MIDI Program Category. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct MidiProgramCategory \r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 thisCategoryIndex; ///< 0 or greater: fill struct for this category index.\r
- char name[kVstMaxNameLen]; ///< name\r
- VstInt32 parentCategoryIndex; ///< -1:no parent category\r
- VstInt32 flags; ///< reserved, none defined yet, zero.\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** MIDI Key Description. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct MidiKeyName \r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 thisProgramIndex; ///< 0 or greater: fill struct for this program index.\r
- VstInt32 thisKeyNumber; ///< 0 - 127. fill struct for this key number.\r
- char keyName[kVstMaxNameLen]; ///< key name, empty means regular key names\r
- VstInt32 reserved; ///< zero\r
- VstInt32 flags; ///< reserved, none defined yet, zero.\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// Surround Setup\r
-//-------------------------------------------------------------------------------------------------------\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Speaker Properties.\r
- The origin for azimuth is right (as by math conventions dealing with radians).\r
- The elevation origin is also right, visualizing a rotation of a circle across the\r
- -pi/pi axis of the horizontal circle. Thus, an elevation of -pi/2 corresponds\r
- to bottom, and a speaker standing on the left, and 'beaming' upwards would have\r
- an azimuth of -pi, and an elevation of pi/2.\r
- For user interface representation, grads are more likely to be used, and the\r
- origins will obviously 'shift' accordingly. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstSpeakerProperties\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- float azimuth; ///< unit: rad, range: -PI...PI, exception: 10.f for LFE channel\r
- float elevation; ///< unit: rad, range: -PI/2...PI/2, exception: 10.f for LFE channel\r
- float radius; ///< unit: meter, exception: 0.f for LFE channel\r
- float reserved; ///< zero (reserved for future use)\r
- char name[kVstMaxNameLen]; ///< for new setups, new names should be given (L/R/C... won't do)\r
- VstInt32 type; ///< @see VstSpeakerType\r
-\r
- char future[28]; ///< reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Speaker Arrangement. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstSpeakerArrangement\r
-{ \r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 type; ///< e.g. #kSpeakerArr51 for 5.1 @see VstSpeakerArrangementType\r
- VstInt32 numChannels; ///< number of channels in this speaker arrangement\r
- VstSpeakerProperties speakers[8]; ///< variable sized speaker array\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Speaker Types. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstSpeakerType\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kSpeakerUndefined = 0x7fffffff, ///< Undefined\r
- kSpeakerM = 0, ///< Mono (M)\r
- kSpeakerL, ///< Left (L)\r
- kSpeakerR, ///< Right (R)\r
- kSpeakerC, ///< Center (C)\r
- kSpeakerLfe, ///< Subbass (Lfe)\r
- kSpeakerLs, ///< Left Surround (Ls)\r
- kSpeakerRs, ///< Right Surround (Rs)\r
- kSpeakerLc, ///< Left of Center (Lc)\r
- kSpeakerRc, ///< Right of Center (Rc)\r
- kSpeakerS, ///< Surround (S)\r
- kSpeakerCs = kSpeakerS, ///< Center of Surround (Cs) = Surround (S)\r
- kSpeakerSl, ///< Side Left (Sl)\r
- kSpeakerSr, ///< Side Right (Sr)\r
- kSpeakerTm, ///< Top Middle (Tm)\r
- kSpeakerTfl, ///< Top Front Left (Tfl)\r
- kSpeakerTfc, ///< Top Front Center (Tfc)\r
- kSpeakerTfr, ///< Top Front Right (Tfr)\r
- kSpeakerTrl, ///< Top Rear Left (Trl)\r
- kSpeakerTrc, ///< Top Rear Center (Trc)\r
- kSpeakerTrr, ///< Top Rear Right (Trr)\r
- kSpeakerLfe2 ///< Subbass 2 (Lfe2)\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** User-defined speaker types, to be extended in the negative range.\r
- Will be handled as their corresponding speaker types with abs values:\r
- e.g abs(#kSpeakerU1) == #kSpeakerL, abs(#kSpeakerU2) == #kSpeakerR) */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstUserSpeakerType\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kSpeakerU32 = -32, \r
- kSpeakerU31, \r
- kSpeakerU30, \r
- kSpeakerU29, \r
- kSpeakerU28, \r
- kSpeakerU27, \r
- kSpeakerU26, \r
- kSpeakerU25, \r
- kSpeakerU24, \r
- kSpeakerU23, \r
- kSpeakerU22, \r
- kSpeakerU21, \r
- kSpeakerU20, ///< == #kSpeakerLfe2\r
- kSpeakerU19, ///< == #kSpeakerTrr\r
- kSpeakerU18, ///< == #kSpeakerTrc\r
- kSpeakerU17, ///< == #kSpeakerTrl\r
- kSpeakerU16, ///< == #kSpeakerTfr\r
- kSpeakerU15, ///< == #kSpeakerTfc\r
- kSpeakerU14, ///< == #kSpeakerTfl\r
- kSpeakerU13, ///< == #kSpeakerTm\r
- kSpeakerU12, ///< == #kSpeakerSr\r
- kSpeakerU11, ///< == #kSpeakerSl\r
- kSpeakerU10, ///< == #kSpeakerCs\r
- kSpeakerU9, ///< == #kSpeakerS\r
- kSpeakerU8, ///< == #kSpeakerRc\r
- kSpeakerU7, ///< == #kSpeakerLc\r
- kSpeakerU6, ///< == #kSpeakerRs\r
- kSpeakerU5, ///< == #kSpeakerLs\r
- kSpeakerU4, ///< == #kSpeakerLfe\r
- kSpeakerU3, ///< == #kSpeakerC\r
- kSpeakerU2, ///< == #kSpeakerR\r
- kSpeakerU1 ///< == #kSpeakerL\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Speaker Arrangement Types*/\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstSpeakerArrangementType\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kSpeakerArrUserDefined = -2,///< user defined\r
- kSpeakerArrEmpty = -1, ///< empty arrangement\r
- kSpeakerArrMono = 0, ///< M\r
- kSpeakerArrStereo, ///< L R\r
- kSpeakerArrStereoSurround, ///< Ls Rs\r
- kSpeakerArrStereoCenter, ///< Lc Rc\r
- kSpeakerArrStereoSide, ///< Sl Sr\r
- kSpeakerArrStereoCLfe, ///< C Lfe\r
- kSpeakerArr30Cine, ///< L R C\r
- kSpeakerArr30Music, ///< L R S\r
- kSpeakerArr31Cine, ///< L R C Lfe\r
- kSpeakerArr31Music, ///< L R Lfe S\r
- kSpeakerArr40Cine, ///< L R C S (LCRS)\r
- kSpeakerArr40Music, ///< L R Ls Rs (Quadro)\r
- kSpeakerArr41Cine, ///< L R C Lfe S (LCRS+Lfe)\r
- kSpeakerArr41Music, ///< L R Lfe Ls Rs (Quadro+Lfe)\r
- kSpeakerArr50, ///< L R C Ls Rs \r
- kSpeakerArr51, ///< L R C Lfe Ls Rs\r
- kSpeakerArr60Cine, ///< L R C Ls Rs Cs\r
- kSpeakerArr60Music, ///< L R Ls Rs Sl Sr \r
- kSpeakerArr61Cine, ///< L R C Lfe Ls Rs Cs\r
- kSpeakerArr61Music, ///< L R Lfe Ls Rs Sl Sr \r
- kSpeakerArr70Cine, ///< L R C Ls Rs Lc Rc \r
- kSpeakerArr70Music, ///< L R C Ls Rs Sl Sr\r
- kSpeakerArr71Cine, ///< L R C Lfe Ls Rs Lc Rc\r
- kSpeakerArr71Music, ///< L R C Lfe Ls Rs Sl Sr\r
- kSpeakerArr80Cine, ///< L R C Ls Rs Lc Rc Cs\r
- kSpeakerArr80Music, ///< L R C Ls Rs Cs Sl Sr\r
- kSpeakerArr81Cine, ///< L R C Lfe Ls Rs Lc Rc Cs\r
- kSpeakerArr81Music, ///< L R C Lfe Ls Rs Cs Sl Sr \r
- kSpeakerArr102, ///< L R C Lfe Ls Rs Tfl Tfc Tfr Trl Trr Lfe2\r
- kNumSpeakerArr\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// Offline Processing\r
-//-------------------------------------------------------------------------------------------------------\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Offline Task Description. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstOfflineTask\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- char processName[96]; ///< set by plug-in\r
-\r
- // audio access\r
- double readPosition; ///< set by plug-in/Host\r
- double writePosition; ///< set by plug-in/Host\r
- VstInt32 readCount; ///< set by plug-in/Host\r
- VstInt32 writeCount; ///< set by plug-in\r
- VstInt32 sizeInputBuffer; ///< set by Host\r
- VstInt32 sizeOutputBuffer; ///< set by Host\r
- void* inputBuffer; ///< set by Host\r
- void* outputBuffer; ///< set by Host\r
- double positionToProcessFrom; ///< set by Host\r
- double numFramesToProcess; ///< set by Host\r
- double maxFramesToWrite; ///< set by plug-in\r
-\r
- // other data access\r
- void* extraBuffer; ///< set by plug-in\r
- VstInt32 value; ///< set by Host or plug-in\r
- VstInt32 index; ///< set by Host or plug-in\r
-\r
- // file attributes\r
- double numFramesInSourceFile; ///< set by Host\r
- double sourceSampleRate; ///< set by Host or plug-in\r
- double destinationSampleRate; ///< set by Host or plug-in\r
- VstInt32 numSourceChannels; ///< set by Host or plug-in\r
- VstInt32 numDestinationChannels;///< set by Host or plug-in\r
- VstInt32 sourceFormat; ///< set by Host\r
- VstInt32 destinationFormat; ///< set by plug-in\r
- char outputText[512]; ///< set by plug-in or Host\r
-\r
- // progress notification\r
- double progress; ///< set by plug-in\r
- VstInt32 progressMode; ///< Reserved for future use\r
- char progressText[100]; ///< set by plug-in\r
-\r
- VstInt32 flags; ///< set by Host and plug-in; see enum #VstOfflineTaskFlags\r
- VstInt32 returnValue; ///< Reserved for future use\r
- void* hostOwned; ///< set by Host\r
- void* plugOwned; ///< set by plug-in\r
-\r
- char future[1024]; ///< Reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in #VstOfflineTask. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstOfflineTaskFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstOfflineUnvalidParameter = 1 << 0, ///< set by Host\r
- kVstOfflineNewFile = 1 << 1, ///< set by Host\r
-\r
- kVstOfflinePlugError = 1 << 10, ///< set by plug-in\r
- kVstOfflineInterleavedAudio = 1 << 11, ///< set by plug-in\r
- kVstOfflineTempOutputFile = 1 << 12, ///< set by plug-in\r
- kVstOfflineFloatOutputFile = 1 << 13, ///< set by plug-in\r
- kVstOfflineRandomWrite = 1 << 14, ///< set by plug-in\r
- kVstOfflineStretch = 1 << 15, ///< set by plug-in\r
- kVstOfflineNoThread = 1 << 16 ///< set by plug-in\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Option passed to #offlineRead/#offlineWrite. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstOfflineOption\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstOfflineAudio, ///< reading/writing audio samples\r
- kVstOfflinePeaks, ///< reading graphic representation\r
- kVstOfflineParameter, ///< reading/writing parameters\r
- kVstOfflineMarker, ///< reading/writing marker\r
- kVstOfflineCursor, ///< reading/moving edit cursor\r
- kVstOfflineSelection, ///< reading/changing selection\r
- kVstOfflineQueryFiles ///< to request the Host to call asynchronously #offlineNotify\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Structure passed to #offlineNotify and #offlineStart */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstAudioFile\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 flags; ///< see enum #VstAudioFileFlags\r
- void* hostOwned; ///< any data private to Host\r
- void* plugOwned; ///< any data private to plug-in\r
- char name[kVstMaxFileNameLen]; ///< file title\r
- VstInt32 uniqueId; ///< uniquely identify a file during a session\r
- double sampleRate; ///< file sample rate\r
- VstInt32 numChannels; ///< number of channels (1 for mono, 2 for stereo...)\r
- double numFrames; ///< number of frames in the audio file\r
- VstInt32 format; ///< Reserved for future use\r
- double editCursorPosition; ///< -1 if no such cursor\r
- double selectionStart; ///< frame index of first selected frame, or -1\r
- double selectionSize; ///< number of frames in selection, or 0\r
- VstInt32 selectedChannelsMask; ///< 1 bit per channel\r
- VstInt32 numMarkers; ///< number of markers in the file\r
- VstInt32 timeRulerUnit; ///< see doc for possible values\r
- double timeRulerOffset; ///< offset in time ruler (positive or negative)\r
- double tempo; ///< as BPM (Beats Per Minute)\r
- VstInt32 timeSigNumerator; ///< time signature numerator\r
- VstInt32 timeSigDenominator; ///< time signature denominator\r
- VstInt32 ticksPerBlackNote; ///< resolution\r
- VstInt32 smpteFrameRate; ///< SMPTE rate (set as in #VstTimeInfo)\r
-\r
- char future[64]; ///< Reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Flags used in #VstAudioFile. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstAudioFileFlags\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstOfflineReadOnly = 1 << 0, ///< set by Host (in call #offlineNotify)\r
- kVstOfflineNoRateConversion = 1 << 1, ///< set by Host (in call #offlineNotify)\r
- kVstOfflineNoChannelChange = 1 << 2, ///< set by Host (in call #offlineNotify)\r
-\r
- kVstOfflineCanProcessSelection = 1 << 10, ///< set by plug-in (in call #offlineStart)\r
- kVstOfflineNoCrossfade = 1 << 11, ///< set by plug-in (in call #offlineStart)\r
- kVstOfflineWantRead = 1 << 12, ///< set by plug-in (in call #offlineStart)\r
- kVstOfflineWantWrite = 1 << 13, ///< set by plug-in (in call #offlineStart)\r
- kVstOfflineWantWriteMarker = 1 << 14, ///< set by plug-in (in call #offlineStart)\r
- kVstOfflineWantMoveCursor = 1 << 15, ///< set by plug-in (in call #offlineStart)\r
- kVstOfflineWantSelect = 1 << 16 ///< set by plug-in (in call #offlineStart)\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Audio file marker. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstAudioFileMarker\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- double position; ///< marker position\r
- char name[32]; ///< marker name\r
- VstInt32 type; ///< marker type\r
- VstInt32 id; ///< marker identifier\r
- VstInt32 reserved; ///< reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-// Others\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** \deprecated Structure used for #openWindow and #closeWindow (deprecated in VST 2.4). */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct DECLARE_VST_DEPRECATED (VstWindow)\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- char title[128];\r
- VstInt16 xPos;\r
- VstInt16 yPos;\r
- VstInt16 width;\r
- VstInt16 height;\r
- VstInt32 style;\r
- void* parent;\r
- void* userHandle;\r
- void* winHandle;\r
-\r
- char future[104];\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Structure used for keyUp/keyDown. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstKeyCode\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 character; ///< ASCII character\r
- unsigned char virt; ///< @see VstVirtualKey\r
- unsigned char modifier; ///< @see VstModifierKey\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Platform-independent definition of Virtual Keys (used in #VstKeyCode). */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstVirtualKey \r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VKEY_BACK = 1, \r
- VKEY_TAB, \r
- VKEY_CLEAR, \r
- VKEY_RETURN, \r
- VKEY_PAUSE, \r
- VKEY_ESCAPE, \r
- VKEY_SPACE, \r
- VKEY_NEXT, \r
- VKEY_END, \r
- VKEY_HOME, \r
- VKEY_LEFT, \r
- VKEY_UP, \r
- VKEY_RIGHT, \r
- VKEY_DOWN, \r
- VKEY_PAGEUP, \r
- VKEY_PAGEDOWN, \r
- VKEY_SELECT, \r
- VKEY_PRINT, \r
- VKEY_ENTER, \r
- VKEY_SNAPSHOT, \r
- VKEY_INSERT, \r
- VKEY_DELETE, \r
- VKEY_HELP, \r
- VKEY_NUMPAD0, \r
- VKEY_NUMPAD1, \r
- VKEY_NUMPAD2, \r
- VKEY_NUMPAD3, \r
- VKEY_NUMPAD4, \r
- VKEY_NUMPAD5, \r
- VKEY_NUMPAD6, \r
- VKEY_NUMPAD7, \r
- VKEY_NUMPAD8, \r
- VKEY_NUMPAD9, \r
- VKEY_MULTIPLY, \r
- VKEY_ADD, \r
- VKEY_SEPARATOR, \r
- VKEY_SUBTRACT, \r
- VKEY_DECIMAL, \r
- VKEY_DIVIDE, \r
- VKEY_F1, \r
- VKEY_F2, \r
- VKEY_F3, \r
- VKEY_F4, \r
- VKEY_F5, \r
- VKEY_F6, \r
- VKEY_F7, \r
- VKEY_F8, \r
- VKEY_F9, \r
- VKEY_F10, \r
- VKEY_F11, \r
- VKEY_F12, \r
- VKEY_NUMLOCK, \r
- VKEY_SCROLL,\r
- VKEY_SHIFT,\r
- VKEY_CONTROL,\r
- VKEY_ALT,\r
- VKEY_EQUALS\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Modifier flags used in #VstKeyCode. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstModifierKey\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- MODIFIER_SHIFT = 1<<0, ///< Shift\r
- MODIFIER_ALTERNATE = 1<<1, ///< Alt\r
- MODIFIER_COMMAND = 1<<2, ///< Control on Mac\r
- MODIFIER_CONTROL = 1<<3 ///< Ctrl on PC, Apple on Mac\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** File filter used in #VstFileSelect. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstFileType\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- char name[128]; ///< display name\r
- char macType[8]; ///< MacOS type\r
- char dosType[8]; ///< Windows file extension\r
- char unixType[8]; ///< Unix file extension\r
- char mimeType1[128]; ///< MIME type\r
- char mimeType2[128]; ///< additional MIME type\r
-\r
- VstFileType (const char* _name = 0, const char* _macType = 0, const char* _dosType = 0,\r
- const char* _unixType = 0, const char* _mimeType1 = 0, const char* _mimeType2 = 0)\r
- {\r
- vst_strncpy (name, _name ? _name : "", 127);\r
- vst_strncpy (macType, _macType ? _macType : "", 7);\r
- vst_strncpy (dosType, _dosType ? _dosType : "", 7);\r
- vst_strncpy (unixType, _unixType ? _unixType : "", 7);\r
- vst_strncpy (mimeType1, _mimeType1 ? _mimeType1 : "", 127);\r
- vst_strncpy (mimeType2, _mimeType2 ? _mimeType2 : "", 127);\r
- }\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** File Selector Description used in #audioMasterOpenFileSelector. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstFileSelect\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 command; ///< @see VstFileSelectCommand\r
- VstInt32 type; ///< @see VstFileSelectType\r
- VstInt32 macCreator; ///< optional: 0 = no creator\r
- VstInt32 nbFileTypes; ///< number of fileTypes\r
- VstFileType* fileTypes; ///< list of fileTypes @see VstFileType\r
- char title[1024]; ///< text to display in file selector's title\r
- char* initialPath; ///< initial path\r
- char* returnPath; ///< use with #kVstFileLoad and #kVstDirectorySelect. null: Host allocates memory, plug-in must call #closeOpenFileSelector!\r
- VstInt32 sizeReturnPath; ///< size of allocated memory for return paths\r
- char** returnMultiplePaths; ///< use with kVstMultipleFilesLoad. Host allocates memory, plug-in must call #closeOpenFileSelector!\r
- VstInt32 nbReturnPath; ///< number of selected paths\r
- VstIntPtr reserved; ///< reserved for Host application\r
-\r
- char future[116]; ///< reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Command constants used in #VstFileSelect structure. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstFileSelectCommand\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstFileLoad = 0, ///< for loading a file\r
- kVstFileSave, ///< for saving a file\r
- kVstMultipleFilesLoad, ///< for loading multiple files\r
- kVstDirectorySelect ///< for selecting a directory/folder\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Types used in #VstFileSelect structure. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstFileSelectType\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstFileType = 0 ///< regular file selector\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Structure used for #effBeginLoadBank/#effBeginLoadProgram. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct VstPatchChunkInfo\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 version; ///< Format Version (should be 1)\r
- VstInt32 pluginUniqueID; ///< UniqueID of the plug-in\r
- VstInt32 pluginVersion; ///< Plug-in Version\r
- VstInt32 numElements; ///< Number of Programs (Bank) or Parameters (Program)\r
-\r
- char future[48]; ///< Reserved for future use\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** PanLaw Type. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstPanLawType\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kLinearPanLaw = 0, ///< L = pan * M; R = (1 - pan) * M;\r
- kEqualPowerPanLaw ///< L = pow (pan, 0.5) * M; R = pow ((1 - pan), 0.5) * M;\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Process Levels returned by #audioMasterGetCurrentProcessLevel. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstProcessLevels\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstProcessLevelUnknown = 0, ///< not supported by Host\r
- kVstProcessLevelUser, ///< 1: currently in user thread (GUI)\r
- kVstProcessLevelRealtime, ///< 2: currently in audio thread (where process is called)\r
- kVstProcessLevelPrefetch, ///< 3: currently in 'sequencer' thread (MIDI, timer etc)\r
- kVstProcessLevelOffline ///< 4: currently offline processing and thus in user thread\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Automation States returned by #audioMasterGetAutomationState. */\r
-//-------------------------------------------------------------------------------------------------------\r
-enum VstAutomationStates\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- kVstAutomationUnsupported = 0, ///< not supported by Host\r
- kVstAutomationOff, ///< off\r
- kVstAutomationRead, ///< read\r
- kVstAutomationWrite, ///< write\r
- kVstAutomationReadWrite ///< read and write\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-#if TARGET_API_MAC_CARBON\r
- #pragma options align=reset\r
-#elif defined(WIN32) || defined(__FLAT__) || defined(__GNUC__)\r
- #pragma pack(pop)\r
-#elif defined __BORLANDC__\r
- #pragma -a-\r
-#endif\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#endif //__aeffectx__\r
+++ /dev/null
-//-------------------------------------------------------------------------------------------------------\r
-// VST Plug-Ins SDK\r
-// Version 2.4 $Date: 2006/02/09 11:05:51 $\r
-//\r
-// Category : VST 2.x Interfaces\r
-// Filename : vstfxstore.h\r
-// Created by : Steinberg Media Technologies\r
-// Description : Definition of Program (fxp) and Bank (fxb) structures\r
-//\r
-// © 2006, Steinberg Media Technologies, All Rights Reserved\r
-//-------------------------------------------------------------------------------------------------------\r
-\r
-#ifndef __vstfxstore__\r
-#define __vstfxstore__\r
-\r
-#ifndef __aeffect__\r
-#include "aeffect.h"\r
-#endif\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Root chunk identifier for Programs (fxp) and Banks (fxb). */\r
-#define cMagic 'CcnK'\r
-\r
-/** Regular Program (fxp) identifier. */\r
-#define fMagic 'FxCk'\r
-\r
-/** Regular Bank (fxb) identifier. */\r
-#define bankMagic 'FxBk'\r
-\r
-/** Program (fxp) identifier for opaque chunk data. */\r
-#define chunkPresetMagic 'FPCh'\r
-\r
-/** Bank (fxb) identifier for opaque chunk data. */\r
-#define chunkBankMagic 'FBCh'\r
-\r
-/* \r
- Note: The C data structures below are for illustration only. You can not read/write them directly.\r
- The byte order on disk of fxp and fxb files is Big Endian. You have to swap integer\r
- and floating-point values on Little Endian platforms (Windows, MacIntel)!\r
-*/\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Program (fxp) structure. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct fxProgram\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 chunkMagic; ///< 'CcnK'\r
- VstInt32 byteSize; ///< size of this chunk, excl. magic + byteSize\r
-\r
- VstInt32 fxMagic; ///< 'FxCk' (regular) or 'FPCh' (opaque chunk)\r
- VstInt32 version; ///< format version (currently 1)\r
- VstInt32 fxID; ///< fx unique ID\r
- VstInt32 fxVersion; ///< fx version\r
-\r
- VstInt32 numParams; ///< number of parameters\r
- char prgName[28]; ///< program name (null-terminated ASCII string)\r
-\r
- union\r
- {\r
- float params[1]; ///< variable sized array with parameter values\r
- struct \r
- {\r
- VstInt32 size; ///< size of program data\r
- char chunk[1]; ///< variable sized array with opaque program data\r
- } data; ///< program chunk data\r
- } content; ///< program content depending on fxMagic\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-//-------------------------------------------------------------------------------------------------------\r
-/** Bank (fxb) structure. */\r
-//-------------------------------------------------------------------------------------------------------\r
-struct fxBank\r
-{\r
-//-------------------------------------------------------------------------------------------------------\r
- VstInt32 chunkMagic; ///< 'CcnK'\r
- VstInt32 byteSize; ///< size of this chunk, excl. magic + byteSize\r
-\r
- VstInt32 fxMagic; ///< 'FxBk' (regular) or 'FBCh' (opaque chunk)\r
- VstInt32 version; ///< format version (1 or 2)\r
- VstInt32 fxID; ///< fx unique ID\r
- VstInt32 fxVersion; ///< fx version\r
-\r
- VstInt32 numPrograms; ///< number of programs\r
-\r
-#if VST_2_4_EXTENSIONS\r
- VstInt32 currentProgram; ///< version 2: current program number\r
- char future[124]; ///< reserved, should be zero\r
-#else\r
- char future[128]; ///< reserved, should be zero\r
-#endif\r
-\r
- union\r
- {\r
- fxProgram programs[1]; ///< variable number of programs\r
- struct\r
- {\r
- VstInt32 size; ///< size of bank data\r
- char chunk[1]; ///< variable sized array with opaque bank data\r
- } data; ///< bank chunk data\r
- } content; ///< bank content depending on fxMagic\r
-//-------------------------------------------------------------------------------------------------------\r
-};\r
-\r
-#endif // __vstfxstore__\r
--- /dev/null
+/* -----------------------------------------------------------------------------
+ *
+ * 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;
+}
--- /dev/null
+/* -----------------------------------------------------------------------------
+ *
+ * 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/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef GLUE_CHANNEL_H
+#define GLUE_CHANNEL_H
+
+
+#include "../core/patch.h"
+
+
+using std::string;
+
+
+/* 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);
+
+/* deleteChannel
+ * Remove a channel from Mixer. */
+
+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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
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];
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)
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();
}
* 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;
}
/* 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);
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);
*
* ---------------------------------------------------------------------
*
- * 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.
*
#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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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"
#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();
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);
}
}
/* 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");
/* 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);
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;
}
/* 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;
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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);
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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
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++;
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);
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
*
* ---------------------------------------------------------------------
*
- * 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.
*
#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
class gEnvelopeChannel *vc;
class gPianoRollContainer *pr;
- gVector <class gActionWidget*> widgets;
+ vector <class gActionWidget*> widgets;
class Channel *chan;
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;
};
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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"
/* 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();
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
extern MidiMapConf G_MidiMap;
-/* -------------------------------------------------------------------------- */
+using std::string;
gTabMisc::gTabMisc(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))
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)
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");
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)");
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);
}
{
/* 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();
fetchInChans(sounddevIn->value());
sounddevIn->activate();
+ samplerate->activate();
}
else {
sounddevOut->deactivate();
sounddevOut->value(0);
channelsOut->deactivate();
devOutInfo->deactivate();
+ samplerate->deactivate();
sounddevIn->deactivate();
sounddevIn->clear();
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;
}
/* 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] = '-';
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 */
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());
}
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)'
}
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)'
}
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);
}
}
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;
#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;
}
}
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();
}
}
*
* ---------------------------------------------------------------------
*
- * 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.
*
#include "../elems/ge_window.h"
+using std::string;
+
+
class gdConfig : public gWindow
{
private:
int systemInitValue;
public:
-
+
class gChoice *system;
class gChoice *portOut;
class gChoice *portIn;
*
* ---------------------------------------------------------------------
*
- * 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.
*
#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();
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);
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
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;
}
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;
}
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();
*
* ---------------------------------------------------------------------
*
- * 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.
*
class gSoundMeter *outMeter;
class gSoundMeter *inMeter;
- class gBeatMeter *beatMeter;
class gDial *outVol;
class gDial *inVol;
#ifdef WITH_VST
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
* 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
redraw();
/* set 'full' flag to FX button */
-
+
/* TODO - awful stuff... we should subclass into gdPluginListChannel and
gdPluginListMaster */
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;
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
/* 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);
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!
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
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);
}
/* 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);
}
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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"
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());
}
}
if (fails) {
- if (paths.size > 1)
+ if (paths.size() > 1)
gdAlert("Some files were not loaded successfully.");
else
parent->printChannelMessage(result);
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
p.fValue = fValue;
p.x = px;
p.y = py;
- points.add(p);
+ points.push_back(p);
}
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;
}
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();
/* 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);
/* 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();
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;
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]
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));
}
/* 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() &&
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)
*
* ---------------------------------------------------------------------
*
- * 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.
*
#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;
/* points
* array of points, filled by fillPoints() */
- gVector<point> points;
+ vector<point> points;
/* selectedPoint
* which point we are selecting? */
*
* -----------------------------------------------------------------------------
*
- * 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.
*
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);
/* 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 */
if (!col) {
__cb_addColumn();
- col = columns.last();
+ col = columns.back();
col->setIndex(colIndex);
gLog("[gKeyboard::addChannel] created new column with index=%d\n", colIndex);
}
void gKeyboard::refreshColumns()
{
- for (unsigned i=0; i<columns.size; i++)
+ for (unsigned i=0; i<columns.size(); i++)
columns.at(i)->refreshChannels();
}
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;
* 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;
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
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;
}
gColumn *gc = new gColumn(colx, y(), width, 2000, indexColumn, this);
add(gc);
- columns.add(gc);
+ columns.push_back(gc);
indexColumn++;
/* move addColumn button */
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 */
void gKeyboard::refreshColIndexes()
{
- for (unsigned i=0; i<columns.size; i++)
+ for (unsigned i=0; i<columns.size(); i++)
columns.at(i)->setIndex(i);
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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:
/* 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);
/* columns
* a vector of columns which in turn contain channels. */
- gVector<gColumn*> columns;
+ vector<gColumn*> columns;
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
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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"
{"Setup keyboard input..."}, // 5
{"Setup MIDI input..."}, // 6
{"Setup MIDI output..."}, // 7
- {"Delete channel"}, // 8
+ {"Clone channel"}, // 8
+ {"Delete channel"}, // 9
{0}
};
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);
mainButton->setKey(ch->key);
#ifdef WITH_VST
- fx->full = ch->plugins.size > 0;
+ fx->full = ch->plugins.size() > 0;
#endif
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
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));
}
clip(false),
mixerPeak(0.0f),
peak(0.0f),
- peak_old(0.0f),
db_level(0.0f),
db_level_old(0.0f) {}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
float mixerPeak; // peak from mixer
private:
float peak;
- float peak_old;
float db_level;
float db_level_old;
};
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;
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
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 */
/* 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);
}
}
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;
}
* 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;
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())
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;
/* 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;
*
* ---------------------------------------------------------------------
*
- * 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.
*
#ifndef GE_MUTECHANNEL_H
#define GE_MUTECHANNEL_H
+
+#include <vector>
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
#include "ge_actionWidget.h"
-class gMuteChannel : public gActionWidget {
+using std::vector;
+
+class gMuteChannel : public gActionWidget
+{
private:
/* point
/* points
* array of on/off points, in frames */
- gVector<point> points;
+ vector<point> points;
/* draggedPoint
* which point we are dragging? */
/* 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
*
* ---------------------------------------------------------------------
*
- * 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.
*
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? */
/* ------------------------------------------------------------------ */
-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),
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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"
{"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 */
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;
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);
}
mainButton->setKey(ch->key);
#ifdef WITH_VST
- fx->full = ch->plugins.size > 0;
+ fx->full = ch->plugins.size() > 0;
fx->redraw();
#endif
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
grid.snap = G_Conf.sampleEditorGridOn;
grid.level = G_Conf.sampleEditorGridVal;
-
+
stretchToWindow();
}
/* ------------------------------------------------------------------ */
-gWaveform::~gWaveform()
+gWaveform::~gWaveform()
{
freeData();
}
/* ------------------------------------------------------------------ */
-void gWaveform::freeData()
+void gWaveform::freeData()
{
if (data.sup != NULL) {
free(data.sup);
int gridFreq = 0;
if (grid.level != 0) {
- gridFreq = chan->wave->size / grid.level;
+ gridFreq = chan->wave->size / grid.level;
if (gridFreq % 2 != 0)
gridFreq--;
}
if (gridFreq != 0)
if (k % gridFreq == 0 && k != 0)
- grid.points.add(i);
-
+ grid.points.push_back(i);
+
k += 2;
}
/* ------------------------------------------------------------------ */
-void gWaveform::recalcPoints()
+void gWaveform::recalcPoints()
{
selectionA = relativePoint(selectionA_abs);
selectionB = relativePoint(selectionB_abs);
/* ------------------------------------------------------------------ */
-void gWaveform::draw()
+void gWaveform::draw()
{
/* blank canvas */
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));
/* ------------------------------------------------------------------ */
-int gWaveform::handle(int e)
+int gWaveform::handle(int e)
{
int ret = 0;
if (chanStartLit && pushed) {
chanStart = Fl::event_x() - x();
-
- if (grid.snap)
+
+ if (grid.snap)
chanStart = applySnap(chanStart);
if (chanStart < 0)
else
if (chanStart >= chanEnd)
chanStart = chanEnd-2;
-
+
redraw();
}
else
chanEnd = Fl::event_x() - x();
- if (grid.snap)
+ if (grid.snap)
chanEnd = applySnap(chanEnd);
if (chanEnd >= data.size - 2)
if (selectionB <= 0)
selectionB = 0;
-
+
if (grid.snap)
selectionB = applySnap(selectionB);
}
/* here the mouse is on a selection boundary i.e. resize */
-
+
else
if (resized) {
int pos = Fl::event_x() - x();
/* ------------------------------------------------------------------ */
-/* 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)
{
/* ------------------------------------------------------------------ */
-bool gWaveform::mouseOnStart()
+bool gWaveform::mouseOnStart()
{
return mouseX-10 > chanStart + x() - BORDER &&
mouseX-10 <= chanStart + x() - BORDER + FLAG_WIDTH &&
/* ------------------------------------------------------------------ */
-bool gWaveform::mouseOnEnd()
+bool gWaveform::mouseOnEnd()
{
return mouseX-10 >= chanEnd + x() - BORDER - FLAG_WIDTH &&
mouseX-10 <= chanEnd + x() - BORDER &&
/* 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;
}
-bool gWaveform::mouseOnSelectionB()
+bool gWaveform::mouseOnSelectionB()
{
if (selectionA == selectionB)
return false;
/* ------------------------------------------------------------------ */
-int gWaveform::absolutePoint(int p)
+int gWaveform::absolutePoint(int p)
{
if (p <= 0)
return 0;
/* ------------------------------------------------------------------ */
-int gWaveform::relativePoint(int p)
+int gWaveform::relativePoint(int p)
{
return (ceilf(p / ratio)) * 2;
}
/* ------------------------------------------------------------------ */
-void gWaveform::openEditMenu()
+void gWaveform::openEditMenu()
{
if (selectionA == selectionB)
return;
/* ------------------------------------------------------------------ */
-void gWaveform::straightSel()
+void gWaveform::straightSel()
{
if (selectionA > selectionB) {
unsigned tmp = selectionB;
/* ------------------------------------------------------------------ */
-void gWaveform::setZoom(int type)
+void gWaveform::setZoom(int type)
{
int newSize;
if (type == -1) newSize = data.size*2; // zoom in
/* ------------------------------------------------------------------ */
-void gWaveform::stretchToWindow()
+void gWaveform::stretchToWindow()
{
int s = ((gWaveTools*)parent())->w();
alloc(s);
/* ------------------------------------------------------------------ */
-bool gWaveform::smaller()
+bool gWaveform::smaller()
{
return w() < ((gWaveTools*)parent())->w();
}
void gWaveform::setGridLevel(int l)
{
- grid.points.clear();
+ grid.points.clear();
grid.level = l;
alloc(data.size);
redraw();
*
* ---------------------------------------------------------------------
*
- * 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.
*
#ifndef GE_WAVEFORM_H
#define GE_WAVEFORM_H
+
+#include <vector>
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
#include "../../utils/utils.h"
+using std::vector;
+
+
#define FLAG_WIDTH 14
#define FLAG_HEIGHT 12
#define BORDER 8 // window border <-> widget border
/* data
* real graphic stuff from the underlying waveform */
-
+
struct data {
int *sup;
int *inf;
struct grid {
bool snap;
int level;
- gVector<int> points;
+ vector<int> points;
} grid;
/* chan
/* openEditMenu
* show edit menu on right-click */
-
+
void openEditMenu();
/* displayRatio
* 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. */
inline void setSnap(bool v) { grid.snap = v; }
inline bool getSnap() { return grid.snap; }
-
+
inline int getSize() { return data.size; }
int chanStart;
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;
*
* ---------------------------------------------------------------------
*
- * 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.
*
/* 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();
}
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;
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();
}
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;
}
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;
}
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");
}
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;
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;
*
* ---------------------------------------------------------------------
*
- * 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.
*
#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;
*
* -----------------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
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);
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;
+}
*
* ---------------------------------------------------------------------
*
- * 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.
*
#endif
+using std::string;
+
+
/* refresh
* refresh all GUI elements. */
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
+++ /dev/null
-/* -----------------------------------------------------------------------------
- *
- * 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
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* ---------------------------------------------------------------------
*
- * 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.
*
*
* -----------------------------------------------------------------------------
*
- * 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.
*
using std::string;
+using std::vector;
bool gFileExists(const char *filename) {
}
+bool gDirExists(const string &path)
+{
+ return gDirExists(path.c_str());
+}
+
+
/* -------------------------------------------------------------------------- */
}
+bool gMkdir(const string &path)
+{
+ return gMkdir(path.c_str());
+}
+
+
/* -------------------------------------------------------------------------- */
/* TODO - avoid this shit, just wrap the other call */
/* -------------------------------------------------------------------------- */
-void gSplit(string in, string sep, gVector<string> *v)
+void gSplit(string in, string sep, vector<string> *v)
{
string full = in;
string token = "";
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);
}
*
* -----------------------------------------------------------------------------
*
- * 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.
*
#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);
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);
string gItoa(int i);
-void gSplit(string in, string sep, gVector<string> *v);
+void gSplit(string in, string sep, vector<string> *v);
#endif
+#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);
+ }
+}
--- /dev/null
+#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);
+ }
+}
using std::string;
+using std::vector;
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;
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";
#ifdef WITH_VST
- patch.masterInPlugins.add(plugin1);
- patch.masterOutPlugins.add(plugin2);
+ patch.masterInPlugins.push_back(plugin1);
+ patch.masterOutPlugins.push_back(plugin2);
#endif
#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")
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");
}
-
--- /dev/null
+#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);
+ }
+}