Compare commits

..

16 Commits

Author SHA1 Message Date
Tobias Doerffel
482f89d03e Made 0.4.9 release
Bumped version number to 0.4.9 in CMakeLists.txt and README.
2010-12-15 00:20:18 +01:00
Tobias Doerffel
a352341080 CMakeLists.txt: new filename for Fluidsynth DLL
When packaging for Win32 use the new filename for the Fluidsynth DLL.
2010-12-14 10:38:15 +01:00
Tobias Doerffel
1590dd0d39 ZynAddSubFX: link against -lws2_32 on Win32
Once more explicit linking is required with recent MinGW toolchains.
2010-12-06 10:42:29 +01:00
Tobias Doerffel
49b6f25b2d Build system: explicitely link against WinMM library on Win32
When building for Win32 with recent MinGW64 runtime we have to link
against WinMM library explicitely.
2010-12-05 23:58:34 +01:00
Tobias Doerffel
8c4a8182ab MidiWinMM: fixed compiler warning
Pass 0 instead of NULL for 3rd and 4th argument of midiOutOpen().
2010-12-05 23:29:23 +01:00
Tobias Doerffel
625e70d50a Build system: fixed relative linker paths warnings
Fixed the warnings about relative linker paths issued by CMake >= 2.8.
2010-12-05 23:27:55 +01:00
Tobias Doerffel
b1b63364d5 Merge branch 'calf-updates'
* calf-updates:
  Reimplement modulation matrix (and tables in general) using configure variables. Slow and most likely incomplete, but a good start.
  Add extra checks to detect when param_count != param array size - 1.
  Fix another install-related crash, this time due to invalid params in fluidsynth. (cherry picked from commit 034e3a47cd40eb6bb7d221274fda2a5c1c79f42f)
  Fix the infamous crash on install. (cherry picked from commit f0568e2f8a4c7d0003cc5a15e300aa2ebb3f93cb)
  The range given in the comment wasn't really correct. (cherry picked from commit 292cdaa81dab7e7d948f597041cb86d70dc5ff92)
  Use symmetric dB range for EQ plugins.
  Fix a few bugs in compilation of limited versions (DSSI without GUI, no JACK host).
  Initialise the vintage delay properly... hopefully this time. (cherry picked from commit c96ff1d680148cc877fab3b641d666068eea06aa)
  Unbreak Monosynth by changing listview to use a 'key' attribute instead of 'param'.
(cherry picked from commit c562952800)
2010-12-05 23:11:43 +01:00
Tobias Doerffel
20d6852cda Refreshed French QM file
For some reason the "lrelease" utility produced an incomplete QM file.
Releasing from within the Qt Linguist seems to work.
2010-11-07 17:04:46 +01:00
Tobias Doerffel
884116e6a6 Updated French localization files
Thanks to Bernard Opic <bernard/dot/opic/at/media-tips/dot/com> for the
contribution!
2010-11-07 17:02:13 +01:00
André Hentschel
1ea719c7c4 vst_base: Fix winelib build on x86-64 2010-11-04 17:09:35 -04:00
Tobias Doerffel
af17d00821 Merge branch 'calf-updates'
* calf-updates:
  Make meters in compressor/EQ/distortion modules sample-rate-dependent. (cherry picked from commit 47a87c696223625d31cf106e12ed08cd3293be14)
(cherry picked from commit 6581a11a45)
2010-10-17 18:19:32 +02:00
Tobias Doerffel
60d302d09e InstrumentTrackView: use QMdiArea's window activation history
There's no need to implement an own (buggy) window activation history
for InstrumentTrackWindows. Use QMdiArea::subWindowList(...) instead.
Fixes buggy keyboard focus when switching between InstrumentTrackWindows.
(cherry picked from commit c05965117c)
2010-10-06 10:17:48 +02:00
Tobias Doerffel
3ae2b40eec InstrumentTrackView: added one-window-mode + global piano focus
Added a one-window-mode which allows to have only one instrument track
window open at a time. The content of this window is replaced each time
you open a different track.

Furthermore added global reception and forwarding of key events to the
piano widget of the top-most instrument track window. This for example
enables the user to play test sounds while tweaking some effects in a
different subwindow.
(cherry picked from commit 93681760d2)
2010-10-05 11:25:43 +02:00
Tobias Doerffel
384a024bae Fixed alternating row color in QTreeView (Sf2 patch selector)
With Qt 4.7 the alternating row color in the Sf2 patch selector dialog
somehow was messed up. Fixed this by explicitely setting the alternating
row color in the style's CSS files.
(cherry picked from commit fd40743772)
2010-09-29 16:33:53 +02:00
Tobias Doerffel
66b83dfaec SampleTrack: do not hide EffectRackView forever when closing subwindow
Whenever closing the sample track effects window using its own close
button and trying to open it again there was only a really small window
without functionality. Fixed this by explicitely also showing subwindow
content in showEffects().

Closes #3075205.
(cherry picked from commit 830c2cb975)
2010-09-29 16:10:52 +02:00
Tobias Doerffel
f1f5040ddc Merge branch 'calf-updates'
* calf-updates:
  LADSPA/CALF: removed unused file
  One table_edit_iface per table; start implementing a bridge class. (cherry picked from commit 2019ae2d8f9636b7d5cdb0c1fdd5f0d6f2b47e3d)
  Move the table_edit_iface out of plugin_metadata_iface, where it should have never been in first place. (cherry picked from commit 6907dc9670eae2313707b142c552a8d9e8b477b5)
  Fix organ crash in calfjackhost. (cherry picked from commit b2853103199b3f5f3a5d22271c5d89122514dd53)
  Remove the forgotten leftover references to the old extensions. (cherry picked from commit deb8b77bdb1e1648a38589b3be3d4d66175b4934)
  Replace string port/message context using persist extension. (cherry picked from commit b8e69ceb2ff7aca549efd939d04447e2f08ad5a8)
  Comment out the barfage when passing configure variables via message_run. (cherry picked from commit 1e767ff88578011c2f65466d5516953271e2cafd)
  Add a crude incomplete implementation of persist extension support. (cherry picked from commit 3ec11c04799fc08fd408c4ef2350df65f88ccfde)
  Add LV2 persist extension by paniq. (cherry picked from commit 1965282a28c6940164ffff7ebd106b27cafd7f2a)
  More refactoring of the VUs. The goal: to be able to add peak meters without major hassle. (cherry picked from commit 00ee132cc2ebe3b664c7d5760260d76dda37bf26)
  Fix handling of very short notes in Monosynth. (cherry picked from commit 5965d9922a0753e2dce4f743a23b9512be01a7ac)
(cherry picked from commit 01c91b6ce3)
2010-09-28 23:44:33 +02:00
42 changed files with 3113 additions and 1917 deletions

View File

@@ -15,7 +15,7 @@ INCLUDE(FindPkgConfig)
SET(VERSION_MAJOR "0")
SET(VERSION_MINOR "4")
SET(VERSION_PATCH "8")
SET(VERSION_PATCH "9")
#SET(VERSION_SUFFIX "")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
IF(VERSION_SUFFIX)
@@ -426,11 +426,15 @@ ADD_SUBDIRECTORY(data)
#
# build LMMS-binary
#
IF(LMMS_BUILD_WIN32)
SET(EXTRA_LIBRARIES "-lwinmm")
ENDIF()
ADD_DEFINITIONS(-D'LIB_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/"' -D'PLUGIN_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/lmms/"' ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PORTAUDIO_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS})
LINK_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/lib ${ASOUND_LIBRARY_DIR} ${JACK_LIBRARY_DIRS} ${SAMPLERATE_LIBRARY_DIRS} ${SNDFILE_LIBRARY_DIRS})
LINK_LIBRARIES(${CMAKE_THREAD_LIBS_INIT} ${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES})
LINK_LIBRARIES(${CMAKE_THREAD_LIBS_INIT} ${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES} ${EXTRA_LIBRARIES})
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/lmms.1.gz COMMAND gzip -c ${CMAKE_SOURCE_DIR}/lmms.1 > ${CMAKE_BINARY_DIR}/lmms.1.gz DEPENDS ${CMAKE_SOURCE_DIR}/lmms.1 COMMENT "Generating lmms.1.gz")
@@ -451,7 +455,7 @@ IF(LMMS_BUILD_WIN32)
${MINGW_PREFIX}/bin/libvorbisenc-2.dll
${MINGW_PREFIX}/bin/libvorbisfile-3.dll
${MINGW_PREFIX}/bin/libogg-0.dll
${MINGW_PREFIX}/bin/libfluidsynth-1.dll
${MINGW_PREFIX}/bin/libfluidsynth.dll
${MINGW_PREFIX}/bin/libfftw3f-3.dll
${MINGW_PREFIX}/bin/libFLAC-8.dll
${MINGW_PREFIX}/bin/SDL.dll

2
README
View File

@@ -1,4 +1,4 @@
Linux MultiMedia Studio 0.4.8
Linux MultiMedia Studio 0.4.9
==============================
Copyright (c) 2004-2010 by LMMS-developers

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -155,6 +155,10 @@ timeLine {
font-size: 8px;
}
QTreeView {
alternate-background-color: rgb(108,108,108);
}
/* Plugins */
TripleOscillatorView knob {

View File

@@ -2,7 +2,7 @@
* InstrumentTrack.h - declaration of class InstrumentTrack, a track + window
* which holds an instrument-plugin
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -258,6 +258,7 @@ public:
return castModel<InstrumentTrack>();
}
static InstrumentTrackWindow * topLevelInstrumentTrackWindow();
QMenu * midiMenu()
{
@@ -266,7 +267,7 @@ public:
void freeInstrumentTrackWindow();
static void cleanupWindowPool();
static void cleanupWindowCache();
protected:
@@ -287,7 +288,7 @@ private slots:
private:
InstrumentTrackWindow * m_window;
static QQueue<InstrumentTrackWindow *> s_windows;
static QQueue<InstrumentTrackWindow *> s_windowCache;
// widgets in track-settings-widget
trackLabelButton * m_tlb;
@@ -334,9 +335,11 @@ public:
return castModel<InstrumentTrack>();
}
void setInstrumentTrackView( InstrumentTrackView * _tv )
void setInstrumentTrackView( InstrumentTrackView * _tv );
PianoView * pianoView()
{
m_itv = _tv;
return m_pianoView;
}
static void dragEnterEventGeneric( QDragEnterEvent * _dee );

View File

