zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit ca1ced7ae08e5200e0a5d239c1fb6ad3fff49855
parent a4fbe0dfd59780f77e5902736a616cda27efde17
Author: fundamental <[email protected]>
Date:   Thu, 13 May 2010 18:12:52 -0400

Merge branch 'master' into nio

Diffstat:
Mdoc/Makefile | 3+++
Adoc/adsynth.txt | 46++++++++++++++++++++++++++++++++++++++++++++++
Adoc/gen/Makefile | 4++++
Adoc/gen/ad-note.tex | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Adoc/images/ad-global.png | 0
Adoc/images/ad-voice.png | 0
Mdoc/zynaddsubfx.txt | 2++
Msrc/Params/Presets.cpp | 6++----
Msrc/Params/PresetsStore.cpp | 138++++++++++++++++++++++++++++---------------------------------------------------
Msrc/Params/PresetsStore.h | 16++++++++++------
Msrc/UI/PresetsUI.fl | 17+++++++++--------
11 files changed, 174 insertions(+), 107 deletions(-)

diff --git a/doc/Makefile b/doc/Makefile @@ -1,3 +1,6 @@ + +.PHONY: subdirs gen + all: xhtml xhtml: zynaddsubfx.txt envelope.txt intro.txt lfo.txt diff --git a/doc/adsynth.txt b/doc/adsynth.txt @@ -0,0 +1,46 @@ +Add Synth +========= + +Additive Synthesis is one of the three major synthesis engines available in +ZynAddSubFX. +Overall it adds together several voices with an oscillator as their sound +source. + +High Level (Global) +------------------- + +From a high level perspective, Add synth can be understood with this block +diagram: + +image:gen/ad-note.png[] + +The red/yellow nodes are controllable with the main adsynth window. + +image:images/ad-global.png[] + +The sum of the voices are passed through filters and amplification to produce +the final sound. +This could lead one to think that ad-note is just a bunch of minor +postprocessing and at this level much of the sound generation is hidden. + +Voices +------ + +The voice gives access to a similar setup to the global parameters and then some +more, such as the modulator, oscillator, and unison features. + +image:images/ad-voice.png[] + +Modulation +~~~~~~~~~~ + +Within the options for modulation, one can select: +* Morph +* Ring Modulation +* Phase Modulation +* Frequency Modulation +* Disabled + +Unison +~~~~~~ + diff --git a/doc/gen/Makefile b/doc/gen/Makefile @@ -0,0 +1,4 @@ +ad-note.png: ad-note.tex + pslatex ad-note.tex + convert ad-note.dvi -trim ad-note.png + rm ad-note.dvi ad-note.log ad-note.aux diff --git a/doc/gen/ad-note.tex b/doc/gen/ad-note.tex @@ -0,0 +1,49 @@ +\documentclass[11pt]{report} +\pagestyle{empty} +\usepackage{pst-sigsys} +\begin{document} +\begin{pspicture}[showgrid=false](-5,-3)(12,3) +\psset{framesize=2 .65} +\psfblock[fillstyle=solid,fillcolor=green](-4,1){inFq}{Note Fq.} +\psfblock[fillstyle=solid,fillcolor=yellow](-4,0){lfoFq}{Fq. LFO} +\psfblock[fillstyle=solid,fillcolor=red](-4,-1){envFq}{Fq. Env.} + +\dotnode(-2.5,1){dot1} +\dotnode(-2.5,0){dot2} +\dotnode(-2.5,-1){dot3} + +\psfblock(-1,0){vce}{Voices} + + +\psfblock(2,0){flt}{Filter} + +\psfblock[fillstyle=solid,fillcolor=red](1,-2){envFl}{Filter Env.} +\psfblock[fillstyle=solid,fillcolor=yellow](3,-2){lfoFl}{Filter LFO} + +\pspolygon(4,1)(6,0)(4,-1) +\psfblock[linecolor=white](5,0){amp}{Amp} + +\psfblock[fillstyle=solid,fillcolor=red](4,2){envAmp}{Amp. Env.} +\psfblock[fillstyle=solid,fillcolor=yellow](6,2){lfoAmp}{Amp. LFO} + +\psfblock(7.5,0){pnch}{Punch} + +\psfblock(10,0){out}{Output} + +\ncline{inFq}{dot1} +\ncline{dot1}{dot2} +\ncline{lfoFq}{dot2} +\ncline{dot3}{dot2} +\ncline{envFq}{dot3} + +\dotnode(2,-1){fltdot} +\ncline{envFl}{fltdot} +\ncline{lfoFl}{fltdot} +\ncline{fltdot}{flt} +\dotnode(5,1){ampdot} +\ncline{lfoAmp}{ampdot} +\ncline{envAmp}{ampdot} +\ncline{ampdot}{amp} +\nclist[arrows=->]{ncline}{dot2,vce,flt,amp,pnch,out} +\end{pspicture} +\end{document} diff --git a/doc/images/ad-global.png b/doc/images/ad-global.png Binary files differ. diff --git a/doc/images/ad-voice.png b/doc/images/ad-voice.png Binary files differ. diff --git a/doc/zynaddsubfx.txt b/doc/zynaddsubfx.txt @@ -13,6 +13,8 @@ include::./lfo.txt[] include::./envelope.txt[] +include::./adsynth.txt[] + include::./controller.txt[] include::./nrpn.txt[] diff --git a/src/Params/Presets.cpp b/src/Params/Presets.cpp @@ -47,11 +47,10 @@ void Presets::copy(const char *name) char type[MAX_PRESETTYPE_SIZE]; strcpy(type, this->type); - strcat(type, "n"); + //strcat(type, "n"); if(name == NULL) if(strstr(type, "Plfo") != NULL) strcpy(type, "Plfo"); - ; xml->beginbranch(type); add2XML(xml); @@ -69,12 +68,11 @@ void Presets::paste(int npreset) { char type[MAX_PRESETTYPE_SIZE]; strcpy(type, this->type); - strcat(type, "n"); + //strcat(type, "n"); if(npreset == 0) if(strstr(type, "Plfo") != NULL) strcpy(type, "Plfo"); - ; XMLwrapper *xml = new XMLwrapper(); if(npreset == 0) { diff --git a/src/Params/PresetsStore.cpp b/src/Params/PresetsStore.cpp @@ -19,6 +19,9 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <iostream> +#include <algorithm> +#include <cctype> #include <stdlib.h> #include <string.h> #include <dirent.h> @@ -27,17 +30,14 @@ #include "PresetsStore.h" #include "../Misc/Util.h" +using namespace std; + PresetsStore presetsstore; PresetsStore::PresetsStore() { clipboard.data = NULL; clipboard.type[0] = 0; - - for(int i = 0; i < MAX_PRESETS; i++) { - presets[i].file = NULL; - presets[i].name = NULL; - } } PresetsStore::~PresetsStore() @@ -78,128 +78,88 @@ bool PresetsStore::checkclipboardtype(char *type) //Presets management void PresetsStore::clearpresets() { - for(int i = 0; i < MAX_PRESETS; i++) { - if(presets[i].file != NULL) { - delete (presets[i].file); - presets[i].file = NULL; - } - if(presets[i].name != NULL) { - delete (presets[i].name); - presets[i].name = NULL; - } - } + presets.clear(); } //a helper function that compares 2 presets[] -int Presets_compar(const void *a, const void *b) +bool PresetsStore::presetstruct::operator<(const presetstruct &b) const { - struct PresetsStore::presetstruct *p1 = (PresetsStore::presetstruct *)a; - struct PresetsStore::presetstruct *p2 = (PresetsStore::presetstruct *)b; - if(((p1->name) == NULL) || ((p2->name) == NULL)) - return 0; - - return strcasecmp(p1->name, p2->name) < 0; + return name < b.name; } -void PresetsStore::rescanforpresets(char *type) +void PresetsStore::rescanforpresets(string type) { + //std::cout << "Scanning For Presets" << std::endl; + //std::cout << "Of Type: " << type << std::endl; + clearpresets(); - int presetk = 0; - char ftype[MAX_STRING_SIZE]; - snprintf(ftype, MAX_STRING_SIZE, ".%s.xpz", type); + string ftype = "." + type + ".xpz"; for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { if(config.cfg.presetsDirList[i] == NULL) continue; - char *dirname = config.cfg.presetsDirList[i]; - DIR *dir = opendir(dirname); + + //open directory + string dirname = config.cfg.presetsDirList[i]; + DIR *dir = opendir(dirname.c_str()); if(dir == NULL) continue; struct dirent *fn; + + //check all files in directory while((fn = readdir(dir))) { - const char *filename = fn->d_name; - if(strstr(filename, ftype) == NULL) + string filename = fn->d_name; + if(filename.find(ftype) == string::npos) continue; - - presets[presetk].file = new char [MAX_STRING_SIZE]; - presets[presetk].name = new char [MAX_STRING_SIZE]; - char tmpc = dirname[strlen(dirname) - 1]; + //ensure proper path is formed + char tmpc = dirname[dirname.size() - 1]; const char *tmps; if((tmpc == '/') || (tmpc == '\\')) tmps = ""; else tmps = "/"; - snprintf(presets[presetk].file, - MAX_STRING_SIZE, - "%s%s%s", - dirname, - tmps, - filename); - snprintf(presets[presetk].name, MAX_STRING_SIZE, "%s", filename); - - char *tmp = strstr(presets[presetk].name, ftype); - if(tmp != NULL) - tmp[0] = '\0'; - presetk++; - if(presetk >= MAX_PRESETS) - return; + + string location = "" + dirname + tmps + filename; + + //trim file type off of name + string name = filename.substr(0, filename.find(ftype)); + + //put on list + presets.push_back(presetstruct(location, name)); } closedir(dir); } //sort the presets - for(int j = 0; j < MAX_PRESETS - 1; j++) { - for(int i = j + 1; i < MAX_PRESETS; i++) { - if(Presets_compar(&presets[i], &presets[j])) { - presetstruct tmp = presets[i]; - presets[i] = presets[j]; - presets[j] = tmp; - } - } - } + sort(presets.begin(), presets.end()); } -void PresetsStore::copypreset(XMLwrapper *xml, char *type, const char *name) -{ - char filename[MAX_STRING_SIZE], tmpfilename[MAX_STRING_SIZE]; +void PresetsStore::copypreset(XMLwrapper *xml, char *type, const string name) +{ if(config.cfg.presetsDirList[0] == NULL) return; - snprintf(tmpfilename, MAX_STRING_SIZE, "%s", name); - //make the filenames legal - for(int i = 0; i < (int) strlen(tmpfilename); i++) { - char c = tmpfilename[i]; - if((c >= '0') && (c <= '9')) - continue; - if((c >= 'A') && (c <= 'Z')) - continue; - if((c >= 'a') && (c <= 'z')) - continue; - if((c == '-') || (c == ' ')) - continue; - tmpfilename[i] = '_'; + for(int i = 0; i < (int) name.size(); i++) { + char c = name[i]; + if(!(isdigit(c) || isalpha(c) || (c == '-') || (c == ' '))) + name[i] = '_'; } - const char *dirname = config.cfg.presetsDirList[0]; - char tmpc = dirname[strlen(dirname) - 1]; + //make path legal + const string dirname = config.cfg.presetsDirList[0]; + char tmpc = dirname[dirname.size() - 1]; const char *tmps; if((tmpc == '/') || (tmpc == '\\')) tmps = ""; else tmps = "/"; - snprintf(filename, - MAX_STRING_SIZE, - "%s%s%s.%s.xpz", - dirname, - tmps, - name, - type); + string filename("" + dirname + tmps + name + type); xml->saveXMLfile(filename); } @@ -207,10 +167,10 @@ void PresetsStore::copypreset(XMLwrapper *xml, char *type, const char *name) bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) { npreset--; - if(npreset >= MAX_PRESETS) + if(npreset >= presets.size()) return false; - char *filename = presets[npreset].file; - if(filename == NULL) + string filename = presets[npreset].file; + if(filename.empty()) return false; bool result = (xml->loadXMLfile(filename) >= 0); return result; @@ -219,11 +179,11 @@ bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) void PresetsStore::deletepreset(int npreset) { npreset--; - if(npreset >= MAX_PRESETS) + if(npreset >= presets.size()) return; - char *filename = presets[npreset].file; - if(filename == NULL) + string filename = presets[npreset].file; + if(filename.empty()) return; - remove(filename); + remove(filename.c_str()); } diff --git a/src/Params/PresetsStore.h b/src/Params/PresetsStore.h @@ -20,11 +20,12 @@ */ +#include <string> +#include <vector> #include "../Misc/XMLwrapper.h" #include "../Misc/Config.h" #define MAX_PRESETTYPE_SIZE 30 -#define MAX_PRESETS 1000 class PresetsStore { @@ -38,17 +39,20 @@ class PresetsStore bool checkclipboardtype(char *type); //presets stuff - void copypreset(XMLwrapper *xml, char *type, const char *name); + void copypreset(XMLwrapper *xml, char *type, const std::string name); bool pastepreset(XMLwrapper *xml, int npreset); void deletepreset(int npreset); struct presetstruct { - char *file; - char *name; + presetstruct(std::string _file, std::string _name) + :file(_file),name(_name){}; + bool operator<(const presetstruct &b) const; + std::string file; + std::string name; }; - presetstruct presets[MAX_PRESETS]; + std::vector<presetstruct> presets; - void rescanforpresets(char *type); + void rescanforpresets(const std::string type); private: struct { diff --git a/src/UI/PresetsUI.fl b/src/UI/PresetsUI.fl @@ -11,8 +11,7 @@ decl {\#include <stdio.h>} {public decl {\#include <stdlib.h>} {public } -decl {\#include "../Params/PresetsArray.h"} {selected -} +decl {\#include "../Params/PresetsArray.h"} {} decl {\#include "../Params/Presets.h"} {public } @@ -190,12 +189,14 @@ paste(p,pui);} {} pastebrowse->clear(); p->rescanforpresets(); -for (int i=0;i<MAX_PRESETS;i++){ - char *name=presetsstore.presets[i].name; - if (name==NULL) break; - copybrowse->add(name); - pastebrowse->add(name); -};} {} +for (int i=0;i<presetsstore.presets.size();i++){ + std::string name=presetsstore.presets[i].name; + if(name.empty()) + continue; + copybrowse->add(name.c_str()); + pastebrowse->add(name.c_str()); +};} {selected + } } decl {Presets *p;} {public }