Merge pull request #508 from diizy/wavetablesynth
Watsyn wavetablesynth
@@ -238,7 +238,7 @@ TrackContainerView QFrame{
|
||||
|
||||
/* autoscroll, loop, stop behaviour toggle buttons */
|
||||
|
||||
nStateButton {
|
||||
nStateButton {
|
||||
max-height: 26px;
|
||||
max-width: 26px;
|
||||
min-height: 26px;
|
||||
@@ -366,7 +366,7 @@ toolButton#playButton {
|
||||
|
||||
toolButton#stopButton {
|
||||
border-top-right-radius: 5px 15px;
|
||||
border-bottom-right-radius: 5px 15px;
|
||||
border-bottom-right-radius: 5px 15px;
|
||||
}
|
||||
|
||||
/* record and record-accompany can be styled with #recordButton and #recordAccompanyButton respectively */
|
||||
@@ -608,6 +608,42 @@ sidInstrumentView knob {
|
||||
qproperty-lineWidth: 2;
|
||||
}
|
||||
|
||||
WatsynView knob {
|
||||
qproperty-innerRadius: 1;
|
||||
qproperty-outerRadius: 7;
|
||||
qproperty-centerPointX: 9.5;
|
||||
qproperty-centerPointY: 9.5;
|
||||
qproperty-lineWidth: 2;
|
||||
}
|
||||
|
||||
WatsynView knob#aKnob {
|
||||
color: #43b2ff;
|
||||
qproperty-outerColor: #43b2ff;
|
||||
}
|
||||
|
||||
WatsynView knob#bKnob {
|
||||
color: #fc5431;
|
||||
qproperty-outerColor: #fc5431;
|
||||
}
|
||||
|
||||
WatsynView knob#mixKnob {
|
||||
color: #43ff82;
|
||||
qproperty-outerColor: #43ff82;
|
||||
qproperty-outerRadius: 13;
|
||||
qproperty-centerPointX: 15.5;
|
||||
qproperty-centerPointY: 15.5;
|
||||
}
|
||||
|
||||
WatsynView knob#mixenvKnob {
|
||||
color: #43ff82;
|
||||
qproperty-outerColor: #43ff82;
|
||||
}
|
||||
|
||||
WatsynView knob#xtalkKnob {
|
||||
color: #fb50fb;
|
||||
qproperty-outerColor: #fb50fb;
|
||||
}
|
||||
|
||||
/* palette information - each colour definition must be on a single line, and the line must begin with "palette:", with no leading whitespace
|
||||
* colour codes MUST be of the form #RRGGBB */
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ ADD_SUBDIRECTORY(triple_oscillator)
|
||||
ADD_SUBDIRECTORY(vestige)
|
||||
ADD_SUBDIRECTORY(vst_base)
|
||||
ADD_SUBDIRECTORY(VstEffect)
|
||||
ADD_SUBDIRECTORY(watsyn)
|
||||
ADD_SUBDIRECTORY(waveshaper)
|
||||
ADD_SUBDIRECTORY(vibed)
|
||||
ADD_SUBDIRECTORY(zynaddsubfx)
|
||||
|
||||
3
plugins/watsyn/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
|
||||
BUILD_PLUGIN(watsyn Watsyn.cpp Watsyn.h MOCFILES Watsyn.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png)
|
||||
1220
plugins/watsyn/Watsyn.cpp
Normal file
337
plugins/watsyn/Watsyn.h
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Watsyn.h - a 4-oscillator modulating wavetable synth
|
||||
*
|
||||
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program 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 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WATSYN_H
|
||||
#define WATSYN_H
|
||||
|
||||
#include "Instrument.h"
|
||||
#include "InstrumentView.h"
|
||||
#include "graph.h"
|
||||
#include "AutomatableModel.h"
|
||||
#include "automatable_button.h"
|
||||
#include "TempoSyncKnob.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "pixmap_button.h"
|
||||
|
||||
|
||||
#define makeknob( name, x, y, hint, unit, oname ) \
|
||||
name = new knob( knobStyled, this ); \
|
||||
name ->move( x, y ); \
|
||||
name ->setHintText( tr( hint ) + " ", unit ); \
|
||||
name ->setObjectName( oname ); \
|
||||
name ->setFixedSize( 19, 19 );
|
||||
|
||||
#define maketsknob( name, x, y, hint, unit, oname ) \
|
||||
name = new TempoSyncKnob( knobStyled, this ); \
|
||||
name ->move( x, y ); \
|
||||
name ->setHintText( tr( hint ) + " ", unit ); \
|
||||
name ->setObjectName( oname ); \
|
||||
name ->setFixedSize( 19, 19 );
|
||||
|
||||
#define A1ROW 26
|
||||
#define A2ROW 49
|
||||
#define B1ROW 72
|
||||
#define B2ROW 95
|
||||
|
||||
|
||||
extern const int WAVELEN = 220;
|
||||
extern const int PMOD_AMT = 110;
|
||||
|
||||
extern const int MOD_MIX = 0;
|
||||
extern const int MOD_AM = 1;
|
||||
extern const int MOD_RM = 2;
|
||||
extern const int MOD_PM = 3;
|
||||
extern const int NUM_MODS = 4;
|
||||
|
||||
extern const int A1_OSC = 0;
|
||||
extern const int A2_OSC = 1;
|
||||
extern const int B1_OSC = 2;
|
||||
extern const int B2_OSC = 3;
|
||||
extern const int NUM_OSCS = 4;
|
||||
|
||||
class WatsynInstrument;
|
||||
|
||||
class WatsynObject
|
||||
{
|
||||
public:
|
||||
WatsynObject( float * _A1wave, float * _A2wave,
|
||||
float * _B1wave, float * _B2wave,
|
||||
int _amod, int _bmod, const sample_rate_t _samplerate, NotePlayHandle * _nph, fpp_t _frames,
|
||||
WatsynInstrument * _w );
|
||||
virtual ~WatsynObject();
|
||||
|
||||
void renderOutput( fpp_t _frames );
|
||||
|
||||
inline sampleFrame * abuf() const
|
||||
{
|
||||
return m_abuf;
|
||||
}
|
||||
inline sampleFrame * bbuf() const
|
||||
{
|
||||
return m_bbuf;
|
||||
}
|
||||
inline sample_rate_t samplerate() const
|
||||
{
|
||||
return m_samplerate;
|
||||
}
|
||||
|
||||
private:
|
||||
// linear interpolation
|
||||
/* inline sample_t interpolate( sample_t s1, sample_t s2, float x )
|
||||
{
|
||||
return s1 + ( s2 - s1 ) * x;
|
||||
}*/
|
||||
|
||||
// quick and dirty approximation of cubic interpolation
|
||||
inline sample_t interpolate( sample_t s1, sample_t s2, float x )
|
||||
{
|
||||
const float x2 = powf( x, 2 );
|
||||
const float x3 = powf( x, 3 );
|
||||
//const float m = s2 - s1;
|
||||
|
||||
return ( ( x3 * 2.0 - x2 * 3.0 + 1.0 ) * s1 ) +
|
||||
( ( x3 * -2.0 + x2 * 3.0 ) * s2 );// +
|
||||
//( ( x + x3 * 2.0 - x2 * 3.0 ) * m );
|
||||
}
|
||||
|
||||
// more accurate cubic interpolation...
|
||||
// consumes more cpu than ^ but doesn't bring a marked increase in sound quality IMO
|
||||
/* inline sample_t interpolate( sample_t s0, sample_t s1, sample_t s2, sample_t s3, float x )
|
||||
{
|
||||
const float x2 = powf( x, 2 );
|
||||
const float x3 = powf( x, 3 );
|
||||
const float m1 = ( s2 - s0 ) / 2;
|
||||
const float m2 = ( s3 - s1 ) / 2;
|
||||
|
||||
return ( ( x3 * 2.0 - x2 * 3.0 + 1.0 ) * s1 ) +
|
||||
( ( x3 * -2.0 + x2 * 3.0 ) * s2 ) +
|
||||
( ( x3 - x2 * 2 + x ) * m1 ) +
|
||||
( ( x3 - x2 ) * m2 );
|
||||
}*/
|
||||
|
||||
int m_amod;
|
||||
int m_bmod;
|
||||
|
||||
const sample_rate_t m_samplerate;
|
||||
NotePlayHandle * m_nph;
|
||||
|
||||
fpp_t m_fpp;
|
||||
|
||||
WatsynInstrument * m_parent;
|
||||
|
||||
sampleFrame * m_abuf;
|
||||
sampleFrame * m_bbuf;
|
||||
|
||||
float m_lphase [NUM_OSCS];
|
||||
float m_rphase [NUM_OSCS];
|
||||
|
||||
float m_A1wave [WAVELEN];
|
||||
float m_A2wave [WAVELEN];
|
||||
float m_B1wave [WAVELEN];
|
||||
float m_B2wave [WAVELEN];
|
||||
};
|
||||
|
||||
class WatsynInstrument : public Instrument
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WatsynInstrument( InstrumentTrack * _instrument_track );
|
||||
virtual ~WatsynInstrument();
|
||||
|
||||
virtual void playNote( NotePlayHandle * _n,
|
||||
sampleFrame * _working_buffer );
|
||||
virtual void deleteNotePluginData( NotePlayHandle * _n );
|
||||
|
||||
|
||||
virtual void saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _this );
|
||||
virtual void loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual QString nodeName() const;
|
||||
|
||||
virtual f_cnt_t desiredReleaseFrames() const
|
||||
{
|
||||
return( 64 );
|
||||
}
|
||||
|
||||
virtual PluginView * instantiateView( QWidget * _parent );
|
||||
|
||||
public slots:
|
||||
void updateVolumes();
|
||||
void updateFreq();
|
||||
|
||||
protected:
|
||||
float m_lvol [NUM_OSCS];
|
||||
float m_rvol [NUM_OSCS];
|
||||
|
||||
float m_lfreq [NUM_OSCS];
|
||||
float m_rfreq [NUM_OSCS];
|
||||
|
||||
private:
|
||||
inline float leftCh( float _vol, float _pan )
|
||||
{
|
||||
return ( _pan <= 0 ? 1.0 : 1.0 - ( _pan / 100.0 ) ) * _vol / 100.0;
|
||||
}
|
||||
|
||||
inline float rightCh( float _vol, float _pan )
|
||||
{
|
||||
return ( _pan >= 0 ? 1.0 : 1.0 + ( _pan / 100.0 ) ) * _vol / 100.0;
|
||||
}
|
||||
|
||||
FloatModel a1_vol;
|
||||
FloatModel a2_vol;
|
||||
FloatModel b1_vol;
|
||||
FloatModel b2_vol;
|
||||
|
||||
FloatModel a1_pan;
|
||||
FloatModel a2_pan;
|
||||
FloatModel b1_pan;
|
||||
FloatModel b2_pan;
|
||||
|
||||
FloatModel a1_mult;
|
||||
FloatModel a2_mult;
|
||||
FloatModel b1_mult;
|
||||
FloatModel b2_mult;
|
||||
|
||||
FloatModel a1_ltune;
|
||||
FloatModel a2_ltune;
|
||||
FloatModel b1_ltune;
|
||||
FloatModel b2_ltune;
|
||||
|
||||
FloatModel a1_rtune;
|
||||
FloatModel a2_rtune;
|
||||
FloatModel b1_rtune;
|
||||
FloatModel b2_rtune;
|
||||
|
||||
graphModel a1_graph;
|
||||
graphModel a2_graph;
|
||||
graphModel b1_graph;
|
||||
graphModel b2_graph;
|
||||
|
||||
FloatModel m_abmix;
|
||||
|
||||
FloatModel m_envAmt;
|
||||
|
||||
TempoSyncKnobModel m_envAtt;
|
||||
TempoSyncKnobModel m_envHold;
|
||||
TempoSyncKnobModel m_envDec;
|
||||
|
||||
FloatModel m_xtalk;
|
||||
|
||||
IntModel m_amod;
|
||||
IntModel m_bmod;
|
||||
|
||||
IntModel m_selectedGraph;
|
||||
|
||||
friend class WatsynObject;
|
||||
friend class WatsynView;
|
||||
};
|
||||
|
||||
|
||||
class WatsynView : public InstrumentView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WatsynView( Instrument * _instrument,
|
||||
QWidget * _parent );
|
||||
virtual ~WatsynView();
|
||||
|
||||
protected slots:
|
||||
void updateLayout();
|
||||
|
||||
void sinWaveClicked();
|
||||
void triWaveClicked();
|
||||
void sawWaveClicked();
|
||||
void sqrWaveClicked();
|
||||
|
||||
void smoothClicked();
|
||||
void normalizeClicked();
|
||||
void invertClicked();
|
||||
void phaseLeftClicked();
|
||||
void phaseRightClicked();
|
||||
void loadClicked();
|
||||
|
||||
private:
|
||||
virtual void modelChanged();
|
||||
|
||||
// knobs
|
||||
knob * a1_volKnob;
|
||||
knob * a2_volKnob;
|
||||
knob * b1_volKnob;
|
||||
knob * b2_volKnob;
|
||||
|
||||
knob * a1_panKnob;
|
||||
knob * a2_panKnob;
|
||||
knob * b1_panKnob;
|
||||
knob * b2_panKnob;
|
||||
|
||||
knob * a1_multKnob;
|
||||
knob * a2_multKnob;
|
||||
knob * b1_multKnob;
|
||||
knob * b2_multKnob;
|
||||
|
||||
knob * a1_ltuneKnob;
|
||||
knob * a2_ltuneKnob;
|
||||
knob * b1_ltuneKnob;
|
||||
knob * b2_ltuneKnob;
|
||||
|
||||
knob * a1_rtuneKnob;
|
||||
knob * a2_rtuneKnob;
|
||||
knob * b1_rtuneKnob;
|
||||
knob * b2_rtuneKnob;
|
||||
|
||||
knob * m_abmixKnob;
|
||||
|
||||
knob * m_envAmtKnob;
|
||||
|
||||
TempoSyncKnob * m_envAttKnob;
|
||||
TempoSyncKnob * m_envHoldKnob;
|
||||
TempoSyncKnob * m_envDecKnob;
|
||||
|
||||
knob * m_xtalkKnob;
|
||||
|
||||
automatableButtonGroup * m_selectedGraphGroup;
|
||||
automatableButtonGroup * m_aModGroup;
|
||||
automatableButtonGroup * m_bModGroup;
|
||||
|
||||
graph * a1_graph;
|
||||
graph * a2_graph;
|
||||
graph * b1_graph;
|
||||
graph * b2_graph;
|
||||
|
||||
pixmapButton * m_sinWaveButton;
|
||||
pixmapButton * m_triWaveButton;
|
||||
pixmapButton * m_sawWaveButton;
|
||||
pixmapButton * m_sqrWaveButton;
|
||||
pixmapButton * m_normalizeButton;
|
||||
pixmapButton * m_invertButton;
|
||||
pixmapButton * m_smoothButton;
|
||||
pixmapButton * m_phaseLeftButton;
|
||||
pixmapButton * m_phaseRightButton;
|
||||
pixmapButton * m_loadButton;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
BIN
plugins/watsyn/a1_active.png
Normal file
|
After Width: | Height: | Size: 767 B |
BIN
plugins/watsyn/a1_inactive.png
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
plugins/watsyn/a2_active.png
Normal file
|
After Width: | Height: | Size: 815 B |
BIN
plugins/watsyn/a2_inactive.png
Normal file
|
After Width: | Height: | Size: 500 B |
BIN
plugins/watsyn/aam_active.png
Normal file
|
After Width: | Height: | Size: 830 B |
BIN
plugins/watsyn/aam_inactive.png
Normal file
|
After Width: | Height: | Size: 480 B |
BIN
plugins/watsyn/amix_active.png
Normal file
|
After Width: | Height: | Size: 1006 B |
BIN
plugins/watsyn/amix_inactive.png
Normal file
|
After Width: | Height: | Size: 619 B |
BIN
plugins/watsyn/apm_active.png
Normal file
|
After Width: | Height: | Size: 829 B |
BIN
plugins/watsyn/apm_inactive.png
Normal file
|
After Width: | Height: | Size: 476 B |
BIN
plugins/watsyn/arm_active.png
Normal file
|
After Width: | Height: | Size: 889 B |
BIN
plugins/watsyn/arm_inactive.png
Normal file
|
After Width: | Height: | Size: 569 B |
BIN
plugins/watsyn/artwork.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
plugins/watsyn/b1_active.png
Normal file
|
After Width: | Height: | Size: 712 B |
BIN
plugins/watsyn/b1_inactive.png
Normal file
|
After Width: | Height: | Size: 431 B |
BIN
plugins/watsyn/b2_active.png
Normal file
|
After Width: | Height: | Size: 764 B |
BIN
plugins/watsyn/b2_inactive.png
Normal file
|
After Width: | Height: | Size: 490 B |
BIN
plugins/watsyn/bam_active.png
Normal file
|
After Width: | Height: | Size: 712 B |
BIN
plugins/watsyn/bam_inactive.png
Normal file
|
After Width: | Height: | Size: 451 B |
BIN
plugins/watsyn/bmix_active.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
plugins/watsyn/bmix_inactive.png
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
plugins/watsyn/bpm_active.png
Normal file
|
After Width: | Height: | Size: 729 B |
BIN
plugins/watsyn/bpm_inactive.png
Normal file
|
After Width: | Height: | Size: 443 B |
BIN
plugins/watsyn/brm_active.png
Normal file
|
After Width: | Height: | Size: 792 B |
BIN
plugins/watsyn/brm_inactive.png
Normal file
|
After Width: | Height: | Size: 540 B |
BIN
plugins/watsyn/inv_active.png
Normal file
|
After Width: | Height: | Size: 655 B |
BIN
plugins/watsyn/inv_inactive.png
Normal file
|
After Width: | Height: | Size: 596 B |
BIN
plugins/watsyn/load_active.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
plugins/watsyn/load_inactive.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
plugins/watsyn/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
plugins/watsyn/norm_active.png
Normal file
|
After Width: | Height: | Size: 702 B |
BIN
plugins/watsyn/norm_inactive.png
Normal file
|
After Width: | Height: | Size: 641 B |
BIN
plugins/watsyn/phl_active.png
Normal file
|
After Width: | Height: | Size: 734 B |
BIN
plugins/watsyn/phl_inactive.png
Normal file
|
After Width: | Height: | Size: 693 B |
BIN
plugins/watsyn/phr_active.png
Normal file
|
After Width: | Height: | Size: 708 B |
BIN
plugins/watsyn/phr_inactive.png
Normal file
|
After Width: | Height: | Size: 671 B |
BIN
plugins/watsyn/saw_active.png
Normal file
|
After Width: | Height: | Size: 706 B |
BIN
plugins/watsyn/saw_inactive.png
Normal file
|
After Width: | Height: | Size: 646 B |
BIN
plugins/watsyn/sin_active.png
Normal file
|
After Width: | Height: | Size: 734 B |
BIN
plugins/watsyn/sin_inactive.png
Normal file
|
After Width: | Height: | Size: 699 B |
BIN
plugins/watsyn/smooth_active.png
Normal file
|
After Width: | Height: | Size: 709 B |
BIN
plugins/watsyn/smooth_inactive.png
Normal file
|
After Width: | Height: | Size: 649 B |
BIN
plugins/watsyn/sqr_active.png
Normal file
|
After Width: | Height: | Size: 687 B |
BIN
plugins/watsyn/sqr_inactive.png
Normal file
|
After Width: | Height: | Size: 640 B |
BIN
plugins/watsyn/tri_active.png
Normal file
|
After Width: | Height: | Size: 738 B |
BIN
plugins/watsyn/tri_inactive.png
Normal file
|
After Width: | Height: | Size: 699 B |
BIN
plugins/watsyn/wavegraph.png
Normal file
|
After Width: | Height: | Size: 612 B |
@@ -679,7 +679,11 @@ void graphModel::shiftPhase( int _deg )
|
||||
|
||||
// shift phase
|
||||
for( int i = 0; i < length(); i++ )
|
||||
m_samples[i] = temp[ ( i + offset ) % length() ];
|
||||
{
|
||||
int o = ( i + offset ) % length();
|
||||
while( o < 0 ) o += length();
|
||||
m_samples[i] = temp[o];
|
||||
}
|
||||
|
||||
emit samplesChanged( 0, length()-1 );
|
||||
}
|
||||
|
||||