@@ -1,7 +1,7 @@
/*
* PianoView.h - declaration of PianoView, an interactive piano/keyboard-widget
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -43,10 +43,13 @@ public:
static int getKeyFromKeyEvent( QKeyEvent * _ke );
protected:
virtual void modelChanged();
public:
virtual void keyPressEvent( QKeyEvent * ke );
virtual void keyReleaseEvent( QKeyEvent * ke );
protected:
virtual void modelChanged();
virtual void contextMenuEvent( QContextMenuEvent * _me );
virtual void paintEvent( QPaintEvent * );
virtual void mousePressEvent( QMouseEvent * me );

View File

@@ -1,7 +1,7 @@
/*
* setup_dialog.h - dialog for setting up LMMS
*
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -104,6 +104,7 @@ private slots:
void toggleDisableChActInd( bool _disabled );
void toggleManualChPiano( bool _enabled );
void toggleOneInstrumentTrackWindow( bool _enabled );
private:
@@ -148,6 +149,7 @@ private:
bool m_disableChActInd;
bool m_manualChPiano;
bool m_oneInstrumentTrackWindow;
typedef QMap<QString, AudioDevice::setupWidget *> AswMap;
typedef QMap<QString, MidiClient::setupWidget *> MswMap;

View File

@@ -47,7 +47,6 @@ enum parameter_flags
PF_BOOL = 0x0002, ///< bool value (usually >=0.5f is treated as TRUE, which is inconsistent with LV2 etc. which treats anything >0 as TRUE)
PF_ENUM = 0x0003, ///< enum value (min, min+1, ..., max, only guaranteed to work when min = 0)
PF_ENUM_MULTI = 0x0004, ///< SET / multiple-choice
PF_STRING = 0x0005, ///< see: http://lv2plug.in/docs/index.php?title=String_port
PF_SCALEMASK = 0xF0, ///< bit mask for scale
PF_SCALE_DEFAULT = 0x00, ///< no scale given
@@ -82,7 +81,6 @@ enum parameter_flags
PF_PROP_OUTPUT = 0x080000, ///< output port
PF_PROP_OPTIONAL = 0x100000, ///< connection optional
PF_PROP_GRAPH = 0x200000, ///< add graph
PF_PROP_MSGCONTEXT= 0x400000, ///< message context
PF_UNITMASK = 0xFF000000, ///< bit mask for units \todo reduce to use only 5 bits
PF_UNIT_DB = 0x01000000, ///< decibels
@@ -224,27 +222,15 @@ struct table_column_info
};
/// 'has string parameters containing tabular data' interface
struct table_edit_iface
struct table_metadata_iface
{
/// retrieve the table layout for specific parameter
virtual const table_column_info *get_table_columns(int param) const = 0;
virtual const table_column_info *get_table_columns() const = 0;
/// return the current number of rows
virtual uint32_t get_table_rows(int param) const = 0;
/// return the fixed number of rows, or 0 if the number of rows is variable
virtual uint32_t get_table_rows() const = 0;
/// retrieve data item from the plugin
virtual std::string get_cell(int param, int row, int column) const;
/// set data item to the plugin
virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const { error.clear(); }
/// return a line graph interface for a specific parameter/column (unused for now)
virtual const line_graph_iface *get_graph_iface(int param, int column) const { return NULL; }
/// return an editor name for a specific grid cell (unused for now - I don't even know how editors be implemented)
virtual const char *get_cell_editor(int param, int column) const { return NULL; }
virtual ~table_edit_iface() {}
virtual ~table_metadata_iface() {}
};
/// 'may receive configure variables' interface
@@ -317,8 +303,6 @@ struct plugin_metadata_iface
virtual bool requires_midi() const =0;
/// @return port offset of first control (parameter) port (= number of audio inputs + number of audio outputs in all existing plugins as for 1 Aug 2008)
virtual int get_param_port_offset() const = 0;
/// @return table_edit_iface if any
virtual const table_edit_iface *get_table_edit_iface() const = 0;
/// @return NULL-terminated list of menu commands
virtual plugin_command_info *get_commands() const { return NULL; }
/// @return description structure for given parameter
@@ -331,12 +315,12 @@ struct plugin_metadata_iface
virtual bool is_cv(int param_no) const = 0;
/// is the given parameter non-interpolated?
virtual bool is_noisy(int param_no) const = 0;
/// does the plugin require message context? (or DSSI configure) may be slow
virtual bool requires_message_context() const = 0;
/// does the plugin require string port extension? (or DSSI configure) may be slow
virtual bool requires_string_ports() const = 0;
/// add all message context parameter numbers to the ports vector
virtual void get_message_context_parameters(std::vector<int> &ports) const = 0;
virtual bool requires_configure() const = 0;
/// obtain array of names of configure variables (or NULL is none needed)
virtual const char *const *get_configure_vars() const { return NULL; }
/// @return table_metadata_iface if any
virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { return NULL; }
/// Do-nothing destructor to silence compiler warning
virtual ~plugin_metadata_iface() {}
@@ -427,7 +411,7 @@ struct audio_module_iface
virtual void set_sample_rate(uint32_t sr) = 0;
/// Execute menu command with given number
virtual void execute(int cmd_no) = 0;
/// DSSI configure call
/// DSSI configure call, value = NULL = reset to default
virtual char *configure(const char *key, const char *value) = 0;
/// Send all understood configure vars (none by default)
virtual void send_configures(send_configure_iface *sci) = 0;
@@ -552,9 +536,6 @@ public:
virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast<const line_graph_iface *>(this); }
};
extern bool check_for_message_context_ports(const parameter_properties *parameters, int count);
extern bool check_for_string_ports(const parameter_properties *parameters, int count);
#if USE_EXEC_GUI || USE_DSSI
enum line_graph_item
@@ -616,7 +597,6 @@ public:
bool get_midi() const { return Metadata::support_midi; }
bool requires_midi() const { return Metadata::require_midi; }
bool is_rt_capable() const { return Metadata::rt_capable; }
const table_edit_iface *get_table_edit_iface() const { return dynamic_cast<const table_edit_iface *>(this); }
int get_param_port_offset() const { return Metadata::in_count + Metadata::out_count; }
const char *get_gui_xml() const { static const char *data_ptr = calf_plugins::load_gui_xml(get_id()); return data_ptr; }
plugin_command_info *get_commands() const { return NULL; }
@@ -625,18 +605,11 @@ public:
bool is_cv(int param_no) const { return true; }
bool is_noisy(int param_no) const { return false; }
const ladspa_plugin_info &get_plugin_info() const { return plugin_info; }
bool requires_message_context() const { return check_for_message_context_ports(param_props, Metadata::param_count); }
bool requires_string_ports() const { return check_for_string_ports(param_props, Metadata::param_count); }
void get_message_context_parameters(std::vector<int> &ports) const {
for (int i = 0; i < get_param_count(); ++i) {
if (get_param_props(i)->flags & PF_PROP_MSGCONTEXT)
ports.push_back(i);
}
}
bool requires_configure() const { return false; }
};
#define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata<name##_metadata>::port_names[]
#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[]
#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[name##_metadata::param_count + 1]
#define CALF_PLUGIN_INFO(name) template<> calf_plugins::ladspa_plugin_info plugin_metadata<name##_metadata>::plugin_info
#define PLUGIN_NAME_ID_LABEL(name, id, label) \
static const char *impl_get_name() { return name; } \
@@ -645,22 +618,22 @@ public:
extern const char *calf_copyright_info;
bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true);
bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true, float res = 256, float ofs = 0.4);
/// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0)
static inline float dB_grid(float amp)
/// convert amplitude value to normalized grid-ish value
static inline float dB_grid(float amp, float res = 256, float ofs = 0.4)
{
return log(amp) * (1.0 / log(256.0)) + 0.4;
return log(amp) * (1.0 / log(res)) + ofs;
}
template<class Fx>
static bool get_graph(Fx &fx, int subindex, float *data, int points)
static bool get_graph(Fx &fx, int subindex, float *data, int points, float res = 256, float ofs = 0.4)
{
for (int i = 0; i < points; i++)
{
typedef std::complex<double> cfloat;
double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate));
data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate), res, ofs);
}
return true;
}
@@ -689,6 +662,59 @@ struct preset_access_iface
virtual ~preset_access_iface() {}
};
/// Implementation of table_metadata_iface providing metadata for mod matrices
class mod_matrix_metadata: public table_metadata_iface
{
public:
/// Mapping modes
enum mapping_mode {
map_positive, ///< 0..100%
map_bipolar, ///< -100%..100%
map_negative, ///< -100%..0%
map_squared, ///< x^2
map_squared_bipolar, ///< x^2 scaled to -100%..100%
map_antisquared, ///< 1-(1-x)^2 scaled to 0..100%
map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100%
map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0)
map_type_count
};
const char **mod_src_names, **mod_dest_names;
mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names);
virtual const table_column_info *get_table_columns() const;
virtual uint32_t get_table_rows() const;
protected:
/// Column descriptions for table widget
table_column_info table_columns[6];
unsigned int matrix_rows;
};
/// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column)
/// @arg key key to parse
/// @arg prefix table prefix (e.g. "modmatrix:")
/// @arg is_rows[out] set to true if key == prefix + "rows"
/// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
/// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
/// @retval true if this is one of the recognized string forms
extern bool parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column);
#if USE_EXEC_GUI
class table_via_configure
{
protected:
typedef std::pair<int, int> coord;
std::vector<table_column_info> columns;
std::map<coord, std::string> values;
int rows;
public:
table_via_configure();
void configure(const char *key, const char *value);
virtual ~table_via_configure();
};
#endif
};
#endif

View File

@@ -88,7 +88,7 @@ struct ladspa_plugin_metadata_set
std::vector<DSSI_Program_Descriptor> *preset_descs;
#endif
int input_count, output_count, param_count, real_param_count;
int input_count, output_count, param_count;
const plugin_metadata_iface *metadata;
ladspa_plugin_metadata_set();

View File

@@ -27,11 +27,9 @@
#include <vector>
#include <lv2.h>
#include <calf/giface.h>
#include <calf/lv2-midiport.h>
#include <calf/lv2_contexts.h>
#include <calf/lv2_event.h>
#include <calf/lv2_persist2.h>
#include <calf/lv2_progress.h>
#include <calf/lv2_string_port.h>
#include <calf/lv2_uri_map.h>
#include <string.h>
@@ -43,32 +41,29 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
audio_module_iface *module;
bool set_srate;
int srate_to_set;
LV2_MIDI *midi_data;
LV2_Event_Buffer *event_data;
LV2_URI_Map_Feature *uri_map;
LV2_Event_Feature *event_feature;
uint32_t midi_event_type;
std::vector<int> message_params;
LV2_Progress *progress_report_feature;
float **ins, **outs, **params;
int out_count;
int real_param_count;
lv2_instance(audio_module_iface *_module)
{
module = _module;
module->get_port_arrays(ins, outs, params);
metadata = module->get_metadata_iface();
metadata->get_message_context_parameters(message_params);
out_count = metadata->get_output_count();
real_param_count = metadata->get_param_count();
uri_map = NULL;
midi_data = NULL;
event_data = NULL;
progress_report_feature = NULL;
midi_event_type = 0xFFFFFFFF;
srate_to_set = 44100;
set_srate = true;
// printf("message params %d\n", (int)message_params.size());
}
/// This, and not Module::post_instantiate, is actually called by lv2_wrapper class
void post_instantiate()
@@ -91,21 +86,27 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
void send_configures(send_configure_iface *sci) {
module->send_configures(sci);
}
uint32_t impl_message_run(const void *valid_inputs, void *output_ports) {
uint8_t *vi = (uint8_t *)valid_inputs;
int ofs = metadata->get_param_port_offset();
for (unsigned int i = 0; i < message_params.size(); i++)
void impl_restore(LV2_Persist_Retrieve_Function retrieve, void *callback_data)
{
const char *const *vars = module->get_metadata_iface()->get_configure_vars();
if (!vars)
return;
assert(uri_map);
uint32_t string_type = uri_map->uri_to_id(uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String");
assert(string_type);
for (unsigned int i = 0; vars[i]; i++)
{
int pn = message_params[i];
const parameter_properties &pp = *metadata->get_param_props(pn);
int ppn = pn + ofs;
if ((pp.flags & PF_TYPEMASK) == PF_STRING && (vi[ppn >> 3] & (1 << (ppn & 7)))
&& (((LV2_String_Data *)params[pn])->flags & LV2_STRING_DATA_CHANGED_FLAG)) {
printf("Calling configure on %s\n", pp.short_name);
configure(pp.short_name, ((LV2_String_Data *)params[pn])->data);
size_t len = 0;
uint32_t type = 0;
const void *ptr = (*retrieve)(callback_data, vars[i], &len, &type);
if (ptr && type == string_type)
{
printf("Calling configure on %s\n", vars[i]);
configure(vars[i], std::string((const char *)ptr, len).c_str());
}
else
configure(vars[i], NULL);
}
return module->message_run(valid_inputs, output_ports);
}
char *configure(const char *key, const char *value) {
// disambiguation - the plugin_ctl_iface version is just a stub, so don't use it
@@ -150,14 +151,14 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
virtual float get_param_value(int param_no)
{
// XXXKF hack
if (param_no >= metadata->get_param_count())
if (param_no >= real_param_count)
return 0;
return (*params)[param_no];
}
virtual void set_param_value(int param_no, float value)
{
// XXXKF hack
if (param_no >= metadata->get_param_count())
if (param_no >= real_param_count)
return;
*params[param_no] = value;
}
@@ -176,7 +177,7 @@ struct lv2_wrapper
typedef lv2_instance instance;
static LV2_Descriptor descriptor;
static LV2_Calf_Descriptor calf_descriptor;
static LV2MessageContext message_context;
static LV2_Persist persist;
std::string uri;
lv2_wrapper()
@@ -191,12 +192,13 @@ struct lv2_wrapper
descriptor.deactivate = cb_deactivate;
descriptor.cleanup = cb_cleanup;
descriptor.extension_data = cb_ext_data;
persist.save = cb_persist_save;
persist.restore = cb_persist_restore;
calf_descriptor.get_pci = cb_get_pci;
message_context.message_connect_port = cb_connect;
message_context.message_run = cb_message_run;
}
static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) {
static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation)
{
instance *const mod = (instance *)Instance;
const plugin_metadata_iface *md = mod->metadata;
unsigned long ins = md->get_input_count();
@@ -215,12 +217,14 @@ struct lv2_wrapper
}
}
static void cb_activate(LV2_Handle Instance) {
static void cb_activate(LV2_Handle Instance)
{
instance *const mod = (instance *)Instance;
mod->set_srate = true;
}
static void cb_deactivate(LV2_Handle Instance) {
static void cb_deactivate(LV2_Handle Instance)
{
instance *const mod = (instance *)Instance;
mod->module->deactivate();
}
@@ -259,11 +263,8 @@ struct lv2_wrapper
return static_cast<plugin_ctl_iface *>(Instance);
}
static uint32_t cb_message_run(LV2_Handle Instance, const void *valid_inputs, void *outputs_written) {
instance *mod = (instance *)Instance;
return mod->impl_message_run(valid_inputs, outputs_written);
}
static void cb_run(LV2_Handle Instance, uint32_t SampleCount) {
static void cb_run(LV2_Handle Instance, uint32_t SampleCount)
{
instance *const inst = (instance *)Instance;
audio_module_iface *mod = inst->module;
if (inst->set_srate) {
@@ -279,20 +280,51 @@ struct lv2_wrapper
}
inst->module->process_slice(offset, SampleCount);
}
static void cb_cleanup(LV2_Handle Instance) {
static void cb_cleanup(LV2_Handle Instance)
{
instance *const mod = (instance *)Instance;
delete mod;
}
static const void *cb_ext_data(const char *URI) {
static const void *cb_ext_data(const char *URI)
{
if (!strcmp(URI, "http://foltman.com/ns/calf-plugin-instance"))
return &calf_descriptor;
if (!strcmp(URI, LV2_CONTEXT_MESSAGE))
return &message_context;
if (!strcmp(URI, LV2_PERSIST_URI))
return &persist;
return NULL;
}
static void cb_persist_save(LV2_Handle Instance, LV2_Persist_Store_Function store, void *callback_data)
{
instance *const inst = (instance *)Instance;
struct store_state: public send_configure_iface
{
LV2_Persist_Store_Function store;
void *callback_data;
uint32_t string_data_type;
virtual void send_configure(const char *key, const char *value)
{
(*store)(callback_data, key, value, strlen(value) + 1, string_data_type);
}
};
// A host that supports a Persist extension should support an URI map extension as well.
assert(inst->uri_map);
store_state s;
s.store = store;
s.callback_data = callback_data;
s.string_data_type = inst->uri_map->uri_to_id(inst->uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String");
inst->send_configures(&s);
}
static void cb_persist_restore(LV2_Handle Instance, LV2_Persist_Retrieve_Function retrieve, void *callback_data)
{
instance *const inst = (instance *)Instance;
inst->impl_restore(retrieve, callback_data);
}
static lv2_wrapper &get() {
static lv2_wrapper instance;
return instance;
static lv2_wrapper *instance = new lv2_wrapper;
return *instance;
}
};

View File

@@ -25,6 +25,9 @@
#include "giface.h"
#define MONO_VU_METER_PARAMS param_meter_in, param_meter_out, param_clip_in, param_clip_out
#define STEREO_VU_METER_PARAMS param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR
namespace calf_plugins {
struct flanger_metadata: public plugin_metadata<flanger_metadata>
@@ -115,6 +118,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
param_count };
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
enum { step_size = 64, step_shift = 6 };
enum { mod_matrix_slots = 10 };
enum {
modsrc_none,
modsrc_velocity,
@@ -140,6 +144,12 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
moddest_count,
};
PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
mod_matrix_metadata mm_metadata;
monosynth_metadata();
/// Lookup of table edit interface
virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; }
};
/// Thor's compressor - metadata
@@ -147,7 +157,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
struct compressor_metadata: public plugin_metadata<compressor_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out,
enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS,
param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression,
param_count };
PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor")
@@ -157,7 +167,7 @@ struct compressor_metadata: public plugin_metadata<compressor_metadata>
struct sidechaincompressor_metadata: public plugin_metadata<sidechaincompressor_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out,
enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS,
param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression,
param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level,
param_sc_listen, param_f1_active, param_f2_active, param_count };
@@ -168,8 +178,8 @@ struct sidechaincompressor_metadata: public plugin_metadata<sidechaincompressor_
struct multibandcompressor_metadata: public plugin_metadata<multibandcompressor_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
enum { param_bypass, param_level_in, param_level_out,
STEREO_VU_METER_PARAMS,
param_freq0, param_freq1, param_freq2,
param_sep0, param_sep1, param_sep2,
param_q0, param_q1, param_q2,
@@ -202,7 +212,7 @@ struct deesser_metadata: public plugin_metadata<deesser_metadata>
struct gate_metadata: public plugin_metadata<gate_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out,
enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS,
param_range, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_gating,
param_count };
PLUGIN_NAME_ID_LABEL("gate", "gate", "Gate")
@@ -212,7 +222,7 @@ struct gate_metadata: public plugin_metadata<gate_metadata>
struct sidechaingate_metadata: public plugin_metadata<sidechaingate_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out,
enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS,
param_range, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_gating,
param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level,
param_sc_listen, param_f1_active, param_f2_active, param_count };
@@ -223,8 +233,7 @@ struct sidechaingate_metadata: public plugin_metadata<sidechaingate_metadata>
struct equalizer5band_metadata: public plugin_metadata<equalizer5band_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
param_meter_outL, param_meter_outR, param_clip_inL, param_clip_outL, param_clip_inR, param_clip_outR,
enum { param_bypass, param_level_in, param_level_out, STEREO_VU_METER_PARAMS,
param_ls_active, param_ls_level, param_ls_freq,
param_hs_active, param_hs_level, param_hs_freq,
param_p1_active, param_p1_level, param_p1_freq, param_p1_q,
@@ -241,8 +250,8 @@ struct equalizer5band_metadata: public plugin_metadata<equalizer5band_metadata>
struct equalizer8band_metadata: public plugin_metadata<equalizer8band_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
enum { param_bypass, param_level_in, param_level_out,
STEREO_VU_METER_PARAMS,
param_hp_active, param_hp_freq, param_hp_mode,
param_lp_active, param_lp_freq, param_lp_mode,
param_ls_active, param_ls_level, param_ls_freq,
@@ -259,8 +268,8 @@ struct equalizer8band_metadata: public plugin_metadata<equalizer8band_metadata>
struct equalizer12band_metadata: public plugin_metadata<equalizer12band_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
enum { param_bypass, param_level_in, param_level_out,
STEREO_VU_METER_PARAMS,
param_hp_active, param_hp_freq, param_hp_mode,
param_lp_active, param_lp_freq, param_lp_mode,
param_ls_active, param_ls_level, param_ls_freq,
@@ -282,8 +291,7 @@ struct equalizer12band_metadata: public plugin_metadata<equalizer12band_metadata
struct pulsator_metadata: public plugin_metadata<pulsator_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
enum { param_bypass, param_level_in, param_level_out, STEREO_VU_METER_PARAMS,
param_mode, param_freq, param_amount, param_offset, param_mono, param_reset, param_count };
PLUGIN_NAME_ID_LABEL("pulsator", "pulsator", "Pulsator")
};
@@ -292,8 +300,7 @@ struct pulsator_metadata: public plugin_metadata<pulsator_metadata>
struct saturator_metadata: public plugin_metadata<saturator_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_mix, param_meter_in,
param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive,
enum { param_bypass, param_level_in, param_level_out, param_mix, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive,
param_lp_pre_freq, param_hp_pre_freq, param_lp_post_freq, param_hp_post_freq,
param_p_freq, param_p_level, param_p_q, param_count };
PLUGIN_NAME_ID_LABEL("saturator", "saturator", "Saturator")
@@ -302,8 +309,7 @@ struct saturator_metadata: public plugin_metadata<saturator_metadata>
struct exciter_metadata: public plugin_metadata<exciter_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_amount, param_meter_in,
param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive,
enum { param_bypass, param_level_in, param_level_out, param_amount, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive,
param_freq, param_listen, param_count };
PLUGIN_NAME_ID_LABEL("exciter", "exciter", "Exciter")
};
@@ -311,8 +317,7 @@ struct exciter_metadata: public plugin_metadata<exciter_metadata>
struct bassenhancer_metadata: public plugin_metadata<bassenhancer_metadata>
{
enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
enum { param_bypass, param_level_in, param_level_out, param_amount, param_meter_in,
param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive,
enum { param_bypass, param_level_in, param_level_out, param_amount, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive,
param_freq, param_listen, param_count };
PLUGIN_NAME_ID_LABEL("bassenhancer", "bassenhancer", "Bass Enhancer")
};
@@ -350,12 +355,8 @@ struct organ_enums
par_bassgain,
par_treblefreq,
par_treblegain,
par_var_mapcurve,
param_count
};
enum {
var_count = 1
};
enum organ_waveform {
wave_sine,
wave_sinepl1, wave_sinepl2, wave_sinepl3,
@@ -405,15 +406,21 @@ struct organ_metadata: public organ_enums, public plugin_metadata<organ_metadata
{
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ")
public:
plugin_command_info *get_commands();
const char *const *get_configure_vars() const;
};
/// FluidSynth - metadata
struct fluidsynth_metadata: public plugin_metadata<fluidsynth_metadata>
{
enum { par_master, par_interpolation, par_reverb, par_chorus, par_soundfont, par_preset_key_set, param_count };
enum { par_master, par_interpolation, par_reverb, par_chorus, param_count };
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = false };
PLUGIN_NAME_ID_LABEL("fluidsynth", "fluidsynth", "Fluidsynth")
public:
const char *const *get_configure_vars() const;
};
/// Wavetable - metadata
@@ -482,8 +489,14 @@ struct wavetable_metadata: public plugin_metadata<wavetable_metadata>
par_pwhlrange,
param_count };
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
enum { mod_matrix_slots = 10 };
enum { step_size = 64 };
PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable")
mod_matrix_metadata mm_metadata;
wavetable_metadata();
/// Lookup of table edit interface
virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; }
};
};

View File

@@ -25,26 +25,13 @@
namespace dsp {
/// Mapping modes
enum mapping_mode {
map_positive, ///< 0..100%
map_bipolar, ///< -100%..100%
map_negative, ///< -100%..0%
map_squared, ///< x^2
map_squared_bipolar, ///< x^2 scaled to -100%..100%
map_antisquared, ///< 1-(1-x)^2 scaled to 0..100%
map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100%
map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0)
map_type_count
};
/// Single entry in modulation matrix
struct modulation_entry
{
/// Mapped source
int src1;
/// Source mapping mode
mapping_mode mapping;
calf_plugins::mod_matrix_metadata::mapping_mode mapping;
/// Unmapped modulating source
int src2;
/// Modulation amount
@@ -60,7 +47,7 @@ struct modulation_entry
void reset() {
src1 = 0;
src2 = 0;
mapping = map_positive;
mapping = calf_plugins::mod_matrix_metadata::map_positive;
amount = 0.f;
dest = 0;
}
@@ -70,24 +57,17 @@ struct modulation_entry
namespace calf_plugins {
class mod_matrix: public table_edit_iface
class mod_matrix_impl
{
protected:
/// Polynomials for different scaling modes (1, x, x^2)
static const float scaling_coeffs[dsp::map_type_count][3];
/// Column descriptions for table widget
table_column_info table_columns[6];
dsp::modulation_entry *matrix;
mod_matrix_metadata *metadata;
unsigned int matrix_rows;
const char **mod_src_names, **mod_dest_names;
/// Polynomials for different scaling modes (1, x, x^2)
static const float scaling_coeffs[calf_plugins::mod_matrix_metadata::map_type_count][3];
mod_matrix(dsp::modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names);
public:
virtual const table_column_info *get_table_columns(int param) const;
virtual uint32_t get_table_rows(int param) const;
virtual std::string get_cell(int param, int row, int column) const;
virtual void set_cell(int param, int row, int column, const std::string &src, std::string &error) const;
mod_matrix_impl(dsp::modulation_entry *_matrix, calf_plugins::mod_matrix_metadata *_metadata);
/// Process modulation matrix, calculate outputs from inputs
inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc)
@@ -105,8 +85,14 @@ public:
}
}
}
};
void send_configures(send_configure_iface *);
char *configure(const char *key, const char *value);
private:
std::string get_cell(int row, int column) const;
void set_cell(int row, int column, const std::string &src, std::string &error);
};
};
#endif

View File

@@ -28,6 +28,7 @@
#include "audio_fx.h"
#include "giface.h"
#include "metadata.h"
#include "plugin_tools.h"
namespace calf_plugins {
@@ -51,8 +52,7 @@ private:
float hs_level_old, hs_freq_old;
float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands];
mutable float old_params_for_graph[graph_param_count];
uint32_t clip_inL, clip_outL, clip_inR, clip_outR;
float meter_inL, meter_outL, meter_inR, meter_outR;
dual_in_out_metering<BaseClass> meters;
CalfEqMode hp_mode, lp_mode;
dsp::biquad_d2<float> hp[3][2], lp[3][2];
dsp::biquad_d2<float> lsL, lsR, hsL, hsR;
@@ -73,6 +73,7 @@ public:
void set_sample_rate(uint32_t sr)
{
srate = sr;
meters.set_sample_rate(sr);
}
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;

View File

@@ -37,10 +37,9 @@ namespace calf_plugins {
/// Monosynth-in-making. Parameters may change at any point, so don't make songs with it!
/// It lacks inertia for parameters, even for those that really need it.
class monosynth_audio_module: public audio_module<monosynth_metadata>, public line_graph_iface, public mod_matrix
class monosynth_audio_module: public audio_module<monosynth_metadata>, public line_graph_iface, public mod_matrix_impl
{
public:
enum { mod_matrix_slots = 10 };
uint32_t srate, crate;
static dsp::waveform_family<MONOSYNTH_WAVE_BITS> *waves;
dsp::waveform_oscillator<MONOSYNTH_WAVE_BITS> osc1, osc2;
@@ -88,6 +87,8 @@ public:
int32_t last_stretch1;
/// Next note to play on the next calculate_step
int queue_note_on;
/// Whether the queued note has been already released
bool queue_note_on_and_off;
/// Velocity of the next note to play
float queue_vel;
/// Integer value for modwheel (0-16383, read from CC1 - MSBs and CC33 - LSBs)
@@ -122,6 +123,8 @@ public:
static void precalculate_waves(progress_report_iface *reporter);
void set_sample_rate(uint32_t sr);
void delayed_note_on();
/// Release a note (physically), called from note-off handler or when note-off has been scheduled after note-on (very short queued note)
void end_note();
/// Handle MIDI Note On message (does not immediately trigger a note, as it must start on
/// boundary of step_size samples).
void note_on(int note, int vel);
@@ -174,6 +177,9 @@ public:
void apply_fadeout();
/// Main processing function
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask);
/// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands)
virtual void send_configures(send_configure_iface *sci) { return mod_matrix_impl::send_configures(sci); }
virtual char *configure(const char *key, const char *value) { return mod_matrix_impl::configure(key, value); }
};
};

View File

@@ -28,12 +28,12 @@
namespace calf_plugins {
/// Base class for universal stereo level metering
struct stereo_in_out_metering_base
template<class Meter>
struct in_out_metering_base
{
dsp::vumeter vumeter_in, vumeter_out;
stereo_in_out_metering_base()
typedef Meter meter;
meter vumeter_in, vumeter_out;
in_out_metering_base()
{
reset();
}
@@ -42,11 +42,16 @@ struct stereo_in_out_metering_base
vumeter_in.reset();
vumeter_out.reset();
}
void set_sample_rate(double sample_rate)
{
vumeter_in.set_falloff(0.f, sample_rate);
vumeter_out.copy_falloff(vumeter_in);
}
};
/// Universal stereo level metering for a specific plugin
/// Universal single stereo level metering for a specific plugin
template<class Metadata>
class stereo_in_out_metering: public stereo_in_out_metering_base
class stereo_in_out_metering: public in_out_metering_base<dsp::vumeter>
{
public:
inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples)
@@ -79,6 +84,49 @@ public:
}
};
/// Universal dual level metering for a specific plugin
template<class Metadata>
class dual_in_out_metering: public in_out_metering_base<dsp::dual_vumeter>
{
public:
inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples)
{
if (params[Metadata::param_meter_inL] || params[Metadata::param_clip_inL] || params[Metadata::param_meter_inR] || params[Metadata::param_clip_inR]) {
if (inputs)
vumeter_in.update_stereo(inputs[0] ? inputs[0] + offset : NULL, inputs[1] ? inputs[1] + offset : NULL, nsamples);
else
vumeter_in.update_zeros(nsamples);
if (params[Metadata::param_meter_inL])
*params[Metadata::param_meter_inL] = vumeter_in.left.level;
if (params[Metadata::param_meter_inR])
*params[Metadata::param_meter_inR] = vumeter_in.right.level;
if (params[Metadata::param_clip_inL])
*params[Metadata::param_clip_inL] = vumeter_in.left.clip > 0 ? 1.f : 0.f;
if (params[Metadata::param_clip_inR])
*params[Metadata::param_clip_inR] = vumeter_in.right.clip > 0 ? 1.f : 0.f;
}
if (params[Metadata::param_meter_outL] || params[Metadata::param_clip_outL] || params[Metadata::param_meter_outR] || params[Metadata::param_clip_outR]) {
if (outputs)
vumeter_out.update_stereo(outputs[0] ? outputs[0] + offset : NULL, outputs[1] ? outputs[1] + offset : NULL, nsamples);
else
vumeter_out.update_zeros(nsamples);
if (params[Metadata::param_meter_outL])
*params[Metadata::param_meter_outL] = vumeter_out.left.level;
if (params[Metadata::param_meter_outR])
*params[Metadata::param_meter_outR] = vumeter_out.right.level;
if (params[Metadata::param_clip_outL])
*params[Metadata::param_clip_outL] = vumeter_out.left.clip > 0 ? 1.f : 0.f;
if (params[Metadata::param_clip_outR])
*params[Metadata::param_clip_outR] = vumeter_out.right.clip > 0 ? 1.f : 0.f;
}
}
void bypassed(float *const *params, unsigned int nsamples)
{
reset();
process(params, NULL, NULL, 0, nsamples);
}
};
};
#endif

View File

@@ -21,6 +21,8 @@
#ifndef __CALF_VUMETER_H
#define __CALF_VUMETER_H
#include <math.h>
namespace dsp {
/// Peak meter class
@@ -48,6 +50,24 @@ struct vumeter
clip = 0;
}
/// Set falloff so that the meter falls 20dB in time_20dB seconds, assuming sample rate of sample_rate
/// @arg time_20dB time for the meter to move by 20dB (default 300ms if <= 0)
void set_falloff(double time_20dB, double sample_rate)
{
if (time_20dB <= 0)
time_20dB = 0.3;
// 20dB = 10x +/- --> 0.1 = pow(falloff, sample_rate * time_20dB) = exp(sample_rate * ln(falloff))
// ln(0.1) = sample_rate * ln(falloff)
falloff = pow(0.1, 1 / (sample_rate * time_20dB));
clip_falloff = falloff;
}
/// Copy falloff from another object
void copy_falloff(const vumeter &src)
{
falloff = src.falloff;
clip_falloff = src.clip_falloff;
}
/// Update peak meter based on input signal
inline void update(const float *src, unsigned int len)
{
@@ -90,6 +110,38 @@ struct vumeter
}
};
struct dual_vumeter
{
vumeter left, right;
inline void update_stereo(const float *src1, const float *src2, unsigned int len)
{
left.update_stereo(src1, NULL, len);
right.update_stereo(NULL, src2, len);
}
inline void update_zeros(unsigned int len)
{
left.update_zeros(len);
right.update_zeros(len);
}
inline void reset()
{
left.reset();
right.reset();
}
inline void set_falloff(double time_20dB, double sample_rate)
{
left.set_falloff(time_20dB, sample_rate);
right.copy_falloff(left);
}
inline void copy_falloff(const dual_vumeter &src)
{
left.copy_falloff(src.left);
right.copy_falloff(src.right);
}
};
};
#endif

View File

@@ -0,0 +1,164 @@
#ifndef __CALF_WAVETABLE_H
#define __CALF_WAVETABLE_H
#include <assert.h>
#include "biquad.h"
#include "onepole.h"
#include "audio_fx.h"
#include "inertia.h"
#include "osc.h"
#include "synth.h"
#include "envelope.h"
#include "modmatrix.h"
namespace calf_plugins {
#define WAVETABLE_WAVE_BITS 8
class wavetable_audio_module;
struct wavetable_oscillator: public dsp::simple_oscillator
{
enum { SIZE = 1 << 8, MASK = SIZE - 1, SCALE = 1 << (32 - 8) };
int16_t (*tables)[256];
inline float get(uint16_t slice)
{
float fracslice = (slice & 255) * (1.0 / 256.0);
slice = slice >> 8;
int16_t *waveform = tables[slice];
int16_t *waveform2 = tables[slice + 1];
float value1 = 0.f, value2 = 0.f;
uint32_t cphase = phase, cphasedelta = phasedelta >> 3;
for (int j = 0; j < 8; j++)
{
uint32_t wpos = cphase >> (32 - 8);
uint32_t wpos2 = (wpos + 1) & MASK;
float frac = (cphase & (SCALE - 1)) * (1.0f / SCALE);
value1 += dsp::lerp((float)waveform[wpos], (float)waveform[wpos2], frac);
value2 += dsp::lerp((float)waveform2[wpos], (float)waveform2[wpos2], frac);
cphase += cphasedelta;
}
phase += phasedelta;
return dsp::lerp(value1, value2, fracslice) * (1.0 / 8.0) * (1.0 / 32768.0);;
}
};
class wavetable_voice: public dsp::voice
{
public:
enum { Channels = 2, BlockSize = 64, EnvCount = 3, OscCount = 2 };
float output_buffer[BlockSize][Channels];
protected:
int note;
wavetable_audio_module *parent;
float **params;
dsp::decay amp;
wavetable_oscillator oscs[OscCount];
dsp::adsr envs[EnvCount];
/// Current MIDI velocity
float velocity;
/// Current calculated mod matrix outputs
float moddest[wavetable_metadata::moddest_count];
/// Last oscillator shift (wavetable index) of each oscillator
float last_oscshift[OscCount];
/// Last oscillator amplitude of each oscillator
float last_oscamp[OscCount];
/// Current osc amplitude
float cur_oscamp[OscCount];
public:
wavetable_voice();
void set_params_ptr(wavetable_audio_module *_parent, int _srate);
void reset();
void note_on(int note, int vel);
void note_off(int /* vel */);
void channel_pressure(int value);
void steal();
void render_block();
virtual int get_current_note() {
return note;
}
virtual bool get_active() {
// printf("note %d getactive %d use_percussion %d pamp active %d\n", note, amp.get_active(), use_percussion(), pamp.get_active());
return (note != -1) && (amp.get_active()) && !envs[0].stopped();
}
inline void calc_derived_dests() {
float cv = dsp::clip<float>(0.5f + moddest[wavetable_metadata::moddest_oscmix], 0.f, 1.f);
cur_oscamp[0] = (cv) * *params[wavetable_metadata::par_o1level];
cur_oscamp[1] = (1 - cv) * *params[wavetable_metadata::par_o2level];
}
};
class wavetable_audio_module: public audio_module<wavetable_metadata>, public dsp::basic_synth, public mod_matrix_impl
{
public:
using dsp::basic_synth::note_on;
using dsp::basic_synth::note_off;
using dsp::basic_synth::control_change;
using dsp::basic_synth::pitch_bend;
protected:
uint32_t crate;
bool panic_flag;
public:
int16_t tables[wt_count][129][256]; // one dummy level for interpolation
/// Rows of the modulation matrix
dsp::modulation_entry mod_matrix_data[mod_matrix_slots];
/// Smoothed cutoff value
dsp::inertia<dsp::exponential_ramp> inertia_cutoff;
/// Smoothed pitch bend value
dsp::inertia<dsp::exponential_ramp> inertia_pitchbend;
/// Smoothed channel pressure value
dsp::inertia<dsp::linear_ramp> inertia_pressure;
/// Unsmoothed mod wheel value
float modwheel_value;
public:
wavetable_audio_module();
dsp::voice *alloc_voice() {
dsp::block_voice<wavetable_voice> *v = new dsp::block_voice<wavetable_voice>();
v->set_params_ptr(this, sample_rate);
return v;
}
/// process function copied from Organ (will probably need some adjustments as well as implementing the panic flag elsewhere
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
float *o[2] = { outs[0] + offset, outs[1] + offset };
if (panic_flag)
{
control_change(120, 0); // stop all sounds
control_change(121, 0); // reset all controllers
panic_flag = false;
}
float buf[4096][2];
dsp::zero(&buf[0][0], 2 * nsamples);
basic_synth::render_to(buf, nsamples);
float gain = 1.0f;
for (uint32_t i=0; i<nsamples; i++) {
o[0][i] = gain*buf[i][0];
o[1][i] = gain*buf[i][1];
}
return 3;
}
void set_sample_rate(uint32_t sr) {
setup(sr);
crate = sample_rate / wavetable_voice::BlockSize;
inertia_cutoff.ramp.set_length(crate / 30); // 1/30s
inertia_pitchbend.ramp.set_length(crate / 30); // 1/30s
inertia_pressure.ramp.set_length(crate / 30); // 1/30s - XXXKF monosynth needs that too
}
/// Handle MIDI Channel Pressure
void channel_pressure(int value);
/// Handle pitch bend message.
inline void pitch_bend(int value)
{
inertia_pitchbend.set_inertia(pow(2.0, (value * *params[par_pwhlrange]) / (1200.0 * 8192.0)));
}
};
};
#endif

