commit 1dd9bc3cc76fac48c2aeb529a11e17db36219c84
parent db48d6e1decfc6dc60c83a8b95642534ac4da9fa
Author: Johannes Lorenz <johannes89@ist-einmalig.de>
Date: Sat, 15 Aug 2015 15:27:37 +0200
Merge branch 'no_globals'
Diffstat:
51 files changed, 537 insertions(+), 341 deletions(-)
diff --git a/doc/adsynth.txt b/doc/adsynth.txt
@@ -17,21 +17,21 @@ image::gen/ad-note.png[scalewidth="50%",width="700"]
The global level of adsynth is almost entirely composed of previously discussed
elements.
However a few new features appear here, this includes velocity sensing, punch,
-detune options and realative bandwidth , and resonance.
+detune options and relative bandwidth , and resonance.
.AdSynth Global Window
image::images/ad-global.png[]
-Velocity sensing is simply an exponental transformation from the note's velocity
+Velocity sensing is simply an exponential transformation from the note's velocity
to some parameter change.
-The below diagram shows how the velocity senseing controls affects this
+The below diagram shows how the velocity sensing controls affects this
translation over the whole range of possible note velocities.
.Velocity Sensing Chart
image::gen/velf.png[scalewidth="50%",width="600"]
-The puch of a note in AdSynth is a constant amplification to the output at the
+The punch of a note in AdSynth is a constant amplification to the output at the
start of the note, with its length determined by the punch time and stretch and
the amplitude being determined by the punch strength and velocity sensing.
The relBW control in the frequency pane is effectively a multiplier for detuning
@@ -88,7 +88,7 @@ Waveshaping can be done using the *Wsh* area in the Oscillator editor.
The type of distortion has much influence on how the overtones are being placed.
Sometimes, you get a "fat" bass, and sometimes, high frequencies are added,
-makeing the sound "crystal clear".
+making the sound "crystal clear".
Atan & Sigmoid
++++++++++++++
diff --git a/doc/controller.txt b/doc/controller.txt
@@ -6,13 +6,13 @@ image::./images/uicontroller.png[]
General
~~~~~~~
-* *ModWh*: Modullation Wheel depth
-* *Exp MWh*: Exponental Modulation Wheel (changes modulation scale to
- exponental)
+* *ModWh*: Modulation Wheel depth
+* *Exp MWh*: Exponential Modulation Wheel (changes modulation scale to
+ exponential)
* *BwDpth*: Bandwidth Depth
-* *Exp BW*: Exponental Bandwidth (changes badwidth scale to exponental)
+* *Exp BW*: Exponential Bandwidth (changes bandwidth scale to exponential)
* *PanDpth*: Panning Depth
-* *FltQ*: Filter Q (ressonance) depth
+* *FltQ*: Filter Q (resonance) depth
* *FltCut* Filter Cutoff frequency depth
* *Expr*: enable/disable expression
* *Vol*: enable/disable receiving volume controller
@@ -27,7 +27,7 @@ Portamento
* *time*: The duration of the portamento
* *thresh*: The threshold of the portamento.
It represents the minimum or the maximum number of halftones
-(or hundried cents) required to start the portamento.
+(or hundred cents) required to start the portamento.
The difference is computed between the last note and current note.
* *th.type*: The threshold type.
Checked means that the portamento activates when the difference of frequencies
@@ -37,13 +37,13 @@ NOTE: The threshold refers to the frequencies and not to MIDI notes
(you should consider this if you use microtonal scales).
-Proportinal Portamento
+Proportional Portamento
^^^^^^^^^^^^^^^^^^^^^^
////
TODO: add graphs to explain prp.rate and prp. depth
////
-* *Propt.*: If the portamento is proportinal to ratio of frequencies
+* *Propt.*: If the portamento is proportional to ratio of frequencies
* *Prp. Rate*: Ratio needed to double the time of portamento
* *Prp. Dpth*: The divergence from
diff --git a/doc/effects.txt b/doc/effects.txt
@@ -1,7 +1,7 @@
Effects
-------
-Effects are, generally, blackboxes that transform audio signals in a
+Effects are, generally, black boxes that transform audio signals in a
specified way. More exactly, the only input data for an effect in ZynAddSubFX
is:
@@ -123,7 +123,7 @@ electronic music, we only have an input wave and need to generate these
different timbres by ourselves. ZynAddSubFX therefore simply plays the sound,
pitch modulated by an LFO, and adds this to the original sound. This explains
the diagram below: The multiple pitches are generated by a delayed version of
-the input. This version is being pitched by an LFO. More detailled, this pitch
+the input. This version is being pitched by an LFO. More detailed, this pitch
is generated by varying the reading speed of the delayed sound; the variation
amount is controlled by an LFO.
@@ -134,8 +134,8 @@ TODO: Add LFO pointing to delay?
Related effects to Chorus are Flangers. Flangers can be described as Chorus
with very short LFO delay and little LFO depth. You can imagine a flanger as two
-copies of a sound playing at almost the same time. This leeds to interference,
-which can be clearly heared. It is popular to apply flangers to guitars, giving
+copies of a sound playing at almost the same time. This leads to interference,
+which can be clearly heard. It is popular to apply flangers to guitars, giving
them more "character".
Usage
@@ -149,8 +149,8 @@ changed at all.
the delay also depends on the current pitch.
* After the correct element of the sound buffer is found using the LFO, the
*Fb* knob lets you set how loud it shall be played. This is mostly redundant to
-the *D/W* knob, but we have not applied panning and substraction yet.
-* Next, the singal can be negated. If the *Substract* Checkbox is activated,
+the *D/W* knob, but we have not applied panning and subtraction yet.
+* Next, the signal can be negated. If the *Substract* checkbox is activated,
the amplitude is multiplied by -1.
* Finally, *Pan* lets you apply panning.
@@ -175,7 +175,7 @@ Distortion can happen in many situations when working with audio. Often, this is
not wanted. In classical music, for example, distortion does not occur
naturally. However, distortion can also be a wanted effect. It is typical for
Rock guitars, but also present in electronic music, mostly in Dubstep and
-DrumNBass.
+Drum & Bass.
The basic components of distortion are mainly
@@ -215,18 +215,18 @@ We explain the functionality in a diagram and list the components below.
image:./gen/distort.png[width=700,
title="The components of a distortion function."]
-* Negation is the first thing to happen. If the *Neg* Checkbox is activated, the
+* Negation is the first thing to happen. If the *Neg* checkbox is activated, the
amplitude is multiplied by -1.
* Panning is applied. Note, however, that you have to activate the
Stereo Checkbox, labeled *St*, before.
-* Pre amplification is done next. The amount can be changed using the
+* Preamplification is done next. The amount can be changed using the
*Drive* nob. Indeed, this is the amount of distortion. For example, if you clip
a signal, the louder the input gets, the more distortion you will get. This can
have different meanings for different types of distortion, as described above.
* *HPF* and *LPF* are filters with 2 poles. Whether they are used before or
after the waveshape, depends on the checkbox labeled *PF*.
* The next step is the wave shape. This defines how the wave is
-actually modified. The *Type* ComboBox lets you define how. We will discuss some
+actually modified. The *Type* combo box lets you define how. We will discuss some
types below.
* After the wave shape, we scale the level again. This is called
output amplification. You can change the value using the *Level* knob.
@@ -383,7 +383,7 @@ Function
As mentioned, a reverb consists of permanent echo. The reverb in ZynAddSubFX is
more complex than the echo. After the delaying, comb filters and then allpass
filters are being applied. These make the resulting sound more realistic. The
-parameters for these filters depend on the roomsize. For details, consider the
+parameters for these filters depend on the room size. For details, consider the
information about https://ccrma.stanford.edu/~jos/pasp/Freeverb.html[Freeverb].
image:./gen/reverb.png[width=700,
@@ -392,13 +392,13 @@ image:./gen/reverb.png[width=700,
Description
^^^^^^^^^^^
-* The *Type* ComboBox lets you select a reverb type:
+* The *Type* combo box lets you select a reverb type:
** *Freeverb* is a preset. It was proposed by Jezar at Dreampoint.
** *Bandwidth* has the same parameters for the comb and allpass filters, but it
applies a unison before the LP/HP. The unison's bandwidth can be set using *bw*.
** Random chooses a random layout for comb and allpass each time the type or
-the roomsize is being changed.
-* The roomsize (*R.S.*) defines parameters only for the comb and allpass
+the room size is being changed.
+* The room size (*R.S.*) defines parameters only for the comb and allpass
filters.
* *Time* controls how long the whole reverb shall take, including how slow the
volume is decreased.
@@ -435,8 +435,8 @@ signal, which *preserves* the amplitude, but determines the delay time. In the
end, both paths are added.
The following picture describes how this works on white noise. Light blue
-signalises that the frequency is not present at the current time, and dark blue
-signalises the opposite. The dark blue peaks appear if the delay time is very
+signalizes that the frequency is not present at the current time, and dark blue
+signalizes the opposite. The dark blue peaks appear if the delay time is very
short, because then, the second path almost equals the first one, which results
in duplication of the signal. If the delay line is very long, then it is --- in
the case of white noise --- totally at random whether the delayed signal
@@ -468,7 +468,7 @@ Description
For the normal phaser, first, the LFO is generated:
-* There are 4 controls (*Freq*,*Rnd*,*LFO tpye*,*St.df*) that define the
+* There are 4 controls (*Freq*,*Rnd*,*LFO type*,*St.df*) that define the
LFO.
* *Phase* and *Depth* are applied afterwards in the usual way (TODO: I don't
understand the code here for the normal phase...). For the analog phaser,
@@ -504,14 +504,14 @@ Function
^^^^^^^^
The way that the filter moves between the two vocals is mainly
-described by an LFO. A bit easified, Paul Nasca has stated the formula (for
+described by an LFO. A bit simplified, Paul Nasca has stated the formula (for
latexmath:[$i^2=-1; R<1$]) as
latexmath:[$fb=R*(\cos(\alpha)+i*\sin(\alpha))$]
latexmath:[$y_n=y_{n-delay}*R*(\cos(\alpha)+i*\sin(\alpha))+x_n*(1-R)$].
-The input latexmath:[$x_n$] has the real part of the samples from the wavefile
+The input latexmath:[$x_n$] has the real part of the samples from the wave file
and the imaginary part is zero. The output of this effect is the real part of
latexmath:[$y_n$]. latexmath:[$\alpha$] is the phase.
@@ -519,7 +519,7 @@ Description
^^^^^^^^^^^
* *Pan*
-* The following 5 controls (*Freq*,*Rnd*,*LFO tpye*,*St.df*, *Dpth*) define the
+* The following 5 controls (*Freq*,*Rnd*,*LFO type*,*St.df*, *Dpth*) define the
LFO.
** *Fb*
diff --git a/doc/getting.txt b/doc/getting.txt
@@ -5,7 +5,7 @@ Usually there are several methods to obtain a copy of ZynAddSubFX.
SourceForge::
http://sourceforge.net/projects/zynaddsubfx/files/
-Distribuition::
+Distribution::
apt/yum/others
Git::
git clone git://git.code.sf.net/p/zynaddsubfx/code zynaddsubfx
@@ -14,7 +14,7 @@ Introduction to Git
~~~~~~~~~~~~~~~~~~~
For those who want to live on the bleeding edge or who want to assist with
-making sure that the next release has fewer bugs, you will want to get aquanted
+making sure that the next release has fewer bugs, you will want to get acquainted
with git.
Git is used to manage the source code for this project and can be used to
quickly and easily get an up-to-date copy of the source code.
diff --git a/doc/intro.txt b/doc/intro.txt
@@ -3,7 +3,7 @@ Getting Started
ZynAddSubFX is a fairly complex software synthesizer with a very large number of
controls.
-As such, it is not alway obvious how to use ZynAddSubFX.
+As such, it is not always obvious how to use ZynAddSubFX.
Many applications under Linux transport MIDI over ALSA and transmit audio over
JACK.
@@ -21,7 +21,7 @@ Currently the beginner interface is deprecated, so the advanced one is
recommended.
Now you should be able to see ZynAddSubFX's main window, from which you can
-setup patches, effects, and general configurations, but more importatnly it
+setup patches, effects, and general configurations, but more importantly it
provides links into the parameters of the patches.
ZynAddSubFX is a powerful tool with a number of base patches, but its true power
lies in the ability to make your own patches.
diff --git a/doc/lfo.txt b/doc/lfo.txt
@@ -7,13 +7,13 @@ Introduction
"LFO" means Low Frequency Oscillator.
These oscillators are not used to make sounds by themselves, but they changes
-somes parameters (like the frequencies, the amplitudes or the filters).
+some parameters (like the frequencies, the amplitudes or the filters).
-The LFOs has some basic parameters:
+The LFOs have some basic parameters:
* *Delay*: This parameter sets how much time takes since the start of the
note to the start of the LFO
-* *Start Phase*: The possition that a LFO will start at
+* *Start Phase*: The position that a LFO will start at
* *Frequency*: How fast the LFO is (i.e. how fast the parameter's controlled by
the LFO changes)
* *Depth*: The amplitude of the LFO (i.e. how much the parameter's controlled
@@ -23,7 +23,7 @@ image:images/lfo0.png[]
Another important LFO parameter is the shape.
There are many LFO Types according to the shape.
-ZynAddSubFX supports the folowing LFO shapes:
+ZynAddSubFX supports the following LFO shapes:
image:images/lfo1.png[]
@@ -31,15 +31,15 @@ Another parameter is the LFO Randomness.
It modifies the LFO amplitude or the LFO frequency at random.
In ZynAddSubFX you can choose how much the LFO frequency or LFO amplitude
changes by this parameter.
-In the folowing images are shown some examples of randomness and how changes
+In the following images are shown some examples of randomness and how changes
the shape of a triangle LFO.
image:images/lfo2.png[]
Other parameters are:
-* *Continous mode*: If this mode is used, the LFO will not start from "zero" on each new note, but it will be continuous. This is very usefull if you apply on filters to make interesting sweeps.
-* *Stretch*: It controlls how much the LFO frequency changes according to the
+* *Continous mode*: If this mode is used, the LFO will not start from "zero" on each new note, but it will be continuous. This is very useful if you apply on filters to make interesting sweeps.
+* *Stretch*: It controls how much the LFO frequency changes according to the
note's frequency.
It can vary from negative stretch (the LFO frequency is decreased on higher
notes) to zero (the LFO frequency will be the same on all notes) to positive
@@ -52,14 +52,14 @@ In ZynAddSubFX, LFO parameters are shown as:
image:images/uilfo.jpg[]
-Theese parameters are:
+These parameters are:
* *Freq*: LFO Frequency
* *Depth*: LFO Depth
* *Start*: LFO Start Phase -
If this knob is at the lowest value, the LFO Start Phase will be random.
* *Delay*: LFO Delay
-* *A.R.*: LFO Amplitude Randomnes
+* *A.R.*: LFO Amplitude Randomness
* *F.R.*: LFO Frequency Randomness
* *C.*: LFO Continous Mode
* *Str.*: LFO Stretch - in the image above the LFO stretch is set to zero
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
@@ -369,7 +369,7 @@ if(CompileTests)
endif(CompileTests)
-add_executable(zynaddsubfx main.cpp)
+add_executable(zynaddsubfx main.cpp globals.cpp)
#Warning: the required ordering of these to get proper linking depends upon the
# phase of the moon
@@ -386,6 +386,7 @@ if (DssiEnable)
add_library(zynaddsubfx_dssi SHARED
UI/ConnectionDummy.cpp
Output/DSSIaudiooutput.cpp
+ globals.cpp
)
target_link_libraries(zynaddsubfx_dssi
diff --git a/src/DSP/Unison.cpp b/src/DSP/Unison.cpp
@@ -24,6 +24,7 @@
#include "../Misc/Allocator.h"
#include "Unison.h"
+#include "globals.h"
#ifndef errx
#include <err.h>
diff --git a/src/Effects/EffectLFO.cpp b/src/Effects/EffectLFO.cpp
@@ -24,6 +24,7 @@
#include "../Misc/Util.h"
#include <cmath>
+#include "globals.h"
EffectLFO::EffectLFO(float srate_f, float bufsize_f)
:Pfreq(40),
@@ -79,7 +80,7 @@ float EffectLFO::getlfoshape(float x)
break;
//when adding more, ensure ::updateparams() gets updated
default:
- out = cosf(x * 2.0f * PI); //EffectLFO_SINE
+ out = cosf(x * 2.0f * PI); //EffectLFO_SINE // TODO: use M_PI ?
}
return out;
}
diff --git a/src/Effects/EffectMgr.cpp b/src/Effects/EffectMgr.cpp
@@ -26,12 +26,14 @@
#include "EffectMgr.h"
#include "Effect.h"
+#include "Alienwah.h"
#include "Reverb.h"
#include "Echo.h"
#include "Chorus.h"
#include "Distorsion.h"
#include "EQ.h"
#include "DynamicFilter.h"
+#include "Phaser.h"
#include "../Misc/XMLwrapper.h"
#include "../Misc/Util.h"
#include "../Params/FilterParams.h"
@@ -307,8 +309,8 @@ void EffectMgr::out(float *smpsl, float *smpsr)
return;
}
for(int i = 0; i < synth.buffersize; ++i) {
- smpsl[i] += denormalkillbuf[i];
- smpsr[i] += denormalkillbuf[i];
+ smpsl[i] += synth.denormalkillbuf[i];
+ smpsr[i] += synth.denormalkillbuf[i];
efxoutl[i] = 0.0f;
efxoutr[i] = 0.0f;
}
diff --git a/src/Effects/EffectMgr.h b/src/Effects/EffectMgr.h
@@ -24,22 +24,15 @@
#include <pthread.h>
-#include "Alienwah.h"
-#include "Phaser.h"
-#include "../Params/Presets.h"
-
class Effect;
class FilterParams;
class XMLwrapper;
class Allocator;
-#include "Distorsion.h"
-#include "EQ.h"
-#include "DynamicFilter.h"
#include "../Params/FilterParams.h"
#include "../Params/Presets.h"
-/**Effect manager, an interface betwen the program and effects*/
+/** Effect manager, an interface between the program and effects */
class EffectMgr:public Presets
{
public:
diff --git a/src/Misc/Allocator.cpp b/src/Misc/Allocator.cpp
@@ -7,7 +7,7 @@
#include "Allocator.h"
//Used for dummy allocations
-Allocator DummyAlloc;
+DummyAllocator DummyAlloc;
//recursive type class to avoid void *v = *(void**)v style casting
struct next_t
@@ -57,7 +57,7 @@ Allocator::~Allocator(void)
delete impl;
}
-void *Allocator::alloc_mem(size_t mem_size)
+void *AllocatorClass::alloc_mem(size_t mem_size)
{
impl->totalAlloced += mem_size;
void *mem = tlsf_malloc(impl->tlsf, mem_size);
@@ -66,14 +66,14 @@ void *Allocator::alloc_mem(size_t mem_size)
//printf("Allocator result = %p\n", mem);
return mem;
}
-void Allocator::dealloc_mem(void *memory)
+void AllocatorClass::dealloc_mem(void *memory)
{
//printf("dealloc_mem(%d)\n", tlsf_block_size(memory));
tlsf_free(impl->tlsf, memory);
//free(memory);
}
-bool Allocator::lowMemory(unsigned n, size_t chunk_size)
+bool AllocatorClass::lowMemory(unsigned n, size_t chunk_size) const
{
//This should stay on the stack
void *buf[n];
@@ -90,7 +90,7 @@ bool Allocator::lowMemory(unsigned n, size_t chunk_size)
}
-void Allocator::addMemory(void *v, size_t mem_size)
+void AllocatorClass::addMemory(void *v, size_t mem_size)
{
next_t *n = impl->pools;
while(n->next) n = n->next;
@@ -124,7 +124,7 @@ typedef struct block_header_t
static const size_t block_header_free_bit = 1 << 0;
#endif
-bool Allocator::memFree(void *pool)
+bool Allocator::memFree(void *pool) const
{
size_t bh_shift = sizeof(next_t)+sizeof(size_t);
//Assume that memory is free to start with
@@ -145,7 +145,7 @@ bool Allocator::memFree(void *pool)
return isFree;
}
-int Allocator::memPools()
+int Allocator::memPools() const
{
int i = 1;
next_t *n = impl->pools;
@@ -156,7 +156,7 @@ int Allocator::memPools()
return i;
}
-int Allocator::freePools()
+int Allocator::freePools() const
{
int i = 0;
next_t *n = impl->pools->next;
@@ -169,7 +169,7 @@ int Allocator::freePools()
}
-unsigned long long Allocator::totalAlloced()
+unsigned long long Allocator::totalAlloced() const
{
return impl->totalAlloced;
}
diff --git a/src/Misc/Allocator.h b/src/Misc/Allocator.h
@@ -2,14 +2,17 @@
#include <cstdlib>
#include <utility>
+//! Allocator Base class
+//! subclasses must specify allocation and deallocation
class Allocator
{
public:
Allocator(void);
Allocator(const Allocator&) = delete;
- ~Allocator(void);
- void *alloc_mem(size_t mem_size);
- void dealloc_mem(void *memory);
+ virtual ~Allocator(void);
+
+ virtual void *alloc_mem(size_t mem_size) = 0;
+ virtual void dealloc_mem(void *memory) = 0;
template <typename T, typename... Ts>
T *alloc(Ts&&... ts)
@@ -64,23 +67,47 @@ class Allocator
}
}
- void addMemory(void *, size_t mem_size);
+ virtual void addMemory(void *, size_t mem_size) = 0;
//Return true if the current pool cannot allocate n chunks of chunk_size
- bool lowMemory(unsigned n, size_t chunk_size);
- bool memFree(void *pool);
+ virtual bool lowMemory(unsigned n, size_t chunk_size) const = 0;
+ bool memFree(void *pool) const;
//returns number of pools
- int memPools();
+ int memPools() const;
- int freePools();
+ int freePools() const;
- unsigned long long totalAlloced();
+ unsigned long long totalAlloced() const;
struct AllocatorImpl *impl;
};
-extern Allocator DummyAlloc;
+//! the allocator for normal use
+class AllocatorClass : public Allocator
+{
+ void *alloc_mem(size_t mem_size);
+ void dealloc_mem(void *memory);
+ void addMemory(void *, size_t mem_size);
+ bool lowMemory(unsigned n, size_t chunk_size) const;
+ using Allocator::Allocator;
+};
+
+//! the dummy allocator, which does not allow any allocation
+class DummyAllocator : public Allocator
+{
+ void not_allowed() const {
+ throw "(de)allocation forbidden"; // TODO: std exception
+ }
+public:
+ void *alloc_mem(size_t ) { return not_allowed(), nullptr; }
+ void dealloc_mem(void* ) { not_allowed(); } // TODO: more functions?
+ void addMemory(void *, size_t ) { not_allowed(); }
+ bool lowMemory(unsigned , size_t ) const { return not_allowed(), true; }
+ using Allocator::Allocator;
+};
+
+extern DummyAllocator DummyAlloc;
/**
* General notes on Memory Allocation Within ZynAddSubFX
diff --git a/src/Misc/Bank.cpp b/src/Misc/Bank.cpp
@@ -46,16 +46,16 @@
using namespace std;
-Bank::Bank()
- :bankpos(0), defaultinsname(" ")
+Bank::Bank(Config *config)
+ :bankpos(0), defaultinsname(" "), config(config)
{
clearbank();
bankfiletitle = dirname;
rescanforbanks();
- loadbank(config.cfg.currentBankDir);
+ loadbank(config->cfg.currentBankDir);
for(unsigned i=0; i<banks.size(); ++i) {
- if(banks[i].dir == config.cfg.currentBankDir) {
+ if(banks[i].dir == config->cfg.currentBankDir) {
bankpos = i;
break;
}
@@ -270,7 +270,7 @@ int Bank::loadbank(string bankdirname)
closedir(dir);
if(!dirname.empty())
- config.cfg.currentBankDir = dirname;
+ config->cfg.currentBankDir = dirname;
return 0;
}
@@ -281,7 +281,7 @@ int Bank::loadbank(string bankdirname)
int Bank::newbank(string newbankdirname)
{
string bankdir;
- bankdir = config.cfg.bankRootDirList[0];
+ bankdir = config->cfg.bankRootDirList[0];
if(((bankdir[bankdir.size() - 1]) != '/')
&& ((bankdir[bankdir.size() - 1]) != '\\'))
@@ -361,8 +361,8 @@ void Bank::rescanforbanks()
banks.clear();
for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i)
- if(!config.cfg.bankRootDirList[i].empty())
- scanrootdir(config.cfg.bankRootDirList[i]);
+ if(!config->cfg.bankRootDirList[i].empty())
+ scanrootdir(config->cfg.bankRootDirList[i]);
//sort the banks
sort(banks.begin(), banks.end());
diff --git a/src/Misc/Bank.h b/src/Misc/Bank.h
@@ -26,6 +26,7 @@
#include <string>
#include <vector>
#include "../globals.h"
+#include "Config.h"
//entries in a bank
#define BANK_SIZE 160
@@ -35,7 +36,7 @@ class Bank
{
public:
/**Constructor*/
- Bank();
+ Bank(Config* config);
~Bank();
std::string getname(unsigned int ninstrument);
std::string getnamenumbered(unsigned int ninstrument);
@@ -96,6 +97,8 @@ class Bank
std::string dirname;
void scanrootdir(std::string rootdir); //scans a root dir for banks
+
+ Config* const config;
};
#endif
diff --git a/src/Misc/CMakeLists.txt b/src/Misc/CMakeLists.txt
@@ -14,6 +14,7 @@ set(zynaddsubfx_misc_SRCS
Misc/MiddleWare.cpp
Misc/PresetExtractor.cpp
Misc/Allocator.cpp
+ Misc/TmpFileMgr.cpp
)
diff --git a/src/Misc/Config.cpp b/src/Misc/Config.cpp
@@ -28,6 +28,7 @@
#include <rtosc/port-sugar.h>
#include "Config.h"
+#include "../src/globals.h"
#include "XMLwrapper.h"
#define rStdString(name, len, ...) \
@@ -46,7 +47,7 @@
#if 1
#define rObject Config
-static rtosc::Ports ports = {
+static const rtosc::Ports ports = {
//rString(cfg.LinuxOSSWaveOutDev),
//rString(cfg.LinuxOSSSeqInDev),
rParamI(cfg.SampleRate, "samples of audio per second"),
@@ -145,7 +146,7 @@ static rtosc::Ports ports = {
d.broadcast(d.loc, "i", (int)(log(c.cfg.OscilSize*1.0)/log(2.0)));
}},
};
-rtosc::Ports &Config::ports = ::ports;
+const rtosc::Ports &Config::ports = ::ports;
#endif
Config::Config()
@@ -160,10 +161,10 @@ void Config::init()
cfg.OscilSize = 1024;
cfg.SwapStereo = 0;
- cfg.LinuxOSSWaveOutDev = new char[MAX_STRING_SIZE];
- snprintf(cfg.LinuxOSSWaveOutDev, MAX_STRING_SIZE, "/dev/dsp");
- cfg.LinuxOSSSeqInDev = new char[MAX_STRING_SIZE];
- snprintf(cfg.LinuxOSSSeqInDev, MAX_STRING_SIZE, "/dev/sequencer");
+ cfg.oss_devs.linux_wave_out = new char[MAX_STRING_SIZE];
+ snprintf(cfg.oss_devs.linux_wave_out, MAX_STRING_SIZE, "/dev/dsp");
+ cfg.oss_devs.linux_seq_in = new char[MAX_STRING_SIZE];
+ snprintf(cfg.oss_devs.linux_seq_in, MAX_STRING_SIZE, "/dev/sequencer");
cfg.WindowsWaveOutId = 0;
cfg.WindowsMidiInId = 0;
@@ -228,8 +229,8 @@ void Config::init()
Config::~Config()
{
- delete [] cfg.LinuxOSSWaveOutDev;
- delete [] cfg.LinuxOSSSeqInDev;
+ delete [] cfg.oss_devs.linux_wave_out;
+ delete [] cfg.oss_devs.linux_seq_in;
for(int i = 0; i < winmidimax; ++i)
delete [] winmididevices[i].name;
@@ -237,7 +238,7 @@ Config::~Config()
}
-void Config::save()
+void Config::save() const
{
char filename[MAX_STRING_SIZE];
getConfigFileName(filename, MAX_STRING_SIZE);
@@ -330,10 +331,10 @@ void Config::readConfig(const char *filename)
//linux stuff
xmlcfg.getparstr("linux_oss_wave_out_dev",
- cfg.LinuxOSSWaveOutDev,
+ cfg.oss_devs.linux_wave_out,
MAX_STRING_SIZE);
xmlcfg.getparstr("linux_oss_seq_in_dev",
- cfg.LinuxOSSSeqInDev,
+ cfg.oss_devs.linux_seq_in,
MAX_STRING_SIZE);
//windows stuff
@@ -352,7 +353,7 @@ void Config::readConfig(const char *filename)
cfg.OscilSize = (int) powf(2, ceil(logf(cfg.OscilSize - 1.0f) / logf(2.0f)));
}
-void Config::saveConfig(const char *filename)
+void Config::saveConfig(const char *filename) const
{
XMLwrapper *xmlcfg = new XMLwrapper();
@@ -392,8 +393,8 @@ void Config::saveConfig(const char *filename)
xmlcfg->addpar("interpolation", cfg.Interpolation);
//linux stuff
- xmlcfg->addparstr("linux_oss_wave_out_dev", cfg.LinuxOSSWaveOutDev);
- xmlcfg->addparstr("linux_oss_seq_in_dev", cfg.LinuxOSSSeqInDev);
+ xmlcfg->addparstr("linux_oss_wave_out_dev", cfg.oss_devs.linux_wave_out);
+ xmlcfg->addparstr("linux_oss_seq_in_dev", cfg.oss_devs.linux_seq_in);
//windows stuff
xmlcfg->addpar("windows_wave_out_id", cfg.WindowsWaveOutId);
@@ -401,15 +402,13 @@ void Config::saveConfig(const char *filename)
xmlcfg->endbranch();
- int tmp = cfg.GzipCompression;
- cfg.GzipCompression = 0;
- xmlcfg->saveXMLfile(filename);
- cfg.GzipCompression = tmp;
+ // for some reason (which one?), the gzip compression is bashed to 0
+ xmlcfg->saveXMLfile(filename, 0);
delete (xmlcfg);
}
-void Config::getConfigFileName(char *name, int namesize)
+void Config::getConfigFileName(char *name, int namesize) const
{
name[0] = 0;
snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg");
diff --git a/src/Misc/Config.h b/src/Misc/Config.h
@@ -22,21 +22,32 @@
#ifndef CONFIG_H
#define CONFIG_H
-#include "../globals.h"
+
#include <string>
#define MAX_STRING_SIZE 4000
#define MAX_BANK_ROOT_DIRS 100
+namespace rtosc
+{
+ struct Ports;
+}
+
+class oss_devs_t
+{
+ public:
+ char *linux_wave_out, *linux_seq_in;
+};
+
/**Configuration file functions*/
class Config
{
public:
- /** Constructor*/
Config();
- /** Destructor*/
+ Config(const Config& ) = delete;
~Config();
+
struct {
- char *LinuxOSSWaveOutDev, *LinuxOSSSeqInDev;
+ oss_devs_t oss_devs;
int SampleRate, SoundBufferSize, OscilSize, SwapStereo;
int WindowsWaveOutId, WindowsMidiInId;
int BankUIAutoClose;
@@ -62,12 +73,12 @@ class Config
void clearbankrootdirlist();
void clearpresetsdirlist();
void init();
- void save();
+ void save() const;
- static rtosc::Ports &ports;
+ static const rtosc::Ports &ports;
private:
void readConfig(const char *filename);
- void saveConfig(const char *filename);
- void getConfigFileName(char *name, int namesize);
+ void saveConfig(const char *filename) const;
+ void getConfigFileName(char *name, int namesize) const;
};
#endif
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
@@ -25,6 +25,8 @@
#include "Part.h"
+#include "../Misc/Stereo.h"
+#include "../Misc/Util.h"
#include "../Params/LFOParams.h"
#include "../Effects/EffectMgr.h"
#include "../DSP/FFTwrapper.h"
@@ -286,12 +288,15 @@ vuData::vuData(void)
rmspeakl(0.0f), rmspeakr(0.0f), clipped(0)
{}
-Master::Master(const SYNTH_T &synth_)
-:HDDRecorder(synth_), ctl(synth_), midi(Master::ports), frozenState(false), pendingMemory(false), synth(synth_)
+Master::Master(const SYNTH_T &synth_, Config* config)
+ :HDDRecorder(synth_), ctl(synth_),
+ microtonal(config->cfg.GzipCompression), bank(config),
+ midi(Master::ports), frozenState(false), pendingMemory(false),
+ synth(synth_), gzip_compression(config->cfg.GzipCompression)
{
bToU = NULL;
uToB = NULL;
- memory = new Allocator();
+ memory = new AllocatorClass();
swaplr = 0;
off = 0;
smps = 0;
@@ -310,7 +315,8 @@ Master::Master(const SYNTH_T &synth_)
}
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
- part[npart] = new Part(*memory, synth, µtonal, fft);
+ part[npart] = new Part(*memory, synth, config->cfg.GzipCompression,
+ config->cfg.Interpolation, µtonal, fft);
//Insertion Effects init
for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
@@ -1044,7 +1050,7 @@ int Master::saveXML(const char *filename)
add2XML(xml);
xml->endbranch();
- int result = xml->saveXMLfile(filename);
+ int result = xml->saveXMLfile(filename, gzip_compression);
delete (xml);
return result;
}
diff --git a/src/Misc/Master.h b/src/Misc/Master.h
@@ -49,7 +49,7 @@ class Master
{
public:
/** Constructor TODO make private*/
- Master(const SYNTH_T &synth);
+ Master(const SYNTH_T &synth, class Config *config);
/** Destructor*/
~Master();
@@ -171,6 +171,7 @@ class Master
rtosc::ThreadLink *uToB;
bool pendingMemory;
const SYNTH_T &synth;
+ const int& gzip_compression; //!< value from config
private:
float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
diff --git a/src/Misc/Microtonal.cpp b/src/Misc/Microtonal.cpp
@@ -75,7 +75,8 @@ const rtosc::Ports Microtonal::ports = {
};
-Microtonal::Microtonal()
+Microtonal::Microtonal(const int &gzip_compression)
+ : gzip_compression(gzip_compression)
{
defaults();
}
@@ -688,7 +689,7 @@ int Microtonal::saveXML(const char *filename) const
add2XML(xml);
xml->endbranch();
- int result = xml->saveXMLfile(filename);
+ int result = xml->saveXMLfile(filename, gzip_compression);
delete (xml);
return result;
}
diff --git a/src/Misc/Microtonal.h b/src/Misc/Microtonal.h
@@ -36,7 +36,7 @@ class Microtonal
{
public:
/**Constructor*/
- Microtonal();
+ Microtonal(const int& gzip_compression);
/**Destructor*/
~Microtonal();
void defaults();
@@ -131,6 +131,8 @@ class Microtonal
//the real tunning is x1/x2
unsigned int x1, x2;
} octave[MAX_OCTAVE_SIZE], tmpoctave[MAX_OCTAVE_SIZE];
+
+ const int& gzip_compression;
};
#endif
diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp
@@ -12,7 +12,6 @@
#include <lo/lo.h>
#include <unistd.h>
-#include <dirent.h>
#include "../UI/Connection.h"
#include "../UI/Fl_Osc_Interface.h"
@@ -20,6 +19,7 @@
#include <map>
#include "Util.h"
+#include "TmpFileMgr.h"
#include "Master.h"
#include "Part.h"
#include "PresetExtractor.h"
@@ -459,13 +459,12 @@ namespace Nio
}
/* Implementation */
-class MiddleWareImpl
+class MiddleWareImpl : TmpFileMgr
{
- static constexpr const char* tmp_nam_prefix = "/tmp/zynaddsubfx_";
MiddleWare *parent;
//Detect if the name of the process is 'zynaddsubfx'
- bool isPlugin()
+ bool isPlugin() const
{
std::string proc_file = "/proc/" + to_s(getpid()) + "/comm";
std::ifstream ifs(proc_file);
@@ -477,113 +476,11 @@ class MiddleWareImpl
return true;
}
- //! returns file name to where UDP port is saved
- std::string get_tmp_nam() const
- {
- return tmp_nam_prefix + to_s(getpid());
- }
-
- void create_tmp_file(unsigned server_port)
- {
- std::string tmp_nam = get_tmp_nam();
- if(0 == access(tmp_nam.c_str(), F_OK)) {
- fprintf(stderr, "Error: Cannot overwrite file %s. "
- "You should probably remove it.", tmp_nam.c_str());
- exit(EXIT_FAILURE);
- }
- FILE* tmp_fp = fopen(tmp_nam.c_str(), "w");
- if(!tmp_fp)
- fprintf(stderr, "Warning: could not create new file %s.\n",
- tmp_nam.c_str());
- else
- fprintf(tmp_fp, "%u", server_port);
- fclose(tmp_fp);
- }
-
- void clean_up_tmp_nams() const
- {
- DIR *dir;
- struct dirent *entry;
- if ((dir = opendir ("/tmp/")) != nullptr)
- {
- while ((entry = readdir (dir)) != nullptr)
- {
- std::string name = std::string("/tmp/") + entry->d_name;
- if(!name.compare(0, strlen(tmp_nam_prefix),tmp_nam_prefix))
- {
- std::string pid = name.substr(strlen(tmp_nam_prefix));
- std::string proc_file = "/proc/" + std::move(pid) +
- "/comm";
-
- std::ifstream ifs(proc_file);
- bool remove = false;
-
- if(!ifs.good())
- {
- fprintf(stderr, "Note: trying to remove %s - the "
- "process does not exist anymore.\n",
- name.c_str());
- remove = true;
- }
- else
- {
- std::string comm_name;
- ifs >> comm_name;
- if(comm_name == "zynaddsubfx")
- fprintf(stderr, "Note: detected running "
- "zynaddsubfx with PID %s.\n",
- name.c_str() + strlen(tmp_nam_prefix));
- else {
- fprintf(stderr, "Note: trying to remove %s - the "
- "PID is owned by\n another "
- "process: %s\n",
- name.c_str(), comm_name.c_str());
- remove = true;
- }
- }
-
-
- if(remove)
- {
- // make sure this file contains only one unsigned
- unsigned udp_port;
- std::ifstream ifs2(name);
- if(!ifs2.good())
- fprintf(stderr, "Warning: could not open %s.\n",
- name.c_str());
- else
- {
- ifs2 >> udp_port;
- if(ifs.good())
- fprintf(stderr, "Warning: could not remove "
- "%s, \n it has not been "
- "written by zynaddsubfx\n",
- name.c_str());
- else
- {
- if(std::remove(name.c_str()) != 0)
- fprintf(stderr, "Warning: can not remove "
- "%s.\n", name.c_str());
- }
- }
- }
-
- /* one might want to connect to zyn here,
- but it is not necessary:
- lo_address la = lo_address_new(nullptr, udp_port.c_str());
- if(lo_send(la, "/echo", nullptr) <= 0)
- fputs("Note: found crashed file %s\n", stderr);
- lo_address_free(la);*/
- }
- }
- closedir (dir);
- } else {
- fputs("Warning: can not read /tmp.\n", stderr);
- }
- }
-
+ Config* const config;
+
public:
- MiddleWareImpl(MiddleWare *mw, SYNTH_T synth, int prefered_port);
+ MiddleWareImpl(MiddleWare *mw, SYNTH_T synth, Config* config,
+ int preferred_port);
~MiddleWareImpl(void);
void warnMemoryLeaks(void);
@@ -670,7 +567,10 @@ public:
auto alloc = std::async(std::launch::async,
[master,filename,this,npart](){
- Part *p = new Part(*master->memory, synth, &master->microtonal, master->fft);
+ Part *p = new Part(*master->memory, synth,
+ config->cfg.GzipCompression,
+ config->cfg.Interpolation,
+ &master->microtonal, master->fft);
if(p->loadXMLinstrument(filename))
fprintf(stderr, "Warning: failed to load part<%s>!\n", filename);
@@ -704,7 +604,10 @@ public:
{
if(npart == -1)
return;
- Part *p = new Part(*master->memory, synth, &master->microtonal, master->fft);
+ Part *p = new Part(*master->memory, synth,
+ config->cfg.GzipCompression,
+ config->cfg.Interpolation,
+ &master->microtonal, master->fft);
p->applyparameters();
obj_store.extractPart(p, npart);
kits.extractPart(p, npart);
@@ -721,7 +624,7 @@ public:
//structures at once... TODO error handling
void loadMaster(const char *filename)
{
- Master *m = new Master(synth);
+ Master *m = new Master(synth, config);
m->uToB = uToB;
m->bToU = bToU;
if(filename) {
@@ -829,7 +732,7 @@ public:
{
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
- DummyDataObj d(buffer, 1024, (void*)&config, this, uToB);
+ DummyDataObj d(buffer, 1024, (void*)config, this, uToB);
strcpy(buffer, "/config/");
Config::ports.dispatch(msg+8, d);
@@ -896,15 +799,20 @@ public:
//Synthesis Rate Parameters
const SYNTH_T synth;
+
+ PresetsStore presetsstore;
};
-MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, int prefered_port)
- :parent(mw), ui(nullptr), synth(synth_)
+MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_,
+ Config* config, int preferrred_port)
+ :parent(mw), config(config), ui(nullptr), synth(std::move(synth_)),
+ presetsstore(*config)
{
bToU = new rtosc::ThreadLink(4096*2,1024);
uToB = new rtosc::ThreadLink(4096*2,1024);
- if(prefered_port != -1)
- server = lo_server_new_with_proto(to_s(prefered_port).c_str(), LO_UDP, liblo_error_cb);
+ if(preferrred_port != -1)
+ server = lo_server_new_with_proto(to_s(preferrred_port).c_str(),
+ LO_UDP, liblo_error_cb);
else
server = lo_server_new_with_proto(NULL, LO_UDP, liblo_error_cb);
lo_server_add_method(server, NULL, NULL, handler_function, mw);
@@ -925,7 +833,7 @@ MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, int prefered_port
#ifndef PLUGINVERSION
the_bToU = bToU;
#endif
- master = new Master(synth);
+ master = new Master(synth, config);
master->bToU = bToU;
master->uToB = uToB;
osc = GUI::genOscInterface(mw);
@@ -1340,8 +1248,9 @@ void MiddleWareImpl::warnMemoryLeaks(void)
/******************************************************************************
* MidleWare Forwarding Stubs *
******************************************************************************/
-MiddleWare::MiddleWare(SYNTH_T synth, int prefered_port)
-:impl(new MiddleWareImpl(this, synth, prefered_port))
+MiddleWare::MiddleWare(SYNTH_T synth, Config* config,
+ int preferred_port)
+:impl(new MiddleWareImpl(this, std::move(synth), config, preferred_port))
{}
MiddleWare::~MiddleWare(void)
{
@@ -1432,3 +1341,13 @@ const char* MiddleWare::getServerAddress(void) const
{
return lo_server_get_url(impl->server);
}
+
+const PresetsStore& MiddleWare::getPresetsStore() const
+{
+ return impl->presetsstore;
+}
+
+PresetsStore& MiddleWare::getPresetsStore()
+{
+ return impl->presetsstore;
+}
diff --git a/src/Misc/MiddleWare.h b/src/Misc/MiddleWare.h
@@ -5,11 +5,14 @@
struct SYNTH_T;
class Master;
+class PresetsStore;
+
//Link between realtime and non-realtime layers
class MiddleWare
{
public:
- MiddleWare(SYNTH_T synth, int prefered_port = -1);
+ MiddleWare(SYNTH_T synth, class Config *config,
+ int preferred_port = -1);
~MiddleWare(void);
void updateResources(Master *m);
//returns internal master pointer
@@ -39,6 +42,9 @@ class MiddleWare
const SYNTH_T &getSynth(void) const;
//liblo stuff
const char* getServerAddress(void) const;
+
+ const PresetsStore& getPresetsStore() const;
+ PresetsStore& getPresetsStore();
private:
class MiddleWareImpl *impl;
};
diff --git a/src/Misc/Part.cpp b/src/Misc/Part.cpp
@@ -188,8 +188,12 @@ static const Ports kitPorts = {
const Ports &Part::Kit::ports = kitPorts;
const Ports &Part::ports = partPorts;
-Part::Part(Allocator &alloc, const SYNTH_T &synth_, Microtonal *microtonal_, FFTwrapper *fft_)
- :ctl(synth_), memory(alloc), synth(synth_)
+Part::Part(Allocator &alloc, const SYNTH_T &synth_,
+ const int &gzip_compression, const int &interpolation,
+ Microtonal *microtonal_, FFTwrapper *fft_)
+ :ctl(synth_), memory(alloc), synth(synth_),
+ gzip_compression(gzip_compression),
+ interpolation(interpolation)
{
microtonal = microtonal_;
fft = fft_;
@@ -333,16 +337,16 @@ void Part::cleanup(bool final_)
for(int k = 0; k < POLYPHONY; ++k)
KillNotePos(k);
for(int i = 0; i < synth.buffersize; ++i) {
- partoutl[i] = final_ ? 0.0f : denormalkillbuf[i];
- partoutr[i] = final_ ? 0.0f : denormalkillbuf[i];
+ partoutl[i] = final_ ? 0.0f : synth.denormalkillbuf[i];
+ partoutr[i] = final_ ? 0.0f : synth.denormalkillbuf[i];
}
ctl.resetall();
for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
partefx[nefx]->cleanup();
for(int n = 0; n < NUM_PART_EFX + 1; ++n)
for(int i = 0; i < synth.buffersize; ++i) {
- partfxinputl[n][i] = final_ ? 0.0f : denormalkillbuf[i];
- partfxinputr[n][i] = final_ ? 0.0f : denormalkillbuf[i];
+ partfxinputl[n][i] = final_ ? 0.0f : synth.denormalkillbuf[i];
+ partfxinputr[n][i] = final_ ? 0.0f : synth.denormalkillbuf[i];
}
}
@@ -584,7 +588,8 @@ void Part::NoteOn(unsigned char note,
memory.alloc<SUBnote>(kit[0].subpars, pars);
if(kit[0].Ppadenabled)
partnote[pos].kititem[0].padnote =
- memory.alloc<PADnote>(kit[0].padpars, pars);
+ memory.alloc<PADnote>(kit[0].padpars, pars,
+ interpolation);
if(kit[0].Padenabled || kit[0].Psubenabled || kit[0].Ppadenabled)
@@ -603,7 +608,8 @@ void Part::NoteOn(unsigned char note,
memory.alloc<SUBnote>(kit[0].subpars, pars);
if(kit[0].Ppadenabled)
partnote[posb].kititem[0].padnote =
- memory.alloc<PADnote>(kit[0].padpars, pars);
+ memory.alloc<PADnote>(kit[0].padpars, pars,
+ interpolation);
if(kit[0].Padenabled || kit[0].Psubenabled || kit[0].Ppadenabled)
partnote[posb].itemsplaying++;
@@ -632,7 +638,8 @@ void Part::NoteOn(unsigned char note,
if(kit[item].padpars && kit[item].Ppadenabled)
note1.padnote =
- memory.alloc<PADnote>(kit[item].padpars, pars);
+ memory.alloc<PADnote>(kit[item].padpars, pars,
+ interpolation);
// Spawn another note (but silent) if legatomodevalid==true
if(legatomodevalid) {
@@ -648,7 +655,8 @@ void Part::NoteOn(unsigned char note,
memory.alloc<SUBnote>(kit[item].subpars, pars);
if(kit[item].padpars && kit[item].Ppadenabled)
note2.padnote =
- memory.alloc<PADnote>(kit[item].padpars, pars);
+ memory.alloc<PADnote>(kit[item].padpars, pars,
+ interpolation);
if(kit[item].adpars || kit[item].subpars || kit[item].padpars)
partnote[posb].itemsplaying++;
@@ -1198,7 +1206,7 @@ int Part::saveXML(const char *filename)
add2XMLinstrument(&xml);
xml.endbranch();
- int result = xml.saveXMLfile(filename);
+ int result = xml.saveXMLfile(filename, gzip_compression);
return result;
}
diff --git a/src/Misc/Part.h b/src/Misc/Part.h
@@ -37,7 +37,9 @@ class Part
/**Constructor
* @param microtonal_ Pointer to the microtonal object
* @param fft_ Pointer to the FFTwrapper*/
- Part(Allocator &alloc, const SYNTH_T &synth, Microtonal *microtonal_, FFTwrapper *fft_);
+ Part(Allocator &alloc, const SYNTH_T &synth,
+ const int& gzip_compression, const int& interpolation,
+ Microtonal *microtonal_, FFTwrapper *fft_);
/**Destructor*/
~Part();
@@ -199,6 +201,7 @@ class Part
FFTwrapper *fft;
Allocator &memory;
const SYNTH_T &synth;
+ const int &gzip_compression, &interpolation;
};
#endif
diff --git a/src/Misc/PresetExtractor.cpp b/src/Misc/PresetExtractor.cpp
@@ -17,7 +17,6 @@
#include "../Params/PADnoteParameters.h"
#include "../Params/Presets.h"
#include "../Params/PresetsArray.h"
-#include "../Params/PresetsStore.h"
#include "../Params/SUBnoteParameters.h"
#include "../Misc/MiddleWare.h"
#include "PresetExtractor.h"
@@ -32,8 +31,9 @@ const rtosc::Ports real_preset_ports =
{
{"scan-for-presets:", 0, 0,
[](const char *msg, rtosc::RtData &d) {
- presetsstore.scanforpresets();
- auto &pre = presetsstore.presets;
+ MiddleWare &mw = *(MiddleWare*)d.obj;
+ mw.getPresetsStore().scanforpresets();
+ auto &pre = mw.getPresetsStore().presets;
d.reply(d.loc, "i", pre.size());
for(unsigned i=0; i<pre.size();++i)
d.reply(d.loc, "isss", i,
@@ -84,11 +84,13 @@ const rtosc::Ports real_preset_ports =
}},
{"clipboard-type:", 0, 0,
[](const char *msg, rtosc::RtData &d) {
- d.reply(d.loc, "s", presetsstore.clipboard.type.c_str());
+ const MiddleWare &mw = *(MiddleWare*)d.obj;
+ d.reply(d.loc, "s", mw.getPresetsStore().clipboard.type.c_str());
}},
{"delete:s", 0, 0,
[](const char *msg, rtosc::RtData &d) {
- presetsstore.deletepreset(rtosc_argument(msg,0).s);
+ MiddleWare &mw = *(MiddleWare*)d.obj;
+ mw.getPresetsStore().deletepreset(rtosc_argument(msg,0).s);
}},
};
@@ -202,7 +204,7 @@ std::string doCopy(MiddleWare &mw, string url, string name)
T *t = (T*)capture<void*>(m, url+"self");
//Extract Via mxml
//t->add2XML(&xml);
- t->copy(presetsstore, name.empty()? NULL:name.c_str());
+ t->copy(mw.getPresetsStore(), name.empty()? NULL:name.c_str());
});
return "";//xml.getXMLdata();
@@ -241,7 +243,7 @@ std::string doArrayCopy(MiddleWare &mw, int field, string url, string name)
//Get the pointer
T *t = (T*)capture<void*>(m, url+"self");
//Extract Via mxml
- t->copy(presetsstore, field, name.empty()?NULL:name.c_str());
+ t->copy(mw.getPresetsStore(), field, name.empty()?NULL:name.c_str());
});
return "";//xml.getXMLdata();
@@ -415,7 +417,7 @@ void presetPaste(MiddleWare &mw, std::string url, std::string name)
string data = "";
XMLwrapper xml;
if(name.empty()) {
- data = presetsstore.clipboard.data;
+ data = mw.getPresetsStore().clipboard.data;
if(data.length() < 20)
return;
if(!xml.putXMLdata(data.c_str()))
@@ -440,7 +442,7 @@ void presetPasteArray(MiddleWare &mw, std::string url, int field, std::string na
string data = "";
XMLwrapper xml;
if(name.empty()) {
- data = presetsstore.clipboard.data;
+ data = mw.getPresetsStore().clipboard.data;
if(data.length() < 20)
return;
if(!xml.putXMLdata(data.c_str()))
diff --git a/src/Misc/TmpFileMgr.cpp b/src/Misc/TmpFileMgr.cpp
@@ -0,0 +1,114 @@
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <cstdio>
+#include <fstream>
+#include <unistd.h>
+#include <dirent.h>
+
+#include "Util.h"
+#include "TmpFileMgr.h"
+
+std::string TmpFileMgr::get_tmp_nam() const
+{
+ return tmp_nam_prefix + to_s(getpid());
+}
+
+void TmpFileMgr::create_tmp_file(unsigned server_port) const
+{
+ std::string tmp_nam = get_tmp_nam();
+ if(0 == access(tmp_nam.c_str(), F_OK)) {
+ fprintf(stderr, "Error: Cannot overwrite file %s. "
+ "You should probably remove it.", tmp_nam.c_str());
+ exit(EXIT_FAILURE);
+ }
+ FILE* tmp_fp = fopen(tmp_nam.c_str(), "w");
+ if(!tmp_fp)
+ fprintf(stderr, "Warning: could not create new file %s.\n",
+ tmp_nam.c_str());
+ else
+ fprintf(tmp_fp, "%u", server_port);
+ fclose(tmp_fp);
+}
+
+void TmpFileMgr::clean_up_tmp_nams() const
+{
+ DIR *dir;
+ struct dirent *entry;
+ if ((dir = opendir ("/tmp/")) != nullptr)
+ {
+ while ((entry = readdir (dir)) != nullptr)
+ {
+ std::string name = std::string("/tmp/") + entry->d_name;
+ if(!name.compare(0, strlen(tmp_nam_prefix),tmp_nam_prefix))
+ {
+ std::string pid = name.substr(strlen(tmp_nam_prefix));
+ std::string proc_file = "/proc/" + std::move(pid) +
+ "/comm";
+
+ std::ifstream ifs(proc_file);
+ bool remove = false;
+
+ if(!ifs.good())
+ {
+ fprintf(stderr, "Note: trying to remove %s - the "
+ "process does not exist anymore.\n",
+ name.c_str());
+ remove = true;
+ }
+ else
+ {
+ std::string comm_name;
+ ifs >> comm_name;
+ if(comm_name == "zynaddsubfx")
+ fprintf(stderr, "Note: detected running "
+ "zynaddsubfx with PID %s.\n",
+ name.c_str() + strlen(tmp_nam_prefix));
+ else {
+ fprintf(stderr, "Note: trying to remove %s - the "
+ "PID is owned by\n another "
+ "process: %s\n",
+ name.c_str(), comm_name.c_str());
+ remove = true;
+ }
+ }
+
+
+ if(remove)
+ {
+ // make sure this file contains only one unsigned
+ unsigned udp_port;
+ std::ifstream ifs2(name);
+ if(!ifs2.good())
+ fprintf(stderr, "Warning: could not open %s.\n",
+ name.c_str());
+ else
+ {
+ ifs2 >> udp_port;
+ if(ifs.good())
+ fprintf(stderr, "Warning: could not remove "
+ "%s, \n it has not been "
+ "written by zynaddsubfx\n",
+ name.c_str());
+ else
+ {
+ if(std::remove(name.c_str()) != 0)
+ fprintf(stderr, "Warning: can not remove "
+ "%s.\n", name.c_str());
+ }
+ }
+ }
+
+ /* one might want to connect to zyn here,
+ but it is not necessary:
+ lo_address la = lo_address_new(nullptr, udp_port.c_str());
+ if(lo_send(la, "/echo", nullptr) <= 0)
+ fputs("Note: found crashed file %s\n", stderr);
+ lo_address_free(la);*/
+ }
+ }
+ closedir (dir);
+ } else {
+ fputs("Warning: can not read /tmp.\n", stderr);
+ }
+}
diff --git a/src/Misc/TmpFileMgr.h b/src/Misc/TmpFileMgr.h
@@ -0,0 +1,18 @@
+
+/**
+ This file provides routines for using zyn's tmp files.
+*/
+class TmpFileMgr
+{
+ static constexpr const char* tmp_nam_prefix = "/tmp/zynaddsubfx_";
+
+public:
+ //! returns file name to where UDP port is saved
+ std::string get_tmp_nam() const;
+
+ //! creates a tmp file with given UDP port information
+ void create_tmp_file(unsigned server_port) const;
+
+ //! cleans up as many tmp files as possible
+ void clean_up_tmp_nams() const;
+};
diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp
@@ -20,6 +20,7 @@
*/
+#include "globals.h"
#include "Util.h"
#include <vector>
#include <cassert>
@@ -45,10 +46,6 @@
prng_t prng_state = 0x1234;
-Config config;
-float *denormalkillbuf;
-
-
/*
* Transform the velocity according the scaling parameter (velocity sensing)
*/
diff --git a/src/Misc/Util.h b/src/Misc/Util.h
@@ -28,8 +28,6 @@
#include <stdint.h>
#include <algorithm>
#include <set>
-#include "Config.h"
-#include "../globals.h"
using std::min;
using std::max;
@@ -58,10 +56,6 @@ std::string os_pid_as_padded_string();
std::string legalizeFilename(std::string filename);
-extern float *denormalkillbuf; /**<the buffer to add noise in order to avoid denormalisation*/
-
-extern class Config config;
-
void invSignal(float *sig, size_t len);
template<class T>
diff --git a/src/Misc/XMLwrapper.cpp b/src/Misc/XMLwrapper.cpp
@@ -31,7 +31,7 @@
#include <iostream>
#include <sstream>
-#include "../globals.h"
+#include "globals.h"
#include "Util.h"
using namespace std;
@@ -187,13 +187,12 @@ bool XMLwrapper::hasPadSynth() const
/* SAVE XML members */
-int XMLwrapper::saveXMLfile(const string &filename) const
+int XMLwrapper::saveXMLfile(const string &filename, int compression) const
{
char *xmldata = getXMLdata();
if(xmldata == NULL)
return -2;
- int compression = config.cfg.GzipCompression;
int result = dosavefile(filename.c_str(), compression, xmldata);
free(xmldata);
diff --git a/src/Misc/XMLwrapper.h b/src/Misc/XMLwrapper.h
@@ -49,7 +49,7 @@ class XMLwrapper
* @param filename the name of the destination file.
* @returns 0 if ok or -1 if the file cannot be saved.
*/
- int saveXMLfile(const std::string &filename) const;
+ int saveXMLfile(const std::string &filename, int compression) const;
/**
* Return XML tree as a string.
diff --git a/src/Nio/EngineMgr.cpp b/src/Nio/EngineMgr.cpp
@@ -25,13 +25,14 @@
using namespace std;
-EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth)
+EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth,
+ const oss_devs_t *oss_devs)
{
- static EngineMgr instance(synth);
+ static EngineMgr instance(synth, *oss_devs);
return instance;
}
-EngineMgr::EngineMgr(const SYNTH_T *synth)
+EngineMgr::EngineMgr(const SYNTH_T *synth, const oss_devs_t& oss_devs)
{
assert(synth);
Engine *defaultEng = new NulEngine(*synth);
@@ -39,8 +40,8 @@ EngineMgr::EngineMgr(const SYNTH_T *synth)
//conditional compiling mess (but contained)
engines.push_back(defaultEng);
#if OSS
- engines.push_back(new OssEngine(*synth));
- engines.push_back(new OssMultiEngine(*synth));
+ engines.push_back(new OssEngine(*synth, oss_devs));
+ engines.push_back(new OssMultiEngine(*synth, oss_devs));
#endif
#if ALSA
engines.push_back(new AlsaEngine(*synth));
diff --git a/src/Nio/EngineMgr.h b/src/Nio/EngineMgr.h
@@ -14,7 +14,9 @@ struct SYNTH_T;
class EngineMgr
{
public:
- static EngineMgr &getInstance(const SYNTH_T *synth=NULL);
+ static EngineMgr &getInstance(
+ const SYNTH_T *synth = nullptr,
+ const class oss_devs_t* oss_devs = nullptr);
~EngineMgr();
/**Gets requested engine
@@ -39,6 +41,6 @@ class EngineMgr
AudioOut *defaultOut;
MidiIn *defaultIn;
private:
- EngineMgr(const SYNTH_T *synth);
+ EngineMgr(const SYNTH_T *synth, const oss_devs_t &oss_devs);
};
#endif
diff --git a/src/Nio/Nio.cpp b/src/Nio/Nio.cpp
@@ -5,6 +5,7 @@
#include "MidiIn.h"
#include "AudioOut.h"
#include "WavEngine.h"
+#include "../Misc/Config.h"
#include <cstring>
#include <iostream>
#include <algorithm>
@@ -30,11 +31,12 @@ bool Nio::pidInClientName = false;
string Nio::defaultSource = IN_DEFAULT;
string Nio::defaultSink = OUT_DEFAULT;
-void Nio::init(const SYNTH_T &synth, class Master *master)
+void Nio::init(const SYNTH_T &synth, const oss_devs_t& oss_devs,
+ class Master *master)
{
in = &InMgr::getInstance(); //Enable input wrapper
out = &OutMgr::getInstance(&synth); //Initialize the Output Systems
- eng = &EngineMgr::getInstance(&synth); //Initialize The Engines
+ eng = &EngineMgr::getInstance(&synth, &oss_devs); //Initialize the Engines
in->setMaster(master);
out->setMaster(master);
diff --git a/src/Nio/Nio.h b/src/Nio/Nio.h
@@ -6,13 +6,14 @@
class WavFile;
class Master;
struct SYNTH_T;
+class oss_devs_t;
/**Interface to Nio Subsystem
*
* Should be only externally included header */
namespace Nio
{
- void init(const SYNTH_T &synth, Master *master);
+ void init(const SYNTH_T &synth, const oss_devs_t &oss_devs, Master *master);
bool start(void);
void stop(void);
diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp
@@ -22,6 +22,7 @@
#include "OssEngine.h"
#include "../Misc/Util.h"
+#include "../Misc/Config.h"
#include "../globals.h"
#include <cstring>
@@ -179,8 +180,11 @@ OssMidiParse(struct OssMidiParse &midi_parse,
return (0);
}
-OssEngine::OssEngine(const SYNTH_T &synth)
- :AudioOut(synth), audioThread(NULL), midiThread(NULL)
+OssEngine::OssEngine(const SYNTH_T &synth,
+ const oss_devs_t& oss_devs)
+ :AudioOut(synth), audioThread(NULL), midiThread(NULL),
+ linux_oss_wave_out_dev(oss_devs.linux_wave_out),
+ linux_oss_seq_in_dev(oss_devs.linux_seq_in)
{
name = "OSS";
@@ -212,7 +216,7 @@ bool OssEngine::openAudio()
const char *device = getenv("DSP_DEVICE");
if(device == NULL)
- device = config.cfg.LinuxOSSWaveOutDev;
+ device = linux_oss_wave_out_dev;
/* NOTE: PIPEs and FIFOs can block when opening them */
audio.handle = open(device, O_WRONLY, O_NONBLOCK);
@@ -350,7 +354,7 @@ bool OssEngine::openMidi()
const char *device = getenv("MIDI_DEVICE");
if(device == NULL)
- device = config.cfg.LinuxOSSSeqInDev;
+ device = linux_oss_seq_in_dev;
/* NOTE: PIPEs and FIFOs can block when opening them */
handle = open(device, O_RDONLY, O_NONBLOCK);
diff --git a/src/Nio/OssEngine.h b/src/Nio/OssEngine.h
@@ -45,7 +45,7 @@ struct OssMidiParse {
class OssEngine:public AudioOut, MidiIn
{
public:
- OssEngine(const SYNTH_T &synth);
+ OssEngine(const SYNTH_T &synth, const class oss_devs_t& oss_devs);
~OssEngine();
bool Start();
@@ -83,6 +83,8 @@ class OssEngine:public AudioOut, MidiIn
bool en;
bool is32bit;
} audio;
+
+ const char* linux_oss_wave_out_dev;
//Midi
bool openMidi();
@@ -94,6 +96,8 @@ class OssEngine:public AudioOut, MidiIn
bool en;
bool run;
} midi;
+
+ const char* linux_oss_seq_in_dev;
};
#endif
diff --git a/src/Nio/OssMultiEngine.cpp b/src/Nio/OssMultiEngine.cpp
@@ -43,8 +43,10 @@ extern MiddleWare *middleware;
using namespace std;
-OssMultiEngine :: OssMultiEngine(const SYNTH_T &synth)
- :AudioOut(synth)
+OssMultiEngine :: OssMultiEngine(const SYNTH_T &synth,
+ const oss_devs_t &oss_devs)
+ :AudioOut(synth),
+ linux_oss_wave_out_dev(oss_devs.linux_wave_out)
{
/* setup variables */
name = "OSS-MULTI";
@@ -81,7 +83,7 @@ OssMultiEngine :: openAudio()
const char *device = getenv("DSP_DEVICE");
if(device == 0)
- device = config.cfg.LinuxOSSWaveOutDev;
+ device = linux_oss_wave_out_dev;
/* NOTE: PIPEs and FIFOs can block when opening them */
handle = open(device, O_WRONLY, O_NONBLOCK);
diff --git a/src/Nio/OssMultiEngine.h b/src/Nio/OssMultiEngine.h
@@ -29,7 +29,8 @@
class OssMultiEngine : public AudioOut
{
public:
- OssMultiEngine(const SYNTH_T &synth);
+ OssMultiEngine(const SYNTH_T &synth,
+ const class oss_devs_t& oss_devs);
~OssMultiEngine();
bool Start();
@@ -62,6 +63,8 @@ class OssMultiEngine : public AudioOut
bool en;
bool is32bit;
+
+ const char* linux_oss_wave_out_dev;
};
#endif
diff --git a/src/Params/PresetsStore.cpp b/src/Params/PresetsStore.cpp
@@ -30,13 +30,14 @@
#include "PresetsStore.h"
#include "../Misc/XMLwrapper.h"
#include "../Misc/Util.h"
+#include "../Misc/Config.h"
using namespace std;
//XXX to remove
-PresetsStore presetsstore;
+//PresetsStore presetsstore;
-PresetsStore::PresetsStore()
+PresetsStore::PresetsStore(const Config& config) : config(config)
{
}
@@ -154,7 +155,7 @@ void PresetsStore::copypreset(XMLwrapper &xml, char *type, string name)
string filename("" + dirname + tmps + name + "." + &type[1] + ".xpz");
- xml.saveXMLfile(filename);
+ xml.saveXMLfile(filename, config.cfg.GzipCompression);
}
bool PresetsStore::pastepreset(XMLwrapper &xml, unsigned int npreset)
diff --git a/src/Params/PresetsStore.h b/src/Params/PresetsStore.h
@@ -29,8 +29,9 @@
class XMLwrapper;
class PresetsStore
{
+ const class Config& config;
public:
- PresetsStore();
+ PresetsStore(const class Config &config);
~PresetsStore();
//Clipboard stuff
@@ -62,5 +63,5 @@ class PresetsStore
void clearpresets();
};
-extern PresetsStore presetsstore;
+//extern PresetsStore presetsstore;
#endif
diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp
@@ -1434,8 +1434,8 @@ inline void ADnote::ComputeVoiceNoise(int nvoice)
*/
int ADnote::noteout(float *outl, float *outr)
{
- memcpy(outl, denormalkillbuf, synth.bufferbytes);
- memcpy(outr, denormalkillbuf, synth.bufferbytes);
+ memcpy(outl, synth.denormalkillbuf, synth.bufferbytes);
+ memcpy(outr, synth.denormalkillbuf, synth.bufferbytes);
if(NoteEnabled == OFF)
return 0;
diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp
@@ -29,8 +29,8 @@
#include "../Misc/Util.h"
PADnote::PADnote(PADnoteParameters *parameters,
- SynthParams pars)
- :SynthNote(pars), pars(*parameters)
+ SynthParams pars, const int& interpolation)
+ :SynthNote(pars), pars(*parameters), interpolation(interpolation)
{
firsttime = true;
setup(pars.frequency, pars.velocity, pars.portamento, pars.note);
@@ -347,7 +347,7 @@ int PADnote::noteout(float *outl, float *outr)
float freqlo = freqrap - floor(freqrap);
- if(config.cfg.Interpolation)
+ if(interpolation)
Compute_Cubic(outl, outr, freqhi, freqlo);
else
Compute_Linear(outl, outr, freqhi, freqlo);
diff --git a/src/Synth/PADnote.h b/src/Synth/PADnote.h
@@ -30,7 +30,8 @@
class PADnote:public SynthNote
{
public:
- PADnote(PADnoteParameters *parameters, SynthParams pars);
+ PADnote(PADnoteParameters *parameters, SynthParams pars,
+ const int &interpolation);
~PADnote();
void legatonote(LegatoParams pars);
@@ -104,6 +105,7 @@ class PADnote:public SynthNote
float globaloldamplitude, globalnewamplitude, velocity, realfreq;
+ const int& interpolation;
};
diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp
@@ -491,8 +491,8 @@ void SUBnote::computecurrentparameters()
*/
int SUBnote::noteout(float *outl, float *outr)
{
- memcpy(outl, denormalkillbuf, synth.bufferbytes);
- memcpy(outr, denormalkillbuf, synth.bufferbytes);
+ memcpy(outl, synth.denormalkillbuf, synth.bufferbytes);
+ memcpy(outr, synth.denormalkillbuf, synth.bufferbytes);
if(NoteEnabled == OFF)
return 0;
diff --git a/src/UI/EffUI.fl b/src/UI/EffUI.fl
@@ -39,7 +39,13 @@ decl {\#include "../Misc/Util.h"} {public local
}
decl {\#include "../Effects/EffectMgr.h"} {public local
-}
+}
+
+decl {\#include "../Effects/Phaser.h" /* for macros only, TODO */} {public local
+}
+
+decl {\#include "../Effects/Alienwah.h" /* for macros only, TODO */ } {public local
+}
decl {\#include "PresetsUI.h"} {public local
}
diff --git a/src/globals.cpp b/src/globals.cpp
@@ -0,0 +1,40 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ globals.h - it contains program settings and the program capabilities
+ like number of parts, of effects
+ Copyright (C) 2002-2005 Nasca Octavian Paul
+ Author: Nasca Octavian Paul
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License
+ as published by the Free Software Foundation.
+
+ This program 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 (version 2 or later) for more details.
+
+ You should have received a copy of the GNU General Public License (version 2)
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#include "Misc/Util.h"
+#include "globals.h"
+
+void SYNTH_T::alias()
+{
+ halfsamplerate_f = (samplerate_f = samplerate) / 2.0f;
+ buffersize_f = buffersize;
+ bufferbytes = buffersize * sizeof(float);
+ oscilsize_f = oscilsize;
+
+ //produce denormal buf
+ // note: once there will be more buffers, use a cleanup function
+ // for deleting the buffers and also call it in the dtor
+ denormalkillbuf.resize(buffersize);
+ for(int i = 0; i < buffersize; ++i)
+ denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
+}
diff --git a/src/globals.h b/src/globals.h
@@ -252,22 +252,51 @@ enum LegatoMsg {
#define O_BINARY 0
#endif
+template<class T>
+class m_unique_ptr
+{
+ T* ptr = nullptr;
+public:
+ m_unique_ptr() = default;
+ m_unique_ptr(m_unique_ptr&& other) {
+ ptr = other.ptr;
+ other.ptr = nullptr;
+ }
+ m_unique_ptr(const m_unique_ptr& other) = delete;
+ ~m_unique_ptr() { ptr = nullptr; }
+ void resize(unsigned sz) {
+ delete[] ptr;
+ ptr = new T[sz]; }
+
+ operator T*() { return ptr; }
+ operator const T*() const { return ptr; }
+ T& operator[](unsigned idx) { return ptr[idx]; }
+ const T& operator[](unsigned idx) const { return ptr[idx]; }
+};
+
//temporary include for synth->{samplerate/buffersize} members
struct SYNTH_T {
+
SYNTH_T(void)
:samplerate(44100), buffersize(256), oscilsize(1024)
{
alias();
}
+ SYNTH_T(const SYNTH_T& ) = delete;
+ SYNTH_T(SYNTH_T&& ) = default;
+
+ /** the buffer to add noise in order to avoid denormalisation */
+ m_unique_ptr<float> denormalkillbuf;
+
/**Sampling rate*/
unsigned int samplerate;
/**
* The size of a sound buffer (or the granularity)
- * All internal transfer of sound data use buffer of this size
- * All parameters are constant during this period of time, exception
- * some parameters(like amplitudes) which are linear interpolated.
+ * All internal transfer of sound data use buffer of this size.
+ * All parameters are constant during this period of time, except
+ * some parameters(like amplitudes) which are linearly interpolated.
* If you increase this you'll ecounter big latencies, but if you
* decrease this the CPU requirements gets high.
*/
@@ -291,13 +320,7 @@ struct SYNTH_T {
{
return buffersize_f / samplerate_f;
}
- inline void alias(void)
- {
- halfsamplerate_f = (samplerate_f = samplerate) / 2.0f;
- buffersize_f = buffersize;
- bufferbytes = buffersize * sizeof(float);
- oscilsize_f = oscilsize;
- }
+ void alias(void);
static float numRandom(void); //defined in Util.cpp for now
};
#endif
diff --git a/src/main.cpp b/src/main.cpp
@@ -76,7 +76,7 @@ NSM_Client *nsm = 0;
char *instance_name = 0;
-void exitprogram();
+void exitprogram(const Config &config);
extern pthread_t main_thread;
@@ -91,21 +91,21 @@ void sigterm_exit(int /*sig*/)
/*
* Program initialisation
*/
-void initprogram(SYNTH_T synth, int prefered_port)
+void initprogram(SYNTH_T synth, Config* config, int prefered_port)
{
- middleware = new MiddleWare(synth, prefered_port);
+ middleware = new MiddleWare(std::move(synth), config, prefered_port);
master = middleware->spawnMaster();
master->swaplr = swaplr;
signal(SIGINT, sigterm_exit);
signal(SIGTERM, sigterm_exit);
- Nio::init(master->synth, master);
+ Nio::init(master->synth, config->cfg.oss_devs, master);
}
/*
* Program exit
*/
-void exitprogram()
+void exitprogram(const Config& config)
{
Nio::stop();
config.save();
@@ -121,7 +121,6 @@ void exitprogram()
delete nsm;
#endif
- delete [] denormalkillbuf;
FFT_cleanup();
}
@@ -129,6 +128,7 @@ int main(int argc, char *argv[])
{
main_thread = pthread_self();
SYNTH_T synth;
+ Config config;
config.init();
int noui = 0;
cerr
@@ -375,12 +375,14 @@ int main(int argc, char *argv[])
return 0;
}
- //produce denormal buf
- denormalkillbuf = new float [synth.buffersize];
- for(int i = 0; i < synth.buffersize; ++i)
- denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
+ cerr.precision(1);
+ cerr << std::fixed;
+ cerr << "\nSample Rate = \t\t" << synth.samplerate << endl;
+ cerr << "Sound Buffer Size = \t" << synth.buffersize << " samples" << endl;
+ cerr << "Internal latency = \t" << synth.dt() * 1000.0f << " ms" << endl;
+ cerr << "ADsynth Oscil.Size = \t" << synth.oscilsize << " samples" << endl;
- initprogram(synth, prefered_port);
+ initprogram(std::move(synth), &config, prefered_port);
if(!loadfile.empty()) {
int tmp = master->loadXML(loadfile.c_str());
@@ -413,13 +415,6 @@ int main(int argc, char *argv[])
//Run the Nio system
bool ioGood = Nio::start();
-
- cerr.precision(1);
- cerr << std::fixed;
- cerr << "\nSample Rate = \t\t" << synth.samplerate << endl;
- cerr << "Sound Buffer Size = \t" << synth.buffersize << " samples" << endl;
- cerr << "Internal latency = \t" << synth.dt() * 1000.0f << " ms" << endl;
- cerr << "ADsynth Oscil.Size = \t" << synth.oscilsize << " samples" << endl;
if(!execAfterInit.empty()) {
cout << "Executing user supplied command: " << execAfterInit << endl;
@@ -519,6 +514,6 @@ done:
middleware->tick();
}
- exitprogram();
+ exitprogram(config);
return 0;
}