View File

@@ -150,8 +150,6 @@ std::string parameter_properties::to_string(float value) const
}
switch(flags & PF_TYPEMASK)
{
case PF_STRING:
return "N/A";
case PF_INT:
case PF_BOOL:
case PF_ENUM:
@@ -190,15 +188,16 @@ std::string parameter_properties::to_string(float value) const
void calf_plugins::plugin_ctl_iface::clear_preset() {
int param_count = get_metadata_iface()->get_param_count();
for (int i=0; i < param_count; i++)
for (int i = 0; i < param_count; i++)
{
const parameter_properties &pp = *get_metadata_iface()->get_param_props(i);
if ((pp.flags & PF_TYPEMASK) == PF_STRING)
{
configure(pp.short_name, pp.choices ? pp.choices[0] : "");
}
else
set_param_value(i, pp.def_value);
set_param_value(i, pp.def_value);
}
const char *const *vars = get_metadata_iface()->get_configure_vars();
if (vars)
{
for (int i = 0; vars[i]; i++)
configure(vars[i], NULL);
}
}
@@ -215,29 +214,7 @@ const char *calf_plugins::load_gui_xml(const std::string &plugin_id)
}
}
bool calf_plugins::check_for_message_context_ports(const parameter_properties *parameters, int count)
{
for (int i = count - 1; i >= 0; i--)
{
if (parameters[i].flags & PF_PROP_MSGCONTEXT)
return true;
}
return false;
}
bool calf_plugins::check_for_string_ports(const parameter_properties *parameters, int count)
{
for (int i = count - 1; i >= 0; i--)
{
if ((parameters[i].flags & PF_TYPEMASK) == PF_STRING)
return true;
if ((parameters[i].flags & PF_TYPEMASK) < PF_STRING)
return false;
}
return false;
}
bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies)
bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies, float res, float ofs)
{
if (subindex < 0 )
return false;
@@ -270,7 +247,7 @@ bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, s
if (subindex >= 32)
return false;
float gain = 16.0 / (1 << subindex);
pos = dB_grid(gain);
pos = dB_grid(gain, res, ofs);
if (pos < -1)
return false;
if (subindex != 4)
@@ -342,11 +319,67 @@ const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char
}
return NULL;
}
///////////////////////////////////////////////////////////////////////////////////////
std::string table_edit_iface::get_cell(int param, int row, int column) const
bool calf_plugins::parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column)
{
return calf_utils::i2s(row)+":"+calf_utils::i2s(column);
is_rows = false;
row = -1;
column = -1;
if (0 != strncmp(key, prefix, strlen(prefix)))
return false;
key += strlen(prefix);
if (!strcmp(key, "rows"))
{
is_rows = true;
return true;
}
const char *comma = strchr(key, ',');
if (comma)
{
row = atoi(string(key, comma - key).c_str());
column = atoi(comma + 1);
return true;
}
printf("Unknown key %s under prefix %s", key, prefix);
return false;
}
///////////////////////////////////////////////////////////////////////////////////////
const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL };
mod_matrix_metadata::mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names)
: mod_src_names(_src_names)
, mod_dest_names(_dest_names)
, matrix_rows(_rows)
{
table_column_info tci[6] = {
{ "Source", TCT_ENUM, 0, 0, 0, mod_src_names },
{ "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names },
{ "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names },
{ "Amount", TCT_FLOAT, 0, 1, 1, NULL},
{ "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names },
{ NULL }
};
assert(sizeof(table_columns) == sizeof(tci));
memcpy(table_columns, tci, sizeof(table_columns));
}
const table_column_info *mod_matrix_metadata::get_table_columns() const
{
return table_columns;
}
uint32_t mod_matrix_metadata::get_table_rows() const
{
return matrix_rows;
}
///////////////////////////////////////////////////////////////////////////////////////
@@ -453,4 +486,13 @@ calf_plugins::dssi_feedback_sender::~dssi_feedback_sender()
delete client;
}
table_via_configure::table_via_configure()
{
rows = 0;
}
table_via_configure::~table_via_configure()
{
}
#endif

View File

@@ -41,6 +41,7 @@ CALF_PORT_PROPS(flanger) = {
{ 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" },
{ 1, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
{ 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" },
{}
};
CALF_PLUGIN_INFO(flanger) = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "FlangerPlugin" };
@@ -82,6 +83,7 @@ CALF_PORT_PROPS(reverb) = {
{ 0, 0, 50, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "predelay", "Pre Delay" },
{ 300, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "bass_cut", "Bass Cut" },
{ 5000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_cut", "Treble Cut" },
{}
};
CALF_PLUGIN_INFO(reverb) = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ReverbPlugin" };
@@ -129,7 +131,8 @@ CALF_PORT_PROPS(filterclavier) = {
biquad_filter_module::mode_12db_lp,
biquad_filter_module::mode_count - 1,
1, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, filter_choices, "mode", "Mode" },
{ 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"}
{ 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"},
{}
};
CALF_PLUGIN_INFO(filterclavier) = { 0x849f, "Filterclavier", "Calf Filterclavier", "Krzysztof Foltman / Hans Baier", calf_plugins::calf_copyright_info, "FilterclavierPlugin" };
@@ -162,6 +165,7 @@ CALF_PORT_PROPS(vintage_delay) = {
{ 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, vintage_delay_fbmodes, "medium", "Medium" },
{ 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" },
{ 1.0, -1, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "width", "Stereo Width" },
{}
};
CALF_PLUGIN_INFO(vintage_delay) = { 0x8482, "VintageDelay", "Calf Vintage Delay", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "DelayPlugin" };
@@ -183,6 +187,7 @@ CALF_PORT_PROPS(rotary_speaker) = {
{ 0.3, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" },
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_l", "Low rotor" },
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_h", "High rotor" },
{}
};
CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SimulatorPlugin" };
@@ -231,6 +236,7 @@ CALF_PORT_PROPS(compressor) = {
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" },
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" },
{ 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Reduction" },
{}
};
CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
@@ -278,6 +284,7 @@ CALF_PORT_PROPS(sidechaincompressor) = {
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" },
{}
};
CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8517, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
@@ -364,6 +371,7 @@ CALF_PORT_PROPS(multibandcompressor) = {
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output3", "Output 4" },
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute3", "Mute 4" },
{}
};
CALF_PLUGIN_INFO(multibandcompressor) = { 0x8516, "Multibandcompressor", "Calf Multiband Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
@@ -395,6 +403,7 @@ CALF_PORT_PROPS(deesser) = {
{ 4, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" },
{ 1, 0.1, 100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
{}
};
CALF_PLUGIN_INFO(deesser) = { 0x8515, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
@@ -423,6 +432,7 @@ CALF_PORT_PROPS(gate) = {
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_detection_names, "detection", "Detection" },
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_stereo_link_names, "stereo_link", "Stereo Link" },
{ 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating", "Gating" },
{}
};
CALF_PLUGIN_INFO(gate) = { 0x8503, "Gate", "Calf Gate", "Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" };
@@ -471,6 +481,7 @@ CALF_PORT_PROPS(sidechaingate) = {
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" },
{}
};
CALF_PLUGIN_INFO(sidechaingate) = { 0x8504, "Sidechaingate", "Calf Sidechain Gate", "Markus Schmidt / Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" };
@@ -527,6 +538,7 @@ CALF_PORT_PROPS(equalizer5band) = {
EQ_BAND_PARAMS(1, 250)
EQ_BAND_PARAMS(2, 1000)
EQ_BAND_PARAMS(3, 2500)
{}
};
CALF_PLUGIN_INFO(equalizer5band) = { 0x8511, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" };
@@ -546,6 +558,7 @@ CALF_PORT_PROPS(equalizer8band) = {
EQ_BAND_PARAMS(2, 1000)
EQ_BAND_PARAMS(3, 2500)
EQ_BAND_PARAMS(4, 5000)
{}
};
CALF_PLUGIN_INFO(equalizer8band) = { 0x8512, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" };
@@ -567,6 +580,7 @@ CALF_PORT_PROPS(equalizer12band) = {
EQ_BAND_PARAMS(6, 2500)
EQ_BAND_PARAMS(7, 4000)
EQ_BAND_PARAMS(8, 6000)
{}
};
CALF_PLUGIN_INFO(equalizer12band) = { 0x8513, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" };
@@ -586,6 +600,7 @@ CALF_PORT_PROPS(pulsator) = {
{ 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "offset", "Offset L/R" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mono", "Mono-in" },
{ 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" },
{}
};
CALF_PLUGIN_INFO(pulsator) = { 0x8514, "Pulsator", "Calf Pulsator", "Markus Schmidt", calf_plugins::calf_copyright_info, "ModulationPlugin" };
@@ -617,6 +632,7 @@ CALF_PORT_PROPS(saturator) = {
{ 2000, 80, 8000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p_freq", "Tone" },
{ 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p_level", "Amount" },
{ 1, 0.1, 10, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p_q", "Gradient" },
{}
};
CALF_PLUGIN_INFO(saturator) = { 0x8530, "Saturator", "Calf Saturator", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
@@ -641,6 +657,7 @@ CALF_PORT_PROPS(exciter) = {
{ 6000, 2000, 12000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" },
{}
};
CALF_PLUGIN_INFO(exciter) = { 0x8531, "Exciter", "Calf Exciter", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
@@ -665,6 +682,7 @@ CALF_PORT_PROPS(bassenhancer) = {
{ 120, 10, 250, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" },
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" },
{}
};
CALF_PLUGIN_INFO(bassenhancer) = { 0x8532, "BassEnhancer", "Calf Bass Enhancer", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
@@ -756,8 +774,40 @@ CALF_PORT_PROPS(monosynth) = {
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, monosynth_lfotrig_names, "lfo2_trig", "LFO2 Trigger Mode" },
{ 5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lfo2_rate", "LFO1 Rate" },
{ 0.5, 0.1, 5, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "lfo2_delay", "LFO1 Delay" },
{}
};
static const char *monosynth_mod_src_names[] = {
"None",
"Velocity",
"Pressure",
"ModWheel",
"Envelope 1",
"Envelope 2",
"LFO 1",
"LFO 2",
NULL
};
static const char *monosynth_mod_dest_names[] = {
"None",
"Attenuation",
"Osc Mix Ratio (%)",
"Cutoff [ct]",
"Resonance",
"O1: Detune [ct]",
"O2: Detune [ct]",
"O1: PW (%)",
"O2: PW (%)",
"O1: Stretch",
NULL
};
monosynth_metadata::monosynth_metadata()
: mm_metadata(mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names)
{
}
////////////////////////////////////////////////////////////////////////////
CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" };
@@ -950,10 +1000,14 @@ CALF_PORT_PROPS(organ) = {
{ 1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "bass_gain", "Bass Gain" },
{ 12000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_freq", "Treble Freq" },
{ 1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "treble_gain", "Treble Gain" },
{ 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &organ_init_map_curve, "map_curve", "Key mapping curve" },
};
const char *const *organ_metadata::get_configure_vars() const
{
static const char *names[] = {"map_curve", NULL};
return names;
}
////////////////////////////////////////////////////////////////////////////
const char *fluidsynth_init_soundfont = "";
@@ -972,10 +1026,14 @@ CALF_PORT_PROPS(fluidsynth) = {
{ 2, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, fluidsynth_interpolation_names, "interpolation", "Interpolation" },
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Reverb" },
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Chorus" },
{ 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &fluidsynth_init_soundfont, "soundfont", "Soundfont" },
{ 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &fluidsynth_init_presetkeyset, "preset_key_set", "Set Preset" },
};
const char *const *fluidsynth_metadata::get_configure_vars() const
{
static const char *names[] = {"soundfont", "preset_key_set", NULL};
return names;
}
////////////////////////////////////////////////////////////////////////////
const char *wavetable_names[] = {
@@ -1010,7 +1068,29 @@ const char *wavetable_names[] = {
"Multi 2",
};
const char *wavetable_init_soundfont = "";
static const char *wavetable_mod_src_names[] = {
"None",
"Velocity",
"Pressure",
"ModWheel",
"Env 1",
"Env 2",
"Env 3",
NULL
};
static const char *wavetable_mod_dest_names[] = {
"None",
"Attenuation",
"Osc Mix Ratio (%)",
"Cutoff [ct]",
"Resonance",
"O1: Shift (%)",
"O2: Shift (%)",
"O1: Detune [ct]",
"O2: Detune [ct]",
NULL
};
CALF_PORT_NAMES(wavetable) = {
"Out L", "Out R",
@@ -1053,8 +1133,14 @@ CALF_PORT_PROPS(wavetable) = {
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" },
{ 200, 0, 2400, 25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" },
{}
};
wavetable_metadata::wavetable_metadata()
: mm_metadata(mod_matrix_slots, wavetable_mod_src_names, wavetable_mod_dest_names)
{
}
////////////////////////////////////////////////////////////////////////////
calf_plugins::plugin_registry::plugin_registry()

View File

@@ -26,10 +26,18 @@
using namespace std;
using namespace dsp;
using namespace calf_plugins;
using namespace calf_utils;
const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL };
mod_matrix_impl::mod_matrix_impl(dsp::modulation_entry *_matrix, mod_matrix_metadata *_metadata)
: matrix(_matrix)
, metadata(_metadata)
{
matrix_rows = metadata->get_table_rows();
for (unsigned int i = 0; i < matrix_rows; i++)
matrix[i].reset();
}
const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = {
const float mod_matrix_impl::scaling_coeffs[mod_matrix_metadata::map_type_count][3] = {
{ 0, 1, 0 },
{ -1, 2, 0 },
{ -1, 1, 0 },
@@ -40,66 +48,33 @@ const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = {
{ 0, 4, -4 },
};
mod_matrix::mod_matrix(modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names)
: matrix(_matrix)
, matrix_rows(_rows)
, mod_src_names(_src_names)
, mod_dest_names(_dest_names)
{
table_column_info tci[6] = {
{ "Source", TCT_ENUM, 0, 0, 0, mod_src_names },
{ "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names },
{ "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names },
{ "Amount", TCT_FLOAT, 0, 1, 1, NULL},
{ "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names },
{ NULL }
};
assert(sizeof(table_columns) == sizeof(tci));
memcpy(table_columns, tci, sizeof(table_columns));
for (unsigned int i = 0; i < matrix_rows; i++)
matrix[i].reset();
}
const table_column_info *mod_matrix::get_table_columns(int param) const
{
return table_columns;
}
uint32_t mod_matrix::get_table_rows(int param) const
{
return matrix_rows;
}
std::string mod_matrix::get_cell(int param, int row, int column) const
std::string mod_matrix_impl::get_cell(int row, int column) const
{
assert(row >= 0 && row < (int)matrix_rows);
modulation_entry &slot = matrix[row];
const char **arr = metadata->get_table_columns()[column].values;
switch(column) {
case 0: // source 1
return mod_src_names[slot.src1];
return arr[slot.src1];
case 1: // mapping mode
return mod_mapping_names[slot.mapping];
return arr[slot.mapping];
case 2: // source 2
return mod_src_names[slot.src2];
return arr[slot.src2];
case 3: // amount
return calf_utils::f2s(slot.amount);
case 4: // destination
return mod_dest_names[slot.dest];
return arr[slot.dest];
default:
assert(0);
return "";
}
}
void mod_matrix::set_cell(int param, int row, int column, const std::string &src, std::string &error) const
void mod_matrix_impl::set_cell(int row, int column, const std::string &src, std::string &error)
{
assert(row >= 0 && row < (int)matrix_rows);
modulation_entry &slot = matrix[row];
const char **arr = mod_src_names;
if (column == 1)
arr = mod_mapping_names;
if (column == 4)
arr = mod_dest_names;
const char **arr = metadata->get_table_columns()[column].values;
switch(column) {
case 0:
case 1:
@@ -113,7 +88,7 @@ void mod_matrix::set_cell(int param, int row, int column, const std::string &src
if (column == 0)
slot.src1 = i;
else if (column == 1)
slot.mapping = (mapping_mode)i;
slot.mapping = (mod_matrix_metadata::mapping_mode)i;
else if (column == 2)
slot.src2 = i;
else if (column == 4)
@@ -135,3 +110,33 @@ void mod_matrix::set_cell(int param, int row, int column, const std::string &src
}
}
void mod_matrix_impl::send_configures(send_configure_iface *sci)
{
for (int i = 0; i < (int)matrix_rows; i++)
{
for (int j = 0; j < 5; j++)
{
string key = "mod_matrix:" + i2s(i) + "," + i2s(j);
sci->send_configure(key.c_str(), get_cell(i, j).c_str());
}
}
}
char *mod_matrix_impl::configure(const char *key, const char *value)
{
bool is_rows;
int row, column;
if (!parse_table_key(key, "mod_matrix:", is_rows, row, column))
return NULL;
if (is_rows)
return strdup("Unexpected key");
if (row != -1 && column != -1)
{
string error;
set_cell(row, column, value, error);
if (!error.empty())
return strdup(error.c_str());
}
return NULL;
}

View File

@@ -189,6 +189,7 @@ static inline void delayline_impl(int age, int deltime, float dry_value, const f
// if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
if (age <= deltime) {
out = 0;
del = dry_value;
amt.step();
fb.step();
}
@@ -206,6 +207,7 @@ static inline void delayline2_impl(int age, int deltime, float dry_value, const
{
if (age <= deltime) {
out = 0;
del = dry_value;
amt.step();
fb.step();
}

View File

@@ -389,6 +389,7 @@ void compressor_audio_module::set_sample_rate(uint32_t sr)
{
srate = sr;
compressor.set_sample_rate(srate);
meters.set_sample_rate(srate);
}
uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
@@ -658,6 +659,7 @@ void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr)
{
srate = sr;
compressor.set_sample_rate(srate);
meters.set_sample_rate(srate);
}
uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
@@ -1123,6 +1125,7 @@ void gate_audio_module::set_sample_rate(uint32_t sr)
{
srate = sr;
gate.set_sample_rate(srate);
meters.set_sample_rate(srate);
}
uint32_t gate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
@@ -1390,6 +1393,7 @@ void sidechaingate_audio_module::set_sample_rate(uint32_t sr)
{
srate = sr;
gate.set_sample_rate(srate);
meters.set_sample_rate(srate);
}
uint32_t sidechaingate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)

View File

@@ -26,8 +26,6 @@
using namespace dsp;
using namespace calf_plugins;
#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
/// Saturator Band by Markus Schmidt
///
/// This module is based on Krzysztof's filters and Tom Szilagyi's distortion routine.
@@ -113,6 +111,7 @@ void saturator_audio_module::set_sample_rate(uint32_t sr)
dist[0].set_sample_rate(sr);
if(in_count > 1 && out_count > 1)
dist[1].set_sample_rate(sr);
meters.set_sample_rate(srate);
}
uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
@@ -302,6 +301,7 @@ void exciter_audio_module::set_sample_rate(uint32_t sr)
dist[0].set_sample_rate(sr);
if(in_count > 1 && out_count > 1)
dist[1].set_sample_rate(sr);
meters.set_sample_rate(srate);
}
uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
@@ -488,6 +488,7 @@ void bassenhancer_audio_module::set_sample_rate(uint32_t sr)
dist[0].set_sample_rate(sr);
if(in_count > 1 && out_count > 1)
dist[1].set_sample_rate(sr);
meters.set_sample_rate(srate);
}
uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)

View File

@@ -26,8 +26,6 @@
using namespace dsp;
using namespace calf_plugins;
#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
/// Equalizer 12 Band by Markus Schmidt
///
/// This module is based on Krzysztof's filters. It provides a couple
@@ -40,8 +38,6 @@ equalizerNband_audio_module<BaseClass, has_lphp>::equalizerNband_audio_module()
is_active = false;
srate = 0;
last_generation = 0;
clip_inL = clip_inR = clip_outL = clip_outR = 0.f;
meter_inL = meter_inR = meter_outL = meter_outR = 0.f;
}
template<class BaseClass, bool has_lphp>
@@ -50,6 +46,7 @@ void equalizerNband_audio_module<BaseClass, has_lphp>::activate()
is_active = true;
// set all filters
params_changed();
meters.reset();
}
template<class BaseClass, bool has_lphp>
@@ -170,6 +167,8 @@ template<class BaseClass, bool has_lphp>
uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
bool bypass = *params[AM::param_bypass] > 0.f;
uint32_t orig_offset = offset;
uint32_t orig_numsamples = numsamples;
numsamples += offset;
if(bypass) {
// everything bypassed
@@ -179,19 +178,8 @@ uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offs
++offset;
}
// displays, too
clip_inL = clip_inR = clip_outL = clip_outR = 0.f;
meter_inL = meter_inR = meter_outL = meter_outR = 0.f;
meters.bypassed(params, orig_numsamples);
} else {
clip_inL -= std::min(clip_inL, numsamples);
clip_inR -= std::min(clip_inR, numsamples);
clip_outL -= std::min(clip_outL, numsamples);
clip_outR -= std::min(clip_outR, numsamples);
meter_inL = 0.f;
meter_inR = 0.f;
meter_outL = 0.f;
meter_outR = 0.f;
// process
while(offset < numsamples) {
// cycle through samples
@@ -230,37 +218,11 @@ uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offs
// send to output
outs[0][offset] = outL;
outs[1][offset] = outR;
// clip LED's
if(inL > 1.f) {
clip_inL = srate >> 3;
}
if(inR > 1.f) {
clip_inR = srate >> 3;
}
if(outL > 1.f) {
clip_outL = srate >> 3;
}
if(outR > 1.f) {
clip_outR = srate >> 3;
}
// set up in / out meters
if(inL > meter_inL) {
meter_inL = inL;
}
if(inR > meter_inR) {
meter_inR = inR;
}
if(outL > meter_outL) {
meter_outL = outL;
}
if(outR > meter_outR) {
meter_outR = outR;
}
// next sample
++offset;
} // cycle trough samples
meters.process(params, ins, outs, orig_offset, orig_numsamples);
// clean up
for(int i = 0; i < 3; ++i) {
hp[i][0].sanitize();
@@ -275,15 +237,6 @@ uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offs
pR[i].sanitize();
}
}
// draw meters
SET_IF_CONNECTED(clip_inL)
SET_IF_CONNECTED(clip_inR)
SET_IF_CONNECTED(clip_outL)
SET_IF_CONNECTED(clip_outR)
SET_IF_CONNECTED(meter_inL)
SET_IF_CONNECTED(meter_inR)
SET_IF_CONNECTED(meter_outL)
SET_IF_CONNECTED(meter_outR)
// whatever has to be returned x)
return outputs_mask;
}
@@ -295,7 +248,7 @@ bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int
return false;
if (index == AM::param_p1_freq && !subindex) {
context->set_line_width(1.5);
return ::get_graph(*this, subindex, data, points);
return ::get_graph(*this, subindex, data, points, 32, 0);
}
return false;
}
@@ -306,7 +259,7 @@ bool equalizerNband_audio_module<BaseClass, has_lphp>::get_gridline(int index, i
if (!is_active) {
return false;
} else {
return get_freq_gridline(subindex, pos, vertical, legend, context);
return get_freq_gridline(subindex, pos, vertical, legend, context, true, 32, 0);
}
}

View File

@@ -27,34 +27,8 @@ using namespace std;
float silence[4097];
static const char *monosynth_mod_src_names[] = {
"None",
"Velocity",
"Pressure",
"ModWheel",
"Envelope 1",
"Envelope 2",
"LFO 1",
"LFO 2",
NULL
};
static const char *monosynth_mod_dest_names[] = {
"None",
"Attenuation",
"Osc Mix Ratio (%)",
"Cutoff [ct]",
"Resonance",
"O1: Detune [ct]",
"O2: Detune [ct]",
"O1: PW (%)",
"O2: PW (%)",
"O1: Stretch",
NULL
};
monosynth_audio_module::monosynth_audio_module()
: mod_matrix(mod_matrix_data, mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names)
: mod_matrix_impl(mod_matrix_data, &mm_metadata)
, inertia_cutoff(1)
, inertia_pitchbend(1)
, inertia_pressure(64)
@@ -76,6 +50,7 @@ void monosynth_audio_module::activate() {
stack.clear();
last_pwshift1 = last_pwshift2 = 0;
last_stretch1 = 65536;
queue_note_on_and_off = false;
}
waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
@@ -433,6 +408,12 @@ void monosynth_audio_module::delayed_note_on()
queue_note_on = -1;
float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get_last(), modwheel_value, envelope1.value, envelope2.value, 0.5+0.5*lfo1.last, 0.5+0.5*lfo2.last};
calculate_modmatrix(moddest, moddest_count, modsrc);
if (queue_note_on_and_off)
{
end_note();
queue_note_on_and_off = false;
}
}
void monosynth_audio_module::set_sample_rate(uint32_t sr) {
@@ -629,6 +610,7 @@ void monosynth_audio_module::apply_fadeout()
void monosynth_audio_module::note_on(int note, int vel)
{
queue_note_on = note;
queue_note_on_and_off = false;
last_key = note;
queue_vel = vel / 127.f;
stack.push(note);
@@ -637,29 +619,40 @@ void monosynth_audio_module::note_on(int note, int vel)
void monosynth_audio_module::note_off(int note, int vel)
{
stack.pop(note);
if (note == queue_note_on)
{
queue_note_on_and_off = true;
return;
}
// If releasing the currently played note, try to get another one from note stack.
if (note == last_key) {
if (stack.count())
{
last_key = note = stack.nth(stack.count() - 1);
start_freq = freq;
target_freq = freq = dsp::note_to_hz(note);
porta_time = 0;
set_frequency();
if (!(legato & 1)) {
envelope1.note_on();
envelope2.note_on();
stopping = false;
running = true;
}
return;
}
gate = false;
envelope1.note_off();
envelope2.note_off();
end_note();
}
}
void monosynth_audio_module::end_note()
{
if (stack.count())
{
int note;
last_key = note = stack.nth(stack.count() - 1);
start_freq = freq;
target_freq = freq = dsp::note_to_hz(note);
porta_time = 0;
set_frequency();
if (!(legato & 1)) {
envelope1.note_on();
envelope2.note_on();
stopping = false;
running = true;
}
return;
}
gate = false;
envelope1.note_off();
envelope2.note_off();
}
void monosynth_audio_module::channel_pressure(int value)
{
inertia_pressure.set_inertia(value * (1.0 / 127.0));

View File

@@ -62,7 +62,7 @@ uint32_t organ_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_
}
void organ_audio_module::params_changed() {
for (int i = 0; i < param_count - var_count; i++)
for (int i = 0; i < param_count; i++)
((float *)&par_values)[i] = *params[i];
unsigned int old_poly = polyphony_limit;
@@ -950,6 +950,8 @@ char *organ_audio_module::configure(const char *key, const char *value)
{
if (!strcmp(key, "map_curve"))
{
if (!value)
value = "2\n0 1\n1 1\n";
var_map_curve = value;
stringstream ss(value);
int i = 0;

View File

@@ -58,7 +58,7 @@ ladspa_instance::ladspa_instance(audio_module_iface *_module, ladspa_plugin_meta
float ladspa_instance::get_param_value(int param_no)
{
// XXXKF hack
if (param_no >= ladspa->real_param_count)
if (param_no >= ladspa->param_count)
return 0;
return *params[param_no];
}
@@ -66,7 +66,7 @@ float ladspa_instance::get_param_value(int param_no)
void ladspa_instance::set_param_value(int param_no, float value)
{
// XXXKF hack
if (param_no >= ladspa->real_param_count)
if (param_no >= ladspa->param_count)
return;
*params[param_no] = value;
}
@@ -116,7 +116,7 @@ void ladspa_instance::run_synth(unsigned long SampleCount, snd_seq_event_t *Even
char *ladspa_instance::configure(const char *key, const char *value)
{
#if USE_DSSI
#if USE_DSSI_GUI
if (!strcmp(key, "OSC:FEEDBACK_URI"))
{
const line_graph_iface *lgi = dynamic_cast<const line_graph_iface *>(metadata);
@@ -231,7 +231,7 @@ static void cb_connect(LADSPA_Handle Instance, unsigned long port, LADSPA_Data *
int first_out = mod->ladspa->input_count;
int first_param = first_out + mod->ladspa->output_count;
int ladspa_port_count = first_param + mod->ladspa->real_param_count;
int ladspa_port_count = first_param + mod->ladspa->param_count;
if ((int)port < first_out)
mod->ins[port] = DataLocation;
@@ -292,7 +292,7 @@ static void cb_select_program(LADSPA_Handle Instance, unsigned long Bank, unsign
unsigned int no = (Bank << 7) + Program - 1;
// printf("no = %d presets = %p:%d\n", no, presets, presets->size());
if (no == -1U) {
int rpc = ladspa->real_param_count;
int rpc = ladspa->param_count;
for (int i =0 ; i < rpc; i++)
*mod->params[i] = mod->metadata->get_param_props(i)->def_value;
return;
@@ -328,9 +328,6 @@ void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA
input_count = md->get_input_count();
output_count = md->get_output_count();
param_count = md->get_param_count(); // XXXKF ladspa_instance<Module>::real_param_count();
real_param_count = 0;
while(real_param_count < md->get_param_count() && (metadata->get_param_props(real_param_count)->flags & PF_TYPEMASK) < PF_STRING)
real_param_count++;
const ladspa_plugin_info &plugin_info = md->get_plugin_info();
descriptor.UniqueID = plugin_info.unique_id;
@@ -339,7 +336,7 @@ void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA
descriptor.Maker = plugin_info.maker;
descriptor.Copyright = plugin_info.copyright;
descriptor.Properties = md->is_rt_capable() ? LADSPA_PROPERTY_HARD_RT_CAPABLE : 0;
descriptor.PortCount = input_count + output_count + real_param_count;
descriptor.PortCount = input_count + output_count + param_count;
descriptor.PortNames = new char *[descriptor.PortCount];
descriptor.PortDescriptors = new LADSPA_PortDescriptor[descriptor.PortCount];
descriptor.PortRangeHints = new LADSPA_PortRangeHint[descriptor.PortCount];
@@ -352,7 +349,7 @@ void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA
prh.HintDescriptor = 0;
((const char **)descriptor.PortNames)[i] = md->get_port_names()[i];
}
for (; i < input_count + output_count + real_param_count; i++)
for (; i < input_count + output_count + param_count; i++)
{
LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i];
const parameter_properties &pp = *md->get_param_props(i - input_count - output_count);
@@ -484,7 +481,7 @@ ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set()
// instantiate descriptor templates
template<class Module> LV2_Descriptor calf_plugins::lv2_wrapper<Module>::descriptor;
template<class Module> LV2_Calf_Descriptor calf_plugins::lv2_wrapper<Module>::calf_descriptor;
template<class Module> LV2MessageContext calf_plugins::lv2_wrapper<Module>::message_context;
template<class Module> LV2_Persist calf_plugins::lv2_wrapper<Module>::persist;
extern "C" {

View File

@@ -0,0 +1,552 @@
/* Calf DSP Library
* Example audio modules - wavetable synthesizer
*
* Copyright (C) 2009 Krzysztof Foltman
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <config.h>
#if ENABLE_EXPERIMENTAL
#include <calf/giface.h>
#include <calf/modules_synths.h>
#include <iostream>
using namespace dsp;
using namespace calf_plugins;
wavetable_voice::wavetable_voice()
{
sample_rate = -1;
}
void wavetable_voice::set_params_ptr(wavetable_audio_module *_parent, int _srate)
{
parent = _parent;
params = parent->params;
sample_rate = _srate;
}
void wavetable_voice::reset()
{
note = -1;
}
void wavetable_voice::note_on(int note, int vel)
{
typedef wavetable_metadata md;
this->note = note;
velocity = vel / 127.0;
amp.set(1.0);
for (int i = 0; i < OscCount; i++) {
oscs[i].reset();
oscs[i].set_freq(note_to_hz(note, 0), sample_rate);
last_oscshift[i] = 0;
}
int cr = sample_rate / BlockSize;
for (int i = 0; i < EnvCount; i++) {
envs[i].set(0.01, 0.1, 0.5, 1, cr);
envs[i].note_on();
}
float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value};
parent->calculate_modmatrix(moddest, md::moddest_count, modsrc);
calc_derived_dests();
float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] };
memcpy(last_oscshift, oscshift, sizeof(oscshift));
memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp));
}
void wavetable_voice::note_off(int vel)
{
for (int i = 0; i < EnvCount; i++)
envs[i].note_off();
}
void wavetable_voice::steal()
{
}
void wavetable_voice::render_block()
{
typedef wavetable_metadata md;
const float step = 1.f / BlockSize;
float s = 0.001;
float scl[EnvCount];
int espc = md::par_eg2attack - md::par_eg1attack;
for (int j = 0; j < EnvCount; j++) {
int o = j*espc;
envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize, *params[md::par_eg1fade + o] * s);
scl[j] = dsp::lerp(1.f, velocity, *params[md::par_eg1velscl + o]);;
}
for (int i = 0; i < EnvCount; i++)
envs[i].advance();
float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value};
parent->calculate_modmatrix(moddest, md::moddest_count, modsrc);
calc_derived_dests();
int ospc = md::par_o2level - md::par_o1level;
for (int j = 0; j < OscCount; j++) {
oscs[j].tables = parent->tables[(int)*params[md::par_o1wave + j * ospc]];
oscs[j].set_freq(note_to_hz(note, *params[md::par_o1transpose + j * ospc] * 100+ *params[md::par_o1detune + j * ospc] + moddest[md::moddest_o1detune]), sample_rate);
}
float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] };
float osstep[2] = { (oscshift[0] - last_oscshift[0]) * step, (oscshift[1] - last_oscshift[1]) * step };
float oastep[2] = { (cur_oscamp[0] - last_oscamp[0]) * step, (cur_oscamp[1] - last_oscamp[1]) * step };
for (int i = 0; i < BlockSize; i++) {
float value = 0.f;
for (int j = 0; j < OscCount; j++) {
float o = last_oscshift[j] * 0.01;
value += last_oscamp[j] * oscs[j].get(dsp::clip(fastf2i_drm((o + *params[md::par_o1offset + j * ospc]) * 127.0 * 256), 0, 127 * 256));
last_oscshift[j] += osstep[j];
last_oscamp[j] += oastep[j];
}
output_buffer[i][0] = output_buffer[i][1] = value;
}
if (envs[0].stopped())
released = true;
memcpy(last_oscshift, oscshift, sizeof(oscshift));
memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
static inline float sincl(float x, float clip)
{
if (fabs(x) > clip)
return 0;
return sin(M_PI * x);
}
static inline float blip(float x, float center, float range)
{
if (x < center - range || x > center + range)
return 0;
return 1 - fabs(x - center)/range;
}
static void interpolate_wt(int16_t table[129][256], int step)
{
for (int i = 0; i < 128; i++)
{
if (!(i % step))
continue;
int prev = i - i % step;
int next = prev + step;
for (int j = 0; j < 256; j++)
{
table[i][j] = table[prev][j] + (i - prev) * (table[next][j] - table[prev][j]) / step;
}
}
}
wavetable_audio_module::wavetable_audio_module()
: mod_matrix_impl(mod_matrix_data, &mm_metadata)
, inertia_cutoff(1)
, inertia_pitchbend(1)
, inertia_pressure(64)
{
panic_flag = false;
modwheel_value = 0.;
for (int i = 0; i < 129; i += 8)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
int harm = 1 + 2 * (i / 8);
float ii = i / 128.0;
float rezo1 = sin(harm * ph) * sin(ph);
float rezo2 = sin((harm+1) * ph) * sin(ph * 2);
float rezo3 = sin((harm+3) * ph) * sin(ph * 4);
float rezo = (rezo1 + rezo2 + rezo3) / 3;
float v = (sin (ph) + ii * ii * rezo) / 2;
tables[0][i][j] = 32767 * v;
}
}
interpolate_wt(tables[0], 8);
for (int i = 0; i < 129; i += 4)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
int harm = 1 + (i / 4);
float ii = i / 128.0;
float h = sin(harm * ph);
float rezo1 = h * sin(ph);
float rezo2 = h * sin(ph * 2)/2;
float rezo3 = h * sin(ph * 3)/3;
float rezo4 = h * sin(ph * 4)/4;
float rezo5 = h * sin(ph * 5)/5;
float rezo = (rezo1 + rezo2 + rezo3 + rezo4 + rezo5) / 3;
float v = sin (ph + ii * rezo);
tables[1][i][j] = 32767 * v;
}
}
interpolate_wt(tables[1], 4);
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = (i & ~3) / 128.0;
float ii2 = ((i & ~3) + 4) / 128.0;
float peak = (32 * ii);
float rezo1 = sin(floor(peak) * ph);
float rezo2 = sin(floor(peak + 1) * ph);
float widener = (0.5 + 0.3 * sin(ph) + 0.2 * sin (3 * ph));
float v1 = 0.5 * sin (ph) + 0.5 * ii * ii * rezo1 * widener;
float v2 = 0.5 * sin (ph) + 0.5 * ii2 * ii2 * rezo2 * widener;
tables[wavetable_metadata::wt_rezo][i][j] = 32767 * lerp(v1, v2, (i & 3) / 4.0);
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 6 * ii * ii * sin(6 * ph)) + ii * ii * ii * ii * sin(ph + 11 * ii * ii * ii * ii * sin(11 * ph))) / 4;
tables[wavetable_metadata::wt_metal][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * sin(5 * ph - 5 * ii * ii * ii * ii * sin(11 * ph))) / 3;
tables[wavetable_metadata::wt_bell][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
//float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 3 * ii * ii * sin(3 * ph)) + ii * ii * ii * sin(ph + 5 * ii * ii * ii * sin(5 * ph))) / 4;
float v = (sin(ph) + sin(ph - 3 * sin(ii * 5 - 2) * sin(ph)) + sin(ii * 4 - 1.3) * sin(5 * ph + 3 * ii * ii * sin(6 * ph))) / 3;
tables[wavetable_metadata::wt_blah][i][j] = 32767 * v;
}
}
for (int i = 0; i < 256; i++)
{
tables[wavetable_metadata::wt_pluck][128][i] = (i < 128) ? 32000 * fabs(sin(i / 32.0 * M_PI) * sin(i / 13.0 * M_PI) * sin(i / 19.0 * M_PI)) : 0;
}
for (int i = 127; i >= 0; i--)
{
int16_t *parent = tables[wavetable_metadata::wt_pluck][i + 1];
float damp = 0.05;
for (int j = 0; j < 256; j++)
{
tables[wavetable_metadata::wt_pluck][i][j] = (1 - 2*damp) * parent[j] + damp * parent[(j+1)&255] + damp * parent[(j+2)&255];// + 0.1 * parent[(j-1)&255]+ 0.1 * parent[(j-2)&255];
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j / 128.0 - 1.0;
float ii = i / 128.0;
float v = sincl(ph * (1 + 15 * ii), 1);
tables[wavetable_metadata::wt_stretch][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j / 128.0 - 1.0;
float ii = i / 128.0;
float v = sincl(ph * (1 + 15 * ii), 4) * sincl(j / 256.0, 1);
tables[wavetable_metadata::wt_stretch2][i][j] = 32000 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j / 128.0 - 1.0;
float ii = i / 128.0;
float w = sincl(ph * (1 + 15 * ii), 4);
float v = pow(w, 9) * sincl(j / 256.0, 1);
tables[wavetable_metadata::wt_hardsync][i][j] = 32000 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j / 128.0 - 1.0;
float ii = i / 128.0;
float w = sincl(ph * (1 + 31 * ii), 3);
float v = pow(w, 5) * sincl(j / 256.0, 1);
tables[wavetable_metadata::wt_hardsync2][i][j] = 32000 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j / 128.0 - 1.0;
float ii = i / 128.0;
float w = sincl(ph * ph * (1 + 15 * ii), 2);
float v = pow(w, 4) * sincl(j / 256.0, 1);
tables[wavetable_metadata::wt_softsync][i][j] = 32000 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(7 * ph - 2 * ii * ii * ii * ii * sin(13 * ph))) / 3;
tables[wavetable_metadata::wt_bell2][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(9 * ph - ii * ii * sin(11 * ph))) / 3;
tables[wavetable_metadata::wt_bell3][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float v = (sin(ph + ii * sin(ph - 3 * ii * sin(ph) + ii * ii * ii * sin(5 * ph - ii * ii * sin(7 * ph)))));
tables[wavetable_metadata::wt_tine][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float v = (sin(ph + ii * sin(ph - 2 * ii * sin(ph) + ii * ii * ii * sin(3 * ph - ii * ii * sin(4 * ph)))));
tables[wavetable_metadata::wt_tine2][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ph2 = j / 128.0 - 1;
float ii = i / 128.0;
float w = sincl(ph2 * (1 + 7 * ii * ii), 4) * pow(sincl(j / 256.0, 1), 2);
float v = sin(ph + ii * sin(ph - 2 * ii * w));
tables[wavetable_metadata::wt_clav][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ph2 = j / 128.0 - 1;
float ii = i / 128.0;
float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * sincl(j / 256.0, 1);
float v = sin(ph + ii * sin(3 * ph - 2 * ii * w));
tables[wavetable_metadata::wt_clav2][i][j] = 32767 * v;
}
}
/*
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ph2 = j / 128.0 - 1;
float ii = i / 128.0;
float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * pow(sincl(j / 256.0, 1), 1);
float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w));
tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v;
}
}
*/
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float ii2 = ii;
float w = pow(sincl(j / 256.0, 1), 1);
float v = sin(ph + ii2 * ii2 * ii2 * sin(3 * ph - ii2 * ii2 * ii2 * w * sin(ph + sin(3 * ph) + ii * sin(11 * ph) + ii * ii * sin(25 * ph))));
tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float ii2 = dsp::clip(ii - 0.5, 0.0, 1.0);
float w = pow(sincl(j / 256.0, 1), 1);
float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w * sin(ph + sin(3 * ph + ii2 * sin(13 * ph)))));
tables[wavetable_metadata::wt_gtr2][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0);
//float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1);
float w = pow(sincl(j / 256.0, 1), 1);
float v = sin(ph + ii * sin(3 * ph - ii * w * sin(ph + sin(3 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph))))));
tables[wavetable_metadata::wt_gtr3][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0);
//float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1);
float w = pow(sincl(j / 256.0, 1), 1);
float v = sin(ph + ii * sin(3 * ph - ii * w * sin(2 * ph + sin(5 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph))))));
tables[wavetable_metadata::wt_gtr4][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0);
//float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1);
float w = pow(sincl(j / 256.0, 1), 3);
float v = sin(ph + (ii + 0.05) * sin(3 * ph - 2 * ii * w * sin(5 * ph + sin(7 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(11 * ph))))));
tables[wavetable_metadata::wt_gtr5][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float w = pow(sincl(2 * (j / 256.0), 2), 3);
float v = sin(ph + (ii + 0.05) * sin(7 * ph - 2 * ii * w * sin(11 * ph)));
tables[wavetable_metadata::wt_reed][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0);
float ii3 = dsp::clip((ii - 0.5)/0.5, 0.0, 1.0);
float v = sin(ph + (ii + 0.05) * sin(ii * sin(2 * ph) - 2 * ii2 * sin(2 * ph + ii2 * sin(3 * ph)) + 3 * ii3 * sin(3 * ph)));
tables[wavetable_metadata::wt_reed2][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float mod = 0;
for (int k = 0; k < 13; k++)
{
mod += blip(i, k * 10, 30) * sin (ph * (5 + 3 * k) + ii * cos(ph * (2 + 2 * k)));
}
float v = sin(ph + ii * mod);
tables[wavetable_metadata::wt_silver][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float mod = 0;
for (int k = 0; k < 16; k++)
{
mod += 2 * blip(i, k * 8, k * 4 + 10) * cos (ph * (k + 1));
}
float v = sin(ph + ii * mod);
tables[wavetable_metadata::wt_brass][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i++)
{
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float ii = i / 128.0;
float mod = 0;
for (int k = 0; k < 16; k++)
{
mod += 2 * blip(i, k * 8, 16) * cos (ph * (2 * k + 1));
}
float v = (sin(ph + ii * mod) + ii * sin(2 * ph + ii * mod)) / 2;
tables[wavetable_metadata::wt_multi][i][j] = 32767 * v;
}
}
for (int i = 0; i < 129; i ++)
{
float h = 1 + i / 16.0;
for (int j = 0; j < 256; j++)
{
float ph = j * 2 * M_PI / 256;
float v = sin(ph), tv = 1;
for (int k = 1; k < 24; k++) {
float amp = blip(i, k * 6, 20) / k;
v += amp * sin((k + 1) * ph + h * sin(ph));
tv += amp;
}
tables[wavetable_metadata::wt_multi2][i][j] = 32767 * v / tv;
}
}
}
void wavetable_audio_module::channel_pressure(int value)
{
inertia_pressure.set_inertia(value * (1.0 / 127.0));
}
#endif

View File

@@ -1,8 +1,8 @@
IF(LMMS_SUPPORT_VST)
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(../vst_base)
LINK_DIRECTORIES(../vst_base)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vst_base)
LINK_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../vst_base)
LINK_LIBRARIES(vstbase)
BUILD_PLUGIN(vestige vestige.cpp vestige.h MOCFILES vestige.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png)

View File

@@ -17,7 +17,7 @@ ENDIF(LMMS_BUILD_WIN32)
IF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE)
IF(LMMS_HOST_X86_64)
SET(EXTRA_FLAGS -m32 -Wb,--as-cmd='as --32',--ld-cmd='ld -melf_i386' -L/usr/lib32)
SET(EXTRA_FLAGS -m32)
ENDIF(LMMS_HOST_X86_64)
ADD_CUSTOM_COMMAND(
SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/remote_vst_plugin.cpp

View File

@@ -1,8 +1,8 @@
IF(LMMS_SUPPORT_VST)
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(../vst_base)
LINK_DIRECTORIES(../vst_base)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vst_base)
LINK_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../vst_base)
LINK_LIBRARIES(vstbase)
BUILD_PLUGIN(vsteffect VstEffect.cpp VstEffectControls.cpp VstEffectControlDialog.cpp VstSubPluginFeatures.cpp VstEffect.h VstEffectControls.h VstEffectControlDialog.h VstSubPluginFeatures.h MOCFILES VstEffectControls.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png)

View File

@@ -105,7 +105,7 @@ ADD_DEPENDENCIES(RemoteZynAddSubFx ZynAddSubFxCore)
# link system libraries when on win32
IF(LMMS_BUILD_WIN32)
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx ${QT_LIBRARIES} -lole32 -luuid -lcomctl32 -lgdi32)
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx ${QT_LIBRARIES} -lole32 -luuid -lcomctl32 -lgdi32 -lws2_32)
ENDIF(LMMS_BUILD_WIN32)
# FLTK needs X

View File

@@ -123,7 +123,7 @@ void engine::destroy()
deleteHelper( &s_fxMixerView );
presetPreviewPlayHandle::cleanup();
InstrumentTrackView::cleanupWindowPool();
InstrumentTrackView::cleanupWindowCache();
s_song->clearProject();

View File

@@ -328,7 +328,7 @@ void MidiWinMM::openDevices()
MIDIOUTCAPS c;
midiOutGetDevCaps( i, &c, sizeof( c ) );
HMIDIOUT hm = 0;
MMRESULT res = midiOutOpen( &hm, i, NULL, NULL, CALLBACK_NULL );
MMRESULT res = midiOutOpen( &hm, i, 0, 0, CALLBACK_NULL );
if( res == MMSYSERR_NOERROR )
{
m_outputDevices[hm] = qstrdup( c.szPname );

View File

@@ -2,7 +2,7 @@
* AutomationEditor.cpp - implementation of AutomationEditor which is used for
* actual setting of dynamic values
*
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -517,37 +517,35 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
case Qt::Key_Up:
m_topBottomScroll->setValue(
m_topBottomScroll->value() - 1 );
_ke->accept();
break;
case Qt::Key_Down:
m_topBottomScroll->setValue(
m_topBottomScroll->value() + 1 );
_ke->accept();
break;
case Qt::Key_Left:
{
if( ( m_timeLine->pos() -= 16 ) < 0 )
{
m_timeLine->pos().setTicks( 0 );
}
m_timeLine->updatePosition();
_ke->accept();
break;
}
case Qt::Key_Right:
{
m_timeLine->pos() += 16;
m_timeLine->updatePosition();
_ke->accept();
break;
}
case Qt::Key_C:
if( _ke->modifiers() & Qt::ControlModifier )
{
copySelectedValues();
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -555,10 +553,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ControlModifier )
{
cutSelectedValues();
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -566,10 +561,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ControlModifier )
{
pasteValues();
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -579,10 +571,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
m_selectButton->setChecked( TRUE );
selectAll();
update();
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -590,10 +579,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ShiftModifier )
{
m_drawButton->setChecked( TRUE );
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -601,10 +587,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ShiftModifier )
{
m_eraseButton->setChecked( TRUE );
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -612,10 +595,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ShiftModifier )
{
m_selectButton->setChecked( TRUE );
}
else
{
_ke->ignore();
_ke->accept();
}
break;
@@ -623,15 +603,13 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ShiftModifier )
{
m_moveButton->setChecked( TRUE );
}
else
{
_ke->ignore();
_ke->accept();
}
break;
case Qt::Key_Delete:
deleteSelectedValues();
_ke->accept();
break;
case Qt::Key_Space:
@@ -643,15 +621,16 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke )
{
play();
}
_ke->accept();
break;
case Qt::Key_Home:
m_timeLine->pos().setTicks( 0 );
m_timeLine->updatePosition();
_ke->accept();
break;
default:
_ke->ignore();
break;
}
}

View File

@@ -3,7 +3,7 @@
/*
* main_window.cpp - implementation of LMMS-main-window
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -46,6 +46,8 @@
#include "embed.h"
#include "engine.h"
#include "FxMixerView.h"
#include "InstrumentTrack.h"
#include "PianoView.h"
#include "about_dialog.h"
#include "ControllerRackView.h"
#include "file_browser.h"
@@ -928,7 +930,18 @@ void MainWindow::keyPressEvent( QKeyEvent * _ke )
case Qt::Key_Shift: m_keyMods.m_shift = TRUE; break;
case Qt::Key_Alt: m_keyMods.m_alt = TRUE; break;
default:
QMainWindow::keyPressEvent( _ke );
{
InstrumentTrackWindow * w =
InstrumentTrackView::topLevelInstrumentTrackWindow();
if( w )
{
w->pianoView()->keyPressEvent( _ke );
}
if( !_ke->isAccepted() )
{
QMainWindow::keyPressEvent( _ke );
}
}
}
}
@@ -943,7 +956,15 @@ void MainWindow::keyReleaseEvent( QKeyEvent * _ke )
case Qt::Key_Shift: m_keyMods.m_shift = FALSE; break;
case Qt::Key_Alt: m_keyMods.m_alt = FALSE; break;
default:
QMainWindow::keyReleaseEvent( _ke );
if( InstrumentTrackView::topLevelInstrumentTrackWindow() )
{
InstrumentTrackView::topLevelInstrumentTrackWindow()->
pianoView()->keyReleaseEvent( _ke );
}
if( !_ke->isAccepted() )
{
QMainWindow::keyReleaseEvent( _ke );
}
}
}

View File

@@ -2,7 +2,7 @@
* Piano.cpp - implementation of piano-widget used in instrument-track-window
* for testing + according model class
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -644,6 +644,7 @@ void PianoView::keyPressEvent( QKeyEvent * _ke )
if( m_piano != NULL )
{
m_piano->handleKeyPress( key_num );
_ke->accept();
update();
}
}
@@ -671,6 +672,7 @@ void PianoView::keyReleaseEvent( QKeyEvent * _ke )
if( m_piano != NULL )
{
m_piano->handleKeyRelease( key_num );
_ke->accept();
update();
}
}

View File

@@ -2,7 +2,7 @@
* piano_roll.cpp - implementation of piano-roll which is used for actual
* writing of melodies
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -900,6 +900,7 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
{
m_pattern->instrumentTrack()->
getPiano()->handleKeyPress( key_num );
_ke->accept();
}
}
@@ -930,7 +931,9 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
Qt::AltModifier );
}
}
_ke->accept();
break;
case Qt::Key_Down:
if( _ke->modifiers() & Qt::ControlModifier
&& m_action == ActionNone )
@@ -956,10 +959,10 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
Qt::AltModifier );
}
}
_ke->accept();
break;
case Qt::Key_Left:
{
if( _ke->modifiers() & Qt::ControlModifier &&
m_action == ActionNone )
{
@@ -997,10 +1000,10 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
}
}
_ke->accept();
break;
}
case Qt::Key_Right:
{
if( _ke->modifiers() & Qt::ControlModifier
&& m_action == ActionNone)
{
@@ -1035,103 +1038,78 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
}
}
_ke->accept();
break;
}
case Qt::Key_C:
if( _ke->modifiers() & Qt::ControlModifier )
{
_ke->accept();
copySelectedNotes();
}
else
{
_ke->ignore();
}
break;
case Qt::Key_X:
if( _ke->modifiers() & Qt::ControlModifier )
{
_ke->accept();
cutSelectedNotes();
}
else
{
_ke->ignore();
}
break;
case Qt::Key_V:
if( _ke->modifiers() & Qt::ControlModifier )
{
_ke->accept();
pasteNotes();
}
else
{
_ke->ignore();
}
break;
case Qt::Key_A:
if( _ke->modifiers() & Qt::ControlModifier )
{
_ke->accept();
m_selectButton->setChecked( true );
selectAll();
update();
}
else
{
_ke->ignore();
}
break;
case Qt::Key_D:
if( _ke->modifiers() & Qt::ShiftModifier )
{
_ke->accept();
m_drawButton->setChecked( true );
}
else
{
_ke->ignore();
}
break;
case Qt::Key_E:
if( _ke->modifiers() & Qt::ShiftModifier )
{
_ke->accept();
m_eraseButton->setChecked( true );
}
else
{
_ke->ignore();
}
break;
case Qt::Key_S:
if( _ke->modifiers() & Qt::ShiftModifier )
{
_ke->accept();
m_selectButton->setChecked( true );
}
else
{
_ke->ignore();
}
break;
case Qt::Key_T:
if( _ke->modifiers() & Qt::ShiftModifier )
{
_ke->accept();
m_detuneButton->setChecked( true );
}
else
{
_ke->ignore();
}
break;
case Qt::Key_Delete:
deleteSelectedNotes();
_ke->accept();
break;
case Qt::Key_Space:
@@ -1143,11 +1121,13 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
{
play();
}
_ke->accept();
break;
case Qt::Key_Home:
m_timeLine->pos().setTicks( 0 );
m_timeLine->updatePosition();
_ke->accept();
break;
case Qt::Key_0:
@@ -1167,11 +1147,13 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() &
( Qt::ControlModifier | Qt::KeypadModifier ) )
{
m_noteLenModel.setValue( len );
m_noteLenModel.setValue( len );
_ke->accept();
}
else if( _ke->modifiers() & Qt::AltModifier )
{
m_quantizeModel.setValue( len );
m_quantizeModel.setValue( len );
_ke->accept();
}
break;
}
@@ -1181,9 +1163,9 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke )
m_editMode = ModeSelect;
QApplication::changeOverrideCursor( Qt::ArrowCursor );
update();
_ke->accept();
break;
default:
_ke->ignore();
break;
}
}
@@ -1202,6 +1184,7 @@ void pianoRoll::keyReleaseEvent( QKeyEvent * _ke )
{
m_pattern->instrumentTrack()->
getPiano()->handleKeyRelease( key_num );
_ke->accept();
}
}
switch( _ke->key() )
@@ -1213,7 +1196,6 @@ void pianoRoll::keyReleaseEvent( QKeyEvent * _ke )
update();
break;
}
_ke->ignore();
}

View File

@@ -1,7 +1,7 @@
/*
* setup_dialog.cpp - dialog for setting up LMMS
*
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -111,7 +111,9 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
m_disableChActInd( configManager::inst()->value( "ui",
"disablechannelactivityindicators" ).toInt() ),
m_manualChPiano( configManager::inst()->value( "ui",
"manualchannelpiano" ).toInt() )
"manualchannelpiano" ).toInt() ),
m_oneInstrumentTrackWindow( configManager::inst()->value( "ui",
"oneinstrumenttrackwindow" ).toInt() )
{
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
setWindowTitle( tr( "Setup LMMS" ) );
@@ -180,7 +182,7 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
tabWidget * misc_tw = new tabWidget( tr( "MISC" ), general );
misc_tw->setFixedHeight( 120 );
misc_tw->setFixedHeight( 138 );
ledCheckBox * enable_tooltips = new ledCheckBox(
tr( "Enable tooltips" ),
@@ -216,10 +218,18 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
connect( mmpz, SIGNAL( toggled( bool ) ),
this, SLOT( toggleMMPZ( bool ) ) );
ledCheckBox * oneitw = new ledCheckBox(
tr( "One instrument track window mode" ),
misc_tw );
oneitw->move( 10, 90 );
oneitw->setChecked( m_oneInstrumentTrackWindow );
connect( oneitw, SIGNAL( toggled( bool ) ),
this, SLOT( toggleOneInstrumentTrackWindow( bool ) ) );
ledCheckBox * hqaudio = new ledCheckBox(
tr( "HQ-mode for output audio-device" ),
misc_tw );
hqaudio->move( 10, 90 );
hqaudio->move( 10, 108 );
hqaudio->setChecked( m_hqAudioDev );
connect( hqaudio, SIGNAL( toggled( bool ) ),
this, SLOT( toggleHQAudioDev( bool ) ) );
@@ -729,6 +739,8 @@ void setupDialog::accept()
QString::number( m_disableChActInd ) );
configManager::inst()->setValue( "ui", "manualchannelpiano",
QString::number( m_manualChPiano ) );
configManager::inst()->setValue( "ui", "oneinstrumenttrackwindow",
QString::number( m_oneInstrumentTrackWindow ) );
configManager::inst()->setWorkingDir( m_workingDir );
configManager::inst()->setVSTDir( m_vstDir );
@@ -885,6 +897,15 @@ void setupDialog::toggleManualChPiano( bool _enabled )
void setupDialog::toggleOneInstrumentTrackWindow( bool _enabled )
{
m_oneInstrumentTrackWindow = _enabled;
}
void setupDialog::openWorkingDir()
{
QString new_dir = QFileDialog::getExistingDirectory( this,

View File

@@ -859,7 +859,7 @@ Instrument * InstrumentTrack::loadInstrument( const QString & _plugin_name )
// #### ITV:
QQueue<InstrumentTrackWindow *> InstrumentTrackView::s_windows;
QQueue<InstrumentTrackWindow *> InstrumentTrackView::s_windowCache;
@@ -970,6 +970,24 @@ InstrumentTrackView::~InstrumentTrackView()
InstrumentTrackWindow * InstrumentTrackView::topLevelInstrumentTrackWindow()
{
InstrumentTrackWindow * w = NULL;
foreach( QMdiSubWindow * sw,
engine::mainWindow()->workspace()->subWindowList(
QMdiArea::ActivationHistoryOrder ) )
{
if( sw->isVisible() && sw->widget()->inherits( "InstrumentTrackWindow" ) )
{
w = qobject_cast<InstrumentTrackWindow *>( sw->widget() );
}
}
return w;
}
// TODO: Add windows to free list on freeInstrumentTrackWindow.
// But, don't NULL m_window or disconnect signals. This will allow windows
// that are being show/hidden frequently to stay connected.
@@ -978,15 +996,19 @@ void InstrumentTrackView::freeInstrumentTrackWindow()
if( m_window != NULL )
{
m_lastPos = m_window->parentWidget()->pos();
if( s_windows.count() < INSTRUMENT_WINDOW_CACHE_SIZE )
if( configManager::inst()->value( "ui",
"oneinstrumenttrackwindow" ).toInt() ||
s_windowCache.count() < INSTRUMENT_WINDOW_CACHE_SIZE )
{
model()->setHook( NULL );
m_window->setInstrumentTrackView( NULL );
m_window->parentWidget()->hide();
m_window->setModel(
engine::dummyTrackContainer()->
dummyInstrumentTrack() );
m_window->updateInstrumentView();
s_windows.enqueue( m_window );
s_windowCache << m_window;
}
else
{
@@ -1000,11 +1022,11 @@ void InstrumentTrackView::freeInstrumentTrackWindow()
void InstrumentTrackView::cleanupWindowPool()
void InstrumentTrackView::cleanupWindowCache()
{
while( s_windows.count() )
while( !s_windowCache.isEmpty() )
{
delete s_windows.dequeue();
delete s_windowCache.dequeue();
}
}
@@ -1016,16 +1038,21 @@ InstrumentTrackWindow * InstrumentTrackView::getInstrumentTrackWindow()
if( m_window != NULL )
{
}
else if( !s_windows.isEmpty() )
else if( !s_windowCache.isEmpty() )
{
m_window = s_windows.dequeue();
m_window = s_windowCache.dequeue();
m_window->setInstrumentTrackView( this );
m_window->setModel( model() );
m_window->updateInstrumentView();
model()->setHook( m_window );
if( m_lastPos.x() > 0 || m_lastPos.y() > 0 )
if( configManager::inst()->
value( "ui", "oneinstrumenttrackwindow" ).toInt() )
{
s_windowCache << m_window;
}
else if( m_lastPos.x() > 0 || m_lastPos.y() > 0 )
{
m_window->parentWidget()->move( m_lastPos );
}
@@ -1033,6 +1060,12 @@ InstrumentTrackWindow * InstrumentTrackView::getInstrumentTrackWindow()
else
{
m_window = new InstrumentTrackWindow( this );
if( configManager::inst()->
value( "ui", "oneinstrumenttrackwindow" ).toInt() )
{
// first time, an InstrumentTrackWindow is opened
s_windowCache << m_window;
}
}
return m_window;
@@ -1247,7 +1280,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
m_tabWidget->addTab( m_midiView, tr( "MIDI" ), 4 );
// setup piano-widget
m_pianoView= new PianoView( this );
m_pianoView = new PianoView( this );
m_pianoView->setFixedSize( INSTRUMENT_WIDTH, PIANO_HEIGHT );
vlayout->addWidget( m_generalSettingsWidget );
@@ -1278,7 +1311,10 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
InstrumentTrackWindow::~InstrumentTrackWindow()
{
InstrumentTrackView::s_windowCache.removeAll( this );
delete m_instrumentView;
if( engine::mainWindow()->workspace() )
{
parentWidget()->hide();
@@ -1289,6 +1325,18 @@ InstrumentTrackWindow::~InstrumentTrackWindow()
void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView * _tv )
{
if( m_itv && _tv )
{
m_itv->m_tlb->setChecked( false );
}
m_itv = _tv;
}
void InstrumentTrackWindow::modelChanged()
{
m_track = castModel<InstrumentTrack>();

View File

@@ -28,6 +28,7 @@
#include <QtGui/QMenu>
#include <QtGui/QLayout>
#include <QtGui/QMdiArea>
#include <QtGui/QMdiSubWindow>
#include <QtGui/QPainter>
#include <QtGui/QPushButton>
@@ -525,8 +526,7 @@ sampleTrackView::sampleTrackView( sampleTrack * _t, trackContainerView * _tcv )
m_effectRack = new EffectRackView( _t->audioPort()->effects() );
m_effectRack->setFixedSize( 240, 242 );
engine::mainWindow()->workspace()->addSubWindow( m_effectRack );
m_effWindow = m_effectRack->parentWidget();
m_effWindow = engine::mainWindow()->workspace()->addSubWindow( m_effectRack );
m_effWindow->setAttribute( Qt::WA_DeleteOnClose, false );
m_effWindow->layout()->setSizeConstraint( QLayout::SetFixedSize );
m_effWindow->setWindowTitle( _t->name() );
@@ -550,6 +550,7 @@ void sampleTrackView::showEffects()
{
if( m_effWindow->isHidden() )
{
m_effectRack->show();
m_effWindow->show();
m_effWindow->raise();
}