From 6f7190f600d03f707813ce0c074e8fabb1dc8695 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jun 2019 19:19:19 -0600 Subject: [PATCH 01/12] Add the Microwave synthesizer and all LMMS changes it requires. --- data/themes/classic/lcd_microwave.png | Bin 0 -> 653 bytes data/themes/default/lcd_microwave.png | Bin 0 -> 653 bytes include/Graph.h | 3 +- include/Knob.h | 37 +- include/SampleBuffer.h | 4 +- plugins/CMakeLists.txt | 1 + plugins/Microwave/CMakeLists.txt | 6 + plugins/Microwave/Microwave.cpp | 6105 +++++++++++++++++ plugins/Microwave/Microwave.h | 1138 +++ plugins/Microwave/MicrowaveLCD.png | Bin 0 -> 653 bytes plugins/Microwave/arrowdown.png | Bin 0 -> 463 bytes plugins/Microwave/arrowup.png | Bin 0 -> 456 bytes plugins/Microwave/confirm_button_active.png | Bin 0 -> 867 bytes plugins/Microwave/confirm_button_inactive.png | Bin 0 -> 923 bytes plugins/Microwave/desaw_button.png | Bin 0 -> 879 bytes plugins/Microwave/desaw_button_active.png | Bin 0 -> 901 bytes plugins/Microwave/exp.png | Bin 0 -> 539 bytes plugins/Microwave/fileload.png | Bin 0 -> 228 bytes plugins/Microwave/filterBoxes.png | Bin 0 -> 13855 bytes plugins/Microwave/filterForeground.png | Bin 0 -> 2684 bytes plugins/Microwave/filter_allpass.png | Bin 0 -> 189 bytes plugins/Microwave/filter_bandpass.png | Bin 0 -> 359 bytes plugins/Microwave/filter_highpass.png | Bin 0 -> 310 bytes plugins/Microwave/filter_highshelf.png | Bin 0 -> 275 bytes plugins/Microwave/filter_lowpass.png | Bin 0 -> 314 bytes plugins/Microwave/filter_lowshelf.png | Bin 0 -> 275 bytes plugins/Microwave/filter_moog.png | Bin 0 -> 289 bytes plugins/Microwave/filter_notch.png | Bin 0 -> 351 bytes plugins/Microwave/filter_peak.png | Bin 0 -> 330 bytes plugins/Microwave/i1_button.png | Bin 0 -> 246 bytes plugins/Microwave/i2_button.png | Bin 0 -> 268 bytes plugins/Microwave/letter_a.png | Bin 0 -> 534 bytes plugins/Microwave/letter_b.png | Bin 0 -> 458 bytes plugins/Microwave/letter_c.png | Bin 0 -> 471 bytes plugins/Microwave/letter_d.png | Bin 0 -> 458 bytes plugins/Microwave/letter_e.png | Bin 0 -> 197 bytes plugins/Microwave/letter_f.png | Bin 0 -> 211 bytes plugins/Microwave/letter_g.png | Bin 0 -> 523 bytes plugins/Microwave/letter_h.png | Bin 0 -> 210 bytes plugins/Microwave/letter_i.png | Bin 0 -> 192 bytes plugins/Microwave/letter_j.png | Bin 0 -> 268 bytes plugins/Microwave/letter_k.png | Bin 0 -> 461 bytes plugins/Microwave/letter_l.png | Bin 0 -> 194 bytes plugins/Microwave/letter_m.png | Bin 0 -> 471 bytes plugins/Microwave/letter_n.png | Bin 0 -> 410 bytes plugins/Microwave/letter_o.png | Bin 0 -> 598 bytes plugins/Microwave/letter_p.png | Bin 0 -> 349 bytes plugins/Microwave/letter_q.png | Bin 0 -> 609 bytes plugins/Microwave/letter_r.png | Bin 0 -> 460 bytes plugins/Microwave/letter_s.png | Bin 0 -> 514 bytes plugins/Microwave/letter_t.png | Bin 0 -> 194 bytes plugins/Microwave/letter_u.png | Bin 0 -> 363 bytes plugins/Microwave/letter_v.png | Bin 0 -> 544 bytes plugins/Microwave/letter_w.png | Bin 0 -> 613 bytes plugins/Microwave/letter_x.png | Bin 0 -> 643 bytes plugins/Microwave/letter_y.png | Bin 0 -> 444 bytes plugins/Microwave/letter_z.png | Bin 0 -> 450 bytes plugins/Microwave/letters.png | Bin 0 -> 9102 bytes plugins/Microwave/logo.png | Bin 0 -> 1686 bytes plugins/Microwave/manual_active.png | Bin 0 -> 1078 bytes plugins/Microwave/manual_inactive.png | Bin 0 -> 1042 bytes plugins/Microwave/matrixBoxes.png | Bin 0 -> 7751 bytes plugins/Microwave/matrixForeground.png | Bin 0 -> 2684 bytes plugins/Microwave/moog.png | Bin 0 -> 498 bytes plugins/Microwave/noise.png | Bin 0 -> 711 bytes plugins/Microwave/noisewave.png | Bin 0 -> 512 bytes plugins/Microwave/noisewave_active.png | Bin 0 -> 589 bytes plugins/Microwave/none.png | Bin 0 -> 208 bytes plugins/Microwave/normalize_button.png | Bin 0 -> 959 bytes plugins/Microwave/normalize_button_active.png | Bin 0 -> 982 bytes plugins/Microwave/number_0.png | Bin 0 -> 523 bytes plugins/Microwave/number_1.png | Bin 0 -> 258 bytes plugins/Microwave/number_2.png | Bin 0 -> 463 bytes plugins/Microwave/number_3.png | Bin 0 -> 519 bytes plugins/Microwave/number_4.png | Bin 0 -> 389 bytes plugins/Microwave/number_5.png | Bin 0 -> 424 bytes plugins/Microwave/number_6.png | Bin 0 -> 589 bytes plugins/Microwave/number_7.png | Bin 0 -> 402 bytes plugins/Microwave/number_8.png | Bin 0 -> 613 bytes plugins/Microwave/number_9.png | Bin 0 -> 594 bytes plugins/Microwave/ramp.png | Bin 0 -> 443 bytes plugins/Microwave/rand.png | Bin 0 -> 554 bytes .../remove_dc_offset_button_disabled.png | Bin 0 -> 1336 bytes .../remove_dc_offset_button_enabled.png | Bin 0 -> 1329 bytes plugins/Microwave/saw.png | Bin 0 -> 489 bytes plugins/Microwave/sawwave.png | Bin 0 -> 420 bytes plugins/Microwave/sawwave_active.png | Bin 0 -> 464 bytes plugins/Microwave/sin.png | Bin 0 -> 596 bytes plugins/Microwave/sinabs.png | Bin 0 -> 530 bytes plugins/Microwave/sinwave.png | Bin 0 -> 400 bytes plugins/Microwave/sinwave_active.png | Bin 0 -> 460 bytes plugins/Microwave/smoothwave.png | Bin 0 -> 390 bytes plugins/Microwave/smoothwave_active.png | Bin 0 -> 429 bytes plugins/Microwave/sqr.png | Bin 0 -> 345 bytes plugins/Microwave/sqrsoft.png | Bin 0 -> 453 bytes plugins/Microwave/sqrwave.png | Bin 0 -> 342 bytes plugins/Microwave/sqrwave_active.png | Bin 0 -> 372 bytes plugins/Microwave/tab1.png | Bin 0 -> 272 bytes plugins/Microwave/tab1_active.png | Bin 0 -> 361 bytes plugins/Microwave/tab1_artwork.png | Bin 0 -> 6192 bytes plugins/Microwave/tab1_artwork_flipped.png | Bin 0 -> 6593 bytes plugins/Microwave/tab1_highlighted.png | Bin 0 -> 332 bytes plugins/Microwave/tab2.png | Bin 0 -> 399 bytes plugins/Microwave/tab2_active.png | Bin 0 -> 444 bytes plugins/Microwave/tab2_artwork.png | Bin 0 -> 24519 bytes plugins/Microwave/tab2_artwork_flipped.png | Bin 0 -> 7538 bytes plugins/Microwave/tab2_highlighted.png | Bin 0 -> 394 bytes plugins/Microwave/tab3.png | Bin 0 -> 388 bytes plugins/Microwave/tab3_active.png | Bin 0 -> 512 bytes plugins/Microwave/tab3_artwork.png | Bin 0 -> 5787 bytes plugins/Microwave/tab3_highlighted.png | Bin 0 -> 418 bytes plugins/Microwave/tab4.png | Bin 0 -> 464 bytes plugins/Microwave/tab4_active.png | Bin 0 -> 412 bytes plugins/Microwave/tab4_artwork.png | Bin 0 -> 2674 bytes plugins/Microwave/tab4_highlighted.png | Bin 0 -> 437 bytes plugins/Microwave/tab5.png | Bin 0 -> 361 bytes plugins/Microwave/tab5_active.png | Bin 0 -> 316 bytes plugins/Microwave/tab5_artwork.png | Bin 0 -> 2659 bytes plugins/Microwave/tab5_highlighted.png | Bin 0 -> 416 bytes plugins/Microwave/tab6.png | Bin 0 -> 513 bytes plugins/Microwave/tab6_active.png | Bin 0 -> 306 bytes plugins/Microwave/tab6_artwork.png | Bin 0 -> 5710 bytes plugins/Microwave/tab6_highlighted.png | Bin 0 -> 443 bytes plugins/Microwave/tab7_artwork.png | Bin 0 -> 3352 bytes plugins/Microwave/tri.png | Bin 0 -> 566 bytes plugins/Microwave/triwave.png | Bin 0 -> 438 bytes plugins/Microwave/triwave_active.png | Bin 0 -> 530 bytes plugins/Microwave/wavegraph.png | Bin 0 -> 4049 bytes plugins/Microwave/wavegraphdisabled.png | Bin 0 -> 3090 bytes plugins/Microwave/xbtn.png | Bin 0 -> 228 bytes src/gui/widgets/Graph.cpp | 42 + src/gui/widgets/Knob.cpp | 77 +- src/gui/widgets/LcdSpinBox.cpp | 2 +- 133 files changed, 7388 insertions(+), 27 deletions(-) create mode 100644 data/themes/classic/lcd_microwave.png create mode 100644 data/themes/default/lcd_microwave.png create mode 100644 plugins/Microwave/CMakeLists.txt create mode 100644 plugins/Microwave/Microwave.cpp create mode 100644 plugins/Microwave/Microwave.h create mode 100644 plugins/Microwave/MicrowaveLCD.png create mode 100644 plugins/Microwave/arrowdown.png create mode 100644 plugins/Microwave/arrowup.png create mode 100644 plugins/Microwave/confirm_button_active.png create mode 100644 plugins/Microwave/confirm_button_inactive.png create mode 100644 plugins/Microwave/desaw_button.png create mode 100644 plugins/Microwave/desaw_button_active.png create mode 100644 plugins/Microwave/exp.png create mode 100644 plugins/Microwave/fileload.png create mode 100644 plugins/Microwave/filterBoxes.png create mode 100644 plugins/Microwave/filterForeground.png create mode 100644 plugins/Microwave/filter_allpass.png create mode 100644 plugins/Microwave/filter_bandpass.png create mode 100644 plugins/Microwave/filter_highpass.png create mode 100644 plugins/Microwave/filter_highshelf.png create mode 100644 plugins/Microwave/filter_lowpass.png create mode 100644 plugins/Microwave/filter_lowshelf.png create mode 100644 plugins/Microwave/filter_moog.png create mode 100644 plugins/Microwave/filter_notch.png create mode 100644 plugins/Microwave/filter_peak.png create mode 100644 plugins/Microwave/i1_button.png create mode 100644 plugins/Microwave/i2_button.png create mode 100644 plugins/Microwave/letter_a.png create mode 100644 plugins/Microwave/letter_b.png create mode 100644 plugins/Microwave/letter_c.png create mode 100644 plugins/Microwave/letter_d.png create mode 100644 plugins/Microwave/letter_e.png create mode 100644 plugins/Microwave/letter_f.png create mode 100644 plugins/Microwave/letter_g.png create mode 100644 plugins/Microwave/letter_h.png create mode 100644 plugins/Microwave/letter_i.png create mode 100644 plugins/Microwave/letter_j.png create mode 100644 plugins/Microwave/letter_k.png create mode 100644 plugins/Microwave/letter_l.png create mode 100644 plugins/Microwave/letter_m.png create mode 100644 plugins/Microwave/letter_n.png create mode 100644 plugins/Microwave/letter_o.png create mode 100644 plugins/Microwave/letter_p.png create mode 100644 plugins/Microwave/letter_q.png create mode 100644 plugins/Microwave/letter_r.png create mode 100644 plugins/Microwave/letter_s.png create mode 100644 plugins/Microwave/letter_t.png create mode 100644 plugins/Microwave/letter_u.png create mode 100644 plugins/Microwave/letter_v.png create mode 100644 plugins/Microwave/letter_w.png create mode 100644 plugins/Microwave/letter_x.png create mode 100644 plugins/Microwave/letter_y.png create mode 100644 plugins/Microwave/letter_z.png create mode 100644 plugins/Microwave/letters.png create mode 100644 plugins/Microwave/logo.png create mode 100644 plugins/Microwave/manual_active.png create mode 100644 plugins/Microwave/manual_inactive.png create mode 100644 plugins/Microwave/matrixBoxes.png create mode 100644 plugins/Microwave/matrixForeground.png create mode 100644 plugins/Microwave/moog.png create mode 100644 plugins/Microwave/noise.png create mode 100644 plugins/Microwave/noisewave.png create mode 100644 plugins/Microwave/noisewave_active.png create mode 100644 plugins/Microwave/none.png create mode 100644 plugins/Microwave/normalize_button.png create mode 100644 plugins/Microwave/normalize_button_active.png create mode 100644 plugins/Microwave/number_0.png create mode 100644 plugins/Microwave/number_1.png create mode 100644 plugins/Microwave/number_2.png create mode 100644 plugins/Microwave/number_3.png create mode 100644 plugins/Microwave/number_4.png create mode 100644 plugins/Microwave/number_5.png create mode 100644 plugins/Microwave/number_6.png create mode 100644 plugins/Microwave/number_7.png create mode 100644 plugins/Microwave/number_8.png create mode 100644 plugins/Microwave/number_9.png create mode 100644 plugins/Microwave/ramp.png create mode 100644 plugins/Microwave/rand.png create mode 100644 plugins/Microwave/remove_dc_offset_button_disabled.png create mode 100644 plugins/Microwave/remove_dc_offset_button_enabled.png create mode 100644 plugins/Microwave/saw.png create mode 100644 plugins/Microwave/sawwave.png create mode 100644 plugins/Microwave/sawwave_active.png create mode 100644 plugins/Microwave/sin.png create mode 100644 plugins/Microwave/sinabs.png create mode 100644 plugins/Microwave/sinwave.png create mode 100644 plugins/Microwave/sinwave_active.png create mode 100644 plugins/Microwave/smoothwave.png create mode 100644 plugins/Microwave/smoothwave_active.png create mode 100644 plugins/Microwave/sqr.png create mode 100644 plugins/Microwave/sqrsoft.png create mode 100644 plugins/Microwave/sqrwave.png create mode 100644 plugins/Microwave/sqrwave_active.png create mode 100644 plugins/Microwave/tab1.png create mode 100644 plugins/Microwave/tab1_active.png create mode 100644 plugins/Microwave/tab1_artwork.png create mode 100644 plugins/Microwave/tab1_artwork_flipped.png create mode 100644 plugins/Microwave/tab1_highlighted.png create mode 100644 plugins/Microwave/tab2.png create mode 100644 plugins/Microwave/tab2_active.png create mode 100644 plugins/Microwave/tab2_artwork.png create mode 100644 plugins/Microwave/tab2_artwork_flipped.png create mode 100644 plugins/Microwave/tab2_highlighted.png create mode 100644 plugins/Microwave/tab3.png create mode 100644 plugins/Microwave/tab3_active.png create mode 100644 plugins/Microwave/tab3_artwork.png create mode 100644 plugins/Microwave/tab3_highlighted.png create mode 100644 plugins/Microwave/tab4.png create mode 100644 plugins/Microwave/tab4_active.png create mode 100644 plugins/Microwave/tab4_artwork.png create mode 100644 plugins/Microwave/tab4_highlighted.png create mode 100644 plugins/Microwave/tab5.png create mode 100644 plugins/Microwave/tab5_active.png create mode 100644 plugins/Microwave/tab5_artwork.png create mode 100644 plugins/Microwave/tab5_highlighted.png create mode 100644 plugins/Microwave/tab6.png create mode 100644 plugins/Microwave/tab6_active.png create mode 100644 plugins/Microwave/tab6_artwork.png create mode 100644 plugins/Microwave/tab6_highlighted.png create mode 100644 plugins/Microwave/tab7_artwork.png create mode 100644 plugins/Microwave/tri.png create mode 100644 plugins/Microwave/triwave.png create mode 100644 plugins/Microwave/triwave_active.png create mode 100644 plugins/Microwave/wavegraph.png create mode 100644 plugins/Microwave/wavegraphdisabled.png create mode 100644 plugins/Microwave/xbtn.png diff --git a/data/themes/classic/lcd_microwave.png b/data/themes/classic/lcd_microwave.png new file mode 100644 index 0000000000000000000000000000000000000000..84b77d3503b49dbbd6b80c6c4d7df8eb417a2ea2 GIT binary patch literal 653 zcmeAS@N?(olHy`uVBq!ia0vp^{Xne7!3HG%7M$1$q}Y|gW!U_%O?XxI14-? ziy0WWg+Q3`(%rg0Ktc8rPhVH|M?5kjMl3r+`%W`3FiCm3IEGZ*dOPcE)*%Ox*7f#B zIXN1gIIb+c5V~!v|3jtqkD8wd#_TG67+o^8Ra;Ser2)s$h6x>_yNxoupRJ#K!Vjc-mYcu`*Z8dkJs7%)i8duVK~ct0Yo&YtjZVT zUg%*Kw`}UsbD<)d+2w^b#l6#ChMa8f`X*FcUZ`_r-J*_5PlKxEa(68v17 zRcdwg`SZ)2Mdw~Ve(U>R%wcNa-c>KE`L{E?Td23l>cBkq1(ggApBYT}e{cuh4YM)n zJ*nkC+1F-=qr>^ho^K6rZdrG>a>XpMI5y^pZ49%3st?rPG%&uueBSe^U3|B7pU%-1 zP1zTZ9HruA8?i?E3mwe{TKJ z-H^lhrV?l>(0Yf@4a+WHOWZBmmGU?>D)P-8_0CP-W-K$mUeN3S^5UepzD%tv?|gW!U_%O?XxI14-? ziy0WWg+Q3`(%rg0Ktc8rPhVH|M?5kjMl3r+`%W`3FiCm3IEGZ*dOPcE)*%Ox*7f#B zIXN1gIIb+c5V~!v|3jtqkD8wd#_TG67+o^8Ra;Ser2)s$h6x>_yNxoupRJ#K!Vjc-mYcu`*Z8dkJs7%)i8duVK~ct0Yo&YtjZVT zUg%*Kw`}UsbD<)d+2w^b#l6#ChMa8f`X*FcUZ`_r-J*_5PlKxEa(68v17 zRcdwg`SZ)2Mdw~Ve(U>R%wcNa-c>KE`L{E?Td23l>cBkq1(ggApBYT}e{cuh4YM)n zJ*nkC+1F-=qr>^ho^K6rZdrG>a>XpMI5y^pZ49%3st?rPG%&uueBSe^U3|B7pU%-1 zP1zTZ9HruA8?i?E3mwe{TKJ z-H^lhrV?l>(0Yf@4a+WHOWZBmmGU?>D)P-8_0CP-W-K$mUeN3S^5UepzD%tv?maxValue() - model()->minValue() ) / 100.0f; + } + + bool m_updateColor; + private slots: virtual void enterValue(); void friendlyUpdate(); void toggleScale(); private: - QString displayValue() const; - virtual void doConnections(); QLineF calculateLine( const QPointF & _mid, float _radius, @@ -154,31 +170,19 @@ private slots: void drawKnob( QPainter * _p ); void setPosition( const QPoint & _p ); bool updateAngle(); + bool updateColor(); int angleFromValue( float value, float minValue, float maxValue, float totalAngle ) const { return static_cast( ( value - 0.5 * ( minValue + maxValue ) ) / ( maxValue - minValue ) * m_totalAngle ) % 360; } - inline float pageSize() const - { - return ( model()->maxValue() - model()->minValue() ) / 100.0f; - } - - - static TextFloat * s_textFloat; - QString m_label; QPixmap * m_knobPixmap; BoolModel m_volumeKnob; FloatModel m_volumeRatio; - QPoint m_mouseOffset; - QPoint m_origMousePos; - float m_leftOver; - bool m_buttonPressed; - float m_totalAngle; int m_angle; QImage m_cache; @@ -189,6 +193,7 @@ private slots: float m_outerRadius; float m_lineWidth; QColor m_outerColor; + QColor m_innerColor; QColor m_lineColor; //!< unused yet QColor m_arcColor; //!< unused yet diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 26dda70a9fe..c3e6e184441 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -228,7 +228,7 @@ class LMMS_EXPORT SampleBuffer : public QObject, public sharedObject // protect calls from the GUI to this function with dataReadLock() and // dataUnlock(), out of loops for efficiency - inline sample_t userWaveSample( const float _sample ) const + inline sample_t userWaveSample( const float _sample, const int channel = 0 ) const { f_cnt_t frames = m_frames; sampleFrame * data = m_data; @@ -238,7 +238,7 @@ class LMMS_EXPORT SampleBuffer : public QObject, public sharedObject { f1 += frames; } - return linearInterpolate( data[f1][0], data[ (f1 + 1) % frames ][0], fraction( frame ) ); + return linearInterpolate( data[f1][channel], data[ (f1 + 1) % frames ][channel], fraction( frame ) ); } void dataReadLock() diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 4f139f8b32b..ef59ef7a24f 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -57,6 +57,7 @@ IF("${PLUGIN_LIST}" STREQUAL "") ladspa_browser LadspaEffect lb302 + Microwave MidiImport MidiExport MultitapEcho diff --git a/plugins/Microwave/CMakeLists.txt b/plugins/Microwave/CMakeLists.txt new file mode 100644 index 00000000000..1908f9aa7d3 --- /dev/null +++ b/plugins/Microwave/CMakeLists.txt @@ -0,0 +1,6 @@ +INCLUDE(BuildPlugin) + +LINK_DIRECTORIES(${SAMPLERATE_LIBRARY_DIRS}) +LINK_LIBRARIES(${SAMPLERATE_LIBRARIES}) + +BUILD_PLUGIN(microwave Microwave.cpp Microwave.h MOCFILES Microwave.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png") diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp new file mode 100644 index 00000000000..3b182a30686 --- /dev/null +++ b/plugins/Microwave/Microwave.cpp @@ -0,0 +1,6105 @@ +/* + * Microwave.cpp - morbidly advanced and versatile modular wavetable synthesizer + * + * Copyright (c) 2019 Robert Daniel Black AKA Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + + + + +#include "Microwave.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base64.h" +#include "CaptionMenu.h" +#include "embed.h" +#include "Engine.h" +#include "FileDialog.h" +#include "Graph.h" +#include "gui_templates.h" +#include "GuiApplication.h" +#include "InstrumentTrack.h" +#include "interpolation.h" +#include "Knob.h" +#include "LcdSpinBox.h" +#include "LedCheckbox.h" +#include "lmms_math.h" +#include "MainWindow.h" +#include "Mixer.h" +#include "NotePlayHandle.h" +#include "Oscillator.h" +#include "PixmapButton.h" +#include "plugin_export.h" +#include "SampleBuffer.h" +#include "Song.h" +#include "StringPairDrag.h" +#include "templates.h" +#include "TextFloat.h" +#include "ToolTip.h" + + +extern "C" +{ + +Plugin::Descriptor PLUGIN_EXPORT microwave_plugin_descriptor = +{ + STRINGIFY( PLUGIN_NAME ), + "Microwave", + QT_TRANSLATE_NOOP( "pluginBrowser", + "Versatile modular wavetable synthesizer" ), + "Lost Robot", + 0x0100, + Plugin::Instrument, + new PluginPixmapLoader( "logo" ), + NULL, + NULL +} ; + +} + + +/* + ____ + ,' , `. + ,-+-,.' _ | ,--, + ,-+-. ; , ||,--.'| __ ,-. ,---. .---. + ,--.'|' | ;|| |, ,' ,'/ /| ' ,'\ /. ./| .---. +| | ,', | ':`--'_ ,---. ' | |' | / / | .-'-. ' | ,--.--. /. ./| ,---. +| | / | | ||,' ,'| / \| | ,'. ; ,. : /___/ \: | / \ .-' . ' | / \ +' | : | : |,' | | / / '' : / ' | |: : .-'.. ' ' ..--. .-. |/___/ \: | / / | +; . | ; |--' | | : . ' / | | ' ' | .; :/___/ \: ' \__\/: . .. \ ' .. ' / | +| : | | , ' : |__ ' ; :__; : | | : |. \ ' .\ ," .--.; | \ \ '' ; /| +| : ' |/ | | '.'|' | '.'| , ; \ \ / \ \ ' \ |/ / ,. | \ \ ' | / | +; | |`-' ; : ;| : :---' `----' \ \ |--"; : .' \ \ \ || : | +| ;/ | , / \ \ / \ \ | | , .-./ '---" \ \ / +'---' ---`-' `----' '---" `--`---' `----' + + .----------------. + /_____________ ____\ + ||\ _________ /|+++| + || |: :| |+++| + || |; (◕‿◕) ;| | + | + || |_________| | _ | + ||/___________\|[_]| + "------------------" + + (Do not scroll down if you value your sanity) + +*/ + + + + +Microwave::Microwave( InstrumentTrack * _instrument_track ) : + Instrument( _instrument_track, µwave_plugin_descriptor ), + visvol( 100, 0, 1000, 0.01f, this, tr( "Visualizer Volume" ) ), + loadChnl( 0, 0, 1, 1, this, tr( "Wavetable Loading Channel" ) ), + mainNum(1, 1, 8, this, tr( "Main Oscillator Number" ) ), + subNum(1, 1, 64, this, tr( "Sub Oscillator Number" ) ), + sampNum(1, 1, 8, this, tr( "Sample Number" ) ), + oversample( this, tr("Oversampling") ), + oversampleMode( this, tr("Interpolation") ), + loadMode( this, tr("Wavetable Loading Algorithm") ), + graph( -1.0f, 1.0f, 204, this ), + visualize( false, this ) +{ + + for( int i = 0; i < 8; ++i ) + { + morph[i] = new FloatModel( 0, 0, 254, 0.0001f, this, tr( "Morph" ) ); + range[i] = new FloatModel( 1, 1, 16, 0.0001f, this, tr( "Range" ) ); + sampLen[i] = new FloatModel( 2048, 1, 16384, 1.f, this, tr( "Waveform Sample Length" ) ); + morphMax[i] = new FloatModel( 255, 0, 254, 0.0001f, this, tr( "Morph Max" ) ); + modify[i] = new FloatModel( 0, 0, 2048, 0.0001f, this, tr( "Wavetable Modifier Value" ) ); + modifyMode[i] = new ComboBoxModel( this, tr( "Wavetable Modifier Mode" ) ); + unisonVoices[i] = new FloatModel( 1, 1, 32, 1, this, tr( "Unison Voices" ) ); + unisonDetune[i] = new FloatModel( 0, 0, 2000, 0.0001f, this, tr( "Unison Detune" ) ); + unisonDetune[i]->setScaleLogarithmic( true ); + unisonMorph[i] = new FloatModel( 0, 0, 256, 0.0001f, this, tr( "Unison Morph" ) ); + unisonModify[i] = new FloatModel( 0, 0, 2048, 0.0001f, this, tr( "Unison Modify" ) ); + detune[i] = new FloatModel( 0, -9600, 9600, 0.0001f, this, tr( "Detune" ) ); + phase[i] = new FloatModel( 0, 0, 200, 0.0001f, this, tr( "Phase" ) ); + phaseRand[i] = new FloatModel( 100, 0, 100, 0.0001f, this, tr( "Phase Randomness" ) ); + vol[i] = new FloatModel( 100.f, 0, 200.f, 0.0001f, this, tr( "Volume" ) ); + enabled[i] = new BoolModel( false, this ); + muted[i] = new BoolModel( false, this ); + pan[i] = new FloatModel( 0.f, -100.f, 100.f, 0.0001f, this, tr( "Panning" ) ); + keytracking[i] = new BoolModel( true, this ); + tempo[i] = new FloatModel( 0.f, 0.f, 999.f, 1.f, this, tr( "Tempo" ) ); + interpolate[i] = new BoolModel( true, this ); + setwavemodel( modifyMode[i] ) + + filtInVol[i] = new FloatModel( 100, 0, 200, 0.0001f, this, tr( "Input Volume" ) ); + filtType[i] = new ComboBoxModel( this, tr( "Filter Type" ) ); + filtSlope[i] = new ComboBoxModel( this, tr( "Filter Slope" ) ); + filtCutoff[i] = new FloatModel( 2000, 20, 20000, 0.0001f, this, tr( "Cutoff Frequency" ) ); + filtCutoff[i]->setScaleLogarithmic( true ); + filtReso[i] = new FloatModel( 0.707, 0, 16, 0.0001f, this, tr( "Resonance" ) ); + filtReso[i]->setScaleLogarithmic( true ); + filtGain[i] = new FloatModel( 0, -64, 64, 0.0001f, this, tr( "dbGain" ) ); + filtGain[i]->setScaleLogarithmic( true ); + filtSatu[i] = new FloatModel( 0, 0, 100, 0.0001f, this, tr( "Saturation" ) ); + filtWetDry[i] = new FloatModel( 100, 0, 100, 0.0001f, this, tr( "Wet/Dry" ) ); + filtBal[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Balance/Panning" ) ); + filtOutVol[i] = new FloatModel( 100, 0, 200, 0.0001f, this, tr( "Output Volume" ) ); + filtEnabled[i] = new BoolModel( false, this ); + filtFeedback[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Feedback" ) ); + filtDetune[i] = new FloatModel( 0, -9600, 9600, 0.0001f, this, tr( "Detune" ) ); + filtKeytracking[i] = new BoolModel( true, this ); + filtMuted[i] = new BoolModel( false, this ); + filtertypesmodel( filtType[i] ) + filterslopesmodel( filtSlope[i] ) + + sampleEnabled[i] = new BoolModel( false, this ); + sampleGraphEnabled[i] = new BoolModel( false, this ); + sampleMuted[i] = new BoolModel( false, this ); + sampleKeytracking[i] = new BoolModel( true, this ); + sampleLoop[i] = new BoolModel( true, this ); + + sampleVolume[i] = new FloatModel( 100, 0, 200, 0.0001f, this, tr( "Volume" ) ); + samplePanning[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Panning" ) ); + sampleDetune[i] = new FloatModel( 0, -9600, 9600, 0.0001f, this, tr( "Detune" ) ); + samplePhase[i] = new FloatModel( 0, 0, 200, 0.0001f, this, tr( "Phase" ) ); + samplePhaseRand[i] = new FloatModel( 0, 0, 100, 0.0001f, this, tr( "Phase Randomness" ) ); + sampleStart[i] = new FloatModel( 0, 0, 1, 0.0001f, this, tr( "Start" ) ); + sampleEnd[i] = new FloatModel( 1, 0, 1, 0.0001f, this, tr( "End" ) ); + + keytrackingArr[i] = true; + interpolateArr[i] = true; + } + + for( int i = 0; i < 18; ++i ) + { + macro[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Macro" ) ); + } + + for( int i = 0; i < 64; ++i ) + { + subEnabled[i] = new BoolModel( false, this ); + subVol[i] = new FloatModel( 100.f, 0.f, 200.f, 0.0001f, this, tr( "Volume" ) ); + subPhase[i] = new FloatModel( 0.f, 0.f, 200.f, 0.0001f, this, tr( "Phase" ) ); + subPhaseRand[i] = new FloatModel( 0.f, 0.f, 100.f, 0.0001f, this, tr( "Phase Randomness" ) ); + subDetune[i] = new FloatModel( 0.f, -9600.f, 9600.f, 0.0001f, this, tr( "Detune" ) ); + subMuted[i] = new BoolModel( true, this ); + subKeytrack[i] = new BoolModel( true, this ); + subSampLen[i] = new FloatModel( STOREDSUBWAVELEN, 1.f, STOREDSUBWAVELEN, 1.f, this, tr( "Sample Length" ) ); + subNoise[i] = new BoolModel( false, this ); + subPanning[i] = new FloatModel( 0.f, -100.f, 100.f, 0.0001f, this, tr( "Panning" ) ); + subTempo[i] = new FloatModel( 0.f, 0.f, 999.f, 1.f, this, tr( "Tempo" ) ); + subRateLimit[i] = new FloatModel( 0.f, 0.f, 1.f, 0.000001f, this, tr( "Rate Limit" ) ); + subRateLimit[i]->setScaleLogarithmic( true ); + subUnisonNum[i] = new FloatModel( 1.f, 1.f, 32.f, 1.f, this, tr( "Unison Voice Number" ) ); + subUnisonDetune[i] = new FloatModel( 0.f, 0.f, 2000.f, 0.0001f, this, tr( "Unison Detune" ) ); + subInterpolate[i] = new BoolModel( true, this ); + + modEnabled[i] = new BoolModel( false, this ); + + modOutSec[i] = new ComboBoxModel( this, tr( "Modulation Section" ) ); + modOutSig[i] = new ComboBoxModel( this, tr( "Modulation Signal" ) ); + modOutSecNum[i] = new IntModel( 1, 1, 8, this, tr( "Modulation Section Number" ) ); + modsectionsmodel( modOutSec[i] ) + mainoscsignalsmodel( modOutSig[i] ) + + modIn[i] = new ComboBoxModel( this, tr( "Modulator" ) ); + modInNum[i] = new IntModel( 1, 1, 8, this, tr( "Modulator Number" ) ); + modinmodel( modIn[i] ) + + modInAmnt[i] = new FloatModel( 0, -200, 200, 0.0001f, this, tr( "Modulator Amount" ) ); + modInCurve[i] = new FloatModel( 100, 10.f, 600, 0.0001f, this, tr( "Modulator Curve" ) ); + modInCurve[i]->setScaleLogarithmic( true ); + + modIn2[i] = new ComboBoxModel( this, tr( "Secondary Modulator" ) ); + modInNum2[i] = new IntModel( 1, 1, 8, this, tr( "Secondary Modulator Number" ) ); + modinmodel( modIn2[i] ) + + modInAmnt2[i] = new FloatModel( 0, -200, 200, 0.0001f, this, tr( "Secondary Modulator Amount" ) ); + modInCurve2[i] = new FloatModel( 100, 10.f, 600, 0.0001f, this, tr( "Secondary Modulator Curve" ) ); + modInCurve2[i]->setScaleLogarithmic( true ); + + modCombineType[i] = new ComboBoxModel( this, tr( "Combination Type" ) ); + modcombinetypemodel( modCombineType[i] ) + + modType[i] = new BoolModel( false, this ); + modType2[i] = new BoolModel( false, this ); + } + + oversamplemodel( oversample ) + oversample.setValue( 1 );// 2x oversampling is default + + loadmodemodel( loadMode ) + + oversamplemodemodel( oversampleMode ) + oversampleMode.setValue( 1 );// Sample averaging is default + + connect( &graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( samplesChanged( int, int ) ) ); + + for( int i = 0; i < 8; ++i ) + { + connect( morph[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(1, i); }, Qt::DirectConnection ); + connect( range[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(2, i); }, Qt::DirectConnection ); + connect( modify[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(3, i); }, Qt::DirectConnection ); + connect( modifyMode[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(4, i); }, Qt::DirectConnection ); + connect( vol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(5, i); }, Qt::DirectConnection ); + connect( pan[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(6, i); }, Qt::DirectConnection ); + connect( detune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(7, i); }, Qt::DirectConnection ); + connect( phase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(8, i); }, Qt::DirectConnection ); + connect( phaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(9, i); }, Qt::DirectConnection ); + connect( enabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(10, i); }, Qt::DirectConnection ); + connect( muted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(11, i); }, Qt::DirectConnection ); + connect( sampLen[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(12, i); }, Qt::DirectConnection ); + connect( morphMax[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(13, i); }, Qt::DirectConnection ); + connect( unisonVoices[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(14, i); }, Qt::DirectConnection ); + connect( unisonDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(15, i); }, Qt::DirectConnection ); + connect( unisonMorph[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(16, i); }, Qt::DirectConnection ); + connect( unisonModify[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(17, i); }, Qt::DirectConnection ); + connect( keytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(18, i); }, Qt::DirectConnection ); + connect( tempo[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(19, i); }, Qt::DirectConnection ); + connect( interpolate[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(20, i); }, Qt::DirectConnection ); + + connect( sampleEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(60, i); }, Qt::DirectConnection ); + connect( sampleMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(61, i); }, Qt::DirectConnection ); + connect( sampleKeytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(62, i); }, Qt::DirectConnection ); + connect( sampleGraphEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(63, i); }, Qt::DirectConnection ); + connect( sampleLoop[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(64, i); }, Qt::DirectConnection ); + connect( sampleVolume[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(65, i); }, Qt::DirectConnection ); + connect( samplePanning[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(66, i); }, Qt::DirectConnection ); + connect( sampleDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(67, i); }, Qt::DirectConnection ); + connect( samplePhase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(68, i); }, Qt::DirectConnection ); + connect( samplePhaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(69, i); }, Qt::DirectConnection ); + connect( sampleStart[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(70, i); }, Qt::DirectConnection ); + connect( sampleEnd[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(71, i); }, Qt::DirectConnection ); + + connect( filtCutoff[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(120, i); }, Qt::DirectConnection ); + connect( filtReso[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(121, i); }, Qt::DirectConnection ); + connect( filtGain[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(122, i); }, Qt::DirectConnection ); + connect( filtType[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(123, i); }, Qt::DirectConnection ); + connect( filtSlope[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(124, i); }, Qt::DirectConnection ); + connect( filtInVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(125, i); }, Qt::DirectConnection ); + connect( filtOutVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(126, i); }, Qt::DirectConnection ); + connect( filtWetDry[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(127, i); }, Qt::DirectConnection ); + connect( filtBal[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(128, i); }, Qt::DirectConnection ); + connect( filtSatu[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(129, i); }, Qt::DirectConnection ); + connect( filtFeedback[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(130, i); }, Qt::DirectConnection ); + connect( filtDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(131, i); }, Qt::DirectConnection ); + connect( filtEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(132, i); }, Qt::DirectConnection ); + connect( filtMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(133, i); }, Qt::DirectConnection ); + connect( filtKeytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(134, i); }, Qt::DirectConnection ); + + for( int j = 1; j <= 20; ++j ) + { + valueChanged(j, i); + } + + for( int j = 60; j <= 71; ++j ) + { + valueChanged(j, i); + } + + for( int j = 120; j <= 134; ++j ) + { + valueChanged(j, i); + } + + connect( sampleEnabled[i], &BoolModel::dataChanged, this, [this, i]() { sampleEnabledChanged(i); }, Qt::DirectConnection ); + + connect( enabled[i], &BoolModel::dataChanged, this, [this, i]() { mainEnabledChanged(i); }, Qt::DirectConnection ); + + connect( filtEnabled[i], &BoolModel::dataChanged, this, [this, i]() { filtEnabledChanged(i); }, Qt::DirectConnection ); + + connect( sampLen[i], &FloatModel::dataChanged, this, [this, i]() { sampLenChanged(i); }, Qt::DirectConnection ); + + connect( interpolate[i], &BoolModel::dataChanged, this, [this, i]() { interpolateChanged(i); } ); + + connect( morphMax[i], &FloatModel::dataChanged, this, [this, i]() { morphMaxChanged(i); }, Qt::DirectConnection ); + } + + for( int i = 0; i < 18; ++i ) + { + connect( macro[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(150, i); }, Qt::DirectConnection ); + + valueChanged(150, i); + + macroColors[i][0] = 102; + macroColors[i][1] = 198; + macroColors[i][2] = 199; + } + + for( int i = 0; i < 64; ++i ) + { + connect( subEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(30, i); }, Qt::DirectConnection ); + connect( subMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(31, i); }, Qt::DirectConnection ); + connect( subKeytrack[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(32, i); }, Qt::DirectConnection ); + connect( subNoise[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(33, i); }, Qt::DirectConnection ); + connect( subVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(34, i); }, Qt::DirectConnection ); + connect( subPanning[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(35, i); }, Qt::DirectConnection ); + connect( subDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(36, i); }, Qt::DirectConnection ); + connect( subPhase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(37, i); }, Qt::DirectConnection ); + connect( subPhaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(38, i); }, Qt::DirectConnection ); + connect( subSampLen[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(39, i); }, Qt::DirectConnection ); + connect( subTempo[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(40, i); }, Qt::DirectConnection ); + connect( subRateLimit[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(41, i); }, Qt::DirectConnection ); + connect( subUnisonNum[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(42, i); }, Qt::DirectConnection ); + connect( subUnisonDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(43, i); }, Qt::DirectConnection ); + connect( subInterpolate[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(44, i); }, Qt::DirectConnection ); + + connect( modIn[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(90, i); }, Qt::DirectConnection ); + connect( modInNum[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(91, i); }, Qt::DirectConnection ); + connect( modInAmnt[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(92, i); }, Qt::DirectConnection ); + connect( modInCurve[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(93, i); }, Qt::DirectConnection ); + connect( modIn2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(94, i); }, Qt::DirectConnection ); + connect( modInNum2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(95, i); }, Qt::DirectConnection ); + connect( modInAmnt2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(96, i); }, Qt::DirectConnection ); + connect( modInCurve2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(97, i); }, Qt::DirectConnection ); + connect( modOutSec[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(98, i); }, Qt::DirectConnection ); + connect( modOutSig[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(99, i); }, Qt::DirectConnection ); + connect( modOutSecNum[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(100, i); }, Qt::DirectConnection ); + connect( modEnabled[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(101, i); }, Qt::DirectConnection ); + connect( modCombineType[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(102, i); }, Qt::DirectConnection ); + connect( modType[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(103, i); }, Qt::DirectConnection ); + connect( modType2[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(104, i); }, Qt::DirectConnection ); + + for( int j = 30; j <= 44; ++j ) + { + valueChanged(j, i); + } + + for( int j = 90; j <= 104; ++j ) + { + valueChanged(j, i); + } + + connect( modEnabled[i], &BoolModel::dataChanged, this, [this, i]() { modEnabledChanged(i); }, Qt::DirectConnection ); + + connect( subSampLen[i], &FloatModel::dataChanged, this, [this, i]() { subSampLenChanged(i); } ); + + connect( subEnabled[i], &BoolModel::dataChanged, this, [this, i]() { subEnabledChanged(i); } ); + + connect( subInterpolate[i], &BoolModel::dataChanged, this, [this, i]() { subInterpolateChanged(i); } ); + } + + for( int i = 0; i < 8; ++i ) + { + samples[i][0].push_back(0); + samples[i][1].push_back(0); + } +} + + +Microwave::~Microwave() +{ + for( int i = 0; i < 64; ++i ) + { + /*The following disconnected functions will run if not disconnected upon deletion, + because deleting a ComboBox includes clearing its contents first, + which will fire a dataChanged event. So, we need to disconnect them to + prevent a crash.*/ + disconnect(modIn[i], &ComboBoxModel::dataChanged, 0, 0); + disconnect(modIn2[i], &ComboBoxModel::dataChanged, 0, 0); + disconnect(modOutSec[i], &ComboBoxModel::dataChanged, 0, 0); + } +} + + +PluginView * Microwave::instantiateView( QWidget * _parent ) +{ + return( new MicrowaveView( this, _parent ) ); +} + + +QString Microwave::nodeName() const +{ + return( microwave_plugin_descriptor.name ); +} + + +void Microwave::saveSettings( QDomDocument & _doc, QDomElement & _this ) +{ + + // NOTE: Only enabled oscillators/sections are saved. This is to prevent ridiculously long project save times, as well as total disk space annihilation. + + // Save plugin version + _this.setAttribute( "version", "Microwave Official Release 1" ); + + /* + + VERSION LIST: + + - 0.9: Every version before Microwave Testing Release 4 was mistakenly listed as 0.9. + + - Microwave Testing Release 4 + - Microwave Testing Release 4.1 + - Microwave Testing Release 4.2 + - Microwave Testing Release 5 + - Microwave Testing Release 5.1 + - Microwave Testing Release 5.2 + + - Microwave Official Release 1 + + */ + + visvol.saveSettings( _doc, _this, "visualizervolume" ); + loadMode.saveSettings( _doc, _this, "loadingalgorithm" ); + loadChnl.saveSettings( _doc, _this, "loadingchannel" ); + + oversample.saveSettings( _doc, _this, "oversample" ); + oversampleMode.saveSettings( _doc, _this, "oversamplemode" ); + removeDC.saveSettings( _doc, _this, "removeDC" ); + + QString saveString; + + for( int i = 0; i < 8; ++i ) + { + if( enabled[i]->value() ) + { + if( updateWavetable[i] ) + { + updateWavetable[i] = false; + base64::encode( (const char *)storedwaveforms[i], + STOREDMAINARRAYLEN * sizeof(float), wavetableSaveStrings[i] ); + } + _this.setAttribute( "waveforms"+QString::number(i), wavetableSaveStrings[i] ); + } + } + + for( int i = 0; i < 64; ++i ) + { + if( subEnabled[i]->value() ) + { + base64::encode( (const char *)storedsubs[i], + STOREDSUBWAVELEN * sizeof(float), saveString ); + _this.setAttribute( "subs"+QString::number(i), saveString ); + } + } + + base64::encode( (const char *)sampGraphs, + 1024 * sizeof(float), saveString ); + _this.setAttribute( "sampGraphs", saveString ); + + int sampleSizes[8] = {0}; + for( int i = 0; i < 8; ++i ) + { + if( sampleEnabled[i]->value() ) + { + for( int j = 0; j < 2; ++j ) + { + base64::encode( (const char *)samples[i][j].data(), + samples[i][j].size() * sizeof(float), saveString ); + _this.setAttribute( "samples_"+QString::number(i)+"_"+QString::number(j), saveString ); + } + + sampleSizes[i] = samples[i][0].size(); + } + } + + base64::encode( (const char *)sampleSizes, + 8 * sizeof(int), saveString ); + _this.setAttribute( "sampleSizes", saveString ); + + for( int i = 0; i < maxMainEnabled; ++i ) + { + if( enabled[i]->value() ) + { + morph[i]->saveSettings( _doc, _this, "morph_"+QString::number(i) ); + range[i]->saveSettings( _doc, _this, "range_"+QString::number(i) ); + modify[i]->saveSettings( _doc, _this, "modify_"+QString::number(i) ); + modifyMode[i]->saveSettings( _doc, _this, "modifyMode_"+QString::number(i) ); + unisonVoices[i]->saveSettings( _doc, _this, "unisonVoices_"+QString::number(i) ); + unisonDetune[i]->saveSettings( _doc, _this, "unisonDetune_"+QString::number(i) ); + unisonMorph[i]->saveSettings( _doc, _this, "unisonMorph_"+QString::number(i) ); + unisonModify[i]->saveSettings( _doc, _this, "unisonModify_"+QString::number(i) ); + morphMax[i]->saveSettings( _doc, _this, "morphMax_"+QString::number(i) ); + detune[i]->saveSettings( _doc, _this, "detune_"+QString::number(i) ); + sampLen[i]->saveSettings( _doc, _this, "sampLen_"+QString::number(i) ); + phase[i]->saveSettings( _doc, _this, "phase_"+QString::number(i) ); + phaseRand[i]->saveSettings( _doc, _this, "phaseRand_"+QString::number(i) ); + vol[i]->saveSettings( _doc, _this, "vol_"+QString::number(i) ); + enabled[i]->saveSettings( _doc, _this, "enabled_"+QString::number(i) ); + muted[i]->saveSettings( _doc, _this, "muted_"+QString::number(i) ); + pan[i]->saveSettings( _doc, _this, "pan_"+QString::number(i) ); + keytracking[i]->saveSettings( _doc, _this, "keytracking_"+QString::number(i) ); + tempo[i]->saveSettings( _doc, _this, "tempo_"+QString::number(i) ); + interpolate[i]->saveSettings( _doc, _this, "interpolate_"+QString::number(i) ); + } + } + + for( int i = 0; i < maxSampleEnabled; ++i ) + { + if( sampleEnabled[i]->value() ) + { + sampleEnabled[i]->saveSettings( _doc, _this, "sampleEnabled_"+QString::number(i) ); + sampleGraphEnabled[i]->saveSettings( _doc, _this, "sampleGraphEnabled_"+QString::number(i) ); + sampleMuted[i]->saveSettings( _doc, _this, "sampleMuted_"+QString::number(i) ); + sampleKeytracking[i]->saveSettings( _doc, _this, "sampleKeytracking_"+QString::number(i) ); + sampleLoop[i]->saveSettings( _doc, _this, "sampleLoop_"+QString::number(i) ); + sampleVolume[i]->saveSettings( _doc, _this, "sampleVolume_"+QString::number(i) ); + samplePanning[i]->saveSettings( _doc, _this, "samplePanning_"+QString::number(i) ); + sampleDetune[i]->saveSettings( _doc, _this, "sampleDetune_"+QString::number(i) ); + samplePhase[i]->saveSettings( _doc, _this, "samplePhase_"+QString::number(i) ); + samplePhaseRand[i]->saveSettings( _doc, _this, "samplePhaseRand_"+QString::number(i) ); + sampleStart[i]->saveSettings( _doc, _this, "sampleStart_"+QString::number(i) ); + sampleEnd[i]->saveSettings( _doc, _this, "sampleEnd_"+QString::number(i) ); + } + } + + for( int i = 0; i < maxFiltEnabled; ++i ) + { + if( filtEnabled[i]->value() ) + { + filtInVol[i]->saveSettings( _doc, _this, "filtInVol_"+QString::number(i) ); + filtType[i]->saveSettings( _doc, _this, "filtType_"+QString::number(i) ); + filtSlope[i]->saveSettings( _doc, _this, "filtSlope_"+QString::number(i) ); + filtCutoff[i]->saveSettings( _doc, _this, "filtCutoff_"+QString::number(i) ); + filtReso[i]->saveSettings( _doc, _this, "filtReso_"+QString::number(i) ); + filtGain[i]->saveSettings( _doc, _this, "filtGain_"+QString::number(i) ); + filtSatu[i]->saveSettings( _doc, _this, "filtSatu_"+QString::number(i) ); + filtWetDry[i]->saveSettings( _doc, _this, "filtWetDry_"+QString::number(i) ); + filtBal[i]->saveSettings( _doc, _this, "filtBal_"+QString::number(i) ); + filtOutVol[i]->saveSettings( _doc, _this, "filtOutVol_"+QString::number(i) ); + filtEnabled[i]->saveSettings( _doc, _this, "filtEnabled_"+QString::number(i) ); + filtFeedback[i]->saveSettings( _doc, _this, "filtFeedback_"+QString::number(i) ); + filtDetune[i]->saveSettings( _doc, _this, "filtDetune_"+QString::number(i) ); + filtKeytracking[i]->saveSettings( _doc, _this, "filtKeytracking_"+QString::number(i) ); + filtMuted[i]->saveSettings( _doc, _this, "filtMuted_"+QString::number(i) ); + } + } + + for( int i = 0; i < maxSubEnabled; ++i ) + { + if( subEnabled[i]->value() ) + { + subEnabled[i]->saveSettings( _doc, _this, "subEnabled_"+QString::number(i) ); + subVol[i]->saveSettings( _doc, _this, "subVol_"+QString::number(i) ); + subPhase[i]->saveSettings( _doc, _this, "subPhase_"+QString::number(i) ); + subPhaseRand[i]->saveSettings( _doc, _this, "subPhaseRand_"+QString::number(i) ); + subDetune[i]->saveSettings( _doc, _this, "subDetune_"+QString::number(i) ); + subMuted[i]->saveSettings( _doc, _this, "subMuted_"+QString::number(i) ); + subKeytrack[i]->saveSettings( _doc, _this, "subKeytrack_"+QString::number(i) ); + subSampLen[i]->saveSettings( _doc, _this, "subSampLen_"+QString::number(i) ); + subNoise[i]->saveSettings( _doc, _this, "subNoise_"+QString::number(i) ); + subPanning[i]->saveSettings( _doc, _this, "subPanning_"+QString::number(i) ); + subTempo[i]->saveSettings( _doc, _this, "subTempo_"+QString::number(i) ); + subRateLimit[i]->saveSettings( _doc, _this, "subRateLimit_"+QString::number(i) ); + subUnisonNum[i]->saveSettings( _doc, _this, "subUnisonNum_"+QString::number(i) ); + subUnisonDetune[i]->saveSettings( _doc, _this, "subUnisonDetune_"+QString::number(i) ); + subInterpolate[i]->saveSettings( _doc, _this, "subInterpolate_"+QString::number(i) ); + } + } + + for( int i = 0; i < maxModEnabled; ++i ) + { + if( modEnabled[i]->value() ) + { + modIn[i]->saveSettings( _doc, _this, "modIn_"+QString::number(i) ); + modInNum[i]->saveSettings( _doc, _this, "modInNu"+QString::number(i) ); + modInAmnt[i]->saveSettings( _doc, _this, "modInAmnt_"+QString::number(i) ); + modInCurve[i]->saveSettings( _doc, _this, "modInCurve_"+QString::number(i) ); + modIn2[i]->saveSettings( _doc, _this, "modIn2_"+QString::number(i) ); + modInNum2[i]->saveSettings( _doc, _this, "modInNum2_"+QString::number(i) ); + modInAmnt2[i]->saveSettings( _doc, _this, "modAmnt2_"+QString::number(i) ); + modInCurve2[i]->saveSettings( _doc, _this, "modCurve2_"+QString::number(i) ); + modOutSec[i]->saveSettings( _doc, _this, "modOutSec_"+QString::number(i) ); + modOutSig[i]->saveSettings( _doc, _this, "modOutSig_"+QString::number(i) ); + modOutSecNum[i]->saveSettings( _doc, _this, "modOutSecNu"+QString::number(i) ); + modEnabled[i]->saveSettings( _doc, _this, "modEnabled_"+QString::number(i) ); + modCombineType[i]->saveSettings( _doc, _this, "modCombineType_"+QString::number(i) ); + modType[i]->saveSettings( _doc, _this, "modType_"+QString::number(i) ); + modType2[i]->saveSettings( _doc, _this, "modType2_"+QString::number(i) ); + } + } + + for( int i = 0; i < 18; ++i ) + { + macro[i]->saveSettings( _doc, _this, "macro_"+QString::number(i) ); + _this.setAttribute( "macroTooltips_"+QString::number(i), macroTooltips[i] ); + _this.setAttribute( "macroRed_"+QString::number(i), macroColors[i][0] ); + _this.setAttribute( "macroGreen_"+QString::number(i), macroColors[i][1] ); + _this.setAttribute( "macroBlue_"+QString::number(i), macroColors[i][2] ); + } +} + + +void Microwave::loadSettings( const QDomElement & _this ) +{ + QString microwaveVersion = _this.attribute( "version" ); + + visvol.loadSettings( _this, "visualizervolume" ); + loadMode.loadSettings( _this, "loadingalgorithm" ); + loadChnl.loadSettings( _this, "loadingchannel" ); + + oversample.loadSettings( _this, "oversample" ); + oversampleMode.loadSettings( _this, "oversamplemode" ); + removeDC.loadSettings( _this, "removeDC" ); + + graph.setLength( 2048 ); + + for( int i = 0; i < 8; ++i ) + { + enabled[i]->loadSettings( _this, "enabled_"+QString::number(i) ); + if( enabled[i]->value() ) + { + morph[i]->loadSettings( _this, "morph_"+QString::number(i) ); + range[i]->loadSettings( _this, "range_"+QString::number(i) ); + modify[i]->loadSettings( _this, "modify_"+QString::number(i) ); + modifyMode[i]->loadSettings( _this, "modifyMode_"+QString::number(i) ); + unisonVoices[i]->loadSettings( _this, "unisonVoices_"+QString::number(i) ); + unisonDetune[i]->loadSettings( _this, "unisonDetune_"+QString::number(i) ); + unisonMorph[i]->loadSettings( _this, "unisonMorph_"+QString::number(i) ); + unisonModify[i]->loadSettings( _this, "unisonModify_"+QString::number(i) ); + morphMax[i]->loadSettings( _this, "morphMax_"+QString::number(i) ); + detune[i]->loadSettings( _this, "detune_"+QString::number(i) ); + sampLen[i]->loadSettings( _this, "sampLen_"+QString::number(i) ); + phase[i]->loadSettings( _this, "phase_"+QString::number(i) ); + phaseRand[i]->loadSettings( _this, "phaseRand_"+QString::number(i) ); + vol[i]->loadSettings( _this, "vol_"+QString::number(i) ); + muted[i]->loadSettings( _this, "muted_"+QString::number(i) ); + pan[i]->loadSettings( _this, "pan_"+QString::number(i) ); + keytracking[i]->loadSettings( _this, "keytracking_"+QString::number(i) ); + tempo[i]->loadSettings( _this, "tempo_"+QString::number(i) ); + interpolate[i]->loadSettings( _this, "interpolate_"+QString::number(i) ); + } + + filtEnabled[i]->loadSettings( _this, "filtEnabled_"+QString::number(i) ); + if( filtEnabled[i]->value() ) + { + filtInVol[i]->loadSettings( _this, "filtInVol_"+QString::number(i) ); + filtType[i]->loadSettings( _this, "filtType_"+QString::number(i) ); + filtSlope[i]->loadSettings( _this, "filtSlope_"+QString::number(i) ); + filtCutoff[i]->loadSettings( _this, "filtCutoff_"+QString::number(i) ); + filtReso[i]->loadSettings( _this, "filtReso_"+QString::number(i) ); + filtGain[i]->loadSettings( _this, "filtGain_"+QString::number(i) ); + filtSatu[i]->loadSettings( _this, "filtSatu_"+QString::number(i) ); + filtWetDry[i]->loadSettings( _this, "filtWetDry_"+QString::number(i) ); + filtBal[i]->loadSettings( _this, "filtBal_"+QString::number(i) ); + filtOutVol[i]->loadSettings( _this, "filtOutVol_"+QString::number(i) ); + filtFeedback[i]->loadSettings( _this, "filtFeedback_"+QString::number(i) ); + filtDetune[i]->loadSettings( _this, "filtDetune_"+QString::number(i) ); + filtKeytracking[i]->loadSettings( _this, "filtKeytracking_"+QString::number(i) ); + filtMuted[i]->loadSettings( _this, "filtMuted_"+QString::number(i) ); + } + + sampleEnabled[i]->loadSettings( _this, "sampleEnabled_"+QString::number(i) ); + if( sampleEnabled[i]->value() ) + { + sampleGraphEnabled[i]->loadSettings( _this, "sampleGraphEnabled_"+QString::number(i) ); + sampleMuted[i]->loadSettings( _this, "sampleMuted_"+QString::number(i) ); + sampleKeytracking[i]->loadSettings( _this, "sampleKeytracking_"+QString::number(i) ); + sampleLoop[i]->loadSettings( _this, "sampleLoop_"+QString::number(i) ); + sampleVolume[i]->loadSettings( _this, "sampleVolume_"+QString::number(i) ); + samplePanning[i]->loadSettings( _this, "samplePanning_"+QString::number(i) ); + sampleDetune[i]->loadSettings( _this, "sampleDetune_"+QString::number(i) ); + samplePhase[i]->loadSettings( _this, "samplePhase_"+QString::number(i) ); + samplePhaseRand[i]->loadSettings( _this, "samplePhaseRand_"+QString::number(i) ); + sampleStart[i]->loadSettings( _this, "sampleStart_"+QString::number(i) ); + sampleEnd[i]->loadSettings( _this, "sampleEnd_"+QString::number(i) ); + } + } + + for( int i = 0; i < 18; ++i ) + { + macro[i]->loadSettings( _this, "macro_"+QString::number(i) ); + } + + for( int i = 0; i < 64; ++i ) + { + subEnabled[i]->loadSettings( _this, "subEnabled_"+QString::number(i) ); + if( subEnabled[i]->value() ) + { + subVol[i]->loadSettings( _this, "subVol_"+QString::number(i) ); + subPhase[i]->loadSettings( _this, "subPhase_"+QString::number(i) ); + subPhaseRand[i]->loadSettings( _this, "subPhaseRand_"+QString::number(i) ); + subDetune[i]->loadSettings( _this, "subDetune_"+QString::number(i) ); + subMuted[i]->loadSettings( _this, "subMuted_"+QString::number(i) ); + subKeytrack[i]->loadSettings( _this, "subKeytrack_"+QString::number(i) ); + subSampLen[i]->loadSettings( _this, "subSampLen_"+QString::number(i) ); + subNoise[i]->loadSettings( _this, "subNoise_"+QString::number(i) ); + subPanning[i]->loadSettings( _this, "subPanning_"+QString::number(i) ); + subTempo[i]->loadSettings( _this, "subTempo_"+QString::number(i) ); + subRateLimit[i]->loadSettings( _this, "subRateLimit_"+QString::number(i) ); + subUnisonNum[i]->loadSettings( _this, "subUnisonNum_"+QString::number(i) ); + subUnisonDetune[i]->loadSettings( _this, "subUnisonDetune_"+QString::number(i) ); + subInterpolate[i]->loadSettings( _this, "subInterpolate_"+QString::number(i) ); + } + + modEnabled[i]->loadSettings( _this, "modEnabled_"+QString::number(i) ); + if( modEnabled[i]->value() ) + { + modIn[i]->loadSettings( _this, "modIn_"+QString::number(i) ); + modInNum[i]->loadSettings( _this, "modInNu"+QString::number(i) ); + modInAmnt[i]->loadSettings( _this, "modInAmnt_"+QString::number(i) ); + modInCurve[i]->loadSettings( _this, "modInCurve_"+QString::number(i) ); + modIn2[i]->loadSettings( _this, "modIn2_"+QString::number(i) ); + modInNum2[i]->loadSettings( _this, "modInNum2_"+QString::number(i) ); + modInAmnt2[i]->loadSettings( _this, "modAmnt2_"+QString::number(i) ); + modInCurve2[i]->loadSettings( _this, "modCurve2_"+QString::number(i) ); + modOutSec[i]->loadSettings( _this, "modOutSec_"+QString::number(i) ); + modOutSig[i]->loadSettings( _this, "modOutSig_"+QString::number(i) ); + modOutSecNum[i]->loadSettings( _this, "modOutSecNu"+QString::number(i) ); + modCombineType[i]->loadSettings( _this, "modCombineType_"+QString::number(i) ); + modType[i]->loadSettings( _this, "modType_"+QString::number(i) ); + modType2[i]->loadSettings( _this, "modType2_"+QString::number(i) ); + } + } + + int size = 0; + char * dst = 0; + + + for( int j = 0; j < 8; ++j ) + { + if( enabled[j]->value() ) + { + base64::decode( _this.attribute( "waveforms"+QString::number(j) ), &dst, &size ); + for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + { + storedwaveforms[j][i] = ( (float*) dst )[i]; + } + } + } + + for( int j = 0; j < 64; ++j ) + { + if( subEnabled[j]->value() ) + { + base64::decode( _this.attribute( "subs"+QString::number(j) ), &dst, &size ); + for( int i = 0; i < STOREDSUBWAVELEN; ++i ) + { + storedsubs[j][i] = ( (float*) dst )[i]; + } + } + } + + base64::decode( _this.attribute( "sampGraphs" ), &dst, &size ); + for( int i = 0; i < 1024; ++i ) + { + sampGraphs[i] = ( (float*) dst )[i]; + } + + int sampleSizes[8] = {0}; + base64::decode( _this.attribute( "sampleSizes" ), &dst, &size ); + for( int i = 0; i < 8; ++i ) + { + sampleSizes[i] = ( (int*) dst )[i]; + } + + for( int i = 0; i < 8; ++i ) + { + if( sampleEnabled[i]->value() ) + { + for( int j = 0; j < 2; ++j ) + { + base64::decode( _this.attribute( "samples_"+QString::number(i)+"_"+QString::number(j) ), &dst, &size ); + for( int k = 0; k < sampleSizes[i]; ++k ) + { + samples[i][j].push_back( ( (float*) dst )[k] ); + } + } + } + } + + for( int i = 0; i < 18; ++i ) + { + macroTooltips[i] = _this.attribute( "macroTooltips_"+QString::number(i) ); + macroColors[i][0] = _this.attribute( "macroRed_"+QString::number(i) ).toInt(); + macroColors[i][1] = _this.attribute( "macroGreen_"+QString::number(i) ).toInt(); + macroColors[i][2] = _this.attribute( "macroBlue_"+QString::number(i) ).toInt(); + } + + delete[] dst; + + // Interpolate all the wavetables and waveforms when loaded. + for( int i = 0; i < 8; ++i ) + { + if( enabled[i]->value() ) + { + fillMainOsc(i, interpolate[i]->value()); + } + } + + for( int i = 0; i < 64; ++i ) + { + if( subEnabled[i]->value() ) + { + fillSubOsc(i, subInterpolate[i]->value()); + } + } + +} + + +// When a knob is changed, send the new value to the array holding the knob values, as well as the note values within mSynths already initialized (notes already playing) +void Microwave::valueChanged( int which, int num ) +{ + //Send new values to array + switch( which ) + { + case 1: morphArr[num] = morph[num]->value(); break; + case 2: rangeArr[num] = range[num]->value(); break; + case 3: modifyArr[num] = modify[num]->value(); break; + case 4: modifyModeArr[num] = modifyMode[num]->value(); break; + case 5: volArr[num] = vol[num]->value(); break; + case 6: panArr[num] = pan[num]->value(); break; + case 7: detuneArr[num] = detune[num]->value(); break; + case 8: phaseArr[num] = phase[num]->value(); break; + case 9: phaseRandArr[num] = phaseRand[num]->value(); break; + case 10: enabledArr[num] = enabled[num]->value(); break; + case 11: mutedArr[num] = muted[num]->value(); break; + case 12: sampLenArr[num] = sampLen[num]->value(); break; + case 13: morphMaxArr[num] = morphMax[num]->value(); break; + case 14: unisonVoicesArr[num] = unisonVoices[num]->value(); break; + case 15: unisonDetuneArr[num] = unisonDetune[num]->value(); break; + case 16: unisonMorphArr[num] = unisonMorph[num]->value(); break; + case 17: unisonModifyArr[num] = unisonModify[num]->value(); break; + case 18: keytrackingArr[num] = keytracking[num]->value(); break; + case 19: tempoArr[num] = tempo[num]->value(); break; + case 20: interpolateArr[num] = interpolate[num]->value(); break; + + case 30: subEnabledArr[num] = subEnabled[num]->value(); break; + case 31: subMutedArr[num] = subMuted[num]->value(); break; + case 32: subKeytrackArr[num] = subKeytrack[num]->value(); break; + case 33: subNoiseArr[num] = subNoise[num]->value(); break; + case 34: subVolArr[num] = subVol[num]->value(); break; + case 35: subPanningArr[num] = subPanning[num]->value(); break; + case 36: subDetuneArr[num] = subDetune[num]->value(); break; + case 37: subPhaseArr[num] = subPhase[num]->value(); break; + case 38: subPhaseRandArr[num] = subPhaseRand[num]->value(); break; + case 39: subSampLenArr[num] = subSampLen[num]->value(); break; + case 40: subTempoArr[num] = subTempo[num]->value(); break; + case 41: subRateLimitArr[num] = subRateLimit[num]->value(); break; + case 42: subUnisonNumArr[num] = subUnisonNum[num]->value(); break; + case 43: subUnisonDetuneArr[num] = subUnisonDetune[num]->value(); break; + case 44: subInterpolateArr[num] = subInterpolate[num]->value(); break; + + case 60: sampleEnabledArr[num] = sampleEnabled[num]->value(); break; + case 61: sampleMutedArr[num] = sampleMuted[num]->value(); break; + case 62: sampleKeytrackingArr[num] = sampleKeytracking[num]->value(); break; + case 63: sampleGraphEnabledArr[num] = sampleGraphEnabled[num]->value(); break; + case 64: sampleLoopArr[num] = sampleLoop[num]->value(); break; + case 65: sampleVolumeArr[num] = sampleVolume[num]->value(); break; + case 66: samplePanningArr[num] = samplePanning[num]->value(); break; + case 67: sampleDetuneArr[num] = sampleDetune[num]->value(); break; + case 68: samplePhaseArr[num] = samplePhase[num]->value(); break; + case 69: samplePhaseRandArr[num] = samplePhaseRand[num]->value(); break; + case 70: sampleStartArr[num] = sampleStart[num]->value(); break; + case 71: sampleEndArr[num] = sampleEnd[num]->value(); break; + + case 90: modInArr[num] = modIn[num]->value(); break; + case 91: modInNumArr[num] = modInNum[num]->value(); break; + case 92: modInAmntArr[num] = modInAmnt[num]->value(); break; + case 93: modInCurveArr[num] = modInCurve[num]->value(); break; + case 94: modIn2Arr[num] = modIn2[num]->value(); break; + case 95: modInNum2Arr[num] = modInNum2[num]->value(); break; + case 96: modInAmnt2Arr[num] = modInAmnt2[num]->value(); break; + case 97: modInCurve2Arr[num] = modInCurve2[num]->value(); break; + case 98: modOutSecArr[num] = modOutSec[num]->value(); break; + case 99: modOutSigArr[num] = modOutSig[num]->value(); break; + case 100: modOutSecNumArr[num] = modOutSecNum[num]->value(); break; + case 101: modEnabledArr[num] = modEnabled[num]->value(); break; + case 102: modCombineTypeArr[num] = modCombineType[num]->value(); break; + case 103: modTypeArr[num] = modType[num]->value(); break; + case 104: modType2Arr[num] = modType2[num]->value(); break; + + case 120: filtCutoffArr[num] = filtCutoff[num]->value(); break; + case 121: filtResoArr[num] = filtReso[num]->value(); break; + case 122: filtGainArr[num] = filtGain[num]->value(); break; + case 123: filtTypeArr[num] = filtType[num]->value(); break; + case 124: filtSlopeArr[num] = filtSlope[num]->value(); break; + case 125: filtInVolArr[num] = filtInVol[num]->value(); break; + case 126: filtOutVolArr[num] = filtOutVol[num]->value(); break; + case 127: filtWetDryArr[num] = filtWetDry[num]->value(); break; + case 128: filtBalArr[num] = filtBal[num]->value(); break; + case 129: filtSatuArr[num] = filtSatu[num]->value(); break; + case 130: filtFeedbackArr[num] = filtFeedback[num]->value(); break; + case 131: filtDetuneArr[num] = filtDetune[num]->value(); break; + case 132: filtEnabledArr[num] = filtEnabled[num]->value(); break; + case 133: filtMutedArr[num] = filtMuted[num]->value(); break; + case 134: filtKeytrackingArr[num] = filtKeytracking[num]->value(); break; + + case 150: macroArr[num] = macro[num]->value(); break; + } + + nphList = NotePlayHandle::nphsOfInstrumentTrack( microwaveTrack, true ); + + for( int i = 0; i < nphList.length(); ++i ) + { + mSynth * ps = static_cast( nphList[i]->m_pluginData ); + + if( ps )// Makes sure "ps" isn't assigned a null value, if m_pluginData hasn't been created yet. + { + //Send new knob values to notes already playing + switch( which ) + { + case 1: ps->morph[num] = morph[num]->value(); break; + case 2: ps->range[num] = range[num]->value(); break; + case 3: ps->modify[num] = modify[num]->value(); break; + case 4: ps->modifyMode[num] = modifyMode[num]->value(); break; + case 5: ps->vol[num] = vol[num]->value(); break; + case 6: ps->pan[num] = pan[num]->value(); break; + case 7: ps->detune[num] = detune[num]->value(); break; + case 8: ps->phase[num] = phase[num]->value(); break; + case 9: ps->phaseRand[num] = phaseRand[num]->value(); break; + case 10: ps->enabled[num] = enabled[num]->value(); break; + case 11: ps->muted[num] = muted[num]->value(); break; + case 12: ps->sampLen[num] = sampLen[num]->value(); break; + case 13: ps->morphMax[num] = morphMax[num]->value(); break; + case 14: ps->unisonVoices[num] = unisonVoices[num]->value(); break; + case 15: ps->unisonDetune[num] = unisonDetune[num]->value(); break; + case 16: ps->unisonMorph[num] = unisonMorph[num]->value(); break; + case 17: ps->unisonModify[num] = unisonModify[num]->value(); break; + case 18: ps->keytracking[num] = keytracking[num]->value(); break; + case 19: ps->tempo[num] = tempo[num]->value(); break; + + case 30: ps->subEnabled[num] = subEnabled[num]->value(); break; + case 31: ps->subMuted[num] = subMuted[num]->value(); break; + case 32: ps->subKeytrack[num] = subKeytrack[num]->value(); break; + case 33: ps->subNoise[num] = subNoise[num]->value(); break; + case 34: ps->subVol[num] = subVol[num]->value(); break; + case 35: ps->subPanning[num] = subPanning[num]->value(); break; + case 36: ps->subDetune[num] = subDetune[num]->value(); break; + case 37: ps->subPhase[num] = subPhase[num]->value(); break; + case 38: ps->subPhaseRand[num] = subPhaseRand[num]->value(); break; + case 39: ps->subSampLen[num] = subSampLen[num]->value(); break; + case 40: ps->subTempo[num] = subTempo[num]->value(); break; + case 41: ps->subRateLimit[num] = subRateLimit[num]->value(); break; + case 42: ps->subUnisonNum[num] = subUnisonNum[num]->value(); break; + case 43: ps->subUnisonDetune[num] = subUnisonDetune[num]->value(); break; + case 44: ps->subInterpolate[num] = subInterpolate[num]->value(); break; + + case 60: ps->sampleEnabled[num] = sampleEnabled[num]->value(); break; + case 61: ps->sampleMuted[num] = sampleMuted[num]->value(); break; + case 62: ps->sampleKeytracking[num] = sampleKeytracking[num]->value(); break; + case 63: ps->sampleGraphEnabled[num] = sampleGraphEnabled[num]->value(); break; + case 64: ps->sampleLoop[num] = sampleLoop[num]->value(); break; + case 65: ps->sampleVolume[num] = sampleVolume[num]->value(); break; + case 66: ps->samplePanning[num] = samplePanning[num]->value(); break; + case 67: ps->sampleDetune[num] = sampleDetune[num]->value(); break; + case 68: ps->samplePhase[num] = samplePhase[num]->value(); break; + case 69: ps->samplePhaseRand[num] = samplePhaseRand[num]->value(); break; + case 70: ps->sampleStart[num] = sampleStart[num]->value(); break; + case 71: ps->sampleEnd[num] = sampleEnd[num]->value(); break; + + case 90: ps->modIn[num] = modIn[num]->value(); break; + case 91: ps->modInNum[num] = modInNum[num]->value(); break; + case 92: ps->modInAmnt[num] = modInAmnt[num]->value(); break; + case 93: ps->modInCurve[num] = modInCurve[num]->value(); break; + case 94: ps->modIn2[num] = modIn2[num]->value(); break; + case 95: ps->modInNum2[num] = modInNum2[num]->value(); break; + case 96: ps->modInAmnt2[num] = modInAmnt2[num]->value(); break; + case 97: ps->modInCurve2[num] = modInCurve2[num]->value(); break; + case 98: ps->modOutSec[num] = modOutSec[num]->value(); break; + case 99: ps->modOutSig[num] = modOutSig[num]->value(); break; + case 100: ps->modOutSecNum[num] = modOutSecNum[num]->value(); break; + case 101: ps->modEnabled[num] = modEnabled[num]->value(); break; + case 102: ps->modCombineType[num] = modCombineType[num]->value(); break; + case 103: ps->modType[num] = modType[num]->value(); break; + case 104: ps->modType2[num] = modType2[num]->value(); break; + + case 120: ps->filtCutoff[num] = filtCutoff[num]->value(); break; + case 121: ps->filtReso[num] = filtReso[num]->value(); break; + case 122: ps->filtGain[num] = filtGain[num]->value(); break; + case 123: ps->filtType[num] = filtType[num]->value(); break; + case 124: ps->filtSlope[num] = filtSlope[num]->value(); break; + case 125: ps->filtInVol[num] = filtInVol[num]->value(); break; + case 126: ps->filtOutVol[num] = filtOutVol[num]->value(); break; + case 127: ps->filtWetDry[num] = filtWetDry[num]->value(); break; + case 128: ps->filtBal[num] = filtBal[num]->value(); break; + case 129: ps->filtSatu[num] = filtSatu[num]->value(); break; + case 130: ps->filtFeedback[num] = filtFeedback[num]->value(); break; + case 131: ps->filtDetune[num] = filtDetune[num]->value(); break; + case 132: ps->filtEnabled[num] = filtEnabled[num]->value(); break; + case 133: ps->filtMuted[num] = filtMuted[num]->value(); break; + case 134: ps->filtKeytracking[num] = filtKeytracking[num]->value(); break; + + case 150: ps->macro[num] = macro[num]->value(); break; + } + } + } +} + + +// Set the range of Morph based on Morph Max +void Microwave::morphMaxChanged( int i ) +{ + morph[i]->setRange( morph[i]->minValue(), morphMax[i]->value(), morph[i]->step() ); + unisonMorph[i]->setRange( unisonMorph[i]->minValue(), morphMax[i]->value(), unisonMorph[i]->step() ); +} + + +// Set the range of morphMax and Modify based on new sample length +void Microwave::sampLenChanged( int i ) +{ + morphMax[i]->setRange( morphMax[i]->minValue(), STOREDMAINARRAYLEN / sampLen[i]->value() - 2, morphMax[i]->step() ); + modify[i]->setRange( modify[i]->minValue(), sampLen[i]->value() - 1, modify[i]->step() ); + unisonModify[i]->setRange( unisonModify[i]->minValue(), sampLen[i]->value() - 1, unisonModify[i]->step() ); +} + + +//Change graph length to sample length +void Microwave::subSampLenChanged( int num ) +{ + if( scroll == 1 && subNum.value() == num + 1 ) + { + graph.setLength( subSampLen[num]->value() ); + } +} + + +//Stores the highest enabled main oscillator. Helps with CPU benefit, refer to its use in mSynth::nextStringSample +void Microwave::mainEnabledChanged( int num ) +{ + for( int i = 0; i < 8; ++i ) + { + if( enabled[i]->value() ) + { + maxMainEnabled = i + 1; + } + } +} + + +//Stores the highest enabled sub oscillator. Helps with major CPU benefit, refer to its use in mSynth::nextStringSample +void Microwave::subEnabledChanged( int num ) +{ + for( int i = 0; i < 64; ++i ) + { + if( subEnabled[i]->value() ) + { + maxSubEnabled = i + 1; + } + } +} + + +//Stores the highest enabled sample. Helps with CPU benefit, refer to its use in mSynth::nextStringSample +void Microwave::sampleEnabledChanged( int num ) +{ + for( int i = 0; i < 8; ++i ) + { + if( sampleEnabled[i]->value() ) + { + maxSampleEnabled = i + 1; + } + } +} + + +//Stores the highest enabled mod section. Helps with major CPU benefit, refer to its use in mSynth::nextStringSample +void Microwave::modEnabledChanged( int num ) +{ + for( int i = 0; i < 64; ++i ) + { + if( modEnabled[i]->value() ) + { + maxModEnabled = i + 1; + } + } +} + + +//Stores the highest enabled filter section. Helps with CPU benefit, refer to its use in mSynth::nextStringSample +void Microwave::filtEnabledChanged( int num ) +{ + for( int i = 0; i < 8; ++i ) + { + if( filtEnabled[i]->value() ) + { + maxFiltEnabled = i + 1; + } + } +} + + +//Updates sub oscillator inteprolation when the interpolation LED is changed. +void Microwave::interpolateChanged( int num ) +{ + fillMainOsc( num, interpolate[num]->value() ); +} + + +//Updates sub oscillator inteprolation when the interpolation LED is changed. +void Microwave::subInterpolateChanged( int num ) +{ + fillSubOsc( num, subInterpolate[num]->value() ); +} + + +//When user drawn on graph, send new values to the correct arrays +void Microwave::samplesChanged( int _begin, int _end ) +{ + switch( (int)scroll ) + { + case 0: + { + break; + } + case 1: + { + for( int i = _begin; i <= _end; ++i ) + { + storedsubs[subNum.value()-1][i] = graph.samples()[i]; + for( int j = 0; j < WAVERATIO; ++j ) + { + // Puts low-quality samples into there so one can change the waveform mid-note. The quality boost will occur at another time. + // It cannot do the interpolation here because it causes lag. + subs[subNum.value()-1][i*WAVERATIO+j] = graph.samples()[i]; + } + } + + subFilled[subNum.value()-1] = false;// Make sure the waveform is interpolated later on. + + // If the entire graph was changed all at once, we can assume it isn't from the user drawing on the graph, + // so we can interpolate the oscillator without worrying about lag. + if( _begin == 0 && _end == STOREDSUBWAVELEN - 1 ) + { + fillSubOsc(subNum.value()-1, subInterpolate[subNum.value()-1]->value()); + } + break; + } + case 2: + { + for( int i = _begin; i <= _end; ++i ) + { + sampGraphs[i + ( (sampNum.value()-1) * 128 )] = graph.samples()[i]; + } + break; + } + } +} + + +void Microwave::switchMatrixSections( int source, int destination ) +{ + int modInTemp = modInArr[destination]; + int modInNumTemp = modInNumArr[destination]; + float modInAmntTemp = modInAmntArr[destination]; + float modInCurveTemp = modInCurveArr[destination]; + int modIn2Temp = modIn2Arr[destination]; + int modInNum2Temp = modInNum2Arr[destination]; + float modInAmnt2Temp = modInAmnt2Arr[destination]; + float modInCurve2Temp = modInCurve2Arr[destination]; + int modOutSecTemp = modOutSecArr[destination]; + int modOutSigTemp = modOutSigArr[destination]; + int modOutSecNumTemp = modOutSecNumArr[destination]; + bool modEnabledTemp = modEnabledArr[destination]; + int modCombineTypeTemp = modCombineTypeArr[destination]; + bool modTypeTemp = modTypeArr[destination]; + bool modType2Temp = modType2Arr[destination]; + + modIn[destination]->setValue( modInArr[source] ); + modInNum[destination]->setValue( modInNumArr[source] ); + modInAmnt[destination]->setValue( modInAmntArr[source] ); + modInCurve[destination]->setValue( modInCurveArr[source] ); + modIn2[destination]->setValue( modIn2Arr[source] ); + modInNum2[destination]->setValue( modInNum2Arr[source] ); + modInAmnt2[destination]->setValue( modInAmnt2Arr[source] ); + modInCurve2[destination]->setValue( modInCurve2Arr[source] ); + modOutSec[destination]->setValue( modOutSecArr[source] ); + modOutSig[destination]->setValue( modOutSigArr[source] ); + modOutSecNum[destination]->setValue( modOutSecNumArr[source] ); + modEnabled[destination]->setValue( modEnabledArr[source] ); + modCombineType[destination]->setValue( modCombineTypeArr[source] ); + modType[destination]->setValue( modTypeArr[source] ); + modType2[destination]->setValue( modType2Arr[source] ); + + modIn[source]->setValue( modInTemp ); + modInNum[source]->setValue( modInNumTemp ); + modInAmnt[source]->setValue( modInAmntTemp ); + modInCurve[source]->setValue( modInCurveTemp ); + modIn2[source]->setValue( modIn2Temp ); + modInNum2[source]->setValue( modInNum2Temp ); + modInAmnt2[source]->setValue( modInAmnt2Temp ); + modInCurve2[source]->setValue( modInCurve2Temp ); + modOutSec[source]->setValue( modOutSecTemp ); + modOutSig[source]->setValue( modOutSigTemp ); + modOutSecNum[source]->setValue( modOutSecNumTemp ); + modEnabled[source]->setValue( modEnabledTemp ); + modCombineType[source]->setValue( modCombineTypeTemp ); + modType[source]->setValue( modTypeTemp ); + modType2[source]->setValue( modType2Temp ); + + // If something is sent to a matrix box and the matrix box is moved, we want to make sure it's still attached to the same box after it is moved. + for( int i = 0; i < 64; ++i ) + { + if( modOutSec[i]->value() == 4 )// Output is being sent to Matrix + { + if( modOutSecNum[i]->value() - 1 == source )// Output was being sent a matrix box that was moved + { + modOutSecNum[i]->setValue( destination + 1 ); + } + else if( modOutSecNum[i]->value() - 1 == destination )// Output was being sent a matrix box that was moved + { + modOutSecNum[i]->setValue( source + 1 ); + } + } + } +} + + +// For when notes are playing. This initializes a new mSynth if the note is new. It also uses mSynth::nextStringSample to get the synthesizer output. This is where oversampling and the visualizer are handled. +void Microwave::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) +{ + + if ( _n->m_pluginData == NULL || _n->totalFramesPlayed() == 0 ) + { + _n->m_pluginData = new mSynth( + _n, + morphArr, rangeArr, modifyArr, modifyModeArr, volArr, panArr, detuneArr, phaseArr, phaseRandArr, enabledArr, mutedArr, + sampLenArr, morphMaxArr, unisonVoicesArr, unisonDetuneArr, unisonMorphArr, unisonModifyArr, keytrackingArr, tempoArr, interpolateArr, + subEnabledArr, subMutedArr, subKeytrackArr, subNoiseArr, subVolArr, subPanningArr, subDetuneArr, subPhaseArr, subPhaseRandArr, + subSampLenArr, subTempoArr, subRateLimitArr, subUnisonNumArr, subUnisonDetuneArr, subInterpolateArr, + sampleEnabledArr, sampleMutedArr, sampleKeytrackingArr, sampleGraphEnabledArr, sampleLoopArr, sampleVolumeArr, samplePanningArr, + sampleDetuneArr, samplePhaseArr, samplePhaseRandArr, sampleStartArr, sampleEndArr, + modInArr, modInNumArr, modInAmntArr, modInCurveArr, modIn2Arr, modInNum2Arr, modInAmnt2Arr, modInCurve2Arr, + modOutSecArr, modOutSigArr, modOutSecNumArr, modEnabledArr, modCombineTypeArr, modTypeArr, modType2Arr, + filtCutoffArr, filtResoArr, filtGainArr, filtTypeArr, filtSlopeArr, filtInVolArr, filtOutVolArr, filtWetDryArr, filtBalArr, + filtSatuArr, filtFeedbackArr, filtDetuneArr, filtEnabledArr, filtMutedArr, filtKeytrackingArr, + macroArr, + samples ); + mwc = dynamic_cast(_n->instrumentTrack()->instrument()); + + for( int i = 0; i < 64; ++i ) + { + if( subEnabled[i]->value() ) + { + if( !subFilled[i] ) + { + fillSubOsc(i, subInterpolate[i]->value()); + } + } + } + } + + const fpp_t frames = _n->framesLeftForCurrentPeriod(); + const f_cnt_t offset = _n->noteOffset(); + + mSynth * ps = static_cast( _n->m_pluginData ); + for( fpp_t frame = offset; frame < frames + offset; ++frame ) + { + sampleFrame outputSample; + sampleFrame totalOutputSample = {0, 0}; + + switch( oversampleMode.value() ) + { + case 0: + { + // Process some samples and ignore the output, depending on the oversampling value. For example, if the oversampling is set to 4x, it will process 4 samples and output 1 of those. + for( int i = 0; i < oversample.value() + 1; ++i ) + { + ps->nextStringSample( outputSample, waveforms, subs, sampGraphs, samples, maxFiltEnabled, maxModEnabled, maxSubEnabled, maxSampleEnabled, maxMainEnabled, Engine::mixer()->processingSampleRate() * ( oversample.value() + 1 ), mwc, removeDC.value(), !!i, storedsubs ); + } + totalOutputSample[0] = outputSample[0]; + totalOutputSample[1] = outputSample[1]; + + break; + } + case 1: + { + // Process some number of samples and average them together, depending on the oversampling value. + for( int i = 0; i < oversample.value() + 1; ++i ) + { + ps->nextStringSample( outputSample, waveforms, subs, sampGraphs, samples, maxFiltEnabled, maxModEnabled, maxSubEnabled, maxSampleEnabled, maxMainEnabled, Engine::mixer()->processingSampleRate() * ( oversample.value() + 1 ), mwc, removeDC.value(), !!i, storedsubs ); + totalOutputSample[0] += outputSample[0]; + totalOutputSample[1] += outputSample[1]; + } + + totalOutputSample[0] /= ( oversample.value() + 1 ); + totalOutputSample[1] /= ( oversample.value() + 1 ); + + break; + } + } + + for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) + { + //Send to output + _working_buffer[frame][chnl] = totalOutputSample[chnl]; + } + + //update visualizer + if( viewOpen && visualize.value() && scroll == 0 && ps->enabled[mainNum.value()-1] ) + { + visualizerValues[int( ( ps->sample_realindex[mainNum.value()-1][0] / ( ps->sampLen[mainNum.value()-1] * WAVERATIO ) ) * 204.f)] = ps->mainsample[mainNum.value()-1][0] * visvol.value() * 0.01f; + if( ps->noteDuration % 1470 == 1 )// Updates around 30 times per second (per note because I'm lazy I guess?) + { + graph.setSamples( visualizerValues ); + } + } + } + + applyRelease( _working_buffer, _n ); + + instrumentTrack()->processAudioBuffer( _working_buffer, frames + offset, _n ); +} + + +void Microwave::deleteNotePluginData( NotePlayHandle * _n ) +{ +} + + +// Fill subs using storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. +inline void Microwave::fillSubOsc( int which, bool doInterpolate ) +{ + if( doInterpolate ) + { + srccpy( subs[which], const_cast( storedsubs[which] ), STOREDSUBWAVELEN ); + } + else + { + for( int i = 0; i < STOREDSUBWAVELEN; ++i ) + { + for( int j = 0; j < WAVERATIO; ++j ) + { + subs[which][i*WAVERATIO+j] = storedsubs[which][i]; + } + } + } + subFilled[which] = true; +} + + + +// Fill subs using storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. +inline void Microwave::fillMainOsc( int which, bool doInterpolate ) +{ + if( doInterpolate ) + { + srccpy( waveforms[which], const_cast( storedwaveforms[which] ), STOREDMAINARRAYLEN ); + } + else + { + for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + { + for( int j = 0; j < WAVERATIO; ++j ) + { + waveforms[which][i*WAVERATIO+j] = storedwaveforms[which][i]; + } + } + } + mainFilled[which] = true; +} + + + + +/* + + ____ + ,' , `. + ,-+-,.' _ | ,--, ,---. ,--, + ,-+-. ; , ||,--.'| __ ,-. ,---. .---. /__./|,--.'| .---. + ,--.'|' | ;|| |, ,' ,'/ /| ' ,'\ /. ./| .---. ,---.; ; || |, /. ./| +| | ,', | ':`--'_ ,---. ' | |' | / / | .-'-. ' | ,--.--. /. ./| ,---./___/ \ | |`--'_ ,---. .-'-. ' | +| | / | | ||,' ,'| / \| | ,'. ; ,. : /___/ \: | / \ .-' . ' | / \ ; \ ' |,' ,'| / \ /___/ \: | +' | : | : |,' | | / / '' : / ' | |: : .-'.. ' ' ..--. .-. |/___/ \: | / / \ \ \: |' | | / / | .-'.. ' ' . +; . | ; |--' | | : . ' / | | ' ' | .; :/___/ \: ' \__\/: . .. \ ' .. ' / |; \ ' .| | : . ' / |/___/ \: ' +| : | | , ' : |__ ' ; :__; : | | : |. \ ' .\ ," .--.; | \ \ '' ; /| \ \ '' : |__ ' ; /|. \ ' .\ +| : ' |/ | | '.'|' | '.'| , ; \ \ / \ \ ' \ |/ / ,. | \ \ ' | / | \ ` ;| | '.'|' | / | \ \ ' \ | +; | |`-' ; : ;| : :---' `----' \ \ |--"; : .' \ \ \ || : | : \ |; : ;| : | \ \ |--" +| ;/ | , / \ \ / \ \ | | , .-./ '---" \ \ / '---" | , / \ \ / \ \ | +'---' ---`-' `----' '---" `--`---' `----' ---`-' `----' '---" + + + +*/ + + + +// Creates the Microwave GUI. Creates all GUI elements. Connects some events to some functions. Calls updateScroll() to put all of the GUI elements in their correct positions. +MicrowaveView::MicrowaveView( Instrument * _instrument, + QWidget * _parent ) : + InstrumentView( _instrument, _parent ) +{ + setAutoFillBackground( true ); + + setMouseTracking( true ); + + setAcceptDrops( true ); + + pal.setBrush( backgroundRole(), tab1ArtworkImg ); + setPalette( pal ); + + QWidget * view = new QWidget( _parent ); + view->setFixedSize( 250, 250 ); + + QPixmap filtBoxesImg = PLUGIN_NAME::getIconPixmap("filterBoxes"); + filtBoxesLabel = new QLabel(this); + filtBoxesLabel->setPixmap(filtBoxesImg); + filtBoxesLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); + + QPixmap matrixBoxesImg = PLUGIN_NAME::getIconPixmap("matrixBoxes"); + matrixBoxesLabel = new QLabel(this); + matrixBoxesLabel->setPixmap(matrixBoxesImg); + matrixBoxesLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); + + + makeknob( morphKnob, knobColored, tr( "Morph" ), tr( "The Morph knob chooses which waveform out of the wavetable to play." ) ); + + makeknob( rangeKnob, knobColored, tr( "Range" ), tr( "The Range knob interpolates (triangularly) the waveforms near the waveform selected by the Morph knob." ) ); + + makeknob( modifyKnob, knobColored, tr( "Modify" ), tr( "The Modify knob warps the wavetable realtime using super math powers. The formula depends on the Modify Mode dropdown box." ) ); + + makeknob( detuneKnob, knobSmallColored, tr( "Detune" ), tr( "This knob changes the pitch of the oscillator, in cents." ) ); + + makeknob( phaseKnob, knobSmallColored, tr( "Phase" ), tr( "This knob changes the phase (starting position) of the oscillator." ) ); + + makeknob( volKnob, knobColored, tr( "Volume" ), tr( "This knob changes the volume. What a surprise!" ) ); + + makeknob( panKnob, knobColored, tr( "Panning" ), tr( "This knob lowers the volume in one ear by an amount depending on this knob's value." ) ); + + makeknob( sampLenKnob, knobColored, tr( "Waveform Sample Length" ), tr( "This knob changes the number of samples per waveform there are in the wavetable. This is useful for finetuning the wavetbale if the wavetable loading was slightly off." ) ); + + makeknob( morphMaxKnob, knobColored, tr( "Morph Max" ), tr( "This knob sets the maximum value of the Morph knob." ) ); + + makeknob( phaseRandKnob, knobSmallColored, tr( "Phase Randomness" ), tr( "This knob chooses a random phase for every note and unison voice. The phase change will never be larger than this knob's value." ) ); + + makeknob( unisonVoicesKnob, knobSmallColored, tr( "Unison Voices" ), tr( "This knob clones this oscillator multiple times depending on its value, and makes slight changes to the clones depending on the other unison-related knobs." ) ); + + makeknob( unisonDetuneKnob, knobSmallColored, tr( "Unison Detune" ), tr( "This knob detunes every unison voice by a random number that is less than the specified amount." ) ); + + makeknob( unisonMorphKnob, knobSmallColored, tr( "Unison Morph" ), tr( "This knob changes the wavetable position of each individual unison voice." ) ); + + makeknob( unisonModifyKnob, knobSmallColored, tr( "Unison Modify" ), tr( "This knob changes the Modify value of each individual unison voice." ) ); + + makeknob( tempoKnob, knobSmallColored, tr( "Tempo Sync" ), tr( "When this knob is anything other than 0, the oscillator is tempo synced to the specified tempo. This is meant for the creation of envelopes/LFOs/step sequencers in the Matrix tab, and you'll most likely want to enable the Muted LED when using this." ) ); + + modifyModeBox = new ComboBox( this ); + modifyModeBox->setGeometry( 0, 5, 42, 22 ); + modifyModeBox->setFont( pointSize<8>( modifyModeBox->font() ) ); + ToolTip::add( modifyModeBox, tr( "The Modify Mode dropdown box chooses the formula for the Modify knob to use to warp the wavetable realtime in cool-sounding ways." ) ); + + enabledToggle = new LedCheckBox( "", this, tr( "Oscillator Enabled" ), LedCheckBox::Green ); + ToolTip::add( enabledToggle, tr( "This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!" ) ); + + mutedToggle = new LedCheckBox( "", this, tr( "Oscillator Muted" ), LedCheckBox::Green ); + ToolTip::add( mutedToggle, tr( "This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output." ) ); + + keytrackingToggle = new LedCheckBox( "", this, tr( "Keytracking" ), LedCheckBox::Green ); + ToolTip::add( keytrackingToggle, tr( "This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound." ) ); + + interpolateToggle = new LedCheckBox( "", this, tr( "Interpolation Enabled" ), LedCheckBox::Green ); + ToolTip::add( interpolateToggle, tr( "This button turns sinc interpolation on/off. Interpolation uses no CPU and makes the oscillator super duper high-quality. You'll probably only ever want to turn this off when you're using small waveform lengths and you don't want the waveform smoothed over." ) ); + + + sampleEnabledToggle = new LedCheckBox( "", this, tr( "Sample Enabled" ), LedCheckBox::Green ); + ToolTip::add( sampleEnabledToggle, tr( "This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!" ) ); + sampleGraphEnabledToggle = new LedCheckBox( "", this, tr( "Sample Graph Enabled" ), LedCheckBox::Green ); + ToolTip::add( sampleGraphEnabledToggle, tr( "This button enables the graph for this oscillator. On the graph, left/right is time and up/down is position in the sample. A saw wave in the graph will play the sample normally." ) ); + sampleMutedToggle = new LedCheckBox( "", this, tr( "Sample Muted" ), LedCheckBox::Green ); + ToolTip::add( sampleMutedToggle, tr( "This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output." ) ); + sampleKeytrackingToggle = new LedCheckBox( "", this, tr( "Sample Keytracking" ), LedCheckBox::Green ); + ToolTip::add( sampleKeytrackingToggle, tr( "This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound." ) ); + sampleLoopToggle = new LedCheckBox( "", this, tr( "Loop Sample" ), LedCheckBox::Green ); + ToolTip::add( sampleLoopToggle, tr( "This button turns looping on/off. When looping is on, the sample will go back to the starting position when it is done playing." ) ); + + makeknob( sampleVolumeKnob, knobColored, tr( "Volume" ), tr( "This, like most other volume knobs, controls the volume." ) ); + + makeknob( samplePanningKnob, knobColored, tr( "Panning" ), tr( "This knob lowers the volume in one ear by an amount depending on this knob's value." ) ); + + makeknob( sampleDetuneKnob, knobSmallColored, tr( "Detune" ), tr( "This knob changes the pitch (and speed) of the sample." ) ); + + makeknob( samplePhaseKnob, knobSmallColored, tr( "Phase" ), tr( "This knob changes the position of the sample, and is updated realtime when automated." ) ); + + makeknob( samplePhaseRandKnob, knobSmallColored, tr( "Phase Randomness" ), tr( "This knob makes the sample start at a random position with every note." ) ); + + makeknob( sampleStartKnob, knobSmallColored, tr( "Start" ), tr( "This knob changes the starting position of the sample." ) ); + + makeknob( sampleEndKnob, knobSmallColored, tr( "End" ), tr( "This knob changes the ending position of the sample." ) ); + + + for( int i = 0; i < 8; ++i ) + { + makeknob( filtInVolKnob[i], knobSmallColored, tr( "Input Volume" ), tr( "This knob changes the input volume of the filter." ) ); + + makeknob( filtCutoffKnob[i], knobSmallColored, tr( "Cutoff Frequency" ), tr( "This knob changes cutoff frequency of the filter." ) ); + + makeknob( filtResoKnob[i], knobSmallColored, tr( "Resonance" ), tr( "This knob changes the resonance of the filter." ) ); + + makeknob( filtGainKnob[i], knobSmallColored, tr( "db Gain" ), tr( "This knob changes the gain of the filter. This only applies to some filter types, e.g. Peak, High Shelf, Low Shelf, etc." ) ); + + makeknob( filtSatuKnob[i], knobSmallColored, tr( "Saturation" ), tr( "This knob applies some basic distortion after the filter is applied." ) ); + + makeknob( filtWetDryKnob[i], knobSmallColored, tr( "Wet/Dry" ), tr( "This knob allows mixing the filtered signal with the unfiltered signal." ) ); + + makeknob( filtBalKnob[i], knobSmallColored, tr( "Balance/Panning" ), tr( "This knob decreases the Wet and increases the Dry of the filter in one ear, depending on the knob's value." ) ); + + makeknob( filtOutVolKnob[i], knobSmallColored, tr( "Output Volume" ), tr( "This knob changes the output volume of the filter." ) ); + + makeknob( filtFeedbackKnob[i], knobSmallColored, tr( "Feedback" ), tr( "This knob sends the specified portion of the filter output back into the input after a certain delay. This delay effects the pitch, and can be changed using the filter's Detune and Keytracking options." ) ); + + makeknob( filtDetuneKnob[i], knobSmallColored, tr( "Detune (Feedback Delay)" ), tr( "This knob changes the delay of the filter's feedback to match the specified pitch." ) ); + + filtTypeBox[i] = new ComboBox( this ); + filtTypeBox[i]->setGeometry( 1000, 5, 42, 22 ); + filtTypeBox[i]->setFont( pointSize<8>( filtTypeBox[i]->font() ) ); + ToolTip::add( filtTypeBox[i], tr( "This dropdown box changes the filter type." ) ); + + filtSlopeBox[i] = new ComboBox( this ); + filtSlopeBox[i]->setGeometry( 1000, 5, 42, 22 ); + filtSlopeBox[i]->setFont( pointSize<8>( filtSlopeBox[i]->font() ) ); + ToolTip::add( filtSlopeBox[i], tr( "This dropdown box changes how many times the audio is run through the filter (which changes the slope). For example, a sound run through a 12 db filter three times will result in a 36 db slope." ) ); + + filtEnabledToggle[i] = new LedCheckBox( "", this, tr( "Filter Enabled" ), LedCheckBox::Green ); + ToolTip::add( filtEnabledToggle[i], tr( "This button enables the filter. A disabled filter will never do anything and does not use any CPU. In many cases, the settings of a disabled filter will not be saved, so be careful!" ) ); + + filtKeytrackingToggle[i] = new LedCheckBox( "", this, tr( "Keytracking" ), LedCheckBox::Green ); + ToolTip::add( filtKeytrackingToggle[i], tr( "When this is enabled, the delay of the filter's feedback changes to match the frequency of the notes you play." ) ); + + filtMutedToggle[i] = new LedCheckBox( "", this, tr( "Muted" ), LedCheckBox::Green ); + ToolTip::add( filtMutedToggle[i], tr( "This button mutes the filter. An enabled but muted filter will still use CPU and still work as a matrix input, but will not be sent to the audio output. You'll want to use this almost every time you send something to the Matrix." ) ); + } + + for( int i = 0; i < 18; ++i ) + { + makeknob( macroKnob[i], knobSmallColored, tr( "Macro" ) + " " + QString::number(i+1) + ":", tr( "Macro %1: " ).arg( i + 1 ) + tr( "This knob's value can be used in the Matrix to control many values at the same time, at different amounts. This is immensely useful for crafting great presets." ) ); + } + + makeknob( subVolKnob, knobColored, tr( "Volume" ), tr( "This knob, as you probably expected, controls the volume." ) ); + + makeknob( subPhaseKnob, knobSmallColored, tr( "Phase" ), tr( "This knob changes the phase (starting position) of the oscillator." ) ); + + makeknob( subPhaseRandKnob, knobSmallColored, tr( "Phase Randomness" ), tr( "This knob chooses a random phase for every note. The phase change will never be larger than this knob's value." ) ); + + makeknob( subDetuneKnob, knobColored, tr( "Detune" ), tr( "This knob changes the pitch of the oscillator." ) ); + + makeknob( subSampLenKnob, knobColored, tr( "Waveform Sample Length" ), tr( "This knob changes the waveform length, which you can see in the graph." ) ); + + makeknob( subPanningKnob, knobColored, tr( "Panning" ), tr( "This knob lowers the volume in one ear by an amount depending on this knob's value." ) ); + + makeknob( subTempoKnob, knobColored, tr( "Tempo Sync" ), tr( "When this knob is anything other than 0, the oscillator is tempo synced to the specified tempo. This is meant for the creation of envelopes/LFOs/step sequencers in the Matrix tab, and you'll most likely want to enable the Muted LED when using this." ) ); + + makeknob( subRateLimitKnob, knobColored, tr( "Rate Limit" ), tr( "This knob limits the rate at which the waveform can change. Combined with the Noise LED being enabled, this could potentially be used as a chaos oscillator." ) ); + + makeknob( subUnisonNumKnob, knobColored, tr( "Unison Voices" ), tr( "This knob clones this oscillator multiple times depending on its value, and makes slight changes to the clones depending on the other unison-related knobs." ) ); + + makeknob( subUnisonDetuneKnob, knobColored, tr( "Unison Detune" ), tr( "This knob detunes every unison voice by a random number that is less than the specified amount." ) ); + + subEnabledToggle = new LedCheckBox( "", this, tr( "Enabled" ), LedCheckBox::Green ); + ToolTip::add( subEnabledToggle, tr( "This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!" ) ); + + subMutedToggle = new LedCheckBox( "", this, tr( "Muted" ), LedCheckBox::Green ); + ToolTip::add( subMutedToggle, tr( "This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output." ) ); + + subKeytrackToggle = new LedCheckBox( "", this, tr( "Keytracking Enabled" ), LedCheckBox::Green ); + ToolTip::add( subKeytrackToggle, tr( "This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound." ) ); + + subNoiseToggle = new LedCheckBox( "", this, tr( "Noise Enabled" ), LedCheckBox::Green ); + ToolTip::add( subNoiseToggle, tr( "This button converts this oscillator into a noise generator. A random part of the graph is chosen, that value is added to the previous output in the same direction it was going, and when the waveform crosses the top or bottom, the direction changes." ) ); + + subInterpolateToggle = new LedCheckBox( "", this, tr( "Interpolation Enabled" ), LedCheckBox::Green ); + ToolTip::add( subInterpolateToggle, tr( "This button turns sinc interpolation on/off. Interpolation uses no CPU and makes the oscillator super duper high-quality. You'll probably only ever want to turn this off when you're using small waveform lengths and you don't want the waveform smoothed over." ) ); + + for( int i = 0; i < 8; ++i ) + { + makeknob( modInAmntKnob[i], knobSmallColored, tr( "Matrix Input Amount" ), tr( "This knob controls how much of the input to send to the output." ) ); + + makeknob( modInCurveKnob[i], knobSmallColored, tr( "Matrix Curve Amount" ), tr( "This knob gives the input value a bias toward the top or bottom" ) ); + + makeknob( modInAmntKnob2[i], knobSmallColored, tr( "Secondary Matrix Input Amount" ), tr( "This knob controls how much of the input to send to the output." ) ); + + makeknob( modInCurveKnob2[i], knobSmallColored, tr( "Secondary Matrix Curve Amount" ), tr( "This knob gives the input value a bias toward the top or bottom" ) ); + + modOutSecBox[i] = new ComboBox( this ); + modOutSecBox[i]->setGeometry( 2000, 5, 42, 22 ); + modOutSecBox[i]->setFont( pointSize<8>( modOutSecBox[i]->font() ) ); + ToolTip::add( modOutSecBox[i], tr( "This dropdown box chooses an output for the Matrix Box." ) ); + + modOutSigBox[i] = new ComboBox( this ); + modOutSigBox[i]->setGeometry( 2000, 5, 42, 22 ); + modOutSigBox[i]->setFont( pointSize<8>( modOutSigBox[i]->font() ) ); + ToolTip::add( modOutSigBox[i], tr( "This dropdown box chooses which part of the input to send to the Matrix Box (e.g. which parameter to control, which filter, etc.)." ) ); + + modOutSecNumBox[i] = new LcdSpinBox( 2, "microwave", this, "Mod Output Number" ); + ToolTip::add( modOutSecNumBox[i], tr( "This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator)." ) ); + + modInBox[i] = new ComboBox( this ); + modInBox[i]->setGeometry( 2000, 5, 42, 22 ); + modInBox[i]->setFont( pointSize<8>( modInBox[i]->font() ) ); + ToolTip::add( modInBox[i], tr( "This dropdown box chooses an input for the Matrix Box." ) ); + + modInNumBox[i] = new LcdSpinBox( 2, "microwave", this, "Mod Input Number" ); + ToolTip::add( modInNumBox[i], tr( "This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator, which filter, etc.)." ) ); + + modInBox2[i] = new ComboBox( this ); + modInBox2[i]->setGeometry( 2000, 5, 42, 22 ); + modInBox2[i]->setFont( pointSize<8>( modInBox2[i]->font() ) ); + ToolTip::add( modInBox2[i], tr( "This dropdown box chooses an input for the Matrix Box." ) ); + + modInNumBox2[i] = new LcdSpinBox( 2, "microwave", this, "Secondary Mod Input Number" ); + ToolTip::add( modInNumBox2[i], tr( "This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator, which filter, etc.)." ) ); + + modEnabledToggle[i] = new LedCheckBox( "", this, tr( "Modulation Enabled" ), LedCheckBox::Green ); + ToolTip::add( modEnabledToggle[i], tr( "This button enables the Matrix Box. While disabled, this does not use CPU." ) ); + + modCombineTypeBox[i] = new ComboBox( this ); + modCombineTypeBox[i]->setGeometry( 2000, 5, 42, 22 ); + modCombineTypeBox[i]->setFont( pointSize<8>( modCombineTypeBox[i]->font() ) ); + ToolTip::add( modCombineTypeBox[i], tr( "This dropdown box chooses how to combine the two Matrix inputs." ) ); + + modTypeToggle[i] = new LedCheckBox( "", this, tr( "Envelope Enabled" ), LedCheckBox::Green ); + ToolTip::add( modTypeToggle[i], tr( "This button, when enabled, treats the input as an envelope rather than an LFO." ) ); + + modType2Toggle[i] = new LedCheckBox( "", this, tr( "Envelope Enabled" ), LedCheckBox::Green ); + ToolTip::add( modType2Toggle[i], tr( "This button, when enabled, treats the input as an envelope rather than an LFO." ) ); + + modUpArrow[i] = new PixmapButton( this, tr( "Move Matrix Section Up" ) ); + modUpArrow[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); + modUpArrow[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); + ToolTip::add( modUpArrow[i], tr( "Move this Matrix Box up" ) ); + + modDownArrow[i] = new PixmapButton( this, tr( "Move Matrix Section Down" ) ); + modDownArrow[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); + modDownArrow[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); + ToolTip::add( modDownArrow[i], tr( "Move this Matrix Box down" ) ); + + i1Button[i] = new PixmapButton( this, tr( "Go to this input's location" ) ); + i1Button[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "i1_button" ) ); + i1Button[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "i1_button" ) ); + ToolTip::add( i1Button[i], tr( "Go to this input's location" ) ); + + i2Button[i] = new PixmapButton( this, tr( "Go to this input's location" ) ); + i2Button[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "i2_button" ) ); + i2Button[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "i2_button" ) ); + ToolTip::add( i2Button[i], tr( "Go to this input's location" ) ); + + modNumText[i] = new QLineEdit(this); + modNumText[i]->resize(23, 19); + } + + makeknob( visvolKnob, knobSmallColored, tr( "Visualizer Volume" ), tr( "This knob works as a vertical zoom knob for the visualizer." ) ); + + makeknob( loadChnlKnob, knobColored, tr( "Wavetable Loading Channel" ), tr( "This knob chooses whether to load the left or right audio of the selected sample/wavetable." ) ); + + + graph = new Graph( this, Graph::BarCenterGradStyle, 204, 134 ); + graph->setAutoFillBackground( true ); + graph->setGraphColor( QColor( 121, 222, 239 ) ); + + ToolTip::add( graph, tr ( "Draw here by dragging your mouse on this graph." ) ); + + pal = QPalette(); + pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap("wavegraph") ); + graph->setPalette( pal ); + + QPixmap filtForegroundImg = PLUGIN_NAME::getIconPixmap("filterForeground"); + filtForegroundLabel = new QLabel(this); + filtForegroundLabel->setPixmap(filtForegroundImg); + filtForegroundLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); + + QPixmap matrixForegroundImg = PLUGIN_NAME::getIconPixmap("matrixForeground"); + matrixForegroundLabel = new QLabel(this); + matrixForegroundLabel->setPixmap(matrixForegroundImg); + matrixForegroundLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); + + sinWaveBtn = new PixmapButton( this, tr( "Sine" ) ); + sinWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave_active" ) ); + sinWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave" ) ); + ToolTip::add( sinWaveBtn, tr( "Sine wave" ) ); + + triangleWaveBtn = new PixmapButton( this, tr( "Nachos" ) ); + triangleWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave_active" ) ); + triangleWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave" ) ); + ToolTip::add( triangleWaveBtn, tr( "Nacho wave" ) ); + + sawWaveBtn = new PixmapButton( this, tr( "Sawsa" ) ); + sawWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave_active" ) ); + sawWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave" ) ); + ToolTip::add( sawWaveBtn, tr( "Sawsa wave" ) ); + + sqrWaveBtn = new PixmapButton( this, tr( "Sosig" ) ); + sqrWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave_active" ) ); + sqrWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave" ) ); + ToolTip::add( sqrWaveBtn, tr( "Sosig wave" ) ); + + whiteNoiseWaveBtn = new PixmapButton( this, tr( "Metal Fork" ) ); + whiteNoiseWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave_active" ) ); + whiteNoiseWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave" ) ); + ToolTip::add( whiteNoiseWaveBtn, tr( "Metal Fork" ) ); + + usrWaveBtn = new PixmapButton( this, tr( "Takeout" ) ); + usrWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + usrWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + ToolTip::add( usrWaveBtn, tr( "Takeout Menu" ) ); + + smoothBtn = new PixmapButton( this, tr( "Microwave Cover" ) ); + smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave_active" ) ); + smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave" ) ); + ToolTip::add( smoothBtn, tr( "Microwave Cover" ) ); + + + sinWave2Btn = new PixmapButton( this, tr( "Sine" ) ); + sinWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave_active" ) ); + sinWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave" ) ); + ToolTip::add( sinWave2Btn, tr( "Sine wave" ) ); + + triangleWave2Btn = new PixmapButton( this, tr( "Nachos" ) ); + triangleWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave_active" ) ); + triangleWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave" ) ); + ToolTip::add( triangleWave2Btn, + tr( "Nacho wave" ) ); + + sawWave2Btn = new PixmapButton( this, tr( "Sawsa" ) ); + sawWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave_active" ) ); + sawWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave" ) ); + ToolTip::add( sawWave2Btn, + tr( "Sawsa wave" ) ); + + sqrWave2Btn = new PixmapButton( this, tr( "Sosig" ) ); + sqrWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave_active" ) ); + sqrWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave" ) ); + ToolTip::add( sqrWave2Btn, tr( "Sosig wave" ) ); + + whiteNoiseWave2Btn = new PixmapButton( this, tr( "Metal Fork" ) ); + whiteNoiseWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave_active" ) ); + whiteNoiseWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave" ) ); + ToolTip::add( whiteNoiseWave2Btn, tr( "Metal Fork" ) ); + + usrWave2Btn = new PixmapButton( this, tr( "Takeout Menu" ) ); + usrWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + usrWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + ToolTip::add( usrWave2Btn, tr( "Takeout Menu" ) ); + + smooth2Btn = new PixmapButton( this, tr( "Microwave Cover" ) ); + smooth2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave_active" ) ); + smooth2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave" ) ); + ToolTip::add( smooth2Btn, tr( "Microwave Cover" ) ); + + + tab1Btn = new PixmapButton( this, tr( "Wavetable Tab" ) ); + tab1Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); + tab1Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); + ToolTip::add( tab1Btn, tr( "Wavetable Tab" ) ); + + tab2Btn = new PixmapButton( this, tr( "Sub Tab" ) ); + tab2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); + tab2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); + ToolTip::add( tab2Btn, tr( "Sub Tab" ) ); + + tab3Btn = new PixmapButton( this, tr( "Sample Tab" ) ); + tab3Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); + tab3Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); + ToolTip::add( tab3Btn, tr( "Sample Tab" ) ); + + tab4Btn = new PixmapButton( this, tr( "Matrix Tab" ) ); + tab4Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); + tab4Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); + ToolTip::add( tab4Btn, tr( "Matrix Tab" ) ); + + tab5Btn = new PixmapButton( this, tr( "Effect Tab" ) ); + tab5Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); + tab5Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); + ToolTip::add( tab5Btn, tr( "Effect Tab" ) ); + + tab6Btn = new PixmapButton( this, tr( "Miscellaneous Tab" ) ); + tab6Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); + tab6Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); + ToolTip::add( tab6Btn, tr( "Miscellaneous Tab" ) ); + + + mainFlipBtn = new PixmapButton( this, tr( "Flip to other knobs" ) ); + mainFlipBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); + mainFlipBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); + ToolTip::add( mainFlipBtn, tr( "Flip to other knobs" ) ); + mainFlipBtn->setCheckable(true); + + subFlipBtn = new PixmapButton( this, tr( "Flip to other knobs" ) ); + subFlipBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); + subFlipBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); + ToolTip::add( subFlipBtn, tr( "Flip to other knobs" ) ); + subFlipBtn->setCheckable(true); + + + manualBtn = new PixmapButton( this, tr( "Manual" ) ); + manualBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "manual_active" ) ); + manualBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "manual_inactive" ) ); + ToolTip::add( manualBtn, tr( "Manual" ) ); + + + removeDCBtn = new PixmapButton( this, tr( "Remove DC Offset" ) ); + removeDCBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "remove_dc_offset_button_enabled" ) ); + removeDCBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "remove_dc_offset_button_disabled" ) ); + ToolTip::add( removeDCBtn, tr( "Remove DC Offset" ) ); + removeDCBtn->setCheckable(true); + + oversampleModeBox = new ComboBox( this ); + oversampleModeBox->setGeometry( 0, 0, 42, 22 ); + oversampleModeBox->setFont( pointSize<8>( oversampleModeBox->font() ) ); + + + normalizeBtn = new PixmapButton( this, tr( "Normalize Wavetable" ) ); + normalizeBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "normalize_button_active" ) ); + normalizeBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "normalize_button" ) ); + ToolTip::add( normalizeBtn, tr( "Normalize Wavetable" ) ); + + desawBtn = new PixmapButton( this, tr( "De-saw Wavetable" ) ); + desawBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "desaw_button_active" ) ); + desawBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "desaw_button" ) ); + ToolTip::add( desawBtn, tr( "De-saw Wavetable" ) ); + + + XBtn = new PixmapButton( this, tr( "Leave wavetable loading section" ) ); + XBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); + XBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); + ToolTip::add( XBtn, tr( "Leave wavetable loading tab" ) ); + + MatrixXBtn = new PixmapButton( this, tr( "Leave Matrix tab" ) ); + MatrixXBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); + MatrixXBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); + ToolTip::add( MatrixXBtn, tr( "Leave wavetable loading tab" ) ); + + + visualizeToggle = new LedCheckBox( "", this, tr( "Visualize" ), LedCheckBox::Green ); + + openWavetableButton = new PixmapButton( this ); + openWavetableButton->setCursor( QCursor( Qt::PointingHandCursor ) ); + openWavetableButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + openWavetableButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + connect( openWavetableButton, SIGNAL( clicked() ), this, SLOT( openWavetableFileBtnClicked() ) ); + ToolTip::add( openWavetableButton, tr( "Open wavetable" ) ); + + confirmLoadButton = new PixmapButton( this ); + confirmLoadButton->setCursor( QCursor( Qt::PointingHandCursor ) ); + confirmLoadButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "confirm_button_active" ) ); + confirmLoadButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "confirm_button_inactive" ) ); + connect( confirmLoadButton, SIGNAL( clicked() ), this, SLOT( confirmWavetableLoadClicked() ) ); + ToolTip::add( confirmLoadButton, tr( "Load Wavetable" ) ); + + subNumBox = new LcdSpinBox( 2, "microwave", this, "Sub Oscillator Number" ); + + sampNumBox = new LcdSpinBox( 2, "microwave", this, "Sample Number" ); + + mainNumBox = new LcdSpinBox( 2, "microwave", this, "Oscillator Number" ); + + oversampleBox = new ComboBox( this ); + oversampleBox->setGeometry( 0, 0, 42, 22 ); + oversampleBox->setFont( pointSize<8>( oversampleBox->font() ) ); + + loadModeBox = new ComboBox( this ); + loadModeBox->setGeometry( 0, 0, 202, 22 ); + loadModeBox->setFont( pointSize<8>( loadModeBox->font() ) ); + + openSampleButton = new PixmapButton( this ); + openSampleButton->setCursor( QCursor( Qt::PointingHandCursor ) ); + openSampleButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + openSampleButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + + effectScrollBar = new QScrollBar( Qt::Vertical, this ); + effectScrollBar->setSingleStep( 1 ); + effectScrollBar->setPageStep( 100 ); + effectScrollBar->setFixedHeight( 197 ); + effectScrollBar->setRange( 0, 590 ); + connect( effectScrollBar, SIGNAL( valueChanged( int ) ), this, SLOT( updateScroll( ) ) ); + + effectScrollBar->setStyleSheet("QScrollBar::handle:horizontal { background: #3f4750; border: none; border-radius: 1px; min-width: 24px; }\ + QScrollBar::handle:horizontal:hover { background: #a6adb1; }\ + QScrollBar::handle:horizontal:pressed { background: #a6adb1; }\ + QScrollBar::handle:vertical { background: #3f4750; border: none; border-radius: 1px; min-height: 24px; }\ + QScrollBar::handle:vertical:hover { background: #a6adb1; }\ + QScrollBar::handle:vertical:pressed { background: #a6adb1; }\ + QScrollBar::handle:horizontal:disabled, QScrollBar::handle:vertical:disabled { background: #262b30; border-radius: 1px; border: none; }"); + + matrixScrollBar = new QScrollBar( Qt::Vertical, this ); + matrixScrollBar->setSingleStep( 1 ); + matrixScrollBar->setPageStep( 100 ); + matrixScrollBar->setFixedHeight( 197 ); + matrixScrollBar->setRange( 0, 6232 ); + connect( matrixScrollBar, SIGNAL( valueChanged( int ) ), this, SLOT( updateScroll( ) ) ); + + matrixScrollBar->setStyleSheet("QScrollBar::handle:horizontal { background: #3f4750; border: none; border-radius: 1px; min-width: 24px; }\ + QScrollBar::handle:horizontal:hover { background: #a6adb1; }\ + QScrollBar::handle:horizontal:pressed { background: #a6adb1; }\ + QScrollBar::handle:vertical { background: #3f4750; border: none; border-radius: 1px; min-height: 24px; }\ + QScrollBar::handle:vertical:hover { background: #a6adb1; }\ + QScrollBar::handle:vertical:pressed { background: #a6adb1; }\ + QScrollBar::handle:horizontal:disabled, QScrollBar::handle:vertical:disabled { background: #262b30; border-radius: 1px; border: none; }"); + + // The above scrollbar style changes don't seem to work entirely for some reason. + + + connect( openSampleButton, SIGNAL( clicked() ), this, SLOT( openSampleFileBtnClicked() ) ); + ToolTip::add( openSampleButton, tr( "Open sample" ) ); + + + + connect( sinWaveBtn, SIGNAL (clicked () ), this, SLOT ( sinWaveClicked() ) ); + connect( triangleWaveBtn, SIGNAL ( clicked () ), this, SLOT ( triangleWaveClicked() ) ); + connect( sawWaveBtn, SIGNAL (clicked () ), this, SLOT ( sawWaveClicked() ) ); + connect( sqrWaveBtn, SIGNAL ( clicked () ), this, SLOT ( sqrWaveClicked() ) ); + connect( whiteNoiseWaveBtn, SIGNAL ( clicked () ), this, SLOT ( noiseWaveClicked() ) ); + connect( usrWaveBtn, SIGNAL ( clicked () ), this, SLOT ( usrWaveClicked() ) ); + connect( smoothBtn, SIGNAL ( clicked () ), this, SLOT ( smoothClicked() ) ); + + connect( sinWave2Btn, SIGNAL (clicked () ), this, SLOT ( sinWaveClicked() ) ); + connect( triangleWave2Btn, SIGNAL ( clicked () ), this, SLOT ( triangleWaveClicked() ) ); + connect( sawWave2Btn, SIGNAL (clicked () ), this, SLOT ( sawWaveClicked() ) ); + connect( sqrWave2Btn, SIGNAL ( clicked () ), this, SLOT ( sqrWaveClicked() ) ); + connect( whiteNoiseWave2Btn, SIGNAL ( clicked () ), this, SLOT ( noiseWaveClicked() ) ); + connect( usrWave2Btn, SIGNAL ( clicked () ), this, SLOT ( usrWaveClicked() ) ); + connect( smooth2Btn, SIGNAL ( clicked () ), this, SLOT ( smoothClicked() ) ); + + + connect( XBtn, SIGNAL (clicked () ), this, SLOT ( XBtnClicked() ) ); + connect( MatrixXBtn, SIGNAL (clicked () ), this, SLOT ( MatrixXBtnClicked() ) ); + + connect( normalizeBtn, SIGNAL (clicked () ), this, SLOT ( normalizeClicked() ) ); + connect( desawBtn, SIGNAL (clicked () ), this, SLOT ( desawClicked() ) ); + + + // This is a mess, but for some reason just entering a number without a variable didn't work... + int ii = 0; + connect( tab1Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + ii = 1; + connect( tab2Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + ii = 2; + connect( tab3Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + ii = 3; + connect( tab4Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + ii = 4; + connect( tab5Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + ii = 5; + connect( tab6Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + + + connect( mainFlipBtn, SIGNAL (clicked () ), this, SLOT ( flipperClicked() ) ); + connect( subFlipBtn, SIGNAL (clicked () ), this, SLOT ( flipperClicked() ) ); + + connect( visualizeToggle, SIGNAL( toggled( bool ) ), this, SLOT ( visualizeToggled( bool ) ) ); + + connect( &b->mainNum, SIGNAL( dataChanged( ) ), this, SLOT( mainNumChanged( ) ) ); + connect( &b->subNum, SIGNAL( dataChanged( ) ), this, SLOT( subNumChanged( ) ) ); + connect( &b->sampNum, SIGNAL( dataChanged( ) ), this, SLOT( sampNumChanged( ) ) ); + + connect( manualBtn, SIGNAL (clicked ( bool ) ), this, SLOT ( manualBtnClicked() ) ); + + for( int i = 0; i < 64; ++i ) + { + connect( b->modOutSec[i], &ComboBoxModel::dataChanged, this, [this, i]() { modOutSecChanged(i); }, Qt::DirectConnection ); + connect( b->modIn[i], &ComboBoxModel::dataChanged, this, [this, i]() { modInChanged(i); }, Qt::DirectConnection ); + connect( b->modIn2[i], &ComboBoxModel::dataChanged, this, [this, i]() { modIn2Changed(i); }, Qt::DirectConnection ); + + connect( b->modEnabled[i], &BoolModel::dataChanged, this, [this, i]() { modEnabledChanged(); } ); + } + + for( int i = 0; i < 8; ++i ) + { + connect( modUpArrow[i], &PixmapButton::clicked, this, [this, i]() { modUpClicked(i); } ); + connect( modDownArrow[i], &PixmapButton::clicked, this, [this, i]() { modDownClicked(i); } ); + + connect( i1Button[i], &PixmapButton::clicked, this, [this, i]() { i1Clicked(i); } ); + connect( i2Button[i], &PixmapButton::clicked, this, [this, i]() { i2Clicked(i); } ); + + //Make changing Enabled LED update graph color + connect( b->enabled[i], SIGNAL( dataChanged( ) ), this, SLOT( mainNumChanged( ) ) ); + connect( b->subEnabled[i], SIGNAL( dataChanged( ) ), this, SLOT( subNumChanged( ) ) ); + connect( b->sampleEnabled[i], SIGNAL( dataChanged( ) ), this, SLOT( sampNumChanged( ) ) ); + } + + for( int i = 0; i < 18; ++i ) + { + if( !b->macroTooltips[i].isEmpty() ) + { + ToolTip::add( macroKnob[i], tr( "Macro %1: " ).arg( i + 1 ) + b->macroTooltips[i] ); + } + + macroKnob[i]->refreshMacroColor(); + } + + b->viewOpen = true; + + updateScroll(); + updateBackground(); + + modEnabledChanged();// Updates scroll bar length in Matrix +} + + +MicrowaveView::~MicrowaveView() +{ + // This got mad when using the vairable "b". + if( castModel() ) { castModel()->viewOpen = false; } +} + + +// Connects knobs/GUI elements to their models +void MicrowaveView::modelChanged() +{ + graph->setModel( &b->graph ); + visvolKnob->setModel( &b->visvol ); + visualizeToggle->setModel( &b->visualize ); + subNumBox->setModel( &b->subNum ); + sampNumBox->setModel( &b->sampNum ); + loadChnlKnob->setModel( &b->loadChnl ); + mainNumBox->setModel( &b->mainNum ); + oversampleBox->setModel( &b->oversample ); + loadModeBox->setModel( &b->loadMode ); + mainFlipBtn->setModel( &b->mainFlipped ); + subFlipBtn->setModel( &b->subFlipped ); + removeDCBtn->setModel( &b->removeDC ); + oversampleModeBox->setModel( &b->oversampleMode ); +} + + +// If you think you've seen ugly workarounds before, you haven't seen anything yet. +// A very old version of Microwave included the GUI elements visually moving left/right. +// Because of that, the GUI elements were just moved off of the screen rather than having their visibility toggled. +// It is because of this that I traded out the move function with visimove, which prevents the GUI elements from +// leaving the 250x250 GUI, and instead toggles their visibility if they try to leave, in case of things checking for the +// bounds of the GUI elements (e.g. instrument window resizing). +void MicrowaveView::updateScroll() +{ + int scrollVal = ( b->scroll ) * 250.f; + int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int effectScrollVal = ( effectScrollBar->value() ) / 100.f * 92.f; + int mainFlipped = b->mainFlipped.value(); + int subFlipped = b->subFlipped.value(); + + int mainIsFlipped = mainFlipped * 500.f; + int mainIsNotFlipped = !mainFlipped * 500.f; + int subIsFlipped = subFlipped * 500.f; + int subIsNotFlipped = !subFlipped * 500.f; + + visimove( morphKnob, ( scrollVal < 250 ? 23 : 1500 + 176 ) - scrollVal, 172 + mainIsFlipped ); + visimove( rangeKnob, ( scrollVal < 250 ? 55 : 1500 + 208 ) - scrollVal, 172 + mainIsFlipped ); + visimove( modifyKnob, 87 - scrollVal, 172 + mainIsFlipped ); + visimove( modifyModeBox, 127 - scrollVal, 186 + mainIsFlipped ); + visimove( volKnob, 23 - scrollVal, 172 + mainIsNotFlipped ); + visimove( panKnob, 55 - scrollVal, 172 + mainIsNotFlipped ); + visimove( detuneKnob, 152 - scrollVal, 216 + mainIsFlipped ); + visimove( phaseKnob, 184 - scrollVal, 203 + mainIsNotFlipped ); + visimove( phaseRandKnob, 209 - scrollVal, 203 + mainIsNotFlipped ); + visimove( enabledToggle, 85 - scrollVal, 229 ); + visimove( mutedToggle, 103 - scrollVal, 229 ); + visimove( sampLenKnob, 137 - scrollVal, 172 + mainIsNotFlipped ); + visimove( morphMaxKnob, 101 - scrollVal, 172 + mainIsNotFlipped ); + visimove( unisonVoicesKnob, 184 - scrollVal, 172 ); + visimove( unisonDetuneKnob, 209 - scrollVal, 172 ); + visimove( unisonMorphKnob, 184 - scrollVal, 203 + mainIsFlipped ); + visimove( unisonModifyKnob, 209 - scrollVal, 203 + mainIsFlipped ); + visimove( keytrackingToggle, 121 - scrollVal, 229 + mainIsFlipped ); + visimove( tempoKnob, 152 - scrollVal, 216 + mainIsNotFlipped ); + visimove( interpolateToggle, 121 - scrollVal, 229 + mainIsNotFlipped ); + + visimove( sampleEnabledToggle, 85 + 500 - scrollVal, 229 ); + visimove( sampleMutedToggle, 103 + 500 - scrollVal, 229 ); + visimove( sampleKeytrackingToggle, 121 + 500 - scrollVal, 229 ); + visimove( sampleGraphEnabledToggle, 138 + 500 - scrollVal, 229 ); + visimove( sampleLoopToggle, 155 + 500 - scrollVal, 229 ); + visimove( sampleVolumeKnob, 23 + 500 - scrollVal, 172 ); + visimove( samplePanningKnob, 55 + 500 - scrollVal, 172 ); + visimove( sampleDetuneKnob, 93 + 500 - scrollVal, 172 ); + visimove( samplePhaseKnob, 180 + 500 - scrollVal, 172 ); + visimove( samplePhaseRandKnob, 206 + 500 - scrollVal, 172 ); + visimove( sampleStartKnob, 121 + 500 - scrollVal, 172 ); + visimove( sampleEndKnob, 145 + 500 - scrollVal, 172 ); + + for( int i = 0; i < 8; ++i ) + { + visimove( filtCutoffKnob[i], 32 + 1000 - scrollVal, i*92+55 - effectScrollVal ); + visimove( filtResoKnob[i], 63 + 1000 - scrollVal, i*92+55 - effectScrollVal ); + visimove( filtGainKnob[i], 94 + 1000 - scrollVal, i*92+55 - effectScrollVal ); + + visimove( filtTypeBox[i], 128 + 1000 - scrollVal, i*92+63 - effectScrollVal ); + visimove( filtSlopeBox[i], 171 + 1000 - scrollVal, i*92+63 - effectScrollVal ); + visimove( filtInVolKnob[i], 30 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtOutVolKnob[i], 55 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtWetDryKnob[i], 80 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtBalKnob[i], 105 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtSatuKnob[i], 135 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtFeedbackKnob[i], 167 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtDetuneKnob[i], 192 + 1000 - scrollVal, i*92+91 - effectScrollVal ); + visimove( filtEnabledToggle[i], 27 + 1000 - scrollVal, i*92+36 - effectScrollVal ); + visimove( filtMutedToggle[i], 166 + 1000 - scrollVal, i*92+36 - effectScrollVal ); + visimove( filtKeytrackingToggle[i], 200 + 1000 - scrollVal, i*92+36 - effectScrollVal ); + } + + visimove( subVolKnob, 23 + 250 - scrollVal, 172 + subIsFlipped ); + visimove( subPanningKnob, 55 + 250 - scrollVal, 172 + subIsFlipped ); + visimove( subDetuneKnob, 95 + 250 - scrollVal, 172 + subIsFlipped ); + visimove( subPhaseKnob, 180 + 250 - scrollVal, 172 ); + visimove( subPhaseRandKnob, 206 + 250 - scrollVal, 172 ); + visimove( subSampLenKnob, 130 + 250 - scrollVal, 172 + subIsFlipped ); + visimove( subTempoKnob, 23 + 250 - scrollVal, 172 + subIsNotFlipped ); + visimove( subRateLimitKnob, 55 + 250 - scrollVal, 172 + subIsNotFlipped ); + visimove( subUnisonNumKnob, 95 + 250 - scrollVal, 172 + subIsNotFlipped ); + visimove( subUnisonDetuneKnob, 130 + 250 - scrollVal, 172 + subIsNotFlipped ); + + if( subIsNotFlipped ) + { + visimove( subEnabledToggle, 85 + 250 - scrollVal, 229 ); + visimove( subMutedToggle, 103 + 250 - scrollVal, 229 ); + visimove( subKeytrackToggle, 121 + 250 - scrollVal, 229 ); + visimove( subNoiseToggle, 138 + 250 - scrollVal, 229 ); + visimove( subInterpolateToggle, 155 + 250 - scrollVal, 229 ); + } + else + { + visimove( subEnabledToggle, 85 + 250 - scrollVal, 235 ); + visimove( subMutedToggle, 103 + 250 - scrollVal, 235 ); + visimove( subKeytrackToggle, 121 + 250 - scrollVal, 235 ); + visimove( subNoiseToggle, 138 + 250 - scrollVal, 235 ); + visimove( subInterpolateToggle, 155 + 250 - scrollVal, 235 ); + } + + int matrixRemainder = modScrollVal % 460; + int matrixDivide = modScrollVal / 460 * 4; + for( int i = 0; i < 8; ++i ) + { + if( i+matrixDivide < 64 ) + { + modOutSecBox[i]->setModel( b->modOutSec[i+matrixDivide] ); + modOutSigBox[i]->setModel( b->modOutSig[i+matrixDivide] ); + modOutSecNumBox[i]->setModel( b->modOutSecNum[i+matrixDivide] ); + + modInBox[i]->setModel( b->modIn[i+matrixDivide] ); + modInNumBox[i]->setModel( b->modInNum[i+matrixDivide] ); + modInAmntKnob[i]->setModel( b->modInAmnt[i+matrixDivide] ); + modInCurveKnob[i]->setModel( b->modInCurve[i+matrixDivide] ); + + modInBox2[i]->setModel( b->modIn2[i+matrixDivide] ); + modInNumBox2[i]->setModel( b->modInNum2[i+matrixDivide] ); + modInAmntKnob2[i]->setModel( b->modInAmnt2[i+matrixDivide] ); + modInCurveKnob2[i]->setModel( b->modInCurve2[i+matrixDivide] ); + + modEnabledToggle[i]->setModel( b->modEnabled[i+matrixDivide] ); + + modCombineTypeBox[i]->setModel( b->modCombineType[i+matrixDivide] ); + + modTypeToggle[i]->setModel( b->modType[i+matrixDivide] ); + modType2Toggle[i]->setModel( b->modType2[i+matrixDivide] ); + + modNumText[i]->setText( QString::number(i+matrixDivide+1) ); + + modInAmntKnob[i]->setMatrixLocation( 4, 1, i ); + modInCurveKnob[i]->setMatrixLocation( 4, 2, i ); + modInAmntKnob2[i]->setMatrixLocation( 4, 3, i ); + modInCurveKnob2[i]->setMatrixLocation( 4, 4, i ); + } + + // Bug evasion. Without this, some display glitches happen in certain conditions. + modOutSecChanged( i+matrixDivide ); + modInChanged( i+matrixDivide ); + modIn2Changed( i+matrixDivide ); + + visimove( modInBox[i], 45 + 750 - scrollVal, i*115+57 - matrixRemainder ); + visimove( modInNumBox[i], 90 + 750 - scrollVal, i*115+57 - matrixRemainder ); + visimove( modInAmntKnob[i], 136 + 750 - scrollVal, i*115+53 - matrixRemainder ); + visimove( modInCurveKnob[i], 161 + 750 - scrollVal, i*115+53 - matrixRemainder ); + visimove( modInBox2[i], 45 + 750 - scrollVal, i*115+118 - matrixRemainder ); + visimove( modInNumBox2[i], 90 + 750 - scrollVal, i*115+118 - matrixRemainder ); + visimove( modInAmntKnob2[i], 136 + 750 - scrollVal, i*115+114 - matrixRemainder ); + visimove( modInCurveKnob2[i], 161 + 750 - scrollVal, i*115+114 - matrixRemainder ); + visimove( modOutSecBox[i], 27 + 750 - scrollVal, i*115+88 - matrixRemainder ); + visimove( modOutSigBox[i], 69 + 750 - scrollVal, i*115+88 - matrixRemainder ); + visimove( modOutSecNumBox[i], 112 + 750 - scrollVal, i*115+88 - matrixRemainder ); + visimove( modEnabledToggle[i], 27 + 750 - scrollVal, i*115+36 - matrixRemainder ); + visimove( modCombineTypeBox[i], 149 + 750 - scrollVal, i*115+88 - matrixRemainder ); + visimove( modTypeToggle[i], 195 + 750 - scrollVal, i*115+67 - matrixRemainder ); + visimove( modType2Toggle[i], 195 + 750 - scrollVal, i*115+128 - matrixRemainder ); + visimove( modUpArrow[i], 181 + 750 - scrollVal, i*115+37 - matrixRemainder ); + visimove( modDownArrow[i], 199 + 750 - scrollVal, i*115+37 - matrixRemainder ); + visimove( i1Button[i], 25 + 750 - scrollVal, i*115+50 - matrixRemainder ); + visimove( i2Button[i], 25 + 750 - scrollVal, i*115+112 - matrixRemainder ); + visimove( modNumText[i], 192 + 750 - scrollVal, i*115+89 - matrixRemainder ); + } + + for( int i = 0; i < 8; ++i ) + { + filtCutoffKnob[i]->setModel( b->filtCutoff[i] ); + filtCutoffKnob[i]->setMatrixLocation( 6, 1, i ); + + filtResoKnob[i]->setModel( b->filtReso[i] ); + filtResoKnob[i]->setMatrixLocation( 6, 2, i ); + + filtGainKnob[i]->setModel( b->filtGain[i] ); + filtGainKnob[i]->setMatrixLocation( 6, 3, i ); + + filtTypeBox[i]->setModel( b->filtType[i] ); + + filtSlopeBox[i]->setModel( b->filtSlope[i] ); + + filtInVolKnob[i]->setModel( b->filtInVol[i] ); + filtInVolKnob[i]->setMatrixLocation( 6, 5, i ); + + filtOutVolKnob[i]->setModel( b->filtOutVol[i] ); + filtOutVolKnob[i]->setMatrixLocation( 6, 6, i ); + + filtWetDryKnob[i]->setModel( b->filtWetDry[i] ); + filtWetDryKnob[i]->setMatrixLocation( 6, 7, i ); + + filtBalKnob[i]->setModel( b->filtBal[i] ); + filtBalKnob[i]->setMatrixLocation( 6, 8, i ); + + filtSatuKnob[i]->setModel( b->filtSatu[i] ); + filtSatuKnob[i]->setMatrixLocation( 6, 9, i ); + + filtFeedbackKnob[i]->setModel( b->filtFeedback[i] ); + filtFeedbackKnob[i]->setMatrixLocation( 6, 10, i ); + + filtDetuneKnob[i]->setModel( b->filtDetune[i] ); + filtDetuneKnob[i]->setMatrixLocation( 6, 11, i ); + + filtEnabledToggle[i]->setModel( b->filtEnabled[i] ); + + filtMutedToggle[i]->setModel( b->filtMuted[i] ); + + filtKeytrackingToggle[i]->setModel( b->filtKeytracking[i] ); + } + + for( int i = 0; i < 18; ++i ) + { + macroKnob[i]->setModel( b->macro[i] ); + macroKnob[i]->setMatrixLocation( 7, i, 0 ); + macroKnob[i]->setWhichMacroKnob( i ); + refreshMacroColor( macroKnob[i], i ); + } + + visimove( visvolKnob, 230 - scrollVal, 24 ); + + visimove( loadChnlKnob, 1500 + 111 - scrollVal, 121 ); + visimove( visualizeToggle, 213 - scrollVal, 26 ); + visimove( subNumBox, 250 + 18 - scrollVal, 219 ); + visimove( sampNumBox, 500 + 18 - scrollVal, 219 ); + visimove( mainNumBox, 18 - scrollVal, 219 ); + visimove( graph, scrollVal >= 500 ? 500 + 23 - scrollVal : 23 , 30 ); + visimove( openWavetableButton, ( scrollVal < 250 ? 54 : 1500 + 115 ) - scrollVal, scrollVal < 250 ? 220 : 24 ); + visimove( openSampleButton, 54 + 500 - scrollVal, 220 ); + + visimove( sinWaveBtn, 179 + 250 - scrollVal, 212 ); + visimove( triangleWaveBtn, 197 + 250 - scrollVal, 212 ); + visimove( sawWaveBtn, 215 + 250 - scrollVal, 212 ); + visimove( sqrWaveBtn, 179 + 250 - scrollVal, 227 ); + visimove( whiteNoiseWaveBtn, 197 + 250 - scrollVal, 227 ); + visimove( smoothBtn, 215 + 250 - scrollVal, 227 ); + visimove( usrWaveBtn, 54 + 250 - scrollVal, 220 ); + + visimove( sinWave2Btn, 179 + 500 - scrollVal, 212 ); + visimove( triangleWave2Btn, 197 + 500 - scrollVal, 212 ); + visimove( sawWave2Btn, 215 + 500 - scrollVal, 212 ); + visimove( sqrWave2Btn, 179 + 500 - scrollVal, 227 ); + visimove( whiteNoiseWave2Btn, 197 + 500 - scrollVal, 227 ); + visimove( smooth2Btn, 215 + 500 - scrollVal, 227 ); + visimove( usrWave2Btn, 54 + 500 - scrollVal, 220 ); + + visimove( oversampleBox, 70 + 1250 - scrollVal, 50 ); + + visimove( effectScrollBar, 221 + 1000 - scrollVal, 32 ); + visimove( matrixScrollBar, 221 + 750 - scrollVal, 32 ); + + visimove( filtForegroundLabel, 1000 - scrollVal, 0 ); + visimove( filtBoxesLabel, 1000 + 24 - scrollVal, 35 - ( effectScrollVal % 92 ) ); + + visimove( matrixForegroundLabel, 750 - scrollVal, 0 ); + visimove( matrixBoxesLabel, 750 + 24 - scrollVal, 35 - ( modScrollVal % 115 ) ); + + visimove( macroKnob[0], 1250 + 59 - scrollVal, 127 ); + visimove( macroKnob[1], 1250 + 81 - scrollVal, 127 ); + visimove( macroKnob[2], 1250 + 103 - scrollVal, 127 ); + visimove( macroKnob[3], 1250 + 125 - scrollVal, 127 ); + visimove( macroKnob[4], 1250 + 147 - scrollVal, 127 ); + visimove( macroKnob[5], 1250 + 169 - scrollVal, 127 ); + visimove( macroKnob[6], 1250 + 59 - scrollVal, 147 ); + visimove( macroKnob[7], 1250 + 81 - scrollVal, 147 ); + visimove( macroKnob[8], 1250 + 103 - scrollVal, 147 ); + visimove( macroKnob[9], 1250 + 125 - scrollVal, 147 ); + visimove( macroKnob[10], 1250 + 147 - scrollVal, 147 ); + visimove( macroKnob[11], 1250 + 169 - scrollVal, 147 ); + visimove( macroKnob[12], 1250 + 59 - scrollVal, 167 ); + visimove( macroKnob[13], 1250 + 81 - scrollVal, 167 ); + visimove( macroKnob[14], 1250 + 103 - scrollVal, 167 ); + visimove( macroKnob[15], 1250 + 125 - scrollVal, 167 ); + visimove( macroKnob[16], 1250 + 147 - scrollVal, 168 ); + visimove( macroKnob[17], 1250 + 169 - scrollVal, 168 ); + + visimove( tab1Btn, 1, 48 ); + visimove( tab2Btn, 1, 63 ); + visimove( tab3Btn, 1, 78 ); + visimove( tab4Btn, 1, 93 ); + visimove( tab5Btn, 1, 108 ); + visimove( tab6Btn, 1, 123 ); + + visimove( mainFlipBtn, 3 - scrollVal, 145 ); + visimove( subFlipBtn, 250 + 3 - scrollVal, 145 ); + + visimove( manualBtn, 1250 + 49 - scrollVal, 199); + + visimove( loadModeBox, 1500 + 25 - scrollVal, 76 ); + visimove( confirmLoadButton, 1500 + 93 - scrollVal, 187); + + visimove( XBtn, 231 + 1500 - scrollVal, 11 ); + visimove( MatrixXBtn, 229 + 750 - scrollVal, 8 ); + + visimove( normalizeBtn, 155 + 1500 - scrollVal, 224 ); + visimove( desawBtn, 39 + 1500 - scrollVal, 224 ); + + visimove( removeDCBtn, 1250 + 68 - scrollVal, 84 ); + visimove( oversampleModeBox, 1250 + 135 - scrollVal, 50 ); + + tabChanged( b->scroll ); + visvolKnob->setVisible( b->visualize.value() ); +} + + + +void MicrowaveView::wheelEvent( QWheelEvent * _me ) +{ + if( _me->x() <= 18 && _me->y() >= 48 && _me->y() <= 138 )// If scroll over tab buttons + { + if( b->scroll != 6 ) + { + if( _me->delta() < 0 && b->scroll != 5 ) + { + b->scroll += 1; + updateScroll(); + } + else if( _me->delta() > 0 && b->scroll > 0 ) + { + b->scroll -= 1; + updateScroll(); + } + } + } +} + + +void MicrowaveView::setGraphEnabledColor( bool isEnabled ) +{ + graph->setGraphColor( isEnabled ? QColor( 121, 222, 239 ) : QColor( 197, 197, 197 ) ); + pal = QPalette(); + pal.setBrush( backgroundRole(), isEnabled ? PLUGIN_NAME::getIconPixmap("wavegraph") : PLUGIN_NAME::getIconPixmap("wavegraphdisabled") ); + graph->setPalette( pal ); +} + + +// Trades out the GUI elements when switching between oscillators +void MicrowaveView::mainNumChanged() +{ + setGraphEnabledColor( b->enabled[b->mainNum.value()-1]->value() ); + + int mainNumValue = b->mainNum.value() - 1; + + morphKnob->setModel( b->morph[mainNumValue] ); + morphKnob->setMatrixLocation( 1, 1, mainNumValue ); + + rangeKnob->setModel( b->range[mainNumValue] ); + rangeKnob->setMatrixLocation( 1, 2, mainNumValue ); + + sampLenKnob->setModel( b->sampLen[mainNumValue] ); + + modifyKnob->setModel( b->modify[mainNumValue] ); + modifyKnob->setMatrixLocation( 1, 3, mainNumValue ); + + morphMaxKnob->setModel( b->morphMax[mainNumValue] ); + + unisonVoicesKnob->setModel( b->unisonVoices[mainNumValue] ); + unisonVoicesKnob->setMatrixLocation( 1, 8, mainNumValue ); + + unisonDetuneKnob->setModel( b->unisonDetune[mainNumValue] ); + unisonDetuneKnob->setMatrixLocation( 1, 9, mainNumValue ); + + unisonMorphKnob->setModel( b->unisonMorph[mainNumValue] ); + unisonMorphKnob->setMatrixLocation( 1, 10, mainNumValue ); + + unisonModifyKnob->setModel( b->unisonModify[mainNumValue] ); + unisonModifyKnob->setMatrixLocation( 1, 11, mainNumValue ); + + detuneKnob->setModel( b->detune[mainNumValue] ); + detuneKnob->setMatrixLocation( 1, 4, mainNumValue ); + + modifyModeBox-> setModel( b-> modifyMode[mainNumValue] ); + + phaseKnob->setModel( b->phase[mainNumValue] ); + phaseKnob->setMatrixLocation( 1, 5, mainNumValue ); + + phaseRandKnob->setModel( b->phaseRand[mainNumValue] ); + + volKnob->setModel( b->vol[mainNumValue] ); + volKnob->setMatrixLocation( 1, 6, mainNumValue ); + + panKnob->setModel( b->pan[mainNumValue] ); + panKnob->setMatrixLocation( 1, 7, mainNumValue ); + + enabledToggle->setModel( b->enabled[mainNumValue] ); + + mutedToggle->setModel( b->muted[mainNumValue] ); + + keytrackingToggle->setModel( b->keytracking[mainNumValue] ); + + tempoKnob->setModel( b->tempo[mainNumValue] ); + + interpolateToggle->setModel( b->interpolate[mainNumValue] ); + +} + + +// Trades out the GUI elements when switching between oscillators, and adjusts graph length when needed +void MicrowaveView::subNumChanged() +{ + b->graph.setLength( b->subSampLen[b->subNum.value()-1]->value() ); + b->graph.setSamples( b->storedsubs[b->subNum.value()-1] ); + setGraphEnabledColor( b->subEnabled[b->subNum.value()-1]->value() ); + + int subNumValue = b->subNum.value() - 1; + + subVolKnob->setModel( b->subVol[subNumValue] ); + subVolKnob->setMatrixLocation( 2, 3, subNumValue ); + + subEnabledToggle->setModel( b->subEnabled[subNumValue] ); + + subPhaseKnob->setModel( b->subPhase[subNumValue] ); + subPhaseKnob->setMatrixLocation( 2, 2, subNumValue ); + + subPhaseRandKnob->setModel( b->subPhaseRand[subNumValue] ); + + subDetuneKnob->setModel( b->subDetune[subNumValue] ); + subDetuneKnob->setMatrixLocation( 2, 1, subNumValue ); + + subMutedToggle->setModel( b->subMuted[subNumValue] ); + + subKeytrackToggle->setModel( b->subKeytrack[subNumValue] ); + + subSampLenKnob->setModel( b->subSampLen[subNumValue] ); + subSampLenKnob->setMatrixLocation( 2, 5, subNumValue ); + + subNoiseToggle->setModel( b->subNoise[subNumValue] ); + + subPanningKnob->setModel( b->subPanning[subNumValue] ); + subPanningKnob->setMatrixLocation( 2, 4, subNumValue ); + + subTempoKnob->setModel( b->subTempo[subNumValue] ); + + subRateLimitKnob->setModel( b->subRateLimit[subNumValue] ); + subRateLimitKnob->setMatrixLocation( 2, 6, subNumValue ); + + subUnisonNumKnob->setModel( b->subUnisonNum[subNumValue] ); + subUnisonNumKnob->setMatrixLocation( 2, 7, subNumValue ); + + subUnisonDetuneKnob->setModel( b->subUnisonDetune[subNumValue] ); + subUnisonDetuneKnob->setMatrixLocation( 2, 8, subNumValue ); + + subInterpolateToggle->setModel( b->subInterpolate[subNumValue] ); + +} + + +// Trades out the GUI elements when switching between oscillators +void MicrowaveView::sampNumChanged() +{ + setGraphEnabledColor( b->sampleEnabled[b->sampNum.value()-1]->value() ); + + for( int i = 0; i < 128; ++i ) + { + b->graph.setSampleAt( i, b->sampGraphs[(b->sampNum.value()-1)*128+i] ); + } + + int sampNumValue = b->sampNum.value() - 1; + + sampleEnabledToggle->setModel( b->sampleEnabled[sampNumValue] ); + sampleGraphEnabledToggle->setModel( b->sampleGraphEnabled[sampNumValue] ); + sampleMutedToggle->setModel( b->sampleMuted[sampNumValue] ); + sampleKeytrackingToggle->setModel( b->sampleKeytracking[sampNumValue] ); + sampleLoopToggle->setModel( b->sampleLoop[sampNumValue] ); + + sampleVolumeKnob->setModel( b->sampleVolume[sampNumValue] ); + sampleVolumeKnob->setMatrixLocation( 3, 3, sampNumValue ); + + samplePanningKnob->setModel( b->samplePanning[sampNumValue] ); + samplePanningKnob->setMatrixLocation( 3, 4, sampNumValue ); + + sampleDetuneKnob->setModel( b->sampleDetune[sampNumValue] ); + sampleDetuneKnob->setMatrixLocation( 3, 1, sampNumValue ); + + samplePhaseKnob->setModel( b->samplePhase[sampNumValue] ); + samplePhaseKnob->setMatrixLocation( 3, 2, sampNumValue ); + + samplePhaseRandKnob->setModel( b->samplePhaseRand[sampNumValue] ); + + sampleStartKnob->setModel( b->sampleStart[sampNumValue] ); + + sampleEndKnob->setModel( b->sampleEnd[sampNumValue] ); + +} + + +// Moves/changes the GUI around depending on the mod out section value +void MicrowaveView::modOutSecChanged( int i ) +{ + int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + + if( i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64 ) + { + temp1 = b->modOutSig[i]->value(); + switch( b->modOutSec[i]->value() ) + { + case 0:// None + { + modOutSigBox[i-matrixDivide]->hide(); + modOutSecNumBox[i-matrixDivide]->hide(); + break; + } + case 1:// Main OSC + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->show(); + mainoscsignalsmodel( b->modOutSig[i] ) + b->modOutSecNum[i]->setRange( 1.f, 8.f, 1.f ); + break; + } + case 2:// Sub OSC + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->show(); + subsignalsmodel( b->modOutSig[i] ) + b->modOutSecNum[i]->setRange( 1.f, 64.f, 1.f ); + break; + } + case 3:// Sample OSC + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->show(); + samplesignalsmodel( b->modOutSig[i] ) + b->modOutSecNum[i]->setRange( 1.f, 8.f, 1.f ); + break; + } + case 4:// Matrix Parameters + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->show(); + matrixsignalsmodel( b->modOutSig[i] ) + b->modOutSecNum[i]->setRange( 1.f, 64.f, 1.f ); + break; + } + case 5:// Filter Input + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->hide(); + mod8model( b->modOutSig[i] ) + break; + } + case 6:// Filter Parameters + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->show(); + filtersignalsmodel( b->modOutSig[i] ) + b->modOutSecNum[i]->setRange( 1.f, 8.f, 1.f ); + break; + } + case 7:// Macro + { + modOutSigBox[i-matrixDivide]->show(); + modOutSecNumBox[i-matrixDivide]->hide(); + matrixoutmodel( b->modOutSig[i] ) + break; + } + default: + { + break; + } + } + b->modOutSig[i]->setValue( temp1 ); + } +} + + +// Moves/changes the GUI around depending on the Mod In Section value +void MicrowaveView::modInChanged( int i ) +{ + int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + + if( i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64 ) + { + switch( b->modIn[i]->value() ) + { + case 0: + { + modInNumBox[i-matrixDivide]->hide(); + break; + } + case 1:// Main OSC + { + modInNumBox[i-matrixDivide]->show(); + b->modInNum[i]->setRange( 1, 8, 1 ); + break; + } + case 2:// Sub OSC + { + modInNumBox[i-matrixDivide]->show(); + b->modInNum[i]->setRange( 1, 64, 1 ); + break; + } + case 3:// Sample OSC + { + modInNumBox[i-matrixDivide]->show(); + b->modInNum[i]->setRange( 1, 8, 1 ); + break; + } + case 4:// Filter + { + modInNumBox[i-matrixDivide]->show(); + b->modInNum[i]->setRange( 1, 8, 1 ); + break; + } + case 5:// Velocity + { + modInNumBox[i-matrixDivide]->hide(); + break; + } + case 6:// Panning + { + modInNumBox[i-matrixDivide]->hide(); + break; + } + case 7:// Humanizer + { + modInNumBox[i-matrixDivide]->show(); + b->modInNum[i]->setRange( 1, 8, 1 ); + break; + } + case 8:// Macro + { + modInNumBox[i-matrixDivide]->show(); + b->modInNum[i]->setRange( 1, 18, 1 ); + break; + } + } + } +} + + +// Moves/changes the GUI around depending on the Mod In Section value +void MicrowaveView::modIn2Changed( int i ) +{ + int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + + if( i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64 ) + { + switch( b->modIn2[i]->value() ) + { + case 0: + { + modInNumBox2[i-matrixDivide]->hide(); + break; + } + case 1:// Main OSC + { + modInNumBox2[i-matrixDivide]->show(); + b->modInNum2[i]->setRange( 1, 8, 1 ); + break; + } + case 2:// Sub OSC + { + modInNumBox2[i-matrixDivide]->show(); + b->modInNum2[i]->setRange( 1, 64, 1 ); + break; + } + case 3:// Sample OSC + { + modInNumBox2[i-matrixDivide]->show(); + b->modInNum2[i]->setRange( 1, 8, 1 ); + break; + } + case 4:// Filter + { + modInNumBox2[i-matrixDivide]->show(); + b->modInNum2[i]->setRange( 1, 8, 1 ); + break; + } + case 5:// Velocity + { + modInNumBox2[i-matrixDivide]->hide(); + break; + } + case 6:// Panning + { + modInNumBox2[i-matrixDivide]->hide(); + break; + } + case 7:// Humanizer + { + modInNumBox2[i-matrixDivide]->show(); + b->modInNum2[i]->setRange( 1, 8, 1 ); + break; + } + case 8:// Macro + { + modInNumBox2[i-matrixDivide]->show(); + b->modInNum2[i]->setRange( 1, 18, 1 ); + break; + } + } + } +} + + + + +// Does what is necessary when the user visits a new tab +void MicrowaveView::tabChanged( int tabnum ) +{ + b->currentTab = tabnum; + + updateBackground(); + + if( tabnum != 3 ) + { + MatrixXBtn->hide(); + } + + if( tabnum != 0 ) + { + tab1Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1" ) ); + tab1Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1" ) ); + } + else + { + tab1Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); + tab1Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); + } + + if( tabnum != 1 ) + { + tab2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); + tab2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); + } + else + { + tab2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2_active" ) ); + tab2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2_active" ) ); + } + + if( tabnum != 2 ) + { + tab3Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); + tab3Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); + } + else + { + tab3Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3_active" ) ); + tab3Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3_active" ) ); + } + + if( tabnum != 3 ) + { + tab4Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); + tab4Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); + } + else + { + tab4Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4_active" ) ); + tab4Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4_active" ) ); + } + + if( tabnum != 4 ) + { + tab5Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); + tab5Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); + } + else + { + tab5Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5_active" ) ); + tab5Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5_active" ) ); + } + + if( tabnum != 5 ) + { + tab6Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); + tab6Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); + } + else + { + tab6Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6_active" ) ); + tab6Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6_active" ) ); + } +} + + + +void MicrowaveView::updateBackground() +{ + int backgroundnum = b->currentTab; + bool mainFlipped = b->mainFlipped.value(); + bool subFlipped = b->subFlipped.value(); + + switch( backgroundnum ) + { + case 0:// Wavetable + { + b->graph.setLength( 204 ); + mainNumChanged(); + + if( !mainFlipped ) + { + pal.setBrush( backgroundRole(), tab1ArtworkImg.copy() ); + } + else + { + pal.setBrush( backgroundRole(), tab1FlippedArtworkImg.copy() ); + } + + setPalette( pal ); + break; + } + case 1:// Sub + { + subNumChanged();// Graph length is set in here + + if( !subFlipped ) + { + pal.setBrush( backgroundRole(), tab2ArtworkImg.copy() ); + } + else + { + pal.setBrush( backgroundRole(), tab2FlippedArtworkImg.copy() ); + } + + setPalette( pal ); + break; + } + case 2:// Sample + { + b->graph.setLength( 128 ); + sampNumChanged(); + + pal.setBrush( backgroundRole(), tab3ArtworkImg.copy() ); + setPalette( pal ); + break; + } + case 3:// Matrix + { + pal.setBrush( backgroundRole(), tab4ArtworkImg.copy() ); + setPalette( pal ); + break; + } + case 4:// Effect + { + pal.setBrush( backgroundRole(), tab5ArtworkImg.copy() ); + setPalette( pal ); + break; + } + case 5:// Miscellaneous + { + pal.setBrush( backgroundRole(), tab6ArtworkImg.copy() ); + setPalette( pal ); + break; + } + case 6:// Wavetable Loading + { + pal.setBrush( backgroundRole(), tab7ArtworkImg.copy() ); + setPalette( pal ); + break; + } + } +} + + + + +void MicrowaveView::visualizeToggled( bool value ) +{ + visvolKnob->setVisible( b->visualize.value() ); +} + + +// V Buttons that change the graph V +void MicrowaveView::sinWaveClicked() +{ + graph->model()->setWaveToSine(); + Engine::getSong()->setModified(); +} + + +void MicrowaveView::triangleWaveClicked() +{ + graph->model()->setWaveToTriangle(); + Engine::getSong()->setModified(); +} + + +void MicrowaveView::sawWaveClicked() +{ + graph->model()->setWaveToSaw(); + Engine::getSong()->setModified(); +} + + +void MicrowaveView::sqrWaveClicked() +{ + graph->model()->setWaveToSquare(); + Engine::getSong()->setModified(); +} + + +void MicrowaveView::noiseWaveClicked() +{ + graph->model()->setWaveToNoise(); + Engine::getSong()->setModified(); +} + + +void MicrowaveView::usrWaveClicked() +{ + QString fileName = graph->model()->setWaveToUser(); + ToolTip::add( usrWaveBtn, fileName ); + Engine::getSong()->setModified(); +} + + +void MicrowaveView::smoothClicked() +{ + graph->model()->smooth(); + Engine::getSong()->setModified(); +} +// ^ Buttons that change the graph ^ + + +void MicrowaveView::flipperClicked() +{ + updateBackground(); + updateScroll(); +} + + +void MicrowaveView::XBtnClicked() +{ + castModel()->scroll = 0; + updateScroll(); +} + + +void MicrowaveView::MatrixXBtnClicked() +{ + castModel()->scroll = tabWhenSendingToMatrix; + updateScroll(); +} + + +void MicrowaveView::normalizeClicked() +{ + int oscilNum = b->mainNum.value() - 1; + + for( int i = 0; i < 256; ++i ) + { + float highestVolume = 0; + for( int j = 0; j < 2048; ++j ) + { + highestVolume = abs(b->storedwaveforms[oscilNum][(i*2048)+j]) > highestVolume ? abs(b->storedwaveforms[oscilNum][(i*2048)+j]) : highestVolume; + } + if( highestVolume ) + { + float multiplierThing = 1.f / highestVolume; + for( int j = 0; j < 2048; ++j ) + { + b->storedwaveforms[oscilNum][(i*2048)+j] *= multiplierThing; + } + } + } + + Engine::getSong()->setModified(); + + b->updateWavetable[oscilNum] = true; + + b->fillMainOsc(oscilNum, b->interpolate[oscilNum]->value()); +} + +void MicrowaveView::desawClicked() +{ + int oscilNum = b->mainNum.value() - 1; + + float start; + float end; + for( int j = 0; j < 256; ++j ) + { + start = -b->storedwaveforms[oscilNum][j*2048]; + end = -b->storedwaveforms[oscilNum][j*2048+2047]; + for( int i = 0; i < 2048; ++i ) + { + b->storedwaveforms[oscilNum][j*2048+i] += (i/2048.f)*end + ((2048.f-i)/2048.f)*start; + } + } + + Engine::getSong()->setModified(); + + b->updateWavetable[oscilNum] = true; + + b->fillMainOsc(oscilNum, b->interpolate[oscilNum]->value()); +} + + + +void MicrowaveView::modUpClicked( int i ) +{ + int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + if( i+matrixDivide > 0 ) + { + castModel()->switchMatrixSections( i+matrixDivide, i+matrixDivide - 1 ); + } +} + + +void MicrowaveView::modDownClicked( int i ) +{ + int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + if( i+matrixDivide < 63 ) + { + castModel()->switchMatrixSections( i+matrixDivide, i+matrixDivide + 1 ); + } +} + + +//NOTE: Different from Microwave::modEnabledChanged. +//Changes maximum value of the Matrix scroll bar. +void MicrowaveView::modEnabledChanged() +{ + matrixScrollBar->setRange( 0, qBound( 100.f, b->maxModEnabled * 100.f, 6232.f ) + 30.f ); +} + + +void MicrowaveView::i1Clicked( int i ) +{ + int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + + switch( b->modIn[i+matrixDivide]->value() ) + { + case 1: + { + b->scroll = 0; + b->mainNum.setValue( b->modInNum[i+matrixDivide]->value() ); + break; + } + case 2: + { + b->scroll = 1; + b->subNum.setValue( b->modInNum[i+matrixDivide]->value() ); + break; + } + case 3: + { + b->scroll = 2; + b->sampNum.setValue( b->modInNum[i+matrixDivide]->value() ); + break; + } + case 4: + { + b->scroll = 3; + effectScrollBar->setValue( ( b->modInNum[i+matrixDivide]->value() - 1 ) * 100.f ); + break; + } + case 8: + { + b->scroll = 5; + break; + } + } + + updateScroll(); +} + + +void MicrowaveView::i2Clicked( int i ) +{ + int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int matrixDivide = modScrollVal / 460 * 4; + + switch( b->modIn2[i+matrixDivide]->value() ) + { + case 1: + { + b->scroll = 0; + b->mainNum.setValue( b->modInNum2[i+matrixDivide]->value() ); + break; + } + case 2: + { + b->scroll = 1; + b->subNum.setValue( b->modInNum2[i+matrixDivide]->value() ); + break; + } + case 3: + { + b->scroll = 2; + b->sampNum.setValue( b->modInNum2[i+matrixDivide]->value() ); + break; + } + case 4: + { + b->scroll = 3; + effectScrollBar->setValue( ( b->modInNum2[i+matrixDivide]->value() - 1 ) * 100.f ); + break; + } + case 8: + { + b->scroll = 5; + break; + } + } + + updateScroll(); +} + + +void MicrowaveView::tabBtnClicked( int i ) +{ + castModel()->scroll = i; + updateScroll(); +} + + + +void MicrowaveView::sendToMatrixAsOutput( int loc1, int loc2, int loc3 ) +{ + int matrixLocation = b->maxModEnabled; + + if( matrixLocation < 64 ) + { + b->modEnabled[matrixLocation]->setValue( true ); + b->modOutSec[matrixLocation]->setValue( loc1 ); + b->modOutSig[matrixLocation]->setValue( loc2 ); + b->modOutSecNum[matrixLocation]->setValue( loc3 + 1 ); + } + + tabWhenSendingToMatrix = b->currentTab; + + MatrixXBtn->show(); + + b->scroll = 3; + updateScroll(); + + matrixScrollBar->setValue( 100 * matrixLocation ); +} + + +void MicrowaveView::switchToMatrixKnob( MicrowaveKnob * theKnob, int loc1, int loc2, int loc3 ) +{ + for( int i = 0; i < 64; ++i ) + { + if( b->modOutSec[i]->value() == loc1 && b->modOutSig[i]->value() == loc2 && b->modOutSecNum[i]->value() - 1 == loc3 ) + { + theKnob->setModel( b->modInAmnt[i] ); + theKnob->setarcColor( QColor(23,94,40) ); + theKnob->setlineColor( QColor(51,248,99) ); + theKnob->setInnerColor( QColor(32,112,50) ); + break; + } + } +} + + +void MicrowaveView::setMacroTooltip( MicrowaveKnob * theKnob, int which ) +{ + bool ok; + QString new_val; + + new_val = QInputDialog::getText( theKnob, tr( "Set new Tooltip" ), tr( "Please enter a new Tooltip for Macro %1:" ).arg( which + 1 ), QLineEdit::Normal, b->macroTooltips[which], &ok ); + + if( ok ) + { + b->macroTooltips[which] = new_val; + ToolTip::add( theKnob, tr( "Macro %1: " ).arg( which + 1 ) + new_val ); + } +} + + + +void MicrowaveView::chooseMacroColor( MicrowaveKnob * theKnob, int which ) +{ + QColor new_color = QColorDialog::getColor( QColor( b->macroColors[which][0], b->macroColors[which][1], b->macroColors[which][2] ) ); + if( ! new_color.isValid() ) + { + return; + } + + b->macroColors[which][0] = new_color.red(); + b->macroColors[which][1] = new_color.green(); + b->macroColors[which][2] = new_color.blue(); + refreshMacroColor( theKnob, which ); +} + + +void MicrowaveView::setMacroColortoDefault( MicrowaveKnob * theKnob, int which ) +{ + b->macroColors[which][0] = 102; + b->macroColors[which][1] = 198; + b->macroColors[which][2] = 199; + refreshMacroColor( theKnob, which ); +} + + +void MicrowaveView::refreshMacroColor( MicrowaveKnob * theKnob, int which ) +{ + int red = b->macroColors[which][0]; + int green = b->macroColors[which][1]; + int blue = b->macroColors[which][2]; + + theKnob->setarcColor( QColor(red*0.4, green*0.4, blue*0.4) ); + theKnob->setlineColor( QColor(red, green, blue) ); + theKnob->setInnerColor( QColor(red*0.5, green*0.5, blue*0.5) ); +} + + + +// Calls MicrowaveView::openWavetableFile when the wavetable opening button is clicked. +void MicrowaveView::openWavetableFileBtnClicked() +{ + if( b->scroll != 6 ) + { + b->scroll = 6; + updateScroll(); + } + else + { + chooseWavetableFile(); + } +} + + +void MicrowaveView::chooseWavetableFile() +{ + SampleBuffer * sampleBuffer = new SampleBuffer; + wavetableFileName = sampleBuffer->openAndSetWaveformFile(); + sharedObject::unref( sampleBuffer ); +} + + +void MicrowaveView::confirmWavetableLoadClicked() +{ + openWavetableFile(); +} + + +// All of the code and algorithms for loading wavetables from samples. Please don't expect this code to look neat. +void MicrowaveView::openWavetableFile( QString fileName ) +{ + const sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); + + if( fileName.isEmpty() ) + { + if( wavetableFileName.isEmpty() ) + { + chooseWavetableFile(); + } + fileName = wavetableFileName; + } + + SampleBuffer * sampleBuffer = new SampleBuffer; + + sampleBuffer->setAudioFile( fileName ); + + int filelength = sampleBuffer->sampleLength(); + int oscilNum = b->mainNum.value() - 1; + int algorithm = b->loadMode.value(); + int channel = b->loadChnl.value(); + + if( !fileName.isEmpty() ) + { + sampleBuffer->dataReadLock(); + float lengthOfSample = ((filelength/1000.f)*sample_rate);//in samples + switch( algorithm ) + { + case 0:// Lock waveform edges to zero crossings + { + //Clear wavetable + for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + { + b->storedwaveforms[oscilNum][i] = 0; + } + + bool above = sampleBuffer->userWaveSample( 1.f/lengthOfSample, channel ) > 0; + float currentValue = 0; + std::vector zeroCrossings; + float previousPoint = 0; + + //Find zero crossings, and store differences between them in a vector. + for( int i = 0; i < lengthOfSample; ++i ) + { + currentValue = sampleBuffer->userWaveSample( i / lengthOfSample, channel ); + if( ( above && currentValue <= 0 ) || ( !above && currentValue > 0 ) ) + { + above = !above; + zeroCrossings.push_back( i-previousPoint ); + previousPoint = i; + } + } + + //Quit if the sample is too short + if( zeroCrossings.size() < 3 ) + { + break; + } + + std::vector betterZC; + float now = 0; + float actualnow = 0; + + //Find and list chosen zero crossings + for( int i = 0; i < zeroCrossings.size() - 1; ++i ) + { + now += zeroCrossings[i]; + actualnow += zeroCrossings[i]; + if( abs( STOREDMAINWAVELEN / 2.f - now ) < abs( STOREDMAINWAVELEN / 2.f - ( now + zeroCrossings[i+1] ) ) ) + { + betterZC.push_back( actualnow ); + now = 0; + } + } + + float start; + float end; + + float lasti = 0; + float lastj = 0; + + bool breakify = false; + + //Take gathered information and cram it into the waveforms. + for( int i = 0; i < betterZC.size() - 1; ++i ) + { + start = betterZC[i]; + end = betterZC[i+1]; + + lasti = i; + + for( int j = 0; j < b->sampLen[oscilNum]->value(); ++j ) + { + lastj = j; + + if( j + ( i * b->sampLen[oscilNum]->value()) >= STOREDMAINARRAYLEN ) + { + breakify = true; + break; + } + b->storedwaveforms[oscilNum][j + ( i * (int)b->sampLen[oscilNum]->value() )] = sampleBuffer->userWaveSample( ( ( j / b->sampLen[oscilNum]->value() ) * ( end - start ) + start ) / lengthOfSample, channel ); + } + + if( breakify ) { break; } + } + + b->morphMax[oscilNum]->setValue( lasti + ( lastj / b->sampLen[oscilNum]->value() ) ); + b->morphMaxChanged( oscilNum ); + + break; + } + case 1:// Load sample without changes + { + for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + { + if ( i <= lengthOfSample * 2.f ) + { + b->storedwaveforms[oscilNum][i] = sampleBuffer->userWaveSample( (i/lengthOfSample) / 2.f, channel ); + } + else// Replace everything else with silence if sample isn't long enough + { + b->morphMax[oscilNum]->setValue( i/b->sampLen[oscilNum]->value() ); + b->morphMaxChanged( oscilNum ); + for( int j = i; j < STOREDMAINARRAYLEN; ++j ) { b->storedwaveforms[oscilNum][j] = 0.f; } + break; + } + } + break; + } + case 2:// For loading wavetable files + { + for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + { + if ( i <= lengthOfSample ) + { + b->storedwaveforms[oscilNum][i] = sampleBuffer->userWaveSample( i/lengthOfSample, channel ); + } + else + { + b->morphMax[oscilNum]->setValue( i/b->sampLen[oscilNum]->value() ); + b->morphMaxChanged( oscilNum ); + for( int j = i; j < STOREDMAINARRAYLEN; ++j ) { b->storedwaveforms[oscilNum][j] = 0.f; } + break; + } + } + break; + } + case 3:// Autocorrelation + { + // This uses a method called autocorrelation to detect the pitch, maliciously stolen from Instructables. It can get a few Hz off (especially at higher frequencies), so I also compare it with the zero crossings to see if I can get it even more accurate. + + // Estimate pitch using autocorrelation: + + float checkLength = qMin( 4000.f, lengthOfSample );// 4000 samples should be long enough to be able to accurately detect most frequencies this way + + float threshold = -1; + float combined = 0; + float oldcombined; + int stage = 0; + + float period = 0; + for( int i = 0; i < checkLength; ++i ) + { + oldcombined = combined; + combined = 0; + for( int k = 0; k < checkLength - i; ++k ) + { + combined += ( sampleBuffer->userWaveSample( k/lengthOfSample, channel ) * sampleBuffer->userWaveSample( (k+i)/lengthOfSample, channel ) + 1 ) * 0.5f - 0.5f; + } + + if( stage == 2 && combined - oldcombined <= 0 ) + { + stage = 3; + period = i; + } + + if( stage == 1 && combined > threshold && combined - oldcombined > 0 ) + { + stage = 2; + } + + if( !i ) + { + threshold = combined * 0.5f; + stage = 1; + } + } + + if( !period ) + { + break; + } + + // Now see if the zero crossings can aid in getting the pitch even more accurate: + + // Note: If the zero crossings give a result very close to the autocorrelation, then it is likely to be more accurate. + // Otherwise, the zero crossing result is probably very inaccurate (common with complex sounds) and is ignored. + + std::vector crossings; + crossings.push_back( 0 ); + std::vector crossingsDif; + bool above = ( sampleBuffer->userWaveSample( 1/lengthOfSample, channel ) > 0 ); + + for( int i = 0; i < checkLength; ++i ) + { + if( ( sampleBuffer->userWaveSample( i/lengthOfSample, channel ) > 0 ) != above ) + { + above = !above; + if( above ) + { + crossingsDif.push_back( i - crossings[crossings.size() - 1] ); + crossings.push_back( i ); + } + } + } + + crossings.erase( crossings.begin() ); + + if( crossingsDif.size() >= 3 ) + { + float crossingsMean = std::accumulate( crossingsDif.begin(), crossingsDif.end(), 0.f ) / crossingsDif.size(); + std::vector crossingsToRemove; + for( int i = 0; i < crossingsDif.size(); ++i ) + { + if( crossingsDif[i] < crossingsMean ) + { + crossingsToRemove.push_back( i ); + } + } + for( int i = crossingsToRemove.size() - 1; i >= 0; --i ) + { + crossingsDif.erase( crossingsDif.begin() + crossingsToRemove[i] ); + } + if( crossingsDif.size() >= 2 ) + { + float crossingsMedian = crossingsDif[int( crossingsDif.size() / 2.f )]; + if( abs( period - crossingsMedian ) < 5.f + period / 100.f ) + { + period = crossingsMedian; + } + } + } + + for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + { + b->storedwaveforms[oscilNum][i] = sampleBuffer->userWaveSample( ((i/2048.f)*period)/lengthOfSample, channel ); + } + + b->morphMax[oscilNum]->setValue( 254 ); + b->morphMaxChanged( oscilNum ); + + break; + } + } + sampleBuffer->dataUnlock(); + + b->updateWavetable[oscilNum] = true; + + b->fillMainOsc(oscilNum, b->interpolate[oscilNum]->value()); + } + + sharedObject::unref( sampleBuffer ); +} + + + +// Calls MicrowaveView::openSampleFile when the sample opening button is clicked. +void MicrowaveView::openSampleFileBtnClicked( ) +{ + openSampleFile(); +} + + +// Loads sample for sample oscillator +void MicrowaveView::openSampleFile() +{ + const sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); + int oscilNum = b->sampNum.value() - 1; + + SampleBuffer * sampleBuffer = new SampleBuffer; + QString fileName = sampleBuffer->openAndSetWaveformFile(); + int filelength = sampleBuffer->sampleLength(); + if( fileName.isEmpty() == false ) + { + sampleBuffer->dataReadLock(); + float lengthOfSample = ((filelength/1000.f)*sample_rate);//in samples + b->samples[oscilNum][0].clear(); + b->samples[oscilNum][1].clear(); + + for( int i = 0; i < lengthOfSample; ++i ) + { + b->samples[oscilNum][0].push_back(sampleBuffer->userWaveSample(i/lengthOfSample, 0)); + b->samples[oscilNum][1].push_back(sampleBuffer->userWaveSample(i/lengthOfSample, 1)); + } + sampleBuffer->dataUnlock(); + } + sharedObject::unref( sampleBuffer ); +} + + + +void MicrowaveView::dropEvent( QDropEvent * _de ) +{ + QString type = StringPairDrag::decodeKey( _de ); + QString value = StringPairDrag::decodeValue( _de ); + if( type == "samplefile" ) + { + wavetableFileName = value; + b->scroll = 6; + updateScroll(); + _de->accept(); + return; + } + _de->ignore(); +} + + +void MicrowaveView::dragEnterEvent( QDragEnterEvent * _dee ) +{ + if( _dee->mimeData()->hasFormat( StringPairDrag::mimeType() ) ) + { + QString txt = _dee->mimeData()->data( + StringPairDrag::mimeType() ); + if( txt.section( ':', 0, 0 ) == "samplefile" ) + { + _dee->acceptProposedAction(); + } + else + { + _dee->ignore(); + } + } + else + { + _dee->ignore(); + } +} + + + + + +/* + + ____ .--.--. ___ ,---, + ,' , `. / / '. ,--.'|_ ,--.' | + ,-+-,.' _ || : /`. / ,---, | | :,' | | : + ,-+-. ; , ||; | |--` ,-+-. / | : : ' : : : : + ,--.'|' | ||| : ;_ .--, ,--.'|' |.;__,' / : | |,--. +| | ,', | |, \ \ `. /_ ./| | | ,"' || | | | : ' | +| | / | |--' `----. \, ' , ' : | | / | |:__,'| : | | /' : +| : | | , __ \ \ /___/ \: | | | | | | ' : |__ ' : | | | +| : | |/ / /`--' /. \ ' | | | | |/ | | '.'|| | ' | : +| | |`-' '--'. / \ ; : | | |--' ; : ;| : :_:,' +| ;/ `--'---' \ \ ; | |/ | , / | | ,' +'---' : \ \'---' ---`-' `--'' + \ ' ; + `--` +*/ + + + + +// Initializes mSynth (when a new note is played). Clone all of the arrays storing the knob values so they can be changed by modulation. +mSynth::mSynth( NotePlayHandle * _nph, + float * morphArr, float * rangeArr, float * modifyArr, int * modifyModeArr, float * volArr, float * panArr, float * detuneArr, float * phaseArr, float * phaseRandArr, bool * enabledArr, bool * mutedArr, + float * sampLenArr, float * morphMaxArr, float * unisonVoicesArr, float * unisonDetuneArr, float * unisonMorphArr, float * unisonModifyArr, bool * keytrackingArr, float * tempoArr, bool * interpolateArr, + bool * subEnabledArr, bool * subMutedArr, bool * subKeytrackArr, bool * subNoiseArr, float * subVolArr, float * subPanningArr, float * subDetuneArr, float * subPhaseArr, float * subPhaseRandArr, + float * subSampLenArr, float * subTempoArr, float * subRateLimitArr, float * subUnisonNumArr, float * subUnisonDetuneArr, bool * subInterpolateArr, + bool * sampleEnabledArr, bool * sampleMutedArr, bool * sampleKeytrackingArr, bool * sampleGraphEnabledArr, bool * sampleLoopArr, float * sampleVolumeArr, float * samplePanningArr, + float * sampleDetuneArr, float * samplePhaseArr, float * samplePhaseRandArr, float * sampleStartArr, float * sampleEndArr, + int * modInArr, int * modInNumArr, float * modInAmntArr, float * modInCurveArr, int * modIn2Arr, int * modInNum2Arr, float * modInAmnt2Arr, float * modInCurve2Arr, + int * modOutSecArr, int * modOutSigArr, int * modOutSecNumArr, bool * modEnabledArr, int * modCombineTypeArr, bool * modTypeArr, bool * modType2Arr, + float * filtCutoffArr, float * filtResoArr, float * filtGainArr, int * filtTypeArr, int * filtSlopeArr, float * filtInVolArr, float * filtOutVolArr, float * filtWetDryArr, float * filtBalArr, + float * filtSatuArr, float * filtFeedbackArr, float * filtDetuneArr, bool * filtEnabledArr, bool * filtMutedArr, bool * filtKeytrackingArr, + float * macroArr, + std::vector (&samples)[8][2] ) : + + nph( _nph ) +{ + memcpy( morph, morphArr, sizeof(float) * 8 ); + memcpy( range, rangeArr, sizeof(float) * 8 ); + memcpy( modify, modifyArr, sizeof(float) * 8 ); + memcpy( modifyMode, modifyModeArr, sizeof(int) * 8 ); + memcpy( vol, volArr, sizeof(int) * 8 ); + memcpy( pan, panArr, sizeof(float) * 8 ); + memcpy( detune, detuneArr, sizeof(float) * 8 ); + memcpy( phase, phaseArr, sizeof(int) * 8 ); + memcpy( phaseRand, phaseRandArr, sizeof(int) * 8 ); + memcpy( enabled, enabledArr, sizeof(bool) * 8 ); + memcpy( muted, mutedArr, sizeof(bool) * 8 ); + memcpy( sampLen, sampLenArr, sizeof(float) * 8 ); + memcpy( morphMax, morphMaxArr, sizeof(float) * 8 ); + memcpy( unisonVoices, unisonVoicesArr, sizeof(float) * 8 ); + memcpy( unisonDetune, unisonDetuneArr, sizeof(float) * 8 ); + memcpy( unisonMorph, unisonMorphArr, sizeof(float) * 8 ); + memcpy( unisonModify, unisonModifyArr, sizeof(float) * 8 ); + memcpy( keytracking, keytrackingArr, sizeof(bool) * 8 ); + memcpy( tempo, tempoArr, sizeof(float) * 8 ); + memcpy( interpolate, interpolateArr, sizeof(bool) * 8 ); + + memcpy( subEnabled, subEnabledArr, sizeof(bool) * 64 ); + memcpy( subMuted, subMutedArr, sizeof(bool) * 64 ); + memcpy( subKeytrack, subKeytrackArr, sizeof(bool) * 64 ); + memcpy( subNoise, subNoiseArr, sizeof(bool) * 64 ); + memcpy( subVol, subVolArr, sizeof(float) * 64 ); + memcpy( subPanning, subPanningArr, sizeof(float) * 64 ); + memcpy( subDetune, subDetuneArr, sizeof(float) * 64 ); + memcpy( subPhase, subPhaseArr, sizeof(float) * 64 ); + memcpy( subPhaseRand, subPhaseRandArr, sizeof(float) * 64 ); + memcpy( subSampLen, subSampLenArr, sizeof(float) * 64 ); + memcpy( subTempo, subTempoArr, sizeof(float) * 64 ); + memcpy( subRateLimit, subRateLimitArr, sizeof(float) * 64 ); + memcpy( subUnisonNum, subUnisonNumArr, sizeof(float) * 64 ); + memcpy( subUnisonDetune, subUnisonDetuneArr, sizeof(float) * 64 ); + memcpy( subInterpolate, subInterpolateArr, sizeof(bool) * 64 ); + + memcpy( sampleEnabled, sampleEnabledArr, sizeof(bool) * 8 ); + memcpy( sampleMuted, sampleMutedArr, sizeof(bool) * 8 ); + memcpy( sampleKeytracking, sampleKeytrackingArr, sizeof(bool) * 8 ); + memcpy( sampleGraphEnabled, sampleGraphEnabledArr, sizeof(bool) * 8 ); + memcpy( sampleLoop, sampleLoopArr, sizeof(bool) * 8 ); + memcpy( sampleVolume, sampleVolumeArr, sizeof(float) * 8 ); + memcpy( samplePanning, samplePanningArr, sizeof(float) * 8 ); + memcpy( sampleDetune, sampleDetuneArr, sizeof(float) * 8 ); + memcpy( samplePhase, samplePhaseArr, sizeof(float) * 8 ); + memcpy( samplePhaseRand, samplePhaseRandArr, sizeof(float) * 8 ); + memcpy( sampleStart, sampleStartArr, sizeof(float) * 8 ); + memcpy( sampleEnd, sampleEndArr, sizeof(float) * 8 ); + + memcpy( modIn, modInArr, sizeof(int) * 64 ); + memcpy( modInNum, modInNumArr, sizeof(int) * 64 ); + memcpy( modInAmnt, modInAmntArr, sizeof(float) * 64 ); + memcpy( modInCurve, modInCurveArr, sizeof(float) * 64 ); + memcpy( modIn2, modIn2Arr, sizeof(int) * 64 ); + memcpy( modInNum2, modInNum2Arr, sizeof(int) * 64 ); + memcpy( modInAmnt2, modInAmnt2Arr, sizeof(float) * 64 ); + memcpy( modInCurve2, modInCurve2Arr, sizeof(float) * 64 ); + memcpy( modOutSec, modOutSecArr, sizeof(int) * 64 ); + memcpy( modOutSig, modOutSigArr, sizeof(int) * 64 ); + memcpy( modOutSecNum, modOutSecNumArr, sizeof(int) * 64 ); + memcpy( modEnabled, modEnabledArr, sizeof(bool) * 64 ); + memcpy( modCombineType, modCombineTypeArr, sizeof(int) * 64 ); + memcpy( modType, modTypeArr, sizeof(bool) * 64 ); + memcpy( modType2, modType2Arr, sizeof(bool) * 64 ); + + memcpy( filtCutoff, filtCutoffArr, sizeof(float) * 8 ); + memcpy( filtReso, filtResoArr, sizeof(float) * 8 ); + memcpy( filtGain, filtGainArr, sizeof(float) * 8 ); + memcpy( filtType, filtTypeArr, sizeof(int) * 8 ); + memcpy( filtSlope, filtSlopeArr, sizeof(int) * 8 ); + memcpy( filtInVol, filtInVolArr, sizeof(float) * 8 ); + memcpy( filtOutVol, filtOutVolArr, sizeof(float) * 8 ); + memcpy( filtWetDry, filtWetDryArr, sizeof(float) * 8 ); + memcpy( filtBal, filtBalArr, sizeof(float) * 8 ); + memcpy( filtSatu, filtSatuArr, sizeof(float) * 8 ); + memcpy( filtFeedback, filtFeedbackArr, sizeof(float) * 8 ); + memcpy( filtDetune, filtDetuneArr, sizeof(float) * 8 ); + memcpy( filtEnabled, filtEnabledArr, sizeof(bool) * 8 ); + memcpy( filtMuted, filtMutedArr, sizeof(bool) * 8 ); + memcpy( filtKeytracking, filtKeytrackingArr, sizeof(bool) * 8 ); + + memcpy( macro, macroArr, sizeof(float) * 18 ); + + + + for( int i = 0; i < 8; ++i ) + { + for( int j = 0; j < 32; ++j ) + { + // Randomize the phases of all of the waveforms + sample_realindex[i][j] = int( ( ( fastRandf( sampLen[i] * WAVERATIO ) ) * ( phaseRand[i] * 0.01f ) ) ) % int( sampLen[i] * WAVERATIO ); + } + } + + for( int i = 0; i < 64; ++i ) + { + for( int l = 0; l < 32; ++l ) + { + sample_subindex[i][l] = int( ( ( fastRandf( subSampLen[i] * WAVERATIO ) - ( subSampLen[i] * WAVERATIO * 0.5f ) ) * ( subPhaseRand[i] * 0.01f ) ) ) % int( subSampLen[i] * WAVERATIO ); + subNoiseDirection[i][l] = 1; + } + } + + for( int i = 0; i < 8; ++i ) + { + sample_sampleindex[i] = fmod( fastRandf( samples[i][0].size() ) * ( samplePhaseRand[i] * 0.01f ), ( samples[i][0].size() *sampleEnd[i] ) - ( samples[i][0].size() * sampleStart[i] ) ) + ( samples[i][0].size() * sampleStart[i] ); + humanizer[i] = ( rand() / float(RAND_MAX) ) * 2 - 1;// Generate humanizer values at the beginning of every note + } + + noteDuration = -1; + + for( int i = 0; i < 8; ++i ) + { + for( int j = 0; j < unisonVoices[i]; ++j ) + { + unisonDetuneAmounts[i][j] = ((rand()/float(RAND_MAX))*2.f)-1; + } + } + + for( int i = 0; i < 64; ++i ) + { + for( int j = 0; j < subUnisonNum[i]; ++j ) + { + subUnisonDetuneAmounts[i][j] = ((rand()/float(RAND_MAX))*2.f)-1; + } + } + +} + + +mSynth::~mSynth() +{ +} + + +// The heart of Microwave. As you probably learned in anatomy class, hearts actually aren't too pretty. This is no exception. +// This is the part that puts everything together and calculates an audio output. +void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][MAINARRAYLEN], float (&subs)[64][SUBWAVELEN], float * sampGraphs, std::vector (&samples)[8][2], int maxFiltEnabled, int maxModEnabled, int maxSubEnabled, int maxSampleEnabled, int maxMainEnabled, int sample_rate, Microwave * mwc, bool removeDC, bool isOversamplingSample, float (&storedsubs)[64][STOREDSUBWAVELEN] ) +{ + + ++noteDuration; + + //============// + //== MATRIX ==// + //============// + + numberToReset = 0; + for( int l = 0; l < maxModEnabled; ++l )// maxModEnabled keeps this from looping 64 times every sample, saving a lot of CPU + { + if( modEnabled[l] ) + { + switch( modIn[l] ) + { + case 0: + { + curModVal[0] = 0; + curModVal[1] = 0; + break; + } + case 1:// Wavetable + { + if( modType[l] )// If envelope + { + curModVal[0] = lastMainOscEnvVal[modInNum[l]-1][0]; + curModVal[1] = lastMainOscEnvVal[modInNum[l]-1][1]; + } + else + { + curModVal[0] = lastMainOscVal[modInNum[l]-1][0]; + curModVal[1] = lastMainOscVal[modInNum[l]-1][1]; + } + break; + } + case 2:// Sub + { + if( modType[l] )// If envelope + { + curModVal[0] = lastSubEnvVal[modInNum[l]-1][0]; + curModVal[1] = lastSubEnvVal[modInNum[l]-1][1]; + } + else + { + curModVal[0] = lastSubVal[modInNum[l]-1][0]; + curModVal[1] = lastSubVal[modInNum[l]-1][1]; + } + break; + } + case 3:// Sample + { + if( modType[l] )// If envelope + { + curModVal[0] = lastSampleEnvVal[modInNum[l]-1][0]; + curModVal[1] = lastSampleEnvVal[modInNum[l]-1][1]; + } + else + { + curModVal[0] = lastSampleVal[modInNum[l]-1][0]; + curModVal[1] = lastSampleVal[modInNum[l]-1][1]; + } + break; + } + case 4:// Filter + { + curModVal[0] = filtModOutputs[modInNum[l]-1][0]; + curModVal[1] = filtModOutputs[modInNum[l]-1][1]; + break; + } + case 5:// Velocity + { + curModVal[0] = ( nph->getVolume() * 0.01f )-1; + curModVal[1] = curModVal[0]; + break; + } + case 6:// Panning + { + curModVal[0] = ( nph->getPanning() * 0.01f ); + curModVal[1] = curModVal[0]; + break; + } + case 7:// Humanizer + { + curModVal[0] = humanizer[modInNum[l]-1]; + curModVal[1] = humanizer[modInNum[l]-1]; + break; + } + case 8:// Macro + { + curModVal[0] = macro[modInNum[l]-1] * 0.01f; + curModVal[1] = macro[modInNum[l]-1] * 0.01f; + break; + } + default: + { + switch( modCombineType[l] ) + { + case 0:// Add Bidirectional + { + curModVal[0] = 0; + curModVal[1] = 0; + break; + } + case 1:// Multiply Bidirectional + { + curModVal[0] = 0; + curModVal[1] = 0; + break; + } + case 2:// Add Unidirectional + { + curModVal[0] = -1; + curModVal[1] = -1; + break; + } + case 3:// Multiply Unidirectional + { + curModVal[0] = -1; + curModVal[1] = -1; + break; + } + } + } + } + switch( modIn2[l] ) + { + case 0: + { + curModVal2[0] = 0; + curModVal2[1] = 0; + break; + } + case 1:// Wavetable + { + if( modType2[l] )// If envelope + { + curModVal2[0] = lastMainOscEnvVal[modInNum2[l]-1][0]; + curModVal2[1] = lastMainOscEnvVal[modInNum2[l]-1][1]; + } + else + { + curModVal2[0] = lastMainOscVal[modInNum2[l]-1][0]; + curModVal2[1] = lastMainOscVal[modInNum2[l]-1][1]; + } + break; + } + case 2:// Sub + { + if( modType2[l] )// If envelope + { + curModVal2[0] = lastSubEnvVal[modInNum2[l]-1][0]; + curModVal2[1] = lastSubEnvVal[modInNum2[l]-1][1]; + } + else + { + curModVal2[0] = lastSubVal[modInNum2[l]-1][0]; + curModVal2[1] = lastSubVal[modInNum2[l]-1][1]; + } + break; + } + case 3:// Sample + { + if( modType[l] )// If envelope + { + curModVal2[0] = lastSampleEnvVal[modInNum2[l]-1][0]; + curModVal2[1] = lastSampleEnvVal[modInNum2[l]-1][1]; + } + else + { + curModVal2[0] = lastSampleVal[modInNum2[l]-1][0]; + curModVal2[1] = lastSampleVal[modInNum2[l]-1][1]; + } + break; + } + case 4:// Filter + { + curModVal2[0] = filtModOutputs[modInNum2[l]-1][0]; + curModVal2[1] = filtModOutputs[modInNum2[l]-1][1]; + } + case 5:// Velocity + { + curModVal2[0] = (nph->getVolume() * 0.01f)-1; + curModVal2[1] = curModVal2[0]; + break; + } + case 6:// Panning + { + curModVal2[0] = (nph->getPanning() * 0.01f); + curModVal2[1] = curModVal2[0]; + break; + } + case 7:// Humanizer + { + curModVal2[0] = humanizer[modInNum2[l]-1]; + curModVal2[1] = humanizer[modInNum2[l]-1]; + break; + } + case 8:// Macro + { + curModVal2[0] = macro[modInNum2[l]-1] * 0.01f; + curModVal2[1] = macro[modInNum2[l]-1] * 0.01f; + break; + } + default: + { + switch( modCombineType[l] ) + { + case 0:// Add Bidirectional + { + curModVal[0] = 0; + curModVal[1] = 0; + break; + } + case 1:// Multiply Bidirectional + { + curModVal[0] = 0; + curModVal[1] = 0; + break; + } + case 2:// Add Unidirectional + { + curModVal[0] = -1; + curModVal[1] = -1; + break; + } + case 3:// Multiply Unidirectional + { + curModVal[0] = -1; + curModVal[1] = -1; + break; + } + } + } + } + + if( curModVal[0] ) { curModVal[0] *= modInAmnt[l] * 0.01f; } + if( curModVal[1] ) { curModVal[1] *= modInAmnt[l] * 0.01f; } + if( curModVal2[0] ) { curModVal2[0] *= modInAmnt2[l] * 0.01f; } + if( curModVal2[1] ) { curModVal2[1] *= modInAmnt2[l] * 0.01f; } + + // Calculate curve + if( modCombineType[l] <= 1 )// Bidirectional + { + if( modInCurve[l] != 100.f )// The "if" statement is there so unnecessary CPU isn't spent (pow is very expensive) if the curve knob isn't being used. + { + // Move to a scale of 0 to 1 (from -1 to 1) and then apply the curve. + curModValCurve[0] = (curModVal[0] <= -1 || curModVal[0] >= 1) ? ( curModVal[0] + 1 ) * 0.5f : pow( ( curModVal[0] + 1 ) * 0.5f, 1.f / ( modInCurve[l] * 0.01f ) ); + curModValCurve[1] = (curModVal[1] <= -1 || curModVal[1] >= 1) ? ( curModVal[1] + 1 ) * 0.5f : pow( ( curModVal[1] + 1 ) * 0.5f, 1.f / ( modInCurve[l] * 0.01f ) ); + } + else + { + curModValCurve[0] = ( curModVal[0] + 1 ) * 0.5f; + curModValCurve[1] = ( curModVal[1] + 1 ) * 0.5f; + } + if( modInCurve2[l] != 100.f ) + { + curModVal2Curve[0] = (curModVal2[0] <= -1 || curModVal2[0] >= 1) ? ( curModVal2[0] + 1 ) * 0.5f : pow( ( curModVal2[0] + 1 ) * 0.5f, 1.f / ( modInCurve2[l] * 0.01f ) ); + curModVal2Curve[1] = (curModVal2[1] <= -1 || curModVal2[1] >= 1) ? ( curModVal2[1] + 1 ) * 0.5f : pow( ( curModVal2[1] + 1 ) * 0.5f, 1.f / ( modInCurve2[l] * 0.01f ) ); + } + else + { + curModVal2Curve[0] = ( curModVal2[0] + 1 ) * 0.5f; + curModVal2Curve[1] = ( curModVal2[1] + 1 ) * 0.5f; + } + } + else// Unidirectional + { + if( modInCurve[l] != 100.f ) + { + curModValCurve[0] = ( (curModVal[0] <= -1 || curModVal[0] >= 1) ? curModVal[0] : pow( abs( curModVal[0] ), 1.f / ( modInCurve[l] * 0.01f ) ) * ( curModVal[0] < 0 ? -1 : 1 ) ) + (modInAmnt[l] * 0.01); + curModValCurve[1] = ( (curModVal[1] <= -1 || curModVal[1] >= 1) ? curModVal[1] : pow( abs( curModVal[1] ), 1.f / ( modInCurve[l] * 0.01f ) ) * ( curModVal[1] < 0 ? -1 : 1 ) ) + (modInAmnt[l] * 0.01); + } + else + { + curModValCurve[0] = curModVal[0] + (modInAmnt[l] * 0.01); + curModValCurve[1] = curModVal[1] + (modInAmnt[l] * 0.01); + } + if( modInCurve2[l] != 100.f ) + { + curModVal2Curve[0] = ( (curModVal2[0] <= -1 || curModVal2[0] >= 1) ? curModVal2[0] : pow( abs( curModVal2[0] ), 1.f / ( modInCurve2[l] * 0.01f ) ) * ( curModVal2[0] < 0 ? -1 : 1 ) ) + (modInAmnt2[l] * 0.01); + curModVal2Curve[1] = ( (curModVal2[1] <= -1 || curModVal2[1] >= 1) ? curModVal2[1] : pow( abs( curModVal2[0] ), 1.f / ( modInCurve2[l] * 0.01f ) ) * ( curModVal2[0] < 0 ? -1 : 1 ) ) + (modInAmnt2[l] * 0.01); + } + else + { + curModVal2Curve[0] = curModVal2[0] + (modInAmnt2[l] * 0.01); + curModVal2Curve[1] = curModVal2[1] + (modInAmnt2[l] * 0.01); + } + } + + switch( modCombineType[l] ) + { + case 0:// Add Bidirectional + { + comboModVal[0] = curModValCurve[0] + curModVal2Curve[0] - 1; + comboModVal[1] = curModValCurve[1] + curModVal2Curve[1] - 1; + break; + } + case 1:// Multiply Bidirectional + { + comboModVal[0] = ( curModValCurve[0] * 2 - 1 ) * ( curModVal2Curve[0] * 2 - 1 ); + comboModVal[1] = ( curModValCurve[1] * 2 - 1 ) * ( curModVal2Curve[1] * 2 - 1 ); + break; + } + case 2:// Add Unidirectional + { + comboModVal[0] = curModValCurve[0] + curModVal2Curve[0]; + comboModVal[1] = curModValCurve[1] + curModVal2Curve[1]; + break; + } + case 3:// Multiply Unidirectional + { + comboModVal[0] = curModValCurve[0] * curModVal2Curve[0]; + comboModVal[1] = curModValCurve[1] * curModVal2Curve[1]; + break; + } + default: + { + comboModVal[0] = 0; + comboModVal[1] = 0; + } + } + + comboModValMono = ( comboModVal[0] + comboModVal[1] ) * 0.5f; + + switch( modOutSec[l] ) + { + case 0: + { + break; + } + case 1:// Main Oscillator + { + switch( modOutSig[l] ) + { + case 0: + { + break; + } + case 1:// Send input to Morph + { + morph[modOutSecNum[l]-1] = qBound( 0.f, morph[modOutSecNum[l]-1] + comboModValMono*morphMax[modOutSecNum[l]-1], morphMax[modOutSecNum[l]-1] ); + modValType[numberToReset] = 1; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 2:// Send input to Range + { + range[modOutSecNum[l]-1] = qMax( 0.f, range[modOutSecNum[l]-1] + comboModValMono * 16.f ); + modValType[numberToReset] = 2; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 3:// Send input to Modify + { + modify[modOutSecNum[l]-1] = qMax( 0.f, modify[modOutSecNum[l]-1] + comboModValMono * 2048.f ); + modValType[numberToReset] = 3; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 4:// Send input to Pitch/Detune + { + detune[modOutSecNum[l]-1] = detune[modOutSecNum[l]-1] + comboModValMono * 4800.f; + modValType[numberToReset] = 7; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 5:// Send input to Phase + { + phase[modOutSecNum[l]-1] = phase[modOutSecNum[l]-1] + comboModValMono * 8.f; + modValType[numberToReset] = 8; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 6:// Send input to Volume + { + vol[modOutSecNum[l]-1] = qMax( 0.f, vol[modOutSecNum[l]-1] + comboModValMono * 100.f ); + modValType[numberToReset] = 5; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 7:// Send input to Panning + { + pan[modOutSecNum[l]-1] = qMax( 0.f, pan[modOutSecNum[l]-1] + comboModValMono * 200.f ); + modValType[numberToReset] = 6; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 8:// Send input to Unison Voice Number + { + unisonVoices[modOutSecNum[l]-1] = qMax( 0.f, unisonVoices[modOutSecNum[l]-1] + comboModValMono * 32.f ); + modValType[numberToReset] = 14; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 9:// Send input to Unison Detune + { + unisonDetune[modOutSecNum[l]-1] = qMax( 0.f, unisonDetune[modOutSecNum[l]-1] + comboModValMono * 2000.f ); + modValType[numberToReset] = 15; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 10:// Send input to Unison Morph + { + unisonMorph[modOutSecNum[l]-1] = qBound( 0.f, unisonMorph[modOutSecNum[l]-1] + comboModValMono*morphMax[modOutSecNum[l]-1], morphMax[modOutSecNum[l]-1] ); + modValType[numberToReset] = 16; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 11:// Send input to Unison Modify + { + unisonModify[modOutSecNum[l]-1] = qMax( 0.f, unisonModify[modOutSecNum[l]-1] + comboModValMono * 2048.f ); + modValType[numberToReset] = 17; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + default: + { + } + } + break; + } + case 2:// Sub Oscillator + { + switch( modOutSig[l] ) + { + case 0: + { + break; + } + case 1:// Send input to Pitch/Detune + { + subDetune[modOutSecNum[l]-1] = subDetune[modOutSecNum[l]-1] + comboModValMono * 4800.f; + modValType[numberToReset] = 36; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 2:// Send input to Phase + { + subPhase[modOutSecNum[l]-1] = subPhase[modOutSecNum[l]-1] + comboModValMono * 8.f; + modValType[numberToReset] = 37; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 3:// Send input to Volume + { + subVol[modOutSecNum[l]-1] = qMax( 0.f, subVol[modOutSecNum[l]-1] + comboModValMono * 100.f ); + modValType[numberToReset] = 34; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 4:// Send input to Panning + { + subPanning[modOutSecNum[l]-1] = qMax( 0.f, subPanning[modOutSecNum[l]-1] + comboModValMono * 200.f ); + modValType[numberToReset] = 35; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 5:// Send input to Sample Length + { + subSampLen[modOutSecNum[l]-1] = qMax( 1, int( subSampLen[modOutSecNum[l]-1] + comboModValMono * STOREDSUBWAVELEN ) ); + modValType[numberToReset] = 39; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 6:// Send input to Rate Limit + { + subRateLimit[modOutSecNum[l]-1] = qMax( 0.f, subRateLimit[modOutSecNum[l]-1] + comboModValMono * 2.f ); + modValType[numberToReset] = 41; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 7:// Send input to Unison Voice Number + { + subUnisonNum[modOutSecNum[l]-1] = qMax( 1.f, subUnisonNum[modOutSecNum[l]-1] + comboModValMono * 32.f ); + modValType[numberToReset] = 42; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 8:// Send input to Unison Detune + { + subUnisonDetune[modOutSecNum[l]-1] = qMax( 0.f, subUnisonDetune[modOutSecNum[l]-1] + comboModValMono * 2000.f ); + modValType[numberToReset] = 43; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + default: + { + } + } + break; + } + case 3:// Sample Oscillator + { + switch( modOutSig[l] ) + { + case 0: + { + break; + } + case 1:// Send input to Pitch/Detune + { + sampleDetune[modOutSecNum[l]-1] = sampleDetune[modOutSecNum[l]-1] + comboModValMono * 4800.f; + modValType[numberToReset] = 67; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 2:// Send input to Phase + { + samplePhase[modOutSecNum[l]-1] = samplePhase[modOutSecNum[l]-1] + comboModValMono * 8.f; + modValType[numberToReset] = 68; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 3:// Send input to Volume + { + sampleVolume[modOutSecNum[l]-1] = qMax( 0.f, sampleVolume[modOutSecNum[l]-1] + comboModValMono * 100.f ); + modValType[numberToReset] = 65; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 4:// Send input to Panning + { + samplePanning[modOutSecNum[l]-1] = qBound( -100.f, samplePanning[modOutSecNum[l]-1] + comboModValMono * 100.f, 100.f ); + modValType[numberToReset] = 66; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + default: + { + } + } + break; + } + case 4:// Matrix + { + switch( modOutSig[l] ) + { + case 0: + { + break; + } + case 1:// Mod In Amount + { + modInAmnt[modOutSecNum[l]-1] = modInAmnt[modOutSecNum[l]-1] + comboModValMono*100.f; + modValType[numberToReset] = 92; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 2:// Mod In Curve + { + modInCurve[modOutSecNum[l]-1] = qMax( 0.f, modInCurve[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 93; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 3:// Secondary Mod In Amount + { + modInAmnt2[modOutSecNum[l]-1] = modInAmnt2[modOutSecNum[l]-1] + comboModValMono*100.f; + modValType[numberToReset] = 95; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 4:// Secondary Mod In Curve + { + modInCurve2[modOutSecNum[l]-1] = qMax( 0.f, modInCurve2[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 96; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 5:// Mod In + { + modIn[modOutSecNum[l]-1] = qMax( 0.f, modIn[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 90; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 6:// Mod In Num + { + modInNum[modOutSecNum[l]-1] = qMax( 0.f, modInNum[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 91; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 7:// Secondary Mod In + { + modIn2[modOutSecNum[l]-1] = qMax( 0.f, modIn2[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 94; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 8:// Secondary Mod In Num + { + modInNum2[modOutSecNum[l]-1] = qMax( 0.f, modInNum2[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 95; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 9:// Mod Out Sec + { + modOutSec[modOutSecNum[l]-1] = qMax( 0.f, modOutSec[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 98; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 10:// Mod Out Sig + { + modOutSig[modOutSecNum[l]-1] = qMax( 0.f, modOutSig[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 99; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 11:// Mod Out Sec Num + { + modOutSecNum[modOutSecNum[l]-1] = qMax( 0.f, modOutSecNum[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 100; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + } + break; + } + case 5:// Filter Input + { + filtInputs[modOutSig[l]][0] += curModVal[0]; + filtInputs[modOutSig[l]][1] += curModVal[1]; + break; + } + case 6:// Filter Parameters + { + switch( modOutSig[l] ) + { + case 0:// None + { + break; + } + case 1:// Cutoff Frequency + { + filtCutoff[modOutSecNum[l]-1] = qBound( 20.f, filtCutoff[modOutSecNum[l]-1] + comboModValMono*19980.f, 21999.f ); + modValType[numberToReset] = 120; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 2:// Resonance + { + filtReso[modOutSecNum[l]-1] = qMax( 0.0001f, filtReso[modOutSecNum[l]-1] + comboModValMono*16.f ); + modValType[numberToReset] = 121; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 3:// dbGain + { + filtGain[modOutSecNum[l]-1] = filtGain[modOutSecNum[l]-1] + comboModValMono*64.f; + modValType[numberToReset] = 122; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 4:// Filter Type + { + filtType[modOutSecNum[l]-1] = qMax( 0, int(filtType[modOutSecNum[l]-1] + comboModValMono*7.f ) ); + modValType[numberToReset] = 123; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 5:// Filter Slope + { + filtSlope[modOutSecNum[l]-1] = qMax( 0, int(filtSlope[modOutSecNum[l]-1] + comboModValMono*8.f ) ); + modValType[numberToReset] = 124; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 6:// Input Volume + { + filtInVol[modOutSecNum[l]-1] = qMax( 0.f, filtInVol[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 125; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 7:// Output Volume + { + filtOutVol[modOutSecNum[l]-1] = qMax( 0.f, filtOutVol[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 126; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 8:// Wet/Dry + { + filtWetDry[modOutSecNum[l]-1] = qBound( 0.f, filtWetDry[modOutSecNum[l]-1] + comboModValMono*100.f, 100.f ); + modValType[numberToReset] = 127; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 9:// Balance/Panning + { + filtBal[modOutSecNum[l]-1] = qBound( -100.f, filtBal[modOutSecNum[l]-1] + comboModValMono*200.f, 100.f ); + modValType[numberToReset] = 128; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 10:// Saturation + { + filtSatu[modOutSecNum[l]-1] = qMax( 0.f, filtSatu[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 129; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 11:// Feedback + { + filtFeedback[modOutSecNum[l]-1] = qMax( 0.f, filtFeedback[modOutSecNum[l]-1] + comboModValMono*100.f ); + modValType[numberToReset] = 130; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + case 12:// Detune + { + filtDetune[modOutSecNum[l]-1] = filtDetune[modOutSecNum[l]-1] + comboModValMono*4800.f; + modValType[numberToReset] = 131; + modValNum[numberToReset] = modOutSecNum[l]-1; + ++numberToReset; + break; + } + } + break; + } + case 7:// Macro + { + macro[modOutSig[l]] = macro[modOutSig[l]] + comboModValMono * 200.f; + modValType[numberToReset] = 150; + modValNum[numberToReset] = modOutSig[l]; + ++numberToReset; + break; + } + default: + { + } + } + } + } + + //============// + //== FILTER ==// + //============// + + // As much as it may seem like it, this section contains no intentional attempts at obfuscation. + + for( int l = 0; l < maxFiltEnabled; ++l ) + { + if( filtEnabled[l] ) + { + temp1 = filtInVol[l] * 0.01f; + filtInputs[l][0] *= temp1; + filtInputs[l][1] *= temp1; + + if( filtKeytracking[l] ) + { + temp1 = round( sample_rate / detuneWithCents( nph->frequency(), filtDetune[l] ) ); + } + else + { + temp1 = round( sample_rate / detuneWithCents( 440.f, filtDetune[l] ) ); + } + if( filtDelayBuf[l][0].size() < temp1 ) + { + filtDelayBuf[l][0].resize( temp1 ); + filtDelayBuf[l][1].resize( temp1 ); + } + + ++filtFeedbackLoc[l]; + if( filtFeedbackLoc[l] > temp1 - 1 ) + { + filtFeedbackLoc[l] = 0; + } + + filtInputs[l][0] += filtDelayBuf[l][0].at( filtFeedbackLoc[l] ); + filtInputs[l][1] += filtDelayBuf[l][1].at( filtFeedbackLoc[l] ); + + cutoff = filtCutoff[l]; + mode = filtType[l]; + reso = filtReso[l]; + dbgain = filtGain[l]; + Fs = sample_rate; + w0 = D_2PI * cutoff / Fs; + + if( mode == 8 ) + { + f = 2 * cutoff / Fs; + k = 3.6*f - 1.6*f*f - 1; + p = (k+1)*0.5f; + scale = pow( D_E, (1-p)*1.386249f ); + r = reso*scale; + } + + for( int m = 0; m < filtSlope[l] + 1; ++m )// m is the slope number. So if m = 2, then the sound is going from a 24 db to a 36 db slope, for example. + { + if( m ) + { + filtInputs[l][0] = filtOutputs[l][0]; + filtInputs[l][1] = filtOutputs[l][1]; + } + + int formulaType = 1; + if( mode <= 7 ) + { + switch( mode ) + { + case 0:// LP + { + temp1 = cos(w0); + alpha = sin(w0) / (2*reso); + b0 = ( 1 - temp1 ) * 0.5f; + b1 = 1 - temp1; + b2 = b0; + a0 = 1 + alpha; + a1 = -2 * temp1; + a2 = 1 - alpha; + break; + } + case 1:// HP + { + temp1 = cos(w0); + alpha = sin(w0) / (2*reso); + b0 = (1 + temp1) * 0.5f; + b1 = -(1 + temp1); + b2 = b0; + a0 = 1 + alpha; + a1 = -2 * temp1; + a2 = 1 - alpha; + break; + } + case 2:// BP + { + temp2 = sin(w0); + alpha = temp2*sinh( log(2) * 0.5 * reso * w0/temp2 ); + b0 = alpha; + b1 = 0; + b2 = -alpha; + a0 = 1 + alpha; + a1 = -2*cos(w0); + a2 = 1 - alpha; + formulaType = 2; + break; + } + case 3:// Low Shelf + { + temp1 = cos(w0); + A = exp10( dbgain / 40 ); + alpha = sin(w0)/2 * sqrt( (A + 1/A)*(1/reso - 1) + 2 ); + temp2 = 2*sqrt(A)*alpha; + b0 = A*( (A+1) - (A-1)*temp1 + temp2 ); + b1 = 2*A*( (A-1) - (A+1)*temp1 ); + b2 = A*( (A+1) - (A-1)*temp1 - temp2 ); + a0 = (A+1) + (A-1)*temp1 + temp2; + a1 = -2*( (A-1) + (A+1)*temp1 ); + a2 = (A+1) + (A-1)*temp1 - temp2; + break; + } + case 4:// High Shelf + { + temp1 = cos(w0); + A = exp10( dbgain / 40 ); + alpha = sin(w0)/2 * sqrt( (A + 1/A)*(1/reso - 1) + 2 ); + temp2 = 2*sqrt(A)*alpha; + b0 = A*( (A+1) + (A-1)*temp1 + temp2 ); + b1 = -2*A*( (A-1) + (A+1)*temp1 ); + b2 = A*( (A+1) + (A-1)*temp1 - temp2 ); + a0 = (A+1) - (A-1)*temp1 + temp2; + a1 = 2*( (A-1) - (A+1)*temp1 ); + a2 = (A+1) - (A-1)*temp1 - temp2; + break; + } + case 5:// Peak + { + temp1 = -2 * cos(w0); + temp2 = sin(w0); + alpha = temp2*sinh( log(2) * 0.5 * reso * w0/temp2 ); + A = exp10( dbgain / 40 ); + b0 = 1 + alpha*A; + b1 = temp1; + b2 = 1 - alpha*A; + a0 = 1 + alpha/A; + a1 = temp1; + a2 = 1 - alpha/A; + break; + } + case 6:// Notch + { + temp1 = -2 * cos(w0); + temp2 = sin(w0); + alpha = temp2*sinh( log(2) * 0.5 * reso * w0/temp2 ); + b0 = 1; + b1 = temp1; + b2 = 1; + a0 = 1 + alpha; + a1 = temp1; + a2 = 1 - alpha; + break; + } + case 7:// Allpass + { + temp1 = -2 * cos(w0); + alpha = sin(w0) / (2*reso); + b0 = 1 - alpha; + b1 = temp1; + b2 = 1 + alpha; + a0 = b2; + a1 = temp1; + a2 = b0; + formulaType = 3; + break; + } + } + + // Translation of this monstrosity (case 1): y[n] = (b0/a0)*x[n] + (b1/a0)*x[n-1] + (b2/a0)*x[n-2] - (a1/a0)*y[n-1] - (a2/a0)*y[n-2] + // See www.musicdsp.org/files/Audio-EQ-Cookbook.txt + switch( formulaType ) + { + case 1:// Normal + { + temp1 = b0/a0; + temp2 = b1/a0; + temp3 = b2/a0; + temp4 = a1/a0; + temp5 = a2/a0; + filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp2*filtPrevSampIn[l][m][1][0] + temp3*filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear + filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp2*filtPrevSampIn[l][m][1][1] + temp3*filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + break; + } + case 2:// Bandpass + { + temp1 = b0/a0; + temp3 = b2/a0; + temp4 = a1/a0; + temp5 = a2/a0; + filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp3*filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear + filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp3*filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + break; + } + case 3:// Allpass + { + temp1 = b0/a0; + temp2 = b1/a0; + temp4 = a1/a0; + temp5 = a2/a0; + filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp2*filtPrevSampIn[l][m][1][0] + filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear + filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp2*filtPrevSampIn[l][m][1][1] + filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + break; + } + case 4:// Notch + { + temp1 = 1.f/a0; + temp2 = b1/a0; + temp3 = temp1; + temp4 = temp2; + temp5 = a2/a0; + filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp2*filtPrevSampIn[l][m][1][0] + temp3*filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear + filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp2*filtPrevSampIn[l][m][1][1] + temp3*filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + break; + } + } + + //Output results + temp1 = filtOutVol[l] * 0.01f; + filtOutputs[l][0] = filtPrevSampOut[l][m][0][0] * temp1; + filtOutputs[l][1] = filtPrevSampOut[l][m][0][1] * temp1; + + } + else if( mode == 8 ) + { + // Moog 24db Lowpass + filtx[0] = filtInputs[l][0]-r*filty4[0]; + filtx[1] = filtInputs[l][1]-r*filty4[1]; + for( int i = 0; i < 2; ++i ) + { + filty1[i]=filtx[i]*p + filtoldx[i]*p - k*filty1[i]; + filty2[i]=filty1[i]*p+filtoldy1[i]*p - k*filty2[i]; + filty3[i]=filty2[i]*p+filtoldy2[i]*p - k*filty3[i]; + filty4[i]=filty3[i]*p+filtoldy3[i]*p - k*filty4[i]; + filty4[i] = filty4[i] - filty4[i] * filty4[i] * filty4[i] / 6.f; + filtoldx[i] = filtx[i]; + filtoldy1[i] = filty1[i]; + filtoldy2[i] = filty2[i]; + filtoldy3[i] = filty3[i]; + } + temp1 = filtOutVol[l] * 0.01f; + filtOutputs[l][0] = filty4[0] * temp1; + filtOutputs[l][1] = filty4[1] * temp1; + } + + // Calculates Saturation. The algorithm is just y = x ^ ( 1 - saturation ); + if( filtSatu[l] ) + { + temp1 = 1 - ( filtSatu[l] * 0.01f ); + filtOutputs[l][0] = pow( abs( filtOutputs[l][0] ), temp1 ) * ( filtOutputs[l][0] < 0 ? -1 : 1 ); + filtOutputs[l][1] = pow( abs( filtOutputs[l][1] ), temp1 ) * ( filtOutputs[l][1] < 0 ? -1 : 1 ); + } + + // Balance knob wet + if( filtBal[l] ) + { + filtOutputs[l][0] *= filtBal[l] > 0 ? ( 100.f - filtBal[l] ) * 0.01f : 1.f; + filtOutputs[l][1] *= filtBal[l] < 0 ? ( 100.f + filtBal[l] ) * 0.01f : 1.f; + } + + // Wet + if( filtWetDry[l] != 100 ) + { + temp1 = filtWetDry[l] * 0.01f; + filtOutputs[l][0] *= temp1; + filtOutputs[l][1] *= temp1; + } + + // Balance knob dry + if( filtBal[l] ) + { + filtOutputs[l][0] += ( 1.f - ( filtBal[l] > 0 ? ( 100.f - filtBal[l] ) * 0.01f : 1.f ) ) * filtInputs[l][0]; + filtOutputs[l][1] += ( 1.f - ( filtBal[l] < 0 ? ( 100.f + filtBal[l] ) * 0.01f : 1.f ) ) * filtInputs[l][1]; + } + + // Dry + temp1 = 1.f - ( filtWetDry[l] * 0.01f ); + filtOutputs[l][0] += temp1 * filtInputs[l][0]; + filtOutputs[l][1] += temp1 * filtInputs[l][1]; + + // Send back past samples + filtPrevSampIn[l][m][4][0] = filtPrevSampIn[l][m][3][0]; + filtPrevSampIn[l][m][4][1] = filtPrevSampIn[l][m][3][1]; + + filtPrevSampIn[l][m][3][0] = filtPrevSampIn[l][m][2][0]; + filtPrevSampIn[l][m][3][1] = filtPrevSampIn[l][m][2][1]; + + filtPrevSampIn[l][m][2][0] = filtPrevSampIn[l][m][1][0]; + filtPrevSampIn[l][m][2][1] = filtPrevSampIn[l][m][1][1]; + + filtPrevSampIn[l][m][1][0] = filtInputs[l][0]; + filtPrevSampIn[l][m][1][1] = filtInputs[l][1]; + + filtPrevSampOut[l][m][4][0] = filtPrevSampOut[l][m][3][0]; + filtPrevSampOut[l][m][4][1] = filtPrevSampOut[l][m][3][1]; + + filtPrevSampOut[l][m][3][0] = filtPrevSampOut[l][m][2][0]; + filtPrevSampOut[l][m][3][1] = filtPrevSampOut[l][m][2][1]; + + filtPrevSampOut[l][m][2][0] = filtPrevSampOut[l][m][1][0]; + filtPrevSampOut[l][m][2][1] = filtPrevSampOut[l][m][1][1]; + + filtPrevSampOut[l][m][1][0] = filtPrevSampOut[l][m][0][0]; + filtPrevSampOut[l][m][1][1] = filtPrevSampOut[l][m][0][1]; + } + + temp1 = filtFeedback[l] * 0.01f; + filtDelayBuf[l][0][filtFeedbackLoc[l]] = filtOutputs[l][0] * temp1; + filtDelayBuf[l][1][filtFeedbackLoc[l]] = filtOutputs[l][1] * temp1; + + filtInputs[l][0] = 0; + filtInputs[l][1] = 0; + + filtModOutputs[l][0] = filtOutputs[l][0]; + filtModOutputs[l][1] = filtOutputs[l][1]; + + if( filtMuted[l] ) + { + filtOutputs[l][0] = 0; + filtOutputs[l][1] = 0; + } + } + } + + //=====================// + //== MAIN OSCILLATOR ==// + //=====================// + + for( int i = 0; i < maxMainEnabled; ++i )// maxMainEnabled keeps this from looping 8 times every sample, saving some CPU + { + if( enabled[i] ) + { + currentSampLen = sampLen[i] * WAVERATIO; + for( int l = 0; l < unisonVoices[i]; ++l ) + { + sample_morerealindex[i][l] = realfmod( ( sample_realindex[i][l] + ( phase[i] * currentSampLen * 0.01f ) ), currentSampLen );// Calculates phase + + unisonVoicesMinusOne = unisonVoices[i] - 1;// unisonVoices[i] - 1 is needed many times, which is why unisonVoicesMinusOne exists + + if( tempo[i] ) + { + temp1 = tempo[i] / 26400.f; + noteFreq = unisonVoicesMinusOne ? detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, unisonDetuneAmounts[i][l]*unisonDetune[i]+detune[i] ) : detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, detune[i] );// Calculates frequency depending on detune and unison detune + noteFreq *= temp1;// Tempo sync + } + else + { + noteFreq = unisonVoicesMinusOne ? detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, unisonDetuneAmounts[i][l]*unisonDetune[i]+detune[i] ) : detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, detune[i] );// Calculates frequency depending on detune and unison detune + } + + sample_step[i][l] = currentSampLen * ( noteFreq / sample_rate ); + + if( unisonVoicesMinusOne )// Figures out Morph and Modify values for individual unison voices + { + if( unisonMorph[i] ) + { + temp1 = ((unisonVoicesMinusOne-l)/unisonVoicesMinusOne)*unisonMorph[i]; + morph[i] = qBound( 0.f, temp1 - ( unisonMorph[i] * 0.5f ) + morph[i], morphMax[i] ); + } + + if( unisonModify[i] ) + { + temp1 = ((unisonVoicesMinusOne-l)/unisonVoicesMinusOne)*unisonModify[i]; + modify[i] = qBound( 0.f, temp1 - ( unisonModify[i] * 0.5f ) + modify[i], currentSampLen-1.f);// SampleLength - 1 = ModifyMax + } + } + + temp7 = modify[i] * WAVERATIO; + + switch( modifyMode[i] )// Horrifying formulas for the various Modify Modes + { + case 0:// None + { + break; + } + case 1:// Pulse Width + { + sample_morerealindex[i][l] /= ( -temp7 + currentSampLen ) / currentSampLen; + + sample_morerealindex[i][l] = qBound( 0.f, sample_morerealindex[i][l], (float)currentSampLen - 1);// Keeps sample index within bounds + break; + } + case 2:// Weird 1 + { + //The cool result of me messing up. + sample_morerealindex[i][l] = ( ( ( sin( ( ( sample_morerealindex[i][l] / currentSampLen ) * ( temp7 / 50.f ) ) / 2 ) ) * currentSampLen ) * ( temp7 / currentSampLen ) + ( sample_morerealindex[i][l] + ( ( -temp7 + currentSampLen ) / currentSampLen ) ) ) / 2.f; + break; + } + case 3:// Weird 2 + { + //Also the cool result of me messing up. + if( sample_morerealindex[i][l] > currentSampLen / 2.f ) + { + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; + } + else + { + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; + sample_morerealindex[i][l] = sample_morerealindex[i][l] - currentSampLen / 2.f; + } + break; + } + case 4:// Asym To Right + { + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; + break; + } + case 5:// Asym To Left + { + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + break; + } + case 6:// Bidirectional Asym + { + temp1 = temp7 / currentSampLen; + if( temp1 < 0.5 ) + { + temp1 = ( -temp1 + 1 ) / 2.f - 0.25f; + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + } + else + { + temp1 = temp1 / 2.f - 0.25f; + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; + } + break; + } + case 7:// Stretch From Center + { + temp1 = currentSampLen / 2.f; + sample_morerealindex[i][l] -= temp1; + sample_morerealindex[i][l] /= temp1; + sample_morerealindex[i][l] = ( sample_morerealindex[i][l] >= 0 ) ? pow( sample_morerealindex[i][l], 1 / ( ( temp7 * 4 ) / currentSampLen + 1 ) ) : -pow( -sample_morerealindex[i][l], 1 / ( ( temp7 * 4 ) / currentSampLen + 1 ) ); + sample_morerealindex[i][l] *= temp1; + sample_morerealindex[i][l] += temp1; + break; + } + case 8:// Squish To Center + { + temp1 = currentSampLen / 2.f; + sample_morerealindex[i][l] -= temp1; + sample_morerealindex[i][l] /= temp1; + sample_morerealindex[i][l] = ( sample_morerealindex[i][l] >= 0 ) ? pow( sample_morerealindex[i][l], 1 / ( -temp7 / currentSampLen + 1 ) ) : -pow( -sample_morerealindex[i][l], 1 / ( -temp7 / currentSampLen + 1 ) ); + sample_morerealindex[i][l] *= temp1; + sample_morerealindex[i][l] += temp1; + break; + } + case 9:// Stretch And Squish + { + temp1 = currentSampLen / 2.f; + sample_morerealindex[i][l] -= temp1; + sample_morerealindex[i][l] /= temp1; + sample_morerealindex[i][l] = ( sample_morerealindex[i][l] >= 0 ) ? pow( sample_morerealindex[i][l], 1 / ( temp7 * 4 / currentSampLen ) ) : -pow( -sample_morerealindex[i][l], 1 / ( temp7 * 4 / currentSampLen ) ); + sample_morerealindex[i][l] *= temp1; + sample_morerealindex[i][l] += temp1; + break; + } + case 10:// Cut Off Right + { + sample_morerealindex[i][l] *= ( -temp7 + currentSampLen ) / currentSampLen; + break; + } + case 11:// Cut Off Left + { + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + sample_morerealindex[i][l] *= ( -temp7 + currentSampLen ) / currentSampLen; + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + break; + } + case 19:// Sync + { + sample_morerealindex[i][l] *= ( ( temp7 * 16.f ) / currentSampLen ) + 1; + sample_morerealindex[i][l] = fmod( sample_morerealindex[i][l], (float)currentSampLen - 1 ); + break; + } + case 20:// Sync Half Interpolate + { + sample_morerealindex[i][l] *= ( ( temp7 * 16.f ) / currentSampLen ) + 1; + sample_morerealindex[i][l] = fmod( sample_morerealindex[i][l], (float)currentSampLen - 1 ); + break; + } + case 21:// Sync Interpolate + { + sample_morerealindex[i][l] *= ( ( temp7 * 16.f ) / currentSampLen ) + 1; + sample_morerealindex[i][l] = fmod( sample_morerealindex[i][l], (float)currentSampLen - 1 ); + break; + } + case 22:// Mirror + { + sample_morerealindex[i][l] = sample_morerealindex[i][l] < currentSampLen / 2 ? sample_morerealindex[i][l] * 2 : ( -sample_morerealindex[i][l] + currentSampLen ) * 2; + temp1 = temp7 / currentSampLen; + if( temp1 < 0.5 ) + { + temp1 = ( -temp1 + 1 ) / 2.f - 0.25f; + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; + sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + } + else + { + temp1 = temp1 / 2.f - 0.25f; + sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; + } + break; + } + default: + {} + } + + mainsample[i][l] = 0; + + if( modifyMode[i] != 12 && modifyMode[i] != 13 && modifyMode[i] != 23 && modifyMode[i] != 24 )// If NOT Squarify/Pulsify/Diagonal/Sideways Modify Mode + { + loopStart = qMax( 0.f, morph[i] - range[i] ) + 1; + loopEnd = qMin( morph[i] + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; + currentRangeValInvert = 1.f / range[i]; + currentIndex = sample_morerealindex[i][l]; + + // Only grab samples from the waveforms when they will be used, depending on the Range knob + for( int j = loopStart; j < loopEnd; ++j ) + { + // Get waveform samples, set their volumes depending on Range knob + mainsample[i][l] += waveforms[i][currentIndex + j * currentSampLen] * ( 1 - ( abs( morph[i] - j ) * currentRangeValInvert ) ); + } + } + else if( modifyMode[i] == 12 )// If Squarify Modify Mode + { + loopStart = qMax( 0.f, morph[i] - range[i] ) + 1; + loopEnd = qMin( morph[i] + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; + currentRangeValInvert = 1.f / range[i]; + currentIndex = sample_morerealindex[i][l]; + + // Self-made formula, may be buggy. Crossfade one half of waveform with the inverse of the other. + + // Taking these calculations out of the following loop will help with performance with high Range values. + temp2 = temp7 / currentSampLen; + temp3 = temp2; + ++temp2; + temp4 = int( currentIndex + ( currentSampLen * 0.5 ) ) % currentSampLen; + + for( int j = loopStart; j < loopEnd; ++j ) + { + temp1 = 1 - ( abs( morph[i] - j ) * currentRangeValInvert ); + mainsample[i][l] += ( + ( waveforms[i][currentIndex + j * currentSampLen] * temp1 ) + // Normal + ( -waveforms[i][int(temp4) + j * currentSampLen] * temp1 * temp3 ) ) / // Inverted other half of waveform + temp2; // Volume compensation + } + } + else if( modifyMode[i] == 13 )// If Pulsify Modify Mode + { + loopStart = qMax( 0.f, morph[i] - range[i] ) + 1; + loopEnd = qMin( morph[i] + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; + currentRangeValInvert = 1.f / range[i]; + currentIndex = sample_morerealindex[i][l]; + + // Self-made formula, may be buggy. Crossfade one side of waveform with the inverse of the other. + + // Taking this calculation out of the following loop will help with performance with high Range values. + temp2 = ( currentIndex + int( currentSampLen * ( temp7 / currentSampLen ) ) ) % currentSampLen; + + for( int j = loopStart; j < loopEnd; ++j ) + { + temp1 = 1 - ( abs( morph[i] - j ) * currentRangeValInvert ); + mainsample[i][l] += ( + ( waveforms[i][currentIndex + j * currentSampLen] * temp1 ) + // Normal + ( ( -waveforms[i][int(temp2) + j * currentSampLen] * temp1 ) ) ) * // Inverted other side of waveform + 0.5f; // Volume compensation + } + } + else if( modifyMode[i] == 23 )// If Diagonal Modify Mode + { + temp5 = realfmod( morph[i] + ( sample_morerealindex[i][l] * temp7 / currentSampLen / 32.f ), morphMax[i] ); + loopStart = temp5 - range[i] + 1; + loopEnd = temp5 + range[i] + 1; + currentRangeValInvert = 1.f / range[i]; + currentIndex = sample_morerealindex[i][l]; + + // Quite experimental, morph value is changed depending on wavetable position. + for( int j = loopStart; j < loopEnd; ++j ) + { + temp3 = realfmod( j, morphMax[i] ); + mainsample[i][l] += waveforms[i][currentIndex + (int)temp3 * currentSampLen] * ( 1 - ( abs( temp5 - j ) * currentRangeValInvert ) ); + } + } + else if( modifyMode[i] == 24 )// If Sideways Modify Mode + { + temp5 = sample_morerealindex[i][l] / currentSampLen * morphMax[i]; + loopStart = qMax( 0.f, temp5 - range[i] ) + 1; + loopEnd = qMin( temp5 + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; + currentRangeValInvert = 1.f / range[i]; + currentIndex = temp7; + + // Quite experimental, swap the Morph value (now controlled using Modify) and the location in the waveform. + for( int j = loopStart; j < loopEnd; ++j ) + { + // Get waveform samples, set their volumes depending on Range knob + mainsample[i][l] += waveforms[i][currentIndex + j * currentSampLen] * ( 1 - ( abs( temp5 - j ) * currentRangeValInvert ) ); + } + } + + switch( modifyMode[i] )// More horrifying formulas for the various Modify Modes + { + case 1:// Pulse Width + { + if( sample_realindex[i][l] / ( ( -temp7 + currentSampLen ) / currentSampLen ) > currentSampLen ) + { + mainsample[i][l] = 0; + } + break; + } + case 14:// Flip + { + if( sample_realindex[i][l] > temp7 ) + { + mainsample[i][l] *= -1; + } + break; + } + case 15:// Clip + { + temp1 = temp7 / ( currentSampLen - 1 ); + mainsample[i][l] = qBound( -temp1, mainsample[i][l], temp1 ); + break; + } + case 16:// Inverse Clip + { + temp1 = temp7 / ( currentSampLen - 1 ); + if( mainsample[i][l] > 0 && mainsample[i][l] < temp1 ) + { + mainsample[i][l] = temp1; + } + else if( mainsample[i][l] < 0 && mainsample[i][l] > -temp1 ) + { + mainsample[i][l] = -temp1; + } + break; + } + case 17:// Sine + { + temp1 = temp7 / ( currentSampLen - 1 ); + mainsample[i][l] = sin( mainsample[i][l] * ( D_PI * temp1 * 8 + 1 ) ); + break; + } + case 18:// Atan + { + temp1 = temp7 / ( currentSampLen - 1 ); + mainsample[i][l] = atan( mainsample[i][l] * ( D_PI * temp1 * 8 + 1 ) ); + break; + } + case 20:// Sync Half Interpolate + { + temp1 = currentSampLen / 2.f; + temp2 = currentSampLen / 4.f; + if( sample_realindex[i][l] < temp2 || sample_realindex[i][l] > 3.f * temp2 ) + { + mainsample[i][l] *= ( -abs( sample_realindex[i][l] - temp1 ) + temp1 ) / currentSampLen * 4.f; + } + break; + } + case 21:// Sync Interpolate + { + temp1 = currentSampLen / 2.f; + mainsample[i][l] *= ( -abs( sample_realindex[i][l] - temp1 ) + temp1 ) / currentSampLen * 2.f; + break; + } + default: + {} + } + + sample_realindex[i][l] += sample_step[i][l]; + + // check overflow + while( sample_realindex[i][l] >= currentSampLen ) + { + sample_realindex[i][l] -= currentSampLen; + lastMainOscEnvDone[l] = true; + } + + mainsample[i][l] *= vol[i] * 0.01f; + } + } + } + + //====================// + //== SUB OSCILLATOR ==// + //====================// + + for( int i = 0; i < maxSubEnabled; ++i )// maxSubEnabled keeps this from looping 64 times every sample, saving a lot of CPU + { + if( subEnabled[i] ) + { + if( !subNoise[i] ) + { + temp2 = subPhase[i] * subSampLen[i]; + temp3 = subVol[i] * 0.01f; + temp4 = subSampLen[i] * WAVERATIO; + + for( int l = 0; l < subUnisonNum[i]; ++l ) + { + subUnisonVoicesMinusOne = subUnisonNum[i] - 1;// subUnisonNum[i] - 1 is needed many times, which is why subUnisonVoicesMinusOne exists + + if( !subUnisonVoicesMinusOne ) + { + if( subTempo[i] ) + { + temp1 = subTempo[i] / 26400.f; + noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subDetune[i] ) * temp1 : detuneWithCents( 440.f, subDetune[i] ) * temp1; + } + else + { + noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subDetune[i] ) : detuneWithCents( 440.f, subDetune[i] ); + } + } + else + { + if( subTempo[i] ) + { + temp1 = subTempo[i] / 26400.f; + noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ) * temp1 : detuneWithCents( 440.f, subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ) * temp1; + } + else + { + noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ) : detuneWithCents( 440.f, subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ); + } + } + + sample_step_sub = temp4 / ( sample_rate / noteFreq ); + + subsample[i][l] = temp3 * subs[i][int( realfmod( sample_subindex[i][l] + temp2, temp4 ) )]; + + sample_subindex[i][l] += sample_step_sub; + + // move waveform position back if it passed the end of the waveform + while ( sample_subindex[i][l] >= temp4 ) + { + sample_subindex[i][l] -= temp4; + lastSubEnvDone[i] = true; + } + + /* That is all that is needed for the sub oscillator calculations. + + (To the tune of Hallelujah) + + There was a Happy CPU + No processing power to chew through + In this wonderful synthesis brew + Hallelujah + + But with some wavetable synthesis + Your CPU just blows a kiss + And leaves you there despite your miss + Hallelujah + + Hallelujah, Hallelujah, Hallelujah, Halleluuu-uuuuuuuu-uuuujah + + Your music ambition lays there, dead + Can't get your ideas out of your head + Because your computer's slower than lead + Hallelujah + + Sometimes you may try and try + To keep your ping from saying goodbye + Leaving you to die and cry + Hallelujah + + Hallelujah, Hallelujah, Hallelujah, Halleluuu-uuuuuuuu-uuuujah + + But what is this, an alternative? + Sub oscillators supported native + To deter CPU obliteratives + Hallelujah + + Your music has come back to life + CPU problems cut off like a knife + Sub oscillators removing your strife + Hallelujah + + Hallelujah, Hallelujah, Hallelujah, Halleluuu-uuuuuuuu-uuuujah + + *cool outro* + + */ + } + } + else// sub oscillator is noise + { + temp2 = subVol[i] * 0.01f; + for( int l = 0; l < subUnisonNum[i]; ++l ) + { + noiseSampRand = fastRandf( subSampLen[l] ) - 1; + + temp1 = ( storedsubs[i][int(noiseSampRand)] * subNoiseDirection[i][l] ) + lastSubNoiseVal[i][l]; + if( temp1 > 1 || temp1 < -1 ) + { + subNoiseDirection[i][l] *= -1; + temp1 = ( storedsubs[i][int( noiseSampRand )] * subNoiseDirection[i][l] ) + lastSubNoiseVal[i][l]; + } + + lastSubNoiseVal[i][l] = temp1; + + subsample[i][l] = temp1 * temp2; + } + } + } + } + + //=======================// + //== SAMPLE OSCILLATOR ==// + //=======================// + + for( int l = 0; l < maxSampleEnabled; ++l )// maxSampleEnabled keeps this from looping 8 times every sample, saving some CPU + { + int sampleSize = samples[l][0].size() * sampleEnd[l]; + if( sampleEnabled[l] && ( sample_sampleindex[l] < sampleSize || sampleLoop[l] ) ) + { + if( sampleLoop[l] ) + { + if( sample_sampleindex[l] > sampleSize ) + { + sample_sampleindex[l] = sample_sampleindex[l] - sampleSize + ( samples[l][0].size() * sampleStart[l] ); + lastSampleEnvDone[l] = true; + } + } + + sample_step_sample = ( detuneWithCents( sampleKeytracking[l] ? nph->frequency() : 440.f, sampleDetune[l] ) / 440.f ) * ( 44100.f / sample_rate ); + + if( sampleGraphEnabled[l] && sampleStart[l] < sampleEnd[l] ) + { + progress = realfmod( ( sample_sampleindex[l] + ( samplePhase[l] * sampleSize * 0.01f ) ), sampleSize ) / sampleSize * 128.f; + intprogress = (int)progress; + + temp1 = fmod( progress, 1 ); + progress2 = sampGraphs[intprogress] * ( 1 - temp1 ); + + if( intprogress < 127 ) + { + progress3 = sampGraphs[intprogress+1] * temp1; + } + else + { + progress3 = sampGraphs[intprogress] * temp1; + } + + temp1 = int( ( ( progress2 + progress3 + 1 ) * 0.5f ) * sampleSize ); + samplesample[l][0] = samples[l][0][temp1]; + samplesample[l][1] = samples[l][1][temp1]; + } + else + { + temp1 = realfmod(( sample_sampleindex[l] + ( samplePhase[l] * sampleSize * 0.01f ) ), sampleSize); + samplesample[l][0] = samples[l][0][temp1]; + samplesample[l][1] = samples[l][1][temp1]; + } + + temp1 = sampleVolume[l] * 0.01f; + samplesample[l][0] *= temp1; + samplesample[l][1] *= temp1; + + if( samplePanning[l] < 0 ) + { + samplesample[l][1] *= ( 100.f + samplePanning[l] ) * 0.01f; + } + else if( samplePanning[l] > 0 ) + { + samplesample[l][0] *= ( 100.f - samplePanning[l] ) * 0.01f; + } + + lastSampleVal[l][0] = samplesample[l][0];// Store value for modulation + lastSampleVal[l][1] = samplesample[l][1];// Store value for modulation + + if( !lastSampleEnvDone[l] ) + { + lastSampleEnvVal[l][0] = lastSampleVal[l][0]; + lastSampleEnvVal[l][1] = lastSampleVal[l][1]; + } + + if( sampleMuted[l] ) + { + samplesample[l][0] = 0; + samplesample[l][1] = 0; + } + + sample_sampleindex[l] += sample_step_sample; + } + } + + outputSample[0] = 0; + outputSample[1] = 0; + // Main Oscillator outputs + for( int i = 0; i < maxMainEnabled; ++i ) + { + if( enabled[i] ) + { + unisonVoicesMinusOne = unisonVoices[i] - 1; + + if( unisonVoicesMinusOne ) + { + sampleMainOsc[0] = 0; + sampleMainOsc[1] = 0; + for( int j = 0; j < unisonVoices[i]; ++j ) + { + // Pan unison voices + sampleMainOsc[0] += mainsample[i][j] * ((unisonVoicesMinusOne-j)/unisonVoicesMinusOne); + sampleMainOsc[1] += mainsample[i][j] * (j/unisonVoicesMinusOne); + } + // Decrease volume so more unison voices won't increase volume too much + temp1 = unisonVoices[i] * 0.5f; + sampleMainOsc[0] /= temp1; + sampleMainOsc[1] /= temp1; + } + else + { + sampleMainOsc[0] = mainsample[i][0]; + sampleMainOsc[1] = mainsample[i][0]; + } + + if( pan[i] ) + { + if( pan[i] < 0 ) + { + sampleMainOsc[1] *= ( 100.f + pan[i] ) * 0.01f; + } + else + { + sampleMainOsc[0] *= ( 100.f - pan[i] ) * 0.01f; + } + } + + lastMainOscVal[i][0] = sampleMainOsc[0];// Store results for modulations + lastMainOscVal[i][1] = sampleMainOsc[1]; + + // second half of "if" statement makes sure the last envelope value is the last value of the graph (not of the waveform), so the sinc interpolation doesn't ruin things. + if( !lastMainOscEnvDone[i] && sample_realindex[i][0] <= sampLen[i] * WAVERATIO - ( WAVERATIO * 2 ) ) + { + lastMainOscEnvVal[i][0] = lastMainOscVal[i][0]; + lastMainOscEnvVal[i][1] = lastMainOscVal[i][1]; + } + + if( !muted[i] ) + { + outputSample[0] += sampleMainOsc[0]; + outputSample[1] += sampleMainOsc[1]; + } + } + } + + // Sub Oscillator outputs + for( int i = 0; i < maxSubEnabled; ++i ) + { + if( subEnabled[i] ) + { + if( subUnisonNum[i] > 1 ) + { + subUnisonVoicesMinusOne = subUnisonNum[i] - 1; + + sampleSubOsc[0] = 0; + sampleSubOsc[1] = 0; + for( int j = 0; j < subUnisonNum[i]; ++j ) + { + // Pan unison voices + sampleSubOsc[0] += subsample[i][j] * ((subUnisonVoicesMinusOne-j)/subUnisonVoicesMinusOne); + sampleSubOsc[1] += subsample[i][j] * (j/subUnisonVoicesMinusOne); + } + // Decrease volume so more unison voices won't increase volume too much + temp1 = subUnisonNum[i] * 0.5f; + sampleSubOsc[0] /= temp1; + sampleSubOsc[1] /= temp1; + } + else + { + sampleSubOsc[0] = subsample[i][0]; + sampleSubOsc[1] = subsample[i][0]; + } + + if( subPanning[i] ) + { + if( subPanning[i] < 0 ) + { + sampleSubOsc[1] *= ( 100.f + subPanning[i] ) * 0.01f; + } + else + { + sampleSubOsc[0] *= ( 100.f - subPanning[i] ) * 0.01f; + } + } + + if( subRateLimit[i] ) + { + sampleSubOsc[0] = lastSubVal[i][0] + qBound( -subRateLimit[i], sampleSubOsc[0] - lastSubVal[i][0], subRateLimit[i] ); + sampleSubOsc[1] = lastSubVal[i][1] + qBound( -subRateLimit[i], sampleSubOsc[1] - lastSubVal[i][1], subRateLimit[i] ); + } + + lastSubVal[i][0] = sampleSubOsc[0];// Store results for modulations + lastSubVal[i][1] = sampleSubOsc[1]; + + // second half of "if" statement makes sure the last envelope value is the last value of the graph (not of the waveform), so the sinc interpolation doesn't ruin things. + if( !lastSubEnvDone[i] && sample_subindex[i][0] <= subSampLen[i] * WAVERATIO - ( WAVERATIO * 2 ) ) + { + lastSubEnvVal[i][0] = lastSubVal[i][0]; + lastSubEnvVal[i][1] = lastSubVal[i][1]; + } + + if( !subMuted[i] ) + { + outputSample[0] += sampleSubOsc[0]; + outputSample[1] += sampleSubOsc[1]; + } + } + } + + // Sample Oscillator outputs + for( int l = 0; l < maxSampleEnabled; ++l )// maxSampleEnabled keeps this from looping 8 times every sample, saving some CPU + { + if( sampleEnabled[l] ) + { + outputSample[0] += samplesample[l][0]; + outputSample[1] += samplesample[l][1]; + } + } + + // Filter outputs + for( int l = 0; l < maxFiltEnabled; ++l )// maxFiltEnabled keeps this from looping 8 times every sample, saving some CPU + { + if( filtEnabled[l] ) + { + outputSample[0] += filtOutputs[l][0]; + outputSample[1] += filtOutputs[l][1]; + } + } + + // Refresh all modulated values back to the value of the knob. + for( int i = 0; i < numberToReset; ++i ) + { + refreshValue( modValType[i], modValNum[i], mwc ); + } + numberToReset = 0; + + if( removeDC ) + { + averageSampleValue[0] = ( averageSampleValue[0] * 0.999f ) + ( outputSample[0] * 0.001f ); + averageSampleValue[1] = ( averageSampleValue[1] * 0.999f ) + ( outputSample[1] * 0.001f ); + + outputSample[0] -= averageSampleValue[0]; + outputSample[1] -= averageSampleValue[1]; + } +} + + +// Takes input of original Hz and the number of cents to detune it by, and returns the detuned result in Hz. +inline float mSynth::detuneWithCents( float pitchValue, float detuneValue ) +{ + if( detuneValue )// Avoids expensive exponentiation if no detuning is necessary + { + return pitchValue * std::exp2( detuneValue / 1200.f ); + } + else + { + return pitchValue; + } +} + + +// At the end of mSynth::nextStringSample, this will refresh all modulated values back to the value of the knob. +inline void mSynth::refreshValue( int which, int num, Microwave * mwc ) +{ + switch( which ) + { + case 1: morph[num] = mwc->morph[num]->value(); break; + case 2: range[num] = mwc->range[num]->value(); break; + case 3: modify[num] = mwc->modify[num]->value(); break; + case 4: modifyMode[num] = mwc->modifyMode[num]->value(); break; + case 5: vol[num] = mwc->vol[num]->value(); break; + case 6: pan[num] = mwc->pan[num]->value(); break; + case 7: detune[num] = mwc->detune[num]->value(); break; + case 8: phase[num] = mwc->phase[num]->value(); break; + case 9: phaseRand[num] = mwc->phaseRand[num]->value(); break; + case 10: enabled[num] = mwc->enabled[num]->value(); break; + case 11: muted[num] = mwc->muted[num]->value(); break; + case 12: sampLen[num] = mwc->sampLen[num]->value(); break; + case 13: morphMax[num] = mwc->morphMax[num]->value(); break; + case 14: unisonVoices[num] = mwc->unisonVoices[num]->value(); break; + case 15: unisonDetune[num] = mwc->unisonDetune[num]->value(); break; + case 16: unisonMorph[num] = mwc->unisonMorph[num]->value(); break; + case 17: unisonModify[num] = mwc->unisonModify[num]->value(); break; + case 18: keytracking[num] = mwc->keytracking[num]->value(); break; + case 19: tempo[num] = mwc->tempo[num]->value(); break; + case 20: interpolate[num] = mwc->interpolate[num]->value(); break; + + case 30: subEnabled[num] = mwc->subEnabled[num]->value(); break; + case 31: subMuted[num] = mwc->subMuted[num]->value(); break; + case 32: subKeytrack[num] = mwc->subKeytrack[num]->value(); break; + case 33: subNoise[num] = mwc->subNoise[num]->value(); break; + case 34: subVol[num] = mwc->subVol[num]->value(); break; + case 35: subPanning[num] = mwc->subPanning[num]->value(); break; + case 36: subDetune[num] = mwc->subDetune[num]->value(); break; + case 37: subPhase[num] = mwc->subPhase[num]->value(); break; + case 38: subPhaseRand[num] = mwc->subPhaseRand[num]->value(); break; + case 39: subSampLen[num] = mwc->subSampLen[num]->value(); break; + case 40: subTempo[num] = mwc->subTempo[num]->value(); break; + case 41: subRateLimit[num] = mwc->subRateLimit[num]->value(); break; + case 42: subUnisonNum[num] = mwc->subUnisonNum[num]->value(); break; + case 43: subUnisonDetune[num] = mwc->subUnisonDetune[num]->value(); break; + case 44: subInterpolate[num] = mwc->subInterpolate[num]->value(); break; + + case 60: sampleEnabled[num] = mwc->sampleEnabled[num]->value(); break; + case 61: sampleMuted[num] = mwc->sampleMuted[num]->value(); break; + case 62: sampleKeytracking[num] = mwc->sampleKeytracking[num]->value(); break; + case 63: sampleGraphEnabled[num] = mwc->sampleGraphEnabled[num]->value(); break; + case 64: sampleLoop[num] = mwc->sampleLoop[num]->value(); break; + case 65: sampleVolume[num] = mwc->sampleVolume[num]->value(); break; + case 66: samplePanning[num] = mwc->samplePanning[num]->value(); break; + case 67: sampleDetune[num] = mwc->sampleDetune[num]->value(); break; + case 68: samplePhase[num] = mwc->samplePhase[num]->value(); break; + case 69: samplePhaseRand[num] = mwc->samplePhaseRand[num]->value(); break; + case 70: sampleStart[num] = mwc->sampleStart[num]->value(); break; + case 71: sampleEnd[num] = mwc->sampleEnd[num]->value(); break; + + case 90: modIn[num] = mwc->modIn[num]->value(); break; + case 91: modInNum[num] = mwc->modInNum[num]->value(); break; + case 92: modInAmnt[num] = mwc->modInAmnt[num]->value(); break; + case 93: modInCurve[num] = mwc->modInCurve[num]->value(); break; + case 94: modIn2[num] = mwc->modIn2[num]->value(); break; + case 95: modInNum2[num] = mwc->modInNum2[num]->value(); break; + case 96: modInAmnt2[num] = mwc->modInAmnt2[num]->value(); break; + case 97: modInCurve2[num] = mwc->modInCurve2[num]->value(); break; + case 98: modOutSec[num] = mwc->modOutSec[num]->value(); break; + case 99: modOutSig[num] = mwc->modOutSig[num]->value(); break; + case 100: modOutSecNum[num] = mwc->modOutSecNum[num]->value(); break; + case 101: modEnabled[num] = mwc->modEnabled[num]->value(); break; + case 102: modCombineType[num] = mwc->modCombineType[num]->value(); break; + case 103: modType[num] = mwc->modType[num]->value(); break; + case 104: modType2[num] = mwc->modType2[num]->value(); break; + + case 120: filtCutoff[num] = mwc->filtCutoff[num]->value(); break; + case 121: filtReso[num] = mwc->filtReso[num]->value(); break; + case 122: filtGain[num] = mwc->filtGain[num]->value(); break; + case 123: filtType[num] = mwc->filtType[num]->value(); break; + case 124: filtSlope[num] = mwc->filtSlope[num]->value(); break; + case 125: filtInVol[num] = mwc->filtInVol[num]->value(); break; + case 126: filtOutVol[num] = mwc->filtOutVol[num]->value(); break; + case 127: filtWetDry[num] = mwc->filtWetDry[num]->value(); break; + case 128: filtBal[num] = mwc->filtBal[num]->value(); break; + case 129: filtSatu[num] = mwc->filtSatu[num]->value(); break; + case 130: filtFeedback[num] = mwc->filtFeedback[num]->value(); break; + case 131: filtDetune[num] = mwc->filtDetune[num]->value(); break; + case 132: filtEnabled[num] = mwc->filtEnabled[num]->value(); break; + case 133: filtMuted[num] = mwc->filtMuted[num]->value(); break; + case 134: filtKeytracking[num] = mwc->filtKeytracking[num]->value(); break; + + case 150: macro[num] = mwc->macro[num]->value(); break; + } +} + + +// Handles negative values properly, unlike fmod. +inline float mSynth::realfmod( float k, float n ) +{ + return ((k = fmod(k,n)) < 0) ? k+n : k; +} + + + + + + + + + + + + + +QString MicrowaveManualView::s_manualText= +"HOW TO OPERATE YOUR MICROWAVE
" +"
" +"Table of Contents:
" +"
" +"1. Feature Overview
" +" a. Wavetable tab
" +" b. Sub Oscillator Tab
" +" c. Sample Tab
" +" d. Matrix Tab
" +" e. Filter Tab
" +" f. Miscellaneous Tab
" +" g. Other features to be aware of
" +"2. CPU Preservation Guidelines
" +"3. FAQ
" +"
" +"
" +"
" +"
" +"
" +"
" +"==FEATURE OVERVIEW==
" +"
" +"
" +"-=WAVETABLE TAB=-
" +"
" +"If you zoom in all the way on a sound or waveform, you'll see these little \"audio pixels\". These are called \"samples\", not to be confused with the common term \"sound sample\" which refers to any stored piece of audio. These \"audio pixels\" can easily be seen when using LMMS's BitInvader.
" +"
" +"A \"wavetable synthesizer\" is a synthesizer that stores its waveforms as a list of samples. This means synthesizers like BitInvader and WatSyn are technically wavetable synthesizers. But, the term \"wavetable synthesizer\" more commonly (but not more or less correctly) refers to a synthesizer that stores multiple waveforms, plays one waveform and repeats it, and allows the user to move a knob to change which waveform is being played. Synthesizers of this nature, even the basic ones, are unimaginably powerful. Microwave is one of them.
" +"
" +"Microwave's wavetables have 256 waveforms, at 2048 samples each. The Morph (MPH) knob chooses which of the 256 waveforms in the wavetable to play. It is important to note that Microwave does not have any wavetable loaded by default, so no sound will be heard currently. Load a sound file as a wavetable now (click the folder button at the bottom). If you play a note while moving the Morph knob, you'll notice the waveform that is playing morphing to create new timbres.
" +"
" +"Range (RNG) is a feature unique to Microwave. It takes waveforms in the wavetable near the one chosen by the Morph one, and mixes those in with the main waveform (at a lower volume as you get further away from the main waveform). For example, a Morph of 5 and a Range of 2 will give you a mix between waveform 5, waveform 4 at half volume, and waveform 6 at half volume.
" +"
" +"MDFY (Modify) and the dropdown box next to it (Modify Mode) are used to warp your wavetable realtime, using formulas I created myself. Change the Modify Mode and move the Modify knob while playing a note. Hear how each Modify Mode causes a drastically different change to the sound. These are extremely useful for injecting more flavor and awesomeness into your sound. Use all of them to learn what they can do.
" +"
" +"DET stands for Detune, which changes the pitch of that oscillator, in cents. PHS stands for Phase, which simply phase shifts the oscillator, and RAND next to it is Phase Randomness, which sets the oscillator to a random phase with each note.
" +"
" +"The arrow button under the tab list can be clicked to expose more knobs.
" +"
" +"When the tempo (BPM) knob is set to anything other than 0, the pitch is decreased drastically (you'll probably want to mute it) so that it perfectly matches up with the set tempo when detune is set to 0. If you need it at half speed, double speed, etc., just change its pitch by octaves (because increasing by an octave doubles the frequency).
" +"
" +"The Morph Max knob (MAX) just changes the maximum value of the Morph knob, for tweaking convenience.
" +"
" +"Microwave supports very advanced unison abillities. Unison is when you clone the oscillator multiple times, and play them all at the same time, usually with slight differences applied to them. The original sound as well as the clones are called \"voices\". In the UNISON box, NUM chooses the number of voices. DET detunes each voice slightly, a common unison feature. MPH and MOD are special. They change the Morph and Modify (respectively) values for each individual voice, which can create an amazing 3D sound. It is important to note that every unison voice is calculated individually, so using large numbers of unison voices can be very detrimental to your CPU.
" +"
" +"Earlier I mentioned that Microwave's wavetables have 256 waveforms, at 2048 samples each. This can be changed using the Sample Length knob. This knob can be used for finetuning your wavetable if the loading was slightly inaccurate. If you notice your waveform moving left/right too much in the visualizer as you morph through the wavetable, the Sample Length knob may be able to fix that.
" +"
" +"With most wavetable synthesizers, CPU would be a major concern. Luckily, I have put an obscene amount of work into optimizing Microwave, so this should be much less of a problem. Feel free to go crazy.
" +"
" +"Explanations on how to use this for modulation is explained in the Matrix Tab section.
" +"
" +"
" +"-=SUB TAB=-
" +"
" +"This tab behaves a lot like BitInvader, but is significantly more useful in the context of Microwave. This tab is meant to be used for many things:
" +"1. Single-waveform oscillators/modulators
" +"2. LFOs
" +"3. Envelopes
" +"4. Step Sequencers
" +"5. Noise Generators
" +"
" +"In very early versions of Microwave, the five things listed above were all in their own tabs, and were later combined into one for obvious user-friendliness reasons. I would like to quickly note here that I implore all of you to use Step Sequencers in Microwave all the time. I wanted it to be one of the more highlighted features of Microwave, but never really had the chance. Step Sequencers are an awesome and unique way to add rhythmic modulations to your sound.
" +"
" +"The LENGTH knob changes the length of the oscillator. Decreasing this to a small number makes it very easy to use this as a Step Sequencer. In some special cases you may also want to automate this knob for some interesting effects.
" +"
" +"There are four LEDs you can see at the bottom. The top left is whether the oscillator is enabled. The top right is \"Muted\", which is different. When an oscillator is enabled but muted, it is still calculated and still used for modulation, but that oscillator's sound is never played. You'll usually want this on when using this as an envelope/LFO/step sequencer. The bottom left is keytracking. When keytracking is disabled, the oscillator always plays at the same frequency regardless of the note you press. You'll want to turn this off when you need your envelopes/LFOs/step sequencers to always go at the same speed. The bottom right LED converts the oscillator into a noise generator, which generates a different flavor of noise depending on the graph you draw.
" +"
" +"The Rate Limit knob (RATE) controls how quickly the waveform can increase or decrease. Combined with the noise generator, this could potentially be used as a chaos oscillator in the Matrix tab.
" +"
" +"Explanations on how to use this for modulation is explained in the Matrix Tab section.
" +"
" +"
" +"-=SAMPLE TAB=-
" +"
" +"This tab is used to import entire samples to use as oscillators. This means you can frequency modulate your cowbells with your airhorns, which you can then phase modulate with an ogre yelling about his swamp, which you can then amplitude modulate with a full-length movie about bees. Alternatively, you could just use it as a simple way to layer in a sound or some noise sample with the sound you have already created. It is important to note that imported samples are stored within Microwave, which means two things:
" +"1. Unlike AudioFileProcessor, where the size of the sample does not impact the project file size, any samples in Microwave will be losslessly stored inside the project file and preset, which can make the project file extremely large.
" +"2. When sending your project file or Microwave preset to somebody else, they do not need to have the sample to open it, unlike with AudioFileProcessor.
" +"
" +"With that being said, Microwave's Sample Tab is not meant as a replacement to AudioFileProcessor. Microwave will use more CPU, and some audio problems may show up when playing notes other than A4 (e.g. unstable pitch and stuff). In most cases, if what you want can be done with AudioFileProcessor, you should use AudioFileProcessor. Otherwise, totally use Microwave. The Sample Tab is useful for many reasons, especially for its modulation capabilities and the weird way Microwave can morph samples depending on its graph waveform.
" +"
" +"The Sample Tab has two new knobs. Those change the start and end position of the sample.
" +"
" +"There are two new LEDs for this tab, at the right. The second to last one enables the graph. The graph determines the order in which the sample is played. A saw wave will play the sample normally, and a reverse wave wave will play it backward. Draw a random squiggle on it and... well, you'll hear it. Pretty much, left/right is time, up/down is position in the sample. Note that this will almost definitely change the pitch in most circumstances, because changing a sound's speed also changes its pitch. The last LED enables and disabled sample looping.
" +"
" +"
" +"-=MATRIX TAB=-
" +"
" +"This tab is used for a lot of things, ranging from modulation, effect routing, humanization, etc. If you think it looks difficult, it's a lot easier than it looks. If you think it looks easy, it's much more difficult than it looks.
" +"
" +"The matrix works by taking one or two inputs (whether it be from an oscillator, effect output, humanizer, or anything else) and outputting it somewhere (e.g. to control/modulate a knob, to an effect input, etc.). It's fairly simple.
" +"
" +"Notice how there are three rows. Only focus on the top two, as the top and bottom ones are functionally identical. The top left dropdown box chooses the matrix input, and the LCD Spinboxes choose which input (e.g. which oscillator, which filter, etc.) to grab from. The AMT knob chooses the Amount of the input that is fed into the output (e.g. input volume to effect, how much to move a knob by, etc.). The CRV (Curve) knob gives that input a bias upward or downward, which can be used as a simple way to shape and sculpt your modulations in interesting ways. The LED to the right of that converts the input from an LFO to an envelope, if applicable. In other words, it ignores repetitions of the input oscillators.
" +"
" +"The middle left dropdown box sends which section to send the output to (e.g. which tab), and the dropdown box to the right of it is more specific (e.g. the Morph knob of the main tab, the third filter, etc.), as well as the LCD Spinbox following (for e.g. which oscillator to send it to). The dropdown box to the right of that lets you choose between unidirectional and bidirectional modulation, as well as choosing how the two inputs are combined (e.g. add vs multiply).
" +"
" +"It seems simple, but this section is one of the most important parts of Microwave. Most synthesizers only have some combination of FM, PM, AM, and PWM modulation types. Because of how Microwave's matrix tab is set up, allowing any parameter to be controlled by any oscillator at any speed, Microwave has those modulation types as well as over a hundred more. Welcome to Choice Paralysis. There will never be any point in time when the amount of choice you have will not overwhelm you. Have fun with your freedom!
" +"
" +"
" +"-=EFFECT TAB=-
" +"(temporarily AKA Filter Tab)
" +"
" +"The current version of Microwave only has filters for effects, but that will be changed in future versions.
" +"
" +"FREQ is the filter's cutoff frequency, and RESO is the filter's resonance. GAIN is the gain for peak filters, shelf filters, etc. TYPE is the type of filter. Microwave currently has lowpass, highpass, bandpass, peak, notch, low shelf, high shelf, allpass, and moog lowpass filters. SLOPE runs the sound through the filter multiple times, changing the filter's slope at (usually) increments of 12 db.
" +"
" +"IN and OUT are volume knobs for the filter's input and output. W/D is Wet/Dry. PAN changes the Wet/Dry amount in individual ears, allowing you to use interesting panning filters. SAT stands for Saturation, which allows you to add some simple distortion to your sound after it is filtered.
" +"
" +"FDBK (Feedback) stores the filter's output and sends it back to the filter's input after a certain amount of time. This is a very odd, unique, interesting, and useful feature. Without a filter in effect, increasing the feedback turns this into a comb filter. Having a filter selected and working can create some ridiculous tibres you'd never hear out of most other synthesizers. The change the feedback makes to the sound is very tonal, and the pitch it creates depends on its delay. Because of this, I made it so the delay is keytracking by default, so the change it makes to your sound matches the note you play. DET detunes that, and the keytracking button in the top right turns keytracking off for that. Definitely have fun with this feature, you can get weird and amazing sounds out of this. Notice that this feature entirely allows Karplus-Strong synthesis, as well as any other ridiculous adaptations that pop into your head.
" +"
" +"
" +"-=MISCELLANEOUS TAB=-
" +"
" +"The oversampling dropdown box is ***VERY*** important when it comes to Microwave's audio quality. The higher it is, the cleaner your sound will be. But, oversampling is also extremely detrimental to your CPU. The multiplier of oversampling will be almost exactly the multiplier it applies to the processing power it uses.
" +"
" +"But how do you know whether you need oversampling? 2x should be appropriate in most (?) cases, but definitely not all of them. If your sound is very basic, and all matrix inputs that control knobs only move very very slowly, then it's possible that as low as 1x oversampling (which means no oversampling) may be appropriate. But, if the sound makes use of modulation, then higher values of oversampling may be appropriate, especially if the modulator contains or plays at high frequencies. When in doubt, use your ears and compare. Never neglect the oversampling. If you're making a sound that uses modulation and it sounds a bit too much like a dying engine, bumping up the oversampling a bit may be all that is needed to bring the sound from okay to awesome. I strongly suggest making oversampling tweaking a part of your habitual workflow when using Microwave.
" +"
" +"The oversampling mode has an \"Average\" option, which decreases audio artifacts but distorts the high frequencies slightly. The default value for this is usually fine unless you hear some weird buzzing, or you're trying to get the sound super clean and the high frequency changes aren't a problem.
" +"
" +"The REMOVE DC OFFSET button removes 0 Hz content from your sound. 0 Hz sound is almost always a bad thing. But of course, don't turn this on if you don't need it, since it does use a small amount of CPU.
" +"
" +"The eight Macro knobs provided are useful for quickly and conveniently changing/automating/modulating multiple knobs at the same time. Use them as Matrix inputs and outputs. It's simple but very useful, especially for presets.
" +"
" +"
" +"-=OTHER FEATURES TO BE AWARE OF=-
" +"
" +"Right clicking some knobs will reveal a new \"Send To Matrix\" option. Choosing that option will send that knob to the Matrix output for you automatically, and bring you there to choose an input.
" +"
" +"If a knob is set as an output in the Matrix, middle click and dragging that knob (or, *alt*ernatively, using Alt and dragging) will control the Amount knob of that Matrix box rather than the knob itself. You can tell it is working correctly if the knob turns the color green when you do so. If the knob is set as an output in multiple places, the uppermost applicable Matrix box will be selected. This is useful for fast workflow, e.g. if you want to control frequency and FM amount in the same spot.
" +"
" +"
" +"
" +"
" +"==CPU PRESERVATION GUIDELINES==
" +"
" +"
" +"Turn the wavetable tab's visualizer off. That uses a lot of processing power.
" +"
" +"Microwave stores the highest oscillator that is enabled, and checks every oscillator from the first one to the highest enabled one to see whether it's enabled. So, having just the 50th oscillator enabled will take significantly more processing power than having just the 1st one enabled, because it would need to check oscillators 1-50 to see whether they're enabled. This also applies to filters and Matrix boxes.
" +"
" +"Increasing the Range knob will use a bit more CPU (since it needs to calculate nearby waveforms as well). With very large Range values the CPU hit can get quite noticeable. But, even though this needs to calculate nearby waveforms, it doesn't need to recalculate the entire oscillator, so increasing the Range won't use nearly as much CPU as, for example, increasing the number of unison voices.
" +"
" +"Having a larger number of unison voices increases the CPU usage by around the voice amount. For example, having 30 voices will use approximately 15x as much processing power as just two voices. This increase is almost exactly linear (with the exception of using only one voice, which uses less than half the CPU as two voices, since having unison disabled entirely will prevent unison stuff from being calculated entirely).
" +"
" +"The values of the Morph and Modify knobs in the UNISON box have no impact on processing power needed, except for a very small performance gain when they are at exactly 0.
" +"
" +"Even when the modify is not in use, having the Modify Mode set to None will use (sometimes significantly) less CPU than if it is set to something else.
" +"
" +"When using modify, expect the largest CPU hit from modes that require accessing other parts of the waveform to work (e.g. Squarify and Pulsify).
" +"
" +"Oversampling results in an almost exact multiplication in processing power needed. So 8x oversampling will use 4x more CPU than 2x oversampling.
" +"
" +"
" +"
" +"
" +"==FAQ==
" +"
" +"
" +"-=WHY WON'T MY MICROWAVE MAKE SOUND?!=-
" +"
" +"1. Wavetable tab: You need to enable the \"Enabled\" LED (has a power icon next to it), then click the folder button to load a wavetable. After the wavetable is loaded correctly, move the Morph knob and you should hear sound.
" +"
" +"2. Sub tab: You need to enable the \"Enabled\" LED (has a power icon next to it), then draw whatever you want on the graph.
" +"
" +"3. Sample tab: You need to enable the \"Enabled\" LED (has a power icon next to it), then click the folder button to load a sample.
" +"
" +"
" +"-=WHY WON'T MY FILTERS WORK?!=-
" +"
" +"Make sure the filter is enabled. Take the oscillator you want to send through your filter, enable its Muted LED, use it as an input in the Matrix, set the output as \"Filter Input\", and set the Matrix Amount knob to 100%. This will prevent the original oscillator audio from being sent directly to the audio output, and send the oscillator audio to the filter.
" +"
" +; + + +MicrowaveManualView::MicrowaveManualView():QTextEdit( s_manualText ) +{ + setWindowTitle ( "Microwave Manual" ); + setTextInteractionFlags ( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse ); + gui->mainWindow()->addWindowedWidget( this ); + parentWidget()->setAttribute( Qt::WA_DeleteOnClose, false ); + parentWidget()->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) ); + parentWidget()->resize( 640, 480 ); +} + + +void MicrowaveView::manualBtnClicked() +{ + MicrowaveManualView::getInstance()->hide(); + MicrowaveManualView::getInstance()->show(); +} + + + +void MicrowaveKnob::setMatrixLocation( int loc1, int loc2, int loc3 ) +{ + matrixLocation[0] = loc1; + matrixLocation[1] = loc2; + matrixLocation[2] = loc3; + + disconnect(this, &MicrowaveKnob::sendToMatrixAsOutput, 0, 0); + connect( this, &MicrowaveKnob::sendToMatrixAsOutput, this, [this, loc1, loc2, loc3]() { knobView->sendToMatrixAsOutput( loc1, loc2, loc3 ); } ); + + disconnect(this, &MicrowaveKnob::switchToMatrixKnob, 0, 0); + connect( this, &MicrowaveKnob::switchToMatrixKnob, this, [this, loc1, loc2, loc3]() { knobView->switchToMatrixKnob( this, loc1, loc2, loc3 ); } ); +} + + +void MicrowaveKnob::setWhichMacroKnob( int which ) +{ + this->whichMacroKnob = which; + + disconnect(this, &MicrowaveKnob::setMacroTooltip, 0, 0); + disconnect(this, &MicrowaveKnob::chooseMacroColor, 0, 0); + disconnect(this, &MicrowaveKnob::refreshMacroColor, 0, 0); + disconnect(this, &MicrowaveKnob::setMacroColortoDefault, 0, 0); + + if( which != -1 ) + { + connect( this, &MicrowaveKnob::setMacroTooltip, this, [this, which]() { knobView->setMacroTooltip( this, which ); } ); + connect( this, &MicrowaveKnob::chooseMacroColor, this, [this, which]() { knobView->chooseMacroColor( this, which ); } ); + connect( this, &MicrowaveKnob::refreshMacroColor, this, [this, which]() { knobView->refreshMacroColor( this, which ); } ); + connect( this, &MicrowaveKnob::setMacroColortoDefault, this, [this, which]() { knobView->setMacroColortoDefault( this, which ); } ); + } +} + + + +void MicrowaveKnob::contextMenuEvent( QContextMenuEvent * ) +{ + // for the case, the user clicked right while pressing left mouse- + // button, the context-menu appears while mouse-cursor is still hidden + // and it isn't shown again until user does something which causes + // an QApplication::restoreOverrideCursor()-call... + mouseReleaseEvent( NULL ); + + CaptionMenu contextMenu( model()->displayName(), this ); + addDefaultActions( &contextMenu ); + contextMenu.addAction( QPixmap(), model()->isScaleLogarithmic() ? tr( "Set linear" ) : tr( "Set logarithmic" ), this, SLOT( toggleScale() ) ); + contextMenu.addSeparator(); + if( this->matrixLocation[0] ) + { + contextMenu.addAction( PLUGIN_NAME::getIconPixmap( "tab4" ), tr( "Control this in Matrix" ), this, SIGNAL( sendToMatrixAsOutput() ) ); + } + if( this->whichMacroKnob != -1 ) + { + contextMenu.addAction( PLUGIN_NAME::getIconPixmap( "tab4" ), tr( "Set Macro Tooltip" ), this, SIGNAL( setMacroTooltip() ) ); + contextMenu.addAction( embed::getIconPixmap( "colorize" ), tr( "Set Knob Color" ), this, SIGNAL( chooseMacroColor() ) ); + contextMenu.addAction( embed::getIconPixmap( "colorize" ), tr( "Set Knob Color To Default" ), this, SIGNAL( setMacroColortoDefault() ) ); + } + contextMenu.addSeparator(); + contextMenu.exec( QCursor::pos() ); +} + + +void MicrowaveKnob::mousePressEvent( QMouseEvent * _me ) +{ + if( ( _me->button() == Qt::LeftButton && gui->mainWindow()->isAltPressed() ) || _me->button() == Qt::MidButton ) + { + if( matrixLocation[0] ) + { + switchToMatrixKnob(); + } + + AutomatableModel *thisModel = model(); + if( thisModel ) + { + thisModel->addJournalCheckPoint(); + thisModel->saveJournallingState( false ); + } + + const QPoint & p = _me->pos(); + m_origMousePos = p; + m_mouseOffset = QPoint(0, 0); + m_leftOver = 0.0f; + + emit sliderPressed(); + + QApplication::setOverrideCursor( Qt::BlankCursor ); + s_textFloat->setText( displayValue() ); + s_textFloat->moveGlobal( this, QPoint( width() + 2, 0 ) ); + s_textFloat->show(); + m_buttonPressed = true; + } + else + { + Knob::mousePressEvent( _me ); + } +} + + +void MicrowaveKnob::mouseReleaseEvent( QMouseEvent * _me ) +{ + Knob::mouseReleaseEvent( _me ); + updateScroll(); + + if( this->whichMacroKnob == -1 ) + { + this->setarcColor( QColor(46,74,80) ); + this->setlineColor( QColor(102,198,199) ); + this->setInnerColor( QColor(64,92,97) ); + } + else + { + refreshMacroColor(); + } +} + + + +extern "C" +{ + +// necessary for getting instance out of shared lib +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) +{ + return( new Microwave( static_cast( m ) ) ); +} + + +} + diff --git a/plugins/Microwave/Microwave.h b/plugins/Microwave/Microwave.h new file mode 100644 index 00000000000..e29f0ce994a --- /dev/null +++ b/plugins/Microwave/Microwave.h @@ -0,0 +1,1138 @@ +/* + * Microwave.h - declaration of class Microwave (a wavetable synthesizer) + * + * Copyright (c) 2019 Robert Daniel Black AKA Lost Robot + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef Microwave_H +#define Microwave_H + +#include +#include +#include +#include + +#include "ComboBox.h" +#include "Graph.h" +#include "Instrument.h" +#include "InstrumentView.h" +#include "Knob.h" +#include "LcdSpinBox.h" +#include "LedCheckbox.h" +#include "MemoryManager.h" +#include "NotePlayHandle.h" +#include "PixmapButton.h" +#include "SampleBuffer.h" +#include "samplerate.h" +#include "stdshims.h" + + +// Macros, mostly for comboboxes but also a few other things + +#define setwavemodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Pulse Width" ), make_unique( "sin" ) );\ + name->addItem( tr( "Weird 1" ), make_unique( "noise" ) );\ + name->addItem( tr( "Weird 2" ), make_unique( "noise" ) );\ + name->addItem( tr( "Asym To Right" ), make_unique( "saw" ) );\ + name->addItem( tr( "Asym To Left" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Bidirectional Asym" ), make_unique( "tri" ) );\ + name->addItem( tr( "Squish To Center" ), make_unique( "exp" ) );\ + name->addItem( tr( "Stretch From Center" ), make_unique( "sinabs" ) );\ + name->addItem( tr( "Stretch And Squish" ), make_unique( "tri" ) );\ + name->addItem( tr( "Cut Off Right" ), make_unique( "saw" ) );\ + name->addItem( tr( "Cut Off Left" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Squarify" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Pulsify" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Flip" ), make_unique( "tri" ) );\ + name->addItem( tr( "Clip" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Inverse Clip" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Sine" ), make_unique( "sin" ) );\ + name->addItem( tr( "Atan" ), make_unique( "tri" ) );\ + name->addItem( tr( "Sync" ), make_unique( "saw" ) );\ + name->addItem( tr( "Sync Half Interpolate" ), make_unique( "saw" ) );\ + name->addItem( tr( "Sync Interpolate" ), make_unique( "saw" ) );\ + name->addItem( tr( "Mirror" ), make_unique( "sinabs" ) );\ + name->addItem( tr( "Diagonal Morph" ), make_unique( "saw" ) );\ + name->addItem( tr( "Sideways Morph" ), make_unique( "saw" ) ); + +#define modinmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Main OSC" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Sub OSC" ), make_unique( "sin" ) );\ + name->addItem( tr( "Sample OSC" ), make_unique( "noise" ) );\ + name->addItem( tr( "Filter Output" ), make_unique( "moog" ) );\ + name->addItem( tr( "Velocity" ), make_unique( "letter_v" ) );\ + name->addItem( tr( "Panning" ), make_unique( "letter_p" ) );\ + name->addItem( tr( "Humanizer" ), make_unique( "letter_h" ) );\ + name->addItem( tr( "Macro" ), make_unique( "letter_m" ) ); + +#define modsectionsmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Main OSC" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Sub OSC" ), make_unique( "sin" ) );\ + name->addItem( tr( "Sample OSC" ), make_unique( "noise" ) );\ + name->addItem( tr( "Matrix" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Filter Input" ), make_unique( "moog" ) );\ + name->addItem( tr( "Filter Parameters" ), make_unique( "letter_f" ) );\ + name->addItem( tr( "Macro" ), make_unique( "letter_m" ) ); + +#define mainoscsignalsmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Morph" ), make_unique( "tri" ) );\ + name->addItem( tr( "Range" ), make_unique( "sqr" ) );\ + name->addItem( tr( "Modify" ), make_unique( "moog" ) );\ + name->addItem( tr( "Detune" ), make_unique( "saw" ) );\ + name->addItem( tr( "Phase" ), make_unique( "sin" ) );\ + name->addItem( tr( "Volume" ), make_unique( "letter_v" ) );\ + name->addItem( tr( "Panning" ), make_unique( "letter_p" ) );\ + name->addItem( tr( "Unison Number" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Unison Detune" ), make_unique( "saw" ) );\ + name->addItem( tr( "Unison Morph" ), make_unique( "tri" ) );\ + name->addItem( tr( "Unison Modify" ), make_unique( "moog" ) ); + +#define subsignalsmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Detune" ), make_unique( "saw" ) );\ + name->addItem( tr( "Phase" ), make_unique( "sin" ) );\ + name->addItem( tr( "Volume" ), make_unique( "letter_v" ) );\ + name->addItem( tr( "Panning" ), make_unique( "letter_p" ) );\ + name->addItem( tr( "Length" ), make_unique( "letter_l" ) );\ + name->addItem( tr( "Rate Limit" ), make_unique( "letter_r" ) );\ + name->addItem( tr( "Unison Voice Number" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Unison Detune" ), make_unique( "saw" ) ); + +#define samplesignalsmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Detune" ), make_unique( "saw" ) );\ + name->addItem( tr( "Phase" ), make_unique( "sin" ) );\ + name->addItem( tr( "Volume" ), make_unique( "letter_v" ) );\ + name->addItem( tr( "Panning" ), make_unique( "letter_p" ) ); + +#define matrixsignalsmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Amount" ), make_unique( "letter_a" ) );\ + name->addItem( tr( "Curve" ), make_unique( "letter_c" ) );\ + name->addItem( tr( "Secondary Amount" ), make_unique( "letter_a" ) );\ + name->addItem( tr( "Secondary Curve" ), make_unique( "letter_c" ) );\ + name->addItem( tr( "Input Section" ), make_unique( "letter_i" ) );\ + name->addItem( tr( "Input Number" ), make_unique( "letter_i" ) );\ + name->addItem( tr( "Secondary Input Section" ), make_unique( "letter_i" ) );\ + name->addItem( tr( "Secondary Input Number" ), make_unique( "letter_i" ) );\ + name->addItem( tr( "Output Section 1" ), make_unique( "letter_o" ) );\ + name->addItem( tr( "Output Section 2" ), make_unique( "letter_o" ) );\ + name->addItem( tr( "Output Section Number" ), make_unique( "letter_o" ) );\ + +#define filtersignalsmodel( name )\ + name->clear();\ + name->addItem( tr( "None" ), make_unique( "none" ) );\ + name->addItem( tr( "Cutoff Frequency" ), make_unique( "moog" ) );\ + name->addItem( tr( "Resonance" ), make_unique( "ramp" ) );\ + name->addItem( tr( "db Gain" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Filter Type" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Slope" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Input Volume" ), make_unique( "sin" ) );\ + name->addItem( tr( "Output Volume" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Wet/Dry" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Balance/Panning" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Saturation" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Feedback" ), make_unique( "ramp" ) );\ + name->addItem( tr( "Detune" ), make_unique( "ramp" ) ); + +#define mod8model( name )\ + name->clear();\ + name->addItem( tr( "1" ), make_unique( "number_1" ) );\ + name->addItem( tr( "2" ), make_unique( "number_2" ) );\ + name->addItem( tr( "3" ), make_unique( "number_3" ) );\ + name->addItem( tr( "4" ), make_unique( "number_4" ) );\ + name->addItem( tr( "5" ), make_unique( "number_5" ) );\ + name->addItem( tr( "6" ), make_unique( "number_6" ) );\ + name->addItem( tr( "7" ), make_unique( "number_7" ) );\ + name->addItem( tr( "8" ), make_unique( "number_8" ) ); + +#define matrixoutmodel( name )\ + name->clear();\ + name->addItem( tr( "1" ) );\ + name->addItem( tr( "2" ) );\ + name->addItem( tr( "3" ) );\ + name->addItem( tr( "4" ) );\ + name->addItem( tr( "5" ) );\ + name->addItem( tr( "6" ) );\ + name->addItem( tr( "7" ) );\ + name->addItem( tr( "8" ) );\ + name->addItem( tr( "9" ) );\ + name->addItem( tr( "10" ) );\ + name->addItem( tr( "11" ) );\ + name->addItem( tr( "12" ) );\ + name->addItem( tr( "13" ) );\ + name->addItem( tr( "14" ) );\ + name->addItem( tr( "15" ) );\ + name->addItem( tr( "16" ) );\ + name->addItem( tr( "17" ) );\ + name->addItem( tr( "18" ) ); + +#define filtertypesmodel( name )\ + name->clear();\ + name->addItem( tr( "Lowpass" ), make_unique( "filter_lowpass" ) );\ + name->addItem( tr( "Highpass" ), make_unique( "filter_highpass" ) );\ + name->addItem( tr( "Bandpass" ), make_unique( "filter_bandpass" ) );\ + name->addItem( tr( "Low Shelf" ), make_unique( "filter_lowshelf" ) );\ + name->addItem( tr( "High Shelf" ), make_unique( "filter_highshelf" ) );\ + name->addItem( tr( "Peak" ), make_unique( "filter_peak" ) );\ + name->addItem( tr( "Notch" ), make_unique( "filter_notch" ) );\ + name->addItem( tr( "Allpass" ), make_unique( "filter_allpass" ) );\ + name->addItem( tr( "Moog Lowpass (Note: Slope is double)" ), make_unique( "filter_moog" ) ); + +#define filterslopesmodel( name )\ + name->clear();\ + name->addItem( tr( "12 db" ), make_unique( "number_1" ) );\ + name->addItem( tr( "24 db" ), make_unique( "number_2" ) );\ + name->addItem( tr( "36 db" ), make_unique( "number_3" ) );\ + name->addItem( tr( "48 db" ), make_unique( "number_4" ) );\ + name->addItem( tr( "60 db" ), make_unique( "number_5" ) );\ + name->addItem( tr( "72 db" ), make_unique( "number_6" ) );\ + name->addItem( tr( "84 db" ), make_unique( "number_7" ) );\ + name->addItem( tr( "96 db" ), make_unique( "number_8" ) ); + +#define modcombinetypemodel( name )\ + name->clear();\ + name->addItem( tr( "Add Bidirectional" ), make_unique( "number_1" ) );\ + name->addItem( tr( "Multiply Bidirectional" ), make_unique( "number_2" ) );\ + name->addItem( tr( "Add Unidirectional" ), make_unique( "number_3" ) );\ + name->addItem( tr( "Multiply Unidirectional" ), make_unique( "number_4" ) ); + +#define oversamplemodel( name )\ + name.clear();\ + name.addItem( tr( "1x" ), make_unique( "number_1" ) );\ + name.addItem( tr( "2x" ), make_unique( "number_2" ) );\ + name.addItem( tr( "3x" ), make_unique( "number_3" ) );\ + name.addItem( tr( "4x" ), make_unique( "number_4" ) );\ + name.addItem( tr( "5x" ), make_unique( "number_5" ) );\ + name.addItem( tr( "6x" ), make_unique( "number_6" ) );\ + name.addItem( tr( "7x" ), make_unique( "number_7" ) );\ + name.addItem( tr( "8x" ), make_unique( "number_8" ) ); + +#define loadmodemodel( name )\ + name.clear();\ + name.addItem( tr( "Lock waveform edges to zero crossings" ) );\ + name.addItem( tr( "Load sample without changes" ) );\ + name.addItem( tr( "Load wavetable file" ) );\ + name.addItem( tr( "Autocorrelation (static pitch detection)" ) ); + +#define oversamplemodemodel( name )\ + name.clear();\ + name.addItem( tr( "Decimate" ), make_unique( "number_1" ) );\ + name.addItem( tr( "Average" ), make_unique( "number_2" ) ); + +#define visimove( name, x, y )\ + if( x >= 0 && x <= 250 )\ + {\ + name->move( x, y );\ + name->setVisible( true );\ + }\ + else\ + {\ + name->move( 0, 0 );\ + name->setVisible( false );\ + } + + +// Create the knob, set its tooltip, set its default color +#define makeknob( name, knobtype, hint, tooltip )\ + name = new MicrowaveKnob( knobtype, this );\ + name->setHintText( hint, "" );\ + ToolTip::add( name, tooltip );\ + name->knobView = this;\ + name->setarcColor( QColor(46,74,80) );\ + name->setlineColor( QColor(102,198,199) );\ + name->setInnerColor( QColor(64,92,97) );\ + connect( name, &MicrowaveKnob::updateScroll, this, &MicrowaveView::updateScroll ); + + +// Constant variables for use in many situations. Strongly related to srccpy stuff. + +const int STOREDSUBWAVELEN = 2048; +const int STOREDMAINWAVELEN = 2048; + +// WAVERATIO is how much larger (multiplication) the waveforms are after interpolation. +// I'd like to increase this, but I will not until project saving/loading is sped up in LMMS, since this increases that drastically. +// I would prefer it to be 8, maybe even 16. +// This number divided by 2 is the number of megabytes of RAM each wavetable will use up. +const int WAVERATIO = 4; + +const int SUBWAVELEN = STOREDSUBWAVELEN * WAVERATIO; +const int MAINWAVELEN = STOREDMAINWAVELEN * WAVERATIO; + +const int STOREDMAINARRAYLEN = STOREDMAINWAVELEN * 256; +const int MAINARRAYLEN = MAINWAVELEN * 256; + + +class oscillator; +class MicrowaveView; +class Microwave; + + +class MicrowaveKnob: public Knob +{ + Q_OBJECT + using Knob::Knob; +public: + void setMatrixLocation( int loc1, int loc2, int loc3 ); + + void setWhichMacroKnob( int which ); + + MicrowaveView * knobView; +signals: + void sendToMatrixAsOutput(); + void switchToMatrixKnob(); + void updateScroll(); + void setMacroTooltip(); + void chooseMacroColor(); + void refreshMacroColor(); + void setMacroColortoDefault(); +protected: + virtual void contextMenuEvent( QContextMenuEvent * _me ); + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void mouseReleaseEvent( QMouseEvent * _me ); +private: + int matrixLocation[3] = {0}; + bool ignoreShift = false; + int whichMacroKnob = -1; +}; + + +class Microwave : public Instrument +{ + Q_OBJECT + +public: + Microwave(InstrumentTrack * _instrument_track ); + virtual ~Microwave(); + virtual PluginView * instantiateView( QWidget * _parent ); + virtual QString nodeName() const; + virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); + virtual void loadSettings( const QDomElement & _this ); + virtual void playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ); + virtual void deleteNotePluginData( NotePlayHandle * _n ); + + virtual f_cnt_t desiredReleaseFrames() const + { + return( 64 ); + } + + void switchMatrixSections( int source, int destination ); + + inline void fillSubOsc( int which, bool doInterpolate = true ); + inline void fillMainOsc( int which, bool doInterpolate = true ); + + float scroll = 0; + bool viewOpen = false; + +protected slots: + void valueChanged( int, int ); + void morphMaxChanged( int ); + void sampLenChanged( int ); + void subSampLenChanged( int ); + void mainEnabledChanged( int ); + void subEnabledChanged( int ); + void modEnabledChanged( int ); + void filtEnabledChanged( int ); + void sampleEnabledChanged( int ); + void samplesChanged( int, int ); + void interpolateChanged( int ); + void subInterpolateChanged( int ); + +private: + + // Stolen from WatSyn, with a few changes + // memcpy utilizing libsamplerate (src) for sinc interpolation + inline void srccpy( float * _dst, float * _src, int wavelength ) + { + int err; + const int margin = 64; + + // copy to temp array + std::unique_ptr tmps(new float[wavelength + margin]); + float * tmp = &tmps.get()[0]; + + memcpy( tmp, _src, sizeof( float ) * wavelength ); + memcpy( tmp + wavelength, _src, sizeof( float ) * margin ); + SRC_STATE * src_state = src_new( SRC_SINC_FASTEST, 1, &err ); + SRC_DATA src_data; + src_data.data_in = tmp; + src_data.input_frames = wavelength + margin; + src_data.data_out = _dst; + src_data.output_frames = wavelength * WAVERATIO; + src_data.src_ratio = static_cast( WAVERATIO ); + src_data.end_of_input = 0; + err = src_process( src_state, &src_data ); + if( err ) { qDebug( "Microwave SRC error: %s", src_strerror( err ) ); } + src_delete( src_state ); + } + + FloatModel * morph[8]; + FloatModel * range[8]; + FloatModel * modify[8]; + ComboBoxModel * modifyMode[8]; + FloatModel * vol[8]; + FloatModel * pan[8]; + FloatModel * detune[8]; + FloatModel * phase[8]; + FloatModel * phaseRand[8]; + BoolModel * enabled[8]; + BoolModel * muted[8]; + FloatModel * sampLen[8]; + FloatModel * morphMax[8]; + FloatModel * unisonVoices[8]; + FloatModel * unisonDetune[8]; + FloatModel * unisonMorph[8]; + FloatModel * unisonModify[8]; + BoolModel * keytracking[8]; + FloatModel * tempo[8]; + BoolModel * interpolate[8]; + + BoolModel * subEnabled[64]; + BoolModel * subMuted[64]; + BoolModel * subKeytrack[64]; + BoolModel * subNoise[64]; + FloatModel * subVol[64]; + FloatModel * subPanning[64]; + FloatModel * subDetune[64]; + FloatModel * subPhase[64]; + FloatModel * subPhaseRand[64]; + FloatModel * subSampLen[64]; + FloatModel * subTempo[64]; + FloatModel * subRateLimit[64]; + FloatModel * subUnisonNum[64]; + FloatModel * subUnisonDetune[64]; + BoolModel * subInterpolate[64]; + + BoolModel * sampleEnabled[8]; + BoolModel * sampleGraphEnabled[8]; + BoolModel * sampleMuted[8]; + BoolModel * sampleKeytracking[8]; + BoolModel * sampleLoop[8]; + FloatModel * sampleVolume[8]; + FloatModel * samplePanning[8]; + FloatModel * sampleDetune[8]; + FloatModel * samplePhase[8]; + FloatModel * samplePhaseRand[8]; + FloatModel * sampleStart[8]; + FloatModel * sampleEnd[8]; + + ComboBoxModel * modIn[64]; + IntModel * modInNum[64]; + FloatModel * modInAmnt[64]; + FloatModel * modInCurve[64]; + ComboBoxModel * modIn2[64]; + IntModel * modInNum2[64]; + FloatModel * modInAmnt2[64]; + FloatModel * modInCurve2[64]; + ComboBoxModel * modOutSec[64]; + ComboBoxModel * modOutSig[64]; + IntModel * modOutSecNum[64]; + BoolModel * modEnabled[64]; + ComboBoxModel * modCombineType[64]; + BoolModel * modType[64]; + BoolModel * modType2[64]; + + FloatModel * filtCutoff[8]; + FloatModel * filtReso[8]; + FloatModel * filtGain[8]; + ComboBoxModel * filtType[8]; + ComboBoxModel * filtSlope[8]; + FloatModel * filtInVol[8]; + FloatModel * filtOutVol[8]; + FloatModel * filtWetDry[8]; + FloatModel * filtBal[8]; + FloatModel * filtSatu[8]; + FloatModel * filtFeedback[8]; + FloatModel * filtDetune[8]; + BoolModel * filtEnabled[8]; + BoolModel * filtMuted[8]; + BoolModel * filtKeytracking[8]; + + FloatModel * macro[18]; + QString macroTooltips[18] = {}; + int macroColors[18][3] = {{0}}; + + FloatModel visvol; + + FloatModel loadAlg; + FloatModel loadChnl; + + IntModel mainNum; + IntModel subNum; + IntModel sampNum; + ComboBoxModel oversample; + ComboBoxModel oversampleMode; + ComboBoxModel loadMode; + + graphModel graph; + + BoolModel visualize; + + float storedwaveforms[8][STOREDMAINARRAYLEN] = {{0}}; + float waveforms[8][MAINARRAYLEN] = {{0}}; + bool mainFilled[8] = {false}; + int currentTab = 0; + float storedsubs[64][STOREDSUBWAVELEN] = {{0}}; + float subs[64][SUBWAVELEN] = {{0}}; + bool subFilled[64] = {false}; + float sampGraphs[1024] = {0}; + std::vector samples[8][2]; + + BoolModel mainFlipped; + BoolModel subFlipped; + + BoolModel removeDC; + + SampleBuffer sampleBuffer; + + //Below is for passing to mSynth initialization + float morphArr[8] = {0}; + float rangeArr[8] = {0}; + float modifyArr[8] = {0}; + int modifyModeArr[8] = {0}; + float volArr[8] = {0}; + float panArr[8] = {0}; + float detuneArr[8] = {0}; + float phaseArr[8] = {0}; + float phaseRandArr[8] = {0}; + bool enabledArr[8] = {false}; + bool mutedArr[8] = {false}; + float sampLenArr[8] = {0}; + float morphMaxArr[8] = {0}; + float unisonVoicesArr[8] = {0}; + float unisonDetuneArr[8] = {0}; + float unisonMorphArr[8] = {0}; + float unisonModifyArr[8] = {0}; + bool keytrackingArr[8] = {true}; + float tempoArr[8] = {0}; + bool interpolateArr[8] = {true}; + + int modInArr[64] = {0}; + int modInNumArr[64] = {0}; + float modInAmntArr[64] = {0}; + float modInCurveArr[64] = {0}; + int modIn2Arr[64] = {0}; + int modInNum2Arr[64] = {0}; + float modInAmnt2Arr[64] = {0}; + float modInCurve2Arr[64] = {0}; + int modOutSecArr[64] = {0}; + int modOutSigArr[64] = {0}; + int modOutSecNumArr[64] = {0}; + bool modEnabledArr[64] = {false}; + int modCombineTypeArr[64] = {0}; + bool modTypeArr[64] = {0}; + bool modType2Arr[64] = {0}; + + bool subEnabledArr[64] = {false}; + float subVolArr[64] = {0}; + float subPhaseArr[64] = {0}; + float subPhaseRandArr[64] = {0}; + float subDetuneArr[64] = {0}; + bool subMutedArr[64] = {false}; + bool subKeytrackArr[64] = {false}; + float subSampLenArr[64] = {0}; + bool subNoiseArr[64] = {false}; + float subPanningArr[64] = {0}; + float subTempoArr[64] = {0}; + float subRateLimitArr[64] = {0}; + float subUnisonNumArr[64] = {0}; + float subUnisonDetuneArr[64] = {0}; + bool subInterpolateArr[64] = {true}; + + float filtInVolArr[8] = {0}; + int filtTypeArr[8] = {0}; + int filtSlopeArr[8] = {0}; + float filtCutoffArr[8] = {0}; + float filtResoArr[8] = {0}; + float filtGainArr[8] = {0}; + float filtSatuArr[8] = {0}; + float filtWetDryArr[8] = {0}; + float filtBalArr[8] = {0}; + float filtOutVolArr[8] = {0}; + bool filtEnabledArr[8] = {false}; + float filtFeedbackArr[8] = {0}; + float filtDetuneArr[8] = {0}; + bool filtKeytrackingArr[8] = {false}; + bool filtMutedArr[8] = {false}; + + bool sampleEnabledArr[8] = {false}; + bool sampleGraphEnabledArr[8] = {false}; + bool sampleMutedArr[8] = {false}; + bool sampleKeytrackingArr[8] = {false}; + bool sampleLoopArr[8] = {false}; + float sampleVolumeArr[8] = {0}; + float samplePanningArr[8] = {0}; + float sampleDetuneArr[8] = {0}; + float samplePhaseArr[8] = {0}; + float samplePhaseRandArr[8] = {0}; + float sampleStartArr[8] = {0}; + float sampleEndArr[8] = {1, 1, 1, 1, 1, 1, 1, 1}; + + float macroArr[18] = {0}; + //Above is for passing to mSynth initialization + + int maxMainEnabled = 0;// The highest number of main oscillator sections that must be looped through + int maxModEnabled = 0;// The highest number of matrix sections that must be looped through + int maxSubEnabled = 0;// The highest number of sub oscillator sections that must be looped through + int maxSampleEnabled = 0;// The highest number of sample sections that must be looped through + int maxFiltEnabled = 0;// The highest number of filter sections that must be looped through + + float visualizerValues[204] = {0}; + + QString wavetableSaveStrings[8] = {""}; + bool updateWavetable[8] = {true,true,true,true,true,true,true,true}; + + ConstNotePlayHandleList nphList; + + InstrumentTrack * microwaveTrack = this->instrumentTrack(); + + Microwave * mwc; + + friend class MicrowaveView; + friend class mSynth; + friend class MicrowaveKnob; +}; + + + +class MicrowaveView : public InstrumentView +{ + Q_OBJECT +public: + MicrowaveView( Instrument * _instrument, + QWidget * _parent ); + + virtual ~MicrowaveView(); + + void sendToMatrixAsOutput( int loc1, int loc2, int loc3 ); + void switchToMatrixKnob( MicrowaveKnob * theKnob, int loc1, int loc2, int loc3 ); + void setMacroTooltip( MicrowaveKnob * theKnob, int which ); + void chooseMacroColor( MicrowaveKnob * theKnob, int which ); + void refreshMacroColor( MicrowaveKnob * theKnob, int which ); + void setMacroColortoDefault( MicrowaveKnob * theKnob, int which ); + void setGraphEnabledColor( bool isEnabled ); + +protected slots: + void updateScroll(); + void mainNumChanged(); + void subNumChanged(); + void sampNumChanged(); + void modOutSecChanged( int i ); + void modInChanged( int i ); + void modIn2Changed( int i ); + void tabChanged( int tabnum ); + void visualizeToggled( bool value ); + void sinWaveClicked(); + void triangleWaveClicked(); + void sqrWaveClicked(); + void sawWaveClicked(); + void noiseWaveClicked(); + void usrWaveClicked(); + void smoothClicked( void ); + void chooseWavetableFile( ); + void openWavetableFile( QString fileName = "" ); + void openWavetableFileBtnClicked(); + void openSampleFile(); + void openSampleFileBtnClicked(); + + void modUpClicked( int ); + void modDownClicked( int ); + void i1Clicked( int ); + void i2Clicked( int ); + + void confirmWavetableLoadClicked(); + + void tabBtnClicked( int ); + + void manualBtnClicked(); + + void updateBackground(); + + void flipperClicked(); + + void XBtnClicked(); + void MatrixXBtnClicked(); + + void normalizeClicked(); + void desawClicked(); + + void modEnabledChanged(); + +private: + virtual void modelChanged(); + + void wheelEvent( QWheelEvent * _me ); + virtual void dropEvent( QDropEvent * _de ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + + PixmapButton * sinWaveBtn; + PixmapButton * triangleWaveBtn; + PixmapButton * sqrWaveBtn; + PixmapButton * sawWaveBtn; + PixmapButton * whiteNoiseWaveBtn; + PixmapButton * smoothBtn; + PixmapButton * usrWaveBtn; + + PixmapButton * sinWave2Btn; + PixmapButton * triangleWave2Btn; + PixmapButton * sqrWave2Btn; + PixmapButton * sawWave2Btn; + PixmapButton * whiteNoiseWave2Btn; + PixmapButton * smooth2Btn; + PixmapButton * usrWave2Btn; + + PixmapButton * XBtn;// For leaving wavetable loading section + PixmapButton * MatrixXBtn;// For when you send something to the Matrix via right click + + PixmapButton * normalizeBtn; + PixmapButton * desawBtn; + + PixmapButton * openWavetableButton; + PixmapButton * confirmLoadButton; + PixmapButton * openSampleButton; + + PixmapButton * modUpArrow[8]; + PixmapButton * modDownArrow[8]; + PixmapButton * i1Button[8]; + PixmapButton * i2Button[8]; + + PixmapButton * tab1Btn; + PixmapButton * tab2Btn; + PixmapButton * tab3Btn; + PixmapButton * tab4Btn; + PixmapButton * tab5Btn; + PixmapButton * tab6Btn; + + PixmapButton * mainFlipBtn; + PixmapButton * subFlipBtn; + + PixmapButton * manualBtn; + + PixmapButton * removeDCBtn; + ComboBox * oversampleModeBox; + + MicrowaveKnob * morphKnob; + MicrowaveKnob * rangeKnob; + MicrowaveKnob * modifyKnob; + ComboBox * modifyModeBox; + MicrowaveKnob * volKnob; + MicrowaveKnob * panKnob; + MicrowaveKnob * detuneKnob; + MicrowaveKnob * phaseKnob; + MicrowaveKnob * phaseRandKnob; + LedCheckBox * enabledToggle; + LedCheckBox * mutedToggle; + MicrowaveKnob * sampLenKnob; + MicrowaveKnob * morphMaxKnob; + MicrowaveKnob * unisonVoicesKnob; + MicrowaveKnob * unisonDetuneKnob; + MicrowaveKnob * unisonMorphKnob; + MicrowaveKnob * unisonModifyKnob; + LedCheckBox * keytrackingToggle; + MicrowaveKnob * tempoKnob; + LedCheckBox * interpolateToggle; + + LedCheckBox * subEnabledToggle; + LedCheckBox * subMutedToggle; + LedCheckBox * subKeytrackToggle; + LedCheckBox * subNoiseToggle; + MicrowaveKnob * subVolKnob; + MicrowaveKnob * subPanningKnob; + MicrowaveKnob * subDetuneKnob; + MicrowaveKnob * subPhaseKnob; + MicrowaveKnob * subPhaseRandKnob; + MicrowaveKnob * subSampLenKnob; + MicrowaveKnob * subTempoKnob; + MicrowaveKnob * subRateLimitKnob; + MicrowaveKnob * subUnisonNumKnob; + MicrowaveKnob * subUnisonDetuneKnob; + LedCheckBox * subInterpolateToggle; + + LedCheckBox * sampleEnabledToggle; + LedCheckBox * sampleGraphEnabledToggle; + LedCheckBox * sampleMutedToggle; + LedCheckBox * sampleKeytrackingToggle; + LedCheckBox * sampleLoopToggle; + MicrowaveKnob * sampleVolumeKnob; + MicrowaveKnob * samplePanningKnob; + MicrowaveKnob * sampleDetuneKnob; + MicrowaveKnob * samplePhaseKnob; + MicrowaveKnob * samplePhaseRandKnob; + MicrowaveKnob * sampleStartKnob; + MicrowaveKnob * sampleEndKnob; + + ComboBox * modInBox[8]; + LcdSpinBox * modInNumBox[8]; + MicrowaveKnob * modInAmntKnob[8]; + MicrowaveKnob * modInCurveKnob[8]; + ComboBox * modInBox2[8]; + LcdSpinBox * modInNumBox2[8]; + MicrowaveKnob * modInAmntKnob2[8]; + MicrowaveKnob * modInCurveKnob2[8]; + ComboBox * modOutSecBox[8]; + ComboBox * modOutSigBox[8]; + LcdSpinBox * modOutSecNumBox[8]; + LedCheckBox * modEnabledToggle[8]; + ComboBox * modCombineTypeBox[8]; + LedCheckBox * modTypeToggle[8]; + LedCheckBox * modType2Toggle[8]; + + MicrowaveKnob * filtCutoffKnob[8]; + MicrowaveKnob * filtResoKnob[8]; + MicrowaveKnob * filtGainKnob[8]; + ComboBox * filtTypeBox[8]; + ComboBox * filtSlopeBox[8]; + MicrowaveKnob * filtInVolKnob[8]; + MicrowaveKnob * filtOutVolKnob[8]; + MicrowaveKnob * filtWetDryKnob[8]; + MicrowaveKnob * filtBalKnob[8]; + MicrowaveKnob * filtSatuKnob[8]; + MicrowaveKnob * filtFeedbackKnob[8]; + MicrowaveKnob * filtDetuneKnob[8]; + LedCheckBox * filtEnabledToggle[8]; + LedCheckBox * filtMutedToggle[8]; + LedCheckBox * filtKeytrackingToggle[8]; + + MicrowaveKnob * macroKnob[18]; + + LcdSpinBox * subNumBox; + LcdSpinBox * sampNumBox; + LcdSpinBox * mainNumBox; + + ComboBox * oversampleBox; + ComboBox * loadModeBox; + + QLineEdit * modNumText[8]; + + MicrowaveKnob * loadAlgKnob; + MicrowaveKnob * loadChnlKnob; + + MicrowaveKnob * visvolKnob; + + Graph * graph; + LedCheckBox * visualizeToggle; + + QScrollBar * effectScrollBar; + QScrollBar * matrixScrollBar; + + QLabel * filtForegroundLabel; + QLabel * filtBoxesLabel; + QLabel * matrixForegroundLabel; + QLabel * matrixBoxesLabel; + + QPalette pal = QPalette(); + QPixmap tab1ArtworkImg = PLUGIN_NAME::getIconPixmap("tab1_artwork"); + QPixmap tab1FlippedArtworkImg = PLUGIN_NAME::getIconPixmap("tab1_artwork_flipped"); + QPixmap tab2ArtworkImg = PLUGIN_NAME::getIconPixmap("tab2_artwork"); + QPixmap tab2FlippedArtworkImg = PLUGIN_NAME::getIconPixmap("tab2_artwork_flipped"); + QPixmap tab3ArtworkImg = PLUGIN_NAME::getIconPixmap("tab3_artwork"); + QPixmap tab4ArtworkImg = PLUGIN_NAME::getIconPixmap("tab4_artwork"); + QPixmap tab5ArtworkImg = PLUGIN_NAME::getIconPixmap("tab5_artwork"); + QPixmap tab6ArtworkImg = PLUGIN_NAME::getIconPixmap("tab6_artwork"); + QPixmap tab7ArtworkImg = PLUGIN_NAME::getIconPixmap("tab7_artwork"); + + QString wavetableFileName = ""; + + Microwave * microwave; + + float temp1; + float temp2; + + int tabWhenSendingToMatrix; + + Microwave * b = castModel(); + + friend class mSynth; +}; + + +class mSynth +{ + MM_OPERATORS +public: + mSynth( NotePlayHandle * _nph, + float * morph, float * range, float * modify, int * modifyMode, float * vol, float * pan, float * detune, float * phase, float * phaseRand, bool * enabled, bool * muted, + float * sampLen, float * morphMax, float * unisonVoices, float * unisonDetune, float * unisonMorph, float * unisonModify, bool * keytracking, float * tempo, bool * interpolate, + bool * subEnabled, bool * subMuted, bool * subKeytrack, bool * subNoise, float * subVol, float * subPanning, float * subDetune, float * subPhase, float * subPhaseRand, + float * subSampLen, float * subTempo, float * subRateLimit, float * subUnisonNum, float * subUnisonDetune, bool * subInterpolate, + bool * sampleEnabled, bool * sampleMuted, bool * sampleKeytracking, bool * sampleGraphEnabled, bool * sampleLoop, float * sampleVolume, float * samplePanning, + float * sampleDetune, float * samplePhase, float * samplePhaseRand, float * sampleStart, float * sampleEnd, + int * modIn, int * modInNum, float * modInAmnt, float * modInCurve, int * modIn2, int * modInNum2, float * modInAmnt2, float * modInCurve2, + int * modOutSec, int * modOutSig, int * modOutSecNum, bool * modEnabled, int * modCombineType, bool * modType, bool * modType2, + float * filtCutoff, float * filtReso, float * filtGain, int * filtType, int * filtSlope, float * filtInVol, float * filtOutVol, float * filtWetDry, float * filtBal, + float * filtSatu, float * filtFeedback, float * filtDetune, bool * filtEnabled, bool * filtMuted, bool * filtKeytracking, + float * macro, + std::vector (&samples)[8][2] ); + + virtual ~mSynth(); + + void nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][MAINARRAYLEN], float (&subs)[64][SUBWAVELEN], float * sampGraphs, std::vector (&samples)[8][2], int maxFiltEnabled, int maxModEnabled, int maxSubEnabled, int maxSampleEnabled, int maxMainEnabled, int sample_rate, Microwave * mwc, bool removeDC, bool isOversamplingSample, float (&storedsubs)[64][STOREDSUBWAVELEN] ); + + inline float detuneWithCents( float pitchValue, float detuneValue ); + + inline void refreshValue( int which, int num, Microwave * mwc ); + + inline float realfmod( float k, float n ); + +private: + double sample_realindex[8][32] = {{0}}; + double sample_subindex[64][32] = {{0}}; + double sample_sampleindex[8] = {0}; + NotePlayHandle* nph; + + int noteDuration; + float noteFreq; + + float lastMainOscVal[8][2] = {{0}}; + float lastSubVal[64][2] = {{0}}; + float lastSubNoiseVal[64][32] = {{0}}; + double sample_step_sub = 0; + float noiseSampRand = 0; + float lastSampleVal[8][2] = {{0}}; + double sample_step_sample = 0; + + float lastMainOscEnvVal[8][2] = {{0}}; + float lastSubEnvVal[64][2] = {{0}}; + float lastSampleEnvVal[8][2] = {{0}}; + + bool lastMainOscEnvDone[8] = {false}; + bool lastSubEnvDone[64] = {false}; + bool lastSampleEnvDone[8] = {false}; + + int subNoiseDirection[64][32] = {{0}}; + + int loopStart = 0; + int loopEnd = 0; + float currentRangeValInvert = 0; + int currentSampLen = 0; + int currentIndex = 0; + + float filtInputs[8][2] = {{0}};// [filter number][channel] + float filtOutputs[8][2] = {{0}};// [filter number][channel] + float filtPrevSampIn[8][8][5][2] = {{{{0}}}};// [filter number][slope][samples back in time][channel] + float filtPrevSampOut[8][8][5][2] = {{{{0}}}};// [filter number][slope][samples back in time][channel] + float filtModOutputs[8][2] = {{0}};// [filter number][channel] + + std::vector filtDelayBuf[8][2];// [filter number][channel] + + float filty1[2] = {0}; + float filty2[2] = {0}; + float filty3[2] = {0}; + float filty4[2] = {0}; + float filtoldx[2] = {0}; + float filtoldy1[2] = {0}; + float filtoldy2[2] = {0}; + float filtoldy3[2] = {0}; + float filtx[2] = {0}; + + int modValType[128] = {0}; + int modValNum[128] = {0}; + + int numberToReset = 0; + + + float morph[8]; + float range[8]; + float modify[8]; + int modifyMode[8]; + float vol[8]; + float pan[8]; + float detune[8]; + float phase[8]; + float phaseRand[8]; + bool enabled[8]; + bool muted[8]; + float sampLen[8]; + float morphMax[8]; + float unisonVoices[8]; + float unisonDetune[8]; + float unisonMorph[8]; + float unisonModify[8]; + bool keytracking[8]; + float tempo[8]; + bool interpolate[64]; + + bool subEnabled[64]; + bool subMuted[64]; + bool subKeytrack[64]; + bool subNoise[64]; + float subVol[64]; + float subPanning[64]; + float subDetune[64]; + float subPhase[64]; + float subPhaseRand[64]; + float subSampLen[64]; + float subTempo[64]; + float subRateLimit[64]; + float subUnisonNum[64]; + float subUnisonDetune[64]; + bool subInterpolate[64]; + + bool sampleEnabled[8]; + bool sampleMuted[8]; + bool sampleKeytracking[8]; + bool sampleGraphEnabled[8]; + bool sampleLoop[8]; + float sampleVolume[8]; + float samplePanning[8]; + float sampleDetune[8]; + float samplePhase[8]; + float samplePhaseRand[8]; + float sampleStart[8]; + float sampleEnd[8]; + + int modIn[64]; + int modInNum[64]; + float modInAmnt[64]; + float modInCurve[64]; + int modIn2[64]; + int modInNum2[64]; + float modInAmnt2[64]; + float modInCurve2[64]; + int modOutSec[64]; + int modOutSig[64]; + int modOutSecNum[64]; + bool modEnabled[64]; + int modCombineType[64]; + bool modType[64]; + bool modType2[64]; + + float filtCutoff[8]; + float filtReso[8]; + float filtGain[8]; + int filtType[8]; + int filtSlope[8]; + float filtInVol[8]; + float filtOutVol[8]; + float filtWetDry[8]; + float filtBal[8]; + float filtSatu[8]; + float filtFeedback[8]; + float filtDetune[8]; + bool filtEnabled[8]; + bool filtMuted[8]; + bool filtKeytracking[8]; + + float cutoff; + int mode; + float reso; + float dbgain; + float Fs; + float a0; + float a1; + float a2; + float b0; + float b1; + float b2; + float alpha; + float w0; + float A; + float f; + float k; + float p; + float scale; + float r; + + float humanizer[8] = {0}; + + float unisonDetuneAmounts[8][32] = {{0}}; + float subUnisonDetuneAmounts[64][32] = {{0}}; + + // Usually used for CPU improvements + float temp1; + float temp2; + float temp3; + float temp4; + float temp5; + float temp6; + float temp7; + + float curModVal[2] = {0}; + float curModVal2[2] = {0}; + float curModValCurve[2] = {0}; + float curModVal2Curve[2] = {0}; + float comboModVal[2] = {0}; + float comboModValMono = 0; + + float sample_morerealindex[8][32] = {{0}}; + double sample_step[8][32] = {{0}}; + + float unisonVoicesMinusOne = 0; + float subUnisonVoicesMinusOne = 0; + + int filtFeedbackLoc[8] = {0}; + + float macro[18]; + + // For DC offset removal + float averageSampleValue[2] = {0}; + + sample_t mainsample[8][32] = {{0}}; + sample_t subsample[64][32] = {{0}}; + sample_t samplesample[8][2] = {{0}}; + + float progress; + float progress2; + float progress3; + int intprogress; + + sampleFrame sampleMainOsc; + sampleFrame sampleSubOsc; + + friend class Microwave; + +}; + + +class MicrowaveManualView: public QTextEdit +{ + Q_OBJECT +public: + static MicrowaveManualView* getInstance() + { + static MicrowaveManualView instance; + return &instance; + } + static void finalize() + { + } + +private: + MicrowaveManualView(); + static QString s_manualText; +}; + + + + +#endif diff --git a/plugins/Microwave/MicrowaveLCD.png b/plugins/Microwave/MicrowaveLCD.png new file mode 100644 index 0000000000000000000000000000000000000000..84b77d3503b49dbbd6b80c6c4d7df8eb417a2ea2 GIT binary patch literal 653 zcmeAS@N?(olHy`uVBq!ia0vp^{Xne7!3HG%7M$1$q}Y|gW!U_%O?XxI14-? ziy0WWg+Q3`(%rg0Ktc8rPhVH|M?5kjMl3r+`%W`3FiCm3IEGZ*dOPcE)*%Ox*7f#B zIXN1gIIb+c5V~!v|3jtqkD8wd#_TG67+o^8Ra;Ser2)s$h6x>_yNxoupRJ#K!Vjc-mYcu`*Z8dkJs7%)i8duVK~ct0Yo&YtjZVT zUg%*Kw`}UsbD<)d+2w^b#l6#ChMa8f`X*FcUZ`_r-J*_5PlKxEa(68v17 zRcdwg`SZ)2Mdw~Ve(U>R%wcNa-c>KE`L{E?Td23l>cBkq1(ggApBYT}e{cuh4YM)n zJ*nkC+1F-=qr>^ho^K6rZdrG>a>XpMI5y^pZ49%3st?rPG%&uueBSe^U3|B7pU%-1 zP1zTZ9HruA8?i?E3mwe{TKJ z-H^lhrV?l>(0Yf@4a+WHOWZBmmGU?>D)P-8_0CP-W-K$mUeN3S^5UepzD%tv?$e03c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0We8KK~yNut&&Yk z0#Ou(pF1-+BkCf-h2g@T)K6$5LIr*N*H&SeEwreFQi)O=DUh+1V3ad7MRRY9QBgEd z=p4@OJrD1D?iJ}w7J$KEpjfj~sgwXP05l___70D+OlxI;|K;=0XejyfEreml)b7C% zx~}88-pY`8JVp=%l#8dK6Ek8m9KNj;<>P%sGP%Jtj#3h(!jt5(n-mK9KbI@jE85Qv zlRW?pKuS5C_Di3;`}$Hqz0u^U+ndu*AxbG`yVh*cvF$m4ZFjk;KhEhU?zOS65HvIA z)f$e|2f*pSQmWoAXc$9`FpfgXV8Q-LvCMvchf?KwX*?-sAfD$Ei$)oZ+y&v;#pO~! zA`!>)LcK_5vIJ78+}1XhWg%94;!oeF({7<_LWuwP_P;UGv;L=tXXO9@002ovPDHLk FV1h)sz+?ab literal 0 HcmV?d00001 diff --git a/plugins/Microwave/arrowup.png b/plugins/Microwave/arrowup.png new file mode 100644 index 0000000000000000000000000000000000000000..caf124ee76af5fbfae8fb6b278c78baff5771297 GIT binary patch literal 456 zcmeAS@N?(olHy`uVBq!ia0vp^fFdh=n1xlGQTDH1El`d@Au}YR#5q4VH#M&W$Yo#%$S+SV zN=;Ens#I|I3)T0@%qy*!6WIKXfq_xe)5S4F%-qCi_=CZrvDQjb6W@5KJrSwNVqKV*_-(m1 zbC1-w4>sZq=WQQW-LPME+tH=vuS7|dN$vj!q4)C(ZrWO3_`6F#r*^4=;H~9yf8)Nt zFxV|Fdrtc6+-bT;d~OSF@ne{wKkbb8=@{utRs2G(ihe6y1X^~6$E=*vxhQ0PR^D8f vZjnu~K~zY`?UzkU z8&MR7pP3{bwI-G}>OjN>o2qLu;Kr4d=t5Nd2ib@qXra=bE<{n#w)z9yxu0w!u3Y%B zD2P(3CczIdP3L!ab_i{3aJaBQrl!V(sZ&$=*twDt zLLWbJ^zL0@NiZxHqVw}uRh8PF9^5`3rR(ebXlui;SoktOk1Z0x-QG@ZPY(zJ>g;U( zyl{3#((5Jdc3+Dvq*A=Bug@805_713>HU#vTY1o&??H;!z}WI~ER`^VD^02M1(auB$|smdHMN zLbAEptTIW;%YAQg@n$7n`h>T(NP4|I{X=B{c11z!>LMe{2)P{ASgi0QSff$Wb#=F6 zFJ4@0pG<8nwrJF}UpYC+*SBv$5N>P-_p4VoU;d?!yR{Wj(>QN!HQ~0)qEGw#@2rBq zCZTL~6~ksD{^kw3(@EChK*}IxZH=5H5g!^NTTy}TbaFg4hV=O}kM{RXaY{Bf zu^k?g=;*jtC)i>!szydQdHotgG^g$e1W0stQXUNc9}S?eVY|4050-U>L}QgEz)<&diW%Xt?*2AcaCmpFW}W_L@mh6g*8$h(CYc t{h4{_6JsKgC=N@-iSc(k6n~Mb@C#|DE)62fJ1+nL002ovPDHLkV1o6Lgz5kQ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/confirm_button_inactive.png b/plugins/Microwave/confirm_button_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..18b5899c25de775e205add7dc9032767b14e51ea GIT binary patch literal 923 zcmV;M17!S(P)TC(IW#gF$(7uhU5Z-P z5Jpa67>8Qfuv&?sEmXU$3)=CG?E-bxJ~Qvl^MBs|`@a8qo@bs{0FWffMK?8@%_j7a zB*~>xsp!V$67d>d5&lL5|A0WY?#$wB$#u?MzD0WGZu<1~1t4JHAhz$%;rx|y&X!zf zQ^qd(`u;32Q4}ews3diBrkiX2q9m3qTjR!lU!mb@L{a4Ot;e$cWfhfNy7`Es`KJjQ z93sQEY}@DNRw{kCc%y>MJqJ5i1cgFDR&D_w>TIMWCa@qu$HV(~m@s7;3Wb8~+yZJW z)g&g&ASE#YK@ixs?}&SU)7M5KG+IK2hW^3b(%j4>%}DpMRGT}DiJhv&T=jy5OP9Mb zyS;(1;c9$*dIK;yO2;d6Rp)0yq;?#R)>iUzviS6|o<@5ErA2y-#Rej^<7jPZ;pDNy zG<^BYr;qhy?aDwsax}q1h5^v#Y~w`kAy%y0_}{532m;@}f0OyHnT$-1(gC20n}e~~ z(D@=rLBZ5msyoCiuU^W0PKN{Q+t&mQ4tD!)UNh0puRmiV$I4=RDV6SYFEm{8ct(4S zsr(5M8ZD=eACciD#d@M+;|Uxj;c9E+L*4t%7r|C*Wmsr7~mg3+SVPIE1zS1QzPSf{`4`m);COz zj`^ojsIPm^ft?wotVu-_FYdl<>h3f9x>{ldxE9fOx3fe#LS*2^OqLsiJ73G xx%vCw_nGcKG1~2R@37>Z7~9Li`-`**KLF-RCE{*cmjM6(002ovPDHLkV1mW;v)=#! literal 0 HcmV?d00001 diff --git a/plugins/Microwave/desaw_button.png b/plugins/Microwave/desaw_button.png new file mode 100644 index 0000000000000000000000000000000000000000..e39b973e3e264c96b1bfe977394899cb553baefc GIT binary patch literal 879 zcmV-#1CacQP)dn00006VoOIv03`q= z040UsOGf|z010qNS#tmY3ljhU3ljkVnw%H_000McNliru;{+T74-&;JUbO%K03c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0?v{4ZRZGw$y zgcO>@V8D+eupv#5)yihGV6@0pE=audt~zquz!b}G-t2$ho7s7S)9C~#Q++1X0%e=c zR&~mCT`yaxV*7W*TPzk-RYg@*9v&Wu#bV6P&LWCp1^@7sm6b0OFDxu@b#+B5l_DGt zQ&(4Kvi|;lve_(dw;O;^D8%ICq{;X9_gPRKo3cBg-!63uK!+&&~#bS|{mlrfmqgX6*e0R1ib5)t!r^eBCsTxnN~IDV z9UY%y=H}*@nVA8gx3?Ef(}>68#N%-Q#>U22T3TXpagm{+A*QCL%(ar%4nYujdV2bL#5$eMYMrqBpRj++Y5_sl^{Tv8{s0EWCP@Z8RL=ka002ovPDHLk FV1k*;jO_pb literal 0 HcmV?d00001 diff --git a/plugins/Microwave/desaw_button_active.png b/plugins/Microwave/desaw_button_active.png new file mode 100644 index 0000000000000000000000000000000000000000..ee3f0f08e51dad698c52634d1b708bb99a7b109e GIT binary patch literal 901 zcmV;01A6?4P)dn00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru;{_QHEGfw<;1&P?03c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0_I6XK~zY`?UqkS z(_t9LKfmAh+dsE-DQuvKX?a>n!eC>UATQ}H!YSgVi_*mm*+E1pJSZZF;H54VfnXQu zq8DL@oF)zYa}c&xAu^Ylroa84+pm)g*~mJ@q6ePC%lCPo_xrr>_j%t}0I*uE3MFQd zNJLOutyaZkGEsu2h?KDXJLDBnBp3(~3WU1fi0h@4KB$K*SA2ySnaYHS4HtH;C9{rh=*_xW=oV`KU8{?HKLySp#mc_EeJ zT4N*ib~{#&hlJC~w}F8I{LC#QBLzw0b~|!g8#P^B)U~vr35AHeTzUMsy`8G@agNjx!oXb$Ez697Yw5 zQZYM=acK#FbWIIHCPT%G7bI`qB&X4!fB&9jQxl3xMY6dW-TFGx&JO9?T29SovgPGy zL!p9o)E5zvc6U)U8nPx6Vl0ND)e;N@@_5zgDCUJ@^bV0!b0XlpB%=I7A_gCuXDvXXE8{fN;h`jwSGyKQn>ElHb=$ixKYuV4SN zz^bXKd=E(BFfo^l!`@yp77N+3GBR~_WX)!xw{KJC^`7e)fK)>R2A_{uOA81Bs#pxo z&JO7-S4cP<7>eka7Tal0`tE}n}uE-Y}|(SdGbgLHj8dcQx9X@fx&K|tEuD@tA{)fZNlW&Xdgf6IhY b{#E_}#zHRVsnSdI00000NkvXXu0mjfcx{@j literal 0 HcmV?d00001 diff --git a/plugins/Microwave/exp.png b/plugins/Microwave/exp.png new file mode 100644 index 0000000000000000000000000000000000000000..acb7a55cbc2671ed17d4cb0e8ae080028f1160a2 GIT binary patch literal 539 zcmV+$0_6RPP)AHt5#EFVf5n0=;+-!GkA{9z&r^f&L9)_o9nLkQOoK2y##( z1Vt#AKgRbU2x^Bdx9^?~wb*2neW~a4Ja3-Y^M2srf&U(=VsARt(VTO3Rhwxi-pL)r z5q!XaXV~EH1rU(L8z<-q1~b^mdV6ZuJ;9dftwvrEU(^%qDzU$VdWd^-R;HTD`(4BK zhf*5Du&NXRq|VH}*Lwq9!5T1gzfbMHRMmGFEcaUfLOWPmT(hM##$*7><@0DL7>d=^ zS_j}lZs#8i?sjxm%X$n@N1tp@#*3fEhc-Z00o2d))Xs5#TiDJz&qOti%J)zv{IsF_ zrS=Hbf{2clPpWHUua5d!*0yubBCw2#i{&Qs$s1eE4vCLW#H#CiL1I8&+@BA((l__b z-K?_&ECaZvI(r!e_>v4CUT9?+)dFCjA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_#3L)BEz{Y0;{i~p(9^{+#Nu?ah=9nS^A5}hjyNbg z7&k{wu#8mqO9(YNd#K5%SyDnm!b~@&W1+_DBb<|X(+{fsNcmL~a{9v$w&~|1IyU}2 z`Q;_gY>pKlyZhDOBqh}}@}w9Uw>uU|n@ZHLIv{phM7n35+)37+#Yfe67#QNTBt_@O SR(1d_XYh3Ob6Mw<&;$VWAW1C% literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filterBoxes.png b/plugins/Microwave/filterBoxes.png new file mode 100644 index 0000000000000000000000000000000000000000..37a0eefb8734c67912c7b971896ccff3a297c4ef GIT binary patch literal 13855 zcma)@1yEaE+peKd9Euco_u}sEP~6?!U5gZVDems>QlPj)aCZsr&Pjip_d7G^Ki>>Y zR@Tn!NoKFL^IXq$C;Yp-1R@*`92giFqLiel66moH3=G^F1`0F^3Q;QnJwO@BNQi=A zgW-V@wQsY22hG4bNNPHRfx)Bw{Ran2&%^>vLc2)Gi9zpv{tSsgTgaWS2bve>NhBe!${=fL=jxHE7<3PMDVUU~kc!93S(d*_l56*n zK1M{s>hkW{!AU*>OTS>Cfb`h{A8J{Ml=4VDj#i6c^L)_v2#PQz9b0sDa@4&D@ujZn zI-I9n5-3<{*9*%FtMlsA{#Zk^ueR0?UUo&FhvQ#{5N>d>#EIgkfOxUv?%AIFQxDrO ze%(12{XW?b$hr7JSbL9PkW_*DvIr#SZHFaJsHdF1Ctu8n8=ISkm$6KA-ht`@ROklqv_a#%@k7{oAY2cnY)4+Agb>Z42rBdhNe;Ja^C7tm1;l=d$fQTQzF z_GV>~P~Y@fJ?0l^t%Lc65+x1aN&L>IAN5Tr(>)ee>^!rOG##G+5Xj>-_g}AN{1-_g{G&k@wZ^T&h%RgNSi z&+fiVYR~XRBV82khQoQgPKCxK%H12CfahD>qQ3UwbhjyxU08$?xpJoVVe)WK=<|NE} zV@YZ4lzB*u%Y>iMX||e92P}6rz|GvMs)?2Nlk#Lp zYgWL*{M9SGBkzYWUX!aUXri;-s;Cmh?(I&9A6A=a|Iv)ZG}BwQ_gq*{t3JuT`w1!_ zI-~w^Yl|2--(x&++1o2(vzA0&HX~>3uFdw~0k#}YQPSCy;Tk;F-tY4Q_;Ib0Fw`S) ze)WLG(4xp!+?k(XZai^#fBj3pZHQC`=%cFcyLZybBg$ z%tuVgBMVzWW+L`n<*M8S)sV*5$j#xBW$PZ_J1^l-#C~@#8p_OjV>+#A;1I6%9#(mB`3CPmmrlX2V)+G&lM_phDJ=XNe zMLlMQ%`rh1Qt7SbWtXzXj;+;on|V~!!f7Pua`27H_eVFVr^d|=Mi#?1&2h)+UsB@Sm;9?uck})2c9^JihZSE$KNzmk zk`JRy&B)sB$5-Dy6D*8AYwsHeIAYIxTCp50mmM$eJ&ZF&$(bH5d}5K}oYf2jRmHCkA9tWv3Q0DyRfV;%W&0qCy}s*3GJ!5- z!T@+PlrajE7QSCi;K{(JD28;rHWyARkyw5J$#hui)x(ApbpW&KO_ zmT|wMngHkM%6&^|3*8F?Ir)}MHB};~9d+e}pteI&@@S3epY?nf#aM$E`PMh0vr@S7 zZECj#le+VMPaE)-dEs?*Gfa0iO+X@6*4J=vw3qXo*WgXe3-W_sb(xFvpBQaV-qwzH zA?VHEH%1g=m0uL;o%1QKS3k<2wg|`ch>g6dkK3V#*`q&`e^>m$@5#2}T9*{lt}YJx zw!p!*e9Vt*@zzK^Q$=vlCp#BA9UdOyblfRag#;^+&)I&t=z%skszo-NY8BO#=E5`& zM&q_g9g8w5NSbJ)xkln;D6lbrCk~|R=(E@jSLyq$#i*;@K(Mf)tGWJF>7kKvmA#fP zc1AP4m7{Lx=_6C-7lXEW=qxGu>vlt|r$hTwnhGLjyju#}>d z&|lHZ3JDcHVoLd|9Bj;SDv1Hz8*EvQvfAymo+Y}j-N58DR9Mf@l|MZnH%o@YM^u=hJ~P#(Ta7p@^%>`$=gJq(h9 z(H~ZdR(e$XHn-xjd)nc)5AlgM=cv@{Pur=S(<^Yl zzxZBSCB;L&_5=5NDxvr($#=kKv+iHc4|vta(^lWCBu|q4S)ZFc1e#0nT;F*& z9(TVu9fWBA^kdi%NYx)WeKUXF8?g#xG%$k{io+H{wlf6X8UyyL6|J=+Ghsn1zdAjz zQ2d{39hn$`vy%-6kLv0_ZleF!PWWFo$$uU?@_l}3D-Am1sw9DgpXqQ%rjKok$IhdD zo+YK@Z5X$DRZPP+wC%~4-FcLdqN-WCFO%hx?oHG$pm(@da^_A!(pm|WtfC`z6=ne= zE;Cgrg3{cWtM737Ol&*R*k~E9#O~mygrkb|vM%JJ?cCyfiTlLreI}sZwb3g#ly#Bb zHc>ala7yjGG>FE16YGq*ICryv-tBk(dN-TOO+PWRYlm6q=XWs0+2c+UT?QJtjZGQc zH#4quL8bCq7LED&JBE5LJ050VeVhX=s|DZmV=xLnWr7aW=RdnY*c1ujw?p;f0IF zi0z-0h0VC;xx31ia6(O98EuIJ6 zm!v@V3-S_!ya#-jL&8vKKYL%tMZGm<;5vVcp%6MP1e1D5l>T__Mq}m~P{>C=}oVe`-x~1el?&m9T$r zCe*5izKUx9(eHn(BPs1V6=SXku(953ztMfMF@_T>DDcii1qZEXEQy+c*!Lm}fBXp9dPAHgZj&fgavq0|z;cJ^S?g_6ADlh-DKu2A-# zd8bjnu(8=9d^Ac*=XvMc_%Ka+8tD~uS8f?gAt`0-TjhNPS>d(T>tfCe~ z{VZd{mzxTcKWH7wk-EIT&CJn79@571qL-DN`%LX15Nau8@yG3vacUuaB`jdNc1-fR z*`gGcGhTk-bh-HX)N^oz@6!qpJb!NB(;}tHUOkJ;b~)%+=>2%N!^YJZc@E1^&_{^A zBN#f9@xeULH>nE`wB>I3d8OMIx-I3D;T;rJ^yE%RlTCxoT=bCK47ZG#7b0Afh%~ASs#`|&RYH2DhL#9-+&BaZ%6w_eS#Eex>p@flU3LNmRG4S!1xAI#P_|5y{_e5^$g3iUR5@&UvuNv?_4vfUwpo);0t-3m8-fdx@JyA z+i#qT?CiNhBam;2b&Y>O!@PFOLaTJvVoG#q=fomd)~&#ET#=4-G^g`*3vj_AB}HxZp_Hms zGBzA!0JcQ}lb>?xH&ztPoB+KVi6W&urLt+@-JbzUgLa3Pto80Jlvm7nZ=ZN$E0+d! z%R^uGGg8k2=lU0_4}ghLO_cezntZgEZ%(?X#E)CCH6iie9{wPB)G`l@0az#~8s<#F z;UA~J1up4k6pClT?$u%Q#<#}Gyn{oIYTSp_?T(wD=r8sNX=`URz0IrA!Y){VuyFSY zbI0R7gwqOm0<&P@;W{s^NxJq74Dvy37972r5FO=wNDW*M>1;Hi-t@Ua1jFSpy#nFZ zLWTcO`gTxI=u#`Sj8Z|y;CZvv`4w0_nw-3+KL-%zmuu+LeHp}l8Ck4xkM(7(5c3o+UU2;158upr%0C&=^M84phix6!$4=R6DjQ%24=}%;y*L z{l}vVquGqfpF|3Pi=;qYIVu(6w*_daXgjp@nyli=(LXkrV;BuZsz|^6?M31>qc3hl zpLy9nMOMv2t+p4DP5tgk#cL^>!G-nVg>h)~fm4Dqc$I{X0{-G3j&fMtwX(c3-aa3l z+Lo5*ZQtl6Tya+f*NjzD_G|t4i;YBNE9q)~R&f-%f0Fq5*9@elE6R@;@zk*X``i@7 zd9Y>_XYLx_Pw2rbXA**p4k!x&YFpZZtaqNuKgRE02gQHqFWx2LkQiwoTvNLzV}! zR59+z#3{vgHvV+KPzr2640wk>nbIA)Hi5}zcnP>aKMF=J2f8}}b^(4WW0|GlulN4t z;EzM~>S0TI((UKq^>W5SuqrCK3VP9Qx^zVa=gIMI-X-GVINe7(X9O5#-sli(nBm?i zJj~Zj@|m2L=-|K0=FA`8UoOD0xaoqIS-vTzC`}GvZwDjc9xxXyQJFedM|46=jZxt) z35OAlRWq)5kR&tKV#qEoRE9RWsjG2>0Ql&~n-OiMj9t{o&gD)W-vth5_s15N^KK{eXc%OoYhQ@nM?4s9SEk564)V5r{B!W}h&aZ9=2!{j)S#_VG1*z4+8(ePew z&><+VZlhue9epS~42Dv&s<{~v->XDK3!o^^-JG!1uRa^l@-)om3+zwCVv2^fi~OTqopoGKwT8dx_ka(N z*)_aSm2ug2Bfqk;@^}L5QFK1XBQ5R}QA|`8|F1m*2qgPxC}?Tke|LBM%f|7_ zdH4HvV&IKb0n;mddyX$UW^8LBeiYGt3j;qz*MQ@%VkWM!S_5htyep!P(l-0jD90#W z?k!rtXLbTIV~T=Onu(NX$0W0+5d1QXU#lt967VwOQzGweph?Gjo!}ll%SL zk=Ga2Yzbe*`6u*Vrc`U(9p)SlJIw5yPjBG8NAa4kf+t^h*9PuxJ6%I+a(Mi^Sc~Ol zoUdC~#VT`ho>(R?vLubmb8_0&uUS&N=%d_fz$p~8j_Wt|*9-}o`4iP0X9v_77ApL_ z$RHaeG$8iFzr@+%7~7p*!gTCp;f_xm5_c+AktR-1eG>T&`7=(ce2mCR;u!VjzQO4( zi85Lk1*^|^S+2T=HOC7{Jz(Y9V(|qaofNMnT+Pw{+Ez*Zmg-!c+xKJQ1*{jWT1d| z1>Iq5c6Q78Q)=Thw2h;=nIeS2nn+X;A18kOP?)s>O8b`j+>rX@5KQ^@q=dL$u!aXSi$Z6M? zUDEKf;<88bL^X%U5p&!-Hk%>BMKA8nm(!&Lc5w1A`T8gzKj+ufI9t|K*o$HVA{7od z{1JQ$Q$`X4bMsPe5OdQYAIcDu&O%dwLc9fbTbKIWm zM@IxDqJkywj@f^@xCn@WYllc>@~IhBRyeYdH1y{pAWWjm8BxmI(g+nQB#B9gj&;b- z2iTIizwl|>ix#o#TbzF%P%alR=SwMXdU&WpZoh_+(R;%?^G~mY72W&}6e|4N zii9f=l7MPXn>_7khAI#mdWI>o_5zfX)(i{o&@$=0eNwPbHI{=nDmPP1cu10Pw2zTj zB0UtUMEX6ww3UGK`9evlUc}lurw4jqFsL%);E;xb<0T8LP;m1*w8%qDaR7F=ezNKLlPE$i6MlQfxv*hv}BW&>w` z=z?;|7cwr`7z~JkA&V#M_9!dv5)$zOp^gm+PysP<}Wo4eGmjeymS;vfeUY-l^dON$B8B#u`&b%)X-3 zI94|$D;ChC<`h!4UBiJm$i8P8NosC+VafUCe8(6{h1K9a8K4xKFlc@I> z6zKJ}MZHeO--<(6>&PjB2cz5VBAJdozPS=`mfmOhW8D!&?OSo<6))&L{M>ww%hwu( z=CIRHDi}yQ>8b6ozO7UbV#Ux>k%zvICe>~)R?fEdIt2AobSU^1I?uJ2TeZd;1g8sY@BOs+`i9^n2x&)yHRC zgv3`4rzb31!r}-LFzJlN3%7mJTM46Lbgw%Dw9#RVZ52tJlxF1*1&E(&CW>OcldDjEvX z6)N2%YV&I`yc~#P!!wm)&q zN;@}bLQl6zX#u9?{h25ym_E+Qhb5kQlCRjnotS}MbChG#2jcgjoTiV%W!&A#W}Vqz zYsGFingBQ|uIs2u_vQ^a6-`v$*qq?*GhH|A_B|2wq#4=WBz<`Fj{3D)N}#N#IMPse z;OzZ0R-hcqUL!K+nBdZ9B~rNkI_$vTJNPraV9+a!SPiPUsv5kx2Si@b`#inQu*Q+%hrg zISBl()lDiX@981S+(`N4mJ3owjYW(m7zac1l#WLys;GV?#@=4!iW1DD7creznE+Ws81KA3fg?T2`Lq<1|L|L zP**TBtq#-=*jOe*TyCy@H&NT=dCTKhi2iM4-PGG`M?J!F$v`n=YjrFBiSWxOJo=o# zBycQ&S@7NGqA$#(Yxk{MT5lSy9oNpS323p^?w6tWx+;PT1@lRS=RF{*VuT5AE=Ip< z9!#vs3)|eZW&&LZ<@%*b+6j=jQw!a!$n~lN+l@Q`uZD>-w!}KE0ksP}&+is5QmGFrB1rJ~HwspCF?=`)b{{~D(Mss}qU0viu#7j4B87wN-Km< zs^J>e2k%LKc91yQ8?l(cpi%yG+>?aeM=t_#Q@yo1e|L8?bng1w792l2TKEMhSAg#F zHw%Dgeiu|wY3m>9HCF$jr1YtKFM>IIH>K|xsqwRfX4$Kj_!_-5<{eD)MeypE*_iTN zoNOa=ISe3w<`9O1Ha$Ss(9O|2S&T1yM(VG-xp*H@c=Wx}GxEb8^VFpWn=9U!%Hrpr zHfr9=!n@;aBAjQYv?A$w%drA`uRBF2Y5tW^?HynQ9e;QRa9))T~CK;}$jbhK1BuA+HJlDhqG^|=ro|hwbRe*1>g;>48 z%0dUpGVjcfsWz9VdRI3pKBYcF{+Cqfl8hW|R-;j!z6}2Tt$9)vwl@|9c}JQYD|>g3 z<pO>DrCgrpBvsiMkOBy{6A4#V|pynlClpGSB#c5;QN)h9#hNx_+dF<9DnYgTR z;3~;ginVz=9i00RNRJKmi80i>0x5jXI}@9m*}I>g?E#rQLt)em$T8s%RaIcGmnFtN zvg``-*iyd*I_2NTthSt$NC=45EqgBPCXEL&+tzD-7V14o6zE4j7)OpO9!~8>3%nDV z>$RF5J?y*%J*kdw_!lc=S5m-0n294prlCM?V~B&+zs5OE6DSFi26FQ|<SDel*9;)}MhxvxU^#49u`zB|tY@z-3|o~qMU@m^m0vYA6|dGlC4 zINcrj`0RDJfrpd&4AEtCvzff-ZYaP*^Y^G5Z_3%!lS6a6mRAHbd-#HN>wu9&wf55o zO!w5#s;NEIOqZ+q$h-0!0@&VDlm$W09SD<*!Bkux-o9#&Lnsy(4H$bB;IIkHUv2(_ z*d*bEIc!a_{ZHpxr4HY|Q~?O8E;ZZ|feaHR+5PCb&Acmj{7tB)g(-2s2}b{K?+G}Z=05GfvWMj)Opt{DHOO0u%=a*R& z>Bva8HK+%utr=uwhEYPVrVGX<=)KEhk^GPcGG<-v(Kc`L6X+p zDL8le5=-khiJsk-xD70zJ&KY&N!4{75Xe7FOuT z5fG@e0zAQ0gu2_AYkMFRAuKb!E+n!j-S>g8py>6rf-rr_+xJ4AD#hh|{WTdjheHPR4KWvLxUaG5lEvD=Eg^$w-nofpknd2U%qtttT&*2_u z%mt>FYbNdS?JKTj6eI$MJ&`LQ7+Kj{3&ndol9EoRS5^)$gzBz{fW=R35hD|Rlu*>u z9Dv?9H@l-vp^9_^z7)+Kt~rn{vyH8_|FT!V=wH-t#KhYWh4AsVhu8Y42_dR2CPDI};%CA^3Eu z4z&DmXe~sy}%X zprG(7)$?*_vI*vom$elvp&q*t>(Qe%I~`%hZ{p2uy{t796IAZ4EK1B35vt4W1OsQPr?WXL(Qz2E`2 z)V92_Gr0xZE&PS0Dc8NxxG4Y&rlMzt({mg?;C$W}tD(#T4Em2NOXO8E8{xx!157A> z3gapb3E04S?h~(yS20zrOqZxPVmtNUfkdDf)qnlAwX`Rwjo}qb?|6>djQLpK46emw%noKFRCoG4D^&Jxw9m{TN*48T#QPbf+ zIO#I*YbuG;Z!c@=R?&lU&d+3(hulsiGwhcLhDPX76G-Mja--@NZJO|ENG|pMl@8fOox7cY=^J>;l)v(8LdSzH84i1QT`y!P27d2uae=GRez`q*dKwm# zlRJHT-~$5@5r|2a>RmzF2O^LgLXLUR9&Rp#0t9Rzy#zX{LWAzrl?}=o%3|8}G_1C; z1b&b>#WFa_M%&%foOMnW`;yta$h#5l=cLP?CSTF5jg~3aTqq|VQN?wK@eIRYT})-? z3j<}R<8jWYX-;o6^GJ0Y^pQKP69J_xKX}=LC{Z6AM+5={vBwCQ+%lhJ-+<2?7S`4c z%{}c_PN5G&lB+vS68n%qxwa$jR|?&J zhJ81vXy>vdoKTZ^O|X8QAOv*pk!U>P{M;uS3R0F5vzqEL=$R#Eepa}gIwPc$| z=?4sg*>>A@01t_fWxwLSdZ}(-|Fba*C)PRPG@83BI{4P*#i_fjwTxD*WMJX)=4Ikr z02@M6xcN*}He)M%(=?Z)nwENIv~1MeI12uFVN1naah3J{J*Pz6pss1fK)WSr5Bm`_ zahILVi}Xh!)Si?pQA#_wTvbAk3GuQZVv{go~ZrK zYK#C&<%>gkLP85B?MwL>ugsNLt28vW_|10(Hn0zkdpML;8L34+P_BrM>PH0J?MTH; zb!3qXpo@9d?gB6@*^jB)x!&JrQ)3kHLgL6^Bq7c}7>-6+MFPg@`i!vY|G@_aiXkz2 z50Z~6jka-;W=wrQ!MK+VF@$Orm*rpKLFeoO==;F8vg{V*qfyXQ9ceM-WqbJ32 z?Ij`0%|FgOqbC2_IKIh`L!EY?Wp17%0_yEAIlkjTa}!etIDcahayd?yCn)9V?`f1J zoXHAJEj*nz<9-P``?LwD>)mDXKMK1a4k7c&HU07|HgALY=E1~BD~o6>c~>DL0wWv0gb`xrX_i%lxj;yLNVST z;oyNvTFlgI8}BjJ#G;E4(y_aG(QUk)kGb6LipKB0A*HR2tMB{9VKtd${3i($X6Vn4 z1vN0g$2lf`iVVt}$`rc{Egc+2ioSq` zZTLDnWj&b|#?rdDNKPiH{>M$?Y^l@I1ycTMddFGNe}t?*+D`6}?6^S=Vca&x*UwNP zt)D%6I?X?`d&C<8UfeKb$@w#58&{w@=>3`x`#wBTU424xm3Dr?Uc!@(!zOgf0m{=m`Fe<(U;N*5);Wv)HfM70HZ(Y3EuS6Ar<5tW(5^!2@&BfOlMB{;w(&MO;VEU4*nh!Ut@p-fDVx{D3r#A!FXZWs*T%He3 z-b-(wvDU^58`A}3tw|A2#<#=*v{@FeBr5o{w(T3chgCPC_@niAI&GF?2_4c~5V{5D z3f|tiemir$i>3+!so}Mk*t}Q(v!@a=E5NB6oHcQazv)N)+q4s3m^lCu?_K6lSgG9G zjrS(sO#5Xa>te+mSD6Y2e|)fC!7Zfg7G~g?VA`!mN zq8WjP2V@LW`J-5Wg(9z#)E>QO*JBQhE(ILGPvDn(NZ%b+4kyeZi^Sel(a0;K5urT1edy2rk(B7Q&xb>%8--Hy&lNm&O zd7kP6g+#U=N4QpeVYkR!<_dM87)bJP+=3jVTrI&^ zY%@(>{qVgqNj}#@Zw&LtX|I#pA7qrhGe)_OSkdvZ1%M1_0b(nhv5lcTZ;tT~Hi?U^ z{vs%+#hkMl9HFZ_8?!pt^Oqle9Q$_B1M=)Y381<+ z%8hk{O@G*=Eif-fk?gQdHZ?O_seHakyd_iD1L5V>8OJKICHE?hx7~)W&v-xt)Ob$< z$oI{9jPpJkA8J7wb+I)Ce__C7!f|tN(pxj0`cITeP?O5SVToPVa-f^gJ@w_WxfMPZ!xm{P8ldhKMTi@tF z5_|TL#q`XjHldP=%+uB&qKs8zs?r;#n|pNj-N`g`ld-&WWXi`QYnUwyd)|#xEj$Dv z=tl#U1(3Z~_^w^5@A)(c^4x>($St%6LRcoR0xQ4-0mERnxWB*Ck`j{_trj*2{6E2f B7})>- literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filterForeground.png b/plugins/Microwave/filterForeground.png new file mode 100644 index 0000000000000000000000000000000000000000..a2446cafda31ef2a7a95476397947423861a663f GIT binary patch literal 2684 zcmb_ec~sKd7RIbheOg(WSw>~aO;R(#G0Rjkx@t~f&ZRvuXA)AJFzsqtN?|?I6lcwm za)_LVTau9@Pf-(5$q~hzBE;g6<$CYlb^m*J{nj~Wt#5t%+k1a&uXBEPtt`!Cq!gt9 z0Duhqf~k$@T>ZYbZ58czW*rSh$5!`W%}fEp?_XwpL6QiO47}hF1OQ0y`o6>fsc8x# zPyz$DfJv}7%K)_X5_q|@0DzPv-1MAX$lx6Fy453|7kq0~YPA3v+?*fLcT1jLjH-r7bb1mDY_USaZC2)#J zB(jzu3q&Dw0d2dB?c1n~OA;)cJ+`;kGC=E0Xd(&EmPuy`s>)?mE)cn_n$nrY8|@C& zHe$%)8P1H|lgD|nv0D?;HBE?ifeYCU{E--W9uzy;f@DXY#@Q$roX-2y-|tT_co9*X ze}Z3CzN=xn?^OZ5)|iE_&iQ?1zdnw5-aM@zyp%v7da8@ojs z;bvd(u7y*|4Y+7tNjxiX-tRu4*NWJ~vNHaBOo>&O_ksN{e`a=FCB&qa*+H`%zMC|M z&v9PyB)@0W0f~+MWvw+e{$$YEoTq+bb#-<=6d$k4Pe@^5*kVpbgkN>hJK7$F-5)XG zF4!urE6pCUAcMn&(P$r>g303){>R1T#U2f0iI=7&QE~ROKVknV&q@_j*gpL-!+Jed z1zC;3bfREZlS*StKv_?%BK%6rCO>+$j=fP+C){x>dVpp>idcJ9C-IMy+=yFQ&4#Dc zLzca8g4G)4tBJ1<%7e*S9Qc$9W^73Va_vi?Auo<{Ah|uBz_^6Ny)z6;+%jX*E;x*( zs>{c8)q;5a=y8;%_smc=F*oClDfrs#<@AB7r*EcBW+jYumb+Yti2=-f0gnq+yH6mL z<>yV0HOfBg^SAf#pn~{N2;^BqLj!#YyMlh1S4!pU62d~xD%6ua-B*K|^v179Ju?EF zDAk$gC8*vF?-_r6)Wy>LhVwT9)WdK1#@~By=+^!r=t$YL0Cq@q)L3A7G3GaAGE@t14Oxr#$Vc$1SotL$y>@x=PF}bAp zyGRd{7#rT4J-_#K0j0u%bmEeRM&8_NQM+KV>N4b*zGF42v+#Mk9`*eBqKw|tfVDK?xHeEteMCoV{VQ}# zS=t%)7ne;a_F!n*t>$x!2S?a<&?6(wYLQvv-Td<~!kIZhBmw*`>xFPKK|w z<&APW|A>8E*#NoK$76X&oqX?M=T75!YQueD!g1L)f7j|G_$kWog2gn)o_iugz-nBh8PZLE8Q^pOi)t4^BR`0QwA=0ab6# zDJnVFc8v26GS8scX?|`_Y-g9w)Oe{a2?q-A&&wX?eX>sGWfXI+Yk$9AHQiUu>EFT%Dao6?Hnr{(Bx%o?($!pkpl@5~H_U+r@HvSjm*VN<(R4lwh<&buj zp`hUKeT~+0NJqyNhv=OYewmiP&{BY?SP+j+B z=YTHi18?e8SsChmEyvErD)WB5zq7^%V)X#iVcMWs3`BL|gR@B#&hQQ&u8(!)sTV&)a^y_sq5*;M*CIT<_Q87o{o zLtYo?ii?hkS@9096CILDfo74Bk@5Eu5LQ+X#@s!|CnwFOqH0rsdqKs$s_=5h(p2DH zhDQ*tV#tW4`{Y4W=lAr0IIfXU8#k!6xUXv!Xwi4(IT*B5H@dVCFS{&;dPoV@%Mw3? z0o<0|p${;Y5LLV?O`V)Nzjpjt)VUZ00!=_{S@oIPvV~EDHM@G%|gNt7Bi1lOM7}u zBGk=t0_WN-dR2d<{#jxse(Y~ZwC3L|03&yvZ1?C^g8WNoOQD|bk?K($NoPQ^fU0!oOSWPtAH*%u41zhE97dM z+<>n(l>vjn^hI+A)*rEyOCs7Kkt%RiFxb}JMlOyURa;nCXx%gVdri<}B2gBIw6Ks7 zp$4jIYQ1N9v(pQ>5SWB{rkQKE=o(dYaLg2r>`@xo!-Vdnqsp_R4B}j!onL!zI#Bat zTGu`J%jQI2mUtjAajDzH#II!QNdD;)NHCry6Br~EpRR%8uk&o_qW?qy9A;@+W_%_3 EKO8UeZvX%Q literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_allpass.png b/plugins/Microwave/filter_allpass.png new file mode 100644 index 0000000000000000000000000000000000000000..53a6e1ef778b8f1fd749137a95c834438a3c19b6 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkeYT^U-Yy3UDP)F3lsM<-=BDPA0J#hd0r};r zMX4zYNtFujexdq4nR%rZa{`;c0j1&stzO{p0kTN6VL3tV+D ZVqo~k&n%&MW#Jc)DW0x=F6*2UngEKNHeLV# literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_bandpass.png b/plugins/Microwave/filter_bandpass.png new file mode 100644 index 0000000000000000000000000000000000000000..5c320cb89bb64b0adfe5e0131e14fac8287ac2de GIT binary patch literal 359 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkHIC0Gs$T+y6f#31N}Tg^b5rw5fLsQKfc)~* zqSO?Hq)G*MzfgUj%)HWyIf2dJfKn$sT^vI+&TpN#m+xSK$kFpV|NAXv3)|gtVdGbY zT{n9lNghe~&JyPuB<9(vo*>-4p7Z(zfmv-*bKcg?`R#p<^`EYq^wg8rG_7_DHpITT zWy|o(YWk9ePo5l8xvjFhuH;pXO2x&UIVZj@4oj#HUVApCda{>5!i*hZ9xsn(>GhQ! zaPbKc4S4XXt@qETUWci6!A=SetG?Xls4Mx_GN-QV^Rid|vDIoDyPMztJZ}BvS^KJu yYeJ_jkJX<(OG4T4n!dDhqsG#yS3jJ77hJyE$mq?gbI1BY{`GYAb6Mw<&;$VS?UO|S literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_highpass.png b/plugins/Microwave/filter_highpass.png new file mode 100644 index 0000000000000000000000000000000000000000..0411ff565cf9d419c3d3b4310731f683e982650c GIT binary patch literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkIW>#MQ+I(v3Yj4hCC>S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pH-5IPpGwMQ^@+C*{FuM8bwbh(UNQ0gGmQ<6<|(K}%v9JVal50B{d4jBturDc t)(Nd{?3_7MvuDbTv|r~>h|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkRnvyv6lgTe~DWM4f0=Zmj literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_lowpass.png b/plugins/Microwave/filter_lowpass.png new file mode 100644 index 0000000000000000000000000000000000000000..1623aafdd8a34957ff54e49d0c08aec6c7b576a6 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkJ+og0Z@hp)3Yj4hCC>S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pHYg(I`e`l$LAvbw3L*d)RYvR4Lg3AG9PAJ?S23M<4ynUnGY|o|NlRG{*~ud zO_$kBzJD?_G$?skDzr@R7{_Vv_>#_R2TmL~aN@`Om8})h3fq1}#{5b1+rtI~ZfwWQ znijV3{rmTG@mUuy9b;qT)`?3V+A9ZZoXq58(6doq$vTmx0^|ixS3j3^P6|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkRrzSMwQqq!3Yj4hCC>S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pH7sn8d^T`PdOcS>3`tsMl=kx#n|34r9y3!8F z$~pO|Jv+%zZSKdPw8OvS#s>K!W9Q228O=>^3u!&Wnmz< NdAj|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|Kk70U?ZU1{VynIH|9`x>v$gT)^v1@8;_G=&Jg^sT)^}7_WIp!4=i096b{s-$ zftngypWDx7|0tz!V7dx#PY;hA&+qS>CnPX0UeMam$*bv?l#r10P0^ECn0c{&q$eAL X#We{|ZO#j8KrZ!k^>bP0l+XkK5R77V literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_notch.png b/plugins/Microwave/filter_notch.png new file mode 100644 index 0000000000000000000000000000000000000000..b05ffa93075647b76349c58888b146ab12b78cea GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|Kk9Tn^U{~Lfp3Yj4hCC>S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pH%`@CVnA{`ynAc^F4a0;Ot(&3hbNmnpbQw*S3**62cl#oR}~3U5>~ zI8;}z{JHNQ=RUC=P4)u&mOGmLp2t>M^pc5T#?6~L?-&?XvQLUTn54;i$@p^Rwf&EO nX<9wE_$Rh{^{;k&k&t!jVdX}gb5*TZf&A&|>gTe~DWM4fT^4-X literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_peak.png b/plugins/Microwave/filter_peak.png new file mode 100644 index 0000000000000000000000000000000000000000..f2981cc7b3d847d6c61db561e7f9e9bb4a71082b GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfV-|KkdF8+l{6IMdh0KtM66gHf+|;}hAeVt5Aiq4d zC^bbPsZzn+FI3+rGq1E_PGIvlpwwzl7sn8d^T`Pk90xKgKSu9=dNltp4-Zd|#H1HY zV$bcZ4GcHGNl!>f`0>B};KLn)&mB`L)p$P7oZ*~!=Kq=hhdB&qp;SHosh{FQoIvN06td zXKoJzGD1w!`v QECzYW)78&qol`;+0DRSeEC2ui literal 0 HcmV?d00001 diff --git a/plugins/Microwave/i1_button.png b/plugins/Microwave/i1_button.png new file mode 100644 index 0000000000000000000000000000000000000000..cb45b61bb1926d5f49dba941667b6b8cc5eac1a6 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^{6MV8!3HGR3O@3Hs3dQ97l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI^m0v(e^VM_lRG^STW=KSdbAE1aYF-JD%fJwjU!Gc& znxc?Yso?Gxs_&DTS6VSAu=yKMD%{h>F~s6@@|5s^|K}al5|S1$^km6hwYg$qU;S;u z!i@_j9X#NWZE}FEH%%-_L{cKdkcI7su>lZVG2b#d?Q<*l^#GHHTO+-^<>&pI^m0v)}q9NRTI#5U zO;JdyRB-nT)%VHFE3KFl*!&GBmFwx^7-Dfcc}jS||ML!N2}uhWda~rM+Az$TZ(Duh z!i|8F2?+~Kr4pLmjJXZFq@=YTzWLQwb}46Feun$Smg{Mnnw309ZwT=SYo2p6pYVcV zcfmucp9}Ba2SI2~dAxnz)|JYD@<);T3K0RZZ@ BSH%DT literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_a.png b/plugins/Microwave/letter_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3066f98ba42a5b627961a6e148cb461796be112a GIT binary patch literal 534 zcmV+x0_pvUP)HeM8yCA03c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0e4A6K~yNujgmo2 zRACf`pZD`l&37lmSqOn(MbxaKHj_Ev!mUCrToiWuA1(b0{exhV+6Qfg6k8~aPT@+# z0?C-rT--a|ne?={O-wV_=v{v2eK?1Q4{|cSoxH0x+cv$Otmn-&_;C0A@iiY_+><1L zZkpcMsE+ORcibRU^cNyYGBX1R3WaE}GXzQMm7W8b^yHsVwQ*9FR57!|*1^FuGdpzB zt^1oNQ|Ce>8tH9$y*qa^HRBZkK@jCbODloo9s_i`ojSnJZd(6+@*|d3f+3Aljd(88 z9Pj+CKmJ&2w(VXco*&vIr>6jR#>;-l%<2G6+58VwS!<079-5h@)>-a{k{{`^nVm^I zsI0X{0Rn(>$uCIq06r-0*P89TkKoHCzW}^&*=a7~Kho>z&ic2BuoQjP)Oor(uKabD9HhD@&JGjGgpr>-b!+zFD^QI)=o1^=fyb9tU5)% Y08Au>)p}Ns82|tP07*qoM6N<$f{ni7lK=n! literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_b.png b/plugins/Microwave/letter_b.png new file mode 100644 index 0000000000000000000000000000000000000000..c4a78ff40439e432b2079f01b6bbbb7e517a48c6 GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^AT~b-8<4#FKaLMbu_bxCyDx`7I;J! zGca%qgD@k*tT_@uLG}_)Usv|WENtR348@Xnf+qqZb`Fm}vZPWn*`|uryXCOH1wIGr4xPMIUdaTiy9w zaIgBj>UDle`-C*k1t$~sYfqlLy6Y+fL!*p~N=HV>gb2fyxb^o+!sL}@iFFz*6*s#fSUT)B{kaN*X8=Ia^aQn@0Y`5p8 zB|`gW?&pnhHkLXQ^WR*G;oj|u^QRftx^A|J@H_1vt9oXhsdt;{n+Xe=@BM!~_ x!;_*DC3c_6NaI^N<@=luaUy%By`M92xqhZaxhdDKo&%sD^>p=fS?83{1OUbCwB-N* literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_c.png b/plugins/Microwave/letter_c.png new file mode 100644 index 0000000000000000000000000000000000000000..af87c79511731a05a2079c4339a9b0dfe3494e29 GIT binary patch literal 471 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!3HERJk;|9Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F$S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pHfP8Eg|6F0ei5cyMio<4i}3`1f)etCA;)wJl&!_NlAU-(S(@pYeALVpsqYzr8WOltWE@_9Uu*t||J41bcdLRIA9T{XE)7O>#F$S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pHUYR8+fOnJ^2x zw7}W~x7e=T&3RnAI=k;5@J|$dt+u1Au+W5SVfWJLmrG`9g+}RQ{@VBag3A@L$+P=* z|GsN4S2T~kNB-Cu#s+?aC?1{<1EcnO1wT@@s$e?e4~o=5@J~vS&Y; zcQxh1wX@o`x2~+wpBc$1)c*5O&C}~F*Ud7cz6b4%pB8kb!(&y!4#i2=K86{W^Q>cN zFnCg@#K0i4YWByY1woASoAZo+1uBYO*pdHT>ADxI$ab+cC*Ce)I&*X9(-*U*hcrw$ z_AY|8!h^-@Yu!u-cZLNOC93LLWqG|zgVm?cJ}IVnM6QvqtG literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_e.png b/plugins/Microwave/letter_e.png new file mode 100644 index 0000000000000000000000000000000000000000..eb34282511c95fcde595edfd9592cabb98cf503f GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRa!3HGFPCVrWQfx`y?k)`fL2$v|<&!~53Opi< z85p>QL70(Y)*K0-AbW|YuPggw7B+DitrcF5TUTMXgz~*m2DK$?Q#}JM4$y;`P`D@S2c;JWwOG2Yz-^)UypcJ96 gB8Gg~_b*ymdKI;Vst0Bm_Ts{jB1 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_f.png b/plugins/Microwave/letter_f.png new file mode 100644 index 0000000000000000000000000000000000000000..7dba71f2fe1186f54ed72cf645628d169daf3e04 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!3HERJk;|9Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F{`A2Fq>|?upLlHAu}YR#5q4VH#M&W$Yo#%$S+SV zN=;Ens#I|I3)T0@%qy*!6WII>C}ra5;uxZFJ~^dm!}q` zrYIy;D!BWF>icBol~&9NZ2rc;z?kFd;uxZFe(I#X-qDF7?ejn1yB*y=L%4tUtrJnm?5ShI>-_BLOgsg&)~t!u5-&pvM7cKKZ7)`hFyF?a;n z$rkLof5Y~O z&UH}|wi&NNJp~V3p84kQf6Mpk4%_crm&EGVKX(dBWo9tEymIon*=zY%Np+tn*&w~w zOPSN5Y=2zIk(uG4tg#ylKYd&idi(dkpD#)ZK6&=%?~>oS&OBA-^EW4^6K}6M_f)DY zy({HhRkbLKd-^0mX@@ LtDnm{r-UW|poh>` literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_h.png b/plugins/Microwave/letter_h.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f54c5d8c55ea6246336951fa3d901b4bd21f67 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mm<1|;p3UCV(KTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1(2s1Lwnj--eWH0gbb!C6dDk&hO@nVwx2B45aW=KSdbAE1aYF-JD%fJwjU!Gc& znxc?Yso?Gxs_&DTS6VSAu=yKM%GlGzF+}5hasm)+*!AV_{;Nyh|Cjv0kYeh?lhW{T sMJKCm%Zud8hPHlgH6KmpG|#D<#qejHuy%#%)>x3yp00i_>zopr0M5=pp#T5? literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_i.png b/plugins/Microwave/letter_i.png new file mode 100644 index 0000000000000000000000000000000000000000..037d03d5e29048b39202c01e58c654ccc7666eca GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!3HERJk;|9Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F{>oMk*E>NVn3jeLS{%riF1B#Zfaf$kjuajkYAo! zl$xTDRH@+Z7pm`*nO9mdC$RY&P)gC$#W6(Vd~(78rZsxC|MN><{;tm{^5Icw3glfZ b#pc7zaCFdh=n1xMTR#C0_vpP^nAu}YR#5q4VH#M&W$Yo#%$S+SV zN=;Ens#I|I3)T0@%qy*!6WII>D3$B!;us=vIXT6FDQx<_|LF-pkaU2lZO(#k|H5r} zfZ+eX|NptfpFB*yo(Pgm`SHJ_Q?W#J^Us~JYD@<);T3K0RULwUyuL* literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_k.png b/plugins/Microwave/letter_k.png new file mode 100644 index 0000000000000000000000000000000000000000..9f5a7d330e766bbe2a4bd2a9d063efbc7c84c3ab GIT binary patch literal 461 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mm<1|;p3UCV(KTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1(2s1Lwnj--eWH0gbb!C6d!X_@O6JgXp3n-+J84^+AoS&PUnpXnkGB5<>m!}q` zrYIy;D!BWF>icBol~&9NZ2rc;z^Lcx;uxZFzIW1IFXlplBkAAQ8GYCLC}sOuK}?M8 z&jAt7M4d|-EGhz1I+k>}ItcnKZC&tw!hh4EWgk3?JWH*`qYcP@%QZi}`P!G?#JRYHzF(9Q63NM!@c-+t8$GrR0aMGS@T^{~uprL-dWHU^ znxBk&!=~_LpH^h3xOeu~yX^BB`TG-!KfSy^!Dey}PyW9!P^fyk`njxgN@xNA{4ux9 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_l.png b/plugins/Microwave/letter_l.png new file mode 100644 index 0000000000000000000000000000000000000000..f2850e5fbd9566e4b5f9118ae23a17e27539fbd6 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRa!3HGFPCVrWQfx`y?k)`fL2$v|<&!~53Opi< z85p>QL70(Y)*K0-AbW|YuPggw7B+ENQ=3TjD4>u+W=KSdbAE1aYF-JD%fJwjU!Gc& znxc?Yso?Gxs_&DTS6VSAu=yKMO4-xJF+}5h@`hbs{_elJ^!x4W#iaPW1 zRTWzQy5+7v->>-g`$ajUiSsYY^8Y)LdSyE6gjR2!o{1YT=wB{xK7aQ@JSf^2JYD@< J);T3K0RZN*xnTeR literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_n.png b/plugins/Microwave/letter_n.png new file mode 100644 index 0000000000000000000000000000000000000000..4950ae554939c84e8531dded1a67aab593bfe593 GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^+(69F!3HFaY)uV-6kC$Fy9>jA5L~c#`DCC7XMsm# zF;Jy22s1Lwnj--eWH0gbb!C6d!X_@q<5Bo$B2Y*nGbEzKIX^cyHLnE7Wnc)%FHbE> zO;JdyRB-nT)%VHFE3KFl*!&GB_1n|MF+}5h>$#2k%!v%FAHLh!+6g@>+FCj(V(E&I zmihzo31+vCs7>@*BIK<;`(nn{=-C%Sd}MW|Nm*R-im5*L-N)RZ=KHqqpQPo?<%Jm= zmi#dF6q|3hNb#SlxthF(+r+KyACCOdd~)zs?*5pLr+0Wy-c*=luXSYRrDRW~jr;HP zX~)%U7qau%p=N1noGaZrfB)t+iZ9zA#BH^W`1Hsxcb)pnu9TCv9$e{WOn7ri*i*Cf z?$>wjSG#wwerUYJd(s?($-eq*4JN;{yu5hM`u(lj@$~52TZg)t^%xGYEHws79enXO w=92o!w@!CfhbLKX<+6WXDcv76>CvA5OfFLC3UU3GS3p7J>FVdQ&MBb@0QX#>oB#j- literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_o.png b/plugins/Microwave/letter_o.png new file mode 100644 index 0000000000000000000000000000000000000000..d0be1e0c4751f747054817e40669b629be50cc74 GIT binary patch literal 598 zcmV-c0;&CpP)x1-evF2z22G=t5B32#Sgz=%&zW|A77hDP5=4 zv~dvxiJ%bOm6C6Bn|H>AH>l8X&+5ROhk=}upk*bqSdiB?~a>4px8;jM>RVVI^nT6ec|D?Ey$z_sB zGkZG@0)VYtu&!qBNG6Y_CYOcA^8lcxtB8>fM;V?I5E%gI^!7i-fxgwML>J8nfHVNq z-q%}kVCBotW@KjsKpOzE7c$dvVE)wHOk|q^LmdEu)NDQuOw3L%ME0ww*#-cJNGT2! z{>d0@Lxz5^VrB;W@aZCVg*n znRM34krK!fNvitWe(LdmB?o}T?RM5BQL70(Y)*K0-AbW|YuPggw7B+D?S*3$_l7T`BnIRD+&iT2ysd*(pE(1eAetBw9 zYKlTqrGmR(sJ>5TUTMXgz~*m2sePUx|O)Dkos5q=lA3FlEOX@X2_{OHnjCSmYyG9@bB-}+u!c*ufHxKIrGO% ziwLQi7fS65LjDw9YI)Cbc)qS2Wi{rJ j6Pg*OcUs8W-4JDDNQw(gZD8=R0r}F?)z4*}Q$iB}(O8Kh literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_q.png b/plugins/Microwave/letter_q.png new file mode 100644 index 0000000000000000000000000000000000000000..21eaca52b4c228f7a1f14d8459d0a07f987d5b86 GIT binary patch literal 609 zcmV-n0-pVeP)%SB=reu*`g>YD1sn@HZ3f06D?XqX!!+d9}%>R z%uEqxk<6k(+k}Yos`K)@ZDy!oY|iQ|&co$i&J}-YY`J(m5!)@HvkpT7Ic&)NeWMnh zE={C!?X247^lIszWRE08bdb9TcYpA4wD%!^0c2Myx6Ptiz(NQwYJ0Wp&Q>w~?fZ6b zy;++G9_9g=+02=h(p>V}C^T9bF>QzpK&i6*xf|Fl6qZ{TJz_u_ zAon(3=msvY|J-TWegldCBj+>y-N5lc&_4#?@YRC* zI{-7g_8(|!a;^Hq)Xw-D3-#S+?p~L4F}qs2)PbD>4gFO^aDQOqj)IYWQQaqu^ vZi1!-Ly`^#_x1L79O#L!0#hGOrpA5)L&UjA5L~c#`DCC7XMsm# zF;Jy22s1Lwnj--eWH0gbb!C6d!X~aDn6;_f6ey&S84^+AoS&PUnpXnkGB5<>m!}q` zrYIy;D!BWF>icBol~&9NZ2rc;z^Lo#;uxZFzBSO++bL0^_FVPZNhSpsrgg={=y|!Q zeifF=DbC=WCGAyEp84u=yNDle(CJ>bKp`&84X(3)D{1&H{XMTu=uzCeuRi>94p;I$ zPgwiW^(XtJZ5?|8A~xsNmh6?-DOKbp!;ru*BP`%%Lt@0t+2?k7$9T2}08!?)W9)z5 zi>y4)sKF{?J6AQG@73vvyYIP||NcI8$)2Np0Z)o6*kj(DtS!(qoG!z?%2`k_;FR9R z&7y*WYb$@=tG_KR+5BYlwW{qiXI6gAS$zAYs!1f1KyaIt@!I7ZmVbVm^=0F)3-?q? zof$U=Up%>|zGsf*g_MW+OXpUuwtYBz=Qe?T3X$vr-R_U0m8;d>G7Ac_K3N(OvhUHW xx}7eYmNq;&?&508q0627!OOvcC6brp4eRZehstSMx z0Q;FvAp|AB1ps*UjcdL853zD06DJ>|+L%3(Mno(Gr$X`JB>D7G+)hn2yaNCMpwE9# zn21>-I6>0h@qb3M!x6+)Ua12B{fGB_*fIETgWWLku*8?rDzr}=>fgmh}fdBvi07*qoM6N<$ Ef~DovHvj+t literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_t.png b/plugins/Microwave/letter_t.png new file mode 100644 index 0000000000000000000000000000000000000000..dc0774311e594c7ebe0fe45c0c136dad4ca8c76a GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!3HERJk;|9Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F$$wi(`n!`Q$CTzWlXk=4|L}lsfS0()a&6a@20N e1@bPIDqvtx%i&b|!0+7+GRo7{&t;ucLK6T$YB&=B literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_u.png b/plugins/Microwave/letter_u.png new file mode 100644 index 0000000000000000000000000000000000000000..a2ff33a85e52af23a73b8903c690424097863bf1 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^+(69F!3HFaY)uV-6kC$Fy9>jA5L~c#`DCC7XMsm# zF;Jy22s1Lwnj--eWH0gbb!C6d!X~bub$e%$AW%plGbEzKIX^cyHLnE7Wnc)%FHbE> zO;JdyRB-nT)%VHFE3KFl*!&GBb;i@hF+}71+e;h$4kbvmKK%YWI%r8}-Z2L4Y+0U* z7AIak5;fRS&EC?u;fv6Xy={6MEHi}{tL^1@a->utZxXlwJCc^{ud`V~Df^Ade< z)ml(0Nb<1!r~dxqt7b8lG?y;tt5|)5HQ?$M21AGaWpW7My^*&n#v%u+|*Bg3+ zzb@pl-@bTS?*0|8{JiJ>{gZb7qEXl0>i3HtZ;?NGBF1Hn()sr+4}NKX)IIGpt8Hr3 zuZK&mZEfB@Q?3-4tv*4qfGx-2{?-J+xSfm#~^aSK*Pgg&ebxsLQ0EOj_ A@c;k- literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_v.png b/plugins/Microwave/letter_v.png new file mode 100644 index 0000000000000000000000000000000000000000..11d67a698ed2eeb2d735086c8f5d4cb52909255a GIT binary patch literal 544 zcmV+*0^j|KP)CJ0jK!wXX})fTfq;bBHzDv6FOnLSrR=2-GBHv$?bD)1cGy z`E^Mdpw?K)9|i!&SOy5v)D{2ugE@d^JE_=CfYQ|u&2z&*q24?%xMe$Owv);LIw&o+ z3{^?WDziBZ&CO*tCCTR5L20oyfO^rrUqp;R3cY)D|9u#GQ{8=G`$q`j^76Z*YXCRi zA1zDalI@?n)!pY45ZkM%9UlRln$2thg#Ky!G25%@Bm|uJq}(V;|0`kx(F>zr6(YOE~ z0S08|_Hog79)#X>S9N{WRdrhPAKLptn$5f2>iWaV9>BuKGdspN7XO06%4%&w0COA1 z)zR^hPqz1iAOj$TI+xcxk%eJLX)H7VY~BXj8Gulu7ZB}l3Slw?P22w7^GjL+FwR1L z5etw$h-sw_T%3#50O;f~3!6_Wd$xZm==R*k(QHAs(hC4I0q(E;z9Z>Yv=6r*RlbCj zvsF2m{KS$+C4PXYptI%lI}+Pbo2H0P9Nmu zI9TYE%n+SHOAP82RZ2kdT#Dcd$&_NXJ zWH%A2(0nyD4S4HVQN#V?zRr@MSjG5aruU09F8x~lnzyPyC`{#!UOEc^-Qk`|lD(=r=cgif0DxQKm#U+# z$W2xKW{nwhT=%i6{tjyOJ;lM;G5|Qu!sqRw(vJRp$3$c&$&)0hs`-VzT{8`aZ67IZ z92CcW4gjk5&3xhg07f%GV=t{jy>2&E)dBz%E6s4baI5HfA@?px0RW1OWJ{I9{}poC z-Iqy8s_I8;&2<0};UrEya@sm%Uaj|gA-7C2Y>XYL{H)H!dZNoD`;4*Y{d8oyIe}it zy-hM~RUi84$n4ug+bYJ`D}Ph+$rmf#|Ae8X>N%48RdscGZl^;s(n0EJB4hvETA d*Ylife*k>l#i4iOLmmJC002ovPDHLkV1i3n7is_i literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_y.png b/plugins/Microwave/letter_y.png new file mode 100644 index 0000000000000000000000000000000000000000..ae50e777bc94a5d659d1414f81a3ac7c4a3cd6c5 GIT binary patch literal 444 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!3HERJk;|9Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F$S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pHQIUD+?vAu_RcjqfDq zq-NEN{u&EE$X|I9x8LF5)usLNisyJQD$Eu0ZC8;hTDj5jbA(*&{5FdPiY~?1%Ra}5 z^KXB@*Qix8GIP;XvZ#@xteST-y8~> z_@pap?XJ!bmJ9`NzV4C;W*6A>uOOUL>iAB^2lagJoww4Kurdg-l%G7&9Hl#9Ny{AX z#}?u$D=*Y2__HuPu-p21)izfnH=|`)(eILX8@%&jIdP2rn!GIg{XE)7O>#F$S|xv6<2KrRDAKz?~@ zQEG}pQl)~sU#PxMW?pHdZ?LOBV3`Wny(? z3Qcw?C@2noy<+j?*|C4w9z9yu-Ocq#i-S*TTA0(TC3<>%p&Oio7jJp_U&h5Tb5-T* z-?GPdSI^j2xp;|$F0aog&U(i_E|tS&>Tx?}OL9$qbgV`GoYby5wgUlLaaz{Q p$N!#c3GaTz;P&rtO=g1NM1I4gg(|`RRbrr^^mO%eS?83{1OOj6v0wlI literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letters.png b/plugins/Microwave/letters.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a2301666a2ed174004ecb0759cc79782925ae4 GIT binary patch literal 9102 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/manual_active.png b/plugins/Microwave/manual_active.png new file mode 100644 index 0000000000000000000000000000000000000000..109bddef15badeb9c5de6725b1f9ec70aaad9a13 GIT binary patch literal 1078 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/matrixForeground.png b/plugins/Microwave/matrixForeground.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5bfde298d9b57bfbd56f55a93e7f5d87a81170 GIT binary patch literal 2684 zcmb_ec~sKd7RJghBamWP6G*i*&syTr@M0*>dAR|DQqomb@!g3q#b-`l|Q3xGCyUs#~7AoVS1PkYY?e4Y;&@>E9B;naI=`2A-sjSj@B9~QFJUM@()v?l6 z3|TnInY4fWC?_^{YeKq)3DG`q?pYmwC`OJ4#SS+i*^y^(wu*UYa%Ovb{R#T7BC2y$ z_!XtQ>n3{M)?!M{JAfchFrDb=lxHQ7u zA@4&IrDkx>IA*7ue)S5^6wL1(j{`ia%l*!xg?u3dUe3Jb#)axxC)R91wFdI9wQw_Q^SzJVN1rnO~gmQb!hD)374SPkr?#96aq+u4D>3pjTp0tIH}Q zt1_6*6wGpRacmJN>#22wUvbIUmutIq*?zk5uq1g{3R^HS|{Nofi;#O9p!D+RS z#cMdhauxH<=xS1FFgc3@A6LSBUQmZz{T67zi=!M$X^kf^F5++>48jt{Crw%fN3m2j zxtNY>5U&?Kg7Wg79H=Bd&v<7FzB+X&y|3cwy9tvi31jWW4p(Ag05ey><3d&M69^@_ zITN4jWnc98J9v6hL3}6#@}jP;j=q3hLch)_rt)ZLbkqU23V@B6zV0;;NwXlt&0gN`Xl zGh}~r-GpNIho;?XJU4%MhA67O(1Dm z5+R;*9_js+b|^|j&*aUcY$~T^cJ`*pOPGb-+ZDcY6(*ml3o?bZ&}g)s(VFQ`+Mf)2 zHowCw6#v1T>`gRQkZHY=<7Yg@tgge>IGU@ugFz2Xh&qC5XDaOb9ZLDxVERpONl2O%D+D&dy+S6lfug=%&!R5e3h47cx^;u(e8UB-QQPx5I7yFT}5?%JnH(dWY^p+Lwod zg2NXN!RqEO+(S!p7+{aiV^sZywr1=oI&^tinY(%xjN@n_SSu|#e5;wk;uWBp&g=F* z9n>e@_?wav)W>R$y{&cT{aS%bKi<{#V%avCij#^42_0gZx7*ssqa=6e8I1$BDKvOC zz9cYGg-g-^_WmWM%B+lR)bqSoC_v19e)~mTjD!wmM*iNr$;Pft#g9@_u%lkF!g)jT zxgXkBp3rzn6fpwodx&;W;ukWb z2I0yEj95C4lN#E;rw7Dwjf7gbe$Dv<9m_z=9>bSl&_d1d!d$%Uq8RD{C0I9W^AQZ- zw(Jf)fU$(A;$>;-*tprs$rn-QVh{*40U^HZGcGR9sKT0Gx#D@rGRh=a#9n{0L;<1% zKjSwLkwmIan;UydvtdhCP^xl6mi`anKTy|GZ6LA35JZE;|4H`G`+AF+L#w7eJs}b5 zZZ(Q?>lD4JKT`iJF%$p!Z%DN6mZ;mmYQepw_Mw~hPyHWHy?N6L_vp00sqyESKKNR#c@Xwre@xQBp4m_@GixDg2O3SW3 zUo9#F27~E|<_@ekWVI`qXpclH!Ii;aI}h7kaonit{QP{IuHoOSg2obwvOuJzrHlyG zS5{T+KFgb$n8Ss@BrGz`-8x0rsJx?7rf_Jl!q8qObSE8E`YcL6&dtT;t@oxwRX?V6 z-GjeuP6TFc4g@AHbefp>6>S~LJ)?pI<5@C+LBh=wRZ#qOo*iBEp9p}%tV~OcFGv3e Dh;8ti literal 0 HcmV?d00001 diff --git a/plugins/Microwave/moog.png b/plugins/Microwave/moog.png new file mode 100644 index 0000000000000000000000000000000000000000..f206bd0da044290a77383c72779c5c414d340b26 GIT binary patch literal 498 zcmVpP^PU6$`RsJX4)30IxMk)iSo}_+Rp#>oM>FLm6{cI| zEt|tfcU>5gUc+0$&)w}Qg&r^1RXda}Mu6x~`*3YmztzxHss9NMW{N8!I;Q9iIKPKO zXAc3(ND@HaH1;QLwW=wQPE_`Dk-)*PVLMZr6!&dUAW?-IgKdX)OSb-TwtSF*0)jqY*$<>f`z1&c8z9qs2?r=R~#` z*NCM-T32K4yF1waY^tVf`179MAj!ueY|%_Jre!E6y=yU5|7!JAvIwJ&Yi zPv_S`9MW%Q*WxdV^#C2CvquH4Bi0Cj*f#)ty)4SE@|$P{(l$~|i_i_=MS~uIk_2}E z)bv0oOQ!)Wa2>1fJp46?M67>Jlk~J@KORz*G=NpYdFMY&p5Q9|$mN-D3-n8YM-ST3~V zMKzfz91*i5CWVPq(|}Wduu8#GOukn9>r!Dn)wDmC+Utu-uH5W89ZR*mcVfL*&sp~4`6~#bT&^`1}v}zfB=p9025uYC+j9q85B5{JKda5WM+PrdoYVg zrN=8;TJYG0V$n^>&UE002ovPDHLkV1i(}F8Tlf literal 0 HcmV?d00001 diff --git a/plugins/Microwave/noisewave.png b/plugins/Microwave/noisewave.png new file mode 100644 index 0000000000000000000000000000000000000000..f212eb0bdfb877c5b01427a7f8dd08ef0e42bcbc GIT binary patch literal 512 zcmV+b0{{JqP)m-;o$pVhCsgBU1BV=y7K2sryz}-CMUy z{rUS({MnQ-L64$9z8j(PS)8N?FXCI%wV^j$_g^{qa~S z#V`y6L4fPJ7Sr!?q9|guTA`G}_kGK*lw!SJ<9VJX(eJXNC?bwywAL77*zI;!Vw$Fe zVQ3raF`>0)u~^_Z4oQ+=jA6UoA|kl1OB~0RQABV?7mYErZOildBu!H$lL<;G7K;VG z?=zW9n9t`{fdeoM1Iy)-%jH7Xb!1saRaIOr7qTp4I-OEg)&Db&#$2yg4u=C_81i^L zD2js3Wlq_(Ju*Qk+-A^{Dyl2mPMZhW*6cmCm2g`Q$^2+*h?S_wEJk+f}Q7rAVW9JY;AcWYw=(=V6;23~6`91c_p2jLcfNk&S`T?WMyQ8B! zhGLOMy{@q!@NuNnno~ju4HgOoOw*)R|H#`?iAJLaz^iSW!@~n?X=|NE;^O-cK8wW_ z(K4b^3D~kM(rE+FJ3u-PmSvH191sLDK%qi-I#u_&+z*tv)PR4 zWXi=wpPb{6&1N|}3z5>kUp3L#YPIwlU)mielPSM`FBlBI5k(Q>@enB`aU9>7^VDN^ z+F!Z4z6Kx+yR23#0GiF_y{qg0Gl}8wQs?3MIYNm?!;NTpi bw7lg%#a^u@nSRNy00000NkvXXu0mjf%Ps;s literal 0 HcmV?d00001 diff --git a/plugins/Microwave/none.png b/plugins/Microwave/none.png new file mode 100644 index 0000000000000000000000000000000000000000..f933a268f61ba4829016d8694a07ae5e4e1ac0bb GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mm<1|;p3UCV(KTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1(2s1Lwnj--eWH0gbb!C6V!^JOTD4(n~11Kb$84^+AoS&PUnpXnkGB7w7r6!i7 zrYMwWmSiZnd-?{X=%um)#Z5e2978nDCvVyHZ+>IQfg=uV5?4)JOk^*oq*!d5)c8=J s`wE8}TigGhAEt(Un^V5bZ){{_Si{6Q|Hz&TXFvvfy85}Sb4q9e001>R&;S4c literal 0 HcmV?d00001 diff --git a/plugins/Microwave/normalize_button.png b/plugins/Microwave/normalize_button.png new file mode 100644 index 0000000000000000000000000000000000000000..3f8a3cb5b24e161720ef8c08c14a6638e150b89e GIT binary patch literal 959 zcmV;w13>(VP)8jw>*(mf@Au<&yT5gli;Ig`tyWb>Mn+g! zSs@yY3fMB5ebG5ZNT<^T0s)4HhlL=A!@=9z8?&>s+~41GcXx*@%T!iYQd(M?14@!4 zo}ZruTO<;}>2w0n($YdW92Wd$vzhnzcNP{FsIIOiFE8((sO@k#a5|lgjg9^Lo3OdL zNl{S|wY9aX&15ohets^*eSCayb#;ZwWCB2^(-DuyIXF1LX0r(_0SJXcG&eV6G#W{# z(77M+-y$lTvkxr*odj?xZJsyvc_vf?4rlzKl zWtokQ4FD2}1m)%BIW1CBQbHn;P$^ecRfWM|AP@*pS68Rz1L~oBdU|qLpw((=Yiko) zXm@v)P$=}D3s78K%*4b5{r&wsJv|A&47P7ghgdAe_4PF_mkWSsG>T5A!{_r+SXiiT zczk@!<>jT2n@lE=WtqXjK{Oh1`EWQ)Q&SU>NJOyL*VnVPwI%c|kW=`tM6cHq2n3L2 zncLgj|8GQ2Pft@(QK3@b>-A!>ScpU-ghC+{MPXoI;M3f*voj744{2|2&uNL8ni^hS zUUFI?n>7II>+5uOc794{pU)@6c6D`Ox7%4;TNC2G$`1yE;v4qUe~hVA>i4ts`(wp<~ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/normalize_button_active.png b/plugins/Microwave/normalize_button_active.png new file mode 100644 index 0000000000000000000000000000000000000000..011d5d13dc655038b5be15376c6a63c60e808fc0 GIT binary patch literal 982 zcmV;{11bE8P)yF$FUYRE5JJRIBkXb&A?Sro{R4ucpvxIV zF$jWg@}eM&er!`pF*ln|x3RfR&*>sP?rjPg-MI&zo9D;-Jn#4YKIeUp1fVF2#txN8 zBqEsR%J z`dD2XqxIZSFi7~r2d1AqAzxc7_#y)X`nqa)IpO#3nZ18sXeQa*Oz87xvMv{eeTB!z zH{tMxJ>J@?*Dus`W24a9x<>Eb-I@tfDn-WaCRblC7Bm|9@!$dG$w}(ZoT2XGMUW&S z!^0c7*(^s~E)Kcf$X~y*(B8gLB#|KJbfQ*N0Fd%{kVB!OjV)cdf^A@crIwa$o#dWJ zk2vCT>1w}qi^``@*)=vM^rrg@4!RfwRb`*gN36G32ue3KA?0$|hK4XME@FzssPTHq z9y>>@ zJk;E|^Y7mT%d1zcR#%fbc~ZBnI2@EsOo;njS;0ItMc(1~%@$cE6bv%)@go_xo4o}r z0kHc0B+j2FuP8{WiYXcu{E3zpsvkc_(lo5ko{>6xcH01ColX`yJ5g@lL{ilaCa?9j zuJP7ZA=@o~)4 z(PbdNfXuz<%Tr>)n0@eUnUc6xG>eWr@9P8;3V&m7Yk!fsX z>iKgaZgGqJ*^v>EDLehem`o;1kEPO!aeW+0e~}UC7s<|dT)G#2w*UYD07*qoM6N<$ Ef?T7{djJ3c literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_0.png b/plugins/Microwave/number_0.png new file mode 100644 index 0000000000000000000000000000000000000000..0489093e7fd90d15286408199378b0e4dffb9279 GIT binary patch literal 523 zcmV+m0`&cfP)`)-<0=2VtO)l}q6A<@)68!NuQT6B7>&g>Cs&iC zNoZ!~&A$nXnXhrOD+KKsC$}d_=B?Tfd-;CY%bT~VBssKO2--8TtIG$MTPsJQEgxRh zqip%`s=jg*TKVA5yV%WgS_QcA{&N(X`7Z!+R*9F<5`g`?X-47SyG*ZQW#BnL_jK5e z!n4+}Gyc`tBzYR3eY`)4!inrjl6(y?zw|a8g%eqrB%cG!EoA4S@Wo>GC4j+2tZdjZ zfTmKVD13C6*{}G`X5Rr)&TZbSpWFt3c{O6|S^Ck*Kh8aENy?hH>R{C00eF_qy_eGm z^Zxf>G*~<-&-aqLy`FNZ+WnF|+-*%>m6Q7f{C|7Xo8JzKnMTr8-2#WWlRt&%?yLX+ N002ovPDHLkV1lxo=cE7t literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_1.png b/plugins/Microwave/number_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ffa7eb0c63a13f11673f971442b6cdea5908d05c GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^{2~MxO&;{@?%K{{P?q=pXOj-#?NcU$0>lz_doM_J4lq%ir~j ta+V!g6nIwI*;rX8^kHy|_T+#RV}`I5GA~^u7B2xg#naW#Wt~$(69B;QT$}&^ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_2.png b/plugins/Microwave/number_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6aea975bf79f803b7bbf7e2e9c5903dffb5077ab GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^{2 zl&PcZv*e-ujY#bfwOf+)t!t;=lIjU~x&FWYE; z%-7njqQYwCtNuI_i)ytU9kPOgnrrM&TyH;JbzHQdb;|#taD0e0sw#; Bw#Wbg literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_3.png b/plugins/Microwave/number_3.png new file mode 100644 index 0000000000000000000000000000000000000000..c1057511fa5deb80179e2e141d11328eefe98530 GIT binary patch literal 519 zcmV+i0{H!jP)L53Jz8%A|6?scZY zL@b!n$jl@{RX2>KxYvf7$20a@_}h*Gs7MG z8MP@&hKRK2w4$`_Yz7N1YK^jBcBd8IJh%9tN)vXu|D>_^u^B8iADY7>qAU_^#XPpd z&O85Whykq6#nt(a;E21AMJ{62s;-S8(l!8ixMY3sCCV$%t$gwFS}>(iAX$0tc5KMz zO81R&vTNAovMUAh1T;>~$@trygXI=m8#*^KC zri-CmXt>fcwjp#sA|4Up8xd(lWDwFf5?-MY;ppZ5YC8}B;19a(tixjmA5Z`Q002ov JPDHLkV1mG|+c*FK literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_4.png b/plugins/Microwave/number_4.png new file mode 100644 index 0000000000000000000000000000000000000000..0564ce16e78ff04905f0faf273727a34125fe749 GIT binary patch literal 389 zcmeAS@N?(olHy`uVBq!ia0vp^{2Y1mDV~EE2BFR;$dNEOWRyLUq@0>a`V6c|HIv9Jqr!LIb+6*=LQA_F*X-> z+Jd3Ye^|dYySNI|Nly`8&kSO2ZO*_US1!c zGiQn=BqZYY|NpdhR-?y(LqK~I1Ouj>J#ixA=lApTC(JfmG{5uenUtDmb7hp3op1lI z|G#aH$)niQ4onG&sj2h-&2Mb{_;E^ZmYfT{})~@VY}4O@B&vv?5}_F^G|DR cnyGY_VON{exANkKrJ&I8boFyt=akR{0FpSL8vpaYIpx|bP&`znlSm8+gcS% z#|;~J%9{Q=cpnVAa7#WxJ0knQp>uw!5gG3e9CGt$5tt&vUS9p^?YYgJbER$0gfJg| zTx-b1(4?VkQ@lSUXy5E(_Gxd{>nNwo&3%)lovXQ2jPZ*{%%1uhx&3+Pj@fOHnzpT@ zW$t#17uTNmgl`L2mosmD`R~0!Nj^6%xBFkpSUX+(lrekj-w^rBdlgPaa9>_gkZ>}* z$g&_zlV@3&{oKt46;(x9)f@IztX|dn%x#XfZ%*0oKUZF^Ul;Q1>yaOQOni(DQ;PFL z56^SbxPJE7VX;25H|sYQPha18Lb5e?(zGcv4q0n&x}7uUO05IK4>peVHIvtc2$_Ha N%+uA+Wt~$(69DcvsJ8$B literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_6.png b/plugins/Microwave/number_6.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d533c5a191bfef99f4a274978665aebab11942 GIT binary patch literal 589 zcmV-T0LMzR7QtT# zwkeI`;-U^>CB(KbFL_a4-aQUYLEx8<<11Uap~1{k5y`uP-kkEq^=<%$1~Q8xlDDeW#3omxAK&}xn?W{?lWA3b z!9K{?Ms2doOTSiC8~=_cO5?dz{u7fHZ>Fsu9wc$MZQ%@nTKkv-A`|6CAjb40t=36I zE*N9xfMdWnRr@5~uH9OnI$Cunzl#zPG1l69#+VzO0ao>MRIe4^Padhbru}PoXENPN z;!9yr=?{ZSf6K;~RrRY889sEl`=+aM3aA0TYI1FLwCDL>-lP0_7^KpvXCiVDm~~bD z1Q6~tOPyxW{JGYagU)HI+BJagUVp69%=ww|w%l~Ktx2+s@#e*NONEWbd{nQ#1n{$c z=RM;s?A^e=w_PkZ?zUI-532S^F>oW#(9pN<4rSJvx!FCwk{&;pE bbbb5>ayO`C;lmZy00000NkvXXu0mjfG~EP{ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_7.png b/plugins/Microwave/number_7.png new file mode 100644 index 0000000000000000000000000000000000000000..0f5e7d9f9d922ae7fd6cb224644dbab1f5b2b54d GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^{2a(YdV~EE2sh2i-J2}d*e|Z0W%5=V~0{NWkgy{yT1WfZMZdV~=&51y6JKq{fzm zE9Ct4Y+$_2kg!nWZ;$fUgDNbQdYOjacKLe>HtfExGLyOFe@V=&s>I}L%BPq0zd3UC z;TDz$K0%-6sceti5pg4PqDsrX;>QWkT6xb_rRXgFUw2Q;PO3K4vd$@?2>_2ypu+$F literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_8.png b/plugins/Microwave/number_8.png new file mode 100644 index 0000000000000000000000000000000000000000..c95f0f985f14459376e10dcf6fd18747625b49d9 GIT binary patch literal 613 zcmV-r0-F7aP)gb$jvfdl-V1y1zu*-Xxhd9T1T)`ITI(FXp#KH3i%DNM;8jZ;~`!{vL$6RvhP( zG`%1qb&^?o%Jz(ttGjWRDK04XM8g71^)}do~dm0 zMebYVTE?AzQf>ry{7$b4068~PvXp)>^u21t27vNTcv&mnCDplqmo<1RGPw78{?JoX zv-)#`Ix1jsoR&oqU7X}bRd=K7TGJyCr~PE5?Y9bTzg0;4$qIp3YkEt~=$g?pfSUjy zgZ|a6Qtrh8ZN0M7-lw*nE8-S_M+R)31%UQ`r#>qFt?|qx&prUSd1ql%oXI)mVd|T) z1sfo)SV}*xG@={bp!KqEDLUENWv%qX;p#SwPqk40abn8O)JPti@VCFFy-sDjeB|>O zcH?~EQxpaz5%C5h??j|0BE4bmMPX1fH3GnI_}jxq=jhCS00000NkvXXu0mjf!&(oH literal 0 HcmV?d00001 diff --git a/plugins/Microwave/number_9.png b/plugins/Microwave/number_9.png new file mode 100644 index 0000000000000000000000000000000000000000..4ba0a5b08f2431a21e2f42207a94d208d9fc9dc1 GIT binary patch literal 594 zcmV-Y0Qf?ogt03c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0kcU&K~yNum6AVb zQ(+Xv&%G~^r17;T8qh&h9E5_zKW!5Qkq){EwvGx8ildW4p^KA_qR_=nM?sv#NfE84 z#?&TmE^2E*NIUp^uSqcZ?s3VW>5I@aUHEAAVR32WdNW#o4FKuw+0&kS_W*#vNNn53 zt806b$;^8d+1n3k_CQpxk#yz4P-0W;#j*U4s1=UWY>vidk{y!Y9No?CZ@b^SCc;)# ztVNejeroYVeWM;<*ncGGeIxO1OXgBFD2m`b0GPQ)@k;`rRBOH@?auerUvE>XR5G96 zb`GLFdh=n1z>t%`#}?Bzd5aLS{%riF1B#Zfaf$kjuajkYAo! zl$xTDRH@+Z7pm`*nO9mdC$RY&0|TRsr;B5V#`&Y?>^+zgWsZG(|9hTUYIdXE*<9D_ zj)EzNc^xNT2{UnxHVKQiaEms%m6cq7K+%U^$-pUUQK03N7BfZD_kXuu`8Ut|{5Kx? zABXnmZo70t;_9mu1 z=B)fk_mCwmvE~`EQOOOrvVPrinb?0J^w6~E+}OzEhA6Y*{I*BTvaFWdFYTLIJ#C5T zKi!Hq*0u5(8mifT+he14{GPMn5X0A_FMnMRsA(}@8aeUG0+Zs~GdCS#Sby`&?w6hY iC%T0`9t&<3I>2w`k#~xF+qZU57<#(;xvX>Kf#02YbR}<$xoO&d+GYJA}{rA27qan}k1^~9+yPMZ8T}WCUqcHj# zq@^|?ur}63w;43PQnb{lrKoP&AIX@ah>M2g*6zoP$7aa_R3l#O$KuE}JHzV5;&z?9LWSVY=%y!9h`6mePlMK;EASnVE9(tc-^m^v} sp`wUY)tnGz2Xul0DmzuxoU|YQ6K6}K8trh0u>b%707*qoM6N<$f+@G?d;kCd literal 0 HcmV?d00001 diff --git a/plugins/Microwave/remove_dc_offset_button_disabled.png b/plugins/Microwave/remove_dc_offset_button_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..b78792d90a0493416ee02278393695e237638ca7 GIT binary patch literal 1336 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

6+beFTQ+BPvC_e&4mI^- zv>??WeWODZ#DZgo4k9r|$# z=jH$~dvB)I#@Uf-8tedc*TxN;n=>#oz92Gz%iNhGY#2lq|_p!)b#rSKLYu&w(5B62zv_V{A=y#7aAu8h4ibX!Dk5EtRC4E3 zew9|rhZo`(e8-vq1Tq%aPu9bG7!RfvTh|=GN_q6dKP_ck1e@!D1K~iFj{oYC{}GWL_4#}|6<$75tf5-Nqyz4fi0o6Wzp=8_llFDr zOHHrePhI|e>J8xfi-Swy!r=n$RRE+NDbyO%rCNDo?yWb5F+rVQVU)vhN>=8haCK{E(V2afYJeZyU z$gTSB*3fN0l(PUdo>f``G-pJ6F{t!r7V+o2>ou{99#xyOkLRyu!|}7 zE*tTbbf}eo@3e@wmElbh{37MC04d&VzhvKAjsDDg_w1Y`47f*D z1aMi~;~@Lm+Q(tuC*oK3OVsa@6#x{sPxeSJ0W1mY{ENx@mr?$Ma((|H=bR<}0-%(L UDvD>tcK`qY07*qoM6N<$g6{q6o$y`wv7L3kyp@*p(c3hv#gHn{RJBs9(Ew0;xWk+~{YEJ&ap$6b zzfZ5%17NXOuwJhb5hC`7i7SV8yG^IlVLF}SoMSi~ve|6N@}lwsW35F*=ytoz=X26D zC4|6syQSG|UVYuDDymA7BzW&n0eSDS)?OEu@lPfbilR8Bx!><`&Rs0OzrB8mL^0PK z(=?^gXq@KcvCeL{yS!M14<>&pI^Rgz!Dtmk+7YoL%qW=KSdbAE1aYF-JD%fJwjU!Gc& znxc?Yso?Gxs_&DTS6VSAu=yJU1Ea2|i(`n!`Kgl@<}o=6wC%UdI4#xW&M+@Hw~DFx zaKi)H3m>Fx4shOMDE(ISNUmYQgcg=^PQ?|)0!5oedD*8ponBvN^!el4aUx_)}guEwzK=_u+~9lIN@DzO_F$6%?qRu6{1-oD!M<>&pI^QAWUu|I+NFW(EdEVNVyw5RLP5CvMDZN)U15k5cl@ z;$Ze`Tey$Gb2T?lpV}>}jZ*j8!V5}NdrA}2S803uzIn35=N99q)g>8OORhvzAJhN- z$C?nkVu(Hsi#w{@K zqYc03B!&y6bMv-)@2xvt_PcP7?wnhBq}X8h?*Hh!%5^LyoTj*ZS8vfW3m zC!cId+g!PC@nee@yW%8He4cagLFdgkU;kK}&E{QvvBPb#<>&pI^Rgzy#taY*KLZFaBW=KSdbAE1aYF-JD%fJwjU!Gc& znxc?Yso?Gxs_&DTS6VSAu=yJU10$cOi(`n!`MDD}W*rI;Y1_}zYtq-Jx9;G5eoM%h_cZ!Il6IY-xdZp$u97R3cDdF_`DyrNO ze2!;dZ27$OP_7nZ$sRGi|3|uBfB)UV;V5w7Z5g9RSJU4*|7oczo3s1goBjLdsO@;}eKo==UdxWbNh4Zh Tb!WH~DAYV%{an^LB{Ts5FE*`= literal 0 HcmV?d00001 diff --git a/plugins/Microwave/sqr.png b/plugins/Microwave/sqr.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d3c211c6e109e02863df08a81c1f60ac721135 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+o!3HFmxV|j}Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F$*sPy9i(De{GT_i(`nz>Er|njRP5VFDBY6x~ji@VwNPFp7`gm z(*OCbiAs9C|Nk4`Nl!>PuugJaN8>}e!~g$Jf9RK#^dRZS`4?U1T?@|k{QsYCnW;aQ z|MBa$H49Ii{P|wa?yS!gmKz5$(<~pVn4Zk}pRD+7KF{Qit0~+57cvVAA66A(V`FOz z?%TwBB+KMhv48)>nLGd4Ge2IsP%5D%_^!sl=%!CVuPt=E?i#c|;52XW@b$86P0Bgq4}}1wSBwOfg)M@wOzAU(2ri z@vilo*;FY`zz4u+RU&EO&^WyUI7OqvWIf-m0kHzg9zCY&3BL-eT}>y`t;OJ^`YfY9 zr?=tj+~D1J0;cVL(gT3!x_je#48P=$3IwOM<)9cA0Q~aYK&|PAj*;7x=M4p=``v$k z#Dsun9?diQCIuYNYK1m8t%HMRubx>O68wlJekQi0a#P v`o78IFkSb$#yl7GM8>&Fap!<>&pI^QAWU0Rf+ehJWcDh0Ea@d`euu~X)J_*8GP`J}EYrn_?s zWlry0a>?ygRNyMM&pON6r*6Hv;MQKT9*#S;%1JLx&VN>P5RyA)z!RNhJE8W>gOEp8 zotdvakCs2Z#v)bxI>UNiy8o$|e j=U<6;(A~$WJ3lh(=S^f6wdwl`^e%&^tDnm{r-UW|u3U@J literal 0 HcmV?d00001 diff --git a/plugins/Microwave/sqrwave_active.png b/plugins/Microwave/sqrwave_active.png new file mode 100644 index 0000000000000000000000000000000000000000..79951bbfa433ddca60872d37a47e7663e486b1a8 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xawj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI^Rgzy-Q{qK*JWxm>GbEzKIX^cyHLnE7Wnc)%FHbE> zO;JdyRB-nT)%VHFE3KFl*!&GBb=A|wF+}5h>%`c;Lk2u8>1~(Z)s}75KlyUvCF4MW zZ+1F{c?%OXgX(PNo#)$MUso%|?$NZHncw=DH?zM|51iMk@?uZS{avMja-GQA2EQpgO6C~?lu%}vcK0dg4_0`kjK zi&9e*k}4J4{X+G9GV@9+<^(o>14Q!D^ z!m}?kzNAHHdPoLuQ%H56Q7-;a&cWr7!zopr09SEZL;wH) literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab1_active.png b/plugins/Microwave/tab1_active.png new file mode 100644 index 0000000000000000000000000000000000000000..48afd4aa7d4cc183704ea7927cadf80ac56728b4 GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^f&XcX%x;bx0tXHTF)!C8<`)MX5lF!N|bS zQrEyl*U&h`z}U*z(8|Sl8W=oX{an^LB{Ts5 DbNFH@ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab1_artwork.png b/plugins/Microwave/tab1_artwork.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5b7e39fad4fa3f609afb3a4e5bda093c7b24de GIT binary patch literal 6192 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab2.png b/plugins/Microwave/tab2.png new file mode 100644 index 0000000000000000000000000000000000000000..a0331be158e54f58f3b1bc4bfe13315f01b57d50 GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=!3HGRT)yals3dQ97l!{JxM1({$v_d#0*}aI z1_o}RQf^^JhFNnYfP(BLp1!W^k6CybL>QUeqd-O}WQIhPIOpf)rskCZxeN>e`Q@oa zsVNFcl?v{Dq53|Vd8HL|0-L`9r9ODNIEGl9PEL?uUBcv+(=>PP-03DJCRZeY;M^R` z;)OeR-fWUMJmVtks#UA{va+&P<=xtn`Ty_l@A9{A-i-YB^Yif!x3*@l=8!zrq_<$@ z%9T}bZfyL_Ew1+^H6bCvz|^#M$+Bf?jy(x+|NmEB-1``4B4bIAUoeBivm0q3PLj8~i{zWUtsOuP zXMsm#F#`j)FbFd;%$g$s6l5>)^mS!_%)-kiZx-7er2-W4^mK6yk+__kaDb&JqoG1j zEln&;M9{2^&reT8Fi+0SEzT}Quueftz{Nb$LqdyHTu?AI<;g?0jdQ(wCeGz`b%|-3 z*=b^~%*?=6$)s=drC14QsA`F8L`h0wNvc(HQ7VvPFfuT-)HN{CH8c(}Ft#!_v@$i( m1~Lo`zCGzSLD7(#pOTqYiCaVaPGgYw7(8A5T-G@yGywqC)QoWe literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab2_artwork.png b/plugins/Microwave/tab2_artwork.png new file mode 100644 index 0000000000000000000000000000000000000000..ab697fe5875308a6c0263bab49561daa2a007867 GIT binary patch literal 24519 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%0AHY_?Y7Tj;j147muhxg? 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 b6Oze?iIgvRj9&rCeUOs8np};HdD#B}bn!n! literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab2_artwork_flipped.png b/plugins/Microwave/tab2_artwork_flipped.png new file mode 100644 index 0000000000000000000000000000000000000000..52083d55d6f1c4149d1f4e82106f001e9ec3ab6f GIT binary patch literal 7538 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab3_highlighted.png b/plugins/Microwave/tab3_highlighted.png new file mode 100644 index 0000000000000000000000000000000000000000..a61c7f3edd1c88cd748618a2370c48ef1827eec1 GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=!2%@L_}VN7QY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fIH=O_Qx!|%#!l{3zn+_g{FGCIEHAPPfn1~dGKg< z_uthsCc4fr5RElBERvk0z!eZK$=$TGD{{)@`TY~$&Nna?_DfBVko-F1t>hNT7K#6c z1&_>pCs}qIzOv_LRz6(MmNw^<1gpeT$r}|NX{) ze*EwJc;?{MiGu(D literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab4.png b/plugins/Microwave/tab4.png new file mode 100644 index 0000000000000000000000000000000000000000..f9df55a4c5a2d193ca20e3d3357c80fa8fd46018 GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=!3HGRT)yals3dQ97l!{JxM1({$v_d#0*}aI z1_o}RQf^^JhFNnYfP(BLp1!W^k6CybM0GV=*gpV;6f#31N}Tg^b5rw5fLsQKfc)~* zqSO?Hq)G*MzfgUj%)HWyIf2dJ7#J80JzX3_EKa|jyx!Y6Q0D0QowFYwU3kctr`za_ znPaoUq1z7(KlB@L%qmHU68y*>A)|9vsVOxzUpuWif+uO?sx`hFY~dI_;p}^58Ev?;|f6cutyXz!T57;QH&g%r_>Mgscqd+yC8X+L{23 zGt4uTET^A;ZqA_4waBP}?PTU8v(?izm2Wb9c=)dS-I~c~cB=2(m~uC-yz|Mdt>3OJ zED~`wR=KWv*V@c-+8K#rg_m7V);e=Dn5mjF?%AoEUO(mQ@4pNOHf{X|w3IzuM=E*S zBMUoqO9lqd)oa7Dla{Qxn^!&QoJU;P>Z{8Qc-R@<#r#|pwwhP7NOT<0Z83b4kZr!?#^MS0xANT#2)nCgO@_*#=O$G(5r>mdKI;Vst E04@=@vH$=8 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab4_active.png b/plugins/Microwave/tab4_active.png new file mode 100644 index 0000000000000000000000000000000000000000..a2c35e19a3501f7fe1e63e5d1618c9a17e06d7ee GIT binary patch literal 412 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab5.png b/plugins/Microwave/tab5.png new file mode 100644 index 0000000000000000000000000000000000000000..17c6a84caaf01f037a0e6cf096908b352eb3d2ea GIT binary patch literal 361 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 M>FVdQ&MBb@0IynyhX4Qo literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab6.png b/plugins/Microwave/tab6.png new file mode 100644 index 0000000000000000000000000000000000000000..90a21d624858f9f73cd1c79a044b21057918e091 GIT binary patch literal 513 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab6_highlighted.png b/plugins/Microwave/tab6_highlighted.png new file mode 100644 index 0000000000000000000000000000000000000000..ea037d19e10a32cb41467abecc78fde6d1a67355 GIT binary patch literal 443 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=!2%@L_}VN7QY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fIH=O_Qx!|%#!l{3zn+_h1PkxIEHAP-#XEd>yU$h zYkgCSG`C`PTg-u5dKpuhmw9RHJQE1J>E}PeYJykd>I0i6vKR(RFaLGsKaX+#lKo<$ zSF6qC-u5)HtloMpLWpbAPEA%_)p-sFf-eP~IV$AER+Z&f!ZSss*syzfdjG)*mmhB| z?zUz!b(>^xh2>6(&!1Uxp<7rEJ$iYJcemJm<_gQu&X%Q~loCIB8@kJtbJ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tab7_artwork.png b/plugins/Microwave/tab7_artwork.png new file mode 100644 index 0000000000000000000000000000000000000000..367f840dbfffaea1b06cd07fafc696b26e0f490b GIT binary patch literal 3352 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 literal 0 HcmV?d00001 diff --git a/plugins/Microwave/tri.png b/plugins/Microwave/tri.png new file mode 100644 index 0000000000000000000000000000000000000000..01119f8941e03c8bc3780912b1a8976e1de19ece GIT binary patch literal 566 zcmV-60?GY}P)R??#U+s*Z$hJiXG*Udk^%DvyT6g0r=!Iy}yAHt&nbRm|RFvIk80o6W~V zVbAjdfJj`;JgWjY^~(Rnx%I;wCO5%OZNdxp<}=ShJ_vH%ZyY@wh|^oN zw*m3#P)WvXpVFuV-7bY^+q(;wL&H7_dLv)&-0O>Ha^nGT-W>JaV&u4F^FDkK))z?h91poj507*qoM6N<$ Eg8o4HO#lD@ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/triwave.png b/plugins/Microwave/triwave.png new file mode 100644 index 0000000000000000000000000000000000000000..56cacb32af2b6d602306e81372b9d5c90f61eead GIT binary patch literal 438 zcmV;n0ZIOeP)#BJIzv*$d2vL zKjJo@HhdqDikSf*B7_hS5k%yvZ`yD4W0?QzWM+s6eaQzIYG(8gKnS4|D7A|SSu{jZ zRYC~NW-|b)s_F!c1X+q0@kXN&tJMk-;dZ<6csx*5%#08Ms*3jcRTbwP*Xxzb<$`nW zPm_RGjWJtUmJ~(7@p#00Pf-*s7K>-b_)k;R>2%6`K4-t*)3z;5)3Dp^D9e(`WYQ@~ zWBNSLan4ay6{pkbiGDtxsq31}W4L{;(LlXhA}I2;bBD(m(7sm~(w z{eGveYnrC%4ByOX+ZOLV gjw9&ra{KkeFL1!*&$`jjssI2007*qoM6N<$f=;iv#sB~S literal 0 HcmV?d00001 diff --git a/plugins/Microwave/triwave_active.png b/plugins/Microwave/triwave_active.png new file mode 100644 index 0000000000000000000000000000000000000000..a547f4deeef78a2233c7ecd74a1c418b6ba1fc81 GIT binary patch literal 530 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 DD10#p literal 0 HcmV?d00001 diff --git a/plugins/Microwave/wavegraphdisabled.png b/plugins/Microwave/wavegraphdisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..2da7d828c512ff4448c1fec26de6fa56f695b4ec GIT binary patch literal 3090 zcmW-j2~?8V8^(1~%EGKD#VO6P-6e4;bI)8GTr$&KQzRD0&JP^1Xtg8jedeCK}m-1pr3o$oyFbAHcFz2xSkyz|$ca&mIY z7oF`d19LAhl6QcBw_3ECH!y)h;7;~(u5u-E-6LGl98giZ>FkS_liLOPIppOEil9Jo zd(=f&hwZb9n#vXiE&2K(KuIg~icgeX1P+G^j{=r*a+e}*qi&(DYlXyWIk|ZmxP*pB z6N)^NB*1s@7wv7Y5GKC_PX7T3+&`UP{$cdE`rzefmz5lL9(B}bYPTqPJ+}N0 zXqsby?7n-Q4?R*M}z3VxVB>E>|1?)0Xf7sEWNK%;K#UuMB15CGp@XW9lD}(K#9F4 z#ukl6m;d|a%{Sh{!h9#?Fs#+F?6)9RV)9I2E5QTU`)g}l+v${)6j&>Mp|5Ls*$_mA{+Pj{{NDm? z?MuShUxagWZ@*Q1k9#}Ot;8;}`SaQVb}xsczU@~wIl{@wiT7LO_$))HHDXL|v^v+) ziK2K=jlt`w_Qtt}y-~*C4Y4bXjEdFkC^+s2BYAYda#2@Q*|oEwNGQ%Q_qMN5j3v(Z z2oidWWJ}bF=`bQ0lJY-WwKeMHpLNWu9~>f*3|p7b3aje_(b_^NNkfHmM?esOldM0U zWB-%{_?L^!3B8e5b21xO%4J8>tV+96L(j4YYxmQBQ!cAH3wpduhuBV{9AMp-C9<+( zup>BlzUrEGQR@#%3&~REGFULY6~sFPC?91`wfTjS$WjqEV`V%2`s-f4JozQ&AgQUf zRc~Wsqn-eV!&lZs7%2BC{L$Q}PjaM`(G!owXD~%oX;z1cxxFFK7f?{bk5?nN6|Du4 z6Jm2!{7ovorN4OXyVmR97?ifo@IhT$jHrfeTLX_O8<;(``TznlDQzPw?!r(O4G z!@C{cw}+TVBHzFSn(0=$&(aa`L+(|AV@M2CQd5eSWs5WA1#gmfb-+C1|KS>vqiqgy zS*@DOqv|IN!ISlds_St+qsnR`^D1`fpK>_O%)q+mv=@+|5(vrm<9U%tG@|*4x>t`6 zLPMi8K-5Nu80(Es?G5klSfjjt8u@h4KYG%y)A0CO^68`NF6CqQS3$mh5A}Mrb{Iu# zVD?97(SFZgGl_+|h_0`!9*UGXO+xP*F@3u;GVarl@GX49^oPpHWk_`~A+~dTa?+ft zGJNCgV^cXlgGljbueH@B2sk1-+RHj|a|hes-#?2=)$nWOkI{QlR1OCdbaizZO-9Od_46QEzvAG6$kdkp~kZ(6zH-`A1 zG_CuZQH)Ag@qz38&94Lj9==N$jDkdj65hD^;-$UKLxHC2!6T(eZIdIVf7(2n?*Hrl z>l1wpqB9Qs?28o7rPb)eJ2Ee@6Maf2vr>bOwQ}&wuff0f z|MBhP?%liH7TAY0G;9~}rD9#IRVU5AY3|FvO|aGtsj!E~I}R4MCv9I@7l%Q)KzW{1 zXbNi;i=!vFT+&Q~pZ>)3bn?vOg_#k)nCWjM>DF()OvAa;mHSb-qp1}oZJ93ssfrs` zPw{z*Y-}~WmQJBQ9^}KXtWSs!O)`uGzLvP?N(J_KadFz-@s^y1=v(IiiJ+kL6tn^^ zCsv}7u?_`&i9DE2(&-3cX`Z&YS_A`|^MWzwC3#6yMEvtr;$AjDB?%U*qG^yFD*8kw z^kD)RW3J;?-=)HjRm&sBU?RB8wLSGLj=GQQ>M<(uRyEo7gcAa=1abA|6LtA7krV2q z1jlEFWFwL-WhhwsNnq%GL511etm9s6x!2g38AaUMTw99I)4lrQeB05ut!_Yv`RSJ1 zFw6SH`N1-$m6drolsnr=nSYn225SWz+FgB>9!$U{DEkTTjUpXH=&imK1O-upzr&Aj zcn9m#l}&Qbkhw`mKG0R!!5nA@@Sqh^$}$lHZ9yHdVGb;{o^h6h7%Qv=h#5X_?Ae-* zs3<`U@R1bxK<=O3OWUEuh#ar=c7G#WPNE6B)>yS=I|g&U@W~C~g+_k+TbQ8D4@>Fj z^I6PuF0}4ig;k6J%)Eyfw*qafkE?^yD`{D5Gj=IPi(y>K=`H#yj#Xo0`LYoDYS@ea zm|5>fyLS~{sFWp<*7PqR?jK!vZU3Wxqwi%W89f31L3e(3KxPxB>?^`Q7`1vn&$-fd zaA1-z-nsCuTxMf^^xV3PVQta9nb#_UfDcIRX_7KA(*wTG*lfGcP_FG=A*US> zRW{Z$fDuHo>|&Qo@yEdI_MxH7sWzgi6dpVI&^c^KD8--AcJMB@IMs76lE!%{P*_n5Z5gD6IWua=$BzqJP!!`$Y7LSX8p6+B=IRWkECrJ4rh1`#z8~O#eYOb zdQ5&f3s$ibZnL6XPe=%CY-&Ofux(1~@&2@2!Pl>E0L62##k+37W8&lE%?~^JYk)K$ zp~MtTR4zGz(zCUDTTDW_yRZH|Gr&333jU}>BYaiRf5CLsKcYaK=!#y{ z@Z4Oxq|U|?>A8lgyZh6iq&EDWKoul7iH&~)Thx2d*p!VO?IpIu7NMYNvpaxX5e+2ph0at>3eF>-bYZR8Cna0E*=RNoMRa4~`>D>MU8$#17JGl--%=Vrm^g2V$TT zKG(?(yjX-7XI{^ppLqjhViXwCS$z+24v2@p(aik9z>`A>Z&?;K>8U>w#=GC|bmYWk zQ@25897V|EW*w}?NE3r)k=t;teco&chGyJs(_L&gI`zmzw|eid(VXdUX_U1~)4$2Q zExy>i-cFSkah`855T{|nU0GoWghIfsag~l`^3-P4rK^`zPwYC8llUl3L75mQsmbN# zy-$;7)?qvZ`ep%RVz6qVSKL9dekOfSHw~oH)#oD^Gi`?n zq9HLV<+Kf7f0wx;fGwdNumCcp??P-ROb`)nLdyS|$AOZH5H5ec2aLW@U5u#r;?X>T z0K)=0FFY;nSHqoFuTVAY9jx-^ISE1zb*_>eZIK e?yYH+frzi=?mkQ8z501Izv$p*|KdXM-Two=q$kDz literal 0 HcmV?d00001 diff --git a/plugins/Microwave/xbtn.png b/plugins/Microwave/xbtn.png new file mode 100644 index 0000000000000000000000000000000000000000..a55eb6255b1099a5211a4e3e1f627e25e64ed3cd GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xawj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI^MMzZ2;C^r57NAg}r;B5V#`&ca9r+p*cvz;ZvHV;7 zk?H*V#R@VXmN@1pC-^VDtC(VNyDsFtPMX$Jrdh2F2duew@txsG3p@OG-jV|+-moS2 zByD(myN6Tp%KF>Y9yM9=7t&ge{?d0BTF6=5Fw2%VZrbNxeTkNu(=#=mHVFq^w{WZZ So^%ChIfJLGpUXO@geCwu4Nmz0 literal 0 HcmV?d00001 diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index 4710089dd1a..09ead171d49 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -384,7 +384,49 @@ void Graph::paintEvent( QPaintEvent * ) } break; + case Graph::BarCenterGradStyle: + m_foreground.fill(Qt::transparent); + for( int i=0; i <= length; i++ ) + { + QLinearGradient gradient(0, 0, 0, height() / 2.f); + gradient.setSpread(QGradient::Spread(1));// ReflectSpread, so gradient on bottom half is a reflection of the top half + gradient.setColorAt(0, QColor::fromRgbF(m_graphColor.red() / 256.f, m_graphColor.green() / 256.f, m_graphColor.blue() / 256.f, 0.55)); + gradient.setColorAt(1, QColor::fromRgbF(m_graphColor.red() / 256.f, m_graphColor.green() / 256.f, m_graphColor.blue() / 256.f, 0)); + if( (*samps)[i] >= 0 )// Graph value is above middle + { + p.fillRect( 2+static_cast( i*xscale ), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + static_cast( (i+1)*xscale ) - static_cast( i*xscale ), + qMax( static_cast( ( ( minVal - maxVal ) * yscale ) / 2.f ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), 1 ), + gradient ); + } + else// Graph value is below middle + { + p.fillRect( 2+static_cast( i*xscale ), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + static_cast( (i+1)*xscale ) - static_cast( i*xscale ), + static_cast( ( ( minVal - maxVal ) * yscale ) / 2.f ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), + gradient ); + } + + p.setPen( QPen( m_graphColor, 1.0 ) ); + p.drawLine(2+static_cast(i*xscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast((i+1)*xscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) + ); + + if( i != length )// So (*samps)[i+1] doesn't grab something too far + { + p.drawLine(2+static_cast((i+1)*xscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast((i+1)*xscale), + 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) + ); + } + } + break; default: break; } diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index c3e26ae117e..f25ad93c97f 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -56,11 +56,12 @@ TextFloat * Knob::s_textFloat = NULL; #define DEFAULT_KNOB_INITIALIZER_LIST \ QWidget( _parent ), \ FloatModelView( new FloatModel( 0, 0, 0, 1, NULL, _name, true ), this ), \ + m_buttonPressed( false ), \ + m_updateColor( false ), \ m_label( "" ), \ m_knobPixmap( NULL ), \ m_volumeKnob( false ), \ m_volumeRatio( 100.0, 0.0, 1000000.0 ), \ - m_buttonPressed( false ), \ m_angle( -10 ), \ m_lineWidth( 0 ), \ m_textColor( 255, 255, 255 ) @@ -116,6 +117,10 @@ void Knob::initUi( const QString & _name ) case knobVintage_32: setlineColor(QApplication::palette().color( QPalette::Active, QPalette::Shadow )); break; + case knobColored: + break; + case knobSmallColored: + break; default: break; } @@ -145,6 +150,12 @@ void Knob::onKnobNumUpdated() case knobVintage_32: knobFilename = "knob05"; break; + case knobColored: + knobFilename = "knob02"; + break; + case knobSmallColored: + knobFilename = "knob03"; + break; case knobStyled: // only here to stop the compiler from complaining break; } @@ -310,6 +321,21 @@ QColor Knob::outerColor() const void Knob::setOuterColor( const QColor & c ) { m_outerColor = c; + m_updateColor = true; +} + + +QColor Knob::innerColor() const +{ + return m_innerColor; +} + + + +void Knob::setInnerColor( const QColor & c ) +{ + m_innerColor = c; + m_updateColor = true; } @@ -324,6 +350,7 @@ QColor Knob::lineColor() const void Knob::setlineColor( const QColor & c ) { m_lineColor = c; + m_updateColor = true; } @@ -338,6 +365,7 @@ QColor Knob::arcColor() const void Knob::setarcColor( const QColor & c ) { m_arcColor = c; + m_updateColor = true; } @@ -386,14 +414,14 @@ bool Knob::updateAngle() - void Knob::drawKnob( QPainter * _p ) { - if( updateAngle() == false && !m_cache.isNull() ) + if( updateAngle() == false && m_updateColor == false && !m_cache.isNull() ) { _p->drawImage( 0, 0, m_cache ); return; } + else if( m_updateColor ) { m_updateColor = false; } m_cache = QImage( size(), QImage::Format_ARGB32 ); m_cache.fill( qRgba( 0, 0, 0, 0 ) ); @@ -436,9 +464,12 @@ void Knob::drawKnob( QPainter * _p ) const float radius = m_knobPixmap->width() / 2.0f - 1; mid = QPoint( width() / 2, m_knobPixmap->height() / 2 ); - p.drawPixmap( static_cast( - width() / 2 - m_knobPixmap->width() / 2 ), 0, - *m_knobPixmap ); + if( m_knobNum != knobColored && m_knobNum != knobSmallColored ) + { + p.drawPixmap( static_cast( + width() / 2 - m_knobPixmap->width() / 2 ), 0, + *m_knobPixmap ); + } p.setRenderHint( QPainter::Antialiasing ); @@ -450,6 +481,8 @@ void Knob::drawKnob( QPainter * _p ) QColor col; if( m_knobNum == knobVintage_32 ) { col = QApplication::palette().color( QPalette::Active, QPalette::Shadow ); } + else if( m_knobNum == knobColored || m_knobNum == knobSmallColored ) + { col = m_arcColor; } else { col = QApplication::palette().color( QPalette::Active, QPalette::WindowText ); } col.setAlpha( 70 ); @@ -482,6 +515,35 @@ void Knob::drawKnob( QPainter * _p ) p.drawLine( ln ); break; } + case knobColored: + { + // Draw circle + p.setPen( QPen( m_innerColor, 2 ) ); + p.setBrush( m_innerColor ); + p.drawEllipse( QRectF( mid.x()-7, mid.y()-7, 15, 15 ) ); + + // Draw line + p.setPen( QPen( lineColor(), 2 ) ); + const float rb = qMax( ( radius - 10 ) / 3.0, + 0.0 ); + const float re = qMax( ( radius - 4 ), 0.0 ); + QLineF ln = calculateLine( mid, re, rb ); + ln.translate( 1, 1 ); + p.drawLine( ln ); + break; + } + case knobSmallColored: + { + // Draw circle + p.setPen( QPen( m_innerColor, 2 ) ); + p.setBrush( m_innerColor ); + p.drawEllipse( QRectF( mid.x()-4, mid.y()-4, 9, 9 ) ); + + // Draw line + p.setPen( QPen( lineColor(), 2 ) ); + p.drawLine( calculateLine( mid, radius-2 ) ); + break; + } case knobVintage_32: { p.setPen( QPen( lineColor(), 2 ) ); @@ -702,7 +764,8 @@ void Knob::paintEvent( QPaintEvent * _me ) void Knob::wheelEvent( QWheelEvent * _we ) { _we->accept(); - const int inc = ( _we->delta() > 0 ) ? 1 : -1; + const float stepMult = model()->range() / 2000 / model()->step(); + const int inc = ( ( _we->delta() > 0 ) ? 1 : -1 ) * ( ( stepMult < 1 ) ? 1 : stepMult ); model()->incValue( inc ); diff --git a/src/gui/widgets/LcdSpinBox.cpp b/src/gui/widgets/LcdSpinBox.cpp index 325c0171d79..6e899cab379 100644 --- a/src/gui/widgets/LcdSpinBox.cpp +++ b/src/gui/widgets/LcdSpinBox.cpp @@ -50,7 +50,7 @@ LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) : LcdSpinBox::LcdSpinBox( int numDigits, const QString& style, QWidget* parent, const QString& name ) : - LcdWidget( numDigits, parent, name ), + LcdWidget( numDigits, style, parent, name ), IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ), m_mouseMoving( false ), m_origMousePos(), From 45bab95a1400681d2f9507b5b70616822af137cd Mon Sep 17 00:00:00 2001 From: root Date: Sun, 2 Jun 2019 13:51:02 -0600 Subject: [PATCH 02/12] Revert accidental knob behavior change, which belongs in a separate PR --- src/gui/widgets/Knob.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index f25ad93c97f..e6f089f35a1 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -764,8 +764,7 @@ void Knob::paintEvent( QPaintEvent * _me ) void Knob::wheelEvent( QWheelEvent * _we ) { _we->accept(); - const float stepMult = model()->range() / 2000 / model()->step(); - const int inc = ( ( _we->delta() > 0 ) ? 1 : -1 ) * ( ( stepMult < 1 ) ? 1 : stepMult ); + const int inc = ( _we->delta() > 0 ) ? 1 : -1; model()->incValue( inc ); From a3cdd79af083f9797de287c9e4854bae8f6b7aa3 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Jun 2019 10:42:59 -0600 Subject: [PATCH 03/12] Fix coding style --- include/Graph.h | 94 +- plugins/Microwave/Microwave.cpp | 6149 ++++++++++++++++--------------- plugins/Microwave/Microwave.h | 1688 ++++----- src/gui/widgets/Graph.cpp | 482 +-- 4 files changed, 4238 insertions(+), 4175 deletions(-) diff --git a/include/Graph.h b/include/Graph.h index daf9d9f2d8c..d5da70c86ed 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -1,7 +1,7 @@ /* * Graph.h - a QT widget for displaying and manipulating waveforms * - * Copyright (c) 2006-2007 Andreas Brandmaier + * Copyright (c)2006-2007 Andreas Brandmaier * 2008 Paul Giblock * * This file is part of LMMS - https://lmms.io @@ -9,7 +9,7 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * 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 @@ -54,19 +54,19 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView /** * @brief Constructor - * @param _width Pixel width of widget - * @param _height Pixel height of widget + * @param width Pixel width of widget + * @param height Pixel height of widget */ - Graph( QWidget * _parent, graphStyle _style = Graph::LinearStyle, - int _width = 132, - int _height = 104 + Graph(QWidget * parent, graphStyle style = Graph::LinearStyle, + int width = 132, + int height = 104 ); - virtual ~Graph() = default; + virtual ~Graph()= default; - void setForeground( const QPixmap & _pixmap ); + void setForeground(const QPixmap & pixmap); - void setGraphColor( const QColor ); + void setGraphColor(const QColor); inline graphModel * model() { @@ -79,31 +79,31 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView } - inline void setGraphStyle( graphStyle _s ) + inline void setGraphStyle(graphStyle s) { - m_graphStyle = _s; + m_graphStyle = s; update(); } signals: void drawn(); protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void dropEvent( QDropEvent * _de ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + virtual void paintEvent(QPaintEvent * pe); + virtual void dropEvent(QDropEvent * de); + virtual void dragEnterEvent(QDragEnterEvent * dee); + virtual void mousePressEvent(QMouseEvent * me); + virtual void mouseMoveEvent(QMouseEvent * me); + virtual void mouseReleaseEvent(QMouseEvent * me); protected slots: - void updateGraph( int _startPos, int _endPos ); + void updateGraph(int startPos, int endPos); void updateGraph(); private: virtual void modelChanged(); - void changeSampleAt( int _x, int _y ); - void drawLineAt( int _x, int _y, int _lastx ); + void changeSampleAt(int x, int y); + void drawLineAt(int x, int y, int lastx); QPixmap m_foreground; @@ -129,41 +129,41 @@ class LMMS_EXPORT graphModel : public Model public: /** * @brief Constructor - * @param _min Minimum y value to display - * @param _max Maximum y value to display - * @param _size Number of samples (e.g. x value) - * @param _step Step size on y axis where values snap to, or 0.0f + * @param min Minimum y value to display + * @param max Maximum y value to display + * @param size Number of samples (e.g. x value) + * @param step Step size on y axis where values snap to, or 0.0f * for "no snapping" */ - graphModel( float _min, - float _max, - int _size, - :: Model * _parent, - bool _default_constructed = false, - float _step = 0.0 ); + graphModel(float min, + float max, + int size, + :: Model * parent, + bool default_constructed = false, + float step = 0.0); - virtual ~graphModel() = default; + virtual ~graphModel()= default; // TODO: saveSettings, loadSettings? - inline float minValue() const + inline float minValue()const { - return( m_minValue ); + return m_minValue; } - inline float maxValue() const + inline float maxValue()const { - return( m_maxValue ); + return m_maxValue; } - inline int length() const + inline int length()const { return m_length; } - inline const float * samples() const + inline const float * samples()const { - return( m_samples.data() ); + return m_samples.data(); } //! Make cyclic convolution @@ -175,36 +175,36 @@ class LMMS_EXPORT graphModel : public Model public slots: //! Set range of y values - void setRange( float _min, float _max ); + void setRange(float min, float max); - void setLength( int _size ); + void setLength(int size); //! Update one sample - void setSampleAt( int x, float val ); + void setSampleAt(int x, float val); //! Update samples array - void setSamples( const float * _value ); + void setSamples(const float * value); void setWaveToSine(); void setWaveToTriangle(); void setWaveToSaw(); void setWaveToSquare(); void setWaveToNoise(); - QString setWaveToUser( ); + QString setWaveToUser(); void smooth(); void smoothNonCyclic(); void normalize(); void invert(); - void shiftPhase( int _deg ); + void shiftPhase(int deg); void clear(); void clearInvisible(); signals: void lengthChanged(); - void samplesChanged( int startPos, int endPos ); + void samplesChanged(int startPos, int endPos); void rangeChanged(); private: - void drawSampleAt( int x, float val ); + void drawSampleAt(int x, float val); QVector m_samples; int m_length; diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 3b182a30686..18c37a0d02e 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -70,14 +70,14 @@ extern "C" Plugin::Descriptor PLUGIN_EXPORT microwave_plugin_descriptor = { - STRINGIFY( PLUGIN_NAME ), + STRINGIFY(PLUGIN_NAME), "Microwave", - QT_TRANSLATE_NOOP( "pluginBrowser", - "Versatile modular wavetable synthesizer" ), + QT_TRANSLATE_NOOP("pluginBrowser", + "Versatile modular wavetable synthesizer"), "Lost Robot", 0x0100, Plugin::Instrument, - new PluginPixmapLoader( "logo" ), + new PluginPixmapLoader("logo"), NULL, NULL } ; @@ -86,10 +86,10 @@ Plugin::Descriptor PLUGIN_EXPORT microwave_plugin_descriptor = /* - ____ + ___ ,' , `. - ,-+-,.' _ | ,--, - ,-+-. ; , ||,--.'| __ ,-. ,---. .---. + ,-+-,.' | ,--, + ,-+-. ; , ||,--.'| _ ,-. ,---. .---. ,--.'|' | ;|| |, ,' ,'/ /| ' ,'\ /. ./| .---. | | ,', | ':`--'_ ,---. ' | |' | / / | .-'-. ' | ,--.--. /. ./| ,---. | | / | | ||,' ,'| / \| | ,'. ; ,. : /___/ \: | / \ .-' . ' | / \ @@ -102,350 +102,341 @@ Plugin::Descriptor PLUGIN_EXPORT microwave_plugin_descriptor = '---' ---`-' `----' '---" `--`---' `----' .----------------. - /_____________ ____\ - ||\ _________ /|+++| + /_____________ ___\ + ||\ ________ /|+++| || |: :| |+++| || |; (◕‿◕) ;| | + | - || |_________| | _ | + || |_________| | | ||/___________\|[_]| "------------------" - (Do not scroll down if you value your sanity) + (Do not m_scroll down if you value your sanity) */ -Microwave::Microwave( InstrumentTrack * _instrument_track ) : - Instrument( _instrument_track, µwave_plugin_descriptor ), - visvol( 100, 0, 1000, 0.01f, this, tr( "Visualizer Volume" ) ), - loadChnl( 0, 0, 1, 1, this, tr( "Wavetable Loading Channel" ) ), - mainNum(1, 1, 8, this, tr( "Main Oscillator Number" ) ), - subNum(1, 1, 64, this, tr( "Sub Oscillator Number" ) ), - sampNum(1, 1, 8, this, tr( "Sample Number" ) ), - oversample( this, tr("Oversampling") ), - oversampleMode( this, tr("Interpolation") ), - loadMode( this, tr("Wavetable Loading Algorithm") ), - graph( -1.0f, 1.0f, 204, this ), - visualize( false, this ) +Microwave::Microwave(InstrumentTrack * instrument_track) : + Instrument(instrument_track, µwave_plugin_descriptor), + m_visvol(100, 0, 1000, 0.01f, this, tr("Visualizer Volume")), + m_loadChnl(0, 0, 1, 1, this, tr("Wavetable Loading Channel")), + m_mainNum(1, 1, 8, this, tr("Main Oscillator Number")), + m_subNum(1, 1, 64, this, tr("Sub Oscillator Number")), + m_sampNum(1, 1, 8, this, tr("Sample Number")), + m_oversample(this, tr("Oversampling")), + m_oversampleMode(this, tr("Interpolation")), + m_loadMode(this, tr("Wavetable Loading Algorithm")), + m_graph(-1.0f, 1.0f, 204, this), + m_visualize(false, this) { - - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - morph[i] = new FloatModel( 0, 0, 254, 0.0001f, this, tr( "Morph" ) ); - range[i] = new FloatModel( 1, 1, 16, 0.0001f, this, tr( "Range" ) ); - sampLen[i] = new FloatModel( 2048, 1, 16384, 1.f, this, tr( "Waveform Sample Length" ) ); - morphMax[i] = new FloatModel( 255, 0, 254, 0.0001f, this, tr( "Morph Max" ) ); - modify[i] = new FloatModel( 0, 0, 2048, 0.0001f, this, tr( "Wavetable Modifier Value" ) ); - modifyMode[i] = new ComboBoxModel( this, tr( "Wavetable Modifier Mode" ) ); - unisonVoices[i] = new FloatModel( 1, 1, 32, 1, this, tr( "Unison Voices" ) ); - unisonDetune[i] = new FloatModel( 0, 0, 2000, 0.0001f, this, tr( "Unison Detune" ) ); - unisonDetune[i]->setScaleLogarithmic( true ); - unisonMorph[i] = new FloatModel( 0, 0, 256, 0.0001f, this, tr( "Unison Morph" ) ); - unisonModify[i] = new FloatModel( 0, 0, 2048, 0.0001f, this, tr( "Unison Modify" ) ); - detune[i] = new FloatModel( 0, -9600, 9600, 0.0001f, this, tr( "Detune" ) ); - phase[i] = new FloatModel( 0, 0, 200, 0.0001f, this, tr( "Phase" ) ); - phaseRand[i] = new FloatModel( 100, 0, 100, 0.0001f, this, tr( "Phase Randomness" ) ); - vol[i] = new FloatModel( 100.f, 0, 200.f, 0.0001f, this, tr( "Volume" ) ); - enabled[i] = new BoolModel( false, this ); - muted[i] = new BoolModel( false, this ); - pan[i] = new FloatModel( 0.f, -100.f, 100.f, 0.0001f, this, tr( "Panning" ) ); - keytracking[i] = new BoolModel( true, this ); - tempo[i] = new FloatModel( 0.f, 0.f, 999.f, 1.f, this, tr( "Tempo" ) ); - interpolate[i] = new BoolModel( true, this ); - setwavemodel( modifyMode[i] ) - - filtInVol[i] = new FloatModel( 100, 0, 200, 0.0001f, this, tr( "Input Volume" ) ); - filtType[i] = new ComboBoxModel( this, tr( "Filter Type" ) ); - filtSlope[i] = new ComboBoxModel( this, tr( "Filter Slope" ) ); - filtCutoff[i] = new FloatModel( 2000, 20, 20000, 0.0001f, this, tr( "Cutoff Frequency" ) ); - filtCutoff[i]->setScaleLogarithmic( true ); - filtReso[i] = new FloatModel( 0.707, 0, 16, 0.0001f, this, tr( "Resonance" ) ); - filtReso[i]->setScaleLogarithmic( true ); - filtGain[i] = new FloatModel( 0, -64, 64, 0.0001f, this, tr( "dbGain" ) ); - filtGain[i]->setScaleLogarithmic( true ); - filtSatu[i] = new FloatModel( 0, 0, 100, 0.0001f, this, tr( "Saturation" ) ); - filtWetDry[i] = new FloatModel( 100, 0, 100, 0.0001f, this, tr( "Wet/Dry" ) ); - filtBal[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Balance/Panning" ) ); - filtOutVol[i] = new FloatModel( 100, 0, 200, 0.0001f, this, tr( "Output Volume" ) ); - filtEnabled[i] = new BoolModel( false, this ); - filtFeedback[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Feedback" ) ); - filtDetune[i] = new FloatModel( 0, -9600, 9600, 0.0001f, this, tr( "Detune" ) ); - filtKeytracking[i] = new BoolModel( true, this ); - filtMuted[i] = new BoolModel( false, this ); - filtertypesmodel( filtType[i] ) - filterslopesmodel( filtSlope[i] ) - - sampleEnabled[i] = new BoolModel( false, this ); - sampleGraphEnabled[i] = new BoolModel( false, this ); - sampleMuted[i] = new BoolModel( false, this ); - sampleKeytracking[i] = new BoolModel( true, this ); - sampleLoop[i] = new BoolModel( true, this ); - - sampleVolume[i] = new FloatModel( 100, 0, 200, 0.0001f, this, tr( "Volume" ) ); - samplePanning[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Panning" ) ); - sampleDetune[i] = new FloatModel( 0, -9600, 9600, 0.0001f, this, tr( "Detune" ) ); - samplePhase[i] = new FloatModel( 0, 0, 200, 0.0001f, this, tr( "Phase" ) ); - samplePhaseRand[i] = new FloatModel( 0, 0, 100, 0.0001f, this, tr( "Phase Randomness" ) ); - sampleStart[i] = new FloatModel( 0, 0, 1, 0.0001f, this, tr( "Start" ) ); - sampleEnd[i] = new FloatModel( 1, 0, 1, 0.0001f, this, tr( "End" ) ); - - keytrackingArr[i] = true; - interpolateArr[i] = true; + m_morph[i] = new FloatModel(0, 0, 254, 0.0001f, this, tr("Morph")); + m_range[i] = new FloatModel(1, 1, 16, 0.0001f, this, tr("Range")); + m_sampLen[i] = new FloatModel(2048, 1, 16384, 1.f, this, tr("Waveform Sample Length")); + m_morphMax[i] = new FloatModel(255, 0, 254, 0.0001f, this, tr("Morph Max")); + m_modify[i] = new FloatModel(0, 0, 2048, 0.0001f, this, tr("Wavetable Modifier Value")); + m_modifyMode[i] = new ComboBoxModel(this, tr("Wavetable Modifier Mode")); + m_unisonVoices[i] = new FloatModel(1, 1, 32, 1, this, tr("Unison Voices")); + m_unisonDetune[i] = new FloatModel(0, 0, 2000, 0.0001f, this, tr("Unison Detune")); + m_unisonDetune[i]->setScaleLogarithmic(true); + m_unisonMorph[i] = new FloatModel(0, 0, 256, 0.0001f, this, tr("Unison Morph")); + m_unisonModify[i] = new FloatModel(0, 0, 2048, 0.0001f, this, tr("Unison Modify")); + m_detune[i] = new FloatModel(0, -9600, 9600, 0.0001f, this, tr("Detune")); + m_phase[i] = new FloatModel(0, 0, 200, 0.0001f, this, tr("Phase")); + m_phaseRand[i] = new FloatModel(100, 0, 100, 0.0001f, this, tr("Phase Randomness")); + m_vol[i] = new FloatModel(100.f, 0, 200.f, 0.0001f, this, tr("Volume")); + m_enabled[i] = new BoolModel(false, this); + m_muted[i] = new BoolModel(false, this); + m_pan[i] = new FloatModel(0.f, -100.f, 100.f, 0.0001f, this, tr("Panning")); + m_keytracking[i] = new BoolModel(true, this); + m_tempo[i] = new FloatModel(0.f, 0.f, 999.f, 1.f, this, tr("Tempo")); + m_interpolate[i] = new BoolModel(true, this); + setwavemodel(m_modifyMode[i]) + + m_filtInVol[i] = new FloatModel(100, 0, 200, 0.0001f, this, tr("Input Volume")); + m_filtType[i] = new ComboBoxModel(this, tr("Filter Type")); + m_filtSlope[i] = new ComboBoxModel(this, tr("Filter Slope")); + m_filtCutoff[i] = new FloatModel(2000, 20, 20000, 0.0001f, this, tr("Cutoff Frequency")); + m_filtCutoff[i]->setScaleLogarithmic(true); + m_filtReso[i] = new FloatModel(0.707, 0, 16, 0.0001f, this, tr("Resonance")); + m_filtReso[i]->setScaleLogarithmic(true); + m_filtGain[i] = new FloatModel(0, -64, 64, 0.0001f, this, tr("dbGain")); + m_filtGain[i]->setScaleLogarithmic(true); + m_filtSatu[i] = new FloatModel(0, 0, 100, 0.0001f, this, tr("Saturation")); + m_filtWetDry[i] = new FloatModel(100, 0, 100, 0.0001f, this, tr("Wet/Dry")); + m_filtBal[i] = new FloatModel(0, -100, 100, 0.0001f, this, tr("Balance/Panning")); + m_filtOutVol[i] = new FloatModel(100, 0, 200, 0.0001f, this, tr("Output Volume")); + m_filtEnabled[i] = new BoolModel(false, this); + m_filtFeedback[i] = new FloatModel(0, -100, 100, 0.0001f, this, tr("Feedback")); + m_filtDetune[i] = new FloatModel(0, -9600, 9600, 0.0001f, this, tr("Detune")); + m_filtKeytracking[i] = new BoolModel(true, this); + m_filtMuted[i] = new BoolModel(false, this); + filtertypesmodel(m_filtType[i]) + filterslopesmodel(m_filtSlope[i]) + + m_sampleEnabled[i] = new BoolModel(false, this); + m_sampleGraphEnabled[i] = new BoolModel(false, this); + m_sampleMuted[i] = new BoolModel(false, this); + m_sampleKeytracking[i] = new BoolModel(true, this); + m_sampleLoop[i] = new BoolModel(true, this); + + m_sampleVolume[i] = new FloatModel(100, 0, 200, 0.0001f, this, tr("Volume")); + m_samplePanning[i] = new FloatModel(0, -100, 100, 0.0001f, this, tr("Panning")); + m_sampleDetune[i] = new FloatModel(0, -9600, 9600, 0.0001f, this, tr("Detune")); + m_samplePhase[i] = new FloatModel(0, 0, 200, 0.0001f, this, tr("Phase")); + m_samplePhaseRand[i] = new FloatModel(0, 0, 100, 0.0001f, this, tr("Phase Randomness")); + m_sampleStart[i] = new FloatModel(0, 0, 1, 0.0001f, this, tr("Start")); + m_sampleEnd[i] = new FloatModel(1, 0, 1, 0.0001f, this, tr("End")); + + m_keytrackingArr[i] = true; + m_interpolateArr[i] = true; } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - macro[i] = new FloatModel( 0, -100, 100, 0.0001f, this, tr( "Macro" ) ); + m_macro[i] = new FloatModel(0, -100, 100, 0.0001f, this, tr("Macro")); } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - subEnabled[i] = new BoolModel( false, this ); - subVol[i] = new FloatModel( 100.f, 0.f, 200.f, 0.0001f, this, tr( "Volume" ) ); - subPhase[i] = new FloatModel( 0.f, 0.f, 200.f, 0.0001f, this, tr( "Phase" ) ); - subPhaseRand[i] = new FloatModel( 0.f, 0.f, 100.f, 0.0001f, this, tr( "Phase Randomness" ) ); - subDetune[i] = new FloatModel( 0.f, -9600.f, 9600.f, 0.0001f, this, tr( "Detune" ) ); - subMuted[i] = new BoolModel( true, this ); - subKeytrack[i] = new BoolModel( true, this ); - subSampLen[i] = new FloatModel( STOREDSUBWAVELEN, 1.f, STOREDSUBWAVELEN, 1.f, this, tr( "Sample Length" ) ); - subNoise[i] = new BoolModel( false, this ); - subPanning[i] = new FloatModel( 0.f, -100.f, 100.f, 0.0001f, this, tr( "Panning" ) ); - subTempo[i] = new FloatModel( 0.f, 0.f, 999.f, 1.f, this, tr( "Tempo" ) ); - subRateLimit[i] = new FloatModel( 0.f, 0.f, 1.f, 0.000001f, this, tr( "Rate Limit" ) ); - subRateLimit[i]->setScaleLogarithmic( true ); - subUnisonNum[i] = new FloatModel( 1.f, 1.f, 32.f, 1.f, this, tr( "Unison Voice Number" ) ); - subUnisonDetune[i] = new FloatModel( 0.f, 0.f, 2000.f, 0.0001f, this, tr( "Unison Detune" ) ); - subInterpolate[i] = new BoolModel( true, this ); - - modEnabled[i] = new BoolModel( false, this ); - - modOutSec[i] = new ComboBoxModel( this, tr( "Modulation Section" ) ); - modOutSig[i] = new ComboBoxModel( this, tr( "Modulation Signal" ) ); - modOutSecNum[i] = new IntModel( 1, 1, 8, this, tr( "Modulation Section Number" ) ); - modsectionsmodel( modOutSec[i] ) - mainoscsignalsmodel( modOutSig[i] ) - - modIn[i] = new ComboBoxModel( this, tr( "Modulator" ) ); - modInNum[i] = new IntModel( 1, 1, 8, this, tr( "Modulator Number" ) ); - modinmodel( modIn[i] ) - - modInAmnt[i] = new FloatModel( 0, -200, 200, 0.0001f, this, tr( "Modulator Amount" ) ); - modInCurve[i] = new FloatModel( 100, 10.f, 600, 0.0001f, this, tr( "Modulator Curve" ) ); - modInCurve[i]->setScaleLogarithmic( true ); - - modIn2[i] = new ComboBoxModel( this, tr( "Secondary Modulator" ) ); - modInNum2[i] = new IntModel( 1, 1, 8, this, tr( "Secondary Modulator Number" ) ); - modinmodel( modIn2[i] ) - - modInAmnt2[i] = new FloatModel( 0, -200, 200, 0.0001f, this, tr( "Secondary Modulator Amount" ) ); - modInCurve2[i] = new FloatModel( 100, 10.f, 600, 0.0001f, this, tr( "Secondary Modulator Curve" ) ); - modInCurve2[i]->setScaleLogarithmic( true ); - - modCombineType[i] = new ComboBoxModel( this, tr( "Combination Type" ) ); - modcombinetypemodel( modCombineType[i] ) - - modType[i] = new BoolModel( false, this ); - modType2[i] = new BoolModel( false, this ); + m_subEnabled[i] = new BoolModel(false, this); + m_subVol[i] = new FloatModel(100.f, 0.f, 200.f, 0.0001f, this, tr("Volume")); + m_subPhase[i] = new FloatModel(0.f, 0.f, 200.f, 0.0001f, this, tr("Phase")); + m_subPhaseRand[i] = new FloatModel(0.f, 0.f, 100.f, 0.0001f, this, tr("Phase Randomness")); + m_subDetune[i] = new FloatModel(0.f, -9600.f, 9600.f, 0.0001f, this, tr("Detune")); + m_subMuted[i] = new BoolModel(true, this); + m_subKeytrack[i] = new BoolModel(true, this); + m_subSampLen[i] = new FloatModel(STOREDSUBWAVELEN, 1.f, STOREDSUBWAVELEN, 1.f, this, tr("Sample Length")); + m_subNoise[i] = new BoolModel(false, this); + m_subPanning[i] = new FloatModel(0.f, -100.f, 100.f, 0.0001f, this, tr("Panning")); + m_subTempo[i] = new FloatModel(0.f, 0.f, 999.f, 1.f, this, tr("Tempo")); + m_subRateLimit[i] = new FloatModel(0.f, 0.f, 1.f, 0.000001f, this, tr("Rate Limit")); + m_subRateLimit[i]->setScaleLogarithmic(true); + m_subUnisonNum[i] = new FloatModel(1.f, 1.f, 32.f, 1.f, this, tr("Unison Voice Number")); + m_subUnisonDetune[i] = new FloatModel(0.f, 0.f, 2000.f, 0.0001f, this, tr("Unison Detune")); + m_subInterpolate[i] = new BoolModel(true, this); + + m_modEnabled[i] = new BoolModel(false, this); + + m_modOutSec[i] = new ComboBoxModel(this, tr("Modulation Section")); + m_modOutSig[i] = new ComboBoxModel(this, tr("Modulation Signal")); + m_modOutSecNum[i] = new IntModel(1, 1, 8, this, tr("Modulation Section Number")); + modsectionsmodel(m_modOutSec[i]) + mainoscsignalsmodel(m_modOutSig[i]) + + m_modIn[i] = new ComboBoxModel(this, tr("Modulator")); + m_modInNum[i] = new IntModel(1, 1, 8, this, tr("Modulator Number")); + modinmodel(m_modIn[i]) + + m_modInAmnt[i] = new FloatModel(0, -200, 200, 0.0001f, this, tr("Modulator Amount")); + m_modInCurve[i] = new FloatModel(100, 10.f, 600, 0.0001f, this, tr("Modulator Curve")); + m_modInCurve[i]->setScaleLogarithmic(true); + + m_modIn2[i] = new ComboBoxModel(this, tr("Secondary Modulator")); + m_modInNum2[i] = new IntModel(1, 1, 8, this, tr("Secondary Modulator Number")); + modinmodel(m_modIn2[i]) + + m_modInAmnt2[i] = new FloatModel(0, -200, 200, 0.0001f, this, tr("Secondary Modulator Amount")); + m_modInCurve2[i] = new FloatModel(100, 10.f, 600, 0.0001f, this, tr("Secondary Modulator Curve")); + m_modInCurve2[i]->setScaleLogarithmic(true); + + m_modCombineType[i] = new ComboBoxModel(this, tr("Combination Type")); + modcombinetypemodel(m_modCombineType[i]) + + m_modType[i] = new BoolModel(false, this); + m_modType2[i] = new BoolModel(false, this); } - oversamplemodel( oversample ) - oversample.setValue( 1 );// 2x oversampling is default + oversamplemodel(m_oversample) + m_oversample.setValue(1);// 2x oversampling is default - loadmodemodel( loadMode ) + loadmodemodel(m_loadMode) - oversamplemodemodel( oversampleMode ) - oversampleMode.setValue( 1 );// Sample averaging is default + oversamplemodemodel(m_oversampleMode) + m_oversampleMode.setValue(1);// Sample averaging is default - connect( &graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( samplesChanged( int, int ) ) ); + connect(&m_graph, SIGNAL(samplesChanged(int, int)), this, SLOT(samplesChanged(int, int))); - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - connect( morph[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(1, i); }, Qt::DirectConnection ); - connect( range[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(2, i); }, Qt::DirectConnection ); - connect( modify[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(3, i); }, Qt::DirectConnection ); - connect( modifyMode[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(4, i); }, Qt::DirectConnection ); - connect( vol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(5, i); }, Qt::DirectConnection ); - connect( pan[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(6, i); }, Qt::DirectConnection ); - connect( detune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(7, i); }, Qt::DirectConnection ); - connect( phase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(8, i); }, Qt::DirectConnection ); - connect( phaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(9, i); }, Qt::DirectConnection ); - connect( enabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(10, i); }, Qt::DirectConnection ); - connect( muted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(11, i); }, Qt::DirectConnection ); - connect( sampLen[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(12, i); }, Qt::DirectConnection ); - connect( morphMax[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(13, i); }, Qt::DirectConnection ); - connect( unisonVoices[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(14, i); }, Qt::DirectConnection ); - connect( unisonDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(15, i); }, Qt::DirectConnection ); - connect( unisonMorph[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(16, i); }, Qt::DirectConnection ); - connect( unisonModify[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(17, i); }, Qt::DirectConnection ); - connect( keytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(18, i); }, Qt::DirectConnection ); - connect( tempo[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(19, i); }, Qt::DirectConnection ); - connect( interpolate[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(20, i); }, Qt::DirectConnection ); - - connect( sampleEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(60, i); }, Qt::DirectConnection ); - connect( sampleMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(61, i); }, Qt::DirectConnection ); - connect( sampleKeytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(62, i); }, Qt::DirectConnection ); - connect( sampleGraphEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(63, i); }, Qt::DirectConnection ); - connect( sampleLoop[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(64, i); }, Qt::DirectConnection ); - connect( sampleVolume[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(65, i); }, Qt::DirectConnection ); - connect( samplePanning[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(66, i); }, Qt::DirectConnection ); - connect( sampleDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(67, i); }, Qt::DirectConnection ); - connect( samplePhase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(68, i); }, Qt::DirectConnection ); - connect( samplePhaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(69, i); }, Qt::DirectConnection ); - connect( sampleStart[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(70, i); }, Qt::DirectConnection ); - connect( sampleEnd[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(71, i); }, Qt::DirectConnection ); - - connect( filtCutoff[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(120, i); }, Qt::DirectConnection ); - connect( filtReso[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(121, i); }, Qt::DirectConnection ); - connect( filtGain[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(122, i); }, Qt::DirectConnection ); - connect( filtType[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(123, i); }, Qt::DirectConnection ); - connect( filtSlope[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(124, i); }, Qt::DirectConnection ); - connect( filtInVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(125, i); }, Qt::DirectConnection ); - connect( filtOutVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(126, i); }, Qt::DirectConnection ); - connect( filtWetDry[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(127, i); }, Qt::DirectConnection ); - connect( filtBal[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(128, i); }, Qt::DirectConnection ); - connect( filtSatu[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(129, i); }, Qt::DirectConnection ); - connect( filtFeedback[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(130, i); }, Qt::DirectConnection ); - connect( filtDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(131, i); }, Qt::DirectConnection ); - connect( filtEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(132, i); }, Qt::DirectConnection ); - connect( filtMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(133, i); }, Qt::DirectConnection ); - connect( filtKeytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(134, i); }, Qt::DirectConnection ); - - for( int j = 1; j <= 20; ++j ) + connect(m_morph[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(1, i); }, Qt::DirectConnection); + connect(m_range[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(2, i); }, Qt::DirectConnection); + connect(m_modify[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(3, i); }, Qt::DirectConnection); + connect(m_modifyMode[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(4, i); }, Qt::DirectConnection); + connect(m_vol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(5, i); }, Qt::DirectConnection); + connect(m_pan[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(6, i); }, Qt::DirectConnection); + connect(m_detune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(7, i); }, Qt::DirectConnection); + connect(m_phase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(8, i); }, Qt::DirectConnection); + connect(m_phaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(9, i); }, Qt::DirectConnection); + connect(m_enabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(10, i); }, Qt::DirectConnection); + connect(m_muted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(11, i); }, Qt::DirectConnection); + connect(m_sampLen[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(12, i); }, Qt::DirectConnection); + connect(m_morphMax[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(13, i); }, Qt::DirectConnection); + connect(m_unisonVoices[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(14, i); }, Qt::DirectConnection); + connect(m_unisonDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(15, i); }, Qt::DirectConnection); + connect(m_unisonMorph[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(16, i); }, Qt::DirectConnection); + connect(m_unisonModify[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(17, i); }, Qt::DirectConnection); + connect(m_keytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(18, i); }, Qt::DirectConnection); + connect(m_tempo[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(19, i); }, Qt::DirectConnection); + connect(m_interpolate[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(20, i); }, Qt::DirectConnection); + + connect(m_sampleEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(60, i); }, Qt::DirectConnection); + connect(m_sampleMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(61, i); }, Qt::DirectConnection); + connect(m_sampleKeytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(62, i); }, Qt::DirectConnection); + connect(m_sampleGraphEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(63, i); }, Qt::DirectConnection); + connect(m_sampleLoop[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(64, i); }, Qt::DirectConnection); + connect(m_sampleVolume[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(65, i); }, Qt::DirectConnection); + connect(m_samplePanning[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(66, i); }, Qt::DirectConnection); + connect(m_sampleDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(67, i); }, Qt::DirectConnection); + connect(m_samplePhase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(68, i); }, Qt::DirectConnection); + connect(m_samplePhaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(69, i); }, Qt::DirectConnection); + connect(m_sampleStart[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(70, i); }, Qt::DirectConnection); + connect(m_sampleEnd[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(71, i); }, Qt::DirectConnection); + + connect(m_filtCutoff[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(120, i); }, Qt::DirectConnection); + connect(m_filtReso[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(121, i); }, Qt::DirectConnection); + connect(m_filtGain[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(122, i); }, Qt::DirectConnection); + connect(m_filtType[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(123, i); }, Qt::DirectConnection); + connect(m_filtSlope[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(124, i); }, Qt::DirectConnection); + connect(m_filtInVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(125, i); }, Qt::DirectConnection); + connect(m_filtOutVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(126, i); }, Qt::DirectConnection); + connect(m_filtWetDry[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(127, i); }, Qt::DirectConnection); + connect(m_filtBal[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(128, i); }, Qt::DirectConnection); + connect(m_filtSatu[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(129, i); }, Qt::DirectConnection); + connect(m_filtFeedback[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(130, i); }, Qt::DirectConnection); + connect(m_filtDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(131, i); }, Qt::DirectConnection); + connect(m_filtEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(132, i); }, Qt::DirectConnection); + connect(m_filtMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(133, i); }, Qt::DirectConnection); + connect(m_filtKeytracking[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(134, i); }, Qt::DirectConnection); + + for (int j = 1; j <= 20; ++j) { valueChanged(j, i); } - for( int j = 60; j <= 71; ++j ) + for (int j = 60; j <= 71; ++j) { valueChanged(j, i); } - for( int j = 120; j <= 134; ++j ) + for (int j = 120; j <= 134; ++j) { valueChanged(j, i); } - connect( sampleEnabled[i], &BoolModel::dataChanged, this, [this, i]() { sampleEnabledChanged(i); }, Qt::DirectConnection ); - - connect( enabled[i], &BoolModel::dataChanged, this, [this, i]() { mainEnabledChanged(i); }, Qt::DirectConnection ); - - connect( filtEnabled[i], &BoolModel::dataChanged, this, [this, i]() { filtEnabledChanged(i); }, Qt::DirectConnection ); - - connect( sampLen[i], &FloatModel::dataChanged, this, [this, i]() { sampLenChanged(i); }, Qt::DirectConnection ); - - connect( interpolate[i], &BoolModel::dataChanged, this, [this, i]() { interpolateChanged(i); } ); - - connect( morphMax[i], &FloatModel::dataChanged, this, [this, i]() { morphMaxChanged(i); }, Qt::DirectConnection ); + connect(m_sampleEnabled[i], &BoolModel::dataChanged, this, [this, i]() { sampleEnabledChanged(i); }, Qt::DirectConnection); + connect(m_enabled[i], &BoolModel::dataChanged, this, [this, i]() { mainEnabledChanged(i); }, Qt::DirectConnection); + connect(m_filtEnabled[i], &BoolModel::dataChanged, this, [this, i]() { filtEnabledChanged(i); }, Qt::DirectConnection); + connect(m_sampLen[i], &FloatModel::dataChanged, this, [this, i]() { sampLenChanged(i); }, Qt::DirectConnection); + connect(m_interpolate[i], &BoolModel::dataChanged, this, [this, i]() { interpolateChanged(i); }); + connect(m_morphMax[i], &FloatModel::dataChanged, this, [this, i]() { morphMaxChanged(i); }, Qt::DirectConnection); } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - connect( macro[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(150, i); }, Qt::DirectConnection ); + connect(m_macro[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(150, i); }, Qt::DirectConnection); valueChanged(150, i); - macroColors[i][0] = 102; - macroColors[i][1] = 198; - macroColors[i][2] = 199; + m_macroColors[i][0] = 102; + m_macroColors[i][1] = 198; + m_macroColors[i][2] = 199; } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - connect( subEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(30, i); }, Qt::DirectConnection ); - connect( subMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(31, i); }, Qt::DirectConnection ); - connect( subKeytrack[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(32, i); }, Qt::DirectConnection ); - connect( subNoise[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(33, i); }, Qt::DirectConnection ); - connect( subVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(34, i); }, Qt::DirectConnection ); - connect( subPanning[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(35, i); }, Qt::DirectConnection ); - connect( subDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(36, i); }, Qt::DirectConnection ); - connect( subPhase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(37, i); }, Qt::DirectConnection ); - connect( subPhaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(38, i); }, Qt::DirectConnection ); - connect( subSampLen[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(39, i); }, Qt::DirectConnection ); - connect( subTempo[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(40, i); }, Qt::DirectConnection ); - connect( subRateLimit[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(41, i); }, Qt::DirectConnection ); - connect( subUnisonNum[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(42, i); }, Qt::DirectConnection ); - connect( subUnisonDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(43, i); }, Qt::DirectConnection ); - connect( subInterpolate[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(44, i); }, Qt::DirectConnection ); - - connect( modIn[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(90, i); }, Qt::DirectConnection ); - connect( modInNum[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(91, i); }, Qt::DirectConnection ); - connect( modInAmnt[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(92, i); }, Qt::DirectConnection ); - connect( modInCurve[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(93, i); }, Qt::DirectConnection ); - connect( modIn2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(94, i); }, Qt::DirectConnection ); - connect( modInNum2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(95, i); }, Qt::DirectConnection ); - connect( modInAmnt2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(96, i); }, Qt::DirectConnection ); - connect( modInCurve2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(97, i); }, Qt::DirectConnection ); - connect( modOutSec[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(98, i); }, Qt::DirectConnection ); - connect( modOutSig[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(99, i); }, Qt::DirectConnection ); - connect( modOutSecNum[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(100, i); }, Qt::DirectConnection ); - connect( modEnabled[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(101, i); }, Qt::DirectConnection ); - connect( modCombineType[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(102, i); }, Qt::DirectConnection ); - connect( modType[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(103, i); }, Qt::DirectConnection ); - connect( modType2[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(104, i); }, Qt::DirectConnection ); - - for( int j = 30; j <= 44; ++j ) + connect(m_subEnabled[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(30, i); }, Qt::DirectConnection); + connect(m_subMuted[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(31, i); }, Qt::DirectConnection); + connect(m_subKeytrack[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(32, i); }, Qt::DirectConnection); + connect(m_subNoise[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(33, i); }, Qt::DirectConnection); + connect(m_subVol[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(34, i); }, Qt::DirectConnection); + connect(m_subPanning[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(35, i); }, Qt::DirectConnection); + connect(m_subDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(36, i); }, Qt::DirectConnection); + connect(m_subPhase[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(37, i); }, Qt::DirectConnection); + connect(m_subPhaseRand[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(38, i); }, Qt::DirectConnection); + connect(m_subSampLen[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(39, i); }, Qt::DirectConnection); + connect(m_subTempo[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(40, i); }, Qt::DirectConnection); + connect(m_subRateLimit[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(41, i); }, Qt::DirectConnection); + connect(m_subUnisonNum[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(42, i); }, Qt::DirectConnection); + connect(m_subUnisonDetune[i], &FloatModel::dataChanged, this, [this, i]() { valueChanged(43, i); }, Qt::DirectConnection); + connect(m_subInterpolate[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(44, i); }, Qt::DirectConnection); + + connect(m_modIn[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(90, i); }, Qt::DirectConnection); + connect(m_modInNum[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(91, i); }, Qt::DirectConnection); + connect(m_modInAmnt[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(92, i); }, Qt::DirectConnection); + connect(m_modInCurve[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(93, i); }, Qt::DirectConnection); + connect(m_modIn2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(94, i); }, Qt::DirectConnection); + connect(m_modInNum2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(95, i); }, Qt::DirectConnection); + connect(m_modInAmnt2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(96, i); }, Qt::DirectConnection); + connect(m_modInCurve2[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(97, i); }, Qt::DirectConnection); + connect(m_modOutSec[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(98, i); }, Qt::DirectConnection); + connect(m_modOutSig[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(99, i); }, Qt::DirectConnection); + connect(m_modOutSecNum[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(100, i); }, Qt::DirectConnection); + connect(m_modEnabled[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(101, i); }, Qt::DirectConnection); + connect(m_modCombineType[i], &ComboBoxModel::dataChanged, this, [this, i]() { valueChanged(102, i); }, Qt::DirectConnection); + connect(m_modType[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(103, i); }, Qt::DirectConnection); + connect(m_modType2[i], &BoolModel::dataChanged, this, [this, i]() { valueChanged(104, i); }, Qt::DirectConnection); + + for (int j = 30; j <= 44; ++j) { valueChanged(j, i); } - for( int j = 90; j <= 104; ++j ) + for (int j = 90; j <= 104; ++j) { valueChanged(j, i); } - connect( modEnabled[i], &BoolModel::dataChanged, this, [this, i]() { modEnabledChanged(i); }, Qt::DirectConnection ); - - connect( subSampLen[i], &FloatModel::dataChanged, this, [this, i]() { subSampLenChanged(i); } ); - - connect( subEnabled[i], &BoolModel::dataChanged, this, [this, i]() { subEnabledChanged(i); } ); - - connect( subInterpolate[i], &BoolModel::dataChanged, this, [this, i]() { subInterpolateChanged(i); } ); + connect(m_modEnabled[i], &BoolModel::dataChanged, this, [this, i]() { modEnabledChanged(i); }, Qt::DirectConnection); + connect(m_subSampLen[i], &FloatModel::dataChanged, this, [this, i]() { subSampLenChanged(i); }); + connect(m_subEnabled[i], &BoolModel::dataChanged, this, [this, i]() { subEnabledChanged(i); }); + connect(m_subInterpolate[i], &BoolModel::dataChanged, this, [this, i]() { subInterpolateChanged(i); }); } - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - samples[i][0].push_back(0); - samples[i][1].push_back(0); + m_samples[i][0].push_back(0); + m_samples[i][1].push_back(0); } } Microwave::~Microwave() { - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { /*The following disconnected functions will run if not disconnected upon deletion, because deleting a ComboBox includes clearing its contents first, which will fire a dataChanged event. So, we need to disconnect them to prevent a crash.*/ - disconnect(modIn[i], &ComboBoxModel::dataChanged, 0, 0); - disconnect(modIn2[i], &ComboBoxModel::dataChanged, 0, 0); - disconnect(modOutSec[i], &ComboBoxModel::dataChanged, 0, 0); + disconnect(m_modIn[i], &ComboBoxModel::dataChanged, 0, 0); + disconnect(m_modIn2[i], &ComboBoxModel::dataChanged, 0, 0); + disconnect(m_modOutSec[i], &ComboBoxModel::dataChanged, 0, 0); } } -PluginView * Microwave::instantiateView( QWidget * _parent ) +PluginView * Microwave::instantiateView(QWidget * parent) { - return( new MicrowaveView( this, _parent ) ); + return new MicrowaveView(this, parent); } QString Microwave::nodeName() const { - return( microwave_plugin_descriptor.name ); + return microwave_plugin_descriptor.name; } -void Microwave::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) { - // NOTE: Only enabled oscillators/sections are saved. This is to prevent ridiculously long project save times, as well as total disk space annihilation. + // NOTE: Only m_enabled oscillators/sections are saved. This is to prevent ridiculously long project save times, as well as total disk space annihilation. // Save plugin version - _this.setAttribute( "version", "Microwave Official Release 1" ); + thissave.setAttribute("version", "Microwave Official Release 1"); /* @@ -464,306 +455,306 @@ void Microwave::saveSettings( QDomDocument & _doc, QDomElement & _this ) */ - visvol.saveSettings( _doc, _this, "visualizervolume" ); - loadMode.saveSettings( _doc, _this, "loadingalgorithm" ); - loadChnl.saveSettings( _doc, _this, "loadingchannel" ); + m_visvol.saveSettings(doc, thissave, "visualizer_volume"); + m_loadMode.saveSettings(doc, thissave, "loadingalgorithm"); + m_loadChnl.saveSettings(doc, thissave, "loadingchannel"); - oversample.saveSettings( _doc, _this, "oversample" ); - oversampleMode.saveSettings( _doc, _this, "oversamplemode" ); - removeDC.saveSettings( _doc, _this, "removeDC" ); + m_oversample.saveSettings(doc, thissave, "oversample"); + m_oversampleMode.saveSettings(doc, thissave, "oversamplemode"); + m_removeDC.saveSettings(doc, thissave, "removeDC"); QString saveString; - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( enabled[i]->value() ) + if (m_enabled[i]->value()) { - if( updateWavetable[i] ) + if (m_updateWavetable[i]) { - updateWavetable[i] = false; - base64::encode( (const char *)storedwaveforms[i], - STOREDMAINARRAYLEN * sizeof(float), wavetableSaveStrings[i] ); + m_updateWavetable[i] = false; + base64::encode((const char *)m_storedwaveforms[i], + STOREDMAINARRAYLEN * sizeof(float), m_wavetableSaveStrings[i]); } - _this.setAttribute( "waveforms"+QString::number(i), wavetableSaveStrings[i] ); + thissave.setAttribute("waveforms"+QString::number(i), m_wavetableSaveStrings[i]); } } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - if( subEnabled[i]->value() ) + if (m_subEnabled[i]->value()) { - base64::encode( (const char *)storedsubs[i], - STOREDSUBWAVELEN * sizeof(float), saveString ); - _this.setAttribute( "subs"+QString::number(i), saveString ); + base64::encode((const char *)m_storedsubs[i], + STOREDSUBWAVELEN * sizeof(float), saveString); + thissave.setAttribute("subs"+QString::number(i), saveString); } } - base64::encode( (const char *)sampGraphs, - 1024 * sizeof(float), saveString ); - _this.setAttribute( "sampGraphs", saveString ); + base64::encode((const char *)m_sampGraphs, + 1024 * sizeof(float), saveString); + thissave.setAttribute("sampGraphs", saveString); int sampleSizes[8] = {0}; - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( sampleEnabled[i]->value() ) + if (m_sampleEnabled[i]->value()) { - for( int j = 0; j < 2; ++j ) + for (int j = 0; j < 2; ++j) { - base64::encode( (const char *)samples[i][j].data(), - samples[i][j].size() * sizeof(float), saveString ); - _this.setAttribute( "samples_"+QString::number(i)+"_"+QString::number(j), saveString ); + base64::encode((const char *)m_samples[i][j].data(), + m_samples[i][j].size() * sizeof(float), saveString); + thissave.setAttribute("samples_"+QString::number(i)+"_"+QString::number(j), saveString); } - sampleSizes[i] = samples[i][0].size(); + sampleSizes[i] = m_samples[i][0].size(); } } - base64::encode( (const char *)sampleSizes, - 8 * sizeof(int), saveString ); - _this.setAttribute( "sampleSizes", saveString ); + base64::encode((const char *)sampleSizes, + 8 * sizeof(int), saveString); + thissave.setAttribute("sampleSizes", saveString); - for( int i = 0; i < maxMainEnabled; ++i ) + for (int i = 0; i < m_maxMainEnabled; ++i) { - if( enabled[i]->value() ) + if (m_enabled[i]->value()) { - morph[i]->saveSettings( _doc, _this, "morph_"+QString::number(i) ); - range[i]->saveSettings( _doc, _this, "range_"+QString::number(i) ); - modify[i]->saveSettings( _doc, _this, "modify_"+QString::number(i) ); - modifyMode[i]->saveSettings( _doc, _this, "modifyMode_"+QString::number(i) ); - unisonVoices[i]->saveSettings( _doc, _this, "unisonVoices_"+QString::number(i) ); - unisonDetune[i]->saveSettings( _doc, _this, "unisonDetune_"+QString::number(i) ); - unisonMorph[i]->saveSettings( _doc, _this, "unisonMorph_"+QString::number(i) ); - unisonModify[i]->saveSettings( _doc, _this, "unisonModify_"+QString::number(i) ); - morphMax[i]->saveSettings( _doc, _this, "morphMax_"+QString::number(i) ); - detune[i]->saveSettings( _doc, _this, "detune_"+QString::number(i) ); - sampLen[i]->saveSettings( _doc, _this, "sampLen_"+QString::number(i) ); - phase[i]->saveSettings( _doc, _this, "phase_"+QString::number(i) ); - phaseRand[i]->saveSettings( _doc, _this, "phaseRand_"+QString::number(i) ); - vol[i]->saveSettings( _doc, _this, "vol_"+QString::number(i) ); - enabled[i]->saveSettings( _doc, _this, "enabled_"+QString::number(i) ); - muted[i]->saveSettings( _doc, _this, "muted_"+QString::number(i) ); - pan[i]->saveSettings( _doc, _this, "pan_"+QString::number(i) ); - keytracking[i]->saveSettings( _doc, _this, "keytracking_"+QString::number(i) ); - tempo[i]->saveSettings( _doc, _this, "tempo_"+QString::number(i) ); - interpolate[i]->saveSettings( _doc, _this, "interpolate_"+QString::number(i) ); + m_morph[i]->saveSettings(doc, thissave, "morph_"+QString::number(i)); + m_range[i]->saveSettings(doc, thissave, "range_"+QString::number(i)); + m_modify[i]->saveSettings(doc, thissave, "modify_"+QString::number(i)); + m_modifyMode[i]->saveSettings(doc, thissave, "modifyMode_"+QString::number(i)); + m_unisonVoices[i]->saveSettings(doc, thissave, "unisonVoices_"+QString::number(i)); + m_unisonDetune[i]->saveSettings(doc, thissave, "unisonDetune_"+QString::number(i)); + m_unisonMorph[i]->saveSettings(doc, thissave, "unisonMorph_"+QString::number(i)); + m_unisonModify[i]->saveSettings(doc, thissave, "unisonModify_"+QString::number(i)); + m_morphMax[i]->saveSettings(doc, thissave, "morphMax_"+QString::number(i)); + m_detune[i]->saveSettings(doc, thissave, "detune_"+QString::number(i)); + m_sampLen[i]->saveSettings(doc, thissave, "sampLen_"+QString::number(i)); + m_phase[i]->saveSettings(doc, thissave, "phase_"+QString::number(i)); + m_phaseRand[i]->saveSettings(doc, thissave, "phaseRand_"+QString::number(i)); + m_vol[i]->saveSettings(doc, thissave, "vol_"+QString::number(i)); + m_enabled[i]->saveSettings(doc, thissave, "enabled_"+QString::number(i)); + m_muted[i]->saveSettings(doc, thissave, "muted_"+QString::number(i)); + m_pan[i]->saveSettings(doc, thissave, "pan_"+QString::number(i)); + m_keytracking[i]->saveSettings(doc, thissave, "keytracking_"+QString::number(i)); + m_tempo[i]->saveSettings(doc, thissave, "tempo_"+QString::number(i)); + m_interpolate[i]->saveSettings(doc, thissave, "interpolate_"+QString::number(i)); } } - for( int i = 0; i < maxSampleEnabled; ++i ) + for (int i = 0; i < m_maxSampleEnabled; ++i) { - if( sampleEnabled[i]->value() ) + if (m_sampleEnabled[i]->value()) { - sampleEnabled[i]->saveSettings( _doc, _this, "sampleEnabled_"+QString::number(i) ); - sampleGraphEnabled[i]->saveSettings( _doc, _this, "sampleGraphEnabled_"+QString::number(i) ); - sampleMuted[i]->saveSettings( _doc, _this, "sampleMuted_"+QString::number(i) ); - sampleKeytracking[i]->saveSettings( _doc, _this, "sampleKeytracking_"+QString::number(i) ); - sampleLoop[i]->saveSettings( _doc, _this, "sampleLoop_"+QString::number(i) ); - sampleVolume[i]->saveSettings( _doc, _this, "sampleVolume_"+QString::number(i) ); - samplePanning[i]->saveSettings( _doc, _this, "samplePanning_"+QString::number(i) ); - sampleDetune[i]->saveSettings( _doc, _this, "sampleDetune_"+QString::number(i) ); - samplePhase[i]->saveSettings( _doc, _this, "samplePhase_"+QString::number(i) ); - samplePhaseRand[i]->saveSettings( _doc, _this, "samplePhaseRand_"+QString::number(i) ); - sampleStart[i]->saveSettings( _doc, _this, "sampleStart_"+QString::number(i) ); - sampleEnd[i]->saveSettings( _doc, _this, "sampleEnd_"+QString::number(i) ); + m_sampleEnabled[i]->saveSettings(doc, thissave, "sampleEnabled_"+QString::number(i)); + m_sampleGraphEnabled[i]->saveSettings(doc, thissave, "sampleGraphEnabled_"+QString::number(i)); + m_sampleMuted[i]->saveSettings(doc, thissave, "sampleMuted_"+QString::number(i)); + m_sampleKeytracking[i]->saveSettings(doc, thissave, "sampleKeytracking_"+QString::number(i)); + m_sampleLoop[i]->saveSettings(doc, thissave, "sampleLoop_"+QString::number(i)); + m_sampleVolume[i]->saveSettings(doc, thissave, "sampleVolume_"+QString::number(i)); + m_samplePanning[i]->saveSettings(doc, thissave, "samplePanning_"+QString::number(i)); + m_sampleDetune[i]->saveSettings(doc, thissave, "sampleDetune_"+QString::number(i)); + m_samplePhase[i]->saveSettings(doc, thissave, "samplePhase_"+QString::number(i)); + m_samplePhaseRand[i]->saveSettings(doc, thissave, "samplePhaseRand_"+QString::number(i)); + m_sampleStart[i]->saveSettings(doc, thissave, "sampleStart_"+QString::number(i)); + m_sampleEnd[i]->saveSettings(doc, thissave, "sampleEnd_"+QString::number(i)); } } - for( int i = 0; i < maxFiltEnabled; ++i ) + for (int i = 0; i < m_maxFiltEnabled; ++i) { - if( filtEnabled[i]->value() ) + if (m_filtEnabled[i]->value()) { - filtInVol[i]->saveSettings( _doc, _this, "filtInVol_"+QString::number(i) ); - filtType[i]->saveSettings( _doc, _this, "filtType_"+QString::number(i) ); - filtSlope[i]->saveSettings( _doc, _this, "filtSlope_"+QString::number(i) ); - filtCutoff[i]->saveSettings( _doc, _this, "filtCutoff_"+QString::number(i) ); - filtReso[i]->saveSettings( _doc, _this, "filtReso_"+QString::number(i) ); - filtGain[i]->saveSettings( _doc, _this, "filtGain_"+QString::number(i) ); - filtSatu[i]->saveSettings( _doc, _this, "filtSatu_"+QString::number(i) ); - filtWetDry[i]->saveSettings( _doc, _this, "filtWetDry_"+QString::number(i) ); - filtBal[i]->saveSettings( _doc, _this, "filtBal_"+QString::number(i) ); - filtOutVol[i]->saveSettings( _doc, _this, "filtOutVol_"+QString::number(i) ); - filtEnabled[i]->saveSettings( _doc, _this, "filtEnabled_"+QString::number(i) ); - filtFeedback[i]->saveSettings( _doc, _this, "filtFeedback_"+QString::number(i) ); - filtDetune[i]->saveSettings( _doc, _this, "filtDetune_"+QString::number(i) ); - filtKeytracking[i]->saveSettings( _doc, _this, "filtKeytracking_"+QString::number(i) ); - filtMuted[i]->saveSettings( _doc, _this, "filtMuted_"+QString::number(i) ); + m_filtInVol[i]->saveSettings(doc, thissave, "filtInVol_"+QString::number(i)); + m_filtType[i]->saveSettings(doc, thissave, "filtType_"+QString::number(i)); + m_filtSlope[i]->saveSettings(doc, thissave, "filtSlope_"+QString::number(i)); + m_filtCutoff[i]->saveSettings(doc, thissave, "filtCutoff_"+QString::number(i)); + m_filtReso[i]->saveSettings(doc, thissave, "filtReso_"+QString::number(i)); + m_filtGain[i]->saveSettings(doc, thissave, "filtGain_"+QString::number(i)); + m_filtSatu[i]->saveSettings(doc, thissave, "filtSatu_"+QString::number(i)); + m_filtWetDry[i]->saveSettings(doc, thissave, "filtWetDry_"+QString::number(i)); + m_filtBal[i]->saveSettings(doc, thissave, "filtBal_"+QString::number(i)); + m_filtOutVol[i]->saveSettings(doc, thissave, "filtOutVol_"+QString::number(i)); + m_filtEnabled[i]->saveSettings(doc, thissave, "filtEnabled_"+QString::number(i)); + m_filtFeedback[i]->saveSettings(doc, thissave, "filtFeedback_"+QString::number(i)); + m_filtDetune[i]->saveSettings(doc, thissave, "filtDetune_"+QString::number(i)); + m_filtKeytracking[i]->saveSettings(doc, thissave, "filtKeytracking_"+QString::number(i)); + m_filtMuted[i]->saveSettings(doc, thissave, "filtMuted_"+QString::number(i)); } } - for( int i = 0; i < maxSubEnabled; ++i ) + for (int i = 0; i < m_maxSubEnabled; ++i) { - if( subEnabled[i]->value() ) + if (m_subEnabled[i]->value()) { - subEnabled[i]->saveSettings( _doc, _this, "subEnabled_"+QString::number(i) ); - subVol[i]->saveSettings( _doc, _this, "subVol_"+QString::number(i) ); - subPhase[i]->saveSettings( _doc, _this, "subPhase_"+QString::number(i) ); - subPhaseRand[i]->saveSettings( _doc, _this, "subPhaseRand_"+QString::number(i) ); - subDetune[i]->saveSettings( _doc, _this, "subDetune_"+QString::number(i) ); - subMuted[i]->saveSettings( _doc, _this, "subMuted_"+QString::number(i) ); - subKeytrack[i]->saveSettings( _doc, _this, "subKeytrack_"+QString::number(i) ); - subSampLen[i]->saveSettings( _doc, _this, "subSampLen_"+QString::number(i) ); - subNoise[i]->saveSettings( _doc, _this, "subNoise_"+QString::number(i) ); - subPanning[i]->saveSettings( _doc, _this, "subPanning_"+QString::number(i) ); - subTempo[i]->saveSettings( _doc, _this, "subTempo_"+QString::number(i) ); - subRateLimit[i]->saveSettings( _doc, _this, "subRateLimit_"+QString::number(i) ); - subUnisonNum[i]->saveSettings( _doc, _this, "subUnisonNum_"+QString::number(i) ); - subUnisonDetune[i]->saveSettings( _doc, _this, "subUnisonDetune_"+QString::number(i) ); - subInterpolate[i]->saveSettings( _doc, _this, "subInterpolate_"+QString::number(i) ); + m_subEnabled[i]->saveSettings(doc, thissave, "subEnabled_"+QString::number(i)); + m_subVol[i]->saveSettings(doc, thissave, "subVol_"+QString::number(i)); + m_subPhase[i]->saveSettings(doc, thissave, "subPhase_"+QString::number(i)); + m_subPhaseRand[i]->saveSettings(doc, thissave, "subPhaseRand_"+QString::number(i)); + m_subDetune[i]->saveSettings(doc, thissave, "subDetune_"+QString::number(i)); + m_subMuted[i]->saveSettings(doc, thissave, "subMuted_"+QString::number(i)); + m_subKeytrack[i]->saveSettings(doc, thissave, "subKeytrack_"+QString::number(i)); + m_subSampLen[i]->saveSettings(doc, thissave, "subSampLen_"+QString::number(i)); + m_subNoise[i]->saveSettings(doc, thissave, "subNoise_"+QString::number(i)); + m_subPanning[i]->saveSettings(doc, thissave, "subPanning_"+QString::number(i)); + m_subTempo[i]->saveSettings(doc, thissave, "subTempo_"+QString::number(i)); + m_subRateLimit[i]->saveSettings(doc, thissave, "subRateLimit_"+QString::number(i)); + m_subUnisonNum[i]->saveSettings(doc, thissave, "subUnisonNum_"+QString::number(i)); + m_subUnisonDetune[i]->saveSettings(doc, thissave, "subUnisonDetune_"+QString::number(i)); + m_subInterpolate[i]->saveSettings(doc, thissave, "subInterpolate_"+QString::number(i)); } } - for( int i = 0; i < maxModEnabled; ++i ) + for (int i = 0; i < m_maxModEnabled; ++i) { - if( modEnabled[i]->value() ) + if (m_modEnabled[i]->value()) { - modIn[i]->saveSettings( _doc, _this, "modIn_"+QString::number(i) ); - modInNum[i]->saveSettings( _doc, _this, "modInNu"+QString::number(i) ); - modInAmnt[i]->saveSettings( _doc, _this, "modInAmnt_"+QString::number(i) ); - modInCurve[i]->saveSettings( _doc, _this, "modInCurve_"+QString::number(i) ); - modIn2[i]->saveSettings( _doc, _this, "modIn2_"+QString::number(i) ); - modInNum2[i]->saveSettings( _doc, _this, "modInNum2_"+QString::number(i) ); - modInAmnt2[i]->saveSettings( _doc, _this, "modAmnt2_"+QString::number(i) ); - modInCurve2[i]->saveSettings( _doc, _this, "modCurve2_"+QString::number(i) ); - modOutSec[i]->saveSettings( _doc, _this, "modOutSec_"+QString::number(i) ); - modOutSig[i]->saveSettings( _doc, _this, "modOutSig_"+QString::number(i) ); - modOutSecNum[i]->saveSettings( _doc, _this, "modOutSecNu"+QString::number(i) ); - modEnabled[i]->saveSettings( _doc, _this, "modEnabled_"+QString::number(i) ); - modCombineType[i]->saveSettings( _doc, _this, "modCombineType_"+QString::number(i) ); - modType[i]->saveSettings( _doc, _this, "modType_"+QString::number(i) ); - modType2[i]->saveSettings( _doc, _this, "modType2_"+QString::number(i) ); + m_modIn[i]->saveSettings(doc, thissave, "modIn_"+QString::number(i)); + m_modInNum[i]->saveSettings(doc, thissave, "modInNu"+QString::number(i)); + m_modInAmnt[i]->saveSettings(doc, thissave, "modInAmnt_"+QString::number(i)); + m_modInCurve[i]->saveSettings(doc, thissave, "modInCurve_"+QString::number(i)); + m_modIn2[i]->saveSettings(doc, thissave, "modIn2_"+QString::number(i)); + m_modInNum2[i]->saveSettings(doc, thissave, "modInNum2_"+QString::number(i)); + m_modInAmnt2[i]->saveSettings(doc, thissave, "modAmnt2_"+QString::number(i)); + m_modInCurve2[i]->saveSettings(doc, thissave, "modCurve2_"+QString::number(i)); + m_modOutSec[i]->saveSettings(doc, thissave, "modOutSec_"+QString::number(i)); + m_modOutSig[i]->saveSettings(doc, thissave, "modOutSig_"+QString::number(i)); + m_modOutSecNum[i]->saveSettings(doc, thissave, "modOutSecNu"+QString::number(i)); + m_modEnabled[i]->saveSettings(doc, thissave, "modEnabled_"+QString::number(i)); + m_modCombineType[i]->saveSettings(doc, thissave, "modCombineType_"+QString::number(i)); + m_modType[i]->saveSettings(doc, thissave, "modType_"+QString::number(i)); + m_modType2[i]->saveSettings(doc, thissave, "modType2_"+QString::number(i)); } } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - macro[i]->saveSettings( _doc, _this, "macro_"+QString::number(i) ); - _this.setAttribute( "macroTooltips_"+QString::number(i), macroTooltips[i] ); - _this.setAttribute( "macroRed_"+QString::number(i), macroColors[i][0] ); - _this.setAttribute( "macroGreen_"+QString::number(i), macroColors[i][1] ); - _this.setAttribute( "macroBlue_"+QString::number(i), macroColors[i][2] ); + m_macro[i]->saveSettings(doc, thissave, "macro_"+QString::number(i)); + thissave.setAttribute("macroTooltips_"+QString::number(i), m_macroTooltips[i]); + thissave.setAttribute("macroRed_"+QString::number(i), m_macroColors[i][0]); + thissave.setAttribute("macroGreen_"+QString::number(i), m_macroColors[i][1]); + thissave.setAttribute("macroBlue_"+QString::number(i), m_macroColors[i][2]); } } -void Microwave::loadSettings( const QDomElement & _this ) +void Microwave::loadSettings(const QDomElement & thissave) { - QString microwaveVersion = _this.attribute( "version" ); + QString microwaveVersion = thissave.attribute("version"); - visvol.loadSettings( _this, "visualizervolume" ); - loadMode.loadSettings( _this, "loadingalgorithm" ); - loadChnl.loadSettings( _this, "loadingchannel" ); + m_visvol.loadSettings(thissave, "visualizer_volume"); + m_loadMode.loadSettings(thissave, "loadingalgorithm"); + m_loadChnl.loadSettings(thissave, "loadingchannel"); - oversample.loadSettings( _this, "oversample" ); - oversampleMode.loadSettings( _this, "oversamplemode" ); - removeDC.loadSettings( _this, "removeDC" ); + m_oversample.loadSettings(thissave, "oversample"); + m_oversampleMode.loadSettings(thissave, "oversamplemode"); + m_removeDC.loadSettings(thissave, "removeDC"); - graph.setLength( 2048 ); + m_graph.setLength(2048); - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - enabled[i]->loadSettings( _this, "enabled_"+QString::number(i) ); - if( enabled[i]->value() ) + m_enabled[i]->loadSettings(thissave, "enabled_"+QString::number(i)); + if (m_enabled[i]->value()) { - morph[i]->loadSettings( _this, "morph_"+QString::number(i) ); - range[i]->loadSettings( _this, "range_"+QString::number(i) ); - modify[i]->loadSettings( _this, "modify_"+QString::number(i) ); - modifyMode[i]->loadSettings( _this, "modifyMode_"+QString::number(i) ); - unisonVoices[i]->loadSettings( _this, "unisonVoices_"+QString::number(i) ); - unisonDetune[i]->loadSettings( _this, "unisonDetune_"+QString::number(i) ); - unisonMorph[i]->loadSettings( _this, "unisonMorph_"+QString::number(i) ); - unisonModify[i]->loadSettings( _this, "unisonModify_"+QString::number(i) ); - morphMax[i]->loadSettings( _this, "morphMax_"+QString::number(i) ); - detune[i]->loadSettings( _this, "detune_"+QString::number(i) ); - sampLen[i]->loadSettings( _this, "sampLen_"+QString::number(i) ); - phase[i]->loadSettings( _this, "phase_"+QString::number(i) ); - phaseRand[i]->loadSettings( _this, "phaseRand_"+QString::number(i) ); - vol[i]->loadSettings( _this, "vol_"+QString::number(i) ); - muted[i]->loadSettings( _this, "muted_"+QString::number(i) ); - pan[i]->loadSettings( _this, "pan_"+QString::number(i) ); - keytracking[i]->loadSettings( _this, "keytracking_"+QString::number(i) ); - tempo[i]->loadSettings( _this, "tempo_"+QString::number(i) ); - interpolate[i]->loadSettings( _this, "interpolate_"+QString::number(i) ); + m_morph[i]->loadSettings(thissave, "morph_"+QString::number(i)); + m_range[i]->loadSettings(thissave, "range_"+QString::number(i)); + m_modify[i]->loadSettings(thissave, "modify_"+QString::number(i)); + m_modifyMode[i]->loadSettings(thissave, "modifyMode_"+QString::number(i)); + m_unisonVoices[i]->loadSettings(thissave, "unisonVoices_"+QString::number(i)); + m_unisonDetune[i]->loadSettings(thissave, "unisonDetune_"+QString::number(i)); + m_unisonMorph[i]->loadSettings(thissave, "unisonMorph_"+QString::number(i)); + m_unisonModify[i]->loadSettings(thissave, "unisonModify_"+QString::number(i)); + m_morphMax[i]->loadSettings(thissave, "morphMax_"+QString::number(i)); + m_detune[i]->loadSettings(thissave, "detune_"+QString::number(i)); + m_sampLen[i]->loadSettings(thissave, "sampLen_"+QString::number(i)); + m_phase[i]->loadSettings(thissave, "phase_"+QString::number(i)); + m_phaseRand[i]->loadSettings(thissave, "phaseRand_"+QString::number(i)); + m_vol[i]->loadSettings(thissave, "vol_"+QString::number(i)); + m_muted[i]->loadSettings(thissave, "muted_"+QString::number(i)); + m_pan[i]->loadSettings(thissave, "pan_"+QString::number(i)); + m_keytracking[i]->loadSettings(thissave, "keytracking_"+QString::number(i)); + m_tempo[i]->loadSettings(thissave, "tempo_"+QString::number(i)); + m_interpolate[i]->loadSettings(thissave, "interpolate_"+QString::number(i)); } - filtEnabled[i]->loadSettings( _this, "filtEnabled_"+QString::number(i) ); - if( filtEnabled[i]->value() ) + m_filtEnabled[i]->loadSettings(thissave, "filtEnabled_"+QString::number(i)); + if (m_filtEnabled[i]->value()) { - filtInVol[i]->loadSettings( _this, "filtInVol_"+QString::number(i) ); - filtType[i]->loadSettings( _this, "filtType_"+QString::number(i) ); - filtSlope[i]->loadSettings( _this, "filtSlope_"+QString::number(i) ); - filtCutoff[i]->loadSettings( _this, "filtCutoff_"+QString::number(i) ); - filtReso[i]->loadSettings( _this, "filtReso_"+QString::number(i) ); - filtGain[i]->loadSettings( _this, "filtGain_"+QString::number(i) ); - filtSatu[i]->loadSettings( _this, "filtSatu_"+QString::number(i) ); - filtWetDry[i]->loadSettings( _this, "filtWetDry_"+QString::number(i) ); - filtBal[i]->loadSettings( _this, "filtBal_"+QString::number(i) ); - filtOutVol[i]->loadSettings( _this, "filtOutVol_"+QString::number(i) ); - filtFeedback[i]->loadSettings( _this, "filtFeedback_"+QString::number(i) ); - filtDetune[i]->loadSettings( _this, "filtDetune_"+QString::number(i) ); - filtKeytracking[i]->loadSettings( _this, "filtKeytracking_"+QString::number(i) ); - filtMuted[i]->loadSettings( _this, "filtMuted_"+QString::number(i) ); + m_filtInVol[i]->loadSettings(thissave, "filtInVol_"+QString::number(i)); + m_filtType[i]->loadSettings(thissave, "filtType_"+QString::number(i)); + m_filtSlope[i]->loadSettings(thissave, "filtSlope_"+QString::number(i)); + m_filtCutoff[i]->loadSettings(thissave, "filtCutoff_"+QString::number(i)); + m_filtReso[i]->loadSettings(thissave, "filtReso_"+QString::number(i)); + m_filtGain[i]->loadSettings(thissave, "filtGain_"+QString::number(i)); + m_filtSatu[i]->loadSettings(thissave, "filtSatu_"+QString::number(i)); + m_filtWetDry[i]->loadSettings(thissave, "filtWetDry_"+QString::number(i)); + m_filtBal[i]->loadSettings(thissave, "filtBal_"+QString::number(i)); + m_filtOutVol[i]->loadSettings(thissave, "filtOutVol_"+QString::number(i)); + m_filtFeedback[i]->loadSettings(thissave, "filtFeedback_"+QString::number(i)); + m_filtDetune[i]->loadSettings(thissave, "filtDetune_"+QString::number(i)); + m_filtKeytracking[i]->loadSettings(thissave, "filtKeytracking_"+QString::number(i)); + m_filtMuted[i]->loadSettings(thissave, "filtMuted_"+QString::number(i)); } - sampleEnabled[i]->loadSettings( _this, "sampleEnabled_"+QString::number(i) ); - if( sampleEnabled[i]->value() ) + m_sampleEnabled[i]->loadSettings(thissave, "sampleEnabled_"+QString::number(i)); + if (m_sampleEnabled[i]->value()) { - sampleGraphEnabled[i]->loadSettings( _this, "sampleGraphEnabled_"+QString::number(i) ); - sampleMuted[i]->loadSettings( _this, "sampleMuted_"+QString::number(i) ); - sampleKeytracking[i]->loadSettings( _this, "sampleKeytracking_"+QString::number(i) ); - sampleLoop[i]->loadSettings( _this, "sampleLoop_"+QString::number(i) ); - sampleVolume[i]->loadSettings( _this, "sampleVolume_"+QString::number(i) ); - samplePanning[i]->loadSettings( _this, "samplePanning_"+QString::number(i) ); - sampleDetune[i]->loadSettings( _this, "sampleDetune_"+QString::number(i) ); - samplePhase[i]->loadSettings( _this, "samplePhase_"+QString::number(i) ); - samplePhaseRand[i]->loadSettings( _this, "samplePhaseRand_"+QString::number(i) ); - sampleStart[i]->loadSettings( _this, "sampleStart_"+QString::number(i) ); - sampleEnd[i]->loadSettings( _this, "sampleEnd_"+QString::number(i) ); + m_sampleGraphEnabled[i]->loadSettings(thissave, "sampleGraphEnabled_"+QString::number(i)); + m_sampleMuted[i]->loadSettings(thissave, "sampleMuted_"+QString::number(i)); + m_sampleKeytracking[i]->loadSettings(thissave, "sampleKeytracking_"+QString::number(i)); + m_sampleLoop[i]->loadSettings(thissave, "sampleLoop_"+QString::number(i)); + m_sampleVolume[i]->loadSettings(thissave, "sampleVolume_"+QString::number(i)); + m_samplePanning[i]->loadSettings(thissave, "samplePanning_"+QString::number(i)); + m_sampleDetune[i]->loadSettings(thissave, "sampleDetune_"+QString::number(i)); + m_samplePhase[i]->loadSettings(thissave, "samplePhase_"+QString::number(i)); + m_samplePhaseRand[i]->loadSettings(thissave, "samplePhaseRand_"+QString::number(i)); + m_sampleStart[i]->loadSettings(thissave, "sampleStart_"+QString::number(i)); + m_sampleEnd[i]->loadSettings(thissave, "sampleEnd_"+QString::number(i)); } } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - macro[i]->loadSettings( _this, "macro_"+QString::number(i) ); + m_macro[i]->loadSettings(thissave, "macro_"+QString::number(i)); } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - subEnabled[i]->loadSettings( _this, "subEnabled_"+QString::number(i) ); - if( subEnabled[i]->value() ) + m_subEnabled[i]->loadSettings(thissave, "subEnabled_"+QString::number(i)); + if (m_subEnabled[i]->value()) { - subVol[i]->loadSettings( _this, "subVol_"+QString::number(i) ); - subPhase[i]->loadSettings( _this, "subPhase_"+QString::number(i) ); - subPhaseRand[i]->loadSettings( _this, "subPhaseRand_"+QString::number(i) ); - subDetune[i]->loadSettings( _this, "subDetune_"+QString::number(i) ); - subMuted[i]->loadSettings( _this, "subMuted_"+QString::number(i) ); - subKeytrack[i]->loadSettings( _this, "subKeytrack_"+QString::number(i) ); - subSampLen[i]->loadSettings( _this, "subSampLen_"+QString::number(i) ); - subNoise[i]->loadSettings( _this, "subNoise_"+QString::number(i) ); - subPanning[i]->loadSettings( _this, "subPanning_"+QString::number(i) ); - subTempo[i]->loadSettings( _this, "subTempo_"+QString::number(i) ); - subRateLimit[i]->loadSettings( _this, "subRateLimit_"+QString::number(i) ); - subUnisonNum[i]->loadSettings( _this, "subUnisonNum_"+QString::number(i) ); - subUnisonDetune[i]->loadSettings( _this, "subUnisonDetune_"+QString::number(i) ); - subInterpolate[i]->loadSettings( _this, "subInterpolate_"+QString::number(i) ); + m_subVol[i]->loadSettings(thissave, "subVol_"+QString::number(i)); + m_subPhase[i]->loadSettings(thissave, "subPhase_"+QString::number(i)); + m_subPhaseRand[i]->loadSettings(thissave, "subPhaseRand_"+QString::number(i)); + m_subDetune[i]->loadSettings(thissave, "subDetune_"+QString::number(i)); + m_subMuted[i]->loadSettings(thissave, "subMuted_"+QString::number(i)); + m_subKeytrack[i]->loadSettings(thissave, "subKeytrack_"+QString::number(i)); + m_subSampLen[i]->loadSettings(thissave, "subSampLen_"+QString::number(i)); + m_subNoise[i]->loadSettings(thissave, "subNoise_"+QString::number(i)); + m_subPanning[i]->loadSettings(thissave, "subPanning_"+QString::number(i)); + m_subTempo[i]->loadSettings(thissave, "subTempo_"+QString::number(i)); + m_subRateLimit[i]->loadSettings(thissave, "subRateLimit_"+QString::number(i)); + m_subUnisonNum[i]->loadSettings(thissave, "subUnisonNum_"+QString::number(i)); + m_subUnisonDetune[i]->loadSettings(thissave, "subUnisonDetune_"+QString::number(i)); + m_subInterpolate[i]->loadSettings(thissave, "subInterpolate_"+QString::number(i)); } - modEnabled[i]->loadSettings( _this, "modEnabled_"+QString::number(i) ); - if( modEnabled[i]->value() ) + m_modEnabled[i]->loadSettings(thissave, "modEnabled_"+QString::number(i)); + if (m_modEnabled[i]->value()) { - modIn[i]->loadSettings( _this, "modIn_"+QString::number(i) ); - modInNum[i]->loadSettings( _this, "modInNu"+QString::number(i) ); - modInAmnt[i]->loadSettings( _this, "modInAmnt_"+QString::number(i) ); - modInCurve[i]->loadSettings( _this, "modInCurve_"+QString::number(i) ); - modIn2[i]->loadSettings( _this, "modIn2_"+QString::number(i) ); - modInNum2[i]->loadSettings( _this, "modInNum2_"+QString::number(i) ); - modInAmnt2[i]->loadSettings( _this, "modAmnt2_"+QString::number(i) ); - modInCurve2[i]->loadSettings( _this, "modCurve2_"+QString::number(i) ); - modOutSec[i]->loadSettings( _this, "modOutSec_"+QString::number(i) ); - modOutSig[i]->loadSettings( _this, "modOutSig_"+QString::number(i) ); - modOutSecNum[i]->loadSettings( _this, "modOutSecNu"+QString::number(i) ); - modCombineType[i]->loadSettings( _this, "modCombineType_"+QString::number(i) ); - modType[i]->loadSettings( _this, "modType_"+QString::number(i) ); - modType2[i]->loadSettings( _this, "modType2_"+QString::number(i) ); + m_modIn[i]->loadSettings(thissave, "modIn_"+QString::number(i)); + m_modInNum[i]->loadSettings(thissave, "modInNu"+QString::number(i)); + m_modInAmnt[i]->loadSettings(thissave, "modInAmnt_"+QString::number(i)); + m_modInCurve[i]->loadSettings(thissave, "modInCurve_"+QString::number(i)); + m_modIn2[i]->loadSettings(thissave, "modIn2_"+QString::number(i)); + m_modInNum2[i]->loadSettings(thissave, "modInNum2_"+QString::number(i)); + m_modInAmnt2[i]->loadSettings(thissave, "modAmnt2_"+QString::number(i)); + m_modInCurve2[i]->loadSettings(thissave, "modCurve2_"+QString::number(i)); + m_modOutSec[i]->loadSettings(thissave, "modOutSec_"+QString::number(i)); + m_modOutSig[i]->loadSettings(thissave, "modOutSig_"+QString::number(i)); + m_modOutSecNum[i]->loadSettings(thissave, "modOutSecNu"+QString::number(i)); + m_modCombineType[i]->loadSettings(thissave, "modCombineType_"+QString::number(i)); + m_modType[i]->loadSettings(thissave, "modType_"+QString::number(i)); + m_modType2[i]->loadSettings(thissave, "modType2_"+QString::number(i)); } } @@ -771,272 +762,273 @@ void Microwave::loadSettings( const QDomElement & _this ) char * dst = 0; - for( int j = 0; j < 8; ++j ) + for (int j = 0; j < 8; ++j) { - if( enabled[j]->value() ) + if (m_enabled[j]->value()) { - base64::decode( _this.attribute( "waveforms"+QString::number(j) ), &dst, &size ); - for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + base64::decode(thissave.attribute("waveforms"+QString::number(j)), &dst, &size); + for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { - storedwaveforms[j][i] = ( (float*) dst )[i]; + m_storedwaveforms[j][i] = ((float*) dst)[i]; } } } - for( int j = 0; j < 64; ++j ) + for (int j = 0; j < 64; ++j) { - if( subEnabled[j]->value() ) + if (m_subEnabled[j]->value()) { - base64::decode( _this.attribute( "subs"+QString::number(j) ), &dst, &size ); - for( int i = 0; i < STOREDSUBWAVELEN; ++i ) + base64::decode(thissave.attribute("subs"+QString::number(j)), &dst, &size); + for (int i = 0; i < STOREDSUBWAVELEN; ++i) { - storedsubs[j][i] = ( (float*) dst )[i]; + m_storedsubs[j][i] = ((float*) dst)[i]; } } } - base64::decode( _this.attribute( "sampGraphs" ), &dst, &size ); - for( int i = 0; i < 1024; ++i ) + base64::decode(thissave.attribute("sampGraphs"), &dst, &size); + for (int i = 0; i < 1024; ++i) { - sampGraphs[i] = ( (float*) dst )[i]; + m_sampGraphs[i] = ((float*) dst)[i]; } - int sampleSizes[8] = {0}; - base64::decode( _this.attribute( "sampleSizes" ), &dst, &size ); - for( int i = 0; i < 8; ++i ) + int m_sampleSizes[8] = {0}; + base64::decode(thissave.attribute("sampleSizes"), &dst, &size); + for (int i = 0; i < 8; ++i) { - sampleSizes[i] = ( (int*) dst )[i]; + m_sampleSizes[i] = ((int*) dst)[i]; } - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( sampleEnabled[i]->value() ) + if (m_sampleEnabled[i]->value()) { - for( int j = 0; j < 2; ++j ) + for (int j = 0; j < 2; ++j) { - base64::decode( _this.attribute( "samples_"+QString::number(i)+"_"+QString::number(j) ), &dst, &size ); - for( int k = 0; k < sampleSizes[i]; ++k ) + base64::decode(thissave.attribute("samples_"+QString::number(i)+"_"+QString::number(j)), &dst, &size); + for (int k = 0; k < m_sampleSizes[i]; ++k) { - samples[i][j].push_back( ( (float*) dst )[k] ); + m_samples[i][j].push_back(((float*) dst)[k]); } } } } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - macroTooltips[i] = _this.attribute( "macroTooltips_"+QString::number(i) ); - macroColors[i][0] = _this.attribute( "macroRed_"+QString::number(i) ).toInt(); - macroColors[i][1] = _this.attribute( "macroGreen_"+QString::number(i) ).toInt(); - macroColors[i][2] = _this.attribute( "macroBlue_"+QString::number(i) ).toInt(); + m_macroTooltips[i] = thissave.attribute("macroTooltips_"+QString::number(i)); + m_macroColors[i][0] = thissave.attribute("macroRed_"+QString::number(i)).toInt(); + m_macroColors[i][1] = thissave.attribute("macroGreen_"+QString::number(i)).toInt(); + m_macroColors[i][2] = thissave.attribute("macroBlue_"+QString::number(i)).toInt(); } delete[] dst; // Interpolate all the wavetables and waveforms when loaded. - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( enabled[i]->value() ) + if (m_enabled[i]->value()) { - fillMainOsc(i, interpolate[i]->value()); + fillMainOsc(i, m_interpolate[i]->value()); } } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - if( subEnabled[i]->value() ) + if (m_subEnabled[i]->value()) { - fillSubOsc(i, subInterpolate[i]->value()); + fillSubOsc(i, m_subInterpolate[i]->value()); } } } -// When a knob is changed, send the new value to the array holding the knob values, as well as the note values within mSynths already initialized (notes already playing) -void Microwave::valueChanged( int which, int num ) +// When a knob is changed, send the new value to the array holding the knob values, +// as well as the note values within mSynths already initialized (notes already playing) +void Microwave::valueChanged(int which, int num) { //Send new values to array - switch( which ) + switch (which) { - case 1: morphArr[num] = morph[num]->value(); break; - case 2: rangeArr[num] = range[num]->value(); break; - case 3: modifyArr[num] = modify[num]->value(); break; - case 4: modifyModeArr[num] = modifyMode[num]->value(); break; - case 5: volArr[num] = vol[num]->value(); break; - case 6: panArr[num] = pan[num]->value(); break; - case 7: detuneArr[num] = detune[num]->value(); break; - case 8: phaseArr[num] = phase[num]->value(); break; - case 9: phaseRandArr[num] = phaseRand[num]->value(); break; - case 10: enabledArr[num] = enabled[num]->value(); break; - case 11: mutedArr[num] = muted[num]->value(); break; - case 12: sampLenArr[num] = sampLen[num]->value(); break; - case 13: morphMaxArr[num] = morphMax[num]->value(); break; - case 14: unisonVoicesArr[num] = unisonVoices[num]->value(); break; - case 15: unisonDetuneArr[num] = unisonDetune[num]->value(); break; - case 16: unisonMorphArr[num] = unisonMorph[num]->value(); break; - case 17: unisonModifyArr[num] = unisonModify[num]->value(); break; - case 18: keytrackingArr[num] = keytracking[num]->value(); break; - case 19: tempoArr[num] = tempo[num]->value(); break; - case 20: interpolateArr[num] = interpolate[num]->value(); break; - - case 30: subEnabledArr[num] = subEnabled[num]->value(); break; - case 31: subMutedArr[num] = subMuted[num]->value(); break; - case 32: subKeytrackArr[num] = subKeytrack[num]->value(); break; - case 33: subNoiseArr[num] = subNoise[num]->value(); break; - case 34: subVolArr[num] = subVol[num]->value(); break; - case 35: subPanningArr[num] = subPanning[num]->value(); break; - case 36: subDetuneArr[num] = subDetune[num]->value(); break; - case 37: subPhaseArr[num] = subPhase[num]->value(); break; - case 38: subPhaseRandArr[num] = subPhaseRand[num]->value(); break; - case 39: subSampLenArr[num] = subSampLen[num]->value(); break; - case 40: subTempoArr[num] = subTempo[num]->value(); break; - case 41: subRateLimitArr[num] = subRateLimit[num]->value(); break; - case 42: subUnisonNumArr[num] = subUnisonNum[num]->value(); break; - case 43: subUnisonDetuneArr[num] = subUnisonDetune[num]->value(); break; - case 44: subInterpolateArr[num] = subInterpolate[num]->value(); break; - - case 60: sampleEnabledArr[num] = sampleEnabled[num]->value(); break; - case 61: sampleMutedArr[num] = sampleMuted[num]->value(); break; - case 62: sampleKeytrackingArr[num] = sampleKeytracking[num]->value(); break; - case 63: sampleGraphEnabledArr[num] = sampleGraphEnabled[num]->value(); break; - case 64: sampleLoopArr[num] = sampleLoop[num]->value(); break; - case 65: sampleVolumeArr[num] = sampleVolume[num]->value(); break; - case 66: samplePanningArr[num] = samplePanning[num]->value(); break; - case 67: sampleDetuneArr[num] = sampleDetune[num]->value(); break; - case 68: samplePhaseArr[num] = samplePhase[num]->value(); break; - case 69: samplePhaseRandArr[num] = samplePhaseRand[num]->value(); break; - case 70: sampleStartArr[num] = sampleStart[num]->value(); break; - case 71: sampleEndArr[num] = sampleEnd[num]->value(); break; - - case 90: modInArr[num] = modIn[num]->value(); break; - case 91: modInNumArr[num] = modInNum[num]->value(); break; - case 92: modInAmntArr[num] = modInAmnt[num]->value(); break; - case 93: modInCurveArr[num] = modInCurve[num]->value(); break; - case 94: modIn2Arr[num] = modIn2[num]->value(); break; - case 95: modInNum2Arr[num] = modInNum2[num]->value(); break; - case 96: modInAmnt2Arr[num] = modInAmnt2[num]->value(); break; - case 97: modInCurve2Arr[num] = modInCurve2[num]->value(); break; - case 98: modOutSecArr[num] = modOutSec[num]->value(); break; - case 99: modOutSigArr[num] = modOutSig[num]->value(); break; - case 100: modOutSecNumArr[num] = modOutSecNum[num]->value(); break; - case 101: modEnabledArr[num] = modEnabled[num]->value(); break; - case 102: modCombineTypeArr[num] = modCombineType[num]->value(); break; - case 103: modTypeArr[num] = modType[num]->value(); break; - case 104: modType2Arr[num] = modType2[num]->value(); break; - - case 120: filtCutoffArr[num] = filtCutoff[num]->value(); break; - case 121: filtResoArr[num] = filtReso[num]->value(); break; - case 122: filtGainArr[num] = filtGain[num]->value(); break; - case 123: filtTypeArr[num] = filtType[num]->value(); break; - case 124: filtSlopeArr[num] = filtSlope[num]->value(); break; - case 125: filtInVolArr[num] = filtInVol[num]->value(); break; - case 126: filtOutVolArr[num] = filtOutVol[num]->value(); break; - case 127: filtWetDryArr[num] = filtWetDry[num]->value(); break; - case 128: filtBalArr[num] = filtBal[num]->value(); break; - case 129: filtSatuArr[num] = filtSatu[num]->value(); break; - case 130: filtFeedbackArr[num] = filtFeedback[num]->value(); break; - case 131: filtDetuneArr[num] = filtDetune[num]->value(); break; - case 132: filtEnabledArr[num] = filtEnabled[num]->value(); break; - case 133: filtMutedArr[num] = filtMuted[num]->value(); break; - case 134: filtKeytrackingArr[num] = filtKeytracking[num]->value(); break; - - case 150: macroArr[num] = macro[num]->value(); break; + case 1: m_morphArr[num] = m_morph[num]->value(); break; + case 2: m_rangeArr[num] = m_range[num]->value(); break; + case 3: m_modifyArr[num] = m_modify[num]->value(); break; + case 4: m_modifyModeArr[num] = m_modifyMode[num]->value(); break; + case 5: m_volArr[num] = m_vol[num]->value(); break; + case 6: m_panArr[num] = m_pan[num]->value(); break; + case 7: m_detuneArr[num] = m_detune[num]->value(); break; + case 8: m_phaseArr[num] = m_phase[num]->value(); break; + case 9: m_phaseRandArr[num] = m_phaseRand[num]->value(); break; + case 10: m_enabledArr[num] = m_enabled[num]->value(); break; + case 11: m_mutedArr[num] = m_muted[num]->value(); break; + case 12: m_sampLenArr[num] = m_sampLen[num]->value(); break; + case 13: m_morphMaxArr[num] = m_morphMax[num]->value(); break; + case 14: m_unisonVoicesArr[num] = m_unisonVoices[num]->value(); break; + case 15: m_unisonDetuneArr[num] = m_unisonDetune[num]->value(); break; + case 16: m_unisonMorphArr[num] = m_unisonMorph[num]->value(); break; + case 17: m_unisonModifyArr[num] = m_unisonModify[num]->value(); break; + case 18: m_keytrackingArr[num] = m_keytracking[num]->value(); break; + case 19: m_tempoArr[num] = m_tempo[num]->value(); break; + case 20: m_interpolateArr[num] = m_interpolate[num]->value(); break; + + case 30: m_subEnabledArr[num] = m_subEnabled[num]->value(); break; + case 31: m_subMutedArr[num] = m_subMuted[num]->value(); break; + case 32: m_subKeytrackArr[num] = m_subKeytrack[num]->value(); break; + case 33: m_subNoiseArr[num] = m_subNoise[num]->value(); break; + case 34: m_subVolArr[num] = m_subVol[num]->value(); break; + case 35: m_subPanningArr[num] = m_subPanning[num]->value(); break; + case 36: m_subDetuneArr[num] = m_subDetune[num]->value(); break; + case 37: m_subPhaseArr[num] = m_subPhase[num]->value(); break; + case 38: m_subPhaseRandArr[num] = m_subPhaseRand[num]->value(); break; + case 39: m_subSampLenArr[num] = m_subSampLen[num]->value(); break; + case 40: m_subTempoArr[num] = m_subTempo[num]->value(); break; + case 41: m_subRateLimitArr[num] = m_subRateLimit[num]->value(); break; + case 42: m_subUnisonNumArr[num] = m_subUnisonNum[num]->value(); break; + case 43: m_subUnisonDetuneArr[num] = m_subUnisonDetune[num]->value(); break; + case 44: m_subInterpolateArr[num] = m_subInterpolate[num]->value(); break; + + case 60: m_sampleEnabledArr[num] = m_sampleEnabled[num]->value(); break; + case 61: m_sampleMutedArr[num] = m_sampleMuted[num]->value(); break; + case 62: m_sampleKeytrackingArr[num] = m_sampleKeytracking[num]->value(); break; + case 63: m_sampleGraphEnabledArr[num] = m_sampleGraphEnabled[num]->value(); break; + case 64: m_sampleLoopArr[num] = m_sampleLoop[num]->value(); break; + case 65: m_sampleVolumeArr[num] = m_sampleVolume[num]->value(); break; + case 66: m_samplePanningArr[num] = m_samplePanning[num]->value(); break; + case 67: m_sampleDetuneArr[num] = m_sampleDetune[num]->value(); break; + case 68: m_samplePhaseArr[num] = m_samplePhase[num]->value(); break; + case 69: m_samplePhaseRandArr[num] = m_samplePhaseRand[num]->value(); break; + case 70: m_sampleStartArr[num] = m_sampleStart[num]->value(); break; + case 71: m_sampleEndArr[num] = m_sampleEnd[num]->value(); break; + + case 90: m_modInArr[num] = m_modIn[num]->value(); break; + case 91: m_modInNumArr[num] = m_modInNum[num]->value(); break; + case 92: m_modInAmntArr[num] = m_modInAmnt[num]->value(); break; + case 93: m_modInCurveArr[num] = m_modInCurve[num]->value(); break; + case 94: m_modIn2Arr[num] = m_modIn2[num]->value(); break; + case 95: m_modInNum2Arr[num] = m_modInNum2[num]->value(); break; + case 96: m_modInAmnt2Arr[num] = m_modInAmnt2[num]->value(); break; + case 97: m_modInCurve2Arr[num] = m_modInCurve2[num]->value(); break; + case 98: m_modOutSecArr[num] = m_modOutSec[num]->value(); break; + case 99: m_modOutSigArr[num] = m_modOutSig[num]->value(); break; + case 100: m_modOutSecNumArr[num] = m_modOutSecNum[num]->value(); break; + case 101: m_modEnabledArr[num] = m_modEnabled[num]->value(); break; + case 102: m_modCombineTypeArr[num] = m_modCombineType[num]->value(); break; + case 103: m_modTypeArr[num] = m_modType[num]->value(); break; + case 104: m_modType2Arr[num] = m_modType2[num]->value(); break; + + case 120: m_filtCutoffArr[num] = m_filtCutoff[num]->value(); break; + case 121: m_filtResoArr[num] = m_filtReso[num]->value(); break; + case 122: m_filtGainArr[num] = m_filtGain[num]->value(); break; + case 123: m_filtTypeArr[num] = m_filtType[num]->value(); break; + case 124: m_filtSlopeArr[num] = m_filtSlope[num]->value(); break; + case 125: m_filtInVolArr[num] = m_filtInVol[num]->value(); break; + case 126: m_filtOutVolArr[num] = m_filtOutVol[num]->value(); break; + case 127: m_filtWetDryArr[num] = m_filtWetDry[num]->value(); break; + case 128: m_filtBalArr[num] = m_filtBal[num]->value(); break; + case 129: m_filtSatuArr[num] = m_filtSatu[num]->value(); break; + case 130: m_filtFeedbackArr[num] = m_filtFeedback[num]->value(); break; + case 131: m_filtDetuneArr[num] = m_filtDetune[num]->value(); break; + case 132: m_filtEnabledArr[num] = m_filtEnabled[num]->value(); break; + case 133: m_filtMutedArr[num] = m_filtMuted[num]->value(); break; + case 134: m_filtKeytrackingArr[num] = m_filtKeytracking[num]->value(); break; + + case 150: m_macroArr[num] = m_macro[num]->value(); break; } - nphList = NotePlayHandle::nphsOfInstrumentTrack( microwaveTrack, true ); + m_nphList = NotePlayHandle::nphsOfInstrumentTrack(m_microwaveTrack, true); - for( int i = 0; i < nphList.length(); ++i ) + for (int i = 0; i < m_nphList.length(); ++i) { - mSynth * ps = static_cast( nphList[i]->m_pluginData ); + mSynth * ps = static_cast(m_nphList[i]->m_pluginData); - if( ps )// Makes sure "ps" isn't assigned a null value, if m_pluginData hasn't been created yet. + if (ps)// Makes sure "ps" isn't assigned a null value, if m_pluginData hasn't been created yet. { //Send new knob values to notes already playing - switch( which ) + switch (which) { - case 1: ps->morph[num] = morph[num]->value(); break; - case 2: ps->range[num] = range[num]->value(); break; - case 3: ps->modify[num] = modify[num]->value(); break; - case 4: ps->modifyMode[num] = modifyMode[num]->value(); break; - case 5: ps->vol[num] = vol[num]->value(); break; - case 6: ps->pan[num] = pan[num]->value(); break; - case 7: ps->detune[num] = detune[num]->value(); break; - case 8: ps->phase[num] = phase[num]->value(); break; - case 9: ps->phaseRand[num] = phaseRand[num]->value(); break; - case 10: ps->enabled[num] = enabled[num]->value(); break; - case 11: ps->muted[num] = muted[num]->value(); break; - case 12: ps->sampLen[num] = sampLen[num]->value(); break; - case 13: ps->morphMax[num] = morphMax[num]->value(); break; - case 14: ps->unisonVoices[num] = unisonVoices[num]->value(); break; - case 15: ps->unisonDetune[num] = unisonDetune[num]->value(); break; - case 16: ps->unisonMorph[num] = unisonMorph[num]->value(); break; - case 17: ps->unisonModify[num] = unisonModify[num]->value(); break; - case 18: ps->keytracking[num] = keytracking[num]->value(); break; - case 19: ps->tempo[num] = tempo[num]->value(); break; - - case 30: ps->subEnabled[num] = subEnabled[num]->value(); break; - case 31: ps->subMuted[num] = subMuted[num]->value(); break; - case 32: ps->subKeytrack[num] = subKeytrack[num]->value(); break; - case 33: ps->subNoise[num] = subNoise[num]->value(); break; - case 34: ps->subVol[num] = subVol[num]->value(); break; - case 35: ps->subPanning[num] = subPanning[num]->value(); break; - case 36: ps->subDetune[num] = subDetune[num]->value(); break; - case 37: ps->subPhase[num] = subPhase[num]->value(); break; - case 38: ps->subPhaseRand[num] = subPhaseRand[num]->value(); break; - case 39: ps->subSampLen[num] = subSampLen[num]->value(); break; - case 40: ps->subTempo[num] = subTempo[num]->value(); break; - case 41: ps->subRateLimit[num] = subRateLimit[num]->value(); break; - case 42: ps->subUnisonNum[num] = subUnisonNum[num]->value(); break; - case 43: ps->subUnisonDetune[num] = subUnisonDetune[num]->value(); break; - case 44: ps->subInterpolate[num] = subInterpolate[num]->value(); break; - - case 60: ps->sampleEnabled[num] = sampleEnabled[num]->value(); break; - case 61: ps->sampleMuted[num] = sampleMuted[num]->value(); break; - case 62: ps->sampleKeytracking[num] = sampleKeytracking[num]->value(); break; - case 63: ps->sampleGraphEnabled[num] = sampleGraphEnabled[num]->value(); break; - case 64: ps->sampleLoop[num] = sampleLoop[num]->value(); break; - case 65: ps->sampleVolume[num] = sampleVolume[num]->value(); break; - case 66: ps->samplePanning[num] = samplePanning[num]->value(); break; - case 67: ps->sampleDetune[num] = sampleDetune[num]->value(); break; - case 68: ps->samplePhase[num] = samplePhase[num]->value(); break; - case 69: ps->samplePhaseRand[num] = samplePhaseRand[num]->value(); break; - case 70: ps->sampleStart[num] = sampleStart[num]->value(); break; - case 71: ps->sampleEnd[num] = sampleEnd[num]->value(); break; - - case 90: ps->modIn[num] = modIn[num]->value(); break; - case 91: ps->modInNum[num] = modInNum[num]->value(); break; - case 92: ps->modInAmnt[num] = modInAmnt[num]->value(); break; - case 93: ps->modInCurve[num] = modInCurve[num]->value(); break; - case 94: ps->modIn2[num] = modIn2[num]->value(); break; - case 95: ps->modInNum2[num] = modInNum2[num]->value(); break; - case 96: ps->modInAmnt2[num] = modInAmnt2[num]->value(); break; - case 97: ps->modInCurve2[num] = modInCurve2[num]->value(); break; - case 98: ps->modOutSec[num] = modOutSec[num]->value(); break; - case 99: ps->modOutSig[num] = modOutSig[num]->value(); break; - case 100: ps->modOutSecNum[num] = modOutSecNum[num]->value(); break; - case 101: ps->modEnabled[num] = modEnabled[num]->value(); break; - case 102: ps->modCombineType[num] = modCombineType[num]->value(); break; - case 103: ps->modType[num] = modType[num]->value(); break; - case 104: ps->modType2[num] = modType2[num]->value(); break; - - case 120: ps->filtCutoff[num] = filtCutoff[num]->value(); break; - case 121: ps->filtReso[num] = filtReso[num]->value(); break; - case 122: ps->filtGain[num] = filtGain[num]->value(); break; - case 123: ps->filtType[num] = filtType[num]->value(); break; - case 124: ps->filtSlope[num] = filtSlope[num]->value(); break; - case 125: ps->filtInVol[num] = filtInVol[num]->value(); break; - case 126: ps->filtOutVol[num] = filtOutVol[num]->value(); break; - case 127: ps->filtWetDry[num] = filtWetDry[num]->value(); break; - case 128: ps->filtBal[num] = filtBal[num]->value(); break; - case 129: ps->filtSatu[num] = filtSatu[num]->value(); break; - case 130: ps->filtFeedback[num] = filtFeedback[num]->value(); break; - case 131: ps->filtDetune[num] = filtDetune[num]->value(); break; - case 132: ps->filtEnabled[num] = filtEnabled[num]->value(); break; - case 133: ps->filtMuted[num] = filtMuted[num]->value(); break; - case 134: ps->filtKeytracking[num] = filtKeytracking[num]->value(); break; - - case 150: ps->macro[num] = macro[num]->value(); break; + case 1: ps->m_morph[num] = m_morph[num]->value(); break; + case 2: ps->m_range[num] = m_range[num]->value(); break; + case 3: ps->m_modify[num] = m_modify[num]->value(); break; + case 4: ps->m_modifyMode[num] = m_modifyMode[num]->value(); break; + case 5: ps->m_vol[num] = m_vol[num]->value(); break; + case 6: ps->m_pan[num] = m_pan[num]->value(); break; + case 7: ps->m_detune[num] = m_detune[num]->value(); break; + case 8: ps->m_phase[num] = m_phase[num]->value(); break; + case 9: ps->m_phaseRand[num] = m_phaseRand[num]->value(); break; + case 10: ps->m_enabled[num] = m_enabled[num]->value(); break; + case 11: ps->m_muted[num] = m_muted[num]->value(); break; + case 12: ps->m_sampLen[num] = m_sampLen[num]->value(); break; + case 13: ps->m_morphMax[num] = m_morphMax[num]->value(); break; + case 14: ps->m_unisonVoices[num] = m_unisonVoices[num]->value(); break; + case 15: ps->m_unisonDetune[num] = m_unisonDetune[num]->value(); break; + case 16: ps->m_unisonMorph[num] = m_unisonMorph[num]->value(); break; + case 17: ps->m_unisonModify[num] = m_unisonModify[num]->value(); break; + case 18: ps->m_keytracking[num] = m_keytracking[num]->value(); break; + case 19: ps->m_tempo[num] = m_tempo[num]->value(); break; + + case 30: ps->m_subEnabled[num] = m_subEnabled[num]->value(); break; + case 31: ps->m_subMuted[num] = m_subMuted[num]->value(); break; + case 32: ps->m_subKeytrack[num] = m_subKeytrack[num]->value(); break; + case 33: ps->m_subNoise[num] = m_subNoise[num]->value(); break; + case 34: ps->m_subVol[num] = m_subVol[num]->value(); break; + case 35: ps->m_subPanning[num] = m_subPanning[num]->value(); break; + case 36: ps->m_subDetune[num] = m_subDetune[num]->value(); break; + case 37: ps->m_subPhase[num] = m_subPhase[num]->value(); break; + case 38: ps->m_subPhaseRand[num] = m_subPhaseRand[num]->value(); break; + case 39: ps->m_subSampLen[num] = m_subSampLen[num]->value(); break; + case 40: ps->m_subTempo[num] = m_subTempo[num]->value(); break; + case 41: ps->m_subRateLimit[num] = m_subRateLimit[num]->value(); break; + case 42: ps->m_subUnisonNum[num] = m_subUnisonNum[num]->value(); break; + case 43: ps->m_subUnisonDetune[num] = m_subUnisonDetune[num]->value(); break; + case 44: ps->m_subInterpolate[num] = m_subInterpolate[num]->value(); break; + + case 60: ps->m_sampleEnabled[num] = m_sampleEnabled[num]->value(); break; + case 61: ps->m_sampleMuted[num] = m_sampleMuted[num]->value(); break; + case 62: ps->m_sampleKeytracking[num] = m_sampleKeytracking[num]->value(); break; + case 63: ps->m_sampleGraphEnabled[num] = m_sampleGraphEnabled[num]->value(); break; + case 64: ps->m_sampleLoop[num] = m_sampleLoop[num]->value(); break; + case 65: ps->m_sampleVolume[num] = m_sampleVolume[num]->value(); break; + case 66: ps->m_samplePanning[num] = m_samplePanning[num]->value(); break; + case 67: ps->m_sampleDetune[num] = m_sampleDetune[num]->value(); break; + case 68: ps->m_samplePhase[num] = m_samplePhase[num]->value(); break; + case 69: ps->m_samplePhaseRand[num] = m_samplePhaseRand[num]->value(); break; + case 70: ps->m_sampleStart[num] = m_sampleStart[num]->value(); break; + case 71: ps->m_sampleEnd[num] = m_sampleEnd[num]->value(); break; + + case 90: ps->m_modIn[num] = m_modIn[num]->value(); break; + case 91: ps->m_modInNum[num] = m_modInNum[num]->value(); break; + case 92: ps->m_modInAmnt[num] = m_modInAmnt[num]->value(); break; + case 93: ps->m_modInCurve[num] = m_modInCurve[num]->value(); break; + case 94: ps->m_modIn2[num] = m_modIn2[num]->value(); break; + case 95: ps->m_modInNum2[num] = m_modInNum2[num]->value(); break; + case 96: ps->m_modInAmnt2[num] = m_modInAmnt2[num]->value(); break; + case 97: ps->m_modInCurve2[num] = m_modInCurve2[num]->value(); break; + case 98: ps->m_modOutSec[num] = m_modOutSec[num]->value(); break; + case 99: ps->m_modOutSig[num] = m_modOutSig[num]->value(); break; + case 100: ps->m_modOutSecNum[num] = m_modOutSecNum[num]->value(); break; + case 101: ps->m_modEnabled[num] = m_modEnabled[num]->value(); break; + case 102: ps->m_modCombineType[num] = m_modCombineType[num]->value(); break; + case 103: ps->m_modType[num] = m_modType[num]->value(); break; + case 104: ps->m_modType2[num] = m_modType2[num]->value(); break; + + case 120: ps->m_filtCutoff[num] = m_filtCutoff[num]->value(); break; + case 121: ps->m_filtReso[num] = m_filtReso[num]->value(); break; + case 122: ps->m_filtGain[num] = m_filtGain[num]->value(); break; + case 123: ps->m_filtType[num] = m_filtType[num]->value(); break; + case 124: ps->m_filtSlope[num] = m_filtSlope[num]->value(); break; + case 125: ps->m_filtInVol[num] = m_filtInVol[num]->value(); break; + case 126: ps->m_filtOutVol[num] = m_filtOutVol[num]->value(); break; + case 127: ps->m_filtWetDry[num] = m_filtWetDry[num]->value(); break; + case 128: ps->m_filtBal[num] = m_filtBal[num]->value(); break; + case 129: ps->m_filtSatu[num] = m_filtSatu[num]->value(); break; + case 130: ps->m_filtFeedback[num] = m_filtFeedback[num]->value(); break; + case 131: ps->m_filtDetune[num] = m_filtDetune[num]->value(); break; + case 132: ps->m_filtEnabled[num] = m_filtEnabled[num]->value(); break; + case 133: ps->m_filtMuted[num] = m_filtMuted[num]->value(); break; + case 134: ps->m_filtKeytracking[num] = m_filtKeytracking[num]->value(); break; + + case 150: ps->m_macro[num] = m_macro[num]->value(); break; } } } @@ -1044,115 +1036,115 @@ void Microwave::valueChanged( int which, int num ) // Set the range of Morph based on Morph Max -void Microwave::morphMaxChanged( int i ) +void Microwave::morphMaxChanged(int i) { - morph[i]->setRange( morph[i]->minValue(), morphMax[i]->value(), morph[i]->step() ); - unisonMorph[i]->setRange( unisonMorph[i]->minValue(), morphMax[i]->value(), unisonMorph[i]->step() ); + m_morph[i]->setRange(m_morph[i]->minValue(), m_morphMax[i]->value(), m_morph[i]->step()); + m_unisonMorph[i]->setRange(m_unisonMorph[i]->minValue(), m_morphMax[i]->value(), m_unisonMorph[i]->step()); } // Set the range of morphMax and Modify based on new sample length -void Microwave::sampLenChanged( int i ) +void Microwave::sampLenChanged(int i) { - morphMax[i]->setRange( morphMax[i]->minValue(), STOREDMAINARRAYLEN / sampLen[i]->value() - 2, morphMax[i]->step() ); - modify[i]->setRange( modify[i]->minValue(), sampLen[i]->value() - 1, modify[i]->step() ); - unisonModify[i]->setRange( unisonModify[i]->minValue(), sampLen[i]->value() - 1, unisonModify[i]->step() ); + m_morphMax[i]->setRange(m_morphMax[i]->minValue(), STOREDMAINARRAYLEN / m_sampLen[i]->value() - 2, m_morphMax[i]->step()); + m_modify[i]->setRange(m_modify[i]->minValue(), m_sampLen[i]->value() - 1, m_modify[i]->step()); + m_unisonModify[i]->setRange(m_unisonModify[i]->minValue(), m_sampLen[i]->value() - 1, m_unisonModify[i]->step()); } -//Change graph length to sample length -void Microwave::subSampLenChanged( int num ) +//Change m_graph length to sample length +void Microwave::subSampLenChanged(int num) { - if( scroll == 1 && subNum.value() == num + 1 ) + if (m_scroll == 1 && m_subNum.value() == num + 1) { - graph.setLength( subSampLen[num]->value() ); + m_graph.setLength(m_subSampLen[num]->value()); } } //Stores the highest enabled main oscillator. Helps with CPU benefit, refer to its use in mSynth::nextStringSample -void Microwave::mainEnabledChanged( int num ) +void Microwave::mainEnabledChanged(int num) { - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( enabled[i]->value() ) + if (m_enabled[i]->value()) { - maxMainEnabled = i + 1; + m_maxMainEnabled = i + 1; } } } //Stores the highest enabled sub oscillator. Helps with major CPU benefit, refer to its use in mSynth::nextStringSample -void Microwave::subEnabledChanged( int num ) +void Microwave::subEnabledChanged(int num) { - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - if( subEnabled[i]->value() ) + if (m_subEnabled[i]->value()) { - maxSubEnabled = i + 1; + m_maxSubEnabled = i + 1; } } } //Stores the highest enabled sample. Helps with CPU benefit, refer to its use in mSynth::nextStringSample -void Microwave::sampleEnabledChanged( int num ) +void Microwave::sampleEnabledChanged(int num) { - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( sampleEnabled[i]->value() ) + if (m_sampleEnabled[i]->value()) { - maxSampleEnabled = i + 1; + m_maxSampleEnabled = i + 1; } } } //Stores the highest enabled mod section. Helps with major CPU benefit, refer to its use in mSynth::nextStringSample -void Microwave::modEnabledChanged( int num ) +void Microwave::modEnabledChanged(int num) { - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - if( modEnabled[i]->value() ) + if (m_modEnabled[i]->value()) { - maxModEnabled = i + 1; + m_maxModEnabled = i + 1; } } } //Stores the highest enabled filter section. Helps with CPU benefit, refer to its use in mSynth::nextStringSample -void Microwave::filtEnabledChanged( int num ) +void Microwave::filtEnabledChanged(int num) { - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( filtEnabled[i]->value() ) + if (m_filtEnabled[i]->value()) { - maxFiltEnabled = i + 1; + m_maxFiltEnabled = i + 1; } } } //Updates sub oscillator inteprolation when the interpolation LED is changed. -void Microwave::interpolateChanged( int num ) +void Microwave::interpolateChanged(int num) { - fillMainOsc( num, interpolate[num]->value() ); + fillMainOsc(num, m_interpolate[num]->value()); } //Updates sub oscillator inteprolation when the interpolation LED is changed. -void Microwave::subInterpolateChanged( int num ) +void Microwave::subInterpolateChanged(int num) { - fillSubOsc( num, subInterpolate[num]->value() ); + fillSubOsc(num, m_subInterpolate[num]->value()); } //When user drawn on graph, send new values to the correct arrays -void Microwave::samplesChanged( int _begin, int _end ) +void Microwave::samplesChanged(int begin, int end) { - switch( (int)scroll ) + switch ((int)m_scroll) { case 0: { @@ -1160,32 +1152,32 @@ void Microwave::samplesChanged( int _begin, int _end ) } case 1: { - for( int i = _begin; i <= _end; ++i ) + for (int i = begin; i <= end; ++i) { - storedsubs[subNum.value()-1][i] = graph.samples()[i]; - for( int j = 0; j < WAVERATIO; ++j ) + m_storedsubs[m_subNum.value()-1][i] = m_graph.samples()[i]; + for (int j = 0; j < WAVERATIO; ++j) { // Puts low-quality samples into there so one can change the waveform mid-note. The quality boost will occur at another time. // It cannot do the interpolation here because it causes lag. - subs[subNum.value()-1][i*WAVERATIO+j] = graph.samples()[i]; + m_subs[m_subNum.value()-1][i*WAVERATIO+j] = m_graph.samples()[i]; } } - subFilled[subNum.value()-1] = false;// Make sure the waveform is interpolated later on. + m_subFilled[m_subNum.value()-1] = false;// Make sure the waveform is interpolated later on. - // If the entire graph was changed all at once, we can assume it isn't from the user drawing on the graph, + // If the entire graph was changed all at once, we can assume it isn't from the user drawing on the m_graph, // so we can interpolate the oscillator without worrying about lag. - if( _begin == 0 && _end == STOREDSUBWAVELEN - 1 ) + if (begin == 0 && end == STOREDSUBWAVELEN - 1) { - fillSubOsc(subNum.value()-1, subInterpolate[subNum.value()-1]->value()); + fillSubOsc(m_subNum.value()-1, m_subInterpolate[m_subNum.value()-1]->value()); } break; } case 2: { - for( int i = _begin; i <= _end; ++i ) + for (int i = begin; i <= end; ++i) { - sampGraphs[i + ( (sampNum.value()-1) * 128 )] = graph.samples()[i]; + m_sampGraphs[i + ((m_sampNum.value()-1) * 128)] = m_graph.samples()[i]; } break; } @@ -1193,125 +1185,128 @@ void Microwave::samplesChanged( int _begin, int _end ) } -void Microwave::switchMatrixSections( int source, int destination ) +void Microwave::switchMatrixSections(int source, int destination) { - int modInTemp = modInArr[destination]; - int modInNumTemp = modInNumArr[destination]; - float modInAmntTemp = modInAmntArr[destination]; - float modInCurveTemp = modInCurveArr[destination]; - int modIn2Temp = modIn2Arr[destination]; - int modInNum2Temp = modInNum2Arr[destination]; - float modInAmnt2Temp = modInAmnt2Arr[destination]; - float modInCurve2Temp = modInCurve2Arr[destination]; - int modOutSecTemp = modOutSecArr[destination]; - int modOutSigTemp = modOutSigArr[destination]; - int modOutSecNumTemp = modOutSecNumArr[destination]; - bool modEnabledTemp = modEnabledArr[destination]; - int modCombineTypeTemp = modCombineTypeArr[destination]; - bool modTypeTemp = modTypeArr[destination]; - bool modType2Temp = modType2Arr[destination]; - - modIn[destination]->setValue( modInArr[source] ); - modInNum[destination]->setValue( modInNumArr[source] ); - modInAmnt[destination]->setValue( modInAmntArr[source] ); - modInCurve[destination]->setValue( modInCurveArr[source] ); - modIn2[destination]->setValue( modIn2Arr[source] ); - modInNum2[destination]->setValue( modInNum2Arr[source] ); - modInAmnt2[destination]->setValue( modInAmnt2Arr[source] ); - modInCurve2[destination]->setValue( modInCurve2Arr[source] ); - modOutSec[destination]->setValue( modOutSecArr[source] ); - modOutSig[destination]->setValue( modOutSigArr[source] ); - modOutSecNum[destination]->setValue( modOutSecNumArr[source] ); - modEnabled[destination]->setValue( modEnabledArr[source] ); - modCombineType[destination]->setValue( modCombineTypeArr[source] ); - modType[destination]->setValue( modTypeArr[source] ); - modType2[destination]->setValue( modType2Arr[source] ); - - modIn[source]->setValue( modInTemp ); - modInNum[source]->setValue( modInNumTemp ); - modInAmnt[source]->setValue( modInAmntTemp ); - modInCurve[source]->setValue( modInCurveTemp ); - modIn2[source]->setValue( modIn2Temp ); - modInNum2[source]->setValue( modInNum2Temp ); - modInAmnt2[source]->setValue( modInAmnt2Temp ); - modInCurve2[source]->setValue( modInCurve2Temp ); - modOutSec[source]->setValue( modOutSecTemp ); - modOutSig[source]->setValue( modOutSigTemp ); - modOutSecNum[source]->setValue( modOutSecNumTemp ); - modEnabled[source]->setValue( modEnabledTemp ); - modCombineType[source]->setValue( modCombineTypeTemp ); - modType[source]->setValue( modTypeTemp ); - modType2[source]->setValue( modType2Temp ); - - // If something is sent to a matrix box and the matrix box is moved, we want to make sure it's still attached to the same box after it is moved. - for( int i = 0; i < 64; ++i ) + int m_modInTemp = m_modInArr[destination]; + int m_modInNumTemp = m_modInNumArr[destination]; + float m_modInAmntTemp = m_modInAmntArr[destination]; + float m_modInCurveTemp = m_modInCurveArr[destination]; + int m_modIn2Temp = m_modIn2Arr[destination]; + int m_modInNum2Temp = m_modInNum2Arr[destination]; + float m_modInAmnt2Temp = m_modInAmnt2Arr[destination]; + float m_modInCurve2Temp = m_modInCurve2Arr[destination]; + int m_modOutSecTemp = m_modOutSecArr[destination]; + int m_modOutSigTemp = m_modOutSigArr[destination]; + int m_modOutSecNumTemp = m_modOutSecNumArr[destination]; + bool m_modEnabledTemp = m_modEnabledArr[destination]; + int m_modCombineTypeTemp = m_modCombineTypeArr[destination]; + bool m_modTypeTemp = m_modTypeArr[destination]; + bool m_modType2Temp = m_modType2Arr[destination]; + + m_modIn[destination]->setValue(m_modInArr[source]); + m_modInNum[destination]->setValue(m_modInNumArr[source]); + m_modInAmnt[destination]->setValue(m_modInAmntArr[source]); + m_modInCurve[destination]->setValue(m_modInCurveArr[source]); + m_modIn2[destination]->setValue(m_modIn2Arr[source]); + m_modInNum2[destination]->setValue(m_modInNum2Arr[source]); + m_modInAmnt2[destination]->setValue(m_modInAmnt2Arr[source]); + m_modInCurve2[destination]->setValue(m_modInCurve2Arr[source]); + m_modOutSec[destination]->setValue(m_modOutSecArr[source]); + m_modOutSig[destination]->setValue(m_modOutSigArr[source]); + m_modOutSecNum[destination]->setValue(m_modOutSecNumArr[source]); + m_modEnabled[destination]->setValue(m_modEnabledArr[source]); + m_modCombineType[destination]->setValue(m_modCombineTypeArr[source]); + m_modType[destination]->setValue(m_modTypeArr[source]); + m_modType2[destination]->setValue(m_modType2Arr[source]); + + m_modIn[source]->setValue(m_modInTemp); + m_modInNum[source]->setValue(m_modInNumTemp); + m_modInAmnt[source]->setValue(m_modInAmntTemp); + m_modInCurve[source]->setValue(m_modInCurveTemp); + m_modIn2[source]->setValue(m_modIn2Temp); + m_modInNum2[source]->setValue(m_modInNum2Temp); + m_modInAmnt2[source]->setValue(m_modInAmnt2Temp); + m_modInCurve2[source]->setValue(m_modInCurve2Temp); + m_modOutSec[source]->setValue(m_modOutSecTemp); + m_modOutSig[source]->setValue(m_modOutSigTemp); + m_modOutSecNum[source]->setValue(m_modOutSecNumTemp); + m_modEnabled[source]->setValue(m_modEnabledTemp); + m_modCombineType[source]->setValue(m_modCombineTypeTemp); + m_modType[source]->setValue(m_modTypeTemp); + m_modType2[source]->setValue(m_modType2Temp); + + // If something is sent to a matrix box and the matrix box is moved, + // we want to make sure it's still attached to the same box after it is moved. + for (int i = 0; i < 64; ++i) { - if( modOutSec[i]->value() == 4 )// Output is being sent to Matrix + if (m_modOutSec[i]->value() == 4)// Output is being sent to Matrix { - if( modOutSecNum[i]->value() - 1 == source )// Output was being sent a matrix box that was moved + if (m_modOutSecNum[i]->value() - 1 == source)// Output was being sent a matrix box that was moved { - modOutSecNum[i]->setValue( destination + 1 ); + m_modOutSecNum[i]->setValue(destination + 1); } - else if( modOutSecNum[i]->value() - 1 == destination )// Output was being sent a matrix box that was moved + else if (m_modOutSecNum[i]->value() - 1 == destination)// Output was being sent a matrix box that was moved { - modOutSecNum[i]->setValue( source + 1 ); + m_modOutSecNum[i]->setValue(source + 1); } } } } -// For when notes are playing. This initializes a new mSynth if the note is new. It also uses mSynth::nextStringSample to get the synthesizer output. This is where oversampling and the visualizer are handled. -void Microwave::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) +// For when notes are playing. This initializes a new mSynth if the note is new. +// It also uses mSynth::nextStringSample to get the synthesizer output. +// This is where oversampling and the m_visualizer are handled. +void Microwave::playNote(NotePlayHandle * n, sampleFrame * working_buffer) { - if ( _n->m_pluginData == NULL || _n->totalFramesPlayed() == 0 ) + if (n->m_pluginData == NULL || n->totalFramesPlayed() == 0) { - _n->m_pluginData = new mSynth( - _n, - morphArr, rangeArr, modifyArr, modifyModeArr, volArr, panArr, detuneArr, phaseArr, phaseRandArr, enabledArr, mutedArr, - sampLenArr, morphMaxArr, unisonVoicesArr, unisonDetuneArr, unisonMorphArr, unisonModifyArr, keytrackingArr, tempoArr, interpolateArr, - subEnabledArr, subMutedArr, subKeytrackArr, subNoiseArr, subVolArr, subPanningArr, subDetuneArr, subPhaseArr, subPhaseRandArr, - subSampLenArr, subTempoArr, subRateLimitArr, subUnisonNumArr, subUnisonDetuneArr, subInterpolateArr, - sampleEnabledArr, sampleMutedArr, sampleKeytrackingArr, sampleGraphEnabledArr, sampleLoopArr, sampleVolumeArr, samplePanningArr, - sampleDetuneArr, samplePhaseArr, samplePhaseRandArr, sampleStartArr, sampleEndArr, - modInArr, modInNumArr, modInAmntArr, modInCurveArr, modIn2Arr, modInNum2Arr, modInAmnt2Arr, modInCurve2Arr, - modOutSecArr, modOutSigArr, modOutSecNumArr, modEnabledArr, modCombineTypeArr, modTypeArr, modType2Arr, - filtCutoffArr, filtResoArr, filtGainArr, filtTypeArr, filtSlopeArr, filtInVolArr, filtOutVolArr, filtWetDryArr, filtBalArr, - filtSatuArr, filtFeedbackArr, filtDetuneArr, filtEnabledArr, filtMutedArr, filtKeytrackingArr, - macroArr, - samples ); - mwc = dynamic_cast(_n->instrumentTrack()->instrument()); - - for( int i = 0; i < 64; ++i ) + n->m_pluginData = new mSynth( + n, + m_morphArr, m_rangeArr, m_modifyArr, m_modifyModeArr, m_volArr, m_panArr, m_detuneArr, m_phaseArr, m_phaseRandArr, m_enabledArr, m_mutedArr, + m_sampLenArr, m_morphMaxArr, m_unisonVoicesArr, m_unisonDetuneArr, m_unisonMorphArr, m_unisonModifyArr, m_keytrackingArr, m_tempoArr, m_interpolateArr, + m_subEnabledArr, m_subMutedArr, m_subKeytrackArr, m_subNoiseArr, m_subVolArr, m_subPanningArr, m_subDetuneArr, m_subPhaseArr, m_subPhaseRandArr, + m_subSampLenArr, m_subTempoArr, m_subRateLimitArr, m_subUnisonNumArr, m_subUnisonDetuneArr, m_subInterpolateArr, + m_sampleEnabledArr, m_sampleMutedArr, m_sampleKeytrackingArr, m_sampleGraphEnabledArr, m_sampleLoopArr, m_sampleVolumeArr, m_samplePanningArr, + m_sampleDetuneArr, m_samplePhaseArr, m_samplePhaseRandArr, m_sampleStartArr, m_sampleEndArr, + m_modInArr, m_modInNumArr, m_modInAmntArr, m_modInCurveArr, m_modIn2Arr, m_modInNum2Arr, m_modInAmnt2Arr, m_modInCurve2Arr, + m_modOutSecArr, m_modOutSigArr, m_modOutSecNumArr, m_modEnabledArr, m_modCombineTypeArr, m_modTypeArr, m_modType2Arr, + m_filtCutoffArr, m_filtResoArr, m_filtGainArr, m_filtTypeArr, m_filtSlopeArr, m_filtInVolArr, m_filtOutVolArr, m_filtWetDryArr, m_filtBalArr, + m_filtSatuArr, m_filtFeedbackArr, m_filtDetuneArr, m_filtEnabledArr, m_filtMutedArr, m_filtKeytrackingArr, + m_macroArr, + m_samples); + m_mwc = dynamic_cast(n->instrumentTrack()->instrument()); + + for (int i = 0; i < 64; ++i) { - if( subEnabled[i]->value() ) + if (m_subEnabled[i]->value()) { - if( !subFilled[i] ) + if (!m_subFilled[i]) { - fillSubOsc(i, subInterpolate[i]->value()); + fillSubOsc(i, m_subInterpolate[i]->value()); } } } } - const fpp_t frames = _n->framesLeftForCurrentPeriod(); - const f_cnt_t offset = _n->noteOffset(); + const fpp_t frames = n->framesLeftForCurrentPeriod(); + const f_cnt_t offset = n->noteOffset(); - mSynth * ps = static_cast( _n->m_pluginData ); - for( fpp_t frame = offset; frame < frames + offset; ++frame ) + mSynth * ps = static_cast(n->m_pluginData); + for (fpp_t frame = offset; frame < frames + offset; ++frame) { sampleFrame outputSample; sampleFrame totalOutputSample = {0, 0}; - switch( oversampleMode.value() ) + switch (m_oversampleMode.value()) { case 0: { // Process some samples and ignore the output, depending on the oversampling value. For example, if the oversampling is set to 4x, it will process 4 samples and output 1 of those. - for( int i = 0; i < oversample.value() + 1; ++i ) + for (int i = 0; i < m_oversample.value() + 1; ++i) { - ps->nextStringSample( outputSample, waveforms, subs, sampGraphs, samples, maxFiltEnabled, maxModEnabled, maxSubEnabled, maxSampleEnabled, maxMainEnabled, Engine::mixer()->processingSampleRate() * ( oversample.value() + 1 ), mwc, removeDC.value(), !!i, storedsubs ); + ps->nextStringSample(outputSample, m_waveforms, m_subs, m_samples, m_sampGraphs, m_maxMainEnabled, m_maxSubEnabled, m_maxSampleEnabled, m_maxFiltEnabled, m_maxModEnabled, Engine::mixer()->processingSampleRate() * (m_oversample.value() + 1), m_mwc, m_removeDC.value(), m_storedsubs); } totalOutputSample[0] = outputSample[0]; totalOutputSample[1] = outputSample[1]; @@ -1321,88 +1316,88 @@ void Microwave::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) case 1: { // Process some number of samples and average them together, depending on the oversampling value. - for( int i = 0; i < oversample.value() + 1; ++i ) + for (int i = 0; i < m_oversample.value() + 1; ++i) { - ps->nextStringSample( outputSample, waveforms, subs, sampGraphs, samples, maxFiltEnabled, maxModEnabled, maxSubEnabled, maxSampleEnabled, maxMainEnabled, Engine::mixer()->processingSampleRate() * ( oversample.value() + 1 ), mwc, removeDC.value(), !!i, storedsubs ); + ps->nextStringSample(outputSample, m_waveforms, m_subs, m_samples, m_sampGraphs, m_maxMainEnabled, m_maxSubEnabled, m_maxSampleEnabled, m_maxFiltEnabled, m_maxModEnabled, Engine::mixer()->processingSampleRate() * (m_oversample.value() + 1), m_mwc, m_removeDC.value(), m_storedsubs); totalOutputSample[0] += outputSample[0]; totalOutputSample[1] += outputSample[1]; } - totalOutputSample[0] /= ( oversample.value() + 1 ); - totalOutputSample[1] /= ( oversample.value() + 1 ); + totalOutputSample[0] /= (m_oversample.value() + 1); + totalOutputSample[1] /= (m_oversample.value() + 1); break; } } - for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) + for (ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl) { //Send to output - _working_buffer[frame][chnl] = totalOutputSample[chnl]; + working_buffer[frame][chnl] = totalOutputSample[chnl]; } //update visualizer - if( viewOpen && visualize.value() && scroll == 0 && ps->enabled[mainNum.value()-1] ) + if (m_viewOpen && m_visualize.value() && m_scroll == 0 && ps->m_enabled[m_mainNum.value()-1]) { - visualizerValues[int( ( ps->sample_realindex[mainNum.value()-1][0] / ( ps->sampLen[mainNum.value()-1] * WAVERATIO ) ) * 204.f)] = ps->mainsample[mainNum.value()-1][0] * visvol.value() * 0.01f; - if( ps->noteDuration % 1470 == 1 )// Updates around 30 times per second (per note because I'm lazy I guess?) + m_visualizerValues[int((ps->m_sample_realindex[m_mainNum.value()-1][0] / (ps->m_sampLen[m_mainNum.value()-1] * WAVERATIO)) * 204.f)] = ps->m_mainsample[m_mainNum.value()-1][0] * m_visvol.value() * 0.01f; + if (ps->m_noteDuration % 1470 == 1)// Updates around 30 times per second (per note because I'm lazy I guess?) { - graph.setSamples( visualizerValues ); + m_graph.setSamples(m_visualizerValues); } } } - applyRelease( _working_buffer, _n ); + applyRelease(working_buffer, n); - instrumentTrack()->processAudioBuffer( _working_buffer, frames + offset, _n ); + instrumentTrack()->processAudioBuffer(working_buffer, frames + offset, n); } -void Microwave::deleteNotePluginData( NotePlayHandle * _n ) +void Microwave::deleteNotePluginData(NotePlayHandle * n) { } -// Fill subs using storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. -inline void Microwave::fillSubOsc( int which, bool doInterpolate ) +// Fill m_subs using m_storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. +inline void Microwave::fillSubOsc(int which, bool doInterpolate) { - if( doInterpolate ) + if (doInterpolate) { - srccpy( subs[which], const_cast( storedsubs[which] ), STOREDSUBWAVELEN ); + srccpy(m_subs[which], const_cast(m_storedsubs[which]), STOREDSUBWAVELEN); } else { - for( int i = 0; i < STOREDSUBWAVELEN; ++i ) + for (int i = 0; i < STOREDSUBWAVELEN; ++i) { - for( int j = 0; j < WAVERATIO; ++j ) + for (int j = 0; j < WAVERATIO; ++j) { - subs[which][i*WAVERATIO+j] = storedsubs[which][i]; + m_subs[which][i*WAVERATIO+j] = m_storedsubs[which][i]; } } } - subFilled[which] = true; + m_subFilled[which] = true; } -// Fill subs using storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. -inline void Microwave::fillMainOsc( int which, bool doInterpolate ) +// Fill m_subs using m_storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. +inline void Microwave::fillMainOsc(int which, bool doInterpolate) { - if( doInterpolate ) + if (doInterpolate) { - srccpy( waveforms[which], const_cast( storedwaveforms[which] ), STOREDMAINARRAYLEN ); + srccpy(m_waveforms[which], const_cast(m_storedwaveforms[which]), STOREDMAINARRAYLEN); } else { - for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { - for( int j = 0; j < WAVERATIO; ++j ) + for (int j = 0; j < WAVERATIO; ++j) { - waveforms[which][i*WAVERATIO+j] = storedwaveforms[which][i]; + m_waveforms[which][i*WAVERATIO+j] = m_storedwaveforms[which][i]; } } } - mainFilled[which] = true; + m_mainFilled[which] = true; } @@ -1410,10 +1405,10 @@ inline void Microwave::fillMainOsc( int which, bool doInterpolate ) /* - ____ + ___ ,' , `. - ,-+-,.' _ | ,--, ,---. ,--, - ,-+-. ; , ||,--.'| __ ,-. ,---. .---. /__./|,--.'| .---. + ,-+-,.' | ,--, ,---. ,--, + ,-+-. ; , ||,--.'| _ ,-. ,---. .---. /__./|,--.'| .---. ,--.'|' | ;|| |, ,' ,'/ /| ' ,'\ /. ./| .---. ,---.; ; || |, /. ./| | | ,', | ':`--'_ ,---. ' | |' | / / | .-'-. ' | ,--.--. /. ./| ,---./___/ \ | |`--'_ ,---. .-'-. ' | | | / | | ||,' ,'| / \| | ,'. ; ,. : /___/ \: | / \ .-' . ' | / \ ; \ ' |,' ,'| / \ /___/ \: | @@ -1432,491 +1427,491 @@ inline void Microwave::fillMainOsc( int which, bool doInterpolate ) // Creates the Microwave GUI. Creates all GUI elements. Connects some events to some functions. Calls updateScroll() to put all of the GUI elements in their correct positions. -MicrowaveView::MicrowaveView( Instrument * _instrument, - QWidget * _parent ) : - InstrumentView( _instrument, _parent ) +MicrowaveView::MicrowaveView(Instrument * instrument, + QWidget * parent) : + InstrumentView(instrument, parent) { - setAutoFillBackground( true ); + setAutoFillBackground(true); - setMouseTracking( true ); + setMouseTracking(true); - setAcceptDrops( true ); + setAcceptDrops(true); - pal.setBrush( backgroundRole(), tab1ArtworkImg ); - setPalette( pal ); + m_pal.setBrush(backgroundRole(), m_tab1ArtworkImg); + setPalette(m_pal); - QWidget * view = new QWidget( _parent ); - view->setFixedSize( 250, 250 ); + QWidget * view = new QWidget(parent); + view->setFixedSize(250, 250); - QPixmap filtBoxesImg = PLUGIN_NAME::getIconPixmap("filterBoxes"); - filtBoxesLabel = new QLabel(this); - filtBoxesLabel->setPixmap(filtBoxesImg); - filtBoxesLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); + QPixmap m_filtBoxesImg = PLUGIN_NAME::getIconPixmap("filterBoxes"); + m_filtBoxesLabel = new QLabel(this); + m_filtBoxesLabel->setPixmap(m_filtBoxesImg); + m_filtBoxesLabel->setAttribute(Qt::WA_TransparentForMouseEvents); - QPixmap matrixBoxesImg = PLUGIN_NAME::getIconPixmap("matrixBoxes"); - matrixBoxesLabel = new QLabel(this); - matrixBoxesLabel->setPixmap(matrixBoxesImg); - matrixBoxesLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); + QPixmap m_matrixBoxesImg = PLUGIN_NAME::getIconPixmap("matrixBoxes"); + m_matrixBoxesLabel = new QLabel(this); + m_matrixBoxesLabel->setPixmap(m_matrixBoxesImg); + m_matrixBoxesLabel->setAttribute(Qt::WA_TransparentForMouseEvents); - makeknob( morphKnob, knobColored, tr( "Morph" ), tr( "The Morph knob chooses which waveform out of the wavetable to play." ) ); + makeknob(m_morphKnob, knobColored, tr("Morph"), tr("The Morph knob chooses which waveform out of the wavetable to play.")); - makeknob( rangeKnob, knobColored, tr( "Range" ), tr( "The Range knob interpolates (triangularly) the waveforms near the waveform selected by the Morph knob." ) ); + makeknob(m_rangeKnob, knobColored, tr("Range"), tr("The Range knob interpolates (triangularly) the waveforms near the waveform selected by the Morph knob.")); - makeknob( modifyKnob, knobColored, tr( "Modify" ), tr( "The Modify knob warps the wavetable realtime using super math powers. The formula depends on the Modify Mode dropdown box." ) ); + makeknob(m_modifyKnob, knobColored, tr("Modify"), tr("The Modify knob warps the wavetable realtime using super math powers. The formula depends on the Modify Mode dropdown box.")); - makeknob( detuneKnob, knobSmallColored, tr( "Detune" ), tr( "This knob changes the pitch of the oscillator, in cents." ) ); + makeknob(m_detuneKnob, knobSmallColored, tr("Detune"), tr("This knob changes the pitch of the oscillator, in cents.")); - makeknob( phaseKnob, knobSmallColored, tr( "Phase" ), tr( "This knob changes the phase (starting position) of the oscillator." ) ); + makeknob(m_phaseKnob, knobSmallColored, tr("Phase"), tr("This knob changes the phase (starting position) of the oscillator.")); - makeknob( volKnob, knobColored, tr( "Volume" ), tr( "This knob changes the volume. What a surprise!" ) ); + makeknob(m_volKnob, knobColored, tr("Volume"), tr("This knob changes the volume. What a surprise!")); - makeknob( panKnob, knobColored, tr( "Panning" ), tr( "This knob lowers the volume in one ear by an amount depending on this knob's value." ) ); + makeknob(m_panKnob, knobColored, tr("Panning"), tr("This knob lowers the volume in one ear by an amount depending on this knob's value.")); - makeknob( sampLenKnob, knobColored, tr( "Waveform Sample Length" ), tr( "This knob changes the number of samples per waveform there are in the wavetable. This is useful for finetuning the wavetbale if the wavetable loading was slightly off." ) ); + makeknob(m_sampLenKnob, knobColored, tr("Waveform Sample Length"), tr("This knob changes the number of samples per waveform there are in the wavetable. This is useful for finetuning the wavetbale if the wavetable loading was slightly off.")); - makeknob( morphMaxKnob, knobColored, tr( "Morph Max" ), tr( "This knob sets the maximum value of the Morph knob." ) ); + makeknob(m_morphMaxKnob, knobColored, tr("Morph Max"), tr("This knob sets the maximum value of the Morph knob.")); - makeknob( phaseRandKnob, knobSmallColored, tr( "Phase Randomness" ), tr( "This knob chooses a random phase for every note and unison voice. The phase change will never be larger than this knob's value." ) ); + makeknob(m_phaseRandKnob, knobSmallColored, tr("Phase Randomness"), tr("This knob chooses a random phase for every note and unison voice. The phase change will never be larger than this knob's value.")); - makeknob( unisonVoicesKnob, knobSmallColored, tr( "Unison Voices" ), tr( "This knob clones this oscillator multiple times depending on its value, and makes slight changes to the clones depending on the other unison-related knobs." ) ); + makeknob(m_unisonVoicesKnob, knobSmallColored, tr("Unison Voices"), tr("This knob clones this oscillator multiple times depending on its value, and makes slight changes to the clones depending on the other unison-related knobs.")); - makeknob( unisonDetuneKnob, knobSmallColored, tr( "Unison Detune" ), tr( "This knob detunes every unison voice by a random number that is less than the specified amount." ) ); + makeknob(m_unisonDetuneKnob, knobSmallColored, tr("Unison Detune"), tr("This knob detunes every unison voice by a random number that is less than the specified amount.")); - makeknob( unisonMorphKnob, knobSmallColored, tr( "Unison Morph" ), tr( "This knob changes the wavetable position of each individual unison voice." ) ); + makeknob(m_unisonMorphKnob, knobSmallColored, tr("Unison Morph"), tr("This knob changes the wavetable position of each individual unison voice.")); - makeknob( unisonModifyKnob, knobSmallColored, tr( "Unison Modify" ), tr( "This knob changes the Modify value of each individual unison voice." ) ); + makeknob(m_unisonModifyKnob, knobSmallColored, tr("Unison Modify"), tr("This knob changes the Modify value of each individual unison voice.")); - makeknob( tempoKnob, knobSmallColored, tr( "Tempo Sync" ), tr( "When this knob is anything other than 0, the oscillator is tempo synced to the specified tempo. This is meant for the creation of envelopes/LFOs/step sequencers in the Matrix tab, and you'll most likely want to enable the Muted LED when using this." ) ); + makeknob(m_tempoKnob, knobSmallColored, tr("Tempo Sync"), tr("When this knob is anything other than 0, the oscillator is tempo synced to the specified tempo. This is meant for the creation of envelopes/LFOs/step sequencers in the Matrix tab, and you'll most likely want to enable the Muted LED when using this.")); - modifyModeBox = new ComboBox( this ); - modifyModeBox->setGeometry( 0, 5, 42, 22 ); - modifyModeBox->setFont( pointSize<8>( modifyModeBox->font() ) ); - ToolTip::add( modifyModeBox, tr( "The Modify Mode dropdown box chooses the formula for the Modify knob to use to warp the wavetable realtime in cool-sounding ways." ) ); + m_modifyModeBox = new ComboBox(this); + m_modifyModeBox->setGeometry(0, 5, 42, 22); + m_modifyModeBox->setFont(pointSize<8>(m_modifyModeBox->font())); + ToolTip::add(m_modifyModeBox, tr("The Modify Mode dropdown box chooses the formula for the Modify knob to use to warp the wavetable realtime in cool-sounding ways.")); - enabledToggle = new LedCheckBox( "", this, tr( "Oscillator Enabled" ), LedCheckBox::Green ); - ToolTip::add( enabledToggle, tr( "This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!" ) ); + m_enabledToggle = new LedCheckBox("", this, tr("Oscillator Enabled"), LedCheckBox::Green); + ToolTip::add(m_enabledToggle, tr("This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!")); - mutedToggle = new LedCheckBox( "", this, tr( "Oscillator Muted" ), LedCheckBox::Green ); - ToolTip::add( mutedToggle, tr( "This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output." ) ); + m_mutedToggle = new LedCheckBox("", this, tr("Oscillator Muted"), LedCheckBox::Green); + ToolTip::add(m_mutedToggle, tr("This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output.")); - keytrackingToggle = new LedCheckBox( "", this, tr( "Keytracking" ), LedCheckBox::Green ); - ToolTip::add( keytrackingToggle, tr( "This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound." ) ); + m_keytrackingToggle = new LedCheckBox("", this, tr("Keytracking"), LedCheckBox::Green); + ToolTip::add(m_keytrackingToggle, tr("This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound.")); - interpolateToggle = new LedCheckBox( "", this, tr( "Interpolation Enabled" ), LedCheckBox::Green ); - ToolTip::add( interpolateToggle, tr( "This button turns sinc interpolation on/off. Interpolation uses no CPU and makes the oscillator super duper high-quality. You'll probably only ever want to turn this off when you're using small waveform lengths and you don't want the waveform smoothed over." ) ); + m_interpolateToggle = new LedCheckBox("", this, tr("Interpolation Enabled"), LedCheckBox::Green); + ToolTip::add(m_interpolateToggle, tr("This button turns sinc interpolation on/off. Interpolation uses no CPU and makes the oscillator super duper high-quality. You'll probably only ever want to turn this off when you're using small waveform lengths and you don't want the waveform smoothed over.")); - sampleEnabledToggle = new LedCheckBox( "", this, tr( "Sample Enabled" ), LedCheckBox::Green ); - ToolTip::add( sampleEnabledToggle, tr( "This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!" ) ); - sampleGraphEnabledToggle = new LedCheckBox( "", this, tr( "Sample Graph Enabled" ), LedCheckBox::Green ); - ToolTip::add( sampleGraphEnabledToggle, tr( "This button enables the graph for this oscillator. On the graph, left/right is time and up/down is position in the sample. A saw wave in the graph will play the sample normally." ) ); - sampleMutedToggle = new LedCheckBox( "", this, tr( "Sample Muted" ), LedCheckBox::Green ); - ToolTip::add( sampleMutedToggle, tr( "This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output." ) ); - sampleKeytrackingToggle = new LedCheckBox( "", this, tr( "Sample Keytracking" ), LedCheckBox::Green ); - ToolTip::add( sampleKeytrackingToggle, tr( "This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound." ) ); - sampleLoopToggle = new LedCheckBox( "", this, tr( "Loop Sample" ), LedCheckBox::Green ); - ToolTip::add( sampleLoopToggle, tr( "This button turns looping on/off. When looping is on, the sample will go back to the starting position when it is done playing." ) ); + m_sampleEnabledToggle = new LedCheckBox("", this, tr("Sample Enabled"), LedCheckBox::Green); + ToolTip::add(m_sampleEnabledToggle, tr("This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!")); + m_sampleGraphEnabledToggle = new LedCheckBox("", this, tr("Sample Graph Enabled"), LedCheckBox::Green); + ToolTip::add(m_sampleGraphEnabledToggle, tr("This button enables the graph for this oscillator. On the graph, left/right is time and up/down is position in the msample. A saw wave in the graph will play the m_sample normally.")); + m_sampleMutedToggle = new LedCheckBox("", this, tr("Sample Muted"), LedCheckBox::Green); + ToolTip::add(m_sampleMutedToggle, tr("This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output.")); + m_sampleKeytrackingToggle = new LedCheckBox("", this, tr("Sample Keytracking"), LedCheckBox::Green); + ToolTip::add(m_sampleKeytrackingToggle, tr("This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound.")); + m_sampleLoopToggle = new LedCheckBox("", this, tr("Loop Sample"), LedCheckBox::Green); + ToolTip::add(m_sampleLoopToggle, tr("This button turns looping on/off. When looping is on, the sample will go back to the starting position when it is done playing.")); - makeknob( sampleVolumeKnob, knobColored, tr( "Volume" ), tr( "This, like most other volume knobs, controls the volume." ) ); + makeknob(m_sampleVolumeKnob, knobColored, tr("Volume"), tr("This, like most other volume knobs, controls the volume.")); - makeknob( samplePanningKnob, knobColored, tr( "Panning" ), tr( "This knob lowers the volume in one ear by an amount depending on this knob's value." ) ); + makeknob(m_samplePanningKnob, knobColored, tr("Panning"), tr("This knob lowers the volume in one ear by an amount depending on this knob's value.")); - makeknob( sampleDetuneKnob, knobSmallColored, tr( "Detune" ), tr( "This knob changes the pitch (and speed) of the sample." ) ); + makeknob(m_sampleDetuneKnob, knobSmallColored, tr("Detune"), tr("This knob changes the pitch (and speed) of the sample.")); - makeknob( samplePhaseKnob, knobSmallColored, tr( "Phase" ), tr( "This knob changes the position of the sample, and is updated realtime when automated." ) ); + makeknob(m_samplePhaseKnob, knobSmallColored, tr("Phase"), tr("This knob changes the position of the sample, and is updated realtime when automated.")); - makeknob( samplePhaseRandKnob, knobSmallColored, tr( "Phase Randomness" ), tr( "This knob makes the sample start at a random position with every note." ) ); + makeknob(m_samplePhaseRandKnob, knobSmallColored, tr("Phase Randomness"), tr("This knob makes the sample start at a random position with every note.")); - makeknob( sampleStartKnob, knobSmallColored, tr( "Start" ), tr( "This knob changes the starting position of the sample." ) ); + makeknob(m_sampleStartKnob, knobSmallColored, tr("Start"), tr("This knob changes the starting position of the sample.")); - makeknob( sampleEndKnob, knobSmallColored, tr( "End" ), tr( "This knob changes the ending position of the sample." ) ); + makeknob(m_sampleEndKnob, knobSmallColored, tr("End"), tr("This knob changes the ending position of the sample.")); - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - makeknob( filtInVolKnob[i], knobSmallColored, tr( "Input Volume" ), tr( "This knob changes the input volume of the filter." ) ); + makeknob(m_filtInVolKnob[i], knobSmallColored, tr("Input Volume"), tr("This knob changes the input volume of the filter.")); - makeknob( filtCutoffKnob[i], knobSmallColored, tr( "Cutoff Frequency" ), tr( "This knob changes cutoff frequency of the filter." ) ); + makeknob(m_filtCutoffKnob[i], knobSmallColored, tr("Cutoff Frequency"), tr("This knob changes cutoff frequency of the filter.")); - makeknob( filtResoKnob[i], knobSmallColored, tr( "Resonance" ), tr( "This knob changes the resonance of the filter." ) ); + makeknob(m_filtResoKnob[i], knobSmallColored, tr("Resonance"), tr("This knob changes the resonance of the filter.")); - makeknob( filtGainKnob[i], knobSmallColored, tr( "db Gain" ), tr( "This knob changes the gain of the filter. This only applies to some filter types, e.g. Peak, High Shelf, Low Shelf, etc." ) ); + makeknob(m_filtGainKnob[i], knobSmallColored, tr("db Gain"), tr("This knob changes the gain of the filter. This only applies to some filter types, e.g. Peak, High Shelf, Low Shelf, etc.")); - makeknob( filtSatuKnob[i], knobSmallColored, tr( "Saturation" ), tr( "This knob applies some basic distortion after the filter is applied." ) ); + makeknob(m_filtSatuKnob[i], knobSmallColored, tr("Saturation"), tr("This knob applies some basic distortion after the filter is applied.")); - makeknob( filtWetDryKnob[i], knobSmallColored, tr( "Wet/Dry" ), tr( "This knob allows mixing the filtered signal with the unfiltered signal." ) ); + makeknob(m_filtWetDryKnob[i], knobSmallColored, tr("Wet/Dry"), tr("This knob allows mixing the filtered signal with the unfiltered signal.")); - makeknob( filtBalKnob[i], knobSmallColored, tr( "Balance/Panning" ), tr( "This knob decreases the Wet and increases the Dry of the filter in one ear, depending on the knob's value." ) ); + makeknob(m_filtBalKnob[i], knobSmallColored, tr("Balance/Panning"), tr("This knob decreases the Wet and increases the Dry of the filter in one ear, depending on the knob's value.")); - makeknob( filtOutVolKnob[i], knobSmallColored, tr( "Output Volume" ), tr( "This knob changes the output volume of the filter." ) ); + makeknob(m_filtOutVolKnob[i], knobSmallColored, tr("Output Volume"), tr("This knob changes the output volume of the filter.")); - makeknob( filtFeedbackKnob[i], knobSmallColored, tr( "Feedback" ), tr( "This knob sends the specified portion of the filter output back into the input after a certain delay. This delay effects the pitch, and can be changed using the filter's Detune and Keytracking options." ) ); + makeknob(m_filtFeedbackKnob[i], knobSmallColored, tr("Feedback"), tr("This knob sends the specified portion of the filter output back into the input after a certain delay. This delay effects the pitch, and can be changed using the m_filter's Detune and Keytracking options.")); - makeknob( filtDetuneKnob[i], knobSmallColored, tr( "Detune (Feedback Delay)" ), tr( "This knob changes the delay of the filter's feedback to match the specified pitch." ) ); + makeknob(m_filtDetuneKnob[i], knobSmallColored, tr("Detune (Feedback Delay)"), tr("This knob changes the delay of the filter's feedback to match the specified pitch.")); - filtTypeBox[i] = new ComboBox( this ); - filtTypeBox[i]->setGeometry( 1000, 5, 42, 22 ); - filtTypeBox[i]->setFont( pointSize<8>( filtTypeBox[i]->font() ) ); - ToolTip::add( filtTypeBox[i], tr( "This dropdown box changes the filter type." ) ); + m_filtTypeBox[i] = new ComboBox(this); + m_filtTypeBox[i]->setGeometry(1000, 5, 42, 22); + m_filtTypeBox[i]->setFont(pointSize<8>(m_filtTypeBox[i]->font())); + ToolTip::add(m_filtTypeBox[i], tr("This dropdown box changes the filter type.")); - filtSlopeBox[i] = new ComboBox( this ); - filtSlopeBox[i]->setGeometry( 1000, 5, 42, 22 ); - filtSlopeBox[i]->setFont( pointSize<8>( filtSlopeBox[i]->font() ) ); - ToolTip::add( filtSlopeBox[i], tr( "This dropdown box changes how many times the audio is run through the filter (which changes the slope). For example, a sound run through a 12 db filter three times will result in a 36 db slope." ) ); + m_filtSlopeBox[i] = new ComboBox(this); + m_filtSlopeBox[i]->setGeometry(1000, 5, 42, 22); + m_filtSlopeBox[i]->setFont(pointSize<8>(m_filtSlopeBox[i]->font())); + ToolTip::add(m_filtSlopeBox[i], tr("This dropdown box changes how many times the audio is run through the filter (which changes the slope). For example, a sound run through a 12 db filter three times will result in a 36 db slope.")); - filtEnabledToggle[i] = new LedCheckBox( "", this, tr( "Filter Enabled" ), LedCheckBox::Green ); - ToolTip::add( filtEnabledToggle[i], tr( "This button enables the filter. A disabled filter will never do anything and does not use any CPU. In many cases, the settings of a disabled filter will not be saved, so be careful!" ) ); + m_filtEnabledToggle[i] = new LedCheckBox("", this, tr("Filter Enabled"), LedCheckBox::Green); + ToolTip::add(m_filtEnabledToggle[i], tr("This button enables the filter. A disabled filter will never do anything and does not use any CPU. In many cases, the settings of a disabled filter will not be saved, so be careful!")); - filtKeytrackingToggle[i] = new LedCheckBox( "", this, tr( "Keytracking" ), LedCheckBox::Green ); - ToolTip::add( filtKeytrackingToggle[i], tr( "When this is enabled, the delay of the filter's feedback changes to match the frequency of the notes you play." ) ); + m_filtKeytrackingToggle[i] = new LedCheckBox("", this, tr("Keytracking"), LedCheckBox::Green); + ToolTip::add(m_filtKeytrackingToggle[i], tr("When this is enabled, the delay of the filter's feedback changes to match the frequency of the notes you play.")); - filtMutedToggle[i] = new LedCheckBox( "", this, tr( "Muted" ), LedCheckBox::Green ); - ToolTip::add( filtMutedToggle[i], tr( "This button mutes the filter. An enabled but muted filter will still use CPU and still work as a matrix input, but will not be sent to the audio output. You'll want to use this almost every time you send something to the Matrix." ) ); + m_filtMutedToggle[i] = new LedCheckBox("", this, tr("Muted"), LedCheckBox::Green); + ToolTip::add(m_filtMutedToggle[i], tr("This button mutes the filter. An enabled but muted filter will still use CPU and still work as a matrix input, but will not be sent to the audio output. You'll want to use this almost every time you send something to the Matrix.")); } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - makeknob( macroKnob[i], knobSmallColored, tr( "Macro" ) + " " + QString::number(i+1) + ":", tr( "Macro %1: " ).arg( i + 1 ) + tr( "This knob's value can be used in the Matrix to control many values at the same time, at different amounts. This is immensely useful for crafting great presets." ) ); + makeknob(m_macroKnob[i], knobSmallColored, tr("Macro") + " " + QString::number(i+1) + ":", tr("Macro %1: ").arg(i + 1) + tr("This knob's value can be used in the Matrix to control many values at the same time, at different amounts. This is immensely useful for crafting great presets.")); } - makeknob( subVolKnob, knobColored, tr( "Volume" ), tr( "This knob, as you probably expected, controls the volume." ) ); + makeknob(m_subVolKnob, knobColored, tr("Volume"), tr("This knob, as you probably expected, controls the volume.")); - makeknob( subPhaseKnob, knobSmallColored, tr( "Phase" ), tr( "This knob changes the phase (starting position) of the oscillator." ) ); + makeknob(m_subPhaseKnob, knobSmallColored, tr("Phase"), tr("This knob changes the phase (starting position) of the oscillator.")); - makeknob( subPhaseRandKnob, knobSmallColored, tr( "Phase Randomness" ), tr( "This knob chooses a random phase for every note. The phase change will never be larger than this knob's value." ) ); + makeknob(m_subPhaseRandKnob, knobSmallColored, tr("Phase Randomness"), tr("This knob chooses a random phase for every note. The phase change will never be larger than this knob's value.")); - makeknob( subDetuneKnob, knobColored, tr( "Detune" ), tr( "This knob changes the pitch of the oscillator." ) ); + makeknob(m_subDetuneKnob, knobColored, tr("Detune"), tr("This knob changes the pitch of the oscillator.")); - makeknob( subSampLenKnob, knobColored, tr( "Waveform Sample Length" ), tr( "This knob changes the waveform length, which you can see in the graph." ) ); + makeknob(m_subSampLenKnob, knobColored, tr("Waveform Sample Length"), tr("This knob changes the waveform length, which you can see in the graph.")); - makeknob( subPanningKnob, knobColored, tr( "Panning" ), tr( "This knob lowers the volume in one ear by an amount depending on this knob's value." ) ); + makeknob(m_subPanningKnob, knobColored, tr("Panning"), tr("This knob lowers the volume in one ear by an amount depending on this knob's value.")); - makeknob( subTempoKnob, knobColored, tr( "Tempo Sync" ), tr( "When this knob is anything other than 0, the oscillator is tempo synced to the specified tempo. This is meant for the creation of envelopes/LFOs/step sequencers in the Matrix tab, and you'll most likely want to enable the Muted LED when using this." ) ); + makeknob(m_subTempoKnob, knobColored, tr("Tempo Sync"), tr("When this knob is anything other than 0, the oscillator is tempo synced to the specified tempo. This is meant for the creation of envelopes/LFOs/step sequencers in the Matrix tab, and you'll most likely want to enable the Muted LED when using this.")); - makeknob( subRateLimitKnob, knobColored, tr( "Rate Limit" ), tr( "This knob limits the rate at which the waveform can change. Combined with the Noise LED being enabled, this could potentially be used as a chaos oscillator." ) ); + makeknob(m_subRateLimitKnob, knobColored, tr("Rate Limit"), tr("This knob limits the rate at which the waveform can change. Combined with the Noise LED being enabled, this could potentially be used as a chaos oscillator.")); - makeknob( subUnisonNumKnob, knobColored, tr( "Unison Voices" ), tr( "This knob clones this oscillator multiple times depending on its value, and makes slight changes to the clones depending on the other unison-related knobs." ) ); + makeknob(m_subUnisonNumKnob, knobColored, tr("Unison Voices"), tr("This knob clones this oscillator multiple times depending on its value, and makes slight changes to the clones depending on the other unison-related knobs.")); - makeknob( subUnisonDetuneKnob, knobColored, tr( "Unison Detune" ), tr( "This knob detunes every unison voice by a random number that is less than the specified amount." ) ); + makeknob(m_subUnisonDetuneKnob, knobColored, tr("Unison Detune"), tr("This knob detunes every unison voice by a random number that is less than the specified amount.")); - subEnabledToggle = new LedCheckBox( "", this, tr( "Enabled" ), LedCheckBox::Green ); - ToolTip::add( subEnabledToggle, tr( "This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!" ) ); + m_subEnabledToggle = new LedCheckBox("", this, tr("Enabled"), LedCheckBox::Green); + ToolTip::add(m_subEnabledToggle, tr("This button enables the oscillator. A disabled oscillator will never do anything and does not use any CPU. In many cases, the settings of a disabled oscillator will not be saved, so be careful!")); - subMutedToggle = new LedCheckBox( "", this, tr( "Muted" ), LedCheckBox::Green ); - ToolTip::add( subMutedToggle, tr( "This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output." ) ); + m_subMutedToggle = new LedCheckBox("", this, tr("Muted"), LedCheckBox::Green); + ToolTip::add(m_subMutedToggle, tr("This button mutes the oscillator. An enabled but muted oscillator will still use CPU and still work as a matrix input, but will not be sent to the audio output.")); - subKeytrackToggle = new LedCheckBox( "", this, tr( "Keytracking Enabled" ), LedCheckBox::Green ); - ToolTip::add( subKeytrackToggle, tr( "This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound." ) ); + m_subKeytrackToggle = new LedCheckBox("", this, tr("Keytracking Enabled"), LedCheckBox::Green); + ToolTip::add(m_subKeytrackToggle, tr("This button turns keytracking on/off. Without keytracking, the frequency will be 440 Hz by default, and will ignore the frequency of the played note, but will still follow other methods of detuning the sound.")); - subNoiseToggle = new LedCheckBox( "", this, tr( "Noise Enabled" ), LedCheckBox::Green ); - ToolTip::add( subNoiseToggle, tr( "This button converts this oscillator into a noise generator. A random part of the graph is chosen, that value is added to the previous output in the same direction it was going, and when the waveform crosses the top or bottom, the direction changes." ) ); + m_subNoiseToggle = new LedCheckBox("", this, tr("Noise Enabled"), LedCheckBox::Green); + ToolTip::add(m_subNoiseToggle, tr("This button converts this oscillator into a noise generator. A random part of the graph is chosen, that value is added to the previous output in the same direction it was going, and when the waveform crosses the top or bottom, the direction changes.")); - subInterpolateToggle = new LedCheckBox( "", this, tr( "Interpolation Enabled" ), LedCheckBox::Green ); - ToolTip::add( subInterpolateToggle, tr( "This button turns sinc interpolation on/off. Interpolation uses no CPU and makes the oscillator super duper high-quality. You'll probably only ever want to turn this off when you're using small waveform lengths and you don't want the waveform smoothed over." ) ); + m_subInterpolateToggle = new LedCheckBox("", this, tr("Interpolation Enabled"), LedCheckBox::Green); + ToolTip::add(m_subInterpolateToggle, tr("This button turns sinc interpolation on/off. Interpolation uses no CPU and makes the oscillator super duper high-quality. You'll probably only ever want to turn this off when you're using small waveform lengths and you don't want the waveform smoothed over.")); - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - makeknob( modInAmntKnob[i], knobSmallColored, tr( "Matrix Input Amount" ), tr( "This knob controls how much of the input to send to the output." ) ); + makeknob(m_modInAmntKnob[i], knobSmallColored, tr("Matrix Input Amount"), tr("This knob controls how much of the input to send to the output.")); - makeknob( modInCurveKnob[i], knobSmallColored, tr( "Matrix Curve Amount" ), tr( "This knob gives the input value a bias toward the top or bottom" ) ); + makeknob(m_modInCurveKnob[i], knobSmallColored, tr("Matrix Curve Amount"), tr("This knob gives the input value a bias toward the top or bottom")); - makeknob( modInAmntKnob2[i], knobSmallColored, tr( "Secondary Matrix Input Amount" ), tr( "This knob controls how much of the input to send to the output." ) ); + makeknob(m_modInAmntKnob2[i], knobSmallColored, tr("Secondary Matrix Input Amount"), tr("This knob controls how much of the input to send to the output.")); - makeknob( modInCurveKnob2[i], knobSmallColored, tr( "Secondary Matrix Curve Amount" ), tr( "This knob gives the input value a bias toward the top or bottom" ) ); + makeknob(m_modInCurveKnob2[i], knobSmallColored, tr("Secondary Matrix Curve Amount"), tr("This knob gives the input value a bias toward the top or bottom")); - modOutSecBox[i] = new ComboBox( this ); - modOutSecBox[i]->setGeometry( 2000, 5, 42, 22 ); - modOutSecBox[i]->setFont( pointSize<8>( modOutSecBox[i]->font() ) ); - ToolTip::add( modOutSecBox[i], tr( "This dropdown box chooses an output for the Matrix Box." ) ); + m_modOutSecBox[i] = new ComboBox(this); + m_modOutSecBox[i]->setGeometry(2000, 5, 42, 22); + m_modOutSecBox[i]->setFont(pointSize<8>(m_modOutSecBox[i]->font())); + ToolTip::add(m_modOutSecBox[i], tr("This dropdown box chooses an output for the Matrix Box.")); - modOutSigBox[i] = new ComboBox( this ); - modOutSigBox[i]->setGeometry( 2000, 5, 42, 22 ); - modOutSigBox[i]->setFont( pointSize<8>( modOutSigBox[i]->font() ) ); - ToolTip::add( modOutSigBox[i], tr( "This dropdown box chooses which part of the input to send to the Matrix Box (e.g. which parameter to control, which filter, etc.)." ) ); + m_modOutSigBox[i] = new ComboBox(this); + m_modOutSigBox[i]->setGeometry(2000, 5, 42, 22); + m_modOutSigBox[i]->setFont(pointSize<8>(m_modOutSigBox[i]->font())); + ToolTip::add(m_modOutSigBox[i], tr("This dropdown box chooses which part of the input to send to the Matrix Box (e.g. which parameter to control, which filter, etc.).")); - modOutSecNumBox[i] = new LcdSpinBox( 2, "microwave", this, "Mod Output Number" ); - ToolTip::add( modOutSecNumBox[i], tr( "This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator)." ) ); + m_modOutSecNumBox[i] = new LcdSpinBox(2, "microwave", this, "Mod Output Number"); + ToolTip::add(m_modOutSecNumBox[i], tr("This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator).")); - modInBox[i] = new ComboBox( this ); - modInBox[i]->setGeometry( 2000, 5, 42, 22 ); - modInBox[i]->setFont( pointSize<8>( modInBox[i]->font() ) ); - ToolTip::add( modInBox[i], tr( "This dropdown box chooses an input for the Matrix Box." ) ); + m_modInBox[i] = new ComboBox(this); + m_modInBox[i]->setGeometry(2000, 5, 42, 22); + m_modInBox[i]->setFont(pointSize<8>(m_modInBox[i]->font())); + ToolTip::add(m_modInBox[i], tr("This dropdown box chooses an input for the Matrix Box.")); - modInNumBox[i] = new LcdSpinBox( 2, "microwave", this, "Mod Input Number" ); - ToolTip::add( modInNumBox[i], tr( "This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator, which filter, etc.)." ) ); + m_modInNumBox[i] = new LcdSpinBox(2, "microwave", this, "Mod Input Number"); + ToolTip::add(m_modInNumBox[i], tr("This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator, which filter, etc.).")); - modInBox2[i] = new ComboBox( this ); - modInBox2[i]->setGeometry( 2000, 5, 42, 22 ); - modInBox2[i]->setFont( pointSize<8>( modInBox2[i]->font() ) ); - ToolTip::add( modInBox2[i], tr( "This dropdown box chooses an input for the Matrix Box." ) ); + m_modInBox2[i] = new ComboBox(this); + m_modInBox2[i]->setGeometry(2000, 5, 42, 22); + m_modInBox2[i]->setFont(pointSize<8>(m_modInBox2[i]->font())); + ToolTip::add(m_modInBox2[i], tr("This dropdown box chooses an input for the Matrix Box.")); - modInNumBox2[i] = new LcdSpinBox( 2, "microwave", this, "Secondary Mod Input Number" ); - ToolTip::add( modInNumBox2[i], tr( "This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator, which filter, etc.)." ) ); + m_modInNumBox2[i] = new LcdSpinBox(2, "microwave", this, "Secondary Mod Input Number"); + ToolTip::add(m_modInNumBox2[i], tr("This spinbox chooses which part of the input to send to the Matrix Box (e.g. which oscillator, which filter, etc.).")); - modEnabledToggle[i] = new LedCheckBox( "", this, tr( "Modulation Enabled" ), LedCheckBox::Green ); - ToolTip::add( modEnabledToggle[i], tr( "This button enables the Matrix Box. While disabled, this does not use CPU." ) ); + m_modEnabledToggle[i] = new LedCheckBox("", this, tr("Modulation Enabled"), LedCheckBox::Green); + ToolTip::add(m_modEnabledToggle[i], tr("This button enables the Matrix Box. While disabled, this does not use CPU.")); - modCombineTypeBox[i] = new ComboBox( this ); - modCombineTypeBox[i]->setGeometry( 2000, 5, 42, 22 ); - modCombineTypeBox[i]->setFont( pointSize<8>( modCombineTypeBox[i]->font() ) ); - ToolTip::add( modCombineTypeBox[i], tr( "This dropdown box chooses how to combine the two Matrix inputs." ) ); + m_modCombineTypeBox[i] = new ComboBox(this); + m_modCombineTypeBox[i]->setGeometry(2000, 5, 42, 22); + m_modCombineTypeBox[i]->setFont(pointSize<8>(m_modCombineTypeBox[i]->font())); + ToolTip::add(m_modCombineTypeBox[i], tr("This dropdown box chooses how to combine the two Matrix inputs.")); - modTypeToggle[i] = new LedCheckBox( "", this, tr( "Envelope Enabled" ), LedCheckBox::Green ); - ToolTip::add( modTypeToggle[i], tr( "This button, when enabled, treats the input as an envelope rather than an LFO." ) ); + m_modTypeToggle[i] = new LedCheckBox("", this, tr("Envelope Enabled"), LedCheckBox::Green); + ToolTip::add(m_modTypeToggle[i], tr("This button, when enabled, treats the input as an envelope rather than an LFO.")); - modType2Toggle[i] = new LedCheckBox( "", this, tr( "Envelope Enabled" ), LedCheckBox::Green ); - ToolTip::add( modType2Toggle[i], tr( "This button, when enabled, treats the input as an envelope rather than an LFO." ) ); + m_modType2Toggle[i] = new LedCheckBox("", this, tr("Envelope Enabled"), LedCheckBox::Green); + ToolTip::add(m_modType2Toggle[i], tr("This button, when enabled, treats the input as an envelope rather than an LFO.")); - modUpArrow[i] = new PixmapButton( this, tr( "Move Matrix Section Up" ) ); - modUpArrow[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); - modUpArrow[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); - ToolTip::add( modUpArrow[i], tr( "Move this Matrix Box up" ) ); + m_modUpArrow[i] = new PixmapButton(this, tr("Move Matrix Section Up")); + m_modUpArrow[i]->setActiveGraphic(PLUGIN_NAME::getIconPixmap("arrowup")); + m_modUpArrow[i]->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("arrowup")); + ToolTip::add(m_modUpArrow[i], tr("Move this Matrix Box up")); - modDownArrow[i] = new PixmapButton( this, tr( "Move Matrix Section Down" ) ); - modDownArrow[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); - modDownArrow[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); - ToolTip::add( modDownArrow[i], tr( "Move this Matrix Box down" ) ); + m_modDownArrow[i] = new PixmapButton(this, tr("Move Matrix Section Down")); + m_modDownArrow[i]->setActiveGraphic(PLUGIN_NAME::getIconPixmap("arrowdown")); + m_modDownArrow[i]->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("arrowdown")); + ToolTip::add(m_modDownArrow[i], tr("Move this Matrix Box down")); - i1Button[i] = new PixmapButton( this, tr( "Go to this input's location" ) ); - i1Button[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "i1_button" ) ); - i1Button[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "i1_button" ) ); - ToolTip::add( i1Button[i], tr( "Go to this input's location" ) ); + m_i1Button[i] = new PixmapButton(this, tr("Go to this input's location")); + m_i1Button[i]->setActiveGraphic(PLUGIN_NAME::getIconPixmap("i1_button")); + m_i1Button[i]->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("i1_button")); + ToolTip::add(m_i1Button[i], tr("Go to this input's location")); - i2Button[i] = new PixmapButton( this, tr( "Go to this input's location" ) ); - i2Button[i]->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "i2_button" ) ); - i2Button[i]->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "i2_button" ) ); - ToolTip::add( i2Button[i], tr( "Go to this input's location" ) ); + m_i2Button[i] = new PixmapButton(this, tr("Go to this input's location")); + m_i2Button[i]->setActiveGraphic(PLUGIN_NAME::getIconPixmap("i2_button")); + m_i2Button[i]->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("i2_button")); + ToolTip::add(m_i2Button[i], tr("Go to this input's location")); - modNumText[i] = new QLineEdit(this); - modNumText[i]->resize(23, 19); + m_modNumText[i] = new QLineEdit(this); + m_modNumText[i]->resize(23, 19); } - makeknob( visvolKnob, knobSmallColored, tr( "Visualizer Volume" ), tr( "This knob works as a vertical zoom knob for the visualizer." ) ); + makeknob(m_visvolKnob, knobSmallColored, tr("Visualizer Volume"), tr("This knob works as a vertical zoom knob for the visualizer.")); - makeknob( loadChnlKnob, knobColored, tr( "Wavetable Loading Channel" ), tr( "This knob chooses whether to load the left or right audio of the selected sample/wavetable." ) ); + makeknob(m_loadChnlKnob, knobColored, tr("Wavetable Loading Channel"), tr("This knob chooses whether to load the left or right audio of the selected sample/wavetable.")); - graph = new Graph( this, Graph::BarCenterGradStyle, 204, 134 ); - graph->setAutoFillBackground( true ); - graph->setGraphColor( QColor( 121, 222, 239 ) ); + m_graph = new Graph(this, Graph::BarCenterGradStyle, 204, 134); + m_graph->setAutoFillBackground(true); + m_graph->setGraphColor(QColor(121, 222, 239)); - ToolTip::add( graph, tr ( "Draw here by dragging your mouse on this graph." ) ); - - pal = QPalette(); - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap("wavegraph") ); - graph->setPalette( pal ); - - QPixmap filtForegroundImg = PLUGIN_NAME::getIconPixmap("filterForeground"); - filtForegroundLabel = new QLabel(this); - filtForegroundLabel->setPixmap(filtForegroundImg); - filtForegroundLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); - - QPixmap matrixForegroundImg = PLUGIN_NAME::getIconPixmap("matrixForeground"); - matrixForegroundLabel = new QLabel(this); - matrixForegroundLabel->setPixmap(matrixForegroundImg); - matrixForegroundLabel->setAttribute( Qt::WA_TransparentForMouseEvents ); - - sinWaveBtn = new PixmapButton( this, tr( "Sine" ) ); - sinWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave_active" ) ); - sinWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave" ) ); - ToolTip::add( sinWaveBtn, tr( "Sine wave" ) ); + ToolTip::add(m_graph, tr ("Draw here by dragging your mouse on this graph.")); + + m_pal = QPalette(); + m_pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("wavegraphdisabled")); + m_graph->setPalette(m_pal); + + QPixmap m_filtForegroundImg = PLUGIN_NAME::getIconPixmap("filterForeground"); + m_filtForegroundLabel = new QLabel(this); + m_filtForegroundLabel->setPixmap(m_filtForegroundImg); + m_filtForegroundLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + + QPixmap m_matrixForegroundImg = PLUGIN_NAME::getIconPixmap("matrixForeground"); + m_matrixForegroundLabel = new QLabel(this); + m_matrixForegroundLabel->setPixmap(m_matrixForegroundImg); + m_matrixForegroundLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + + m_sinWaveBtn = new PixmapButton(this, tr("Sine")); + m_sinWaveBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sinwave_active")); + m_sinWaveBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sinwave")); + ToolTip::add(m_sinWaveBtn, tr("Sine wave")); - triangleWaveBtn = new PixmapButton( this, tr( "Nachos" ) ); - triangleWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave_active" ) ); - triangleWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave" ) ); - ToolTip::add( triangleWaveBtn, tr( "Nacho wave" ) ); - - sawWaveBtn = new PixmapButton( this, tr( "Sawsa" ) ); - sawWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave_active" ) ); - sawWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave" ) ); - ToolTip::add( sawWaveBtn, tr( "Sawsa wave" ) ); - - sqrWaveBtn = new PixmapButton( this, tr( "Sosig" ) ); - sqrWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave_active" ) ); - sqrWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave" ) ); - ToolTip::add( sqrWaveBtn, tr( "Sosig wave" ) ); - - whiteNoiseWaveBtn = new PixmapButton( this, tr( "Metal Fork" ) ); - whiteNoiseWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave_active" ) ); - whiteNoiseWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave" ) ); - ToolTip::add( whiteNoiseWaveBtn, tr( "Metal Fork" ) ); + m_triangleWaveBtn = new PixmapButton(this, tr("Nachos")); + m_triangleWaveBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("triwave_active")); + m_triangleWaveBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("triwave")); + ToolTip::add(m_triangleWaveBtn, tr("Nacho wave")); + + m_sawWaveBtn = new PixmapButton(this, tr("Sawsa")); + m_sawWaveBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sawwave_active")); + m_sawWaveBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sawwave")); + ToolTip::add(m_sawWaveBtn, tr("Sawsa wave")); + + m_sqrWaveBtn = new PixmapButton(this, tr("Sosig")); + m_sqrWaveBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sqrwave_active")); + m_sqrWaveBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sqrwave")); + ToolTip::add(m_sqrWaveBtn, tr("Sosig wave")); + + m_whiteNoiseWaveBtn = new PixmapButton(this, tr("Metal Fork")); + m_whiteNoiseWaveBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("noisewave_active")); + m_whiteNoiseWaveBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("noisewave")); + ToolTip::add(m_whiteNoiseWaveBtn, tr("Metal Fork")); - usrWaveBtn = new PixmapButton( this, tr( "Takeout" ) ); - usrWaveBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - usrWaveBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - ToolTip::add( usrWaveBtn, tr( "Takeout Menu" ) ); - - smoothBtn = new PixmapButton( this, tr( "Microwave Cover" ) ); - smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave_active" ) ); - smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave" ) ); - ToolTip::add( smoothBtn, tr( "Microwave Cover" ) ); + m_usrWaveBtn = new PixmapButton(this, tr("Takeout")); + m_usrWaveBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + m_usrWaveBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + ToolTip::add(m_usrWaveBtn, tr("Takeout Menu")); + + m_smoothBtn = new PixmapButton(this, tr("Microwave Cover")); + m_smoothBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("smoothwave_active")); + m_smoothBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("smoothwave")); + ToolTip::add(m_smoothBtn, tr("Microwave Cover")); - sinWave2Btn = new PixmapButton( this, tr( "Sine" ) ); - sinWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave_active" ) ); - sinWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sinwave" ) ); - ToolTip::add( sinWave2Btn, tr( "Sine wave" ) ); + m_sinWave2Btn = new PixmapButton(this, tr("Sine")); + m_sinWave2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sinwave_active")); + m_sinWave2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sinwave")); + ToolTip::add(m_sinWave2Btn, tr("Sine wave")); - triangleWave2Btn = new PixmapButton( this, tr( "Nachos" ) ); - triangleWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave_active" ) ); - triangleWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "triwave" ) ); - ToolTip::add( triangleWave2Btn, - tr( "Nacho wave" ) ); + m_triangleWave2Btn = new PixmapButton(this, tr("Nachos")); + m_triangleWave2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("triwave_active")); + m_triangleWave2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("triwave")); + ToolTip::add(m_triangleWave2Btn, + tr("Nacho wave")); - sawWave2Btn = new PixmapButton( this, tr( "Sawsa" ) ); - sawWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave_active" ) ); - sawWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sawwave" ) ); - ToolTip::add( sawWave2Btn, - tr( "Sawsa wave" ) ); + m_sawWave2Btn = new PixmapButton(this, tr("Sawsa")); + m_sawWave2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sawwave_active")); + m_sawWave2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sawwave")); + ToolTip::add(m_sawWave2Btn, + tr("Sawsa wave")); - sqrWave2Btn = new PixmapButton( this, tr( "Sosig" ) ); - sqrWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave_active" ) ); - sqrWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sqrwave" ) ); - ToolTip::add( sqrWave2Btn, tr( "Sosig wave" ) ); + m_sqrWave2Btn = new PixmapButton(this, tr("Sosig")); + m_sqrWave2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sqrwave_active")); + m_sqrWave2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sqrwave")); + ToolTip::add(m_sqrWave2Btn, tr("Sosig wave")); - whiteNoiseWave2Btn = new PixmapButton( this, tr( "Metal Fork" ) ); - whiteNoiseWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave_active" ) ); - whiteNoiseWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "noisewave" ) ); - ToolTip::add( whiteNoiseWave2Btn, tr( "Metal Fork" ) ); + m_whiteNoiseWave2Btn = new PixmapButton(this, tr("Metal Fork")); + m_whiteNoiseWave2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("noisewave_active")); + m_whiteNoiseWave2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("noisewave")); + ToolTip::add(m_whiteNoiseWave2Btn, tr("Metal Fork")); - usrWave2Btn = new PixmapButton( this, tr( "Takeout Menu" ) ); - usrWave2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - usrWave2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - ToolTip::add( usrWave2Btn, tr( "Takeout Menu" ) ); + m_usrWave2Btn = new PixmapButton(this, tr("Takeout Menu")); + m_usrWave2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + m_usrWave2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + ToolTip::add(m_usrWave2Btn, tr("Takeout Menu")); - smooth2Btn = new PixmapButton( this, tr( "Microwave Cover" ) ); - smooth2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave_active" ) ); - smooth2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smoothwave" ) ); - ToolTip::add( smooth2Btn, tr( "Microwave Cover" ) ); + m_smooth2Btn = new PixmapButton(this, tr("Microwave Cover")); + m_smooth2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("smoothwave_active")); + m_smooth2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("smoothwave")); + ToolTip::add(m_smooth2Btn, tr("Microwave Cover")); - tab1Btn = new PixmapButton( this, tr( "Wavetable Tab" ) ); - tab1Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); - tab1Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); - ToolTip::add( tab1Btn, tr( "Wavetable Tab" ) ); - - tab2Btn = new PixmapButton( this, tr( "Sub Tab" ) ); - tab2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); - tab2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); - ToolTip::add( tab2Btn, tr( "Sub Tab" ) ); - - tab3Btn = new PixmapButton( this, tr( "Sample Tab" ) ); - tab3Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); - tab3Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); - ToolTip::add( tab3Btn, tr( "Sample Tab" ) ); - - tab4Btn = new PixmapButton( this, tr( "Matrix Tab" ) ); - tab4Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); - tab4Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); - ToolTip::add( tab4Btn, tr( "Matrix Tab" ) ); - - tab5Btn = new PixmapButton( this, tr( "Effect Tab" ) ); - tab5Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); - tab5Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); - ToolTip::add( tab5Btn, tr( "Effect Tab" ) ); - - tab6Btn = new PixmapButton( this, tr( "Miscellaneous Tab" ) ); - tab6Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); - tab6Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); - ToolTip::add( tab6Btn, tr( "Miscellaneous Tab" ) ); - - - mainFlipBtn = new PixmapButton( this, tr( "Flip to other knobs" ) ); - mainFlipBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); - mainFlipBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); - ToolTip::add( mainFlipBtn, tr( "Flip to other knobs" ) ); - mainFlipBtn->setCheckable(true); - - subFlipBtn = new PixmapButton( this, tr( "Flip to other knobs" ) ); - subFlipBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowup" ) ); - subFlipBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arrowdown" ) ); - ToolTip::add( subFlipBtn, tr( "Flip to other knobs" ) ); - subFlipBtn->setCheckable(true); - - - manualBtn = new PixmapButton( this, tr( "Manual" ) ); - manualBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "manual_active" ) ); - manualBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "manual_inactive" ) ); - ToolTip::add( manualBtn, tr( "Manual" ) ); - - - removeDCBtn = new PixmapButton( this, tr( "Remove DC Offset" ) ); - removeDCBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "remove_dc_offset_button_enabled" ) ); - removeDCBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "remove_dc_offset_button_disabled" ) ); - ToolTip::add( removeDCBtn, tr( "Remove DC Offset" ) ); - removeDCBtn->setCheckable(true); + m_tab1Btn = new PixmapButton(this, tr("Wavetable Tab")); + m_tab1Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab1_active")); + m_tab1Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab1_active")); + ToolTip::add(m_tab1Btn, tr("Wavetable Tab")); + + m_tab2Btn = new PixmapButton(this, tr("Sub Tab")); + m_tab2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab2")); + m_tab2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab2")); + ToolTip::add(m_tab2Btn, tr("Sub Tab")); + + m_tab3Btn = new PixmapButton(this, tr("Sample Tab")); + m_tab3Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab3")); + m_tab3Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab3")); + ToolTip::add(m_tab3Btn, tr("Sample Tab")); + + m_tab4Btn = new PixmapButton(this, tr("Matrix Tab")); + m_tab4Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab4")); + m_tab4Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab4")); + ToolTip::add(m_tab4Btn, tr("Matrix Tab")); + + m_tab5Btn = new PixmapButton(this, tr("Effect Tab")); + m_tab5Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab5")); + m_tab5Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab5")); + ToolTip::add(m_tab5Btn, tr("Effect Tab")); + + m_tab6Btn = new PixmapButton(this, tr("Miscellaneous Tab")); + m_tab6Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab6")); + m_tab6Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab6")); + ToolTip::add(m_tab6Btn, tr("Miscellaneous Tab")); + + + m_mainFlipBtn = new PixmapButton(this, tr("Flip to other knobs")); + m_mainFlipBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("arrowup")); + m_mainFlipBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("arrowdown")); + ToolTip::add(m_mainFlipBtn, tr("Flip to other knobs")); + m_mainFlipBtn->setCheckable(true); + + m_subFlipBtn = new PixmapButton(this, tr("Flip to other knobs")); + m_subFlipBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("arrowup")); + m_subFlipBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("arrowdown")); + ToolTip::add(m_subFlipBtn, tr("Flip to other knobs")); + m_subFlipBtn->setCheckable(true); + + + m_manualBtn = new PixmapButton(this, tr("Manual")); + m_manualBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("manual_active")); + m_manualBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("manual_inactive")); + ToolTip::add(m_manualBtn, tr("Manual")); + + + m_removeDCBtn = new PixmapButton(this, tr("Remove DC Offset")); + m_removeDCBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("remove_dc_offset_button_enabled")); + m_removeDCBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("remove_dc_offset_button_disabled")); + ToolTip::add(m_removeDCBtn, tr("Remove DC Offset")); + m_removeDCBtn->setCheckable(true); - oversampleModeBox = new ComboBox( this ); - oversampleModeBox->setGeometry( 0, 0, 42, 22 ); - oversampleModeBox->setFont( pointSize<8>( oversampleModeBox->font() ) ); + m_oversampleModeBox = new ComboBox(this); + m_oversampleModeBox->setGeometry(0, 0, 42, 22); + m_oversampleModeBox->setFont(pointSize<8>(m_oversampleModeBox->font())); - normalizeBtn = new PixmapButton( this, tr( "Normalize Wavetable" ) ); - normalizeBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "normalize_button_active" ) ); - normalizeBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "normalize_button" ) ); - ToolTip::add( normalizeBtn, tr( "Normalize Wavetable" ) ); - - desawBtn = new PixmapButton( this, tr( "De-saw Wavetable" ) ); - desawBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "desaw_button_active" ) ); - desawBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "desaw_button" ) ); - ToolTip::add( desawBtn, tr( "De-saw Wavetable" ) ); - + m_normalizeBtn = new PixmapButton(this, tr("Normalize Wavetable")); + m_normalizeBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("normalize_button_active")); + m_normalizeBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("normalize_button")); + ToolTip::add(m_normalizeBtn, tr("Normalize Wavetable")); + + m_desawBtn = new PixmapButton(this, tr("De-saw Wavetable")); + m_desawBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("desaw_button_active")); + m_desawBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("desaw_button")); + ToolTip::add(m_desawBtn, tr("De-saw Wavetable")); + - XBtn = new PixmapButton( this, tr( "Leave wavetable loading section" ) ); - XBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); - XBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); - ToolTip::add( XBtn, tr( "Leave wavetable loading tab" ) ); + m_XBtn = new PixmapButton(this, tr("Leave wavetable loading section")); + m_XBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("xbtn")); + m_XBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("xbtn")); + ToolTip::add(m_XBtn, tr("Leave wavetable loading tab")); - MatrixXBtn = new PixmapButton( this, tr( "Leave Matrix tab" ) ); - MatrixXBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); - MatrixXBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "xbtn" ) ); - ToolTip::add( MatrixXBtn, tr( "Leave wavetable loading tab" ) ); + m_MatrixXBtn = new PixmapButton(this, tr("Leave Matrix tab")); + m_MatrixXBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("xbtn")); + m_MatrixXBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("xbtn")); + ToolTip::add(m_MatrixXBtn, tr("Leave wavetable loading tab")); - visualizeToggle = new LedCheckBox( "", this, tr( "Visualize" ), LedCheckBox::Green ); + m_visualizeToggle = new LedCheckBox("", this, tr("Visualize"), LedCheckBox::Green); - openWavetableButton = new PixmapButton( this ); - openWavetableButton->setCursor( QCursor( Qt::PointingHandCursor ) ); - openWavetableButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - openWavetableButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - connect( openWavetableButton, SIGNAL( clicked() ), this, SLOT( openWavetableFileBtnClicked() ) ); - ToolTip::add( openWavetableButton, tr( "Open wavetable" ) ); + m_openWavetableButton = new PixmapButton(this); + m_openWavetableButton->setCursor(QCursor(Qt::PointingHandCursor)); + m_openWavetableButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + m_openWavetableButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + connect(m_openWavetableButton, SIGNAL(clicked()), this, SLOT(openWavetableFileBtnClicked())); + ToolTip::add(m_openWavetableButton, tr("Open wavetable")); - confirmLoadButton = new PixmapButton( this ); - confirmLoadButton->setCursor( QCursor( Qt::PointingHandCursor ) ); - confirmLoadButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "confirm_button_active" ) ); - confirmLoadButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "confirm_button_inactive" ) ); - connect( confirmLoadButton, SIGNAL( clicked() ), this, SLOT( confirmWavetableLoadClicked() ) ); - ToolTip::add( confirmLoadButton, tr( "Load Wavetable" ) ); + m_confirmLoadButton = new PixmapButton(this); + m_confirmLoadButton->setCursor(QCursor(Qt::PointingHandCursor)); + m_confirmLoadButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("confirm_button_active")); + m_confirmLoadButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("confirm_button_inactive")); + connect(m_confirmLoadButton, SIGNAL(clicked()), this, SLOT(confirmWavetableLoadClicked())); + ToolTip::add(m_confirmLoadButton, tr("Load Wavetable")); - subNumBox = new LcdSpinBox( 2, "microwave", this, "Sub Oscillator Number" ); + m_subNumBox = new LcdSpinBox(2, "microwave", this, "Sub Oscillator Number"); - sampNumBox = new LcdSpinBox( 2, "microwave", this, "Sample Number" ); + m_sampNumBox = new LcdSpinBox(2, "microwave", this, "Sample Number"); - mainNumBox = new LcdSpinBox( 2, "microwave", this, "Oscillator Number" ); + m_mainNumBox = new LcdSpinBox(2, "microwave", this, "Oscillator Number"); - oversampleBox = new ComboBox( this ); - oversampleBox->setGeometry( 0, 0, 42, 22 ); - oversampleBox->setFont( pointSize<8>( oversampleBox->font() ) ); + m_oversampleBox = new ComboBox(this); + m_oversampleBox->setGeometry(0, 0, 42, 22); + m_oversampleBox->setFont(pointSize<8>(m_oversampleBox->font())); - loadModeBox = new ComboBox( this ); - loadModeBox->setGeometry( 0, 0, 202, 22 ); - loadModeBox->setFont( pointSize<8>( loadModeBox->font() ) ); + m_loadModeBox = new ComboBox(this); + m_loadModeBox->setGeometry(0, 0, 202, 22); + m_loadModeBox->setFont(pointSize<8>(m_loadModeBox->font())); - openSampleButton = new PixmapButton( this ); - openSampleButton->setCursor( QCursor( Qt::PointingHandCursor ) ); - openSampleButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); - openSampleButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "fileload" ) ); + m_openSampleButton = new PixmapButton(this); + m_openSampleButton->setCursor(QCursor(Qt::PointingHandCursor)); + m_openSampleButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + m_openSampleButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); - effectScrollBar = new QScrollBar( Qt::Vertical, this ); - effectScrollBar->setSingleStep( 1 ); - effectScrollBar->setPageStep( 100 ); - effectScrollBar->setFixedHeight( 197 ); - effectScrollBar->setRange( 0, 590 ); - connect( effectScrollBar, SIGNAL( valueChanged( int ) ), this, SLOT( updateScroll( ) ) ); + m_effectScrollBar = new QScrollBar(Qt::Vertical, this); + m_effectScrollBar->setSingleStep(1); + m_effectScrollBar->setPageStep(100); + m_effectScrollBar->setFixedHeight(197); + m_effectScrollBar->setRange(0, 590); + connect(m_effectScrollBar, SIGNAL(valueChanged(int)), this, SLOT(updateScroll())); - effectScrollBar->setStyleSheet("QScrollBar::handle:horizontal { background: #3f4750; border: none; border-radius: 1px; min-width: 24px; }\ + m_effectScrollBar->setStyleSheet("QScrollBar::handle:horizontal { background: #3f4750; border: none; border-radius: 1px; min-width: 24px; }\ QScrollBar::handle:horizontal:hover { background: #a6adb1; }\ QScrollBar::handle:horizontal:pressed { background: #a6adb1; }\ QScrollBar::handle:vertical { background: #3f4750; border: none; border-radius: 1px; min-height: 24px; }\ @@ -1924,14 +1919,14 @@ MicrowaveView::MicrowaveView( Instrument * _instrument, QScrollBar::handle:vertical:pressed { background: #a6adb1; }\ QScrollBar::handle:horizontal:disabled, QScrollBar::handle:vertical:disabled { background: #262b30; border-radius: 1px; border: none; }"); - matrixScrollBar = new QScrollBar( Qt::Vertical, this ); - matrixScrollBar->setSingleStep( 1 ); - matrixScrollBar->setPageStep( 100 ); - matrixScrollBar->setFixedHeight( 197 ); - matrixScrollBar->setRange( 0, 6232 ); - connect( matrixScrollBar, SIGNAL( valueChanged( int ) ), this, SLOT( updateScroll( ) ) ); + m_matrixScrollBar = new QScrollBar(Qt::Vertical, this); + m_matrixScrollBar->setSingleStep(1); + m_matrixScrollBar->setPageStep(100); + m_matrixScrollBar->setFixedHeight(197); + m_matrixScrollBar->setRange(0, 6232); + connect(m_matrixScrollBar, SIGNAL(valueChanged(int)), this, SLOT(updateScroll())); - matrixScrollBar->setStyleSheet("QScrollBar::handle:horizontal { background: #3f4750; border: none; border-radius: 1px; min-width: 24px; }\ + m_matrixScrollBar->setStyleSheet("QScrollBar::handle:horizontal { background: #3f4750; border: none; border-radius: 1px; min-width: 24px; }\ QScrollBar::handle:horizontal:hover { background: #a6adb1; }\ QScrollBar::handle:horizontal:pressed { background: #a6adb1; }\ QScrollBar::handle:vertical { background: #3f4750; border: none; border-radius: 1px; min-height: 24px; }\ @@ -1942,95 +1937,95 @@ MicrowaveView::MicrowaveView( Instrument * _instrument, // The above scrollbar style changes don't seem to work entirely for some reason. - connect( openSampleButton, SIGNAL( clicked() ), this, SLOT( openSampleFileBtnClicked() ) ); - ToolTip::add( openSampleButton, tr( "Open sample" ) ); + connect(m_openSampleButton, SIGNAL(clicked()), this, SLOT(openSampleFileBtnClicked())); + ToolTip::add(m_openSampleButton, tr("Open sample")); - connect( sinWaveBtn, SIGNAL (clicked () ), this, SLOT ( sinWaveClicked() ) ); - connect( triangleWaveBtn, SIGNAL ( clicked () ), this, SLOT ( triangleWaveClicked() ) ); - connect( sawWaveBtn, SIGNAL (clicked () ), this, SLOT ( sawWaveClicked() ) ); - connect( sqrWaveBtn, SIGNAL ( clicked () ), this, SLOT ( sqrWaveClicked() ) ); - connect( whiteNoiseWaveBtn, SIGNAL ( clicked () ), this, SLOT ( noiseWaveClicked() ) ); - connect( usrWaveBtn, SIGNAL ( clicked () ), this, SLOT ( usrWaveClicked() ) ); - connect( smoothBtn, SIGNAL ( clicked () ), this, SLOT ( smoothClicked() ) ); + connect(m_sinWaveBtn, SIGNAL (clicked ()), this, SLOT (sinWaveClicked())); + connect(m_triangleWaveBtn, SIGNAL (clicked ()), this, SLOT (triangleWaveClicked())); + connect(m_sawWaveBtn, SIGNAL (clicked ()), this, SLOT (sawWaveClicked())); + connect(m_sqrWaveBtn, SIGNAL (clicked ()), this, SLOT (sqrWaveClicked())); + connect(m_whiteNoiseWaveBtn, SIGNAL (clicked ()), this, SLOT (noiseWaveClicked())); + connect(m_usrWaveBtn, SIGNAL (clicked ()), this, SLOT (usrWaveClicked())); + connect(m_smoothBtn, SIGNAL (clicked ()), this, SLOT (smoothClicked())); - connect( sinWave2Btn, SIGNAL (clicked () ), this, SLOT ( sinWaveClicked() ) ); - connect( triangleWave2Btn, SIGNAL ( clicked () ), this, SLOT ( triangleWaveClicked() ) ); - connect( sawWave2Btn, SIGNAL (clicked () ), this, SLOT ( sawWaveClicked() ) ); - connect( sqrWave2Btn, SIGNAL ( clicked () ), this, SLOT ( sqrWaveClicked() ) ); - connect( whiteNoiseWave2Btn, SIGNAL ( clicked () ), this, SLOT ( noiseWaveClicked() ) ); - connect( usrWave2Btn, SIGNAL ( clicked () ), this, SLOT ( usrWaveClicked() ) ); - connect( smooth2Btn, SIGNAL ( clicked () ), this, SLOT ( smoothClicked() ) ); + connect(m_sinWave2Btn, SIGNAL (clicked ()), this, SLOT (sinWaveClicked())); + connect(m_triangleWave2Btn, SIGNAL (clicked ()), this, SLOT (triangleWaveClicked())); + connect(m_sawWave2Btn, SIGNAL (clicked ()), this, SLOT (sawWaveClicked())); + connect(m_sqrWave2Btn, SIGNAL (clicked ()), this, SLOT (sqrWaveClicked())); + connect(m_whiteNoiseWave2Btn, SIGNAL (clicked ()), this, SLOT (noiseWaveClicked())); + connect(m_usrWave2Btn, SIGNAL (clicked ()), this, SLOT (usrWaveClicked())); + connect(m_smooth2Btn, SIGNAL (clicked ()), this, SLOT (smoothClicked())); - connect( XBtn, SIGNAL (clicked () ), this, SLOT ( XBtnClicked() ) ); - connect( MatrixXBtn, SIGNAL (clicked () ), this, SLOT ( MatrixXBtnClicked() ) ); + connect(m_XBtn, SIGNAL (clicked ()), this, SLOT (XBtnClicked())); + connect(m_MatrixXBtn, SIGNAL (clicked ()), this, SLOT (MatrixXBtnClicked())); - connect( normalizeBtn, SIGNAL (clicked () ), this, SLOT ( normalizeClicked() ) ); - connect( desawBtn, SIGNAL (clicked () ), this, SLOT ( desawClicked() ) ); + connect(m_normalizeBtn, SIGNAL (clicked ()), this, SLOT (normalizeClicked())); + connect(m_desawBtn, SIGNAL (clicked ()), this, SLOT (desawClicked())); // This is a mess, but for some reason just entering a number without a variable didn't work... int ii = 0; - connect( tab1Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + connect(m_tab1Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); ii = 1; - connect( tab2Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + connect(m_tab2Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); ii = 2; - connect( tab3Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + connect(m_tab3Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); ii = 3; - connect( tab4Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + connect(m_tab4Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); ii = 4; - connect( tab5Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + connect(m_tab5Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); ii = 5; - connect( tab6Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); } ); + connect(m_tab6Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); - connect( mainFlipBtn, SIGNAL (clicked () ), this, SLOT ( flipperClicked() ) ); - connect( subFlipBtn, SIGNAL (clicked () ), this, SLOT ( flipperClicked() ) ); + connect(m_mainFlipBtn, SIGNAL (clicked ()), this, SLOT (flipperClicked())); + connect(m_subFlipBtn, SIGNAL (clicked ()), this, SLOT (flipperClicked())); - connect( visualizeToggle, SIGNAL( toggled( bool ) ), this, SLOT ( visualizeToggled( bool ) ) ); + connect(m_visualizeToggle, SIGNAL(toggled(bool)), this, SLOT (visualizeToggled(bool))); - connect( &b->mainNum, SIGNAL( dataChanged( ) ), this, SLOT( mainNumChanged( ) ) ); - connect( &b->subNum, SIGNAL( dataChanged( ) ), this, SLOT( subNumChanged( ) ) ); - connect( &b->sampNum, SIGNAL( dataChanged( ) ), this, SLOT( sampNumChanged( ) ) ); + connect(&m_b->m_mainNum, SIGNAL(dataChanged()), this, SLOT(mainNumChanged())); + connect(&m_b->m_subNum, SIGNAL(dataChanged()), this, SLOT(subNumChanged())); + connect(&m_b->m_sampNum, SIGNAL(dataChanged()), this, SLOT(sampNumChanged())); - connect( manualBtn, SIGNAL (clicked ( bool ) ), this, SLOT ( manualBtnClicked() ) ); + connect(m_manualBtn, SIGNAL (clicked (bool)), this, SLOT (manualBtnClicked())); - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - connect( b->modOutSec[i], &ComboBoxModel::dataChanged, this, [this, i]() { modOutSecChanged(i); }, Qt::DirectConnection ); - connect( b->modIn[i], &ComboBoxModel::dataChanged, this, [this, i]() { modInChanged(i); }, Qt::DirectConnection ); - connect( b->modIn2[i], &ComboBoxModel::dataChanged, this, [this, i]() { modIn2Changed(i); }, Qt::DirectConnection ); + connect(m_b->m_modOutSec[i], &ComboBoxModel::dataChanged, this, [this, i]() { modOutSecChanged(i); }, Qt::DirectConnection); + connect(m_b->m_modIn[i], &ComboBoxModel::dataChanged, this, [this, i]() { modInChanged(i); }, Qt::DirectConnection); + connect(m_b->m_modIn2[i], &ComboBoxModel::dataChanged, this, [this, i]() { modIn2Changed(i); }, Qt::DirectConnection); - connect( b->modEnabled[i], &BoolModel::dataChanged, this, [this, i]() { modEnabledChanged(); } ); + connect(m_b->m_modEnabled[i], &BoolModel::dataChanged, this, [this, i]() { modEnabledChanged(); }); } - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - connect( modUpArrow[i], &PixmapButton::clicked, this, [this, i]() { modUpClicked(i); } ); - connect( modDownArrow[i], &PixmapButton::clicked, this, [this, i]() { modDownClicked(i); } ); + connect(m_modUpArrow[i], &PixmapButton::clicked, this, [this, i]() { modUpClicked(i); }); + connect(m_modDownArrow[i], &PixmapButton::clicked, this, [this, i]() { modDownClicked(i); }); - connect( i1Button[i], &PixmapButton::clicked, this, [this, i]() { i1Clicked(i); } ); - connect( i2Button[i], &PixmapButton::clicked, this, [this, i]() { i2Clicked(i); } ); + connect(m_i1Button[i], &PixmapButton::clicked, this, [this, i]() { i1Clicked(i); }); + connect(m_i2Button[i], &PixmapButton::clicked, this, [this, i]() { i2Clicked(i); }); //Make changing Enabled LED update graph color - connect( b->enabled[i], SIGNAL( dataChanged( ) ), this, SLOT( mainNumChanged( ) ) ); - connect( b->subEnabled[i], SIGNAL( dataChanged( ) ), this, SLOT( subNumChanged( ) ) ); - connect( b->sampleEnabled[i], SIGNAL( dataChanged( ) ), this, SLOT( sampNumChanged( ) ) ); + connect(m_b->m_enabled[i], SIGNAL(dataChanged()), this, SLOT(mainNumChanged())); + connect(m_b->m_subEnabled[i], SIGNAL(dataChanged()), this, SLOT(subNumChanged())); + connect(m_b->m_sampleEnabled[i], SIGNAL(dataChanged()), this, SLOT(sampNumChanged())); } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - if( !b->macroTooltips[i].isEmpty() ) + if (!m_b->m_macroTooltips[i].isEmpty()) { - ToolTip::add( macroKnob[i], tr( "Macro %1: " ).arg( i + 1 ) + b->macroTooltips[i] ); + ToolTip::add(m_macroKnob[i], tr("Macro %1: ").arg(i + 1) + m_b->m_macroTooltips[i]); } - macroKnob[i]->refreshMacroColor(); + m_macroKnob[i]->refreshMacroColor(); } - b->viewOpen = true; + m_b->m_viewOpen = true; updateScroll(); updateBackground(); @@ -2041,27 +2036,27 @@ MicrowaveView::MicrowaveView( Instrument * _instrument, MicrowaveView::~MicrowaveView() { - // This got mad when using the vairable "b". - if( castModel() ) { castModel()->viewOpen = false; } + // This got mad when using the vairable "m_b". + if (castModel()) { castModel()->m_viewOpen = false; } } // Connects knobs/GUI elements to their models void MicrowaveView::modelChanged() { - graph->setModel( &b->graph ); - visvolKnob->setModel( &b->visvol ); - visualizeToggle->setModel( &b->visualize ); - subNumBox->setModel( &b->subNum ); - sampNumBox->setModel( &b->sampNum ); - loadChnlKnob->setModel( &b->loadChnl ); - mainNumBox->setModel( &b->mainNum ); - oversampleBox->setModel( &b->oversample ); - loadModeBox->setModel( &b->loadMode ); - mainFlipBtn->setModel( &b->mainFlipped ); - subFlipBtn->setModel( &b->subFlipped ); - removeDCBtn->setModel( &b->removeDC ); - oversampleModeBox->setModel( &b->oversampleMode ); + m_graph->setModel(&m_b->m_graph); + m_visvolKnob->setModel(&m_b->m_visvol); + m_visualizeToggle->setModel(&m_b->m_visualize); + m_subNumBox->setModel(&m_b->m_subNum); + m_sampNumBox->setModel(&m_b->m_sampNum); + m_loadChnlKnob->setModel(&m_b->m_loadChnl); + m_mainNumBox->setModel(&m_b->m_mainNum); + m_oversampleBox->setModel(&m_b->m_oversample); + m_loadModeBox->setModel(&m_b->m_loadMode); + m_mainFlipBtn->setModel(&m_b->m_mainFlipped); + m_subFlipBtn->setModel(&m_b->m_subFlipped); + m_removeDCBtn->setModel(&m_b->m_removeDC); + m_oversampleModeBox->setModel(&m_b->m_oversampleMode); } @@ -2073,313 +2068,313 @@ void MicrowaveView::modelChanged() // bounds of the GUI elements (e.g. instrument window resizing). void MicrowaveView::updateScroll() { - int scrollVal = ( b->scroll ) * 250.f; - int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; - int effectScrollVal = ( effectScrollBar->value() ) / 100.f * 92.f; - int mainFlipped = b->mainFlipped.value(); - int subFlipped = b->subFlipped.value(); - - int mainIsFlipped = mainFlipped * 500.f; - int mainIsNotFlipped = !mainFlipped * 500.f; - int subIsFlipped = subFlipped * 500.f; - int subIsNotFlipped = !subFlipped * 500.f; - - visimove( morphKnob, ( scrollVal < 250 ? 23 : 1500 + 176 ) - scrollVal, 172 + mainIsFlipped ); - visimove( rangeKnob, ( scrollVal < 250 ? 55 : 1500 + 208 ) - scrollVal, 172 + mainIsFlipped ); - visimove( modifyKnob, 87 - scrollVal, 172 + mainIsFlipped ); - visimove( modifyModeBox, 127 - scrollVal, 186 + mainIsFlipped ); - visimove( volKnob, 23 - scrollVal, 172 + mainIsNotFlipped ); - visimove( panKnob, 55 - scrollVal, 172 + mainIsNotFlipped ); - visimove( detuneKnob, 152 - scrollVal, 216 + mainIsFlipped ); - visimove( phaseKnob, 184 - scrollVal, 203 + mainIsNotFlipped ); - visimove( phaseRandKnob, 209 - scrollVal, 203 + mainIsNotFlipped ); - visimove( enabledToggle, 85 - scrollVal, 229 ); - visimove( mutedToggle, 103 - scrollVal, 229 ); - visimove( sampLenKnob, 137 - scrollVal, 172 + mainIsNotFlipped ); - visimove( morphMaxKnob, 101 - scrollVal, 172 + mainIsNotFlipped ); - visimove( unisonVoicesKnob, 184 - scrollVal, 172 ); - visimove( unisonDetuneKnob, 209 - scrollVal, 172 ); - visimove( unisonMorphKnob, 184 - scrollVal, 203 + mainIsFlipped ); - visimove( unisonModifyKnob, 209 - scrollVal, 203 + mainIsFlipped ); - visimove( keytrackingToggle, 121 - scrollVal, 229 + mainIsFlipped ); - visimove( tempoKnob, 152 - scrollVal, 216 + mainIsNotFlipped ); - visimove( interpolateToggle, 121 - scrollVal, 229 + mainIsNotFlipped ); - - visimove( sampleEnabledToggle, 85 + 500 - scrollVal, 229 ); - visimove( sampleMutedToggle, 103 + 500 - scrollVal, 229 ); - visimove( sampleKeytrackingToggle, 121 + 500 - scrollVal, 229 ); - visimove( sampleGraphEnabledToggle, 138 + 500 - scrollVal, 229 ); - visimove( sampleLoopToggle, 155 + 500 - scrollVal, 229 ); - visimove( sampleVolumeKnob, 23 + 500 - scrollVal, 172 ); - visimove( samplePanningKnob, 55 + 500 - scrollVal, 172 ); - visimove( sampleDetuneKnob, 93 + 500 - scrollVal, 172 ); - visimove( samplePhaseKnob, 180 + 500 - scrollVal, 172 ); - visimove( samplePhaseRandKnob, 206 + 500 - scrollVal, 172 ); - visimove( sampleStartKnob, 121 + 500 - scrollVal, 172 ); - visimove( sampleEndKnob, 145 + 500 - scrollVal, 172 ); - - for( int i = 0; i < 8; ++i ) + int m_scrollVal = (m_b->m_scroll) * 250.f; + int modScrollVal = (m_matrixScrollBar->value()) / 100.f * 115.f; + int m_effectScrollVal = (m_effectScrollBar->value()) / 100.f * 92.f; + int m_mainFlipped = m_b->m_mainFlipped.value(); + int m_subFlipped = m_b->m_subFlipped.value(); + + int mainIsFlipped = m_mainFlipped * 500.f; + int mainIsNotFlipped = !m_mainFlipped * 500.f; + int m_subIsFlipped = m_subFlipped * 500.f; + int m_subIsNotFlipped = !m_subFlipped * 500.f; + + visimove(m_morphKnob, (m_scrollVal < 250 ? 23 : 1500 + 176) - m_scrollVal, 172 + mainIsFlipped); + visimove(m_rangeKnob, (m_scrollVal < 250 ? 55 : 1500 + 208) - m_scrollVal, 172 + mainIsFlipped); + visimove(m_modifyKnob, 87 - m_scrollVal, 172 + mainIsFlipped); + visimove(m_modifyModeBox, 127 - m_scrollVal, 186 + mainIsFlipped); + visimove(m_volKnob, 23 - m_scrollVal, 172 + mainIsNotFlipped); + visimove(m_panKnob, 55 - m_scrollVal, 172 + mainIsNotFlipped); + visimove(m_detuneKnob, 152 - m_scrollVal, 216 + mainIsFlipped); + visimove(m_phaseKnob, 184 - m_scrollVal, 203 + mainIsNotFlipped); + visimove(m_phaseRandKnob, 209 - m_scrollVal, 203 + mainIsNotFlipped); + visimove(m_enabledToggle, 85 - m_scrollVal, 229); + visimove(m_mutedToggle, 103 - m_scrollVal, 229); + visimove(m_sampLenKnob, 137 - m_scrollVal, 172 + mainIsNotFlipped); + visimove(m_morphMaxKnob, 101 - m_scrollVal, 172 + mainIsNotFlipped); + visimove(m_unisonVoicesKnob, 184 - m_scrollVal, 172); + visimove(m_unisonDetuneKnob, 209 - m_scrollVal, 172); + visimove(m_unisonMorphKnob, 184 - m_scrollVal, 203 + mainIsFlipped); + visimove(m_unisonModifyKnob, 209 - m_scrollVal, 203 + mainIsFlipped); + visimove(m_keytrackingToggle, 121 - m_scrollVal, 229 + mainIsFlipped); + visimove(m_tempoKnob, 152 - m_scrollVal, 216 + mainIsNotFlipped); + visimove(m_interpolateToggle, 121 - m_scrollVal, 229 + mainIsNotFlipped); + + visimove(m_sampleEnabledToggle, 85 + 500 - m_scrollVal, 229); + visimove(m_sampleMutedToggle, 103 + 500 - m_scrollVal, 229); + visimove(m_sampleKeytrackingToggle, 121 + 500 - m_scrollVal, 229); + visimove(m_sampleGraphEnabledToggle, 138 + 500 - m_scrollVal, 229); + visimove(m_sampleLoopToggle, 155 + 500 - m_scrollVal, 229); + visimove(m_sampleVolumeKnob, 23 + 500 - m_scrollVal, 172); + visimove(m_samplePanningKnob, 55 + 500 - m_scrollVal, 172); + visimove(m_sampleDetuneKnob, 93 + 500 - m_scrollVal, 172); + visimove(m_samplePhaseKnob, 180 + 500 - m_scrollVal, 172); + visimove(m_samplePhaseRandKnob, 206 + 500 - m_scrollVal, 172); + visimove(m_sampleStartKnob, 121 + 500 - m_scrollVal, 172); + visimove(m_sampleEndKnob, 145 + 500 - m_scrollVal, 172); + + for (int i = 0; i < 8; ++i) { - visimove( filtCutoffKnob[i], 32 + 1000 - scrollVal, i*92+55 - effectScrollVal ); - visimove( filtResoKnob[i], 63 + 1000 - scrollVal, i*92+55 - effectScrollVal ); - visimove( filtGainKnob[i], 94 + 1000 - scrollVal, i*92+55 - effectScrollVal ); - - visimove( filtTypeBox[i], 128 + 1000 - scrollVal, i*92+63 - effectScrollVal ); - visimove( filtSlopeBox[i], 171 + 1000 - scrollVal, i*92+63 - effectScrollVal ); - visimove( filtInVolKnob[i], 30 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtOutVolKnob[i], 55 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtWetDryKnob[i], 80 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtBalKnob[i], 105 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtSatuKnob[i], 135 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtFeedbackKnob[i], 167 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtDetuneKnob[i], 192 + 1000 - scrollVal, i*92+91 - effectScrollVal ); - visimove( filtEnabledToggle[i], 27 + 1000 - scrollVal, i*92+36 - effectScrollVal ); - visimove( filtMutedToggle[i], 166 + 1000 - scrollVal, i*92+36 - effectScrollVal ); - visimove( filtKeytrackingToggle[i], 200 + 1000 - scrollVal, i*92+36 - effectScrollVal ); + visimove(m_filtCutoffKnob[i], 32 + 1000 - m_scrollVal, i*92+55 - m_effectScrollVal); + visimove(m_filtResoKnob[i], 63 + 1000 - m_scrollVal, i*92+55 - m_effectScrollVal); + visimove(m_filtGainKnob[i], 94 + 1000 - m_scrollVal, i*92+55 - m_effectScrollVal); + + visimove(m_filtTypeBox[i], 128 + 1000 - m_scrollVal, i*92+63 - m_effectScrollVal); + visimove(m_filtSlopeBox[i], 171 + 1000 - m_scrollVal, i*92+63 - m_effectScrollVal); + visimove(m_filtInVolKnob[i], 30 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtOutVolKnob[i], 55 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtWetDryKnob[i], 80 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtBalKnob[i], 105 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtSatuKnob[i], 135 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtFeedbackKnob[i], 167 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtDetuneKnob[i], 192 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); + visimove(m_filtEnabledToggle[i], 27 + 1000 - m_scrollVal, i*92+36 - m_effectScrollVal); + visimove(m_filtMutedToggle[i], 166 + 1000 - m_scrollVal, i*92+36 - m_effectScrollVal); + visimove(m_filtKeytrackingToggle[i], 200 + 1000 - m_scrollVal, i*92+36 - m_effectScrollVal); } - visimove( subVolKnob, 23 + 250 - scrollVal, 172 + subIsFlipped ); - visimove( subPanningKnob, 55 + 250 - scrollVal, 172 + subIsFlipped ); - visimove( subDetuneKnob, 95 + 250 - scrollVal, 172 + subIsFlipped ); - visimove( subPhaseKnob, 180 + 250 - scrollVal, 172 ); - visimove( subPhaseRandKnob, 206 + 250 - scrollVal, 172 ); - visimove( subSampLenKnob, 130 + 250 - scrollVal, 172 + subIsFlipped ); - visimove( subTempoKnob, 23 + 250 - scrollVal, 172 + subIsNotFlipped ); - visimove( subRateLimitKnob, 55 + 250 - scrollVal, 172 + subIsNotFlipped ); - visimove( subUnisonNumKnob, 95 + 250 - scrollVal, 172 + subIsNotFlipped ); - visimove( subUnisonDetuneKnob, 130 + 250 - scrollVal, 172 + subIsNotFlipped ); - - if( subIsNotFlipped ) + visimove(m_subVolKnob, 23 + 250 - m_scrollVal, 172 + m_subIsFlipped); + visimove(m_subPanningKnob, 55 + 250 - m_scrollVal, 172 + m_subIsFlipped); + visimove(m_subDetuneKnob, 95 + 250 - m_scrollVal, 172 + m_subIsFlipped); + visimove(m_subPhaseKnob, 180 + 250 - m_scrollVal, 172); + visimove(m_subPhaseRandKnob, 206 + 250 - m_scrollVal, 172); + visimove(m_subSampLenKnob, 130 + 250 - m_scrollVal, 172 + m_subIsFlipped); + visimove(m_subTempoKnob, 23 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); + visimove(m_subRateLimitKnob, 55 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); + visimove(m_subUnisonNumKnob, 95 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); + visimove(m_subUnisonDetuneKnob, 130 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); + + if (m_subIsNotFlipped) { - visimove( subEnabledToggle, 85 + 250 - scrollVal, 229 ); - visimove( subMutedToggle, 103 + 250 - scrollVal, 229 ); - visimove( subKeytrackToggle, 121 + 250 - scrollVal, 229 ); - visimove( subNoiseToggle, 138 + 250 - scrollVal, 229 ); - visimove( subInterpolateToggle, 155 + 250 - scrollVal, 229 ); + visimove(m_subEnabledToggle, 85 + 250 - m_scrollVal, 229); + visimove(m_subMutedToggle, 103 + 250 - m_scrollVal, 229); + visimove(m_subKeytrackToggle, 121 + 250 - m_scrollVal, 229); + visimove(m_subNoiseToggle, 138 + 250 - m_scrollVal, 229); + visimove(m_subInterpolateToggle, 155 + 250 - m_scrollVal, 229); } else { - visimove( subEnabledToggle, 85 + 250 - scrollVal, 235 ); - visimove( subMutedToggle, 103 + 250 - scrollVal, 235 ); - visimove( subKeytrackToggle, 121 + 250 - scrollVal, 235 ); - visimove( subNoiseToggle, 138 + 250 - scrollVal, 235 ); - visimove( subInterpolateToggle, 155 + 250 - scrollVal, 235 ); + visimove(m_subEnabledToggle, 85 + 250 - m_scrollVal, 235); + visimove(m_subMutedToggle, 103 + 250 - m_scrollVal, 235); + visimove(m_subKeytrackToggle, 121 + 250 - m_scrollVal, 235); + visimove(m_subNoiseToggle, 138 + 250 - m_scrollVal, 235); + visimove(m_subInterpolateToggle, 155 + 250 - m_scrollVal, 235); } int matrixRemainder = modScrollVal % 460; int matrixDivide = modScrollVal / 460 * 4; - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - if( i+matrixDivide < 64 ) + if (i+matrixDivide < 64) { - modOutSecBox[i]->setModel( b->modOutSec[i+matrixDivide] ); - modOutSigBox[i]->setModel( b->modOutSig[i+matrixDivide] ); - modOutSecNumBox[i]->setModel( b->modOutSecNum[i+matrixDivide] ); + m_modOutSecBox[i]->setModel(m_b->m_modOutSec[i+matrixDivide]); + m_modOutSigBox[i]->setModel(m_b->m_modOutSig[i+matrixDivide]); + m_modOutSecNumBox[i]->setModel(m_b->m_modOutSecNum[i+matrixDivide]); - modInBox[i]->setModel( b->modIn[i+matrixDivide] ); - modInNumBox[i]->setModel( b->modInNum[i+matrixDivide] ); - modInAmntKnob[i]->setModel( b->modInAmnt[i+matrixDivide] ); - modInCurveKnob[i]->setModel( b->modInCurve[i+matrixDivide] ); + m_modInBox[i]->setModel(m_b->m_modIn[i+matrixDivide]); + m_modInNumBox[i]->setModel(m_b->m_modInNum[i+matrixDivide]); + m_modInAmntKnob[i]->setModel(m_b->m_modInAmnt[i+matrixDivide]); + m_modInCurveKnob[i]->setModel(m_b->m_modInCurve[i+matrixDivide]); - modInBox2[i]->setModel( b->modIn2[i+matrixDivide] ); - modInNumBox2[i]->setModel( b->modInNum2[i+matrixDivide] ); - modInAmntKnob2[i]->setModel( b->modInAmnt2[i+matrixDivide] ); - modInCurveKnob2[i]->setModel( b->modInCurve2[i+matrixDivide] ); + m_modInBox2[i]->setModel(m_b->m_modIn2[i+matrixDivide]); + m_modInNumBox2[i]->setModel(m_b->m_modInNum2[i+matrixDivide]); + m_modInAmntKnob2[i]->setModel(m_b->m_modInAmnt2[i+matrixDivide]); + m_modInCurveKnob2[i]->setModel(m_b->m_modInCurve2[i+matrixDivide]); - modEnabledToggle[i]->setModel( b->modEnabled[i+matrixDivide] ); + m_modEnabledToggle[i]->setModel(m_b->m_modEnabled[i+matrixDivide]); - modCombineTypeBox[i]->setModel( b->modCombineType[i+matrixDivide] ); + m_modCombineTypeBox[i]->setModel(m_b->m_modCombineType[i+matrixDivide]); - modTypeToggle[i]->setModel( b->modType[i+matrixDivide] ); - modType2Toggle[i]->setModel( b->modType2[i+matrixDivide] ); + m_modTypeToggle[i]->setModel(m_b->m_modType[i+matrixDivide]); + m_modType2Toggle[i]->setModel(m_b->m_modType2[i+matrixDivide]); - modNumText[i]->setText( QString::number(i+matrixDivide+1) ); + m_modNumText[i]->setText(QString::number(i+matrixDivide+1)); - modInAmntKnob[i]->setMatrixLocation( 4, 1, i ); - modInCurveKnob[i]->setMatrixLocation( 4, 2, i ); - modInAmntKnob2[i]->setMatrixLocation( 4, 3, i ); - modInCurveKnob2[i]->setMatrixLocation( 4, 4, i ); + m_modInAmntKnob[i]->setMatrixLocation(4, 1, i); + m_modInCurveKnob[i]->setMatrixLocation(4, 2, i); + m_modInAmntKnob2[i]->setMatrixLocation(4, 3, i); + m_modInCurveKnob2[i]->setMatrixLocation(4, 4, i); } // Bug evasion. Without this, some display glitches happen in certain conditions. - modOutSecChanged( i+matrixDivide ); - modInChanged( i+matrixDivide ); - modIn2Changed( i+matrixDivide ); - - visimove( modInBox[i], 45 + 750 - scrollVal, i*115+57 - matrixRemainder ); - visimove( modInNumBox[i], 90 + 750 - scrollVal, i*115+57 - matrixRemainder ); - visimove( modInAmntKnob[i], 136 + 750 - scrollVal, i*115+53 - matrixRemainder ); - visimove( modInCurveKnob[i], 161 + 750 - scrollVal, i*115+53 - matrixRemainder ); - visimove( modInBox2[i], 45 + 750 - scrollVal, i*115+118 - matrixRemainder ); - visimove( modInNumBox2[i], 90 + 750 - scrollVal, i*115+118 - matrixRemainder ); - visimove( modInAmntKnob2[i], 136 + 750 - scrollVal, i*115+114 - matrixRemainder ); - visimove( modInCurveKnob2[i], 161 + 750 - scrollVal, i*115+114 - matrixRemainder ); - visimove( modOutSecBox[i], 27 + 750 - scrollVal, i*115+88 - matrixRemainder ); - visimove( modOutSigBox[i], 69 + 750 - scrollVal, i*115+88 - matrixRemainder ); - visimove( modOutSecNumBox[i], 112 + 750 - scrollVal, i*115+88 - matrixRemainder ); - visimove( modEnabledToggle[i], 27 + 750 - scrollVal, i*115+36 - matrixRemainder ); - visimove( modCombineTypeBox[i], 149 + 750 - scrollVal, i*115+88 - matrixRemainder ); - visimove( modTypeToggle[i], 195 + 750 - scrollVal, i*115+67 - matrixRemainder ); - visimove( modType2Toggle[i], 195 + 750 - scrollVal, i*115+128 - matrixRemainder ); - visimove( modUpArrow[i], 181 + 750 - scrollVal, i*115+37 - matrixRemainder ); - visimove( modDownArrow[i], 199 + 750 - scrollVal, i*115+37 - matrixRemainder ); - visimove( i1Button[i], 25 + 750 - scrollVal, i*115+50 - matrixRemainder ); - visimove( i2Button[i], 25 + 750 - scrollVal, i*115+112 - matrixRemainder ); - visimove( modNumText[i], 192 + 750 - scrollVal, i*115+89 - matrixRemainder ); + modOutSecChanged(i+matrixDivide); + modInChanged(i+matrixDivide); + modIn2Changed(i+matrixDivide); + + visimove(m_modInBox[i], 45 + 750 - m_scrollVal, i*115+57 - matrixRemainder); + visimove(m_modInNumBox[i], 90 + 750 - m_scrollVal, i*115+57 - matrixRemainder); + visimove(m_modInAmntKnob[i], 136 + 750 - m_scrollVal, i*115+53 - matrixRemainder); + visimove(m_modInCurveKnob[i], 161 + 750 - m_scrollVal, i*115+53 - matrixRemainder); + visimove(m_modInBox2[i], 45 + 750 - m_scrollVal, i*115+118 - matrixRemainder); + visimove(m_modInNumBox2[i], 90 + 750 - m_scrollVal, i*115+118 - matrixRemainder); + visimove(m_modInAmntKnob2[i], 136 + 750 - m_scrollVal, i*115+114 - matrixRemainder); + visimove(m_modInCurveKnob2[i], 161 + 750 - m_scrollVal, i*115+114 - matrixRemainder); + visimove(m_modOutSecBox[i], 27 + 750 - m_scrollVal, i*115+88 - matrixRemainder); + visimove(m_modOutSigBox[i], 69 + 750 - m_scrollVal, i*115+88 - matrixRemainder); + visimove(m_modOutSecNumBox[i], 112 + 750 - m_scrollVal, i*115+88 - matrixRemainder); + visimove(m_modEnabledToggle[i], 27 + 750 - m_scrollVal, i*115+36 - matrixRemainder); + visimove(m_modCombineTypeBox[i], 149 + 750 - m_scrollVal, i*115+88 - matrixRemainder); + visimove(m_modTypeToggle[i], 195 + 750 - m_scrollVal, i*115+67 - matrixRemainder); + visimove(m_modType2Toggle[i], 195 + 750 - m_scrollVal, i*115+128 - matrixRemainder); + visimove(m_modUpArrow[i], 181 + 750 - m_scrollVal, i*115+37 - matrixRemainder); + visimove(m_modDownArrow[i], 199 + 750 - m_scrollVal, i*115+37 - matrixRemainder); + visimove(m_i1Button[i], 25 + 750 - m_scrollVal, i*115+50 - matrixRemainder); + visimove(m_i2Button[i], 25 + 750 - m_scrollVal, i*115+112 - matrixRemainder); + visimove(m_modNumText[i], 192 + 750 - m_scrollVal, i*115+89 - matrixRemainder); } - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - filtCutoffKnob[i]->setModel( b->filtCutoff[i] ); - filtCutoffKnob[i]->setMatrixLocation( 6, 1, i ); + m_filtCutoffKnob[i]->setModel(m_b->m_filtCutoff[i]); + m_filtCutoffKnob[i]->setMatrixLocation(6, 1, i); - filtResoKnob[i]->setModel( b->filtReso[i] ); - filtResoKnob[i]->setMatrixLocation( 6, 2, i ); + m_filtResoKnob[i]->setModel(m_b->m_filtReso[i]); + m_filtResoKnob[i]->setMatrixLocation(6, 2, i); - filtGainKnob[i]->setModel( b->filtGain[i] ); - filtGainKnob[i]->setMatrixLocation( 6, 3, i ); + m_filtGainKnob[i]->setModel(m_b->m_filtGain[i]); + m_filtGainKnob[i]->setMatrixLocation(6, 3, i); - filtTypeBox[i]->setModel( b->filtType[i] ); + m_filtTypeBox[i]->setModel(m_b->m_filtType[i]); - filtSlopeBox[i]->setModel( b->filtSlope[i] ); + m_filtSlopeBox[i]->setModel(m_b->m_filtSlope[i]); - filtInVolKnob[i]->setModel( b->filtInVol[i] ); - filtInVolKnob[i]->setMatrixLocation( 6, 5, i ); + m_filtInVolKnob[i]->setModel(m_b->m_filtInVol[i]); + m_filtInVolKnob[i]->setMatrixLocation(6, 5, i); - filtOutVolKnob[i]->setModel( b->filtOutVol[i] ); - filtOutVolKnob[i]->setMatrixLocation( 6, 6, i ); + m_filtOutVolKnob[i]->setModel(m_b->m_filtOutVol[i]); + m_filtOutVolKnob[i]->setMatrixLocation(6, 6, i); - filtWetDryKnob[i]->setModel( b->filtWetDry[i] ); - filtWetDryKnob[i]->setMatrixLocation( 6, 7, i ); + m_filtWetDryKnob[i]->setModel(m_b->m_filtWetDry[i]); + m_filtWetDryKnob[i]->setMatrixLocation(6, 7, i); - filtBalKnob[i]->setModel( b->filtBal[i] ); - filtBalKnob[i]->setMatrixLocation( 6, 8, i ); + m_filtBalKnob[i]->setModel(m_b->m_filtBal[i]); + m_filtBalKnob[i]->setMatrixLocation(6, 8, i); - filtSatuKnob[i]->setModel( b->filtSatu[i] ); - filtSatuKnob[i]->setMatrixLocation( 6, 9, i ); + m_filtSatuKnob[i]->setModel(m_b->m_filtSatu[i]); + m_filtSatuKnob[i]->setMatrixLocation(6, 9, i); - filtFeedbackKnob[i]->setModel( b->filtFeedback[i] ); - filtFeedbackKnob[i]->setMatrixLocation( 6, 10, i ); + m_filtFeedbackKnob[i]->setModel(m_b->m_filtFeedback[i]); + m_filtFeedbackKnob[i]->setMatrixLocation(6, 10, i); - filtDetuneKnob[i]->setModel( b->filtDetune[i] ); - filtDetuneKnob[i]->setMatrixLocation( 6, 11, i ); + m_filtDetuneKnob[i]->setModel(m_b->m_filtDetune[i]); + m_filtDetuneKnob[i]->setMatrixLocation(6, 11, i); - filtEnabledToggle[i]->setModel( b->filtEnabled[i] ); + m_filtEnabledToggle[i]->setModel(m_b->m_filtEnabled[i]); - filtMutedToggle[i]->setModel( b->filtMuted[i] ); + m_filtMutedToggle[i]->setModel(m_b->m_filtMuted[i]); - filtKeytrackingToggle[i]->setModel( b->filtKeytracking[i] ); + m_filtKeytrackingToggle[i]->setModel(m_b->m_filtKeytracking[i]); } - for( int i = 0; i < 18; ++i ) + for (int i = 0; i < 18; ++i) { - macroKnob[i]->setModel( b->macro[i] ); - macroKnob[i]->setMatrixLocation( 7, i, 0 ); - macroKnob[i]->setWhichMacroKnob( i ); - refreshMacroColor( macroKnob[i], i ); + m_macroKnob[i]->setModel(m_b->m_macro[i]); + m_macroKnob[i]->setMatrixLocation(7, i, 0); + m_macroKnob[i]->setWhichMacroKnob(i); + refreshMacroColor(m_macroKnob[i], i); } - visimove( visvolKnob, 230 - scrollVal, 24 ); - - visimove( loadChnlKnob, 1500 + 111 - scrollVal, 121 ); - visimove( visualizeToggle, 213 - scrollVal, 26 ); - visimove( subNumBox, 250 + 18 - scrollVal, 219 ); - visimove( sampNumBox, 500 + 18 - scrollVal, 219 ); - visimove( mainNumBox, 18 - scrollVal, 219 ); - visimove( graph, scrollVal >= 500 ? 500 + 23 - scrollVal : 23 , 30 ); - visimove( openWavetableButton, ( scrollVal < 250 ? 54 : 1500 + 115 ) - scrollVal, scrollVal < 250 ? 220 : 24 ); - visimove( openSampleButton, 54 + 500 - scrollVal, 220 ); - - visimove( sinWaveBtn, 179 + 250 - scrollVal, 212 ); - visimove( triangleWaveBtn, 197 + 250 - scrollVal, 212 ); - visimove( sawWaveBtn, 215 + 250 - scrollVal, 212 ); - visimove( sqrWaveBtn, 179 + 250 - scrollVal, 227 ); - visimove( whiteNoiseWaveBtn, 197 + 250 - scrollVal, 227 ); - visimove( smoothBtn, 215 + 250 - scrollVal, 227 ); - visimove( usrWaveBtn, 54 + 250 - scrollVal, 220 ); - - visimove( sinWave2Btn, 179 + 500 - scrollVal, 212 ); - visimove( triangleWave2Btn, 197 + 500 - scrollVal, 212 ); - visimove( sawWave2Btn, 215 + 500 - scrollVal, 212 ); - visimove( sqrWave2Btn, 179 + 500 - scrollVal, 227 ); - visimove( whiteNoiseWave2Btn, 197 + 500 - scrollVal, 227 ); - visimove( smooth2Btn, 215 + 500 - scrollVal, 227 ); - visimove( usrWave2Btn, 54 + 500 - scrollVal, 220 ); - - visimove( oversampleBox, 70 + 1250 - scrollVal, 50 ); - - visimove( effectScrollBar, 221 + 1000 - scrollVal, 32 ); - visimove( matrixScrollBar, 221 + 750 - scrollVal, 32 ); - - visimove( filtForegroundLabel, 1000 - scrollVal, 0 ); - visimove( filtBoxesLabel, 1000 + 24 - scrollVal, 35 - ( effectScrollVal % 92 ) ); - - visimove( matrixForegroundLabel, 750 - scrollVal, 0 ); - visimove( matrixBoxesLabel, 750 + 24 - scrollVal, 35 - ( modScrollVal % 115 ) ); - - visimove( macroKnob[0], 1250 + 59 - scrollVal, 127 ); - visimove( macroKnob[1], 1250 + 81 - scrollVal, 127 ); - visimove( macroKnob[2], 1250 + 103 - scrollVal, 127 ); - visimove( macroKnob[3], 1250 + 125 - scrollVal, 127 ); - visimove( macroKnob[4], 1250 + 147 - scrollVal, 127 ); - visimove( macroKnob[5], 1250 + 169 - scrollVal, 127 ); - visimove( macroKnob[6], 1250 + 59 - scrollVal, 147 ); - visimove( macroKnob[7], 1250 + 81 - scrollVal, 147 ); - visimove( macroKnob[8], 1250 + 103 - scrollVal, 147 ); - visimove( macroKnob[9], 1250 + 125 - scrollVal, 147 ); - visimove( macroKnob[10], 1250 + 147 - scrollVal, 147 ); - visimove( macroKnob[11], 1250 + 169 - scrollVal, 147 ); - visimove( macroKnob[12], 1250 + 59 - scrollVal, 167 ); - visimove( macroKnob[13], 1250 + 81 - scrollVal, 167 ); - visimove( macroKnob[14], 1250 + 103 - scrollVal, 167 ); - visimove( macroKnob[15], 1250 + 125 - scrollVal, 167 ); - visimove( macroKnob[16], 1250 + 147 - scrollVal, 168 ); - visimove( macroKnob[17], 1250 + 169 - scrollVal, 168 ); - - visimove( tab1Btn, 1, 48 ); - visimove( tab2Btn, 1, 63 ); - visimove( tab3Btn, 1, 78 ); - visimove( tab4Btn, 1, 93 ); - visimove( tab5Btn, 1, 108 ); - visimove( tab6Btn, 1, 123 ); - - visimove( mainFlipBtn, 3 - scrollVal, 145 ); - visimove( subFlipBtn, 250 + 3 - scrollVal, 145 ); - - visimove( manualBtn, 1250 + 49 - scrollVal, 199); - - visimove( loadModeBox, 1500 + 25 - scrollVal, 76 ); - visimove( confirmLoadButton, 1500 + 93 - scrollVal, 187); - - visimove( XBtn, 231 + 1500 - scrollVal, 11 ); - visimove( MatrixXBtn, 229 + 750 - scrollVal, 8 ); - - visimove( normalizeBtn, 155 + 1500 - scrollVal, 224 ); - visimove( desawBtn, 39 + 1500 - scrollVal, 224 ); - - visimove( removeDCBtn, 1250 + 68 - scrollVal, 84 ); - visimove( oversampleModeBox, 1250 + 135 - scrollVal, 50 ); - - tabChanged( b->scroll ); - visvolKnob->setVisible( b->visualize.value() ); + visimove(m_visvolKnob, 230 - m_scrollVal, 24); + + visimove(m_loadChnlKnob, 1500 + 111 - m_scrollVal, 121); + visimove(m_visualizeToggle, 213 - m_scrollVal, 26); + visimove(m_subNumBox, 250 + 18 - m_scrollVal, 219); + visimove(m_sampNumBox, 500 + 18 - m_scrollVal, 219); + visimove(m_mainNumBox, 18 - m_scrollVal, 219); + visimove(m_graph, m_scrollVal >= 500 ? 500 + 23 - m_scrollVal : 23 , 30); + visimove(m_openWavetableButton, (m_scrollVal < 250 ? 54 : 1500 + 115) - m_scrollVal, m_scrollVal < 250 ? 220 : 24); + visimove(m_openSampleButton, 54 + 500 - m_scrollVal, 220); + + visimove(m_sinWaveBtn, 179 + 250 - m_scrollVal, 212); + visimove(m_triangleWaveBtn, 197 + 250 - m_scrollVal, 212); + visimove(m_sawWaveBtn, 215 + 250 - m_scrollVal, 212); + visimove(m_sqrWaveBtn, 179 + 250 - m_scrollVal, 227); + visimove(m_whiteNoiseWaveBtn, 197 + 250 - m_scrollVal, 227); + visimove(m_smoothBtn, 215 + 250 - m_scrollVal, 227); + visimove(m_usrWaveBtn, 54 + 250 - m_scrollVal, 220); + + visimove(m_sinWave2Btn, 179 + 500 - m_scrollVal, 212); + visimove(m_triangleWave2Btn, 197 + 500 - m_scrollVal, 212); + visimove(m_sawWave2Btn, 215 + 500 - m_scrollVal, 212); + visimove(m_sqrWave2Btn, 179 + 500 - m_scrollVal, 227); + visimove(m_whiteNoiseWave2Btn, 197 + 500 - m_scrollVal, 227); + visimove(m_smooth2Btn, 215 + 500 - m_scrollVal, 227); + visimove(m_usrWave2Btn, 54 + 500 - m_scrollVal, 220); + + visimove(m_oversampleBox, 70 + 1250 - m_scrollVal, 50); + + visimove(m_effectScrollBar, 221 + 1000 - m_scrollVal, 32); + visimove(m_matrixScrollBar, 221 + 750 - m_scrollVal, 32); + + visimove(m_filtForegroundLabel, 1000 - m_scrollVal, 0); + visimove(m_filtBoxesLabel, 1000 + 24 - m_scrollVal, 35 - (m_effectScrollVal % 92)); + + visimove(m_matrixForegroundLabel, 750 - m_scrollVal, 0); + visimove(m_matrixBoxesLabel, 750 + 24 - m_scrollVal, 35 - (modScrollVal % 115)); + + visimove(m_macroKnob[0], 1250 + 59 - m_scrollVal, 127); + visimove(m_macroKnob[1], 1250 + 81 - m_scrollVal, 127); + visimove(m_macroKnob[2], 1250 + 103 - m_scrollVal, 127); + visimove(m_macroKnob[3], 1250 + 125 - m_scrollVal, 127); + visimove(m_macroKnob[4], 1250 + 147 - m_scrollVal, 127); + visimove(m_macroKnob[5], 1250 + 169 - m_scrollVal, 127); + visimove(m_macroKnob[6], 1250 + 59 - m_scrollVal, 147); + visimove(m_macroKnob[7], 1250 + 81 - m_scrollVal, 147); + visimove(m_macroKnob[8], 1250 + 103 - m_scrollVal, 147); + visimove(m_macroKnob[9], 1250 + 125 - m_scrollVal, 147); + visimove(m_macroKnob[10], 1250 + 147 - m_scrollVal, 147); + visimove(m_macroKnob[11], 1250 + 169 - m_scrollVal, 147); + visimove(m_macroKnob[12], 1250 + 59 - m_scrollVal, 167); + visimove(m_macroKnob[13], 1250 + 81 - m_scrollVal, 167); + visimove(m_macroKnob[14], 1250 + 103 - m_scrollVal, 167); + visimove(m_macroKnob[15], 1250 + 125 - m_scrollVal, 167); + visimove(m_macroKnob[16], 1250 + 147 - m_scrollVal, 168); + visimove(m_macroKnob[17], 1250 + 169 - m_scrollVal, 168); + + visimove(m_tab1Btn, 1, 48); + visimove(m_tab2Btn, 1, 63); + visimove(m_tab3Btn, 1, 78); + visimove(m_tab4Btn, 1, 93); + visimove(m_tab5Btn, 1, 108); + visimove(m_tab6Btn, 1, 123); + + visimove(m_mainFlipBtn, 3 - m_scrollVal, 145); + visimove(m_subFlipBtn, 250 + 3 - m_scrollVal, 145); + + visimove(m_manualBtn, 1250 + 49 - m_scrollVal, 199); + + visimove(m_loadModeBox, 1500 + 25 - m_scrollVal, 76); + visimove(m_confirmLoadButton, 1500 + 93 - m_scrollVal, 187); + + visimove(m_XBtn, 231 + 1500 - m_scrollVal, 11); + visimove(m_MatrixXBtn, 229 + 750 - m_scrollVal, 8); + + visimove(m_normalizeBtn, 155 + 1500 - m_scrollVal, 224); + visimove(m_desawBtn, 39 + 1500 - m_scrollVal, 224); + + visimove(m_removeDCBtn, 1250 + 68 - m_scrollVal, 84); + visimove(m_oversampleModeBox, 1250 + 135 - m_scrollVal, 50); + + tabChanged(m_b->m_scroll); + m_visvolKnob->setVisible(m_b->m_visualize.value()); } -void MicrowaveView::wheelEvent( QWheelEvent * _me ) +void MicrowaveView::wheelEvent(QWheelEvent * me) { - if( _me->x() <= 18 && _me->y() >= 48 && _me->y() <= 138 )// If scroll over tab buttons + if (me->x() <= 18 && me->y() >= 48 && me->y() <= 138)// If scroll over tab buttons { - if( b->scroll != 6 ) + if (m_b->m_scroll != 6) { - if( _me->delta() < 0 && b->scroll != 5 ) + if (me->delta() < 0 && m_b->m_scroll != 5) { - b->scroll += 1; + m_b->m_scroll += 1; updateScroll(); } - else if( _me->delta() > 0 && b->scroll > 0 ) + else if (me->delta() > 0 && m_b->m_scroll > 0) { - b->scroll -= 1; + m_b->m_scroll -= 1; updateScroll(); } } @@ -2387,72 +2382,72 @@ void MicrowaveView::wheelEvent( QWheelEvent * _me ) } -void MicrowaveView::setGraphEnabledColor( bool isEnabled ) +void MicrowaveView::setGraphEnabledColor(bool isEnabled) { - graph->setGraphColor( isEnabled ? QColor( 121, 222, 239 ) : QColor( 197, 197, 197 ) ); - pal = QPalette(); - pal.setBrush( backgroundRole(), isEnabled ? PLUGIN_NAME::getIconPixmap("wavegraph") : PLUGIN_NAME::getIconPixmap("wavegraphdisabled") ); - graph->setPalette( pal ); + m_graph->setGraphColor(isEnabled ? QColor(121, 222, 239) : QColor(197, 197, 197)); + m_pal = QPalette(); + m_pal.setBrush(backgroundRole(), isEnabled ? PLUGIN_NAME::getIconPixmap("wavegraph") : PLUGIN_NAME::getIconPixmap("wavegraphdisabled")); + m_graph->setPalette(m_pal); } // Trades out the GUI elements when switching between oscillators void MicrowaveView::mainNumChanged() { - setGraphEnabledColor( b->enabled[b->mainNum.value()-1]->value() ); + setGraphEnabledColor(m_b->m_enabled[m_b->m_mainNum.value()-1]->value()); - int mainNumValue = b->mainNum.value() - 1; + int mainNumValue = m_b->m_mainNum.value() - 1; - morphKnob->setModel( b->morph[mainNumValue] ); - morphKnob->setMatrixLocation( 1, 1, mainNumValue ); + m_morphKnob->setModel(m_b->m_morph[mainNumValue]); + m_morphKnob->setMatrixLocation(1, 1, mainNumValue); - rangeKnob->setModel( b->range[mainNumValue] ); - rangeKnob->setMatrixLocation( 1, 2, mainNumValue ); + m_rangeKnob->setModel(m_b->m_range[mainNumValue]); + m_rangeKnob->setMatrixLocation(1, 2, mainNumValue); - sampLenKnob->setModel( b->sampLen[mainNumValue] ); + m_sampLenKnob->setModel(m_b->m_sampLen[mainNumValue]); - modifyKnob->setModel( b->modify[mainNumValue] ); - modifyKnob->setMatrixLocation( 1, 3, mainNumValue ); + m_modifyKnob->setModel(m_b->m_modify[mainNumValue]); + m_modifyKnob->setMatrixLocation(1, 3, mainNumValue); - morphMaxKnob->setModel( b->morphMax[mainNumValue] ); + m_morphMaxKnob->setModel(m_b->m_morphMax[mainNumValue]); - unisonVoicesKnob->setModel( b->unisonVoices[mainNumValue] ); - unisonVoicesKnob->setMatrixLocation( 1, 8, mainNumValue ); + m_unisonVoicesKnob->setModel(m_b->m_unisonVoices[mainNumValue]); + m_unisonVoicesKnob->setMatrixLocation(1, 8, mainNumValue); - unisonDetuneKnob->setModel( b->unisonDetune[mainNumValue] ); - unisonDetuneKnob->setMatrixLocation( 1, 9, mainNumValue ); + m_unisonDetuneKnob->setModel(m_b->m_unisonDetune[mainNumValue]); + m_unisonDetuneKnob->setMatrixLocation(1, 9, mainNumValue); - unisonMorphKnob->setModel( b->unisonMorph[mainNumValue] ); - unisonMorphKnob->setMatrixLocation( 1, 10, mainNumValue ); + m_unisonMorphKnob->setModel(m_b->m_unisonMorph[mainNumValue]); + m_unisonMorphKnob->setMatrixLocation(1, 10, mainNumValue); - unisonModifyKnob->setModel( b->unisonModify[mainNumValue] ); - unisonModifyKnob->setMatrixLocation( 1, 11, mainNumValue ); + m_unisonModifyKnob->setModel(m_b->m_unisonModify[mainNumValue]); + m_unisonModifyKnob->setMatrixLocation(1, 11, mainNumValue); - detuneKnob->setModel( b->detune[mainNumValue] ); - detuneKnob->setMatrixLocation( 1, 4, mainNumValue ); + m_detuneKnob->setModel(m_b->m_detune[mainNumValue]); + m_detuneKnob->setMatrixLocation(1, 4, mainNumValue); - modifyModeBox-> setModel( b-> modifyMode[mainNumValue] ); + m_modifyModeBox-> setModel(m_b-> m_modifyMode[mainNumValue]); - phaseKnob->setModel( b->phase[mainNumValue] ); - phaseKnob->setMatrixLocation( 1, 5, mainNumValue ); + m_phaseKnob->setModel(m_b->m_phase[mainNumValue]); + m_phaseKnob->setMatrixLocation(1, 5, mainNumValue); - phaseRandKnob->setModel( b->phaseRand[mainNumValue] ); + m_phaseRandKnob->setModel(m_b->m_phaseRand[mainNumValue]); - volKnob->setModel( b->vol[mainNumValue] ); - volKnob->setMatrixLocation( 1, 6, mainNumValue ); + m_volKnob->setModel(m_b->m_vol[mainNumValue]); + m_volKnob->setMatrixLocation(1, 6, mainNumValue); - panKnob->setModel( b->pan[mainNumValue] ); - panKnob->setMatrixLocation( 1, 7, mainNumValue ); + m_panKnob->setModel(m_b->m_pan[mainNumValue]); + m_panKnob->setMatrixLocation(1, 7, mainNumValue); - enabledToggle->setModel( b->enabled[mainNumValue] ); + m_enabledToggle->setModel(m_b->m_enabled[mainNumValue]); - mutedToggle->setModel( b->muted[mainNumValue] ); + m_mutedToggle->setModel(m_b->m_muted[mainNumValue]); - keytrackingToggle->setModel( b->keytracking[mainNumValue] ); + m_keytrackingToggle->setModel(m_b->m_keytracking[mainNumValue]); - tempoKnob->setModel( b->tempo[mainNumValue] ); + m_tempoKnob->setModel(m_b->m_tempo[mainNumValue]); - interpolateToggle->setModel( b->interpolate[mainNumValue] ); + m_interpolateToggle->setModel(m_b->m_interpolate[mainNumValue]); } @@ -2460,49 +2455,49 @@ void MicrowaveView::mainNumChanged() // Trades out the GUI elements when switching between oscillators, and adjusts graph length when needed void MicrowaveView::subNumChanged() { - b->graph.setLength( b->subSampLen[b->subNum.value()-1]->value() ); - b->graph.setSamples( b->storedsubs[b->subNum.value()-1] ); - setGraphEnabledColor( b->subEnabled[b->subNum.value()-1]->value() ); + m_b->m_graph.setLength(m_b->m_subSampLen[m_b->m_subNum.value()-1]->value()); + m_b->m_graph.setSamples(m_b->m_storedsubs[m_b->m_subNum.value()-1]); + setGraphEnabledColor(m_b->m_subEnabled[m_b->m_subNum.value()-1]->value()); - int subNumValue = b->subNum.value() - 1; + int subNumValue = m_b->m_subNum.value() - 1; - subVolKnob->setModel( b->subVol[subNumValue] ); - subVolKnob->setMatrixLocation( 2, 3, subNumValue ); + m_subVolKnob->setModel(m_b->m_subVol[subNumValue]); + m_subVolKnob->setMatrixLocation(2, 3, subNumValue); - subEnabledToggle->setModel( b->subEnabled[subNumValue] ); + m_subEnabledToggle->setModel(m_b->m_subEnabled[subNumValue]); - subPhaseKnob->setModel( b->subPhase[subNumValue] ); - subPhaseKnob->setMatrixLocation( 2, 2, subNumValue ); + m_subPhaseKnob->setModel(m_b->m_subPhase[subNumValue]); + m_subPhaseKnob->setMatrixLocation(2, 2, subNumValue); - subPhaseRandKnob->setModel( b->subPhaseRand[subNumValue] ); + m_subPhaseRandKnob->setModel(m_b->m_subPhaseRand[subNumValue]); - subDetuneKnob->setModel( b->subDetune[subNumValue] ); - subDetuneKnob->setMatrixLocation( 2, 1, subNumValue ); + m_subDetuneKnob->setModel(m_b->m_subDetune[subNumValue]); + m_subDetuneKnob->setMatrixLocation(2, 1, subNumValue); - subMutedToggle->setModel( b->subMuted[subNumValue] ); + m_subMutedToggle->setModel(m_b->m_subMuted[subNumValue]); - subKeytrackToggle->setModel( b->subKeytrack[subNumValue] ); + m_subKeytrackToggle->setModel(m_b->m_subKeytrack[subNumValue]); - subSampLenKnob->setModel( b->subSampLen[subNumValue] ); - subSampLenKnob->setMatrixLocation( 2, 5, subNumValue ); + m_subSampLenKnob->setModel(m_b->m_subSampLen[subNumValue]); + m_subSampLenKnob->setMatrixLocation(2, 5, subNumValue); - subNoiseToggle->setModel( b->subNoise[subNumValue] ); + m_subNoiseToggle->setModel(m_b->m_subNoise[subNumValue]); - subPanningKnob->setModel( b->subPanning[subNumValue] ); - subPanningKnob->setMatrixLocation( 2, 4, subNumValue ); + m_subPanningKnob->setModel(m_b->m_subPanning[subNumValue]); + m_subPanningKnob->setMatrixLocation(2, 4, subNumValue); - subTempoKnob->setModel( b->subTempo[subNumValue] ); + m_subTempoKnob->setModel(m_b->m_subTempo[subNumValue]); - subRateLimitKnob->setModel( b->subRateLimit[subNumValue] ); - subRateLimitKnob->setMatrixLocation( 2, 6, subNumValue ); + m_subRateLimitKnob->setModel(m_b->m_subRateLimit[subNumValue]); + m_subRateLimitKnob->setMatrixLocation(2, 6, subNumValue); - subUnisonNumKnob->setModel( b->subUnisonNum[subNumValue] ); - subUnisonNumKnob->setMatrixLocation( 2, 7, subNumValue ); + m_subUnisonNumKnob->setModel(m_b->m_subUnisonNum[subNumValue]); + m_subUnisonNumKnob->setMatrixLocation(2, 7, subNumValue); - subUnisonDetuneKnob->setModel( b->subUnisonDetune[subNumValue] ); - subUnisonDetuneKnob->setMatrixLocation( 2, 8, subNumValue ); + m_subUnisonDetuneKnob->setModel(m_b->m_subUnisonDetune[subNumValue]); + m_subUnisonDetuneKnob->setMatrixLocation(2, 8, subNumValue); - subInterpolateToggle->setModel( b->subInterpolate[subNumValue] ); + m_subInterpolateToggle->setModel(m_b->m_subInterpolate[subNumValue]); } @@ -2510,111 +2505,111 @@ void MicrowaveView::subNumChanged() // Trades out the GUI elements when switching between oscillators void MicrowaveView::sampNumChanged() { - setGraphEnabledColor( b->sampleEnabled[b->sampNum.value()-1]->value() ); + setGraphEnabledColor(m_b->m_sampleEnabled[m_b->m_sampNum.value()-1]->value()); - for( int i = 0; i < 128; ++i ) + for (int i = 0; i < 128; ++i) { - b->graph.setSampleAt( i, b->sampGraphs[(b->sampNum.value()-1)*128+i] ); + m_b->m_graph.setSampleAt(i, m_b->m_sampGraphs[(m_b->m_sampNum.value()-1)*128+i]); } - int sampNumValue = b->sampNum.value() - 1; + int sampNumValue = m_b->m_sampNum.value() - 1; - sampleEnabledToggle->setModel( b->sampleEnabled[sampNumValue] ); - sampleGraphEnabledToggle->setModel( b->sampleGraphEnabled[sampNumValue] ); - sampleMutedToggle->setModel( b->sampleMuted[sampNumValue] ); - sampleKeytrackingToggle->setModel( b->sampleKeytracking[sampNumValue] ); - sampleLoopToggle->setModel( b->sampleLoop[sampNumValue] ); + m_sampleEnabledToggle->setModel(m_b->m_sampleEnabled[sampNumValue]); + m_sampleGraphEnabledToggle->setModel(m_b->m_sampleGraphEnabled[sampNumValue]); + m_sampleMutedToggle->setModel(m_b->m_sampleMuted[sampNumValue]); + m_sampleKeytrackingToggle->setModel(m_b->m_sampleKeytracking[sampNumValue]); + m_sampleLoopToggle->setModel(m_b->m_sampleLoop[sampNumValue]); - sampleVolumeKnob->setModel( b->sampleVolume[sampNumValue] ); - sampleVolumeKnob->setMatrixLocation( 3, 3, sampNumValue ); + m_sampleVolumeKnob->setModel(m_b->m_sampleVolume[sampNumValue]); + m_sampleVolumeKnob->setMatrixLocation(3, 3, sampNumValue); - samplePanningKnob->setModel( b->samplePanning[sampNumValue] ); - samplePanningKnob->setMatrixLocation( 3, 4, sampNumValue ); + m_samplePanningKnob->setModel(m_b->m_samplePanning[sampNumValue]); + m_samplePanningKnob->setMatrixLocation(3, 4, sampNumValue); - sampleDetuneKnob->setModel( b->sampleDetune[sampNumValue] ); - sampleDetuneKnob->setMatrixLocation( 3, 1, sampNumValue ); + m_sampleDetuneKnob->setModel(m_b->m_sampleDetune[sampNumValue]); + m_sampleDetuneKnob->setMatrixLocation(3, 1, sampNumValue); - samplePhaseKnob->setModel( b->samplePhase[sampNumValue] ); - samplePhaseKnob->setMatrixLocation( 3, 2, sampNumValue ); + m_samplePhaseKnob->setModel(m_b->m_samplePhase[sampNumValue]); + m_samplePhaseKnob->setMatrixLocation(3, 2, sampNumValue); - samplePhaseRandKnob->setModel( b->samplePhaseRand[sampNumValue] ); + m_samplePhaseRandKnob->setModel(m_b->m_samplePhaseRand[sampNumValue]); - sampleStartKnob->setModel( b->sampleStart[sampNumValue] ); + m_sampleStartKnob->setModel(m_b->m_sampleStart[sampNumValue]); - sampleEndKnob->setModel( b->sampleEnd[sampNumValue] ); + m_sampleEndKnob->setModel(m_b->m_sampleEnd[sampNumValue]); } // Moves/changes the GUI around depending on the mod out section value -void MicrowaveView::modOutSecChanged( int i ) +void MicrowaveView::modOutSecChanged(int i) { - int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int modScrollVal = (m_matrixScrollBar->value()) / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - if( i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64 ) + if (i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64) { - temp1 = b->modOutSig[i]->value(); - switch( b->modOutSec[i]->value() ) + m_temp1 = m_b->m_modOutSig[i]->value(); + switch (m_b->m_modOutSec[i]->value()) { case 0:// None { - modOutSigBox[i-matrixDivide]->hide(); - modOutSecNumBox[i-matrixDivide]->hide(); + m_modOutSigBox[i-matrixDivide]->hide(); + m_modOutSecNumBox[i-matrixDivide]->hide(); break; } case 1:// Main OSC { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->show(); - mainoscsignalsmodel( b->modOutSig[i] ) - b->modOutSecNum[i]->setRange( 1.f, 8.f, 1.f ); + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->show(); + mainoscsignalsmodel(m_b->m_modOutSig[i]) + m_b->m_modOutSecNum[i]->setRange(1.f, 8.f, 1.f); break; } case 2:// Sub OSC { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->show(); - subsignalsmodel( b->modOutSig[i] ) - b->modOutSecNum[i]->setRange( 1.f, 64.f, 1.f ); + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->show(); + subsignalsmodel(m_b->m_modOutSig[i]) + m_b->m_modOutSecNum[i]->setRange(1.f, 64.f, 1.f); break; } case 3:// Sample OSC { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->show(); - samplesignalsmodel( b->modOutSig[i] ) - b->modOutSecNum[i]->setRange( 1.f, 8.f, 1.f ); + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->show(); + samplesignalsmodel(m_b->m_modOutSig[i]) + m_b->m_modOutSecNum[i]->setRange(1.f, 8.f, 1.f); break; } case 4:// Matrix Parameters { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->show(); - matrixsignalsmodel( b->modOutSig[i] ) - b->modOutSecNum[i]->setRange( 1.f, 64.f, 1.f ); + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->show(); + matrixsignalsmodel(m_b->m_modOutSig[i]) + m_b->m_modOutSecNum[i]->setRange(1.f, 64.f, 1.f); break; } case 5:// Filter Input { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->hide(); - mod8model( b->modOutSig[i] ) + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->hide(); + mod8model(m_b->m_modOutSig[i]) break; } case 6:// Filter Parameters { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->show(); - filtersignalsmodel( b->modOutSig[i] ) - b->modOutSecNum[i]->setRange( 1.f, 8.f, 1.f ); + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->show(); + filtersignalsmodel(m_b->m_modOutSig[i]) + m_b->m_modOutSecNum[i]->setRange(1.f, 8.f, 1.f); break; } case 7:// Macro { - modOutSigBox[i-matrixDivide]->show(); - modOutSecNumBox[i-matrixDivide]->hide(); - matrixoutmodel( b->modOutSig[i] ) + m_modOutSigBox[i-matrixDivide]->show(); + m_modOutSecNumBox[i-matrixDivide]->hide(); + matrixoutmodel(m_b->m_modOutSig[i]) break; } default: @@ -2622,70 +2617,70 @@ void MicrowaveView::modOutSecChanged( int i ) break; } } - b->modOutSig[i]->setValue( temp1 ); + m_b->m_modOutSig[i]->setValue(m_temp1); } } // Moves/changes the GUI around depending on the Mod In Section value -void MicrowaveView::modInChanged( int i ) +void MicrowaveView::modInChanged(int i) { - int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int modScrollVal = (m_matrixScrollBar->value()) / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - if( i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64 ) + if (i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64) { - switch( b->modIn[i]->value() ) + switch (m_b->m_modIn[i]->value()) { case 0: { - modInNumBox[i-matrixDivide]->hide(); + m_modInNumBox[i-matrixDivide]->hide(); break; } case 1:// Main OSC { - modInNumBox[i-matrixDivide]->show(); - b->modInNum[i]->setRange( 1, 8, 1 ); + m_modInNumBox[i-matrixDivide]->show(); + m_b->m_modInNum[i]->setRange(1, 8, 1); break; } case 2:// Sub OSC { - modInNumBox[i-matrixDivide]->show(); - b->modInNum[i]->setRange( 1, 64, 1 ); + m_modInNumBox[i-matrixDivide]->show(); + m_b->m_modInNum[i]->setRange(1, 64, 1); break; } case 3:// Sample OSC { - modInNumBox[i-matrixDivide]->show(); - b->modInNum[i]->setRange( 1, 8, 1 ); + m_modInNumBox[i-matrixDivide]->show(); + m_b->m_modInNum[i]->setRange(1, 8, 1); break; } case 4:// Filter { - modInNumBox[i-matrixDivide]->show(); - b->modInNum[i]->setRange( 1, 8, 1 ); + m_modInNumBox[i-matrixDivide]->show(); + m_b->m_modInNum[i]->setRange(1, 8, 1); break; } case 5:// Velocity { - modInNumBox[i-matrixDivide]->hide(); + m_modInNumBox[i-matrixDivide]->hide(); break; } case 6:// Panning { - modInNumBox[i-matrixDivide]->hide(); + m_modInNumBox[i-matrixDivide]->hide(); break; } case 7:// Humanizer { - modInNumBox[i-matrixDivide]->show(); - b->modInNum[i]->setRange( 1, 8, 1 ); + m_modInNumBox[i-matrixDivide]->show(); + m_b->m_modInNum[i]->setRange(1, 8, 1); break; } case 8:// Macro { - modInNumBox[i-matrixDivide]->show(); - b->modInNum[i]->setRange( 1, 18, 1 ); + m_modInNumBox[i-matrixDivide]->show(); + m_b->m_modInNum[i]->setRange(1, 18, 1); break; } } @@ -2694,64 +2689,64 @@ void MicrowaveView::modInChanged( int i ) // Moves/changes the GUI around depending on the Mod In Section value -void MicrowaveView::modIn2Changed( int i ) +void MicrowaveView::modIn2Changed(int i) { - int modScrollVal = ( matrixScrollBar->value() ) / 100.f * 115.f; + int modScrollVal = (m_matrixScrollBar->value()) / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - if( i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64 ) + if (i-matrixDivide < 8 && i-matrixDivide >= 0 && i < 64) { - switch( b->modIn2[i]->value() ) + switch (m_b->m_modIn2[i]->value()) { case 0: { - modInNumBox2[i-matrixDivide]->hide(); + m_modInNumBox2[i-matrixDivide]->hide(); break; } case 1:// Main OSC { - modInNumBox2[i-matrixDivide]->show(); - b->modInNum2[i]->setRange( 1, 8, 1 ); + m_modInNumBox2[i-matrixDivide]->show(); + m_b->m_modInNum2[i]->setRange(1, 8, 1); break; } case 2:// Sub OSC { - modInNumBox2[i-matrixDivide]->show(); - b->modInNum2[i]->setRange( 1, 64, 1 ); + m_modInNumBox2[i-matrixDivide]->show(); + m_b->m_modInNum2[i]->setRange(1, 64, 1); break; } case 3:// Sample OSC { - modInNumBox2[i-matrixDivide]->show(); - b->modInNum2[i]->setRange( 1, 8, 1 ); + m_modInNumBox2[i-matrixDivide]->show(); + m_b->m_modInNum2[i]->setRange(1, 8, 1); break; } case 4:// Filter { - modInNumBox2[i-matrixDivide]->show(); - b->modInNum2[i]->setRange( 1, 8, 1 ); + m_modInNumBox2[i-matrixDivide]->show(); + m_b->m_modInNum2[i]->setRange(1, 8, 1); break; } case 5:// Velocity { - modInNumBox2[i-matrixDivide]->hide(); + m_modInNumBox2[i-matrixDivide]->hide(); break; } case 6:// Panning { - modInNumBox2[i-matrixDivide]->hide(); + m_modInNumBox2[i-matrixDivide]->hide(); break; } case 7:// Humanizer { - modInNumBox2[i-matrixDivide]->show(); - b->modInNum2[i]->setRange( 1, 8, 1 ); + m_modInNumBox2[i-matrixDivide]->show(); + m_b->m_modInNum2[i]->setRange(1, 8, 1); break; } case 8:// Macro { - modInNumBox2[i-matrixDivide]->show(); - b->modInNum2[i]->setRange( 1, 18, 1 ); + m_modInNumBox2[i-matrixDivide]->show(); + m_b->m_modInNum2[i]->setRange(1, 18, 1); break; } } @@ -2762,81 +2757,81 @@ void MicrowaveView::modIn2Changed( int i ) // Does what is necessary when the user visits a new tab -void MicrowaveView::tabChanged( int tabnum ) +void MicrowaveView::tabChanged(int tabnum) { - b->currentTab = tabnum; + m_b->m_currentTab = tabnum; updateBackground(); - if( tabnum != 3 ) + if (tabnum != 3) { - MatrixXBtn->hide(); + m_MatrixXBtn->hide(); } - if( tabnum != 0 ) + if (tabnum != 0) { - tab1Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1" ) ); - tab1Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1" ) ); + m_tab1Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab1")); + m_tab1Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab1")); } else { - tab1Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); - tab1Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab1_active" ) ); + m_tab1Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab1_active")); + m_tab1Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab1_active")); } - if( tabnum != 1 ) + if (tabnum != 1) { - tab2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); - tab2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2" ) ); + m_tab2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab2")); + m_tab2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab2")); } else { - tab2Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2_active" ) ); - tab2Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab2_active" ) ); + m_tab2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab2_active")); + m_tab2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab2_active")); } - if( tabnum != 2 ) + if (tabnum != 2) { - tab3Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); - tab3Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3" ) ); + m_tab3Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab3")); + m_tab3Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab3")); } else { - tab3Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3_active" ) ); - tab3Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab3_active" ) ); + m_tab3Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab3_active")); + m_tab3Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab3_active")); } - if( tabnum != 3 ) + if (tabnum != 3) { - tab4Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); - tab4Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4" ) ); + m_tab4Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab4")); + m_tab4Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab4")); } else { - tab4Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4_active" ) ); - tab4Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab4_active" ) ); + m_tab4Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab4_active")); + m_tab4Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab4_active")); } - if( tabnum != 4 ) + if (tabnum != 4) { - tab5Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); - tab5Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5" ) ); + m_tab5Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab5")); + m_tab5Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab5")); } else { - tab5Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5_active" ) ); - tab5Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab5_active" ) ); + m_tab5Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab5_active")); + m_tab5Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab5_active")); } - if( tabnum != 5 ) + if (tabnum != 5) { - tab6Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); - tab6Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6" ) ); + m_tab6Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab6")); + m_tab6Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab6")); } else { - tab6Btn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6_active" ) ); - tab6Btn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tab6_active" ) ); + m_tab6Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("tab6_active")); + m_tab6Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("tab6_active")); } } @@ -2844,76 +2839,76 @@ void MicrowaveView::tabChanged( int tabnum ) void MicrowaveView::updateBackground() { - int backgroundnum = b->currentTab; - bool mainFlipped = b->mainFlipped.value(); - bool subFlipped = b->subFlipped.value(); + int backgroundnum = m_b->m_currentTab; + bool m_mainFlipped = m_b->m_mainFlipped.value(); + bool m_subFlipped = m_b->m_subFlipped.value(); - switch( backgroundnum ) + switch (backgroundnum) { case 0:// Wavetable { - b->graph.setLength( 204 ); + m_b->m_graph.setLength(204); mainNumChanged(); - if( !mainFlipped ) + if (!m_mainFlipped) { - pal.setBrush( backgroundRole(), tab1ArtworkImg.copy() ); + m_pal.setBrush(backgroundRole(), m_tab1ArtworkImg.copy()); } else { - pal.setBrush( backgroundRole(), tab1FlippedArtworkImg.copy() ); + m_pal.setBrush(backgroundRole(), m_tab1FlippedArtworkImg.copy()); } - setPalette( pal ); + setPalette(m_pal); break; } case 1:// Sub { subNumChanged();// Graph length is set in here - if( !subFlipped ) + if (!m_subFlipped) { - pal.setBrush( backgroundRole(), tab2ArtworkImg.copy() ); + m_pal.setBrush(backgroundRole(), m_tab2ArtworkImg.copy()); } else { - pal.setBrush( backgroundRole(), tab2FlippedArtworkImg.copy() ); + m_pal.setBrush(backgroundRole(), m_tab2FlippedArtworkImg.copy()); } - setPalette( pal ); + setPalette(m_pal); break; } case 2:// Sample { - b->graph.setLength( 128 ); + m_b->m_graph.setLength(128); sampNumChanged(); - pal.setBrush( backgroundRole(), tab3ArtworkImg.copy() ); - setPalette( pal ); + m_pal.setBrush(backgroundRole(), m_tab3ArtworkImg.copy()); + setPalette(m_pal); break; } case 3:// Matrix { - pal.setBrush( backgroundRole(), tab4ArtworkImg.copy() ); - setPalette( pal ); + m_pal.setBrush(backgroundRole(), m_tab4ArtworkImg.copy()); + setPalette(m_pal); break; } case 4:// Effect { - pal.setBrush( backgroundRole(), tab5ArtworkImg.copy() ); - setPalette( pal ); + m_pal.setBrush(backgroundRole(), m_tab5ArtworkImg.copy()); + setPalette(m_pal); break; } case 5:// Miscellaneous { - pal.setBrush( backgroundRole(), tab6ArtworkImg.copy() ); - setPalette( pal ); + m_pal.setBrush(backgroundRole(), m_tab6ArtworkImg.copy()); + setPalette(m_pal); break; } case 6:// Wavetable Loading { - pal.setBrush( backgroundRole(), tab7ArtworkImg.copy() ); - setPalette( pal ); + m_pal.setBrush(backgroundRole(), m_tab7ArtworkImg.copy()); + setPalette(m_pal); break; } } @@ -2922,59 +2917,59 @@ void MicrowaveView::updateBackground() -void MicrowaveView::visualizeToggled( bool value ) +void MicrowaveView::visualizeToggled(bool value) { - visvolKnob->setVisible( b->visualize.value() ); + m_visvolKnob->setVisible(m_b->m_visualize.value()); } // V Buttons that change the graph V void MicrowaveView::sinWaveClicked() { - graph->model()->setWaveToSine(); + m_graph->model()->setWaveToSine(); Engine::getSong()->setModified(); } void MicrowaveView::triangleWaveClicked() { - graph->model()->setWaveToTriangle(); + m_graph->model()->setWaveToTriangle(); Engine::getSong()->setModified(); } void MicrowaveView::sawWaveClicked() { - graph->model()->setWaveToSaw(); + m_graph->model()->setWaveToSaw(); Engine::getSong()->setModified(); } void MicrowaveView::sqrWaveClicked() { - graph->model()->setWaveToSquare(); + m_graph->model()->setWaveToSquare(); Engine::getSong()->setModified(); } void MicrowaveView::noiseWaveClicked() { - graph->model()->setWaveToNoise(); + m_graph->model()->setWaveToNoise(); Engine::getSong()->setModified(); } void MicrowaveView::usrWaveClicked() { - QString fileName = graph->model()->setWaveToUser(); - ToolTip::add( usrWaveBtn, fileName ); + QString fileName = m_graph->model()->setWaveToUser(); + ToolTip::add(m_usrWaveBtn, fileName); Engine::getSong()->setModified(); } void MicrowaveView::smoothClicked() { - graph->model()->smooth(); + m_graph->model()->smooth(); Engine::getSong()->setModified(); } // ^ Buttons that change the graph ^ @@ -2989,89 +2984,89 @@ void MicrowaveView::flipperClicked() void MicrowaveView::XBtnClicked() { - castModel()->scroll = 0; + castModel()->m_scroll = 0; updateScroll(); } void MicrowaveView::MatrixXBtnClicked() { - castModel()->scroll = tabWhenSendingToMatrix; + castModel()->m_scroll = m_tabWhenSendingToMatrix; updateScroll(); } void MicrowaveView::normalizeClicked() { - int oscilNum = b->mainNum.value() - 1; + int oscilNum = m_b->m_mainNum.value() - 1; - for( int i = 0; i < 256; ++i ) + for (int i = 0; i < 256; ++i) { float highestVolume = 0; - for( int j = 0; j < 2048; ++j ) + for (int j = 0; j < 2048; ++j) { - highestVolume = abs(b->storedwaveforms[oscilNum][(i*2048)+j]) > highestVolume ? abs(b->storedwaveforms[oscilNum][(i*2048)+j]) : highestVolume; + highestVolume = abs(m_b->m_storedwaveforms[oscilNum][(i*2048)+j]) > highestVolume ? abs(m_b->m_storedwaveforms[oscilNum][(i*2048)+j]) : highestVolume; } - if( highestVolume ) + if (highestVolume) { float multiplierThing = 1.f / highestVolume; - for( int j = 0; j < 2048; ++j ) + for (int j = 0; j < 2048; ++j) { - b->storedwaveforms[oscilNum][(i*2048)+j] *= multiplierThing; + m_b->m_storedwaveforms[oscilNum][(i*2048)+j] *= multiplierThing; } } } Engine::getSong()->setModified(); - b->updateWavetable[oscilNum] = true; + m_b->m_updateWavetable[oscilNum] = true; - b->fillMainOsc(oscilNum, b->interpolate[oscilNum]->value()); + m_b->fillMainOsc(oscilNum, m_b->m_interpolate[oscilNum]->value()); } void MicrowaveView::desawClicked() { - int oscilNum = b->mainNum.value() - 1; + int oscilNum = m_b->m_mainNum.value() - 1; float start; float end; - for( int j = 0; j < 256; ++j ) + for (int j = 0; j < 256; ++j) { - start = -b->storedwaveforms[oscilNum][j*2048]; - end = -b->storedwaveforms[oscilNum][j*2048+2047]; - for( int i = 0; i < 2048; ++i ) + start = -m_b->m_storedwaveforms[oscilNum][j*2048]; + end = -m_b->m_storedwaveforms[oscilNum][j*2048+2047]; + for (int i = 0; i < 2048; ++i) { - b->storedwaveforms[oscilNum][j*2048+i] += (i/2048.f)*end + ((2048.f-i)/2048.f)*start; + m_b->m_storedwaveforms[oscilNum][j*2048+i] += (i/2048.f)*end + ((2048.f-i)/2048.f)*start; } } Engine::getSong()->setModified(); - b->updateWavetable[oscilNum] = true; + m_b->m_updateWavetable[oscilNum] = true; - b->fillMainOsc(oscilNum, b->interpolate[oscilNum]->value()); + m_b->fillMainOsc(oscilNum, m_b->m_interpolate[oscilNum]->value()); } -void MicrowaveView::modUpClicked( int i ) +void MicrowaveView::modUpClicked(int i) { - int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int modScrollVal = m_matrixScrollBar->value() / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - if( i+matrixDivide > 0 ) + if (i+matrixDivide > 0) { - castModel()->switchMatrixSections( i+matrixDivide, i+matrixDivide - 1 ); + castModel()->switchMatrixSections(i+matrixDivide, i+matrixDivide - 1); } } -void MicrowaveView::modDownClicked( int i ) +void MicrowaveView::modDownClicked(int i) { - int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int modScrollVal = m_matrixScrollBar->value() / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - if( i+matrixDivide < 63 ) + if (i+matrixDivide < 63) { - castModel()->switchMatrixSections( i+matrixDivide, i+matrixDivide + 1 ); + castModel()->switchMatrixSections(i+matrixDivide, i+matrixDivide + 1); } } @@ -3080,44 +3075,44 @@ void MicrowaveView::modDownClicked( int i ) //Changes maximum value of the Matrix scroll bar. void MicrowaveView::modEnabledChanged() { - matrixScrollBar->setRange( 0, qBound( 100.f, b->maxModEnabled * 100.f, 6232.f ) + 30.f ); + m_matrixScrollBar->setRange(0, qBound(100.f, m_b->m_maxModEnabled * 100.f, 6232.f) + 30.f); } -void MicrowaveView::i1Clicked( int i ) +void MicrowaveView::i1Clicked(int i) { - int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int modScrollVal = m_matrixScrollBar->value() / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - switch( b->modIn[i+matrixDivide]->value() ) + switch (m_b->m_modIn[i+matrixDivide]->value()) { case 1: { - b->scroll = 0; - b->mainNum.setValue( b->modInNum[i+matrixDivide]->value() ); + m_b->m_scroll = 0; + m_b->m_mainNum.setValue(m_b->m_modInNum[i+matrixDivide]->value()); break; } case 2: { - b->scroll = 1; - b->subNum.setValue( b->modInNum[i+matrixDivide]->value() ); + m_b->m_scroll = 1; + m_b->m_subNum.setValue(m_b->m_modInNum[i+matrixDivide]->value()); break; } case 3: { - b->scroll = 2; - b->sampNum.setValue( b->modInNum[i+matrixDivide]->value() ); + m_b->m_scroll = 2; + m_b->m_sampNum.setValue(m_b->m_modInNum[i+matrixDivide]->value()); break; } case 4: { - b->scroll = 3; - effectScrollBar->setValue( ( b->modInNum[i+matrixDivide]->value() - 1 ) * 100.f ); + m_b->m_scroll = 3; + m_effectScrollBar->setValue((m_b->m_modInNum[i+matrixDivide]->value() - 1) * 100.f); break; } case 8: { - b->scroll = 5; + m_b->m_scroll = 5; break; } } @@ -3126,40 +3121,40 @@ void MicrowaveView::i1Clicked( int i ) } -void MicrowaveView::i2Clicked( int i ) +void MicrowaveView::i2Clicked(int i) { - int modScrollVal = matrixScrollBar->value() / 100.f * 115.f; + int modScrollVal = m_matrixScrollBar->value() / 100.f * 115.f; int matrixDivide = modScrollVal / 460 * 4; - switch( b->modIn2[i+matrixDivide]->value() ) + switch (m_b->m_modIn2[i+matrixDivide]->value()) { case 1: { - b->scroll = 0; - b->mainNum.setValue( b->modInNum2[i+matrixDivide]->value() ); + m_b->m_scroll = 0; + m_b->m_mainNum.setValue(m_b->m_modInNum2[i+matrixDivide]->value()); break; } case 2: { - b->scroll = 1; - b->subNum.setValue( b->modInNum2[i+matrixDivide]->value() ); + m_b->m_scroll = 1; + m_b->m_subNum.setValue(m_b->m_modInNum2[i+matrixDivide]->value()); break; } case 3: { - b->scroll = 2; - b->sampNum.setValue( b->modInNum2[i+matrixDivide]->value() ); + m_b->m_scroll = 2; + m_b->m_sampNum.setValue(m_b->m_modInNum2[i+matrixDivide]->value()); break; } case 4: { - b->scroll = 3; - effectScrollBar->setValue( ( b->modInNum2[i+matrixDivide]->value() - 1 ) * 100.f ); + m_b->m_scroll = 3; + m_effectScrollBar->setValue((m_b->m_modInNum2[i+matrixDivide]->value() - 1) * 100.f); break; } case 8: { - b->scroll = 5; + m_b->m_scroll = 5; break; } } @@ -3168,102 +3163,102 @@ void MicrowaveView::i2Clicked( int i ) } -void MicrowaveView::tabBtnClicked( int i ) +void MicrowaveView::tabBtnClicked(int i) { - castModel()->scroll = i; + castModel()->m_scroll = i; updateScroll(); } -void MicrowaveView::sendToMatrixAsOutput( int loc1, int loc2, int loc3 ) +void MicrowaveView::sendToMatrixAsOutput(int loc1, int loc2, int loc3) { - int matrixLocation = b->maxModEnabled; + int m_matrixLocation = m_b->m_maxModEnabled; - if( matrixLocation < 64 ) + if (m_matrixLocation < 64) { - b->modEnabled[matrixLocation]->setValue( true ); - b->modOutSec[matrixLocation]->setValue( loc1 ); - b->modOutSig[matrixLocation]->setValue( loc2 ); - b->modOutSecNum[matrixLocation]->setValue( loc3 + 1 ); + m_b->m_modEnabled[m_matrixLocation]->setValue(true); + m_b->m_modOutSec[m_matrixLocation]->setValue(loc1); + m_b->m_modOutSig[m_matrixLocation]->setValue(loc2); + m_b->m_modOutSecNum[m_matrixLocation]->setValue(loc3 + 1); } - tabWhenSendingToMatrix = b->currentTab; + m_tabWhenSendingToMatrix = m_b->m_currentTab; - MatrixXBtn->show(); + m_MatrixXBtn->show(); - b->scroll = 3; + m_b->m_scroll = 3; updateScroll(); - matrixScrollBar->setValue( 100 * matrixLocation ); + m_matrixScrollBar->setValue(100 * m_matrixLocation); } -void MicrowaveView::switchToMatrixKnob( MicrowaveKnob * theKnob, int loc1, int loc2, int loc3 ) +void MicrowaveView::switchToMatrixKnob(MicrowaveKnob * theKnob, int loc1, int loc2, int loc3) { - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - if( b->modOutSec[i]->value() == loc1 && b->modOutSig[i]->value() == loc2 && b->modOutSecNum[i]->value() - 1 == loc3 ) + if (m_b->m_modOutSec[i]->value() == loc1 && m_b->m_modOutSig[i]->value() == loc2 && m_b->m_modOutSecNum[i]->value() - 1 == loc3) { - theKnob->setModel( b->modInAmnt[i] ); - theKnob->setarcColor( QColor(23,94,40) ); - theKnob->setlineColor( QColor(51,248,99) ); - theKnob->setInnerColor( QColor(32,112,50) ); + theKnob->setModel(m_b->m_modInAmnt[i]); + theKnob->setarcColor(QColor(23,94,40)); + theKnob->setlineColor(QColor(51,248,99)); + theKnob->setInnerColor(QColor(32,112,50)); break; } } } -void MicrowaveView::setMacroTooltip( MicrowaveKnob * theKnob, int which ) +void MicrowaveView::setMacroTooltip(MicrowaveKnob * theKnob, int which) { bool ok; QString new_val; - new_val = QInputDialog::getText( theKnob, tr( "Set new Tooltip" ), tr( "Please enter a new Tooltip for Macro %1:" ).arg( which + 1 ), QLineEdit::Normal, b->macroTooltips[which], &ok ); + new_val = QInputDialog::getText(theKnob, tr("Set new Tooltip"), tr("Please enter a new Tooltip for Macro %1:").arg(which + 1), QLineEdit::Normal, m_b->m_macroTooltips[which], &ok); - if( ok ) + if (ok) { - b->macroTooltips[which] = new_val; - ToolTip::add( theKnob, tr( "Macro %1: " ).arg( which + 1 ) + new_val ); + m_b->m_macroTooltips[which] = new_val; + ToolTip::add(theKnob, tr("Macro %1: ").arg(which + 1) + new_val); } } -void MicrowaveView::chooseMacroColor( MicrowaveKnob * theKnob, int which ) +void MicrowaveView::chooseMacroColor(MicrowaveKnob * theKnob, int which) { - QColor new_color = QColorDialog::getColor( QColor( b->macroColors[which][0], b->macroColors[which][1], b->macroColors[which][2] ) ); - if( ! new_color.isValid() ) + QColor new_color = QColorDialog::getColor(QColor(m_b->m_macroColors[which][0], m_b->m_macroColors[which][1], m_b->m_macroColors[which][2])); + if (! new_color.isValid()) { return; } - b->macroColors[which][0] = new_color.red(); - b->macroColors[which][1] = new_color.green(); - b->macroColors[which][2] = new_color.blue(); - refreshMacroColor( theKnob, which ); + m_b->m_macroColors[which][0] = new_color.red(); + m_b->m_macroColors[which][1] = new_color.green(); + m_b->m_macroColors[which][2] = new_color.blue(); + refreshMacroColor(theKnob, which); } -void MicrowaveView::setMacroColortoDefault( MicrowaveKnob * theKnob, int which ) +void MicrowaveView::setMacroColortoDefault(MicrowaveKnob * theKnob, int which) { - b->macroColors[which][0] = 102; - b->macroColors[which][1] = 198; - b->macroColors[which][2] = 199; - refreshMacroColor( theKnob, which ); + m_b->m_macroColors[which][0] = 102; + m_b->m_macroColors[which][1] = 198; + m_b->m_macroColors[which][2] = 199; + refreshMacroColor(theKnob, which); } -void MicrowaveView::refreshMacroColor( MicrowaveKnob * theKnob, int which ) +void MicrowaveView::refreshMacroColor(MicrowaveKnob * theKnob, int which) { - int red = b->macroColors[which][0]; - int green = b->macroColors[which][1]; - int blue = b->macroColors[which][2]; + int red = m_b->m_macroColors[which][0]; + int green = m_b->m_macroColors[which][1]; + int blue = m_b->m_macroColors[which][2]; - theKnob->setarcColor( QColor(red*0.4, green*0.4, blue*0.4) ); - theKnob->setlineColor( QColor(red, green, blue) ); - theKnob->setInnerColor( QColor(red*0.5, green*0.5, blue*0.5) ); + theKnob->setarcColor(QColor(red*0.4, green*0.4, blue*0.4)); + theKnob->setlineColor(QColor(red, green, blue)); + theKnob->setInnerColor(QColor(red*0.5, green*0.5, blue*0.5)); } @@ -3271,9 +3266,9 @@ void MicrowaveView::refreshMacroColor( MicrowaveKnob * theKnob, int which ) // Calls MicrowaveView::openWavetableFile when the wavetable opening button is clicked. void MicrowaveView::openWavetableFileBtnClicked() { - if( b->scroll != 6 ) + if (m_b->m_scroll != 6) { - b->scroll = 6; + m_b->m_scroll = 6; updateScroll(); } else @@ -3285,9 +3280,9 @@ void MicrowaveView::openWavetableFileBtnClicked() void MicrowaveView::chooseWavetableFile() { - SampleBuffer * sampleBuffer = new SampleBuffer; - wavetableFileName = sampleBuffer->openAndSetWaveformFile(); - sharedObject::unref( sampleBuffer ); + SampleBuffer * m_sampleBuffer = new SampleBuffer; + m_wavetableFileName = m_sampleBuffer->openAndSetWaveformFile(); + sharedObject::unref(m_sampleBuffer); } @@ -3297,62 +3292,62 @@ void MicrowaveView::confirmWavetableLoadClicked() } -// All of the code and algorithms for loading wavetables from samples. Please don't expect this code to look neat. -void MicrowaveView::openWavetableFile( QString fileName ) +// All of the code and algorithms for loading wavetables from m_samples. Please don't expect this code to look neat. +void MicrowaveView::openWavetableFile(QString fileName) { const sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); - if( fileName.isEmpty() ) + if (fileName.isEmpty()) { - if( wavetableFileName.isEmpty() ) + if (m_wavetableFileName.isEmpty()) { chooseWavetableFile(); } - fileName = wavetableFileName; + fileName = m_wavetableFileName; } - SampleBuffer * sampleBuffer = new SampleBuffer; + SampleBuffer * m_sampleBuffer = new SampleBuffer; - sampleBuffer->setAudioFile( fileName ); + m_sampleBuffer->setAudioFile(fileName); - int filelength = sampleBuffer->sampleLength(); - int oscilNum = b->mainNum.value() - 1; - int algorithm = b->loadMode.value(); - int channel = b->loadChnl.value(); + int filelength = m_sampleBuffer->sampleLength(); + int oscilNum = m_b->m_mainNum.value() - 1; + int algorithm = m_b->m_loadMode.value(); + int channel = m_b->m_loadChnl.value(); - if( !fileName.isEmpty() ) + if (!fileName.isEmpty()) { - sampleBuffer->dataReadLock(); - float lengthOfSample = ((filelength/1000.f)*sample_rate);//in samples - switch( algorithm ) + m_sampleBuffer->dataReadLock(); + float lengthOfSample = ((filelength/1000.f)*sample_rate);//in m_samples + switch (algorithm) { case 0:// Lock waveform edges to zero crossings { //Clear wavetable - for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { - b->storedwaveforms[oscilNum][i] = 0; + m_b->m_storedwaveforms[oscilNum][i] = 0; } - bool above = sampleBuffer->userWaveSample( 1.f/lengthOfSample, channel ) > 0; + bool above = m_sampleBuffer->userWaveSample(1.f/lengthOfSample, channel) > 0; float currentValue = 0; std::vector zeroCrossings; float previousPoint = 0; //Find zero crossings, and store differences between them in a vector. - for( int i = 0; i < lengthOfSample; ++i ) + for (int i = 0; i < lengthOfSample; ++i) { - currentValue = sampleBuffer->userWaveSample( i / lengthOfSample, channel ); - if( ( above && currentValue <= 0 ) || ( !above && currentValue > 0 ) ) + currentValue = m_sampleBuffer->userWaveSample(i / lengthOfSample, channel); + if ((above && currentValue <= 0) || (!above && currentValue > 0)) { above = !above; - zeroCrossings.push_back( i-previousPoint ); + zeroCrossings.push_back(i-previousPoint); previousPoint = i; } } //Quit if the sample is too short - if( zeroCrossings.size() < 3 ) + if (zeroCrossings.size() < 3) { break; } @@ -3362,13 +3357,13 @@ void MicrowaveView::openWavetableFile( QString fileName ) float actualnow = 0; //Find and list chosen zero crossings - for( int i = 0; i < zeroCrossings.size() - 1; ++i ) + for (int i = 0; i < zeroCrossings.size() - 1; ++i) { now += zeroCrossings[i]; actualnow += zeroCrossings[i]; - if( abs( STOREDMAINWAVELEN / 2.f - now ) < abs( STOREDMAINWAVELEN / 2.f - ( now + zeroCrossings[i+1] ) ) ) + if (abs(STOREDMAINWAVELEN / 2.f - now) < abs(STOREDMAINWAVELEN / 2.f - (now + zeroCrossings[i+1]))) { - betterZC.push_back( actualnow ); + betterZC.push_back(actualnow); now = 0; } } @@ -3382,46 +3377,46 @@ void MicrowaveView::openWavetableFile( QString fileName ) bool breakify = false; //Take gathered information and cram it into the waveforms. - for( int i = 0; i < betterZC.size() - 1; ++i ) + for (int i = 0; i < betterZC.size() - 1; ++i) { start = betterZC[i]; end = betterZC[i+1]; lasti = i; - for( int j = 0; j < b->sampLen[oscilNum]->value(); ++j ) + for (int j = 0; j < m_b->m_sampLen[oscilNum]->value(); ++j) { lastj = j; - if( j + ( i * b->sampLen[oscilNum]->value()) >= STOREDMAINARRAYLEN ) + if (j + (i * m_b->m_sampLen[oscilNum]->value()) >= STOREDMAINARRAYLEN) { breakify = true; break; } - b->storedwaveforms[oscilNum][j + ( i * (int)b->sampLen[oscilNum]->value() )] = sampleBuffer->userWaveSample( ( ( j / b->sampLen[oscilNum]->value() ) * ( end - start ) + start ) / lengthOfSample, channel ); + m_b->m_storedwaveforms[oscilNum][j + (i * (int)m_b->m_sampLen[oscilNum]->value())] = m_sampleBuffer->userWaveSample(((j / m_b->m_sampLen[oscilNum]->value()) * (end - start) + start) / lengthOfSample, channel); } - if( breakify ) { break; } + if (breakify) { break; } } - b->morphMax[oscilNum]->setValue( lasti + ( lastj / b->sampLen[oscilNum]->value() ) ); - b->morphMaxChanged( oscilNum ); + m_b->m_morphMax[oscilNum]->setValue(lasti + (lastj / m_b->m_sampLen[oscilNum]->value())); + m_b->morphMaxChanged(oscilNum); break; } - case 1:// Load sample without changes + case 1:// Load m_sample without changes { - for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { - if ( i <= lengthOfSample * 2.f ) + if (i <= lengthOfSample * 2.f) { - b->storedwaveforms[oscilNum][i] = sampleBuffer->userWaveSample( (i/lengthOfSample) / 2.f, channel ); + m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample((i/lengthOfSample) / 2.f, channel); } else// Replace everything else with silence if sample isn't long enough { - b->morphMax[oscilNum]->setValue( i/b->sampLen[oscilNum]->value() ); - b->morphMaxChanged( oscilNum ); - for( int j = i; j < STOREDMAINARRAYLEN; ++j ) { b->storedwaveforms[oscilNum][j] = 0.f; } + m_b->m_morphMax[oscilNum]->setValue(i/m_b->m_sampLen[oscilNum]->value()); + m_b->morphMaxChanged(oscilNum); + for (int j = i; j < STOREDMAINARRAYLEN; ++j) { m_b->m_storedwaveforms[oscilNum][j] = 0.f; } break; } } @@ -3429,17 +3424,17 @@ void MicrowaveView::openWavetableFile( QString fileName ) } case 2:// For loading wavetable files { - for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { - if ( i <= lengthOfSample ) + if (i <= lengthOfSample) { - b->storedwaveforms[oscilNum][i] = sampleBuffer->userWaveSample( i/lengthOfSample, channel ); + m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample(i/lengthOfSample, channel); } else { - b->morphMax[oscilNum]->setValue( i/b->sampLen[oscilNum]->value() ); - b->morphMaxChanged( oscilNum ); - for( int j = i; j < STOREDMAINARRAYLEN; ++j ) { b->storedwaveforms[oscilNum][j] = 0.f; } + m_b->m_morphMax[oscilNum]->setValue(i/m_b->m_sampLen[oscilNum]->value()); + m_b->morphMaxChanged(oscilNum); + for (int j = i; j < STOREDMAINARRAYLEN; ++j) { m_b->m_storedwaveforms[oscilNum][j] = 0.f; } break; } } @@ -3451,7 +3446,7 @@ void MicrowaveView::openWavetableFile( QString fileName ) // Estimate pitch using autocorrelation: - float checkLength = qMin( 4000.f, lengthOfSample );// 4000 samples should be long enough to be able to accurately detect most frequencies this way + float checkLength = qMin(4000.f, lengthOfSample);// 4000 samples should be long enough to be able to accurately detect most frequencies this way float threshold = -1; float combined = 0; @@ -3459,34 +3454,35 @@ void MicrowaveView::openWavetableFile( QString fileName ) int stage = 0; float period = 0; - for( int i = 0; i < checkLength; ++i ) + for (int i = 0; i < checkLength; ++i) { oldcombined = combined; combined = 0; - for( int k = 0; k < checkLength - i; ++k ) + for (int k = 0; k < checkLength - i; ++k) { - combined += ( sampleBuffer->userWaveSample( k/lengthOfSample, channel ) * sampleBuffer->userWaveSample( (k+i)/lengthOfSample, channel ) + 1 ) * 0.5f - 0.5f; + combined += (m_sampleBuffer->userWaveSample(k/lengthOfSample, channel) * + m_sampleBuffer->userWaveSample((k+i)/lengthOfSample, channel) + 1) * 0.5f - 0.5f; } - if( stage == 2 && combined - oldcombined <= 0 ) + if (stage == 2 && combined - oldcombined <= 0) { stage = 3; period = i; } - if( stage == 1 && combined > threshold && combined - oldcombined > 0 ) + if (stage == 1 && combined > threshold && combined - oldcombined > 0) { stage = 2; } - if( !i ) + if (!i) { threshold = combined * 0.5f; stage = 1; } } - if( !period ) + if (!period) { break; } @@ -3497,142 +3493,142 @@ void MicrowaveView::openWavetableFile( QString fileName ) // Otherwise, the zero crossing result is probably very inaccurate (common with complex sounds) and is ignored. std::vector crossings; - crossings.push_back( 0 ); + crossings.push_back(0); std::vector crossingsDif; - bool above = ( sampleBuffer->userWaveSample( 1/lengthOfSample, channel ) > 0 ); + bool above = (m_sampleBuffer->userWaveSample(1/lengthOfSample, channel) > 0); - for( int i = 0; i < checkLength; ++i ) + for (int i = 0; i < checkLength; ++i) { - if( ( sampleBuffer->userWaveSample( i/lengthOfSample, channel ) > 0 ) != above ) + if ((m_sampleBuffer->userWaveSample(i/lengthOfSample, channel) > 0) != above) { above = !above; - if( above ) + if (above) { - crossingsDif.push_back( i - crossings[crossings.size() - 1] ); - crossings.push_back( i ); + crossingsDif.push_back(i - crossings[crossings.size() - 1]); + crossings.push_back(i); } } } - crossings.erase( crossings.begin() ); + crossings.erase(crossings.begin()); - if( crossingsDif.size() >= 3 ) + if (crossingsDif.size() >= 3) { - float crossingsMean = std::accumulate( crossingsDif.begin(), crossingsDif.end(), 0.f ) / crossingsDif.size(); + float crossingsMean = std::accumulate(crossingsDif.begin(), crossingsDif.end(), 0.f) / crossingsDif.size(); std::vector crossingsToRemove; - for( int i = 0; i < crossingsDif.size(); ++i ) + for (int i = 0; i < crossingsDif.size(); ++i) { - if( crossingsDif[i] < crossingsMean ) + if (crossingsDif[i] < crossingsMean) { - crossingsToRemove.push_back( i ); + crossingsToRemove.push_back(i); } } - for( int i = crossingsToRemove.size() - 1; i >= 0; --i ) + for (int i = crossingsToRemove.size() - 1; i >= 0; --i) { - crossingsDif.erase( crossingsDif.begin() + crossingsToRemove[i] ); + crossingsDif.erase(crossingsDif.begin() + crossingsToRemove[i]); } - if( crossingsDif.size() >= 2 ) + if (crossingsDif.size() >= 2) { - float crossingsMedian = crossingsDif[int( crossingsDif.size() / 2.f )]; - if( abs( period - crossingsMedian ) < 5.f + period / 100.f ) + float crossingsMedian = crossingsDif[int(crossingsDif.size() / 2.f)]; + if (abs(period - crossingsMedian) < 5.f + period / 100.f) { period = crossingsMedian; } } } - for( int i = 0; i < STOREDMAINARRAYLEN; ++i ) + for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { - b->storedwaveforms[oscilNum][i] = sampleBuffer->userWaveSample( ((i/2048.f)*period)/lengthOfSample, channel ); + m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample(((i/2048.f)*period)/lengthOfSample, channel); } - b->morphMax[oscilNum]->setValue( 254 ); - b->morphMaxChanged( oscilNum ); + m_b->m_morphMax[oscilNum]->setValue(254); + m_b->morphMaxChanged(oscilNum); break; } } - sampleBuffer->dataUnlock(); + m_sampleBuffer->dataUnlock(); - b->updateWavetable[oscilNum] = true; + m_b->m_updateWavetable[oscilNum] = true; - b->fillMainOsc(oscilNum, b->interpolate[oscilNum]->value()); + m_b->fillMainOsc(oscilNum, m_b->m_interpolate[oscilNum]->value()); } - sharedObject::unref( sampleBuffer ); + sharedObject::unref(m_sampleBuffer); } // Calls MicrowaveView::openSampleFile when the sample opening button is clicked. -void MicrowaveView::openSampleFileBtnClicked( ) +void MicrowaveView::openSampleFileBtnClicked() { openSampleFile(); } -// Loads sample for sample oscillator +// Loads m_sample for sample oscillator void MicrowaveView::openSampleFile() { const sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); - int oscilNum = b->sampNum.value() - 1; + int oscilNum = m_b->m_sampNum.value() - 1; - SampleBuffer * sampleBuffer = new SampleBuffer; - QString fileName = sampleBuffer->openAndSetWaveformFile(); - int filelength = sampleBuffer->sampleLength(); - if( fileName.isEmpty() == false ) + SampleBuffer * m_sampleBuffer = new SampleBuffer; + QString fileName = m_sampleBuffer->openAndSetWaveformFile(); + int filelength = m_sampleBuffer->sampleLength(); + if (fileName.isEmpty() == false) { - sampleBuffer->dataReadLock(); + m_sampleBuffer->dataReadLock(); float lengthOfSample = ((filelength/1000.f)*sample_rate);//in samples - b->samples[oscilNum][0].clear(); - b->samples[oscilNum][1].clear(); + m_b->m_samples[oscilNum][0].clear(); + m_b->m_samples[oscilNum][1].clear(); - for( int i = 0; i < lengthOfSample; ++i ) + for (int i = 0; i < lengthOfSample; ++i) { - b->samples[oscilNum][0].push_back(sampleBuffer->userWaveSample(i/lengthOfSample, 0)); - b->samples[oscilNum][1].push_back(sampleBuffer->userWaveSample(i/lengthOfSample, 1)); + m_b->m_samples[oscilNum][0].push_back(m_sampleBuffer->userWaveSample(i/lengthOfSample, 0)); + m_b->m_samples[oscilNum][1].push_back(m_sampleBuffer->userWaveSample(i/lengthOfSample, 1)); } - sampleBuffer->dataUnlock(); + m_sampleBuffer->dataUnlock(); } - sharedObject::unref( sampleBuffer ); + sharedObject::unref(m_sampleBuffer); } -void MicrowaveView::dropEvent( QDropEvent * _de ) +void MicrowaveView::dropEvent(QDropEvent * de) { - QString type = StringPairDrag::decodeKey( _de ); - QString value = StringPairDrag::decodeValue( _de ); - if( type == "samplefile" ) + QString type = StringPairDrag::decodeKey(de); + QString value = StringPairDrag::decodeValue(de); + if (type == "samplefile") { - wavetableFileName = value; - b->scroll = 6; + m_wavetableFileName = value; + m_b->m_scroll = 6; updateScroll(); - _de->accept(); + de->accept(); return; } - _de->ignore(); + de->ignore(); } -void MicrowaveView::dragEnterEvent( QDragEnterEvent * _dee ) +void MicrowaveView::dragEnterEvent(QDragEnterEvent * dee) { - if( _dee->mimeData()->hasFormat( StringPairDrag::mimeType() ) ) + if (dee->mimeData()->hasFormat(StringPairDrag::mimeType())) { - QString txt = _dee->mimeData()->data( - StringPairDrag::mimeType() ); - if( txt.section( ':', 0, 0 ) == "samplefile" ) + QString txt = dee->mimeData()->data( + StringPairDrag::mimeType()); + if (txt.section(':', 0, 0) == "samplefile") { - _dee->acceptProposedAction(); + dee->acceptProposedAction(); } else { - _dee->ignore(); + dee->ignore(); } } else { - _dee->ignore(); + dee->ignore(); } } @@ -3642,14 +3638,14 @@ void MicrowaveView::dragEnterEvent( QDragEnterEvent * _dee ) /* - ____ .--.--. ___ ,---, + ___ .--.--. __ ,---, ,' , `. / / '. ,--.'|_ ,--.' | - ,-+-,.' _ || : /`. / ,---, | | :,' | | : + ,-+-,.' || : /`. / ,---, | | :,' | | : ,-+-. ; , ||; | |--` ,-+-. / | : : ' : : : : ,--.'|' | ||| : ;_ .--, ,--.'|' |.;__,' / : | |,--. | | ,', | |, \ \ `. /_ ./| | | ,"' || | | | : ' | | | / | |--' `----. \, ' , ' : | | / | |:__,'| : | | /' : -| : | | , __ \ \ /___/ \: | | | | | | ' : |__ ' : | | | +| : | | , _ \ \ /___/ \: | | | | | | ' : |__ ' : | | | | : | |/ / /`--' /. \ ' | | | | |/ | | '.'|| | ' | : | | |`-' '--'. / \ ; : | | |--' ; : ;| : :_:,' | ;/ `--'---' \ \ ; | |/ | , / | | ,' @@ -3662,147 +3658,156 @@ void MicrowaveView::dragEnterEvent( QDragEnterEvent * _dee ) // Initializes mSynth (when a new note is played). Clone all of the arrays storing the knob values so they can be changed by modulation. -mSynth::mSynth( NotePlayHandle * _nph, - float * morphArr, float * rangeArr, float * modifyArr, int * modifyModeArr, float * volArr, float * panArr, float * detuneArr, float * phaseArr, float * phaseRandArr, bool * enabledArr, bool * mutedArr, - float * sampLenArr, float * morphMaxArr, float * unisonVoicesArr, float * unisonDetuneArr, float * unisonMorphArr, float * unisonModifyArr, bool * keytrackingArr, float * tempoArr, bool * interpolateArr, - bool * subEnabledArr, bool * subMutedArr, bool * subKeytrackArr, bool * subNoiseArr, float * subVolArr, float * subPanningArr, float * subDetuneArr, float * subPhaseArr, float * subPhaseRandArr, - float * subSampLenArr, float * subTempoArr, float * subRateLimitArr, float * subUnisonNumArr, float * subUnisonDetuneArr, bool * subInterpolateArr, - bool * sampleEnabledArr, bool * sampleMutedArr, bool * sampleKeytrackingArr, bool * sampleGraphEnabledArr, bool * sampleLoopArr, float * sampleVolumeArr, float * samplePanningArr, - float * sampleDetuneArr, float * samplePhaseArr, float * samplePhaseRandArr, float * sampleStartArr, float * sampleEndArr, - int * modInArr, int * modInNumArr, float * modInAmntArr, float * modInCurveArr, int * modIn2Arr, int * modInNum2Arr, float * modInAmnt2Arr, float * modInCurve2Arr, - int * modOutSecArr, int * modOutSigArr, int * modOutSecNumArr, bool * modEnabledArr, int * modCombineTypeArr, bool * modTypeArr, bool * modType2Arr, - float * filtCutoffArr, float * filtResoArr, float * filtGainArr, int * filtTypeArr, int * filtSlopeArr, float * filtInVolArr, float * filtOutVolArr, float * filtWetDryArr, float * filtBalArr, - float * filtSatuArr, float * filtFeedbackArr, float * filtDetuneArr, bool * filtEnabledArr, bool * filtMutedArr, bool * filtKeytrackingArr, - float * macroArr, - std::vector (&samples)[8][2] ) : - - nph( _nph ) +mSynth::mSynth(NotePlayHandle * m_nph, + float * m_morphArr, float * m_rangeArr, float * m_modifyArr, int * m_modifyModeArr, float * m_volArr, float * m_panArr, + float * m_detuneArr, float * m_phaseArr, float * m_phaseRandArr, bool * m_enabledArr, bool * m_mutedArr, + float * m_sampLenArr, float * m_morphMaxArr, float * m_unisonVoicesArr, float * m_unisonDetuneArr, float * m_unisonMorphArr, + float * m_unisonModifyArr, bool * m_keytrackingArr, float * m_tempoArr, bool * m_interpolateArr, + bool * m_subEnabledArr, bool * m_subMutedArr, bool * m_subKeytrackArr, bool * m_subNoiseArr, float * m_subVolArr, + float * m_subPanningArr, float * m_subDetuneArr, float * m_subPhaseArr, float * m_subPhaseRandArr, + float * m_subSampLenArr, float * m_subTempoArr, float * m_subRateLimitArr, float * m_subUnisonNumArr, float * m_subUnisonDetuneArr, bool * m_subInterpolateArr, + bool * m_sampleEnabledArr, bool * m_sampleMutedArr, bool * m_sampleKeytrackingArr, bool * m_sampleGraphEnabledArr, bool * m_sampleLoopArr, + float * m_sampleVolumeArr, float * m_samplePanningArr, float * m_sampleDetuneArr, float * m_samplePhaseArr, float * m_samplePhaseRandArr, float * m_sampleStartArr, float * m_sampleEndArr, + int * m_modInArr, int * m_modInNumArr, float * m_modInAmntArr, float * m_modInCurveArr, int * m_modIn2Arr, int * m_modInNum2Arr, float * m_modInAmnt2Arr, float * m_modInCurve2Arr, + int * m_modOutSecArr, int * m_modOutSigArr, int * m_modOutSecNumArr, bool * m_modEnabledArr, int * m_modCombineTypeArr, bool * m_modTypeArr, bool * m_modType2Arr, + float * m_filtCutoffArr, float * m_filtResoArr, float * m_filtGainArr, int * m_filtTypeArr, int * m_filtSlopeArr, + float * m_filtInVolArr, float * m_filtOutVolArr, float * m_filtWetDryArr, float * m_filtBalArr, + float * m_filtSatuArr, float * m_filtFeedbackArr, float * m_filtDetuneArr, bool * m_filtEnabledArr, bool * m_filtMutedArr, bool * m_filtKeytrackingArr, + float * m_macroArr, + std::vector (&m_samples)[8][2]) : + + m_nph(m_nph) { - memcpy( morph, morphArr, sizeof(float) * 8 ); - memcpy( range, rangeArr, sizeof(float) * 8 ); - memcpy( modify, modifyArr, sizeof(float) * 8 ); - memcpy( modifyMode, modifyModeArr, sizeof(int) * 8 ); - memcpy( vol, volArr, sizeof(int) * 8 ); - memcpy( pan, panArr, sizeof(float) * 8 ); - memcpy( detune, detuneArr, sizeof(float) * 8 ); - memcpy( phase, phaseArr, sizeof(int) * 8 ); - memcpy( phaseRand, phaseRandArr, sizeof(int) * 8 ); - memcpy( enabled, enabledArr, sizeof(bool) * 8 ); - memcpy( muted, mutedArr, sizeof(bool) * 8 ); - memcpy( sampLen, sampLenArr, sizeof(float) * 8 ); - memcpy( morphMax, morphMaxArr, sizeof(float) * 8 ); - memcpy( unisonVoices, unisonVoicesArr, sizeof(float) * 8 ); - memcpy( unisonDetune, unisonDetuneArr, sizeof(float) * 8 ); - memcpy( unisonMorph, unisonMorphArr, sizeof(float) * 8 ); - memcpy( unisonModify, unisonModifyArr, sizeof(float) * 8 ); - memcpy( keytracking, keytrackingArr, sizeof(bool) * 8 ); - memcpy( tempo, tempoArr, sizeof(float) * 8 ); - memcpy( interpolate, interpolateArr, sizeof(bool) * 8 ); - - memcpy( subEnabled, subEnabledArr, sizeof(bool) * 64 ); - memcpy( subMuted, subMutedArr, sizeof(bool) * 64 ); - memcpy( subKeytrack, subKeytrackArr, sizeof(bool) * 64 ); - memcpy( subNoise, subNoiseArr, sizeof(bool) * 64 ); - memcpy( subVol, subVolArr, sizeof(float) * 64 ); - memcpy( subPanning, subPanningArr, sizeof(float) * 64 ); - memcpy( subDetune, subDetuneArr, sizeof(float) * 64 ); - memcpy( subPhase, subPhaseArr, sizeof(float) * 64 ); - memcpy( subPhaseRand, subPhaseRandArr, sizeof(float) * 64 ); - memcpy( subSampLen, subSampLenArr, sizeof(float) * 64 ); - memcpy( subTempo, subTempoArr, sizeof(float) * 64 ); - memcpy( subRateLimit, subRateLimitArr, sizeof(float) * 64 ); - memcpy( subUnisonNum, subUnisonNumArr, sizeof(float) * 64 ); - memcpy( subUnisonDetune, subUnisonDetuneArr, sizeof(float) * 64 ); - memcpy( subInterpolate, subInterpolateArr, sizeof(bool) * 64 ); - - memcpy( sampleEnabled, sampleEnabledArr, sizeof(bool) * 8 ); - memcpy( sampleMuted, sampleMutedArr, sizeof(bool) * 8 ); - memcpy( sampleKeytracking, sampleKeytrackingArr, sizeof(bool) * 8 ); - memcpy( sampleGraphEnabled, sampleGraphEnabledArr, sizeof(bool) * 8 ); - memcpy( sampleLoop, sampleLoopArr, sizeof(bool) * 8 ); - memcpy( sampleVolume, sampleVolumeArr, sizeof(float) * 8 ); - memcpy( samplePanning, samplePanningArr, sizeof(float) * 8 ); - memcpy( sampleDetune, sampleDetuneArr, sizeof(float) * 8 ); - memcpy( samplePhase, samplePhaseArr, sizeof(float) * 8 ); - memcpy( samplePhaseRand, samplePhaseRandArr, sizeof(float) * 8 ); - memcpy( sampleStart, sampleStartArr, sizeof(float) * 8 ); - memcpy( sampleEnd, sampleEndArr, sizeof(float) * 8 ); - - memcpy( modIn, modInArr, sizeof(int) * 64 ); - memcpy( modInNum, modInNumArr, sizeof(int) * 64 ); - memcpy( modInAmnt, modInAmntArr, sizeof(float) * 64 ); - memcpy( modInCurve, modInCurveArr, sizeof(float) * 64 ); - memcpy( modIn2, modIn2Arr, sizeof(int) * 64 ); - memcpy( modInNum2, modInNum2Arr, sizeof(int) * 64 ); - memcpy( modInAmnt2, modInAmnt2Arr, sizeof(float) * 64 ); - memcpy( modInCurve2, modInCurve2Arr, sizeof(float) * 64 ); - memcpy( modOutSec, modOutSecArr, sizeof(int) * 64 ); - memcpy( modOutSig, modOutSigArr, sizeof(int) * 64 ); - memcpy( modOutSecNum, modOutSecNumArr, sizeof(int) * 64 ); - memcpy( modEnabled, modEnabledArr, sizeof(bool) * 64 ); - memcpy( modCombineType, modCombineTypeArr, sizeof(int) * 64 ); - memcpy( modType, modTypeArr, sizeof(bool) * 64 ); - memcpy( modType2, modType2Arr, sizeof(bool) * 64 ); - - memcpy( filtCutoff, filtCutoffArr, sizeof(float) * 8 ); - memcpy( filtReso, filtResoArr, sizeof(float) * 8 ); - memcpy( filtGain, filtGainArr, sizeof(float) * 8 ); - memcpy( filtType, filtTypeArr, sizeof(int) * 8 ); - memcpy( filtSlope, filtSlopeArr, sizeof(int) * 8 ); - memcpy( filtInVol, filtInVolArr, sizeof(float) * 8 ); - memcpy( filtOutVol, filtOutVolArr, sizeof(float) * 8 ); - memcpy( filtWetDry, filtWetDryArr, sizeof(float) * 8 ); - memcpy( filtBal, filtBalArr, sizeof(float) * 8 ); - memcpy( filtSatu, filtSatuArr, sizeof(float) * 8 ); - memcpy( filtFeedback, filtFeedbackArr, sizeof(float) * 8 ); - memcpy( filtDetune, filtDetuneArr, sizeof(float) * 8 ); - memcpy( filtEnabled, filtEnabledArr, sizeof(bool) * 8 ); - memcpy( filtMuted, filtMutedArr, sizeof(bool) * 8 ); - memcpy( filtKeytracking, filtKeytrackingArr, sizeof(bool) * 8 ); - - memcpy( macro, macroArr, sizeof(float) * 18 ); - - - - for( int i = 0; i < 8; ++i ) + memcpy(m_morph, m_morphArr, sizeof(float) * 8); + memcpy(m_range, m_rangeArr, sizeof(float) * 8); + memcpy(m_modify, m_modifyArr, sizeof(float) * 8); + memcpy(m_modifyMode, m_modifyModeArr, sizeof(int) * 8); + memcpy(m_vol, m_volArr, sizeof(int) * 8); + memcpy(m_pan, m_panArr, sizeof(float) * 8); + memcpy(m_detune, m_detuneArr, sizeof(float) * 8); + memcpy(m_phase, m_phaseArr, sizeof(int) * 8); + memcpy(m_phaseRand, m_phaseRandArr, sizeof(int) * 8); + memcpy(m_enabled, m_enabledArr, sizeof(bool) * 8); + memcpy(m_muted, m_mutedArr, sizeof(bool) * 8); + memcpy(m_sampLen, m_sampLenArr, sizeof(float) * 8); + memcpy(m_morphMax, m_morphMaxArr, sizeof(float) * 8); + memcpy(m_unisonVoices, m_unisonVoicesArr, sizeof(float) * 8); + memcpy(m_unisonDetune, m_unisonDetuneArr, sizeof(float) * 8); + memcpy(m_unisonMorph, m_unisonMorphArr, sizeof(float) * 8); + memcpy(m_unisonModify, m_unisonModifyArr, sizeof(float) * 8); + memcpy(m_keytracking, m_keytrackingArr, sizeof(bool) * 8); + memcpy(m_tempo, m_tempoArr, sizeof(float) * 8); + memcpy(m_interpolate, m_interpolateArr, sizeof(bool) * 8); + + memcpy(m_subEnabled, m_subEnabledArr, sizeof(bool) * 64); + memcpy(m_subMuted, m_subMutedArr, sizeof(bool) * 64); + memcpy(m_subKeytrack, m_subKeytrackArr, sizeof(bool) * 64); + memcpy(m_subNoise, m_subNoiseArr, sizeof(bool) * 64); + memcpy(m_subVol, m_subVolArr, sizeof(float) * 64); + memcpy(m_subPanning, m_subPanningArr, sizeof(float) * 64); + memcpy(m_subDetune, m_subDetuneArr, sizeof(float) * 64); + memcpy(m_subPhase, m_subPhaseArr, sizeof(float) * 64); + memcpy(m_subPhaseRand, m_subPhaseRandArr, sizeof(float) * 64); + memcpy(m_subSampLen, m_subSampLenArr, sizeof(float) * 64); + memcpy(m_subTempo, m_subTempoArr, sizeof(float) * 64); + memcpy(m_subRateLimit, m_subRateLimitArr, sizeof(float) * 64); + memcpy(m_subUnisonNum, m_subUnisonNumArr, sizeof(float) * 64); + memcpy(m_subUnisonDetune, m_subUnisonDetuneArr, sizeof(float) * 64); + memcpy(m_subInterpolate, m_subInterpolateArr, sizeof(bool) * 64); + + memcpy(m_sampleEnabled, m_sampleEnabledArr, sizeof(bool) * 8); + memcpy(m_sampleMuted, m_sampleMutedArr, sizeof(bool) * 8); + memcpy(m_sampleKeytracking, m_sampleKeytrackingArr, sizeof(bool) * 8); + memcpy(m_sampleGraphEnabled, m_sampleGraphEnabledArr, sizeof(bool) * 8); + memcpy(m_sampleLoop, m_sampleLoopArr, sizeof(bool) * 8); + memcpy(m_sampleVolume, m_sampleVolumeArr, sizeof(float) * 8); + memcpy(m_samplePanning, m_samplePanningArr, sizeof(float) * 8); + memcpy(m_sampleDetune, m_sampleDetuneArr, sizeof(float) * 8); + memcpy(m_samplePhase, m_samplePhaseArr, sizeof(float) * 8); + memcpy(m_samplePhaseRand, m_samplePhaseRandArr, sizeof(float) * 8); + memcpy(m_sampleStart, m_sampleStartArr, sizeof(float) * 8); + memcpy(m_sampleEnd, m_sampleEndArr, sizeof(float) * 8); + + memcpy(m_modIn, m_modInArr, sizeof(int) * 64); + memcpy(m_modInNum, m_modInNumArr, sizeof(int) * 64); + memcpy(m_modInAmnt, m_modInAmntArr, sizeof(float) * 64); + memcpy(m_modInCurve, m_modInCurveArr, sizeof(float) * 64); + memcpy(m_modIn2, m_modIn2Arr, sizeof(int) * 64); + memcpy(m_modInNum2, m_modInNum2Arr, sizeof(int) * 64); + memcpy(m_modInAmnt2, m_modInAmnt2Arr, sizeof(float) * 64); + memcpy(m_modInCurve2, m_modInCurve2Arr, sizeof(float) * 64); + memcpy(m_modOutSec, m_modOutSecArr, sizeof(int) * 64); + memcpy(m_modOutSig, m_modOutSigArr, sizeof(int) * 64); + memcpy(m_modOutSecNum, m_modOutSecNumArr, sizeof(int) * 64); + memcpy(m_modEnabled, m_modEnabledArr, sizeof(bool) * 64); + memcpy(m_modCombineType, m_modCombineTypeArr, sizeof(int) * 64); + memcpy(m_modType, m_modTypeArr, sizeof(bool) * 64); + memcpy(m_modType2, m_modType2Arr, sizeof(bool) * 64); + + memcpy(m_filtCutoff, m_filtCutoffArr, sizeof(float) * 8); + memcpy(m_filtReso, m_filtResoArr, sizeof(float) * 8); + memcpy(m_filtGain, m_filtGainArr, sizeof(float) * 8); + memcpy(m_filtType, m_filtTypeArr, sizeof(int) * 8); + memcpy(m_filtSlope, m_filtSlopeArr, sizeof(int) * 8); + memcpy(m_filtInVol, m_filtInVolArr, sizeof(float) * 8); + memcpy(m_filtOutVol, m_filtOutVolArr, sizeof(float) * 8); + memcpy(m_filtWetDry, m_filtWetDryArr, sizeof(float) * 8); + memcpy(m_filtBal, m_filtBalArr, sizeof(float) * 8); + memcpy(m_filtSatu, m_filtSatuArr, sizeof(float) * 8); + memcpy(m_filtFeedback, m_filtFeedbackArr, sizeof(float) * 8); + memcpy(m_filtDetune, m_filtDetuneArr, sizeof(float) * 8); + memcpy(m_filtEnabled, m_filtEnabledArr, sizeof(bool) * 8); + memcpy(m_filtMuted, m_filtMutedArr, sizeof(bool) * 8); + memcpy(m_filtKeytracking, m_filtKeytrackingArr, sizeof(bool) * 8); + + memcpy(m_macro, m_macroArr, sizeof(float) * 18); + + + + for (int i = 0; i < 8; ++i) { - for( int j = 0; j < 32; ++j ) + for (int j = 0; j < 32; ++j) { // Randomize the phases of all of the waveforms - sample_realindex[i][j] = int( ( ( fastRandf( sampLen[i] * WAVERATIO ) ) * ( phaseRand[i] * 0.01f ) ) ) % int( sampLen[i] * WAVERATIO ); + m_sample_realindex[i][j] = int(((fastRandf(m_sampLen[i] * WAVERATIO)) * + (m_phaseRand[i] * 0.01f))) % int(m_sampLen[i] * WAVERATIO); } } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - for( int l = 0; l < 32; ++l ) + for (int l = 0; l < 32; ++l) { - sample_subindex[i][l] = int( ( ( fastRandf( subSampLen[i] * WAVERATIO ) - ( subSampLen[i] * WAVERATIO * 0.5f ) ) * ( subPhaseRand[i] * 0.01f ) ) ) % int( subSampLen[i] * WAVERATIO ); - subNoiseDirection[i][l] = 1; + m_sample_subindex[i][l] = int(((fastRandf(m_subSampLen[i] * WAVERATIO) - + (m_subSampLen[i] * WAVERATIO * 0.5f)) * (m_subPhaseRand[i] * 0.01f))) % + int(m_subSampLen[i] * WAVERATIO); + m_subNoiseDirection[i][l] = 1; } } - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - sample_sampleindex[i] = fmod( fastRandf( samples[i][0].size() ) * ( samplePhaseRand[i] * 0.01f ), ( samples[i][0].size() *sampleEnd[i] ) - ( samples[i][0].size() * sampleStart[i] ) ) + ( samples[i][0].size() * sampleStart[i] ); - humanizer[i] = ( rand() / float(RAND_MAX) ) * 2 - 1;// Generate humanizer values at the beginning of every note + m_sample_sampleindex[i] = fmod(fastRandf(m_samples[i][0].size()) * (m_samplePhaseRand[i] * 0.01f), + (m_samples[i][0].size() *m_sampleEnd[i]) - (m_samples[i][0].size() * m_sampleStart[i])) + + (m_samples[i][0].size() * m_sampleStart[i]); + m_humanizer[i] = (rand() / float(RAND_MAX)) * 2 - 1;// Generate humanizer values at the beginning of every note } - noteDuration = -1; + m_noteDuration = -1; - for( int i = 0; i < 8; ++i ) + for (int i = 0; i < 8; ++i) { - for( int j = 0; j < unisonVoices[i]; ++j ) + for (int j = 0; j < m_unisonVoices[i]; ++j) { - unisonDetuneAmounts[i][j] = ((rand()/float(RAND_MAX))*2.f)-1; + m_unisonDetuneAmounts[i][j] = ((rand()/float(RAND_MAX))*2.f)-1; } } - for( int i = 0; i < 64; ++i ) + for (int i = 0; i < 64; ++i) { - for( int j = 0; j < subUnisonNum[i]; ++j ) + for (int j = 0; j < m_subUnisonNum[i]; ++j) { - subUnisonDetuneAmounts[i][j] = ((rand()/float(RAND_MAX))*2.f)-1; + m_subUnisonDetuneAmounts[i][j] = ((rand()/float(RAND_MAX))*2.f)-1; } } @@ -3816,332 +3821,344 @@ mSynth::~mSynth() // The heart of Microwave. As you probably learned in anatomy class, hearts actually aren't too pretty. This is no exception. // This is the part that puts everything together and calculates an audio output. -void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][MAINARRAYLEN], float (&subs)[64][SUBWAVELEN], float * sampGraphs, std::vector (&samples)[8][2], int maxFiltEnabled, int maxModEnabled, int maxSubEnabled, int maxSampleEnabled, int maxMainEnabled, int sample_rate, Microwave * mwc, bool removeDC, bool isOversamplingSample, float (&storedsubs)[64][STOREDSUBWAVELEN] ) +void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8][MAINARRAYLEN], float (&m_subs)[64][SUBWAVELEN], + std::vector (&m_samples)[8][2], float * m_sampGraphs, int m_maxMainEnabled, int m_maxSubEnabled, + int m_maxSampleEnabled, int m_maxFiltEnabled, int m_maxModEnabled, int sample_rate, Microwave * m_mwc, + bool m_removeDC, float (&m_storedsubs)[64][STOREDSUBWAVELEN]) { - - ++noteDuration; + ++m_noteDuration; //============// //== MATRIX ==// //============// - numberToReset = 0; - for( int l = 0; l < maxModEnabled; ++l )// maxModEnabled keeps this from looping 64 times every sample, saving a lot of CPU + m_numberToReset = 0; + for (int l = 0; l < m_maxModEnabled; ++l)// m_maxModEnabled keeps this from looping 64 times every m_sample, saving a lot of CPU { - if( modEnabled[l] ) + if (m_modEnabled[l]) { - switch( modIn[l] ) + switch (m_modIn[l]) { case 0: { - curModVal[0] = 0; - curModVal[1] = 0; + m_curModVal[0] = 0; + m_curModVal[1] = 0; break; } - case 1:// Wavetable + case 1:// Wavetablenumber { - if( modType[l] )// If envelope + if (m_modType[l])// If envelope { - curModVal[0] = lastMainOscEnvVal[modInNum[l]-1][0]; - curModVal[1] = lastMainOscEnvVal[modInNum[l]-1][1]; + m_curModVal[0] = m_lastMainOscEnvVal[m_modInNum[l]-1][0]; + m_curModVal[1] = m_lastMainOscEnvVal[m_modInNum[l]-1][1]; } else { - curModVal[0] = lastMainOscVal[modInNum[l]-1][0]; - curModVal[1] = lastMainOscVal[modInNum[l]-1][1]; + m_curModVal[0] = m_lastMainOscVal[m_modInNum[l]-1][0]; + m_curModVal[1] = m_lastMainOscVal[m_modInNum[l]-1][1]; } break; } case 2:// Sub { - if( modType[l] )// If envelope + if (m_modType[l])// If envelope { - curModVal[0] = lastSubEnvVal[modInNum[l]-1][0]; - curModVal[1] = lastSubEnvVal[modInNum[l]-1][1]; + m_curModVal[0] = m_lastSubEnvVal[m_modInNum[l]-1][0]; + m_curModVal[1] = m_lastSubEnvVal[m_modInNum[l]-1][1]; } else { - curModVal[0] = lastSubVal[modInNum[l]-1][0]; - curModVal[1] = lastSubVal[modInNum[l]-1][1]; + m_curModVal[0] = m_lastSubVal[m_modInNum[l]-1][0]; + m_curModVal[1] = m_lastSubVal[m_modInNum[l]-1][1]; } break; } case 3:// Sample { - if( modType[l] )// If envelope + if (m_modType[l])// If envelope { - curModVal[0] = lastSampleEnvVal[modInNum[l]-1][0]; - curModVal[1] = lastSampleEnvVal[modInNum[l]-1][1]; + m_curModVal[0] = m_lastSampleEnvVal[m_modInNum[l]-1][0]; + m_curModVal[1] = m_lastSampleEnvVal[m_modInNum[l]-1][1]; } else { - curModVal[0] = lastSampleVal[modInNum[l]-1][0]; - curModVal[1] = lastSampleVal[modInNum[l]-1][1]; + m_curModVal[0] = m_lastSampleVal[m_modInNum[l]-1][0]; + m_curModVal[1] = m_lastSampleVal[m_modInNum[l]-1][1]; } break; } case 4:// Filter { - curModVal[0] = filtModOutputs[modInNum[l]-1][0]; - curModVal[1] = filtModOutputs[modInNum[l]-1][1]; + m_curModVal[0] = m_filtModOutputs[m_modInNum[l]-1][0]; + m_curModVal[1] = m_filtModOutputs[m_modInNum[l]-1][1]; break; } case 5:// Velocity { - curModVal[0] = ( nph->getVolume() * 0.01f )-1; - curModVal[1] = curModVal[0]; + m_curModVal[0] = (m_nph->getVolume() * 0.01f)-1; + m_curModVal[1] = m_curModVal[0]; break; } case 6:// Panning { - curModVal[0] = ( nph->getPanning() * 0.01f ); - curModVal[1] = curModVal[0]; + m_curModVal[0] = (m_nph->getPanning() * 0.01f); + m_curModVal[1] = m_curModVal[0]; break; } case 7:// Humanizer { - curModVal[0] = humanizer[modInNum[l]-1]; - curModVal[1] = humanizer[modInNum[l]-1]; + m_curModVal[0] = m_humanizer[m_modInNum[l]-1]; + m_curModVal[1] = m_humanizer[m_modInNum[l]-1]; break; } case 8:// Macro { - curModVal[0] = macro[modInNum[l]-1] * 0.01f; - curModVal[1] = macro[modInNum[l]-1] * 0.01f; + m_curModVal[0] = m_macro[m_modInNum[l]-1] * 0.01f; + m_curModVal[1] = m_macro[m_modInNum[l]-1] * 0.01f; break; } default: { - switch( modCombineType[l] ) + switch (m_modCombineType[l]) { case 0:// Add Bidirectional { - curModVal[0] = 0; - curModVal[1] = 0; + m_curModVal[0] = 0; + m_curModVal[1] = 0; break; } case 1:// Multiply Bidirectional { - curModVal[0] = 0; - curModVal[1] = 0; + m_curModVal[0] = 0; + m_curModVal[1] = 0; break; } case 2:// Add Unidirectional { - curModVal[0] = -1; - curModVal[1] = -1; + m_curModVal[0] = -1; + m_curModVal[1] = -1; break; } case 3:// Multiply Unidirectional { - curModVal[0] = -1; - curModVal[1] = -1; + m_curModVal[0] = -1; + m_curModVal[1] = -1; break; } } } } - switch( modIn2[l] ) + switch (m_modIn2[l]) { case 0: { - curModVal2[0] = 0; - curModVal2[1] = 0; + m_curModVal2[0] = 0; + m_curModVal2[1] = 0; break; } case 1:// Wavetable { - if( modType2[l] )// If envelope + if (m_modType2[l])// If envelope { - curModVal2[0] = lastMainOscEnvVal[modInNum2[l]-1][0]; - curModVal2[1] = lastMainOscEnvVal[modInNum2[l]-1][1]; + m_curModVal2[0] = m_lastMainOscEnvVal[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_lastMainOscEnvVal[m_modInNum2[l]-1][1]; } else { - curModVal2[0] = lastMainOscVal[modInNum2[l]-1][0]; - curModVal2[1] = lastMainOscVal[modInNum2[l]-1][1]; + m_curModVal2[0] = m_lastMainOscVal[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_lastMainOscVal[m_modInNum2[l]-1][1]; } break; } case 2:// Sub { - if( modType2[l] )// If envelope + if (m_modType2[l])// If envelope { - curModVal2[0] = lastSubEnvVal[modInNum2[l]-1][0]; - curModVal2[1] = lastSubEnvVal[modInNum2[l]-1][1]; + m_curModVal2[0] = m_lastSubEnvVal[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_lastSubEnvVal[m_modInNum2[l]-1][1]; } else { - curModVal2[0] = lastSubVal[modInNum2[l]-1][0]; - curModVal2[1] = lastSubVal[modInNum2[l]-1][1]; + m_curModVal2[0] = m_lastSubVal[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_lastSubVal[m_modInNum2[l]-1][1]; } break; } case 3:// Sample { - if( modType[l] )// If envelope + if (m_modType[l])// If envelope { - curModVal2[0] = lastSampleEnvVal[modInNum2[l]-1][0]; - curModVal2[1] = lastSampleEnvVal[modInNum2[l]-1][1]; + m_curModVal2[0] = m_lastSampleEnvVal[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_lastSampleEnvVal[m_modInNum2[l]-1][1]; } else { - curModVal2[0] = lastSampleVal[modInNum2[l]-1][0]; - curModVal2[1] = lastSampleVal[modInNum2[l]-1][1]; + m_curModVal2[0] = m_lastSampleVal[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_lastSampleVal[m_modInNum2[l]-1][1]; } break; } case 4:// Filter { - curModVal2[0] = filtModOutputs[modInNum2[l]-1][0]; - curModVal2[1] = filtModOutputs[modInNum2[l]-1][1]; + m_curModVal2[0] = m_filtModOutputs[m_modInNum2[l]-1][0]; + m_curModVal2[1] = m_filtModOutputs[m_modInNum2[l]-1][1]; } case 5:// Velocity { - curModVal2[0] = (nph->getVolume() * 0.01f)-1; - curModVal2[1] = curModVal2[0]; + m_curModVal2[0] = (m_nph->getVolume() * 0.01f)-1; + m_curModVal2[1] = m_curModVal2[0]; break; } case 6:// Panning { - curModVal2[0] = (nph->getPanning() * 0.01f); - curModVal2[1] = curModVal2[0]; + m_curModVal2[0] = (m_nph->getPanning() * 0.01f); + m_curModVal2[1] = m_curModVal2[0]; break; } case 7:// Humanizer { - curModVal2[0] = humanizer[modInNum2[l]-1]; - curModVal2[1] = humanizer[modInNum2[l]-1]; + m_curModVal2[0] = m_humanizer[m_modInNum2[l]-1]; + m_curModVal2[1] = m_humanizer[m_modInNum2[l]-1]; break; } case 8:// Macro { - curModVal2[0] = macro[modInNum2[l]-1] * 0.01f; - curModVal2[1] = macro[modInNum2[l]-1] * 0.01f; + m_curModVal2[0] = m_macro[m_modInNum2[l]-1] * 0.01f; + m_curModVal2[1] = m_macro[m_modInNum2[l]-1] * 0.01f; break; } default: { - switch( modCombineType[l] ) + switch (m_modCombineType[l]) { case 0:// Add Bidirectional { - curModVal[0] = 0; - curModVal[1] = 0; + m_curModVal[0] = 0; + m_curModVal[1] = 0; break; } case 1:// Multiply Bidirectional { - curModVal[0] = 0; - curModVal[1] = 0; + m_curModVal[0] = 0; + m_curModVal[1] = 0; break; } case 2:// Add Unidirectional { - curModVal[0] = -1; - curModVal[1] = -1; + m_curModVal[0] = -1; + m_curModVal[1] = -1; break; } case 3:// Multiply Unidirectional { - curModVal[0] = -1; - curModVal[1] = -1; + m_curModVal[0] = -1; + m_curModVal[1] = -1; break; } } } } - if( curModVal[0] ) { curModVal[0] *= modInAmnt[l] * 0.01f; } - if( curModVal[1] ) { curModVal[1] *= modInAmnt[l] * 0.01f; } - if( curModVal2[0] ) { curModVal2[0] *= modInAmnt2[l] * 0.01f; } - if( curModVal2[1] ) { curModVal2[1] *= modInAmnt2[l] * 0.01f; } + if (m_curModVal[0] ) { m_curModVal[0] *= m_modInAmnt[l] * 0.01f; } + if (m_curModVal[1] ) { m_curModVal[1] *= m_modInAmnt[l] * 0.01f; } + if (m_curModVal2[0]) { m_curModVal2[0] *= m_modInAmnt2[l] * 0.01f; } + if (m_curModVal2[1]) { m_curModVal2[1] *= m_modInAmnt2[l] * 0.01f; } // Calculate curve - if( modCombineType[l] <= 1 )// Bidirectional + if (m_modCombineType[l] <= 1)// Bidirectional { - if( modInCurve[l] != 100.f )// The "if" statement is there so unnecessary CPU isn't spent (pow is very expensive) if the curve knob isn't being used. + if (m_modInCurve[l] != 100.f)// The "if" statement is there so unnecessary CPU isn't spent (pow is very expensive) if the curve knob isn't being used. { // Move to a scale of 0 to 1 (from -1 to 1) and then apply the curve. - curModValCurve[0] = (curModVal[0] <= -1 || curModVal[0] >= 1) ? ( curModVal[0] + 1 ) * 0.5f : pow( ( curModVal[0] + 1 ) * 0.5f, 1.f / ( modInCurve[l] * 0.01f ) ); - curModValCurve[1] = (curModVal[1] <= -1 || curModVal[1] >= 1) ? ( curModVal[1] + 1 ) * 0.5f : pow( ( curModVal[1] + 1 ) * 0.5f, 1.f / ( modInCurve[l] * 0.01f ) ); + m_temp1 = 1.f / (m_modInCurve[l] * 0.01f); + m_curModValCurve[0] = (m_curModVal[0] <= -1 || m_curModVal[0] >= 1) ? (m_curModVal[0] + 1) * 0.5f : pow((m_curModVal[0] + 1) * 0.5f, m_temp1); + m_curModValCurve[1] = (m_curModVal[1] <= -1 || m_curModVal[1] >= 1) ? (m_curModVal[1] + 1) * 0.5f : pow((m_curModVal[1] + 1) * 0.5f, m_temp1); } else { - curModValCurve[0] = ( curModVal[0] + 1 ) * 0.5f; - curModValCurve[1] = ( curModVal[1] + 1 ) * 0.5f; + m_curModValCurve[0] = (m_curModVal[0] + 1) * 0.5f; + m_curModValCurve[1] = (m_curModVal[1] + 1) * 0.5f; } - if( modInCurve2[l] != 100.f ) + if (m_modInCurve2[l] != 100.f) { - curModVal2Curve[0] = (curModVal2[0] <= -1 || curModVal2[0] >= 1) ? ( curModVal2[0] + 1 ) * 0.5f : pow( ( curModVal2[0] + 1 ) * 0.5f, 1.f / ( modInCurve2[l] * 0.01f ) ); - curModVal2Curve[1] = (curModVal2[1] <= -1 || curModVal2[1] >= 1) ? ( curModVal2[1] + 1 ) * 0.5f : pow( ( curModVal2[1] + 1 ) * 0.5f, 1.f / ( modInCurve2[l] * 0.01f ) ); + m_temp1 = 1.f / (m_modInCurve2[l] * 0.01f); + m_curModVal2Curve[0] = (m_curModVal2[0] <= -1 || m_curModVal2[0] >= 1) ? (m_curModVal2[0] + 1) * 0.5f : pow((m_curModVal2[0] + 1) * 0.5f, m_temp1); + m_curModVal2Curve[1] = (m_curModVal2[1] <= -1 || m_curModVal2[1] >= 1) ? (m_curModVal2[1] + 1) * 0.5f : pow((m_curModVal2[1] + 1) * 0.5f, m_temp1); } else { - curModVal2Curve[0] = ( curModVal2[0] + 1 ) * 0.5f; - curModVal2Curve[1] = ( curModVal2[1] + 1 ) * 0.5f; + m_curModVal2Curve[0] = (m_curModVal2[0] + 1) * 0.5f; + m_curModVal2Curve[1] = (m_curModVal2[1] + 1) * 0.5f; } } else// Unidirectional { - if( modInCurve[l] != 100.f ) + if (m_modInCurve[l] != 100.f) { - curModValCurve[0] = ( (curModVal[0] <= -1 || curModVal[0] >= 1) ? curModVal[0] : pow( abs( curModVal[0] ), 1.f / ( modInCurve[l] * 0.01f ) ) * ( curModVal[0] < 0 ? -1 : 1 ) ) + (modInAmnt[l] * 0.01); - curModValCurve[1] = ( (curModVal[1] <= -1 || curModVal[1] >= 1) ? curModVal[1] : pow( abs( curModVal[1] ), 1.f / ( modInCurve[l] * 0.01f ) ) * ( curModVal[1] < 0 ? -1 : 1 ) ) + (modInAmnt[l] * 0.01); + m_temp1 = m_modInCurve[l] * 0.01f; + m_temp2 = m_curModVal[0] < 0 ? -1 : 1; + m_temp3 = m_modInAmnt[l] * 0.01; + m_curModValCurve[0] = ((m_curModVal[0] <= -1 || m_curModVal[0] >= 1) ? m_curModVal[0] : pow(abs(m_curModVal[0]), 1.f / m_temp1) * m_temp2) + m_temp3; + m_curModValCurve[1] = ((m_curModVal[1] <= -1 || m_curModVal[1] >= 1) ? m_curModVal[1] : pow(abs(m_curModVal[1]), 1.f / m_temp1) * m_temp2) + m_temp3; } else { - curModValCurve[0] = curModVal[0] + (modInAmnt[l] * 0.01); - curModValCurve[1] = curModVal[1] + (modInAmnt[l] * 0.01); + m_temp1 = m_modInAmnt[l] * 0.01; + m_curModValCurve[0] = m_curModVal[0] + m_temp1; + m_curModValCurve[1] = m_curModVal[1] + m_temp1; } - if( modInCurve2[l] != 100.f ) + if (m_modInCurve2[l] != 100.f) { - curModVal2Curve[0] = ( (curModVal2[0] <= -1 || curModVal2[0] >= 1) ? curModVal2[0] : pow( abs( curModVal2[0] ), 1.f / ( modInCurve2[l] * 0.01f ) ) * ( curModVal2[0] < 0 ? -1 : 1 ) ) + (modInAmnt2[l] * 0.01); - curModVal2Curve[1] = ( (curModVal2[1] <= -1 || curModVal2[1] >= 1) ? curModVal2[1] : pow( abs( curModVal2[0] ), 1.f / ( modInCurve2[l] * 0.01f ) ) * ( curModVal2[0] < 0 ? -1 : 1 ) ) + (modInAmnt2[l] * 0.01); + m_temp1 = m_modInCurve2[l] * 0.01f; + m_temp2 = m_curModVal2[0] < 0 ? -1 : 1; + m_temp3 = m_modInAmnt2[l] * 0.01; + m_curModVal2Curve[0] = ((m_curModVal2[0] <= -1 || m_curModVal2[0] >= 1) ? m_curModVal2[0] : pow(abs(m_curModVal2[0]), 1.f / m_temp1) * m_temp2) + m_temp3; + m_curModVal2Curve[1] = ((m_curModVal2[1] <= -1 || m_curModVal2[1] >= 1) ? m_curModVal2[1] : pow(abs(m_curModVal2[0]), 1.f / m_temp1) * m_temp2) + m_temp3; } else { - curModVal2Curve[0] = curModVal2[0] + (modInAmnt2[l] * 0.01); - curModVal2Curve[1] = curModVal2[1] + (modInAmnt2[l] * 0.01); + m_temp1 = m_modInAmnt2[l] * 0.01; + m_curModVal2Curve[0] = m_curModVal2[0] + m_temp1; + m_curModVal2Curve[1] = m_curModVal2[1] + m_temp1; } } - switch( modCombineType[l] ) + switch (m_modCombineType[l]) { case 0:// Add Bidirectional { - comboModVal[0] = curModValCurve[0] + curModVal2Curve[0] - 1; - comboModVal[1] = curModValCurve[1] + curModVal2Curve[1] - 1; + m_comboModVal[0] = m_curModValCurve[0] + m_curModVal2Curve[0] - 1; + m_comboModVal[1] = m_curModValCurve[1] + m_curModVal2Curve[1] - 1; break; } case 1:// Multiply Bidirectional { - comboModVal[0] = ( curModValCurve[0] * 2 - 1 ) * ( curModVal2Curve[0] * 2 - 1 ); - comboModVal[1] = ( curModValCurve[1] * 2 - 1 ) * ( curModVal2Curve[1] * 2 - 1 ); + m_comboModVal[0] = (m_curModValCurve[0] * 2 - 1) * (m_curModVal2Curve[0] * 2 - 1); + m_comboModVal[1] = (m_curModValCurve[1] * 2 - 1) * (m_curModVal2Curve[1] * 2 - 1); break; } case 2:// Add Unidirectional { - comboModVal[0] = curModValCurve[0] + curModVal2Curve[0]; - comboModVal[1] = curModValCurve[1] + curModVal2Curve[1]; + m_comboModVal[0] = m_curModValCurve[0] + m_curModVal2Curve[0]; + m_comboModVal[1] = m_curModValCurve[1] + m_curModVal2Curve[1]; break; } case 3:// Multiply Unidirectional { - comboModVal[0] = curModValCurve[0] * curModVal2Curve[0]; - comboModVal[1] = curModValCurve[1] * curModVal2Curve[1]; + m_comboModVal[0] = m_curModValCurve[0] * m_curModVal2Curve[0]; + m_comboModVal[1] = m_curModValCurve[1] * m_curModVal2Curve[1]; break; } default: { - comboModVal[0] = 0; - comboModVal[1] = 0; + m_comboModVal[0] = 0; + m_comboModVal[1] = 0; } } - comboModValMono = ( comboModVal[0] + comboModVal[1] ) * 0.5f; + m_comboModValMono = (m_comboModVal[0] + m_comboModVal[1]) * 0.5f; - switch( modOutSec[l] ) + switch (m_modOutSec[l]) { case 0: { @@ -4149,7 +4166,7 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Main Oscillator { - switch( modOutSig[l] ) + switch (m_modOutSig[l]) { case 0: { @@ -4157,90 +4174,92 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Send input to Morph { - morph[modOutSecNum[l]-1] = qBound( 0.f, morph[modOutSecNum[l]-1] + comboModValMono*morphMax[modOutSecNum[l]-1], morphMax[modOutSecNum[l]-1] ); - modValType[numberToReset] = 1; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_morph[m_modOutSecNum[l]-1] = qBound(0.f, m_morph[m_modOutSecNum[l]-1] + + m_comboModValMono*m_morphMax[m_modOutSecNum[l]-1], m_morphMax[m_modOutSecNum[l]-1]); + m_modValType[m_numberToReset] = 1; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 2:// Send input to Range { - range[modOutSecNum[l]-1] = qMax( 0.f, range[modOutSecNum[l]-1] + comboModValMono * 16.f ); - modValType[numberToReset] = 2; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_range[m_modOutSecNum[l]-1] = qMax(0.f, m_range[m_modOutSecNum[l]-1] + m_comboModValMono * 16.f); + m_modValType[m_numberToReset] = 2; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 3:// Send input to Modify { - modify[modOutSecNum[l]-1] = qMax( 0.f, modify[modOutSecNum[l]-1] + comboModValMono * 2048.f ); - modValType[numberToReset] = 3; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modify[m_modOutSecNum[l]-1] = qMax(0.f, m_modify[m_modOutSecNum[l]-1] + m_comboModValMono * 2048.f); + m_modValType[m_numberToReset] = 3; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 4:// Send input to Pitch/Detune { - detune[modOutSecNum[l]-1] = detune[modOutSecNum[l]-1] + comboModValMono * 4800.f; - modValType[numberToReset] = 7; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_detune[m_modOutSecNum[l]-1] = m_detune[m_modOutSecNum[l]-1] + m_comboModValMono * 4800.f; + m_modValType[m_numberToReset] = 7; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 5:// Send input to Phase { - phase[modOutSecNum[l]-1] = phase[modOutSecNum[l]-1] + comboModValMono * 8.f; - modValType[numberToReset] = 8; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_phase[m_modOutSecNum[l]-1] = m_phase[m_modOutSecNum[l]-1] + m_comboModValMono * 8.f; + m_modValType[m_numberToReset] = 8; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 6:// Send input to Volume { - vol[modOutSecNum[l]-1] = qMax( 0.f, vol[modOutSecNum[l]-1] + comboModValMono * 100.f ); - modValType[numberToReset] = 5; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_vol[m_modOutSecNum[l]-1] = qMax(0.f, m_vol[m_modOutSecNum[l]-1] + m_comboModValMono * 100.f); + m_modValType[m_numberToReset] = 5; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 7:// Send input to Panning { - pan[modOutSecNum[l]-1] = qMax( 0.f, pan[modOutSecNum[l]-1] + comboModValMono * 200.f ); - modValType[numberToReset] = 6; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_pan[m_modOutSecNum[l]-1] = qMax(0.f, m_pan[m_modOutSecNum[l]-1] + m_comboModValMono * 200.f); + m_modValType[m_numberToReset] = 6; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 8:// Send input to Unison Voice Number { - unisonVoices[modOutSecNum[l]-1] = qMax( 0.f, unisonVoices[modOutSecNum[l]-1] + comboModValMono * 32.f ); - modValType[numberToReset] = 14; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_unisonVoices[m_modOutSecNum[l]-1] = qMax(0.f, m_unisonVoices[m_modOutSecNum[l]-1] + m_comboModValMono * 32.f); + m_modValType[m_numberToReset] = 14; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 9:// Send input to Unison Detune { - unisonDetune[modOutSecNum[l]-1] = qMax( 0.f, unisonDetune[modOutSecNum[l]-1] + comboModValMono * 2000.f ); - modValType[numberToReset] = 15; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_unisonDetune[m_modOutSecNum[l]-1] = qMax(0.f, m_unisonDetune[m_modOutSecNum[l]-1] + m_comboModValMono * 2000.f); + m_modValType[m_numberToReset] = 15; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 10:// Send input to Unison Morph { - unisonMorph[modOutSecNum[l]-1] = qBound( 0.f, unisonMorph[modOutSecNum[l]-1] + comboModValMono*morphMax[modOutSecNum[l]-1], morphMax[modOutSecNum[l]-1] ); - modValType[numberToReset] = 16; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_unisonMorph[m_modOutSecNum[l]-1] = qBound(0.f, m_unisonMorph[m_modOutSecNum[l]-1] + + m_comboModValMono*m_morphMax[m_modOutSecNum[l]-1], m_morphMax[m_modOutSecNum[l]-1]); + m_modValType[m_numberToReset] = 16; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 11:// Send input to Unison Modify { - unisonModify[modOutSecNum[l]-1] = qMax( 0.f, unisonModify[modOutSecNum[l]-1] + comboModValMono * 2048.f ); - modValType[numberToReset] = 17; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_unisonModify[m_modOutSecNum[l]-1] = qMax(0.f, m_unisonModify[m_modOutSecNum[l]-1] + m_comboModValMono * 2048.f); + m_modValType[m_numberToReset] = 17; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } default: @@ -4251,7 +4270,7 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 2:// Sub Oscillator { - switch( modOutSig[l] ) + switch (m_modOutSig[l]) { case 0: { @@ -4259,66 +4278,66 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Send input to Pitch/Detune { - subDetune[modOutSecNum[l]-1] = subDetune[modOutSecNum[l]-1] + comboModValMono * 4800.f; - modValType[numberToReset] = 36; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subDetune[m_modOutSecNum[l]-1] = m_subDetune[m_modOutSecNum[l]-1] + m_comboModValMono * 4800.f; + m_modValType[m_numberToReset] = 36; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 2:// Send input to Phase { - subPhase[modOutSecNum[l]-1] = subPhase[modOutSecNum[l]-1] + comboModValMono * 8.f; - modValType[numberToReset] = 37; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subPhase[m_modOutSecNum[l]-1] = m_subPhase[m_modOutSecNum[l]-1] + m_comboModValMono * 8.f; + m_modValType[m_numberToReset] = 37; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 3:// Send input to Volume { - subVol[modOutSecNum[l]-1] = qMax( 0.f, subVol[modOutSecNum[l]-1] + comboModValMono * 100.f ); - modValType[numberToReset] = 34; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subVol[m_modOutSecNum[l]-1] = qMax(0.f, m_subVol[m_modOutSecNum[l]-1] + m_comboModValMono * 100.f); + m_modValType[m_numberToReset] = 34; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 4:// Send input to Panning { - subPanning[modOutSecNum[l]-1] = qMax( 0.f, subPanning[modOutSecNum[l]-1] + comboModValMono * 200.f ); - modValType[numberToReset] = 35; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subPanning[m_modOutSecNum[l]-1] = qMax(0.f, m_subPanning[m_modOutSecNum[l]-1] + m_comboModValMono * 200.f); + m_modValType[m_numberToReset] = 35; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 5:// Send input to Sample Length { - subSampLen[modOutSecNum[l]-1] = qMax( 1, int( subSampLen[modOutSecNum[l]-1] + comboModValMono * STOREDSUBWAVELEN ) ); - modValType[numberToReset] = 39; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subSampLen[m_modOutSecNum[l]-1] = qMax(1, int(m_subSampLen[m_modOutSecNum[l]-1] + m_comboModValMono * STOREDSUBWAVELEN)); + m_modValType[m_numberToReset] = 39; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 6:// Send input to Rate Limit { - subRateLimit[modOutSecNum[l]-1] = qMax( 0.f, subRateLimit[modOutSecNum[l]-1] + comboModValMono * 2.f ); - modValType[numberToReset] = 41; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subRateLimit[m_modOutSecNum[l]-1] = qMax(0.f, m_subRateLimit[m_modOutSecNum[l]-1] + m_comboModValMono * 2.f); + m_modValType[m_numberToReset] = 41; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 7:// Send input to Unison Voice Number { - subUnisonNum[modOutSecNum[l]-1] = qMax( 1.f, subUnisonNum[modOutSecNum[l]-1] + comboModValMono * 32.f ); - modValType[numberToReset] = 42; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subUnisonNum[m_modOutSecNum[l]-1] = qMax(1.f, m_subUnisonNum[m_modOutSecNum[l]-1] + m_comboModValMono * 32.f); + m_modValType[m_numberToReset] = 42; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 8:// Send input to Unison Detune { - subUnisonDetune[modOutSecNum[l]-1] = qMax( 0.f, subUnisonDetune[modOutSecNum[l]-1] + comboModValMono * 2000.f ); - modValType[numberToReset] = 43; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_subUnisonDetune[m_modOutSecNum[l]-1] = qMax(0.f, m_subUnisonDetune[m_modOutSecNum[l]-1] + m_comboModValMono * 2000.f); + m_modValType[m_numberToReset] = 43; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } default: @@ -4329,7 +4348,7 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 3:// Sample Oscillator { - switch( modOutSig[l] ) + switch (m_modOutSig[l]) { case 0: { @@ -4337,34 +4356,34 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Send input to Pitch/Detune { - sampleDetune[modOutSecNum[l]-1] = sampleDetune[modOutSecNum[l]-1] + comboModValMono * 4800.f; - modValType[numberToReset] = 67; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_sampleDetune[m_modOutSecNum[l]-1] = m_sampleDetune[m_modOutSecNum[l]-1] + m_comboModValMono * 4800.f; + m_modValType[m_numberToReset] = 67; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 2:// Send input to Phase { - samplePhase[modOutSecNum[l]-1] = samplePhase[modOutSecNum[l]-1] + comboModValMono * 8.f; - modValType[numberToReset] = 68; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_samplePhase[m_modOutSecNum[l]-1] = m_samplePhase[m_modOutSecNum[l]-1] + m_comboModValMono * 8.f; + m_modValType[m_numberToReset] = 68; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 3:// Send input to Volume { - sampleVolume[modOutSecNum[l]-1] = qMax( 0.f, sampleVolume[modOutSecNum[l]-1] + comboModValMono * 100.f ); - modValType[numberToReset] = 65; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_sampleVolume[m_modOutSecNum[l]-1] = qMax(0.f, m_sampleVolume[m_modOutSecNum[l]-1] + m_comboModValMono * 100.f); + m_modValType[m_numberToReset] = 65; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 4:// Send input to Panning { - samplePanning[modOutSecNum[l]-1] = qBound( -100.f, samplePanning[modOutSecNum[l]-1] + comboModValMono * 100.f, 100.f ); - modValType[numberToReset] = 66; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_samplePanning[m_modOutSecNum[l]-1] = qBound(-100.f, m_samplePanning[m_modOutSecNum[l]-1] + m_comboModValMono * 100.f, 100.f); + m_modValType[m_numberToReset] = 66; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } default: @@ -4375,7 +4394,7 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 4:// Matrix { - switch( modOutSig[l] ) + switch (m_modOutSig[l]) { case 0: { @@ -4383,90 +4402,90 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Mod In Amount { - modInAmnt[modOutSecNum[l]-1] = modInAmnt[modOutSecNum[l]-1] + comboModValMono*100.f; - modValType[numberToReset] = 92; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modInAmnt[m_modOutSecNum[l]-1] = m_modInAmnt[m_modOutSecNum[l]-1] + m_comboModValMono*100.f; + m_modValType[m_numberToReset] = 92; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 2:// Mod In Curve { - modInCurve[modOutSecNum[l]-1] = qMax( 0.f, modInCurve[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 93; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modInCurve[m_modOutSecNum[l]-1] = qMax(0.f, m_modInCurve[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 93; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 3:// Secondary Mod In Amount { - modInAmnt2[modOutSecNum[l]-1] = modInAmnt2[modOutSecNum[l]-1] + comboModValMono*100.f; - modValType[numberToReset] = 95; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modInAmnt2[m_modOutSecNum[l]-1] = m_modInAmnt2[m_modOutSecNum[l]-1] + m_comboModValMono*100.f; + m_modValType[m_numberToReset] = 95; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 4:// Secondary Mod In Curve { - modInCurve2[modOutSecNum[l]-1] = qMax( 0.f, modInCurve2[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 96; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modInCurve2[m_modOutSecNum[l]-1] = qMax(0.f, m_modInCurve2[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 96; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 5:// Mod In { - modIn[modOutSecNum[l]-1] = qMax( 0.f, modIn[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 90; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modIn[m_modOutSecNum[l]-1] = qMax(0.f, m_modIn[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 90; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 6:// Mod In Num { - modInNum[modOutSecNum[l]-1] = qMax( 0.f, modInNum[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 91; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modInNum[m_modOutSecNum[l]-1] = qMax(0.f, m_modInNum[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 91; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 7:// Secondary Mod In { - modIn2[modOutSecNum[l]-1] = qMax( 0.f, modIn2[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 94; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modIn2[m_modOutSecNum[l]-1] = qMax(0.f, m_modIn2[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 94; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 8:// Secondary Mod In Num { - modInNum2[modOutSecNum[l]-1] = qMax( 0.f, modInNum2[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 95; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modInNum2[m_modOutSecNum[l]-1] = qMax(0.f, m_modInNum2[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 95; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 9:// Mod Out Sec { - modOutSec[modOutSecNum[l]-1] = qMax( 0.f, modOutSec[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 98; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modOutSec[m_modOutSecNum[l]-1] = qMax(0.f, m_modOutSec[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 98; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 10:// Mod Out Sig { - modOutSig[modOutSecNum[l]-1] = qMax( 0.f, modOutSig[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 99; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modOutSig[m_modOutSecNum[l]-1] = qMax(0.f, m_modOutSig[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 99; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 11:// Mod Out Sec Num { - modOutSecNum[modOutSecNum[l]-1] = qMax( 0.f, modOutSecNum[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 100; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_modOutSecNum[m_modOutSecNum[l]-1] = qMax(0.f, m_modOutSecNum[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 100; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } } @@ -4474,13 +4493,13 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 5:// Filter Input { - filtInputs[modOutSig[l]][0] += curModVal[0]; - filtInputs[modOutSig[l]][1] += curModVal[1]; + m_filtInputs[m_modOutSig[l]][0] += m_curModVal[0]; + m_filtInputs[m_modOutSig[l]][1] += m_curModVal[1]; break; } case 6:// Filter Parameters { - switch( modOutSig[l] ) + switch (m_modOutSig[l]) { case 0:// None { @@ -4488,98 +4507,98 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Cutoff Frequency { - filtCutoff[modOutSecNum[l]-1] = qBound( 20.f, filtCutoff[modOutSecNum[l]-1] + comboModValMono*19980.f, 21999.f ); - modValType[numberToReset] = 120; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtCutoff[m_modOutSecNum[l]-1] = qBound(20.f, m_filtCutoff[m_modOutSecNum[l]-1] + m_comboModValMono*19980.f, 21999.f); + m_modValType[m_numberToReset] = 120; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 2:// Resonance { - filtReso[modOutSecNum[l]-1] = qMax( 0.0001f, filtReso[modOutSecNum[l]-1] + comboModValMono*16.f ); - modValType[numberToReset] = 121; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtReso[m_modOutSecNum[l]-1] = qMax(0.0001f, m_filtReso[m_modOutSecNum[l]-1] + m_comboModValMono*16.f); + m_modValType[m_numberToReset] = 121; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 3:// dbGain { - filtGain[modOutSecNum[l]-1] = filtGain[modOutSecNum[l]-1] + comboModValMono*64.f; - modValType[numberToReset] = 122; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtGain[m_modOutSecNum[l]-1] = m_filtGain[m_modOutSecNum[l]-1] + m_comboModValMono*64.f; + m_modValType[m_numberToReset] = 122; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 4:// Filter Type { - filtType[modOutSecNum[l]-1] = qMax( 0, int(filtType[modOutSecNum[l]-1] + comboModValMono*7.f ) ); - modValType[numberToReset] = 123; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtType[m_modOutSecNum[l]-1] = qMax(0, int(m_filtType[m_modOutSecNum[l]-1] + m_comboModValMono*7.f)); + m_modValType[m_numberToReset] = 123; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 5:// Filter Slope { - filtSlope[modOutSecNum[l]-1] = qMax( 0, int(filtSlope[modOutSecNum[l]-1] + comboModValMono*8.f ) ); - modValType[numberToReset] = 124; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtSlope[m_modOutSecNum[l]-1] = qMax(0, int(m_filtSlope[m_modOutSecNum[l]-1] + m_comboModValMono*8.f)); + m_modValType[m_numberToReset] = 124; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 6:// Input Volume { - filtInVol[modOutSecNum[l]-1] = qMax( 0.f, filtInVol[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 125; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtInVol[m_modOutSecNum[l]-1] = qMax(0.f, m_filtInVol[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 125; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 7:// Output Volume { - filtOutVol[modOutSecNum[l]-1] = qMax( 0.f, filtOutVol[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 126; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtOutVol[m_modOutSecNum[l]-1] = qMax(0.f, m_filtOutVol[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 126; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 8:// Wet/Dry { - filtWetDry[modOutSecNum[l]-1] = qBound( 0.f, filtWetDry[modOutSecNum[l]-1] + comboModValMono*100.f, 100.f ); - modValType[numberToReset] = 127; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtWetDry[m_modOutSecNum[l]-1] = qBound(0.f, m_filtWetDry[m_modOutSecNum[l]-1] + m_comboModValMono*100.f, 100.f); + m_modValType[m_numberToReset] = 127; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 9:// Balance/Panning { - filtBal[modOutSecNum[l]-1] = qBound( -100.f, filtBal[modOutSecNum[l]-1] + comboModValMono*200.f, 100.f ); - modValType[numberToReset] = 128; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtBal[m_modOutSecNum[l]-1] = qBound(-100.f, m_filtBal[m_modOutSecNum[l]-1] + m_comboModValMono*200.f, 100.f); + m_modValType[m_numberToReset] = 128; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 10:// Saturation { - filtSatu[modOutSecNum[l]-1] = qMax( 0.f, filtSatu[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 129; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtSatu[m_modOutSecNum[l]-1] = qMax(0.f, m_filtSatu[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 129; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 11:// Feedback { - filtFeedback[modOutSecNum[l]-1] = qMax( 0.f, filtFeedback[modOutSecNum[l]-1] + comboModValMono*100.f ); - modValType[numberToReset] = 130; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtFeedback[m_modOutSecNum[l]-1] = qMax(0.f, m_filtFeedback[m_modOutSecNum[l]-1] + m_comboModValMono*100.f); + m_modValType[m_numberToReset] = 130; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } case 12:// Detune { - filtDetune[modOutSecNum[l]-1] = filtDetune[modOutSecNum[l]-1] + comboModValMono*4800.f; - modValType[numberToReset] = 131; - modValNum[numberToReset] = modOutSecNum[l]-1; - ++numberToReset; + m_filtDetune[m_modOutSecNum[l]-1] = m_filtDetune[m_modOutSecNum[l]-1] + m_comboModValMono*4800.f; + m_modValType[m_numberToReset] = 131; + m_modValNum[m_numberToReset] = m_modOutSecNum[l]-1; + ++m_numberToReset; break; } } @@ -4587,10 +4606,10 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 7:// Macro { - macro[modOutSig[l]] = macro[modOutSig[l]] + comboModValMono * 200.f; - modValType[numberToReset] = 150; - modValNum[numberToReset] = modOutSig[l]; - ++numberToReset; + m_macro[m_modOutSig[l]] = m_macro[m_modOutSig[l]] + m_comboModValMono * 200.f; + m_modValType[m_numberToReset] = 150; + m_modValNum[m_numberToReset] = m_modOutSig[l]; + ++m_numberToReset; break; } default: @@ -4606,168 +4625,169 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ // As much as it may seem like it, this section contains no intentional attempts at obfuscation. - for( int l = 0; l < maxFiltEnabled; ++l ) + for (int l = 0; l < m_maxFiltEnabled; ++l) { - if( filtEnabled[l] ) + if (m_filtEnabled[l]) { - temp1 = filtInVol[l] * 0.01f; - filtInputs[l][0] *= temp1; - filtInputs[l][1] *= temp1; + m_temp1 = m_filtInVol[l] * 0.01f; + m_filtInputs[l][0] *= m_temp1; + m_filtInputs[l][1] *= m_temp1; - if( filtKeytracking[l] ) + if (m_filtKeytracking[l]) { - temp1 = round( sample_rate / detuneWithCents( nph->frequency(), filtDetune[l] ) ); + m_temp1 = round(sample_rate / detuneWithCents(m_nph->frequency(), m_filtDetune[l])); } else { - temp1 = round( sample_rate / detuneWithCents( 440.f, filtDetune[l] ) ); + m_temp1 = round(sample_rate / detuneWithCents(440.f, m_filtDetune[l])); } - if( filtDelayBuf[l][0].size() < temp1 ) + if (m_filtDelayBuf[l][0].size() < m_temp1) { - filtDelayBuf[l][0].resize( temp1 ); - filtDelayBuf[l][1].resize( temp1 ); + m_filtDelayBuf[l][0].resize(m_temp1); + m_filtDelayBuf[l][1].resize(m_temp1); } - ++filtFeedbackLoc[l]; - if( filtFeedbackLoc[l] > temp1 - 1 ) + ++m_filtFeedbackLoc[l]; + if (m_filtFeedbackLoc[l] > m_temp1 - 1) { - filtFeedbackLoc[l] = 0; + m_filtFeedbackLoc[l] = 0; } - filtInputs[l][0] += filtDelayBuf[l][0].at( filtFeedbackLoc[l] ); - filtInputs[l][1] += filtDelayBuf[l][1].at( filtFeedbackLoc[l] ); + m_filtInputs[l][0] += m_filtDelayBuf[l][0].at(m_filtFeedbackLoc[l]); + m_filtInputs[l][1] += m_filtDelayBuf[l][1].at(m_filtFeedbackLoc[l]); - cutoff = filtCutoff[l]; - mode = filtType[l]; - reso = filtReso[l]; - dbgain = filtGain[l]; - Fs = sample_rate; - w0 = D_2PI * cutoff / Fs; + m_cutoff = m_filtCutoff[l]; + m_mode = m_filtType[l]; + m_reso = m_filtReso[l]; + m_dbgain = m_filtGain[l]; + m_Fs = sample_rate; + m_w0 = D_2PI * m_cutoff / m_Fs; - if( mode == 8 ) + if (m_mode == 8) { - f = 2 * cutoff / Fs; - k = 3.6*f - 1.6*f*f - 1; - p = (k+1)*0.5f; - scale = pow( D_E, (1-p)*1.386249f ); - r = reso*scale; + m_f = 2 * m_cutoff / m_Fs; + m_k = 3.6*m_f - 1.6*m_f*m_f - 1; + m_p = (m_k+1)*0.5f; + m_scale = pow(D_E, (1-m_p)*1.386249f); + m_r = m_reso*m_scale; } - for( int m = 0; m < filtSlope[l] + 1; ++m )// m is the slope number. So if m = 2, then the sound is going from a 24 db to a 36 db slope, for example. + // m is the slope number. So if m = 2, then the sound is going from a 24 db to a 36 db slope, for example. + for (int m = 0; m < m_filtSlope[l] + 1; ++m) { - if( m ) + if (m) { - filtInputs[l][0] = filtOutputs[l][0]; - filtInputs[l][1] = filtOutputs[l][1]; + m_filtInputs[l][0] = m_filtOutputs[l][0]; + m_filtInputs[l][1] = m_filtOutputs[l][1]; } int formulaType = 1; - if( mode <= 7 ) + if (m_mode <= 7) { - switch( mode ) + switch (m_mode) { case 0:// LP { - temp1 = cos(w0); - alpha = sin(w0) / (2*reso); - b0 = ( 1 - temp1 ) * 0.5f; - b1 = 1 - temp1; - b2 = b0; - a0 = 1 + alpha; - a1 = -2 * temp1; - a2 = 1 - alpha; + m_temp1 = cos(m_w0); + m_alpha = sin(m_w0) / (2*m_reso); + m_b0 = (1 - m_temp1) * 0.5f; + m_b1 = 1 - m_temp1; + m_b2 = m_b0; + m_a0 = 1 + m_alpha; + m_a1 = -2 * m_temp1; + m_a2 = 1 - m_alpha; break; } case 1:// HP { - temp1 = cos(w0); - alpha = sin(w0) / (2*reso); - b0 = (1 + temp1) * 0.5f; - b1 = -(1 + temp1); - b2 = b0; - a0 = 1 + alpha; - a1 = -2 * temp1; - a2 = 1 - alpha; + m_temp1 = cos(m_w0); + m_alpha = sin(m_w0) / (2*m_reso); + m_b0 = (1 + m_temp1) * 0.5f; + m_b1 = -(1 + m_temp1); + m_b2 = m_b0; + m_a0 = 1 + m_alpha; + m_a1 = -2 * m_temp1; + m_a2 = 1 - m_alpha; break; } case 2:// BP { - temp2 = sin(w0); - alpha = temp2*sinh( log(2) * 0.5 * reso * w0/temp2 ); - b0 = alpha; - b1 = 0; - b2 = -alpha; - a0 = 1 + alpha; - a1 = -2*cos(w0); - a2 = 1 - alpha; + m_temp2 = sin(m_w0); + m_alpha = m_temp2*sinh(log(2) * 0.5 * m_reso * m_w0/m_temp2); + m_b0 = m_alpha; + m_b1 = 0; + m_b2 = -m_alpha; + m_a0 = 1 + m_alpha; + m_a1 = -2*cos(m_w0); + m_a2 = 1 - m_alpha; formulaType = 2; break; } case 3:// Low Shelf { - temp1 = cos(w0); - A = exp10( dbgain / 40 ); - alpha = sin(w0)/2 * sqrt( (A + 1/A)*(1/reso - 1) + 2 ); - temp2 = 2*sqrt(A)*alpha; - b0 = A*( (A+1) - (A-1)*temp1 + temp2 ); - b1 = 2*A*( (A-1) - (A+1)*temp1 ); - b2 = A*( (A+1) - (A-1)*temp1 - temp2 ); - a0 = (A+1) + (A-1)*temp1 + temp2; - a1 = -2*( (A-1) + (A+1)*temp1 ); - a2 = (A+1) + (A-1)*temp1 - temp2; + m_temp1 = cos(m_w0); + m_A = exp10(m_dbgain / 40); + m_alpha = sin(m_w0)/2 * sqrt((m_A + 1/m_A)*(1/m_reso - 1) + 2); + m_temp2 = 2*sqrt(m_A)*m_alpha; + m_b0 = m_A*((m_A+1) - (m_A-1)*m_temp1 + m_temp2); + m_b1 = 2*m_A*((m_A-1) - (m_A+1)*m_temp1 ); + m_b2 = m_A*((m_A+1) - (m_A-1)*m_temp1 - m_temp2); + m_a0 = (m_A+1) + (m_A-1)*m_temp1 + m_temp2; + m_a1 = -2*((m_A-1) + (m_A+1)*m_temp1 ); + m_a2 = (m_A+1) + (m_A-1)*m_temp1 - m_temp2; break; } case 4:// High Shelf { - temp1 = cos(w0); - A = exp10( dbgain / 40 ); - alpha = sin(w0)/2 * sqrt( (A + 1/A)*(1/reso - 1) + 2 ); - temp2 = 2*sqrt(A)*alpha; - b0 = A*( (A+1) + (A-1)*temp1 + temp2 ); - b1 = -2*A*( (A-1) + (A+1)*temp1 ); - b2 = A*( (A+1) + (A-1)*temp1 - temp2 ); - a0 = (A+1) - (A-1)*temp1 + temp2; - a1 = 2*( (A-1) - (A+1)*temp1 ); - a2 = (A+1) - (A-1)*temp1 - temp2; + m_temp1 = cos(m_w0); + m_A = exp10(m_dbgain / 40); + m_alpha = sin(m_w0)/2 * sqrt((m_A + 1/m_A)*(1/m_reso - 1) + 2); + m_temp2 = 2*sqrt(m_A)*m_alpha; + m_b0 = m_A*((m_A+1) + (m_A-1)*m_temp1 + m_temp2); + m_b1 = -2*m_A*((m_A-1) + (m_A+1)*m_temp1 ); + m_b2 = m_A*((m_A+1) + (m_A-1)*m_temp1 - m_temp2); + m_a0 = (m_A+1) - (m_A-1)*m_temp1 + m_temp2; + m_a1 = 2*((m_A-1) - (m_A+1)*m_temp1 ); + m_a2 = (m_A+1) - (m_A-1)*m_temp1 - m_temp2; break; } case 5:// Peak { - temp1 = -2 * cos(w0); - temp2 = sin(w0); - alpha = temp2*sinh( log(2) * 0.5 * reso * w0/temp2 ); - A = exp10( dbgain / 40 ); - b0 = 1 + alpha*A; - b1 = temp1; - b2 = 1 - alpha*A; - a0 = 1 + alpha/A; - a1 = temp1; - a2 = 1 - alpha/A; + m_temp1 = -2 * cos(m_w0); + m_temp2 = sin(m_w0); + m_alpha = m_temp2*sinh(log(2) * 0.5 * m_reso * m_w0/m_temp2); + m_A = exp10(m_dbgain / 40); + m_b0 = 1 + m_alpha*m_A; + m_b1 = m_temp1; + m_b2 = 1 - m_alpha*m_A; + m_a0 = 1 + m_alpha/m_A; + m_a1 = m_temp1; + m_a2 = 1 - m_alpha/m_A; break; } case 6:// Notch { - temp1 = -2 * cos(w0); - temp2 = sin(w0); - alpha = temp2*sinh( log(2) * 0.5 * reso * w0/temp2 ); - b0 = 1; - b1 = temp1; - b2 = 1; - a0 = 1 + alpha; - a1 = temp1; - a2 = 1 - alpha; + m_temp1 = -2 * cos(m_w0); + m_temp2 = sin(m_w0); + m_alpha = m_temp2*sinh(log(2) * 0.5 * m_reso * m_w0/m_temp2); + m_b0 = 1; + m_b1 = m_temp1; + m_b2 = 1; + m_a0 = 1 + m_alpha; + m_a1 = m_temp1; + m_a2 = 1 - m_alpha; break; } case 7:// Allpass { - temp1 = -2 * cos(w0); - alpha = sin(w0) / (2*reso); - b0 = 1 - alpha; - b1 = temp1; - b2 = 1 + alpha; - a0 = b2; - a1 = temp1; - a2 = b0; + m_temp1 = -2 * cos(m_w0); + m_alpha = sin(m_w0) / (2*m_reso); + m_b0 = 1 - m_alpha; + m_b1 = m_temp1; + m_b2 = 1 + m_alpha; + m_a0 = m_b2; + m_a1 = m_temp1; + m_a2 = m_b0; formulaType = 3; break; } @@ -4775,155 +4795,163 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ // Translation of this monstrosity (case 1): y[n] = (b0/a0)*x[n] + (b1/a0)*x[n-1] + (b2/a0)*x[n-2] - (a1/a0)*y[n-1] - (a2/a0)*y[n-2] // See www.musicdsp.org/files/Audio-EQ-Cookbook.txt - switch( formulaType ) + switch (formulaType) { case 1:// Normal { - temp1 = b0/a0; - temp2 = b1/a0; - temp3 = b2/a0; - temp4 = a1/a0; - temp5 = a2/a0; - filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp2*filtPrevSampIn[l][m][1][0] + temp3*filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear - filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp2*filtPrevSampIn[l][m][1][1] + temp3*filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + m_temp1 = m_b0/m_a0; + m_temp2 = m_b1/m_a0; + m_temp3 = m_b2/m_a0; + m_temp4 = m_a1/m_a0; + m_temp5 = m_a2/m_a0; + m_filtPrevSampOut[l][m][0][0] = m_temp1*m_filtInputs[l][0] + m_temp2*m_filtPrevSampIn[l][m][1][0] + + m_temp3*m_filtPrevSampIn[l][m][2][0] - m_temp4*m_filtPrevSampOut[l][m][1][0] - m_temp5*m_filtPrevSampOut[l][m][2][0];// Left ear + m_filtPrevSampOut[l][m][0][1] = m_temp1*m_filtInputs[l][1] + m_temp2*m_filtPrevSampIn[l][m][1][1] + + m_temp3*m_filtPrevSampIn[l][m][2][1] - m_temp4*m_filtPrevSampOut[l][m][1][1] - m_temp5*m_filtPrevSampOut[l][m][2][1];// Right ear break; } case 2:// Bandpass { - temp1 = b0/a0; - temp3 = b2/a0; - temp4 = a1/a0; - temp5 = a2/a0; - filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp3*filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear - filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp3*filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + m_temp1 = m_b0/m_a0; + m_temp3 = m_b2/m_a0; + m_temp4 = m_a1/m_a0; + m_temp5 = m_a2/m_a0; + m_filtPrevSampOut[l][m][0][0] = m_temp1*m_filtInputs[l][0] + m_temp3*m_filtPrevSampIn[l][m][2][0] - + m_temp4*m_filtPrevSampOut[l][m][1][0] - m_temp5*m_filtPrevSampOut[l][m][2][0];// Left ear + m_filtPrevSampOut[l][m][0][1] = m_temp1*m_filtInputs[l][1] + m_temp3*m_filtPrevSampIn[l][m][2][1] - + m_temp4*m_filtPrevSampOut[l][m][1][1] - m_temp5*m_filtPrevSampOut[l][m][2][1];// Right ear break; } case 3:// Allpass { - temp1 = b0/a0; - temp2 = b1/a0; - temp4 = a1/a0; - temp5 = a2/a0; - filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp2*filtPrevSampIn[l][m][1][0] + filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear - filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp2*filtPrevSampIn[l][m][1][1] + filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + m_temp1 = m_b0/m_a0; + m_temp2 = m_b1/m_a0; + m_temp4 = m_a1/m_a0; + m_temp5 = m_a2/m_a0; + m_filtPrevSampOut[l][m][0][0] = m_temp1*m_filtInputs[l][0] + m_temp2*m_filtPrevSampIn[l][m][1][0] + + m_filtPrevSampIn[l][m][2][0] - m_temp4*m_filtPrevSampOut[l][m][1][0] - m_temp5*m_filtPrevSampOut[l][m][2][0];// Left ear + m_filtPrevSampOut[l][m][0][1] = m_temp1*m_filtInputs[l][1] + m_temp2*m_filtPrevSampIn[l][m][1][1] + + m_filtPrevSampIn[l][m][2][1] - m_temp4*m_filtPrevSampOut[l][m][1][1] - m_temp5*m_filtPrevSampOut[l][m][2][1];// Right ear break; } case 4:// Notch { - temp1 = 1.f/a0; - temp2 = b1/a0; - temp3 = temp1; - temp4 = temp2; - temp5 = a2/a0; - filtPrevSampOut[l][m][0][0] = temp1*filtInputs[l][0] + temp2*filtPrevSampIn[l][m][1][0] + temp3*filtPrevSampIn[l][m][2][0] - temp4*filtPrevSampOut[l][m][1][0] - temp5*filtPrevSampOut[l][m][2][0];// Left ear - filtPrevSampOut[l][m][0][1] = temp1*filtInputs[l][1] + temp2*filtPrevSampIn[l][m][1][1] + temp3*filtPrevSampIn[l][m][2][1] - temp4*filtPrevSampOut[l][m][1][1] - temp5*filtPrevSampOut[l][m][2][1];// Right ear + m_temp1 = 1.f/m_a0; + m_temp2 = m_b1/m_a0; + m_temp3 = m_temp1; + m_temp4 = m_temp2; + m_temp5 = m_a2/m_a0; + m_filtPrevSampOut[l][m][0][0] = m_temp1*m_filtInputs[l][0] + m_temp2*m_filtPrevSampIn[l][m][1][0] + + m_temp3*m_filtPrevSampIn[l][m][2][0] - m_temp4*m_filtPrevSampOut[l][m][1][0] - m_temp5*m_filtPrevSampOut[l][m][2][0];// Left ear + m_filtPrevSampOut[l][m][0][1] = m_temp1*m_filtInputs[l][1] + m_temp2*m_filtPrevSampIn[l][m][1][1] + + m_temp3*m_filtPrevSampIn[l][m][2][1] - m_temp4*m_filtPrevSampOut[l][m][1][1] - m_temp5*m_filtPrevSampOut[l][m][2][1];// Right ear break; } } //Output results - temp1 = filtOutVol[l] * 0.01f; - filtOutputs[l][0] = filtPrevSampOut[l][m][0][0] * temp1; - filtOutputs[l][1] = filtPrevSampOut[l][m][0][1] * temp1; + m_temp1 = m_filtOutVol[l] * 0.01f; + m_filtOutputs[l][0] = m_filtPrevSampOut[l][m][0][0] * m_temp1; + m_filtOutputs[l][1] = m_filtPrevSampOut[l][m][0][1] * m_temp1; } - else if( mode == 8 ) + else if (m_mode == 8) { // Moog 24db Lowpass - filtx[0] = filtInputs[l][0]-r*filty4[0]; - filtx[1] = filtInputs[l][1]-r*filty4[1]; - for( int i = 0; i < 2; ++i ) + m_filtx[0] = m_filtInputs[l][0]-m_r*m_filty4[0]; + m_filtx[1] = m_filtInputs[l][1]-m_r*m_filty4[1]; + for (int i = 0; i < 2; ++i) { - filty1[i]=filtx[i]*p + filtoldx[i]*p - k*filty1[i]; - filty2[i]=filty1[i]*p+filtoldy1[i]*p - k*filty2[i]; - filty3[i]=filty2[i]*p+filtoldy2[i]*p - k*filty3[i]; - filty4[i]=filty3[i]*p+filtoldy3[i]*p - k*filty4[i]; - filty4[i] = filty4[i] - filty4[i] * filty4[i] * filty4[i] / 6.f; - filtoldx[i] = filtx[i]; - filtoldy1[i] = filty1[i]; - filtoldy2[i] = filty2[i]; - filtoldy3[i] = filty3[i]; + m_filty1[i]=m_filtx[i]*m_p + m_filtoldx[i]*m_p - m_k*m_filty1[i]; + m_filty2[i]=m_filty1[i]*m_p+m_filtoldy1[i]*m_p - m_k*m_filty2[i]; + m_filty3[i]=m_filty2[i]*m_p+m_filtoldy2[i]*m_p - m_k*m_filty3[i]; + m_filty4[i]=m_filty3[i]*m_p+m_filtoldy3[i]*m_p - m_k*m_filty4[i]; + m_filty4[i] = m_filty4[i] - m_filty4[i] * m_filty4[i] * m_filty4[i] / 6.f; + m_filtoldx[i] = m_filtx[i]; + m_filtoldy1[i] = m_filty1[i]; + m_filtoldy2[i] = m_filty2[i]; + m_filtoldy3[i] = m_filty3[i]; } - temp1 = filtOutVol[l] * 0.01f; - filtOutputs[l][0] = filty4[0] * temp1; - filtOutputs[l][1] = filty4[1] * temp1; + m_temp1 = m_filtOutVol[l] * 0.01f; + m_filtOutputs[l][0] = m_filty4[0] * m_temp1; + m_filtOutputs[l][1] = m_filty4[1] * m_temp1; } - // Calculates Saturation. The algorithm is just y = x ^ ( 1 - saturation ); - if( filtSatu[l] ) + // Calculates Saturation. The algorithm is just y = x ^ (1 - saturation); + if (m_filtSatu[l]) { - temp1 = 1 - ( filtSatu[l] * 0.01f ); - filtOutputs[l][0] = pow( abs( filtOutputs[l][0] ), temp1 ) * ( filtOutputs[l][0] < 0 ? -1 : 1 ); - filtOutputs[l][1] = pow( abs( filtOutputs[l][1] ), temp1 ) * ( filtOutputs[l][1] < 0 ? -1 : 1 ); + m_temp1 = 1 - (m_filtSatu[l] * 0.01f); + m_filtOutputs[l][0] = pow(abs(m_filtOutputs[l][0]), m_temp1) * (m_filtOutputs[l][0] < 0 ? -1 : 1); + m_filtOutputs[l][1] = pow(abs(m_filtOutputs[l][1]), m_temp1) * (m_filtOutputs[l][1] < 0 ? -1 : 1); } // Balance knob wet - if( filtBal[l] ) + if (m_filtBal[l]) { - filtOutputs[l][0] *= filtBal[l] > 0 ? ( 100.f - filtBal[l] ) * 0.01f : 1.f; - filtOutputs[l][1] *= filtBal[l] < 0 ? ( 100.f + filtBal[l] ) * 0.01f : 1.f; + m_filtOutputs[l][0] *= m_filtBal[l] > 0 ? (100.f - m_filtBal[l]) * 0.01f : 1.f; + m_filtOutputs[l][1] *= m_filtBal[l] < 0 ? (100.f + m_filtBal[l]) * 0.01f : 1.f; } // Wet - if( filtWetDry[l] != 100 ) + if (m_filtWetDry[l] != 100) { - temp1 = filtWetDry[l] * 0.01f; - filtOutputs[l][0] *= temp1; - filtOutputs[l][1] *= temp1; + m_temp1 = m_filtWetDry[l] * 0.01f; + m_filtOutputs[l][0] *= m_temp1; + m_filtOutputs[l][1] *= m_temp1; } // Balance knob dry - if( filtBal[l] ) + if (m_filtBal[l]) { - filtOutputs[l][0] += ( 1.f - ( filtBal[l] > 0 ? ( 100.f - filtBal[l] ) * 0.01f : 1.f ) ) * filtInputs[l][0]; - filtOutputs[l][1] += ( 1.f - ( filtBal[l] < 0 ? ( 100.f + filtBal[l] ) * 0.01f : 1.f ) ) * filtInputs[l][1]; + m_filtOutputs[l][0] += (1.f - (m_filtBal[l] > 0 ? (100.f - m_filtBal[l]) * 0.01f : 1.f)) * m_filtInputs[l][0]; + m_filtOutputs[l][1] += (1.f - (m_filtBal[l] < 0 ? (100.f + m_filtBal[l]) * 0.01f : 1.f)) * m_filtInputs[l][1]; } // Dry - temp1 = 1.f - ( filtWetDry[l] * 0.01f ); - filtOutputs[l][0] += temp1 * filtInputs[l][0]; - filtOutputs[l][1] += temp1 * filtInputs[l][1]; + m_temp1 = 1.f - (m_filtWetDry[l] * 0.01f); + m_filtOutputs[l][0] += m_temp1 * m_filtInputs[l][0]; + m_filtOutputs[l][1] += m_temp1 * m_filtInputs[l][1]; // Send back past samples - filtPrevSampIn[l][m][4][0] = filtPrevSampIn[l][m][3][0]; - filtPrevSampIn[l][m][4][1] = filtPrevSampIn[l][m][3][1]; + m_filtPrevSampIn[l][m][4][0] = m_filtPrevSampIn[l][m][3][0]; + m_filtPrevSampIn[l][m][4][1] = m_filtPrevSampIn[l][m][3][1]; - filtPrevSampIn[l][m][3][0] = filtPrevSampIn[l][m][2][0]; - filtPrevSampIn[l][m][3][1] = filtPrevSampIn[l][m][2][1]; + m_filtPrevSampIn[l][m][3][0] = m_filtPrevSampIn[l][m][2][0]; + m_filtPrevSampIn[l][m][3][1] = m_filtPrevSampIn[l][m][2][1]; - filtPrevSampIn[l][m][2][0] = filtPrevSampIn[l][m][1][0]; - filtPrevSampIn[l][m][2][1] = filtPrevSampIn[l][m][1][1]; + m_filtPrevSampIn[l][m][2][0] = m_filtPrevSampIn[l][m][1][0]; + m_filtPrevSampIn[l][m][2][1] = m_filtPrevSampIn[l][m][1][1]; - filtPrevSampIn[l][m][1][0] = filtInputs[l][0]; - filtPrevSampIn[l][m][1][1] = filtInputs[l][1]; + m_filtPrevSampIn[l][m][1][0] = m_filtInputs[l][0]; + m_filtPrevSampIn[l][m][1][1] = m_filtInputs[l][1]; - filtPrevSampOut[l][m][4][0] = filtPrevSampOut[l][m][3][0]; - filtPrevSampOut[l][m][4][1] = filtPrevSampOut[l][m][3][1]; + m_filtPrevSampOut[l][m][4][0] = m_filtPrevSampOut[l][m][3][0]; + m_filtPrevSampOut[l][m][4][1] = m_filtPrevSampOut[l][m][3][1]; - filtPrevSampOut[l][m][3][0] = filtPrevSampOut[l][m][2][0]; - filtPrevSampOut[l][m][3][1] = filtPrevSampOut[l][m][2][1]; + m_filtPrevSampOut[l][m][3][0] = m_filtPrevSampOut[l][m][2][0]; + m_filtPrevSampOut[l][m][3][1] = m_filtPrevSampOut[l][m][2][1]; - filtPrevSampOut[l][m][2][0] = filtPrevSampOut[l][m][1][0]; - filtPrevSampOut[l][m][2][1] = filtPrevSampOut[l][m][1][1]; + m_filtPrevSampOut[l][m][2][0] = m_filtPrevSampOut[l][m][1][0]; + m_filtPrevSampOut[l][m][2][1] = m_filtPrevSampOut[l][m][1][1]; - filtPrevSampOut[l][m][1][0] = filtPrevSampOut[l][m][0][0]; - filtPrevSampOut[l][m][1][1] = filtPrevSampOut[l][m][0][1]; + m_filtPrevSampOut[l][m][1][0] = m_filtPrevSampOut[l][m][0][0]; + m_filtPrevSampOut[l][m][1][1] = m_filtPrevSampOut[l][m][0][1]; } - temp1 = filtFeedback[l] * 0.01f; - filtDelayBuf[l][0][filtFeedbackLoc[l]] = filtOutputs[l][0] * temp1; - filtDelayBuf[l][1][filtFeedbackLoc[l]] = filtOutputs[l][1] * temp1; + m_temp1 = m_filtFeedback[l] * 0.01f; + m_filtDelayBuf[l][0][m_filtFeedbackLoc[l]] = m_filtOutputs[l][0] * m_temp1; + m_filtDelayBuf[l][1][m_filtFeedbackLoc[l]] = m_filtOutputs[l][1] * m_temp1; - filtInputs[l][0] = 0; - filtInputs[l][1] = 0; + m_filtInputs[l][0] = 0; + m_filtInputs[l][1] = 0; - filtModOutputs[l][0] = filtOutputs[l][0]; - filtModOutputs[l][1] = filtOutputs[l][1]; + m_filtModOutputs[l][0] = m_filtOutputs[l][0]; + m_filtModOutputs[l][1] = m_filtOutputs[l][1]; - if( filtMuted[l] ) + if (m_filtMuted[l]) { - filtOutputs[l][0] = 0; - filtOutputs[l][1] = 0; + m_filtOutputs[l][0] = 0; + m_filtOutputs[l][1] = 0; } } } @@ -4932,48 +4960,58 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ //== MAIN OSCILLATOR ==// //=====================// - for( int i = 0; i < maxMainEnabled; ++i )// maxMainEnabled keeps this from looping 8 times every sample, saving some CPU + for (int i = 0; i < m_maxMainEnabled; ++i)// m_maxMainEnabled keeps this from looping 8 times every m_sample, saving some CPU { - if( enabled[i] ) + if (m_enabled[i]) { - currentSampLen = sampLen[i] * WAVERATIO; - for( int l = 0; l < unisonVoices[i]; ++l ) + m_currentSampLen = m_sampLen[i] * WAVERATIO; + for (int l = 0; l < m_unisonVoices[i]; ++l) { - sample_morerealindex[i][l] = realfmod( ( sample_realindex[i][l] + ( phase[i] * currentSampLen * 0.01f ) ), currentSampLen );// Calculates phase + m_sample_morerealindex[i][l] = realfmod((m_sample_realindex[i][l] + + (m_phase[i] * m_currentSampLen * 0.01f)), m_currentSampLen);// Calculates phase - unisonVoicesMinusOne = unisonVoices[i] - 1;// unisonVoices[i] - 1 is needed many times, which is why unisonVoicesMinusOne exists + m_unisonVoicesMinusOne = m_unisonVoices[i] - 1;// m_unisonVoices[i] - 1 is needed many times, which is why m_unisonVoicesMinusOne exists - if( tempo[i] ) + if (m_tempo[i]) { - temp1 = tempo[i] / 26400.f; - noteFreq = unisonVoicesMinusOne ? detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, unisonDetuneAmounts[i][l]*unisonDetune[i]+detune[i] ) : detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, detune[i] );// Calculates frequency depending on detune and unison detune - noteFreq *= temp1;// Tempo sync + m_temp1 = m_tempo[i] / 26400.f; + + // Calculates frequency depending on m_detune and unison detune + m_noteFreq = m_unisonVoicesMinusOne ? detuneWithCents(m_keytracking[i] ? + m_nph->frequency() : 440.f, m_unisonDetuneAmounts[i][l]*m_unisonDetune[i]+m_detune[i]) : + detuneWithCents(m_keytracking[i] ? m_nph->frequency() : 440.f, m_detune[i]); + + m_noteFreq *= m_temp1;// Tempo sync } else { - noteFreq = unisonVoicesMinusOne ? detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, unisonDetuneAmounts[i][l]*unisonDetune[i]+detune[i] ) : detuneWithCents( keytracking[i] ? nph->frequency() : 440.f, detune[i] );// Calculates frequency depending on detune and unison detune + // Calculates frequency depending on m_detune and unison detune + m_noteFreq = m_unisonVoicesMinusOne ? detuneWithCents(m_keytracking[i] ? + m_nph->frequency() : 440.f, m_unisonDetuneAmounts[i][l]*m_unisonDetune[i]+m_detune[i]) : + detuneWithCents(m_keytracking[i] ? m_nph->frequency() : 440.f, m_detune[i]); } - sample_step[i][l] = currentSampLen * ( noteFreq / sample_rate ); + m_sample_step[i][l] = m_currentSampLen * (m_noteFreq / sample_rate); - if( unisonVoicesMinusOne )// Figures out Morph and Modify values for individual unison voices + if (m_unisonVoicesMinusOne)// Figures out Morph and Modify values for individual unison voices { - if( unisonMorph[i] ) + if (m_unisonMorph[i]) { - temp1 = ((unisonVoicesMinusOne-l)/unisonVoicesMinusOne)*unisonMorph[i]; - morph[i] = qBound( 0.f, temp1 - ( unisonMorph[i] * 0.5f ) + morph[i], morphMax[i] ); + m_temp1 = ((m_unisonVoicesMinusOne-l)/m_unisonVoicesMinusOne)*m_unisonMorph[i]; + m_morph[i] = qBound(0.f, m_temp1 - (m_unisonMorph[i] * 0.5f) + m_morph[i], m_morphMax[i]); } - if( unisonModify[i] ) + if (m_unisonModify[i]) { - temp1 = ((unisonVoicesMinusOne-l)/unisonVoicesMinusOne)*unisonModify[i]; - modify[i] = qBound( 0.f, temp1 - ( unisonModify[i] * 0.5f ) + modify[i], currentSampLen-1.f);// SampleLength - 1 = ModifyMax + m_temp1 = ((m_unisonVoicesMinusOne-l)/m_unisonVoicesMinusOne)*m_unisonModify[i]; + m_modify[i] = qBound(0.f, m_temp1 - (m_unisonModify[i] * 0.5f) + + m_modify[i], m_currentSampLen-1.f);// SampleLength - 1 = ModifyMax } } - temp7 = modify[i] * WAVERATIO; + m_temp7 = m_modify[i] * WAVERATIO; - switch( modifyMode[i] )// Horrifying formulas for the various Modify Modes + switch (m_modifyMode[i])// Horrifying formulas for the various Modify Modes { case 0:// None { @@ -4981,136 +5019,150 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } case 1:// Pulse Width { - sample_morerealindex[i][l] /= ( -temp7 + currentSampLen ) / currentSampLen; + m_sample_morerealindex[i][l] /= (-m_temp7 + m_currentSampLen) / m_currentSampLen; - sample_morerealindex[i][l] = qBound( 0.f, sample_morerealindex[i][l], (float)currentSampLen - 1);// Keeps sample index within bounds + m_sample_morerealindex[i][l] = qBound(0.f, m_sample_morerealindex[i][l], + (float)m_currentSampLen - 1);// Keeps m_sample index within bounds break; } case 2:// Weird 1 { //The cool result of me messing up. - sample_morerealindex[i][l] = ( ( ( sin( ( ( sample_morerealindex[i][l] / currentSampLen ) * ( temp7 / 50.f ) ) / 2 ) ) * currentSampLen ) * ( temp7 / currentSampLen ) + ( sample_morerealindex[i][l] + ( ( -temp7 + currentSampLen ) / currentSampLen ) ) ) / 2.f; + m_sample_morerealindex[i][l] = (((sin(((m_sample_morerealindex[i][l] / m_currentSampLen) * + (m_temp7 / 50.f)) / 2)) * m_currentSampLen) * (m_temp7 / m_currentSampLen) + + (m_sample_morerealindex[i][l] + ((-m_temp7 + m_currentSampLen) / m_currentSampLen))) / 2.f; break; } case 3:// Weird 2 { //Also the cool result of me messing up. - if( sample_morerealindex[i][l] > currentSampLen / 2.f ) + if (m_sample_morerealindex[i][l] > m_currentSampLen / 2.f) { - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, + m_temp7 * 10 / m_currentSampLen + 1) * m_currentSampLen; } else { - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; - sample_morerealindex[i][l] = sample_morerealindex[i][l] - currentSampLen / 2.f; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, + m_temp7 * 10 / m_currentSampLen + 1) * m_currentSampLen; + m_sample_morerealindex[i][l] = m_sample_morerealindex[i][l] - m_currentSampLen / 2.f; } break; } case 4:// Asym To Right { - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, + m_temp7 * 10 / m_currentSampLen + 1) * m_currentSampLen; break; } case 5:// Asym To Left { - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp7 * 10 / currentSampLen + 1 ) * currentSampLen; - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, + m_temp7 * 10 / m_currentSampLen + 1) * m_currentSampLen; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; break; } case 6:// Bidirectional Asym { - temp1 = temp7 / currentSampLen; - if( temp1 < 0.5 ) + m_temp1 = m_temp7 / m_currentSampLen; + if (m_temp1 < 0.5) { - temp1 = ( -temp1 + 1 ) / 2.f - 0.25f; - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + m_temp1 = (-m_temp1 + 1) / 2.f - 0.25f; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, m_temp1 * 10 + 1) * m_currentSampLen; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; } else { - temp1 = temp1 / 2.f - 0.25f; - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; + m_temp1 = m_temp1 / 2.f - 0.25f; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, m_temp1 * 10 + 1) * m_currentSampLen; } break; } case 7:// Stretch From Center { - temp1 = currentSampLen / 2.f; - sample_morerealindex[i][l] -= temp1; - sample_morerealindex[i][l] /= temp1; - sample_morerealindex[i][l] = ( sample_morerealindex[i][l] >= 0 ) ? pow( sample_morerealindex[i][l], 1 / ( ( temp7 * 4 ) / currentSampLen + 1 ) ) : -pow( -sample_morerealindex[i][l], 1 / ( ( temp7 * 4 ) / currentSampLen + 1 ) ); - sample_morerealindex[i][l] *= temp1; - sample_morerealindex[i][l] += temp1; + m_temp1 = m_currentSampLen / 2.f; + m_sample_morerealindex[i][l] -= m_temp1; + m_sample_morerealindex[i][l] /= m_temp1; + m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) ? + pow(m_sample_morerealindex[i][l], 1 / ((m_temp7 * 4) / m_currentSampLen + 1)) : + -pow(-m_sample_morerealindex[i][l], 1 / ((m_temp7 * 4) / m_currentSampLen + 1)); + m_sample_morerealindex[i][l] *= m_temp1; + m_sample_morerealindex[i][l] += m_temp1; break; } case 8:// Squish To Center { - temp1 = currentSampLen / 2.f; - sample_morerealindex[i][l] -= temp1; - sample_morerealindex[i][l] /= temp1; - sample_morerealindex[i][l] = ( sample_morerealindex[i][l] >= 0 ) ? pow( sample_morerealindex[i][l], 1 / ( -temp7 / currentSampLen + 1 ) ) : -pow( -sample_morerealindex[i][l], 1 / ( -temp7 / currentSampLen + 1 ) ); - sample_morerealindex[i][l] *= temp1; - sample_morerealindex[i][l] += temp1; + m_temp1 = m_currentSampLen / 2.f; + m_sample_morerealindex[i][l] -= m_temp1; + m_sample_morerealindex[i][l] /= m_temp1; + m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) ? + pow(m_sample_morerealindex[i][l], 1 / (-m_temp7 / m_currentSampLen + 1 )) : + -pow(-m_sample_morerealindex[i][l], 1 / (-m_temp7 / m_currentSampLen + 1)); + m_sample_morerealindex[i][l] *= m_temp1; + m_sample_morerealindex[i][l] += m_temp1; break; } case 9:// Stretch And Squish { - temp1 = currentSampLen / 2.f; - sample_morerealindex[i][l] -= temp1; - sample_morerealindex[i][l] /= temp1; - sample_morerealindex[i][l] = ( sample_morerealindex[i][l] >= 0 ) ? pow( sample_morerealindex[i][l], 1 / ( temp7 * 4 / currentSampLen ) ) : -pow( -sample_morerealindex[i][l], 1 / ( temp7 * 4 / currentSampLen ) ); - sample_morerealindex[i][l] *= temp1; - sample_morerealindex[i][l] += temp1; + m_temp1 = m_currentSampLen / 2.f; + m_sample_morerealindex[i][l] -= m_temp1; + m_sample_morerealindex[i][l] /= m_temp1; + m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) ? + pow(m_sample_morerealindex[i][l], 1 / (m_temp7 * 4 / m_currentSampLen)) : + -pow(-m_sample_morerealindex[i][l], 1 / (m_temp7 * 4 / m_currentSampLen)); + m_sample_morerealindex[i][l] *= m_temp1; + m_sample_morerealindex[i][l] += m_temp1; break; } case 10:// Cut Off Right { - sample_morerealindex[i][l] *= ( -temp7 + currentSampLen ) / currentSampLen; + m_sample_morerealindex[i][l] *= (-m_temp7 + m_currentSampLen) / m_currentSampLen; break; } case 11:// Cut Off Left { - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; - sample_morerealindex[i][l] *= ( -temp7 + currentSampLen ) / currentSampLen; - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; + m_sample_morerealindex[i][l] *= (-m_temp7 + m_currentSampLen) / m_currentSampLen; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; break; } case 19:// Sync { - sample_morerealindex[i][l] *= ( ( temp7 * 16.f ) / currentSampLen ) + 1; - sample_morerealindex[i][l] = fmod( sample_morerealindex[i][l], (float)currentSampLen - 1 ); + m_sample_morerealindex[i][l] *= ((m_temp7 * 16.f) / m_currentSampLen) + 1; + m_sample_morerealindex[i][l] = fmod(m_sample_morerealindex[i][l], (float)m_currentSampLen - 1); break; } case 20:// Sync Half Interpolate { - sample_morerealindex[i][l] *= ( ( temp7 * 16.f ) / currentSampLen ) + 1; - sample_morerealindex[i][l] = fmod( sample_morerealindex[i][l], (float)currentSampLen - 1 ); + m_sample_morerealindex[i][l] *= ((m_temp7 * 16.f) / m_currentSampLen) + 1; + m_sample_morerealindex[i][l] = fmod(m_sample_morerealindex[i][l], (float)m_currentSampLen - 1); break; } case 21:// Sync Interpolate { - sample_morerealindex[i][l] *= ( ( temp7 * 16.f ) / currentSampLen ) + 1; - sample_morerealindex[i][l] = fmod( sample_morerealindex[i][l], (float)currentSampLen - 1 ); + m_sample_morerealindex[i][l] *= ((m_temp7 * 16.f) / m_currentSampLen) + 1; + m_sample_morerealindex[i][l] = fmod(m_sample_morerealindex[i][l], (float)m_currentSampLen - 1); break; } case 22:// Mirror { - sample_morerealindex[i][l] = sample_morerealindex[i][l] < currentSampLen / 2 ? sample_morerealindex[i][l] * 2 : ( -sample_morerealindex[i][l] + currentSampLen ) * 2; - temp1 = temp7 / currentSampLen; - if( temp1 < 0.5 ) + m_sample_morerealindex[i][l] = m_sample_morerealindex[i][l] < m_currentSampLen / 2 ? + m_sample_morerealindex[i][l] * 2 : (-m_sample_morerealindex[i][l] + m_currentSampLen) * 2; + m_temp1 = m_temp7 / m_currentSampLen; + if (m_temp1 < 0.5) { - temp1 = ( -temp1 + 1 ) / 2.f - 0.25f; - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; - sample_morerealindex[i][l] = -sample_morerealindex[i][l] + currentSampLen; + m_temp1 = (-m_temp1 + 1) / 2.f - 0.25f; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, m_temp1 * 10 + 1) * m_currentSampLen; + m_sample_morerealindex[i][l] = -m_sample_morerealindex[i][l] + m_currentSampLen; } else { - temp1 = temp1 / 2.f - 0.25f; - sample_morerealindex[i][l] = pow( sample_morerealindex[i][l] / currentSampLen, temp1 * 10 + 1 ) * currentSampLen; + m_temp1 = m_temp1 / 2.f - 0.25f; + m_sample_morerealindex[i][l] = pow(m_sample_morerealindex[i][l] / m_currentSampLen, m_temp1 * 10 + 1) * m_currentSampLen; } break; } @@ -5118,177 +5170,181 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ {} } - mainsample[i][l] = 0; + m_mainsample[i][l] = 0; - if( modifyMode[i] != 12 && modifyMode[i] != 13 && modifyMode[i] != 23 && modifyMode[i] != 24 )// If NOT Squarify/Pulsify/Diagonal/Sideways Modify Mode + // If NOT Squarify/Pulsify/Diagonal/Sideways Modify Mode + if (m_modifyMode[i] != 12 && m_modifyMode[i] != 13 && m_modifyMode[i] != 23 && m_modifyMode[i] != 24) { - loopStart = qMax( 0.f, morph[i] - range[i] ) + 1; - loopEnd = qMin( morph[i] + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; - currentRangeValInvert = 1.f / range[i]; - currentIndex = sample_morerealindex[i][l]; + m_loopStart = qMax(0.f, m_morph[i] - m_range[i]) + 1; + m_loopEnd = qMin(m_morph[i] + m_range[i], MAINARRAYLEN / (float)m_currentSampLen) + 1; + m_currentRangeValInvert = 1.f / m_range[i]; + m_currentIndex = m_sample_morerealindex[i][l]; // Only grab samples from the waveforms when they will be used, depending on the Range knob - for( int j = loopStart; j < loopEnd; ++j ) + for (int j = m_loopStart; j < m_loopEnd; ++j) { // Get waveform samples, set their volumes depending on Range knob - mainsample[i][l] += waveforms[i][currentIndex + j * currentSampLen] * ( 1 - ( abs( morph[i] - j ) * currentRangeValInvert ) ); + m_mainsample[i][l] += m_waveforms[i][m_currentIndex + j * m_currentSampLen] * + (1 - (abs(m_morph[i] - j) * m_currentRangeValInvert)); } } - else if( modifyMode[i] == 12 )// If Squarify Modify Mode + else if (m_modifyMode[i] == 12)// If Squarify Modify Mode { - loopStart = qMax( 0.f, morph[i] - range[i] ) + 1; - loopEnd = qMin( morph[i] + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; - currentRangeValInvert = 1.f / range[i]; - currentIndex = sample_morerealindex[i][l]; + m_loopStart = qMax(0.f, m_morph[i] - m_range[i]) + 1; + m_loopEnd = qMin(m_morph[i] + m_range[i], MAINARRAYLEN / (float)m_currentSampLen) + 1; + m_currentRangeValInvert = 1.f / m_range[i]; + m_currentIndex = m_sample_morerealindex[i][l]; // Self-made formula, may be buggy. Crossfade one half of waveform with the inverse of the other. // Taking these calculations out of the following loop will help with performance with high Range values. - temp2 = temp7 / currentSampLen; - temp3 = temp2; - ++temp2; - temp4 = int( currentIndex + ( currentSampLen * 0.5 ) ) % currentSampLen; + m_temp2 = m_temp7 / m_currentSampLen; + m_temp3 = m_temp2; + ++m_temp2; + m_temp4 = int(m_currentIndex + (m_currentSampLen * 0.5)) % m_currentSampLen; - for( int j = loopStart; j < loopEnd; ++j ) + for (int j = m_loopStart; j < m_loopEnd; ++j) { - temp1 = 1 - ( abs( morph[i] - j ) * currentRangeValInvert ); - mainsample[i][l] += ( - ( waveforms[i][currentIndex + j * currentSampLen] * temp1 ) + // Normal - ( -waveforms[i][int(temp4) + j * currentSampLen] * temp1 * temp3 ) ) / // Inverted other half of waveform - temp2; // Volume compensation + m_temp1 = 1 - (abs(m_morph[i] - j) * m_currentRangeValInvert); + m_mainsample[i][l] += ( + ( m_waveforms[i][m_currentIndex + j * m_currentSampLen] * m_temp1) + // Normal + (-m_waveforms[i][int(m_temp4) + j * m_currentSampLen] * m_temp1 * m_temp3)) / // Inverted other half of waveform + m_temp2; // Volume compensation } } - else if( modifyMode[i] == 13 )// If Pulsify Modify Mode + else if (m_modifyMode[i] == 13)// If Pulsify Modify Mode { - loopStart = qMax( 0.f, morph[i] - range[i] ) + 1; - loopEnd = qMin( morph[i] + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; - currentRangeValInvert = 1.f / range[i]; - currentIndex = sample_morerealindex[i][l]; + m_loopStart = qMax(0.f, m_morph[i] - m_range[i]) + 1; + m_loopEnd = qMin(m_morph[i] + m_range[i], MAINARRAYLEN / (float)m_currentSampLen) + 1; + m_currentRangeValInvert = 1.f / m_range[i]; + m_currentIndex = m_sample_morerealindex[i][l]; // Self-made formula, may be buggy. Crossfade one side of waveform with the inverse of the other. // Taking this calculation out of the following loop will help with performance with high Range values. - temp2 = ( currentIndex + int( currentSampLen * ( temp7 / currentSampLen ) ) ) % currentSampLen; + m_temp2 = (m_currentIndex + int(m_currentSampLen * (m_temp7 / m_currentSampLen))) % m_currentSampLen; - for( int j = loopStart; j < loopEnd; ++j ) + for (int j = m_loopStart; j < m_loopEnd; ++j) { - temp1 = 1 - ( abs( morph[i] - j ) * currentRangeValInvert ); - mainsample[i][l] += ( - ( waveforms[i][currentIndex + j * currentSampLen] * temp1 ) + // Normal - ( ( -waveforms[i][int(temp2) + j * currentSampLen] * temp1 ) ) ) * // Inverted other side of waveform + m_temp1 = 1 - (abs(m_morph[i] - j) * m_currentRangeValInvert); + m_mainsample[i][l] += ( + ( m_waveforms[i][m_currentIndex + j * m_currentSampLen] * m_temp1) + // Normal + ((-m_waveforms[i][int(m_temp2) + j * m_currentSampLen] * m_temp1))) * // Inverted other side of waveform 0.5f; // Volume compensation } } - else if( modifyMode[i] == 23 )// If Diagonal Modify Mode + else if (m_modifyMode[i] == 23)// If Diagonal Modify Mode { - temp5 = realfmod( morph[i] + ( sample_morerealindex[i][l] * temp7 / currentSampLen / 32.f ), morphMax[i] ); - loopStart = temp5 - range[i] + 1; - loopEnd = temp5 + range[i] + 1; - currentRangeValInvert = 1.f / range[i]; - currentIndex = sample_morerealindex[i][l]; + m_temp5 = realfmod(m_morph[i] + (m_sample_morerealindex[i][l] * m_temp7 / m_currentSampLen / 32.f), m_morphMax[i]); + m_loopStart = m_temp5 - m_range[i] + 1; + m_loopEnd = m_temp5 + m_range[i] + 1; + m_currentRangeValInvert = 1.f / m_range[i]; + m_currentIndex = m_sample_morerealindex[i][l]; // Quite experimental, morph value is changed depending on wavetable position. - for( int j = loopStart; j < loopEnd; ++j ) + for (int j = m_loopStart; j < m_loopEnd; ++j) { - temp3 = realfmod( j, morphMax[i] ); - mainsample[i][l] += waveforms[i][currentIndex + (int)temp3 * currentSampLen] * ( 1 - ( abs( temp5 - j ) * currentRangeValInvert ) ); + m_temp3 = realfmod(j, m_morphMax[i]); + m_mainsample[i][l] += m_waveforms[i][m_currentIndex + (int)m_temp3 * m_currentSampLen] * + (1 - (abs(m_temp5 - j) * m_currentRangeValInvert)); } } - else if( modifyMode[i] == 24 )// If Sideways Modify Mode + else if (m_modifyMode[i] == 24)// If Sideways Modify Mode { - temp5 = sample_morerealindex[i][l] / currentSampLen * morphMax[i]; - loopStart = qMax( 0.f, temp5 - range[i] ) + 1; - loopEnd = qMin( temp5 + range[i], MAINARRAYLEN / (float)currentSampLen ) + 1; - currentRangeValInvert = 1.f / range[i]; - currentIndex = temp7; + m_temp5 = m_sample_morerealindex[i][l] / m_currentSampLen * m_morphMax[i]; + m_loopStart = qMax(0.f, m_temp5 - m_range[i]) + 1; + m_loopEnd = qMin(m_temp5 + m_range[i], MAINARRAYLEN / (float)m_currentSampLen) + 1; + m_currentRangeValInvert = 1.f / m_range[i]; + m_currentIndex = m_temp7; // Quite experimental, swap the Morph value (now controlled using Modify) and the location in the waveform. - for( int j = loopStart; j < loopEnd; ++j ) + for (int j = m_loopStart; j < m_loopEnd; ++j) { // Get waveform samples, set their volumes depending on Range knob - mainsample[i][l] += waveforms[i][currentIndex + j * currentSampLen] * ( 1 - ( abs( temp5 - j ) * currentRangeValInvert ) ); + m_mainsample[i][l] += m_waveforms[i][m_currentIndex + j * m_currentSampLen] * + (1 - (abs(m_temp5 - j) * m_currentRangeValInvert)); } } - switch( modifyMode[i] )// More horrifying formulas for the various Modify Modes + switch (m_modifyMode[i])// More horrifying formulas for the various Modify Modes { case 1:// Pulse Width { - if( sample_realindex[i][l] / ( ( -temp7 + currentSampLen ) / currentSampLen ) > currentSampLen ) + if (m_sample_realindex[i][l] / ((-m_temp7 + m_currentSampLen) / m_currentSampLen) > m_currentSampLen) { - mainsample[i][l] = 0; + m_mainsample[i][l] = 0; } break; } case 14:// Flip { - if( sample_realindex[i][l] > temp7 ) + if (m_sample_realindex[i][l] > m_temp7) { - mainsample[i][l] *= -1; + m_mainsample[i][l] *= -1; } break; } case 15:// Clip { - temp1 = temp7 / ( currentSampLen - 1 ); - mainsample[i][l] = qBound( -temp1, mainsample[i][l], temp1 ); + m_temp1 = m_temp7 / (m_currentSampLen - 1); + m_mainsample[i][l] = qBound(-m_temp1, m_mainsample[i][l], m_temp1); break; } case 16:// Inverse Clip { - temp1 = temp7 / ( currentSampLen - 1 ); - if( mainsample[i][l] > 0 && mainsample[i][l] < temp1 ) + m_temp1 = m_temp7 / (m_currentSampLen - 1); + if (m_mainsample[i][l] > 0 && m_mainsample[i][l] < m_temp1) { - mainsample[i][l] = temp1; + m_mainsample[i][l] = m_temp1; } - else if( mainsample[i][l] < 0 && mainsample[i][l] > -temp1 ) + else if (m_mainsample[i][l] < 0 && m_mainsample[i][l] > -m_temp1) { - mainsample[i][l] = -temp1; + m_mainsample[i][l] = -m_temp1; } break; } case 17:// Sine { - temp1 = temp7 / ( currentSampLen - 1 ); - mainsample[i][l] = sin( mainsample[i][l] * ( D_PI * temp1 * 8 + 1 ) ); + m_temp1 = m_temp7 / (m_currentSampLen - 1); + m_mainsample[i][l] = sin(m_mainsample[i][l] * (D_PI * m_temp1 * 8 + 1)); break; } case 18:// Atan { - temp1 = temp7 / ( currentSampLen - 1 ); - mainsample[i][l] = atan( mainsample[i][l] * ( D_PI * temp1 * 8 + 1 ) ); + m_temp1 = m_temp7 / (m_currentSampLen - 1); + m_mainsample[i][l] = atan(m_mainsample[i][l] * (D_PI * m_temp1 * 8 + 1)); break; } case 20:// Sync Half Interpolate { - temp1 = currentSampLen / 2.f; - temp2 = currentSampLen / 4.f; - if( sample_realindex[i][l] < temp2 || sample_realindex[i][l] > 3.f * temp2 ) + m_temp1 = m_currentSampLen / 2.f; + m_temp2 = m_currentSampLen / 4.f; + if (m_sample_realindex[i][l] < m_temp2 || m_sample_realindex[i][l] > 3.f * m_temp2) { - mainsample[i][l] *= ( -abs( sample_realindex[i][l] - temp1 ) + temp1 ) / currentSampLen * 4.f; + m_mainsample[i][l] *= (-abs(m_sample_realindex[i][l] - m_temp1) + m_temp1) / m_currentSampLen * 4.f; } break; } case 21:// Sync Interpolate { - temp1 = currentSampLen / 2.f; - mainsample[i][l] *= ( -abs( sample_realindex[i][l] - temp1 ) + temp1 ) / currentSampLen * 2.f; + m_temp1 = m_currentSampLen / 2.f; + m_mainsample[i][l] *= (-abs(m_sample_realindex[i][l] - m_temp1) + m_temp1) / m_currentSampLen * 2.f; break; } default: {} } - sample_realindex[i][l] += sample_step[i][l]; + m_sample_realindex[i][l] += m_sample_step[i][l]; // check overflow - while( sample_realindex[i][l] >= currentSampLen ) + while (m_sample_realindex[i][l] >= m_currentSampLen) { - sample_realindex[i][l] -= currentSampLen; - lastMainOscEnvDone[l] = true; + m_sample_realindex[i][l] -= m_currentSampLen; + m_lastMainOscEnvDone[l] = true; } - mainsample[i][l] *= vol[i] * 0.01f; + m_mainsample[i][l] *= m_vol[i] * 0.01f; } } } @@ -5297,59 +5353,63 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ //== SUB OSCILLATOR ==// //====================// - for( int i = 0; i < maxSubEnabled; ++i )// maxSubEnabled keeps this from looping 64 times every sample, saving a lot of CPU + for (int i = 0; i < m_maxSubEnabled; ++i)// m_maxSubEnabled keeps this from looping 64 times every m_sample, saving a lot of CPU { - if( subEnabled[i] ) + if (m_subEnabled[i]) { - if( !subNoise[i] ) + if (!m_subNoise[i]) { - temp2 = subPhase[i] * subSampLen[i]; - temp3 = subVol[i] * 0.01f; - temp4 = subSampLen[i] * WAVERATIO; + m_temp2 = m_subPhase[i] * m_subSampLen[i]; + m_temp3 = m_subVol[i] * 0.01f; + m_temp4 = m_subSampLen[i] * WAVERATIO; - for( int l = 0; l < subUnisonNum[i]; ++l ) + for (int l = 0; l < m_subUnisonNum[i]; ++l) { - subUnisonVoicesMinusOne = subUnisonNum[i] - 1;// subUnisonNum[i] - 1 is needed many times, which is why subUnisonVoicesMinusOne exists + m_subUnisonVoicesMinusOne = m_subUnisonNum[i] - 1;// m_subUnisonNum[i] - 1 is needed many times, which is why m_subUnisonVoicesMinusOne exists - if( !subUnisonVoicesMinusOne ) + if (!m_subUnisonVoicesMinusOne) { - if( subTempo[i] ) + if (m_subTempo[i]) { - temp1 = subTempo[i] / 26400.f; - noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subDetune[i] ) * temp1 : detuneWithCents( 440.f, subDetune[i] ) * temp1; + m_temp1 = m_subTempo[i] / 26400.f; + m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), m_subDetune[i]) * m_temp1 : detuneWithCents(440.f, m_subDetune[i]) * m_temp1; } else { - noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subDetune[i] ) : detuneWithCents( 440.f, subDetune[i] ); + m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), m_subDetune[i]) : detuneWithCents(440.f, m_subDetune[i]); } } else { - if( subTempo[i] ) + if (m_subTempo[i]) { - temp1 = subTempo[i] / 26400.f; - noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ) * temp1 : detuneWithCents( 440.f, subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ) * temp1; + m_temp1 = m_subTempo[i] / 26400.f; + m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), + m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) * m_temp1 : + detuneWithCents(440.f, m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) * m_temp1; } else { - noteFreq = subKeytrack[i] ? detuneWithCents( nph->frequency(), subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ) : detuneWithCents( 440.f, subUnisonDetuneAmounts[i][l]*subUnisonDetune[i]+subDetune[i] ); + m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), + m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) : + detuneWithCents(440.f, m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]); } } - sample_step_sub = temp4 / ( sample_rate / noteFreq ); + m_sample_step_sub = m_temp4 / (sample_rate / m_noteFreq); - subsample[i][l] = temp3 * subs[i][int( realfmod( sample_subindex[i][l] + temp2, temp4 ) )]; + m_subsample[i][l] = m_temp3 * m_subs[i][int(realfmod(m_sample_subindex[i][l] + m_temp2, m_temp4))]; - sample_subindex[i][l] += sample_step_sub; + m_sample_subindex[i][l] += m_sample_step_sub; // move waveform position back if it passed the end of the waveform - while ( sample_subindex[i][l] >= temp4 ) + while (m_sample_subindex[i][l] >= m_temp4) { - sample_subindex[i][l] -= temp4; - lastSubEnvDone[i] = true; + m_sample_subindex[i][l] -= m_temp4; + m_lastSubEnvDone[i] = true; } - /* That is all that is needed for the sub oscillator calculations. + /* That is all that is needed for the m_sub oscillator calculations. (To the tune of Hallelujah) @@ -5396,21 +5456,21 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ } else// sub oscillator is noise { - temp2 = subVol[i] * 0.01f; - for( int l = 0; l < subUnisonNum[i]; ++l ) + m_temp2 = m_subVol[i] * 0.01f; + for (int l = 0; l < m_subUnisonNum[i]; ++l) { - noiseSampRand = fastRandf( subSampLen[l] ) - 1; + m_noiseSampRand = fastRandf(m_subSampLen[l]) - 1; - temp1 = ( storedsubs[i][int(noiseSampRand)] * subNoiseDirection[i][l] ) + lastSubNoiseVal[i][l]; - if( temp1 > 1 || temp1 < -1 ) + m_temp1 = (m_storedsubs[i][int(m_noiseSampRand)] * m_subNoiseDirection[i][l]) + m_lastSubNoiseVal[i][l]; + if (m_temp1 > 1 || m_temp1 < -1) { - subNoiseDirection[i][l] *= -1; - temp1 = ( storedsubs[i][int( noiseSampRand )] * subNoiseDirection[i][l] ) + lastSubNoiseVal[i][l]; + m_subNoiseDirection[i][l] *= -1; + m_temp1 = (m_storedsubs[i][int(m_noiseSampRand)] * m_subNoiseDirection[i][l]) + m_lastSubNoiseVal[i][l]; } - lastSubNoiseVal[i][l] = temp1; + m_lastSubNoiseVal[i][l] = m_temp1; - subsample[i][l] = temp1 * temp2; + m_subsample[i][l] = m_temp1 * m_temp2; } } } @@ -5420,250 +5480,253 @@ void mSynth::nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][ //== SAMPLE OSCILLATOR ==// //=======================// - for( int l = 0; l < maxSampleEnabled; ++l )// maxSampleEnabled keeps this from looping 8 times every sample, saving some CPU + for (int l = 0; l < m_maxSampleEnabled; ++l)// m_maxSampleEnabled keeps this from looping 8 times every sample, saving some CPU { - int sampleSize = samples[l][0].size() * sampleEnd[l]; - if( sampleEnabled[l] && ( sample_sampleindex[l] < sampleSize || sampleLoop[l] ) ) + int sampleSize = m_samples[l][0].size() * m_sampleEnd[l]; + if (m_sampleEnabled[l] && (m_sample_sampleindex[l] < sampleSize || m_sampleLoop[l])) { - if( sampleLoop[l] ) + if (m_sampleLoop[l]) { - if( sample_sampleindex[l] > sampleSize ) + if (m_sample_sampleindex[l] > sampleSize) { - sample_sampleindex[l] = sample_sampleindex[l] - sampleSize + ( samples[l][0].size() * sampleStart[l] ); - lastSampleEnvDone[l] = true; + m_sample_sampleindex[l] = m_sample_sampleindex[l] - sampleSize + (m_samples[l][0].size() * m_sampleStart[l]); + m_lastSampleEnvDone[l] = true; } } - sample_step_sample = ( detuneWithCents( sampleKeytracking[l] ? nph->frequency() : 440.f, sampleDetune[l] ) / 440.f ) * ( 44100.f / sample_rate ); + m_sample_step_sample = (detuneWithCents(m_sampleKeytracking[l] ? m_nph->frequency() : 440.f, + m_sampleDetune[l]) / 440.f) * (44100.f / sample_rate); - if( sampleGraphEnabled[l] && sampleStart[l] < sampleEnd[l] ) + if (m_sampleGraphEnabled[l] && m_sampleStart[l] < m_sampleEnd[l]) { - progress = realfmod( ( sample_sampleindex[l] + ( samplePhase[l] * sampleSize * 0.01f ) ), sampleSize ) / sampleSize * 128.f; - intprogress = (int)progress; + m_progress = realfmod((m_sample_sampleindex[l] + (m_samplePhase[l] * sampleSize * 0.01f)), sampleSize) / sampleSize * 128.f; + m_intprogress = (int)m_progress; - temp1 = fmod( progress, 1 ); - progress2 = sampGraphs[intprogress] * ( 1 - temp1 ); + m_temp1 = fmod(m_progress, 1); + m_progress2 = m_sampGraphs[m_intprogress] * (1 - m_temp1); - if( intprogress < 127 ) + if (m_intprogress < 127) { - progress3 = sampGraphs[intprogress+1] * temp1; + m_progress3 = m_sampGraphs[m_intprogress+1] * m_temp1; } else { - progress3 = sampGraphs[intprogress] * temp1; + m_progress3 = m_sampGraphs[m_intprogress] * m_temp1; } - temp1 = int( ( ( progress2 + progress3 + 1 ) * 0.5f ) * sampleSize ); - samplesample[l][0] = samples[l][0][temp1]; - samplesample[l][1] = samples[l][1][temp1]; + m_temp1 = int(((m_progress2 + m_progress3 + 1) * 0.5f) * sampleSize); + m_samplesample[l][0] = m_samples[l][0][m_temp1]; + m_samplesample[l][1] = m_samples[l][1][m_temp1]; } else { - temp1 = realfmod(( sample_sampleindex[l] + ( samplePhase[l] * sampleSize * 0.01f ) ), sampleSize); - samplesample[l][0] = samples[l][0][temp1]; - samplesample[l][1] = samples[l][1][temp1]; + m_temp1 = realfmod((m_sample_sampleindex[l] + (m_samplePhase[l] * sampleSize * 0.01f)), sampleSize); + m_samplesample[l][0] = m_samples[l][0][m_temp1]; + m_samplesample[l][1] = m_samples[l][1][m_temp1]; } - temp1 = sampleVolume[l] * 0.01f; - samplesample[l][0] *= temp1; - samplesample[l][1] *= temp1; + m_temp1 = m_sampleVolume[l] * 0.01f; + m_samplesample[l][0] *= m_temp1; + m_samplesample[l][1] *= m_temp1; - if( samplePanning[l] < 0 ) + if (m_samplePanning[l] < 0) { - samplesample[l][1] *= ( 100.f + samplePanning[l] ) * 0.01f; + m_samplesample[l][1] *= (100.f + m_samplePanning[l]) * 0.01f; } - else if( samplePanning[l] > 0 ) + else if (m_samplePanning[l] > 0) { - samplesample[l][0] *= ( 100.f - samplePanning[l] ) * 0.01f; + m_samplesample[l][0] *= (100.f - m_samplePanning[l]) * 0.01f; } - lastSampleVal[l][0] = samplesample[l][0];// Store value for modulation - lastSampleVal[l][1] = samplesample[l][1];// Store value for modulation + m_lastSampleVal[l][0] = m_samplesample[l][0];// Store value for modulation + m_lastSampleVal[l][1] = m_samplesample[l][1];// Store value for modulation - if( !lastSampleEnvDone[l] ) + if (!m_lastSampleEnvDone[l]) { - lastSampleEnvVal[l][0] = lastSampleVal[l][0]; - lastSampleEnvVal[l][1] = lastSampleVal[l][1]; + m_lastSampleEnvVal[l][0] = m_lastSampleVal[l][0]; + m_lastSampleEnvVal[l][1] = m_lastSampleVal[l][1]; } - if( sampleMuted[l] ) + if (m_sampleMuted[l]) { - samplesample[l][0] = 0; - samplesample[l][1] = 0; + m_samplesample[l][0] = 0; + m_samplesample[l][1] = 0; } - sample_sampleindex[l] += sample_step_sample; + m_sample_sampleindex[l] += m_sample_step_sample; } } outputSample[0] = 0; outputSample[1] = 0; // Main Oscillator outputs - for( int i = 0; i < maxMainEnabled; ++i ) + for (int i = 0; i < m_maxMainEnabled; ++i) { - if( enabled[i] ) + if (m_enabled[i]) { - unisonVoicesMinusOne = unisonVoices[i] - 1; + m_unisonVoicesMinusOne = m_unisonVoices[i] - 1; - if( unisonVoicesMinusOne ) + if (m_unisonVoicesMinusOne) { - sampleMainOsc[0] = 0; - sampleMainOsc[1] = 0; - for( int j = 0; j < unisonVoices[i]; ++j ) + m_sampleMainOsc[0] = 0; + m_sampleMainOsc[1] = 0; + for (int j = 0; j < m_unisonVoices[i]; ++j) { // Pan unison voices - sampleMainOsc[0] += mainsample[i][j] * ((unisonVoicesMinusOne-j)/unisonVoicesMinusOne); - sampleMainOsc[1] += mainsample[i][j] * (j/unisonVoicesMinusOne); + m_sampleMainOsc[0] += m_mainsample[i][j] * ((m_unisonVoicesMinusOne-j)/m_unisonVoicesMinusOne); + m_sampleMainOsc[1] += m_mainsample[i][j] * (j/m_unisonVoicesMinusOne); } // Decrease volume so more unison voices won't increase volume too much - temp1 = unisonVoices[i] * 0.5f; - sampleMainOsc[0] /= temp1; - sampleMainOsc[1] /= temp1; + m_temp1 = m_unisonVoices[i] * 0.5f; + m_sampleMainOsc[0] /= m_temp1; + m_sampleMainOsc[1] /= m_temp1; } else { - sampleMainOsc[0] = mainsample[i][0]; - sampleMainOsc[1] = mainsample[i][0]; + m_sampleMainOsc[0] = m_mainsample[i][0]; + m_sampleMainOsc[1] = m_mainsample[i][0]; } - if( pan[i] ) + if (m_pan[i]) { - if( pan[i] < 0 ) + if (m_pan[i] < 0) { - sampleMainOsc[1] *= ( 100.f + pan[i] ) * 0.01f; + m_sampleMainOsc[1] *= (100.f + m_pan[i]) * 0.01f; } else { - sampleMainOsc[0] *= ( 100.f - pan[i] ) * 0.01f; + m_sampleMainOsc[0] *= (100.f - m_pan[i]) * 0.01f; } } - lastMainOscVal[i][0] = sampleMainOsc[0];// Store results for modulations - lastMainOscVal[i][1] = sampleMainOsc[1]; + m_lastMainOscVal[i][0] = m_sampleMainOsc[0];// Store results for modulations + m_lastMainOscVal[i][1] = m_sampleMainOsc[1]; - // second half of "if" statement makes sure the last envelope value is the last value of the graph (not of the waveform), so the sinc interpolation doesn't ruin things. - if( !lastMainOscEnvDone[i] && sample_realindex[i][0] <= sampLen[i] * WAVERATIO - ( WAVERATIO * 2 ) ) + // second half of "if" statement makes sure the last envelope value is the last value of the + // graph (not of the waveform), so the sinc interpolation doesn't ruin things. + if (!m_lastMainOscEnvDone[i] && m_sample_realindex[i][0] <= m_sampLen[i] * WAVERATIO - (WAVERATIO * 2)) { - lastMainOscEnvVal[i][0] = lastMainOscVal[i][0]; - lastMainOscEnvVal[i][1] = lastMainOscVal[i][1]; + m_lastMainOscEnvVal[i][0] = m_lastMainOscVal[i][0]; + m_lastMainOscEnvVal[i][1] = m_lastMainOscVal[i][1]; } - if( !muted[i] ) + if (!m_muted[i]) { - outputSample[0] += sampleMainOsc[0]; - outputSample[1] += sampleMainOsc[1]; + outputSample[0] += m_sampleMainOsc[0]; + outputSample[1] += m_sampleMainOsc[1]; } } } // Sub Oscillator outputs - for( int i = 0; i < maxSubEnabled; ++i ) + for (int i = 0; i < m_maxSubEnabled; ++i) { - if( subEnabled[i] ) + if (m_subEnabled[i]) { - if( subUnisonNum[i] > 1 ) + if (m_subUnisonNum[i] > 1) { - subUnisonVoicesMinusOne = subUnisonNum[i] - 1; + m_subUnisonVoicesMinusOne = m_subUnisonNum[i] - 1; - sampleSubOsc[0] = 0; - sampleSubOsc[1] = 0; - for( int j = 0; j < subUnisonNum[i]; ++j ) + m_sampleSubOsc[0] = 0; + m_sampleSubOsc[1] = 0; + for (int j = 0; j < m_subUnisonNum[i]; ++j) { // Pan unison voices - sampleSubOsc[0] += subsample[i][j] * ((subUnisonVoicesMinusOne-j)/subUnisonVoicesMinusOne); - sampleSubOsc[1] += subsample[i][j] * (j/subUnisonVoicesMinusOne); + m_sampleSubOsc[0] += m_subsample[i][j] * ((m_subUnisonVoicesMinusOne-j)/m_subUnisonVoicesMinusOne); + m_sampleSubOsc[1] += m_subsample[i][j] * (j/m_subUnisonVoicesMinusOne); } // Decrease volume so more unison voices won't increase volume too much - temp1 = subUnisonNum[i] * 0.5f; - sampleSubOsc[0] /= temp1; - sampleSubOsc[1] /= temp1; + m_temp1 = m_subUnisonNum[i] * 0.5f; + m_sampleSubOsc[0] /= m_temp1; + m_sampleSubOsc[1] /= m_temp1; } else { - sampleSubOsc[0] = subsample[i][0]; - sampleSubOsc[1] = subsample[i][0]; + m_sampleSubOsc[0] = m_subsample[i][0]; + m_sampleSubOsc[1] = m_subsample[i][0]; } - if( subPanning[i] ) + if (m_subPanning[i]) { - if( subPanning[i] < 0 ) + if (m_subPanning[i] < 0) { - sampleSubOsc[1] *= ( 100.f + subPanning[i] ) * 0.01f; + m_sampleSubOsc[1] *= (100.f + m_subPanning[i]) * 0.01f; } else { - sampleSubOsc[0] *= ( 100.f - subPanning[i] ) * 0.01f; + m_sampleSubOsc[0] *= (100.f - m_subPanning[i]) * 0.01f; } } - if( subRateLimit[i] ) + if (m_subRateLimit[i]) { - sampleSubOsc[0] = lastSubVal[i][0] + qBound( -subRateLimit[i], sampleSubOsc[0] - lastSubVal[i][0], subRateLimit[i] ); - sampleSubOsc[1] = lastSubVal[i][1] + qBound( -subRateLimit[i], sampleSubOsc[1] - lastSubVal[i][1], subRateLimit[i] ); + m_sampleSubOsc[0] = m_lastSubVal[i][0] + qBound(-m_subRateLimit[i], m_sampleSubOsc[0] - m_lastSubVal[i][0], m_subRateLimit[i]); + m_sampleSubOsc[1] = m_lastSubVal[i][1] + qBound(-m_subRateLimit[i], m_sampleSubOsc[1] - m_lastSubVal[i][1], m_subRateLimit[i]); } - lastSubVal[i][0] = sampleSubOsc[0];// Store results for modulations - lastSubVal[i][1] = sampleSubOsc[1]; + m_lastSubVal[i][0] = m_sampleSubOsc[0];// Store results for modulations + m_lastSubVal[i][1] = m_sampleSubOsc[1]; - // second half of "if" statement makes sure the last envelope value is the last value of the graph (not of the waveform), so the sinc interpolation doesn't ruin things. - if( !lastSubEnvDone[i] && sample_subindex[i][0] <= subSampLen[i] * WAVERATIO - ( WAVERATIO * 2 ) ) + // second half of "if" statement makes sure the last envelope value is the last value of the + // graph (not of the waveform), so the sinc interpolation doesn't ruin things. + if (!m_lastSubEnvDone[i] && m_sample_subindex[i][0] <= m_subSampLen[i] * WAVERATIO - (WAVERATIO * 2)) { - lastSubEnvVal[i][0] = lastSubVal[i][0]; - lastSubEnvVal[i][1] = lastSubVal[i][1]; + m_lastSubEnvVal[i][0] = m_lastSubVal[i][0]; + m_lastSubEnvVal[i][1] = m_lastSubVal[i][1]; } - if( !subMuted[i] ) + if (!m_subMuted[i]) { - outputSample[0] += sampleSubOsc[0]; - outputSample[1] += sampleSubOsc[1]; + outputSample[0] += m_sampleSubOsc[0]; + outputSample[1] += m_sampleSubOsc[1]; } } } // Sample Oscillator outputs - for( int l = 0; l < maxSampleEnabled; ++l )// maxSampleEnabled keeps this from looping 8 times every sample, saving some CPU + for (int l = 0; l < m_maxSampleEnabled; ++l)// m_maxSampleEnabled keeps this from looping 8 times every m_sample, saving some CPU { - if( sampleEnabled[l] ) + if (m_sampleEnabled[l]) { - outputSample[0] += samplesample[l][0]; - outputSample[1] += samplesample[l][1]; + outputSample[0] += m_samplesample[l][0]; + outputSample[1] += m_samplesample[l][1]; } } // Filter outputs - for( int l = 0; l < maxFiltEnabled; ++l )// maxFiltEnabled keeps this from looping 8 times every sample, saving some CPU + for (int l = 0; l < m_maxFiltEnabled; ++l)// m_maxFiltEnabled keeps this from looping 8 times every m_sample, saving some CPU { - if( filtEnabled[l] ) + if (m_filtEnabled[l]) { - outputSample[0] += filtOutputs[l][0]; - outputSample[1] += filtOutputs[l][1]; + outputSample[0] += m_filtOutputs[l][0]; + outputSample[1] += m_filtOutputs[l][1]; } } // Refresh all modulated values back to the value of the knob. - for( int i = 0; i < numberToReset; ++i ) + for (int i = 0; i < m_numberToReset; ++i) { - refreshValue( modValType[i], modValNum[i], mwc ); + refreshValue(m_modValType[i], m_modValNum[i], m_mwc); } - numberToReset = 0; + m_numberToReset = 0; - if( removeDC ) + if (m_removeDC) { - averageSampleValue[0] = ( averageSampleValue[0] * 0.999f ) + ( outputSample[0] * 0.001f ); - averageSampleValue[1] = ( averageSampleValue[1] * 0.999f ) + ( outputSample[1] * 0.001f ); + m_averageSampleValue[0] = (m_averageSampleValue[0] * 0.999f) + (outputSample[0] * 0.001f); + m_averageSampleValue[1] = (m_averageSampleValue[1] * 0.999f) + (outputSample[1] * 0.001f); - outputSample[0] -= averageSampleValue[0]; - outputSample[1] -= averageSampleValue[1]; + outputSample[0] -= m_averageSampleValue[0]; + outputSample[1] -= m_averageSampleValue[1]; } } -// Takes input of original Hz and the number of cents to detune it by, and returns the detuned result in Hz. -inline float mSynth::detuneWithCents( float pitchValue, float detuneValue ) +// Takes input of original Hz and the number of cents to m_detune it by, and returns the detuned result in Hz. +inline float mSynth::detuneWithCents(float pitchValue, float m_detuneValue) { - if( detuneValue )// Avoids expensive exponentiation if no detuning is necessary + if (m_detuneValue)// Avoids expensive exponentiation if no detuning is necessary { - return pitchValue * std::exp2( detuneValue / 1200.f ); + return pitchValue * std::exp2(m_detuneValue / 1200.f); } else { @@ -5673,99 +5736,99 @@ inline float mSynth::detuneWithCents( float pitchValue, float detuneValue ) // At the end of mSynth::nextStringSample, this will refresh all modulated values back to the value of the knob. -inline void mSynth::refreshValue( int which, int num, Microwave * mwc ) +inline void mSynth::refreshValue(int which, int num, Microwave * m_mwc) { - switch( which ) + switch (which) { - case 1: morph[num] = mwc->morph[num]->value(); break; - case 2: range[num] = mwc->range[num]->value(); break; - case 3: modify[num] = mwc->modify[num]->value(); break; - case 4: modifyMode[num] = mwc->modifyMode[num]->value(); break; - case 5: vol[num] = mwc->vol[num]->value(); break; - case 6: pan[num] = mwc->pan[num]->value(); break; - case 7: detune[num] = mwc->detune[num]->value(); break; - case 8: phase[num] = mwc->phase[num]->value(); break; - case 9: phaseRand[num] = mwc->phaseRand[num]->value(); break; - case 10: enabled[num] = mwc->enabled[num]->value(); break; - case 11: muted[num] = mwc->muted[num]->value(); break; - case 12: sampLen[num] = mwc->sampLen[num]->value(); break; - case 13: morphMax[num] = mwc->morphMax[num]->value(); break; - case 14: unisonVoices[num] = mwc->unisonVoices[num]->value(); break; - case 15: unisonDetune[num] = mwc->unisonDetune[num]->value(); break; - case 16: unisonMorph[num] = mwc->unisonMorph[num]->value(); break; - case 17: unisonModify[num] = mwc->unisonModify[num]->value(); break; - case 18: keytracking[num] = mwc->keytracking[num]->value(); break; - case 19: tempo[num] = mwc->tempo[num]->value(); break; - case 20: interpolate[num] = mwc->interpolate[num]->value(); break; - - case 30: subEnabled[num] = mwc->subEnabled[num]->value(); break; - case 31: subMuted[num] = mwc->subMuted[num]->value(); break; - case 32: subKeytrack[num] = mwc->subKeytrack[num]->value(); break; - case 33: subNoise[num] = mwc->subNoise[num]->value(); break; - case 34: subVol[num] = mwc->subVol[num]->value(); break; - case 35: subPanning[num] = mwc->subPanning[num]->value(); break; - case 36: subDetune[num] = mwc->subDetune[num]->value(); break; - case 37: subPhase[num] = mwc->subPhase[num]->value(); break; - case 38: subPhaseRand[num] = mwc->subPhaseRand[num]->value(); break; - case 39: subSampLen[num] = mwc->subSampLen[num]->value(); break; - case 40: subTempo[num] = mwc->subTempo[num]->value(); break; - case 41: subRateLimit[num] = mwc->subRateLimit[num]->value(); break; - case 42: subUnisonNum[num] = mwc->subUnisonNum[num]->value(); break; - case 43: subUnisonDetune[num] = mwc->subUnisonDetune[num]->value(); break; - case 44: subInterpolate[num] = mwc->subInterpolate[num]->value(); break; - - case 60: sampleEnabled[num] = mwc->sampleEnabled[num]->value(); break; - case 61: sampleMuted[num] = mwc->sampleMuted[num]->value(); break; - case 62: sampleKeytracking[num] = mwc->sampleKeytracking[num]->value(); break; - case 63: sampleGraphEnabled[num] = mwc->sampleGraphEnabled[num]->value(); break; - case 64: sampleLoop[num] = mwc->sampleLoop[num]->value(); break; - case 65: sampleVolume[num] = mwc->sampleVolume[num]->value(); break; - case 66: samplePanning[num] = mwc->samplePanning[num]->value(); break; - case 67: sampleDetune[num] = mwc->sampleDetune[num]->value(); break; - case 68: samplePhase[num] = mwc->samplePhase[num]->value(); break; - case 69: samplePhaseRand[num] = mwc->samplePhaseRand[num]->value(); break; - case 70: sampleStart[num] = mwc->sampleStart[num]->value(); break; - case 71: sampleEnd[num] = mwc->sampleEnd[num]->value(); break; - - case 90: modIn[num] = mwc->modIn[num]->value(); break; - case 91: modInNum[num] = mwc->modInNum[num]->value(); break; - case 92: modInAmnt[num] = mwc->modInAmnt[num]->value(); break; - case 93: modInCurve[num] = mwc->modInCurve[num]->value(); break; - case 94: modIn2[num] = mwc->modIn2[num]->value(); break; - case 95: modInNum2[num] = mwc->modInNum2[num]->value(); break; - case 96: modInAmnt2[num] = mwc->modInAmnt2[num]->value(); break; - case 97: modInCurve2[num] = mwc->modInCurve2[num]->value(); break; - case 98: modOutSec[num] = mwc->modOutSec[num]->value(); break; - case 99: modOutSig[num] = mwc->modOutSig[num]->value(); break; - case 100: modOutSecNum[num] = mwc->modOutSecNum[num]->value(); break; - case 101: modEnabled[num] = mwc->modEnabled[num]->value(); break; - case 102: modCombineType[num] = mwc->modCombineType[num]->value(); break; - case 103: modType[num] = mwc->modType[num]->value(); break; - case 104: modType2[num] = mwc->modType2[num]->value(); break; - - case 120: filtCutoff[num] = mwc->filtCutoff[num]->value(); break; - case 121: filtReso[num] = mwc->filtReso[num]->value(); break; - case 122: filtGain[num] = mwc->filtGain[num]->value(); break; - case 123: filtType[num] = mwc->filtType[num]->value(); break; - case 124: filtSlope[num] = mwc->filtSlope[num]->value(); break; - case 125: filtInVol[num] = mwc->filtInVol[num]->value(); break; - case 126: filtOutVol[num] = mwc->filtOutVol[num]->value(); break; - case 127: filtWetDry[num] = mwc->filtWetDry[num]->value(); break; - case 128: filtBal[num] = mwc->filtBal[num]->value(); break; - case 129: filtSatu[num] = mwc->filtSatu[num]->value(); break; - case 130: filtFeedback[num] = mwc->filtFeedback[num]->value(); break; - case 131: filtDetune[num] = mwc->filtDetune[num]->value(); break; - case 132: filtEnabled[num] = mwc->filtEnabled[num]->value(); break; - case 133: filtMuted[num] = mwc->filtMuted[num]->value(); break; - case 134: filtKeytracking[num] = mwc->filtKeytracking[num]->value(); break; - - case 150: macro[num] = mwc->macro[num]->value(); break; + case 1: m_morph[num] = m_mwc->m_morph[num]->value(); break; + case 2: m_range[num] = m_mwc->m_range[num]->value(); break; + case 3: m_modify[num] = m_mwc->m_modify[num]->value(); break; + case 4: m_modifyMode[num] = m_mwc->m_modifyMode[num]->value(); break; + case 5: m_vol[num] = m_mwc->m_vol[num]->value(); break; + case 6: m_pan[num] = m_mwc->m_pan[num]->value(); break; + case 7: m_detune[num] = m_mwc->m_detune[num]->value(); break; + case 8: m_phase[num] = m_mwc->m_phase[num]->value(); break; + case 9: m_phaseRand[num] = m_mwc->m_phaseRand[num]->value(); break; + case 10: m_enabled[num] = m_mwc->m_enabled[num]->value(); break; + case 11: m_muted[num] = m_mwc->m_muted[num]->value(); break; + case 12: m_sampLen[num] = m_mwc->m_sampLen[num]->value(); break; + case 13: m_morphMax[num] = m_mwc->m_morphMax[num]->value(); break; + case 14: m_unisonVoices[num] = m_mwc->m_unisonVoices[num]->value(); break; + case 15: m_unisonDetune[num] = m_mwc->m_unisonDetune[num]->value(); break; + case 16: m_unisonMorph[num] = m_mwc->m_unisonMorph[num]->value(); break; + case 17: m_unisonModify[num] = m_mwc->m_unisonModify[num]->value(); break; + case 18: m_keytracking[num] = m_mwc->m_keytracking[num]->value(); break; + case 19: m_tempo[num] = m_mwc->m_tempo[num]->value(); break; + case 20: m_interpolate[num] = m_mwc->m_interpolate[num]->value(); break; + + case 30: m_subEnabled[num] = m_mwc->m_subEnabled[num]->value(); break; + case 31: m_subMuted[num] = m_mwc->m_subMuted[num]->value(); break; + case 32: m_subKeytrack[num] = m_mwc->m_subKeytrack[num]->value(); break; + case 33: m_subNoise[num] = m_mwc->m_subNoise[num]->value(); break; + case 34: m_subVol[num] = m_mwc->m_subVol[num]->value(); break; + case 35: m_subPanning[num] = m_mwc->m_subPanning[num]->value(); break; + case 36: m_subDetune[num] = m_mwc->m_subDetune[num]->value(); break; + case 37: m_subPhase[num] = m_mwc->m_subPhase[num]->value(); break; + case 38: m_subPhaseRand[num] = m_mwc->m_subPhaseRand[num]->value(); break; + case 39: m_subSampLen[num] = m_mwc->m_subSampLen[num]->value(); break; + case 40: m_subTempo[num] = m_mwc->m_subTempo[num]->value(); break; + case 41: m_subRateLimit[num] = m_mwc->m_subRateLimit[num]->value(); break; + case 42: m_subUnisonNum[num] = m_mwc->m_subUnisonNum[num]->value(); break; + case 43: m_subUnisonDetune[num] = m_mwc->m_subUnisonDetune[num]->value(); break; + case 44: m_subInterpolate[num] = m_mwc->m_subInterpolate[num]->value(); break; + + case 60: m_sampleEnabled[num] = m_mwc->m_sampleEnabled[num]->value(); break; + case 61: m_sampleMuted[num] = m_mwc->m_sampleMuted[num]->value(); break; + case 62: m_sampleKeytracking[num] = m_mwc->m_sampleKeytracking[num]->value(); break; + case 63: m_sampleGraphEnabled[num] = m_mwc->m_sampleGraphEnabled[num]->value(); break; + case 64: m_sampleLoop[num] = m_mwc->m_sampleLoop[num]->value(); break; + case 65: m_sampleVolume[num] = m_mwc->m_sampleVolume[num]->value(); break; + case 66: m_samplePanning[num] = m_mwc->m_samplePanning[num]->value(); break; + case 67: m_sampleDetune[num] = m_mwc->m_sampleDetune[num]->value(); break; + case 68: m_samplePhase[num] = m_mwc->m_samplePhase[num]->value(); break; + case 69: m_samplePhaseRand[num] = m_mwc->m_samplePhaseRand[num]->value(); break; + case 70: m_sampleStart[num] = m_mwc->m_sampleStart[num]->value(); break; + case 71: m_sampleEnd[num] = m_mwc->m_sampleEnd[num]->value(); break; + + case 90: m_modIn[num] = m_mwc->m_modIn[num]->value(); break; + case 91: m_modInNum[num] = m_mwc->m_modInNum[num]->value(); break; + case 92: m_modInAmnt[num] = m_mwc->m_modInAmnt[num]->value(); break; + case 93: m_modInCurve[num] = m_mwc->m_modInCurve[num]->value(); break; + case 94: m_modIn2[num] = m_mwc->m_modIn2[num]->value(); break; + case 95: m_modInNum2[num] = m_mwc->m_modInNum2[num]->value(); break; + case 96: m_modInAmnt2[num] = m_mwc->m_modInAmnt2[num]->value(); break; + case 97: m_modInCurve2[num] = m_mwc->m_modInCurve2[num]->value(); break; + case 98: m_modOutSec[num] = m_mwc->m_modOutSec[num]->value(); break; + case 99: m_modOutSig[num] = m_mwc->m_modOutSig[num]->value(); break; + case 100: m_modOutSecNum[num] = m_mwc->m_modOutSecNum[num]->value(); break; + case 101: m_modEnabled[num] = m_mwc->m_modEnabled[num]->value(); break; + case 102: m_modCombineType[num] = m_mwc->m_modCombineType[num]->value(); break; + case 103: m_modType[num] = m_mwc->m_modType[num]->value(); break; + case 104: m_modType2[num] = m_mwc->m_modType2[num]->value(); break; + + case 120: m_filtCutoff[num] = m_mwc->m_filtCutoff[num]->value(); break; + case 121: m_filtReso[num] = m_mwc->m_filtReso[num]->value(); break; + case 122: m_filtGain[num] = m_mwc->m_filtGain[num]->value(); break; + case 123: m_filtType[num] = m_mwc->m_filtType[num]->value(); break; + case 124: m_filtSlope[num] = m_mwc->m_filtSlope[num]->value(); break; + case 125: m_filtInVol[num] = m_mwc->m_filtInVol[num]->value(); break; + case 126: m_filtOutVol[num] = m_mwc->m_filtOutVol[num]->value(); break; + case 127: m_filtWetDry[num] = m_mwc->m_filtWetDry[num]->value(); break; + case 128: m_filtBal[num] = m_mwc->m_filtBal[num]->value(); break; + case 129: m_filtSatu[num] = m_mwc->m_filtSatu[num]->value(); break; + case 130: m_filtFeedback[num] = m_mwc->m_filtFeedback[num]->value(); break; + case 131: m_filtDetune[num] = m_mwc->m_filtDetune[num]->value(); break; + case 132: m_filtEnabled[num] = m_mwc->m_filtEnabled[num]->value(); break; + case 133: m_filtMuted[num] = m_mwc->m_filtMuted[num]->value(); break; + case 134: m_filtKeytracking[num] = m_mwc->m_filtKeytracking[num]->value(); break; + + case 150: m_macro[num] = m_mwc->m_macro[num]->value(); break; } } // Handles negative values properly, unlike fmod. -inline float mSynth::realfmod( float k, float n ) +inline float mSynth::realfmod(float k, float n) { return ((k = fmod(k,n)) < 0) ? k+n : k; } @@ -5956,14 +6019,14 @@ QString MicrowaveManualView::s_manualText= ; -MicrowaveManualView::MicrowaveManualView():QTextEdit( s_manualText ) +MicrowaveManualView::MicrowaveManualView():QTextEdit(s_manualText) { - setWindowTitle ( "Microwave Manual" ); - setTextInteractionFlags ( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse ); - gui->mainWindow()->addWindowedWidget( this ); - parentWidget()->setAttribute( Qt::WA_DeleteOnClose, false ); - parentWidget()->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) ); - parentWidget()->resize( 640, 480 ); + setWindowTitle ("Microwave Manual"); + setTextInteractionFlags (Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse); + gui->mainWindow()->addWindowedWidget(this); + parentWidget()->setAttribute(Qt::WA_DeleteOnClose, false); + parentWidget()->setWindowIcon(PLUGIN_NAME::getIconPixmap("logo")); + parentWidget()->resize(640, 480); } @@ -5975,113 +6038,113 @@ void MicrowaveView::manualBtnClicked() -void MicrowaveKnob::setMatrixLocation( int loc1, int loc2, int loc3 ) +void MicrowaveKnob::setMatrixLocation(int loc1, int loc2, int loc3) { - matrixLocation[0] = loc1; - matrixLocation[1] = loc2; - matrixLocation[2] = loc3; + m_matrixLocation[0] = loc1; + m_matrixLocation[1] = loc2; + m_matrixLocation[2] = loc3; disconnect(this, &MicrowaveKnob::sendToMatrixAsOutput, 0, 0); - connect( this, &MicrowaveKnob::sendToMatrixAsOutput, this, [this, loc1, loc2, loc3]() { knobView->sendToMatrixAsOutput( loc1, loc2, loc3 ); } ); + connect(this, &MicrowaveKnob::sendToMatrixAsOutput, this, [this, loc1, loc2, loc3]() { m_knobView->sendToMatrixAsOutput(loc1, loc2, loc3); }); disconnect(this, &MicrowaveKnob::switchToMatrixKnob, 0, 0); - connect( this, &MicrowaveKnob::switchToMatrixKnob, this, [this, loc1, loc2, loc3]() { knobView->switchToMatrixKnob( this, loc1, loc2, loc3 ); } ); + connect(this, &MicrowaveKnob::switchToMatrixKnob, this, [this, loc1, loc2, loc3]() { m_knobView->switchToMatrixKnob(this, loc1, loc2, loc3); }); } -void MicrowaveKnob::setWhichMacroKnob( int which ) +void MicrowaveKnob::setWhichMacroKnob(int which) { - this->whichMacroKnob = which; + this->m_whichMacroKnob = which; disconnect(this, &MicrowaveKnob::setMacroTooltip, 0, 0); disconnect(this, &MicrowaveKnob::chooseMacroColor, 0, 0); disconnect(this, &MicrowaveKnob::refreshMacroColor, 0, 0); disconnect(this, &MicrowaveKnob::setMacroColortoDefault, 0, 0); - if( which != -1 ) + if (which != -1) { - connect( this, &MicrowaveKnob::setMacroTooltip, this, [this, which]() { knobView->setMacroTooltip( this, which ); } ); - connect( this, &MicrowaveKnob::chooseMacroColor, this, [this, which]() { knobView->chooseMacroColor( this, which ); } ); - connect( this, &MicrowaveKnob::refreshMacroColor, this, [this, which]() { knobView->refreshMacroColor( this, which ); } ); - connect( this, &MicrowaveKnob::setMacroColortoDefault, this, [this, which]() { knobView->setMacroColortoDefault( this, which ); } ); + connect(this, &MicrowaveKnob::setMacroTooltip, this, [this, which]() { m_knobView->setMacroTooltip(this, which); }); + connect(this, &MicrowaveKnob::chooseMacroColor, this, [this, which]() { m_knobView->chooseMacroColor(this, which); }); + connect(this, &MicrowaveKnob::refreshMacroColor, this, [this, which]() { m_knobView->refreshMacroColor(this, which); }); + connect(this, &MicrowaveKnob::setMacroColortoDefault, this, [this, which]() { m_knobView->setMacroColortoDefault(this, which); }); } } -void MicrowaveKnob::contextMenuEvent( QContextMenuEvent * ) +void MicrowaveKnob::contextMenuEvent(QContextMenuEvent *) { // for the case, the user clicked right while pressing left mouse- // button, the context-menu appears while mouse-cursor is still hidden // and it isn't shown again until user does something which causes // an QApplication::restoreOverrideCursor()-call... - mouseReleaseEvent( NULL ); + mouseReleaseEvent(NULL); - CaptionMenu contextMenu( model()->displayName(), this ); - addDefaultActions( &contextMenu ); - contextMenu.addAction( QPixmap(), model()->isScaleLogarithmic() ? tr( "Set linear" ) : tr( "Set logarithmic" ), this, SLOT( toggleScale() ) ); + CaptionMenu contextMenu(model()->displayName(), this); + addDefaultActions(&contextMenu); + contextMenu.addAction(QPixmap(), model()->isScaleLogarithmic() ? tr("Set linear") : tr("Set logarithmic"), this, SLOT(toggleScale())); contextMenu.addSeparator(); - if( this->matrixLocation[0] ) + if (this->m_matrixLocation[0]) { - contextMenu.addAction( PLUGIN_NAME::getIconPixmap( "tab4" ), tr( "Control this in Matrix" ), this, SIGNAL( sendToMatrixAsOutput() ) ); + contextMenu.addAction(PLUGIN_NAME::getIconPixmap("tab4"), tr("Control this in Matrix"), this, SIGNAL(sendToMatrixAsOutput())); } - if( this->whichMacroKnob != -1 ) + if (this->m_whichMacroKnob != -1) { - contextMenu.addAction( PLUGIN_NAME::getIconPixmap( "tab4" ), tr( "Set Macro Tooltip" ), this, SIGNAL( setMacroTooltip() ) ); - contextMenu.addAction( embed::getIconPixmap( "colorize" ), tr( "Set Knob Color" ), this, SIGNAL( chooseMacroColor() ) ); - contextMenu.addAction( embed::getIconPixmap( "colorize" ), tr( "Set Knob Color To Default" ), this, SIGNAL( setMacroColortoDefault() ) ); + contextMenu.addAction(PLUGIN_NAME::getIconPixmap("tab4"), tr("Set Macro Tooltip"), this, SIGNAL(setMacroTooltip())); + contextMenu.addAction(embed::getIconPixmap("colorize"), tr("Set Knob Color"), this, SIGNAL(chooseMacroColor())); + contextMenu.addAction(embed::getIconPixmap("colorize"), tr("Set Knob Color To Default"), this, SIGNAL(setMacroColortoDefault())); } contextMenu.addSeparator(); - contextMenu.exec( QCursor::pos() ); + contextMenu.exec(QCursor::pos()); } -void MicrowaveKnob::mousePressEvent( QMouseEvent * _me ) +void MicrowaveKnob::mousePressEvent(QMouseEvent * me) { - if( ( _me->button() == Qt::LeftButton && gui->mainWindow()->isAltPressed() ) || _me->button() == Qt::MidButton ) + if ((me->button() == Qt::LeftButton && gui->mainWindow()->isAltPressed()) || me->button() == Qt::MidButton) { - if( matrixLocation[0] ) + if (m_matrixLocation[0]) { switchToMatrixKnob(); } AutomatableModel *thisModel = model(); - if( thisModel ) + if (thisModel) { thisModel->addJournalCheckPoint(); - thisModel->saveJournallingState( false ); + thisModel->saveJournallingState(false); } - const QPoint & p = _me->pos(); + const QPoint & p = me->pos(); m_origMousePos = p; m_mouseOffset = QPoint(0, 0); m_leftOver = 0.0f; emit sliderPressed(); - QApplication::setOverrideCursor( Qt::BlankCursor ); - s_textFloat->setText( displayValue() ); - s_textFloat->moveGlobal( this, QPoint( width() + 2, 0 ) ); + QApplication::setOverrideCursor(Qt::BlankCursor); + s_textFloat->setText(displayValue()); + s_textFloat->moveGlobal(this, QPoint(width() + 2, 0)); s_textFloat->show(); m_buttonPressed = true; } else { - Knob::mousePressEvent( _me ); + Knob::mousePressEvent(me); } } -void MicrowaveKnob::mouseReleaseEvent( QMouseEvent * _me ) +void MicrowaveKnob::mouseReleaseEvent(QMouseEvent * me) { - Knob::mouseReleaseEvent( _me ); + Knob::mouseReleaseEvent(me); updateScroll(); - if( this->whichMacroKnob == -1 ) + if (this->m_whichMacroKnob == -1) { - this->setarcColor( QColor(46,74,80) ); - this->setlineColor( QColor(102,198,199) ); - this->setInnerColor( QColor(64,92,97) ); + this->setarcColor(QColor(46,74,80)); + this->setlineColor(QColor(102,198,199)); + this->setInnerColor(QColor(64,92,97)); } else { @@ -6095,9 +6158,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) +PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *m, void *) { - return( new Microwave( static_cast( m ) ) ); + return new Microwave(static_cast(m)); } diff --git a/plugins/Microwave/Microwave.h b/plugins/Microwave/Microwave.h index e29f0ce994a..fdf5e6b35fd 100644 --- a/plugins/Microwave/Microwave.h +++ b/plugins/Microwave/Microwave.h @@ -48,231 +48,231 @@ // Macros, mostly for comboboxes but also a few other things -#define setwavemodel( name )\ +#define setwavemodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Pulse Width" ), make_unique( "sin" ) );\ - name->addItem( tr( "Weird 1" ), make_unique( "noise" ) );\ - name->addItem( tr( "Weird 2" ), make_unique( "noise" ) );\ - name->addItem( tr( "Asym To Right" ), make_unique( "saw" ) );\ - name->addItem( tr( "Asym To Left" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Bidirectional Asym" ), make_unique( "tri" ) );\ - name->addItem( tr( "Squish To Center" ), make_unique( "exp" ) );\ - name->addItem( tr( "Stretch From Center" ), make_unique( "sinabs" ) );\ - name->addItem( tr( "Stretch And Squish" ), make_unique( "tri" ) );\ - name->addItem( tr( "Cut Off Right" ), make_unique( "saw" ) );\ - name->addItem( tr( "Cut Off Left" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Squarify" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Pulsify" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Flip" ), make_unique( "tri" ) );\ - name->addItem( tr( "Clip" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Inverse Clip" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Sine" ), make_unique( "sin" ) );\ - name->addItem( tr( "Atan" ), make_unique( "tri" ) );\ - name->addItem( tr( "Sync" ), make_unique( "saw" ) );\ - name->addItem( tr( "Sync Half Interpolate" ), make_unique( "saw" ) );\ - name->addItem( tr( "Sync Interpolate" ), make_unique( "saw" ) );\ - name->addItem( tr( "Mirror" ), make_unique( "sinabs" ) );\ - name->addItem( tr( "Diagonal Morph" ), make_unique( "saw" ) );\ - name->addItem( tr( "Sideways Morph" ), make_unique( "saw" ) ); - -#define modinmodel( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Pulse Width"), make_unique("sin"));\ + name->addItem(tr("Weird 1"), make_unique("noise"));\ + name->addItem(tr("Weird 2"), make_unique("noise"));\ + name->addItem(tr("Asym To Right"), make_unique("saw"));\ + name->addItem(tr("Asym To Left"), make_unique("ramp"));\ + name->addItem(tr("Bidirectional Asym"), make_unique("tri"));\ + name->addItem(tr("Squish To Center"), make_unique("exp"));\ + name->addItem(tr("Stretch From Center"), make_unique("sinabs"));\ + name->addItem(tr("Stretch And Squish"), make_unique("tri"));\ + name->addItem(tr("Cut Off Right"), make_unique("saw"));\ + name->addItem(tr("Cut Off Left"), make_unique("ramp"));\ + name->addItem(tr("Squarify"), make_unique("sqr"));\ + name->addItem(tr("Pulsify"), make_unique("sqr"));\ + name->addItem(tr("Flip"), make_unique("tri"));\ + name->addItem(tr("Clip"), make_unique("sqr"));\ + name->addItem(tr("Inverse Clip"), make_unique("sqr"));\ + name->addItem(tr("Sine"), make_unique("sin"));\ + name->addItem(tr("Atan"), make_unique("tri"));\ + name->addItem(tr("Sync"), make_unique("saw"));\ + name->addItem(tr("Sync Half Interpolate"), make_unique("saw"));\ + name->addItem(tr("Sync Interpolate"), make_unique("saw"));\ + name->addItem(tr("Mirror"), make_unique("sinabs"));\ + name->addItem(tr("Diagonal Morph"), make_unique("saw"));\ + name->addItem(tr("Sideways Morph"), make_unique("saw")); + +#define modinmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Main OSC" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Sub OSC" ), make_unique( "sin" ) );\ - name->addItem( tr( "Sample OSC" ), make_unique( "noise" ) );\ - name->addItem( tr( "Filter Output" ), make_unique( "moog" ) );\ - name->addItem( tr( "Velocity" ), make_unique( "letter_v" ) );\ - name->addItem( tr( "Panning" ), make_unique( "letter_p" ) );\ - name->addItem( tr( "Humanizer" ), make_unique( "letter_h" ) );\ - name->addItem( tr( "Macro" ), make_unique( "letter_m" ) ); - -#define modsectionsmodel( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Main OSC"), make_unique("sqr"));\ + name->addItem(tr("Sub OSC"), make_unique("sin"));\ + name->addItem(tr("Sample OSC"), make_unique("noise"));\ + name->addItem(tr("Filter Output"), make_unique("moog"));\ + name->addItem(tr("Velocity"), make_unique("letter_v"));\ + name->addItem(tr("Panning"), make_unique("letter_p"));\ + name->addItem(tr("Humanizer"), make_unique("letter_h"));\ + name->addItem(tr("Macro"), make_unique("letter_m")); + +#define modsectionsmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Main OSC" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Sub OSC" ), make_unique( "sin" ) );\ - name->addItem( tr( "Sample OSC" ), make_unique( "noise" ) );\ - name->addItem( tr( "Matrix" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Filter Input" ), make_unique( "moog" ) );\ - name->addItem( tr( "Filter Parameters" ), make_unique( "letter_f" ) );\ - name->addItem( tr( "Macro" ), make_unique( "letter_m" ) ); - -#define mainoscsignalsmodel( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Main OSC"), make_unique("sqr"));\ + name->addItem(tr("Sub OSC"), make_unique("sin"));\ + name->addItem(tr("Sample OSC"), make_unique("noise"));\ + name->addItem(tr("Matrix"), make_unique("ramp"));\ + name->addItem(tr("Filter Input"), make_unique("moog"));\ + name->addItem(tr("Filter Parameters"), make_unique("letter_f"));\ + name->addItem(tr("Macro"), make_unique("letter_m")); + +#define mainoscsignalsmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Morph" ), make_unique( "tri" ) );\ - name->addItem( tr( "Range" ), make_unique( "sqr" ) );\ - name->addItem( tr( "Modify" ), make_unique( "moog" ) );\ - name->addItem( tr( "Detune" ), make_unique( "saw" ) );\ - name->addItem( tr( "Phase" ), make_unique( "sin" ) );\ - name->addItem( tr( "Volume" ), make_unique( "letter_v" ) );\ - name->addItem( tr( "Panning" ), make_unique( "letter_p" ) );\ - name->addItem( tr( "Unison Number" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Unison Detune" ), make_unique( "saw" ) );\ - name->addItem( tr( "Unison Morph" ), make_unique( "tri" ) );\ - name->addItem( tr( "Unison Modify" ), make_unique( "moog" ) ); - -#define subsignalsmodel( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Morph"), make_unique("tri"));\ + name->addItem(tr("Range"), make_unique("sqr"));\ + name->addItem(tr("Modify"), make_unique("moog"));\ + name->addItem(tr("Detune"), make_unique("saw"));\ + name->addItem(tr("Phase"), make_unique("sin"));\ + name->addItem(tr("Volume"), make_unique("letter_v"));\ + name->addItem(tr("Panning"), make_unique("letter_p"));\ + name->addItem(tr("Unison Number"), make_unique("ramp"));\ + name->addItem(tr("Unison Detune"), make_unique("saw"));\ + name->addItem(tr("Unison Morph"), make_unique("tri"));\ + name->addItem(tr("Unison Modify"), make_unique("moog")); + +#define subsignalsmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Detune" ), make_unique( "saw" ) );\ - name->addItem( tr( "Phase" ), make_unique( "sin" ) );\ - name->addItem( tr( "Volume" ), make_unique( "letter_v" ) );\ - name->addItem( tr( "Panning" ), make_unique( "letter_p" ) );\ - name->addItem( tr( "Length" ), make_unique( "letter_l" ) );\ - name->addItem( tr( "Rate Limit" ), make_unique( "letter_r" ) );\ - name->addItem( tr( "Unison Voice Number" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Unison Detune" ), make_unique( "saw" ) ); - -#define samplesignalsmodel( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Detune"), make_unique("saw"));\ + name->addItem(tr("Phase"), make_unique("sin"));\ + name->addItem(tr("Volume"), make_unique("letter_v"));\ + name->addItem(tr("Panning"), make_unique("letter_p"));\ + name->addItem(tr("Length"), make_unique("letter_l"));\ + name->addItem(tr("Rate Limit"), make_unique("letter_r"));\ + name->addItem(tr("Unison Voice Number"), make_unique("ramp"));\ + name->addItem(tr("Unison Detune"), make_unique("saw")); + +#define samplesignalsmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Detune" ), make_unique( "saw" ) );\ - name->addItem( tr( "Phase" ), make_unique( "sin" ) );\ - name->addItem( tr( "Volume" ), make_unique( "letter_v" ) );\ - name->addItem( tr( "Panning" ), make_unique( "letter_p" ) ); + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Detune"), make_unique("saw"));\ + name->addItem(tr("Phase"), make_unique("sin"));\ + name->addItem(tr("Volume"), make_unique("letter_v"));\ + name->addItem(tr("Panning"), make_unique("letter_p")); -#define matrixsignalsmodel( name )\ +#define matrixsignalsmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Amount" ), make_unique( "letter_a" ) );\ - name->addItem( tr( "Curve" ), make_unique( "letter_c" ) );\ - name->addItem( tr( "Secondary Amount" ), make_unique( "letter_a" ) );\ - name->addItem( tr( "Secondary Curve" ), make_unique( "letter_c" ) );\ - name->addItem( tr( "Input Section" ), make_unique( "letter_i" ) );\ - name->addItem( tr( "Input Number" ), make_unique( "letter_i" ) );\ - name->addItem( tr( "Secondary Input Section" ), make_unique( "letter_i" ) );\ - name->addItem( tr( "Secondary Input Number" ), make_unique( "letter_i" ) );\ - name->addItem( tr( "Output Section 1" ), make_unique( "letter_o" ) );\ - name->addItem( tr( "Output Section 2" ), make_unique( "letter_o" ) );\ - name->addItem( tr( "Output Section Number" ), make_unique( "letter_o" ) );\ - -#define filtersignalsmodel( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Amount"), make_unique("letter_a"));\ + name->addItem(tr("Curve"), make_unique("letter_c"));\ + name->addItem(tr("Secondary Amount"), make_unique("letter_a"));\ + name->addItem(tr("Secondary Curve"), make_unique("letter_c"));\ + name->addItem(tr("Input Section"), make_unique("letter_i"));\ + name->addItem(tr("Input Number"), make_unique("letter_i"));\ + name->addItem(tr("Secondary Input Section"), make_unique("letter_i"));\ + name->addItem(tr("Secondary Input Number"), make_unique("letter_i"));\ + name->addItem(tr("Output Section 1"), make_unique("letter_o"));\ + name->addItem(tr("Output Section 2"), make_unique("letter_o"));\ + name->addItem(tr("Output Section Number"), make_unique("letter_o"));\ + +#define filtersignalsmodel(name)\ name->clear();\ - name->addItem( tr( "None" ), make_unique( "none" ) );\ - name->addItem( tr( "Cutoff Frequency" ), make_unique( "moog" ) );\ - name->addItem( tr( "Resonance" ), make_unique( "ramp" ) );\ - name->addItem( tr( "db Gain" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Filter Type" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Slope" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Input Volume" ), make_unique( "sin" ) );\ - name->addItem( tr( "Output Volume" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Wet/Dry" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Balance/Panning" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Saturation" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Feedback" ), make_unique( "ramp" ) );\ - name->addItem( tr( "Detune" ), make_unique( "ramp" ) ); - -#define mod8model( name )\ + name->addItem(tr("None"), make_unique("none"));\ + name->addItem(tr("Cutoff Frequency"), make_unique("moog"));\ + name->addItem(tr("Resonance"), make_unique("ramp"));\ + name->addItem(tr("db Gain"), make_unique("ramp"));\ + name->addItem(tr("Filter Type"), make_unique("ramp"));\ + name->addItem(tr("Slope"), make_unique("ramp"));\ + name->addItem(tr("Input Volume"), make_unique("sin"));\ + name->addItem(tr("Output Volume"), make_unique("ramp"));\ + name->addItem(tr("Wet/Dry"), make_unique("ramp"));\ + name->addItem(tr("Balance/Panning"), make_unique("ramp"));\ + name->addItem(tr("Saturation"), make_unique("ramp"));\ + name->addItem(tr("Feedback"), make_unique("ramp"));\ + name->addItem(tr("Detune"), make_unique("ramp")); + +#define mod8model(name)\ name->clear();\ - name->addItem( tr( "1" ), make_unique( "number_1" ) );\ - name->addItem( tr( "2" ), make_unique( "number_2" ) );\ - name->addItem( tr( "3" ), make_unique( "number_3" ) );\ - name->addItem( tr( "4" ), make_unique( "number_4" ) );\ - name->addItem( tr( "5" ), make_unique( "number_5" ) );\ - name->addItem( tr( "6" ), make_unique( "number_6" ) );\ - name->addItem( tr( "7" ), make_unique( "number_7" ) );\ - name->addItem( tr( "8" ), make_unique( "number_8" ) ); - -#define matrixoutmodel( name )\ + name->addItem(tr("1"), make_unique("number_1"));\ + name->addItem(tr("2"), make_unique("number_2"));\ + name->addItem(tr("3"), make_unique("number_3"));\ + name->addItem(tr("4"), make_unique("number_4"));\ + name->addItem(tr("5"), make_unique("number_5"));\ + name->addItem(tr("6"), make_unique("number_6"));\ + name->addItem(tr("7"), make_unique("number_7"));\ + name->addItem(tr("8"), make_unique("number_8")); + +#define matrixoutmodel(name)\ name->clear();\ - name->addItem( tr( "1" ) );\ - name->addItem( tr( "2" ) );\ - name->addItem( tr( "3" ) );\ - name->addItem( tr( "4" ) );\ - name->addItem( tr( "5" ) );\ - name->addItem( tr( "6" ) );\ - name->addItem( tr( "7" ) );\ - name->addItem( tr( "8" ) );\ - name->addItem( tr( "9" ) );\ - name->addItem( tr( "10" ) );\ - name->addItem( tr( "11" ) );\ - name->addItem( tr( "12" ) );\ - name->addItem( tr( "13" ) );\ - name->addItem( tr( "14" ) );\ - name->addItem( tr( "15" ) );\ - name->addItem( tr( "16" ) );\ - name->addItem( tr( "17" ) );\ - name->addItem( tr( "18" ) ); - -#define filtertypesmodel( name )\ + name->addItem(tr("1"));\ + name->addItem(tr("2"));\ + name->addItem(tr("3"));\ + name->addItem(tr("4"));\ + name->addItem(tr("5"));\ + name->addItem(tr("6"));\ + name->addItem(tr("7"));\ + name->addItem(tr("8"));\ + name->addItem(tr("9"));\ + name->addItem(tr("10"));\ + name->addItem(tr("11"));\ + name->addItem(tr("12"));\ + name->addItem(tr("13"));\ + name->addItem(tr("14"));\ + name->addItem(tr("15"));\ + name->addItem(tr("16"));\ + name->addItem(tr("17"));\ + name->addItem(tr("18")); + +#define filtertypesmodel(name)\ name->clear();\ - name->addItem( tr( "Lowpass" ), make_unique( "filter_lowpass" ) );\ - name->addItem( tr( "Highpass" ), make_unique( "filter_highpass" ) );\ - name->addItem( tr( "Bandpass" ), make_unique( "filter_bandpass" ) );\ - name->addItem( tr( "Low Shelf" ), make_unique( "filter_lowshelf" ) );\ - name->addItem( tr( "High Shelf" ), make_unique( "filter_highshelf" ) );\ - name->addItem( tr( "Peak" ), make_unique( "filter_peak" ) );\ - name->addItem( tr( "Notch" ), make_unique( "filter_notch" ) );\ - name->addItem( tr( "Allpass" ), make_unique( "filter_allpass" ) );\ - name->addItem( tr( "Moog Lowpass (Note: Slope is double)" ), make_unique( "filter_moog" ) ); - -#define filterslopesmodel( name )\ + name->addItem(tr("Lowpass"), make_unique("filter_lowpass"));\ + name->addItem(tr("Highpass"), make_unique("filter_highpass"));\ + name->addItem(tr("Bandpass"), make_unique("filter_bandpass"));\ + name->addItem(tr("Low Shelf"), make_unique("filter_lowshelf"));\ + name->addItem(tr("High Shelf"), make_unique("filter_highshelf"));\ + name->addItem(tr("Peak"), make_unique("filter_peak"));\ + name->addItem(tr("Notch"), make_unique("filter_notch"));\ + name->addItem(tr("Allpass"), make_unique("filter_allpass"));\ + name->addItem(tr("Moog Lowpass (Note: Slope is double)"), make_unique("filter_moog")); + +#define filterslopesmodel(name)\ name->clear();\ - name->addItem( tr( "12 db" ), make_unique( "number_1" ) );\ - name->addItem( tr( "24 db" ), make_unique( "number_2" ) );\ - name->addItem( tr( "36 db" ), make_unique( "number_3" ) );\ - name->addItem( tr( "48 db" ), make_unique( "number_4" ) );\ - name->addItem( tr( "60 db" ), make_unique( "number_5" ) );\ - name->addItem( tr( "72 db" ), make_unique( "number_6" ) );\ - name->addItem( tr( "84 db" ), make_unique( "number_7" ) );\ - name->addItem( tr( "96 db" ), make_unique( "number_8" ) ); - -#define modcombinetypemodel( name )\ + name->addItem(tr("12 db"), make_unique("number_1"));\ + name->addItem(tr("24 db"), make_unique("number_2"));\ + name->addItem(tr("36 db"), make_unique("number_3"));\ + name->addItem(tr("48 db"), make_unique("number_4"));\ + name->addItem(tr("60 db"), make_unique("number_5"));\ + name->addItem(tr("72 db"), make_unique("number_6"));\ + name->addItem(tr("84 db"), make_unique("number_7"));\ + name->addItem(tr("96 db"), make_unique("number_8")); + +#define modcombinetypemodel(name)\ name->clear();\ - name->addItem( tr( "Add Bidirectional" ), make_unique( "number_1" ) );\ - name->addItem( tr( "Multiply Bidirectional" ), make_unique( "number_2" ) );\ - name->addItem( tr( "Add Unidirectional" ), make_unique( "number_3" ) );\ - name->addItem( tr( "Multiply Unidirectional" ), make_unique( "number_4" ) ); + name->addItem(tr("Add Bidirectional"), make_unique("number_1"));\ + name->addItem(tr("Multiply Bidirectional"), make_unique("number_2"));\ + name->addItem(tr("Add Unidirectional"), make_unique("number_3"));\ + name->addItem(tr("Multiply Unidirectional"), make_unique("number_4")); -#define oversamplemodel( name )\ +#define oversamplemodel(name)\ name.clear();\ - name.addItem( tr( "1x" ), make_unique( "number_1" ) );\ - name.addItem( tr( "2x" ), make_unique( "number_2" ) );\ - name.addItem( tr( "3x" ), make_unique( "number_3" ) );\ - name.addItem( tr( "4x" ), make_unique( "number_4" ) );\ - name.addItem( tr( "5x" ), make_unique( "number_5" ) );\ - name.addItem( tr( "6x" ), make_unique( "number_6" ) );\ - name.addItem( tr( "7x" ), make_unique( "number_7" ) );\ - name.addItem( tr( "8x" ), make_unique( "number_8" ) ); - -#define loadmodemodel( name )\ + name.addItem(tr("1x"), make_unique("number_1"));\ + name.addItem(tr("2x"), make_unique("number_2"));\ + name.addItem(tr("3x"), make_unique("number_3"));\ + name.addItem(tr("4x"), make_unique("number_4"));\ + name.addItem(tr("5x"), make_unique("number_5"));\ + name.addItem(tr("6x"), make_unique("number_6"));\ + name.addItem(tr("7x"), make_unique("number_7"));\ + name.addItem(tr("8x"), make_unique("number_8")); + +#define loadmodemodel(name)\ name.clear();\ - name.addItem( tr( "Lock waveform edges to zero crossings" ) );\ - name.addItem( tr( "Load sample without changes" ) );\ - name.addItem( tr( "Load wavetable file" ) );\ - name.addItem( tr( "Autocorrelation (static pitch detection)" ) ); + name.addItem(tr("Lock waveform edges to zero crossings"));\ + name.addItem(tr("Load sample without changes"));\ + name.addItem(tr("Load wavetable file"));\ + name.addItem(tr("Autocorrelation (static pitch detection)")); -#define oversamplemodemodel( name )\ +#define oversamplemodemodel(name)\ name.clear();\ - name.addItem( tr( "Decimate" ), make_unique( "number_1" ) );\ - name.addItem( tr( "Average" ), make_unique( "number_2" ) ); + name.addItem(tr("Decimate"), make_unique("number_1"));\ + name.addItem(tr("Average"), make_unique("number_2")); -#define visimove( name, x, y )\ - if( x >= 0 && x <= 250 )\ +#define visimove(name, x, y)\ + if (x >= 0 && x <= 250)\ {\ - name->move( x, y );\ - name->setVisible( true );\ + name->move(x, y);\ + name->setVisible(true);\ }\ else\ {\ - name->move( 0, 0 );\ - name->setVisible( false );\ + name->move(0, 0);\ + name->setVisible(false);\ } // Create the knob, set its tooltip, set its default color -#define makeknob( name, knobtype, hint, tooltip )\ - name = new MicrowaveKnob( knobtype, this );\ - name->setHintText( hint, "" );\ - ToolTip::add( name, tooltip );\ - name->knobView = this;\ - name->setarcColor( QColor(46,74,80) );\ - name->setlineColor( QColor(102,198,199) );\ - name->setInnerColor( QColor(64,92,97) );\ - connect( name, &MicrowaveKnob::updateScroll, this, &MicrowaveView::updateScroll ); +#define makeknob(name, knobtype, hint, tooltip)\ + name = new MicrowaveKnob(knobtype, this);\ + name->setHintText(hint, "");\ + ToolTip::add(name, tooltip);\ + name->m_knobView = this;\ + name->setarcColor(QColor(46,74,80));\ + name->setlineColor(QColor(102,198,199));\ + name->setInnerColor(QColor(64,92,97));\ + connect(name, &MicrowaveKnob::updateScroll, this, &MicrowaveView::updateScroll); // Constant variables for use in many situations. Strongly related to srccpy stuff. @@ -283,7 +283,7 @@ const int STOREDMAINWAVELEN = 2048; // WAVERATIO is how much larger (multiplication) the waveforms are after interpolation. // I'd like to increase this, but I will not until project saving/loading is sped up in LMMS, since this increases that drastically. // I would prefer it to be 8, maybe even 16. -// This number divided by 2 is the number of megabytes of RAM each wavetable will use up. +// This number divided by 4 is the number of megabytes of RAM each wavetable will use up (I think?). const int WAVERATIO = 4; const int SUBWAVELEN = STOREDSUBWAVELEN * WAVERATIO; @@ -303,11 +303,11 @@ class MicrowaveKnob: public Knob Q_OBJECT using Knob::Knob; public: - void setMatrixLocation( int loc1, int loc2, int loc3 ); + void setMatrixLocation(int loc1, int loc2, int loc3); - void setWhichMacroKnob( int which ); + void setWhichMacroKnob(int which); - MicrowaveView * knobView; + MicrowaveView * m_knobView; signals: void sendToMatrixAsOutput(); void switchToMatrixKnob(); @@ -317,13 +317,13 @@ class MicrowaveKnob: public Knob void refreshMacroColor(); void setMacroColortoDefault(); protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + virtual void contextMenuEvent(QContextMenuEvent * me); + virtual void mousePressEvent(QMouseEvent * me); + virtual void mouseReleaseEvent(QMouseEvent * me); private: - int matrixLocation[3] = {0}; - bool ignoreShift = false; - int whichMacroKnob = -1; + int m_matrixLocation[3] = {0}; + bool m_ignoreShift = false; + int m_whichMacroKnob = -1; }; @@ -332,47 +332,47 @@ class Microwave : public Instrument Q_OBJECT public: - Microwave(InstrumentTrack * _instrument_track ); + Microwave(InstrumentTrack * instrument_track); virtual ~Microwave(); - virtual PluginView * instantiateView( QWidget * _parent ); + virtual PluginView * instantiateView(QWidget * parent); virtual QString nodeName() const; - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - virtual void playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ); - virtual void deleteNotePluginData( NotePlayHandle * _n ); + virtual void saveSettings(QDomDocument & doc, QDomElement & parent); + virtual void loadSettings(const QDomElement & thissave); + virtual void playNote(NotePlayHandle * n, sampleFrame * working_buffer); + virtual void deleteNotePluginData(NotePlayHandle * n); virtual f_cnt_t desiredReleaseFrames() const { - return( 64 ); + return(64); } - void switchMatrixSections( int source, int destination ); + void switchMatrixSections(int source, int destination); - inline void fillSubOsc( int which, bool doInterpolate = true ); - inline void fillMainOsc( int which, bool doInterpolate = true ); + inline void fillSubOsc(int which, bool doInterpolate = true); + inline void fillMainOsc(int which, bool doInterpolate = true); - float scroll = 0; - bool viewOpen = false; + float m_scroll = 0; + bool m_viewOpen = false; protected slots: - void valueChanged( int, int ); - void morphMaxChanged( int ); - void sampLenChanged( int ); - void subSampLenChanged( int ); - void mainEnabledChanged( int ); - void subEnabledChanged( int ); - void modEnabledChanged( int ); - void filtEnabledChanged( int ); - void sampleEnabledChanged( int ); - void samplesChanged( int, int ); - void interpolateChanged( int ); - void subInterpolateChanged( int ); + void valueChanged(int, int); + void morphMaxChanged(int); + void sampLenChanged(int); + void subSampLenChanged(int); + void mainEnabledChanged(int); + void subEnabledChanged(int); + void modEnabledChanged(int); + void filtEnabledChanged(int); + void sampleEnabledChanged(int); + void samplesChanged(int, int); + void interpolateChanged(int); + void subInterpolateChanged(int); private: // Stolen from WatSyn, with a few changes // memcpy utilizing libsamplerate (src) for sinc interpolation - inline void srccpy( float * _dst, float * _src, int wavelength ) + inline void srccpy(float * dst, float * src, int wavelength) { int err; const int margin = 64; @@ -381,242 +381,242 @@ protected slots: std::unique_ptr tmps(new float[wavelength + margin]); float * tmp = &tmps.get()[0]; - memcpy( tmp, _src, sizeof( float ) * wavelength ); - memcpy( tmp + wavelength, _src, sizeof( float ) * margin ); - SRC_STATE * src_state = src_new( SRC_SINC_FASTEST, 1, &err ); + memcpy(tmp, src, sizeof(float) * wavelength); + memcpy(tmp + wavelength, src, sizeof(float) * margin); + SRC_STATE * src_state = src_new(SRC_SINC_FASTEST, 1, &err); SRC_DATA src_data; src_data.data_in = tmp; src_data.input_frames = wavelength + margin; - src_data.data_out = _dst; + src_data.data_out = dst; src_data.output_frames = wavelength * WAVERATIO; - src_data.src_ratio = static_cast( WAVERATIO ); + src_data.src_ratio = static_cast(WAVERATIO); src_data.end_of_input = 0; - err = src_process( src_state, &src_data ); - if( err ) { qDebug( "Microwave SRC error: %s", src_strerror( err ) ); } - src_delete( src_state ); + err = src_process(src_state, &src_data); + if (err) { qDebug("Microwave SRC error: %s", src_strerror(err)); } + src_delete(src_state); } - FloatModel * morph[8]; - FloatModel * range[8]; - FloatModel * modify[8]; - ComboBoxModel * modifyMode[8]; - FloatModel * vol[8]; - FloatModel * pan[8]; - FloatModel * detune[8]; - FloatModel * phase[8]; - FloatModel * phaseRand[8]; - BoolModel * enabled[8]; - BoolModel * muted[8]; - FloatModel * sampLen[8]; - FloatModel * morphMax[8]; - FloatModel * unisonVoices[8]; - FloatModel * unisonDetune[8]; - FloatModel * unisonMorph[8]; - FloatModel * unisonModify[8]; - BoolModel * keytracking[8]; - FloatModel * tempo[8]; - BoolModel * interpolate[8]; - - BoolModel * subEnabled[64]; - BoolModel * subMuted[64]; - BoolModel * subKeytrack[64]; - BoolModel * subNoise[64]; - FloatModel * subVol[64]; - FloatModel * subPanning[64]; - FloatModel * subDetune[64]; - FloatModel * subPhase[64]; - FloatModel * subPhaseRand[64]; - FloatModel * subSampLen[64]; - FloatModel * subTempo[64]; - FloatModel * subRateLimit[64]; - FloatModel * subUnisonNum[64]; - FloatModel * subUnisonDetune[64]; - BoolModel * subInterpolate[64]; - - BoolModel * sampleEnabled[8]; - BoolModel * sampleGraphEnabled[8]; - BoolModel * sampleMuted[8]; - BoolModel * sampleKeytracking[8]; - BoolModel * sampleLoop[8]; - FloatModel * sampleVolume[8]; - FloatModel * samplePanning[8]; - FloatModel * sampleDetune[8]; - FloatModel * samplePhase[8]; - FloatModel * samplePhaseRand[8]; - FloatModel * sampleStart[8]; - FloatModel * sampleEnd[8]; - - ComboBoxModel * modIn[64]; - IntModel * modInNum[64]; - FloatModel * modInAmnt[64]; - FloatModel * modInCurve[64]; - ComboBoxModel * modIn2[64]; - IntModel * modInNum2[64]; - FloatModel * modInAmnt2[64]; - FloatModel * modInCurve2[64]; - ComboBoxModel * modOutSec[64]; - ComboBoxModel * modOutSig[64]; - IntModel * modOutSecNum[64]; - BoolModel * modEnabled[64]; - ComboBoxModel * modCombineType[64]; - BoolModel * modType[64]; - BoolModel * modType2[64]; - - FloatModel * filtCutoff[8]; - FloatModel * filtReso[8]; - FloatModel * filtGain[8]; - ComboBoxModel * filtType[8]; - ComboBoxModel * filtSlope[8]; - FloatModel * filtInVol[8]; - FloatModel * filtOutVol[8]; - FloatModel * filtWetDry[8]; - FloatModel * filtBal[8]; - FloatModel * filtSatu[8]; - FloatModel * filtFeedback[8]; - FloatModel * filtDetune[8]; - BoolModel * filtEnabled[8]; - BoolModel * filtMuted[8]; - BoolModel * filtKeytracking[8]; - - FloatModel * macro[18]; - QString macroTooltips[18] = {}; - int macroColors[18][3] = {{0}}; - - FloatModel visvol; - - FloatModel loadAlg; - FloatModel loadChnl; - - IntModel mainNum; - IntModel subNum; - IntModel sampNum; - ComboBoxModel oversample; - ComboBoxModel oversampleMode; - ComboBoxModel loadMode; - - graphModel graph; + FloatModel * m_morph[8]; + FloatModel * m_range[8]; + FloatModel * m_modify[8]; + ComboBoxModel * m_modifyMode[8]; + FloatModel * m_vol[8]; + FloatModel * m_pan[8]; + FloatModel * m_detune[8]; + FloatModel * m_phase[8]; + FloatModel * m_phaseRand[8]; + BoolModel * m_enabled[8]; + BoolModel * m_muted[8]; + FloatModel * m_sampLen[8]; + FloatModel * m_morphMax[8]; + FloatModel * m_unisonVoices[8]; + FloatModel * m_unisonDetune[8]; + FloatModel * m_unisonMorph[8]; + FloatModel * m_unisonModify[8]; + BoolModel * m_keytracking[8]; + FloatModel * m_tempo[8]; + BoolModel * m_interpolate[8]; + + BoolModel * m_subEnabled[64]; + BoolModel * m_subMuted[64]; + BoolModel * m_subKeytrack[64]; + BoolModel * m_subNoise[64]; + FloatModel * m_subVol[64]; + FloatModel * m_subPanning[64]; + FloatModel * m_subDetune[64]; + FloatModel * m_subPhase[64]; + FloatModel * m_subPhaseRand[64]; + FloatModel * m_subSampLen[64]; + FloatModel * m_subTempo[64]; + FloatModel * m_subRateLimit[64]; + FloatModel * m_subUnisonNum[64]; + FloatModel * m_subUnisonDetune[64]; + BoolModel * m_subInterpolate[64]; + + BoolModel * m_sampleEnabled[8]; + BoolModel * m_sampleGraphEnabled[8]; + BoolModel * m_sampleMuted[8]; + BoolModel * m_sampleKeytracking[8]; + BoolModel * m_sampleLoop[8]; + FloatModel * m_sampleVolume[8]; + FloatModel * m_samplePanning[8]; + FloatModel * m_sampleDetune[8]; + FloatModel * m_samplePhase[8]; + FloatModel * m_samplePhaseRand[8]; + FloatModel * m_sampleStart[8]; + FloatModel * m_sampleEnd[8]; + + ComboBoxModel * m_modIn[64]; + IntModel * m_modInNum[64]; + FloatModel * m_modInAmnt[64]; + FloatModel * m_modInCurve[64]; + ComboBoxModel * m_modIn2[64]; + IntModel * m_modInNum2[64]; + FloatModel * m_modInAmnt2[64]; + FloatModel * m_modInCurve2[64]; + ComboBoxModel * m_modOutSec[64]; + ComboBoxModel * m_modOutSig[64]; + IntModel * m_modOutSecNum[64]; + BoolModel * m_modEnabled[64]; + ComboBoxModel * m_modCombineType[64]; + BoolModel * m_modType[64]; + BoolModel * m_modType2[64]; + + FloatModel * m_filtCutoff[8]; + FloatModel * m_filtReso[8]; + FloatModel * m_filtGain[8]; + ComboBoxModel * m_filtType[8]; + ComboBoxModel * m_filtSlope[8]; + FloatModel * m_filtInVol[8]; + FloatModel * m_filtOutVol[8]; + FloatModel * m_filtWetDry[8]; + FloatModel * m_filtBal[8]; + FloatModel * m_filtSatu[8]; + FloatModel * m_filtFeedback[8]; + FloatModel * m_filtDetune[8]; + BoolModel * m_filtEnabled[8]; + BoolModel * m_filtMuted[8]; + BoolModel * m_filtKeytracking[8]; + + FloatModel * m_macro[18]; + QString m_macroTooltips[18] = {}; + int m_macroColors[18][3] = {{0}}; + + FloatModel m_visvol; + + FloatModel m_loadAlg; + FloatModel m_loadChnl; + + IntModel m_mainNum; + IntModel m_subNum; + IntModel m_sampNum; + ComboBoxModel m_oversample; + ComboBoxModel m_oversampleMode; + ComboBoxModel m_loadMode; + + graphModel m_graph; - BoolModel visualize; + BoolModel m_visualize; - float storedwaveforms[8][STOREDMAINARRAYLEN] = {{0}}; - float waveforms[8][MAINARRAYLEN] = {{0}}; - bool mainFilled[8] = {false}; - int currentTab = 0; - float storedsubs[64][STOREDSUBWAVELEN] = {{0}}; - float subs[64][SUBWAVELEN] = {{0}}; - bool subFilled[64] = {false}; - float sampGraphs[1024] = {0}; - std::vector samples[8][2]; + float m_storedwaveforms[8][STOREDMAINARRAYLEN] = {{0}}; + float m_waveforms[8][MAINARRAYLEN] = {{0}}; + bool m_mainFilled[8] = {false}; + int m_currentTab = 0; + float m_storedsubs[64][STOREDSUBWAVELEN] = {{0}}; + float m_subs[64][SUBWAVELEN] = {{0}}; + bool m_subFilled[64] = {false}; + float m_sampGraphs[1024] = {0}; + std::vector m_samples[8][2]; - BoolModel mainFlipped; - BoolModel subFlipped; + BoolModel m_mainFlipped; + BoolModel m_subFlipped; - BoolModel removeDC; + BoolModel m_removeDC; - SampleBuffer sampleBuffer; + SampleBuffer m_sampleBuffer; //Below is for passing to mSynth initialization - float morphArr[8] = {0}; - float rangeArr[8] = {0}; - float modifyArr[8] = {0}; - int modifyModeArr[8] = {0}; - float volArr[8] = {0}; - float panArr[8] = {0}; - float detuneArr[8] = {0}; - float phaseArr[8] = {0}; - float phaseRandArr[8] = {0}; - bool enabledArr[8] = {false}; - bool mutedArr[8] = {false}; - float sampLenArr[8] = {0}; - float morphMaxArr[8] = {0}; - float unisonVoicesArr[8] = {0}; - float unisonDetuneArr[8] = {0}; - float unisonMorphArr[8] = {0}; - float unisonModifyArr[8] = {0}; - bool keytrackingArr[8] = {true}; - float tempoArr[8] = {0}; - bool interpolateArr[8] = {true}; - - int modInArr[64] = {0}; - int modInNumArr[64] = {0}; - float modInAmntArr[64] = {0}; - float modInCurveArr[64] = {0}; - int modIn2Arr[64] = {0}; - int modInNum2Arr[64] = {0}; - float modInAmnt2Arr[64] = {0}; - float modInCurve2Arr[64] = {0}; - int modOutSecArr[64] = {0}; - int modOutSigArr[64] = {0}; - int modOutSecNumArr[64] = {0}; - bool modEnabledArr[64] = {false}; - int modCombineTypeArr[64] = {0}; - bool modTypeArr[64] = {0}; - bool modType2Arr[64] = {0}; + float m_morphArr[8] = {0}; + float m_rangeArr[8] = {0}; + float m_modifyArr[8] = {0}; + int m_modifyModeArr[8] = {0}; + float m_volArr[8] = {0}; + float m_panArr[8] = {0}; + float m_detuneArr[8] = {0}; + float m_phaseArr[8] = {0}; + float m_phaseRandArr[8] = {0}; + bool m_enabledArr[8] = {false}; + bool m_mutedArr[8] = {false}; + float m_sampLenArr[8] = {0}; + float m_morphMaxArr[8] = {0}; + float m_unisonVoicesArr[8] = {0}; + float m_unisonDetuneArr[8] = {0}; + float m_unisonMorphArr[8] = {0}; + float m_unisonModifyArr[8] = {0}; + bool m_keytrackingArr[8] = {true}; + float m_tempoArr[8] = {0}; + bool m_interpolateArr[8] = {true}; + + int m_modInArr[64] = {0}; + int m_modInNumArr[64] = {0}; + float m_modInAmntArr[64] = {0}; + float m_modInCurveArr[64] = {0}; + int m_modIn2Arr[64] = {0}; + int m_modInNum2Arr[64] = {0}; + float m_modInAmnt2Arr[64] = {0}; + float m_modInCurve2Arr[64] = {0}; + int m_modOutSecArr[64] = {0}; + int m_modOutSigArr[64] = {0}; + int m_modOutSecNumArr[64] = {0}; + bool m_modEnabledArr[64] = {false}; + int m_modCombineTypeArr[64] = {0}; + bool m_modTypeArr[64] = {0}; + bool m_modType2Arr[64] = {0}; - bool subEnabledArr[64] = {false}; - float subVolArr[64] = {0}; - float subPhaseArr[64] = {0}; - float subPhaseRandArr[64] = {0}; - float subDetuneArr[64] = {0}; - bool subMutedArr[64] = {false}; - bool subKeytrackArr[64] = {false}; - float subSampLenArr[64] = {0}; - bool subNoiseArr[64] = {false}; - float subPanningArr[64] = {0}; - float subTempoArr[64] = {0}; - float subRateLimitArr[64] = {0}; - float subUnisonNumArr[64] = {0}; - float subUnisonDetuneArr[64] = {0}; - bool subInterpolateArr[64] = {true}; + bool m_subEnabledArr[64] = {false}; + float m_subVolArr[64] = {0}; + float m_subPhaseArr[64] = {0}; + float m_subPhaseRandArr[64] = {0}; + float m_subDetuneArr[64] = {0}; + bool m_subMutedArr[64] = {false}; + bool m_subKeytrackArr[64] = {false}; + float m_subSampLenArr[64] = {0}; + bool m_subNoiseArr[64] = {false}; + float m_subPanningArr[64] = {0}; + float m_subTempoArr[64] = {0}; + float m_subRateLimitArr[64] = {0}; + float m_subUnisonNumArr[64] = {0}; + float m_subUnisonDetuneArr[64] = {0}; + bool m_subInterpolateArr[64] = {true}; - float filtInVolArr[8] = {0}; - int filtTypeArr[8] = {0}; - int filtSlopeArr[8] = {0}; - float filtCutoffArr[8] = {0}; - float filtResoArr[8] = {0}; - float filtGainArr[8] = {0}; - float filtSatuArr[8] = {0}; - float filtWetDryArr[8] = {0}; - float filtBalArr[8] = {0}; - float filtOutVolArr[8] = {0}; - bool filtEnabledArr[8] = {false}; - float filtFeedbackArr[8] = {0}; - float filtDetuneArr[8] = {0}; - bool filtKeytrackingArr[8] = {false}; - bool filtMutedArr[8] = {false}; - - bool sampleEnabledArr[8] = {false}; - bool sampleGraphEnabledArr[8] = {false}; - bool sampleMutedArr[8] = {false}; - bool sampleKeytrackingArr[8] = {false}; - bool sampleLoopArr[8] = {false}; - float sampleVolumeArr[8] = {0}; - float samplePanningArr[8] = {0}; - float sampleDetuneArr[8] = {0}; - float samplePhaseArr[8] = {0}; - float samplePhaseRandArr[8] = {0}; - float sampleStartArr[8] = {0}; - float sampleEndArr[8] = {1, 1, 1, 1, 1, 1, 1, 1}; - - float macroArr[18] = {0}; + float m_filtInVolArr[8] = {0}; + int m_filtTypeArr[8] = {0}; + int m_filtSlopeArr[8] = {0}; + float m_filtCutoffArr[8] = {0}; + float m_filtResoArr[8] = {0}; + float m_filtGainArr[8] = {0}; + float m_filtSatuArr[8] = {0}; + float m_filtWetDryArr[8] = {0}; + float m_filtBalArr[8] = {0}; + float m_filtOutVolArr[8] = {0}; + bool m_filtEnabledArr[8] = {false}; + float m_filtFeedbackArr[8] = {0}; + float m_filtDetuneArr[8] = {0}; + bool m_filtKeytrackingArr[8] = {false}; + bool m_filtMutedArr[8] = {false}; + + bool m_sampleEnabledArr[8] = {false}; + bool m_sampleGraphEnabledArr[8] = {false}; + bool m_sampleMutedArr[8] = {false}; + bool m_sampleKeytrackingArr[8] = {false}; + bool m_sampleLoopArr[8] = {false}; + float m_sampleVolumeArr[8] = {0}; + float m_samplePanningArr[8] = {0}; + float m_sampleDetuneArr[8] = {0}; + float m_samplePhaseArr[8] = {0}; + float m_samplePhaseRandArr[8] = {0}; + float m_sampleStartArr[8] = {0}; + float m_sampleEndArr[8] = {1, 1, 1, 1, 1, 1, 1, 1}; + + float m_macroArr[18] = {0}; //Above is for passing to mSynth initialization - int maxMainEnabled = 0;// The highest number of main oscillator sections that must be looped through - int maxModEnabled = 0;// The highest number of matrix sections that must be looped through - int maxSubEnabled = 0;// The highest number of sub oscillator sections that must be looped through - int maxSampleEnabled = 0;// The highest number of sample sections that must be looped through - int maxFiltEnabled = 0;// The highest number of filter sections that must be looped through + int m_maxMainEnabled = 0;// The highest number of main oscillator sections that must be looped through + int m_maxModEnabled = 0;// The highest number of matrix sections that must be looped through + int m_maxSubEnabled = 0;// The highest number of sub oscillator sections that must be looped through + int m_maxSampleEnabled = 0;// The highest number of sample sections that must be looped through + int m_maxFiltEnabled = 0;// The highest number of filter sections that must be looped through - float visualizerValues[204] = {0}; + float m_visualizerValues[204] = {0}; - QString wavetableSaveStrings[8] = {""}; - bool updateWavetable[8] = {true,true,true,true,true,true,true,true}; + QString m_wavetableSaveStrings[8] = {""}; + bool m_updateWavetable[8] = {true,true,true,true,true,true,true,true}; - ConstNotePlayHandleList nphList; + ConstNotePlayHandleList m_nphList; - InstrumentTrack * microwaveTrack = this->instrumentTrack(); + InstrumentTrack * m_microwaveTrack = this->instrumentTrack(); - Microwave * mwc; + Microwave * m_mwc; friend class MicrowaveView; friend class mSynth; @@ -629,50 +629,50 @@ class MicrowaveView : public InstrumentView { Q_OBJECT public: - MicrowaveView( Instrument * _instrument, - QWidget * _parent ); + MicrowaveView(Instrument * instrument, + QWidget * parent); virtual ~MicrowaveView(); - void sendToMatrixAsOutput( int loc1, int loc2, int loc3 ); - void switchToMatrixKnob( MicrowaveKnob * theKnob, int loc1, int loc2, int loc3 ); - void setMacroTooltip( MicrowaveKnob * theKnob, int which ); - void chooseMacroColor( MicrowaveKnob * theKnob, int which ); - void refreshMacroColor( MicrowaveKnob * theKnob, int which ); - void setMacroColortoDefault( MicrowaveKnob * theKnob, int which ); - void setGraphEnabledColor( bool isEnabled ); + void sendToMatrixAsOutput(int loc1, int loc2, int loc3); + void switchToMatrixKnob(MicrowaveKnob * m_theKnob, int loc1, int loc2, int loc3); + void setMacroTooltip(MicrowaveKnob * m_theKnob, int which); + void chooseMacroColor(MicrowaveKnob * m_theKnob, int which); + void refreshMacroColor(MicrowaveKnob * m_theKnob, int which); + void setMacroColortoDefault(MicrowaveKnob * m_theKnob, int which); + void setGraphEnabledColor(bool isEnabled); protected slots: void updateScroll(); void mainNumChanged(); void subNumChanged(); void sampNumChanged(); - void modOutSecChanged( int i ); - void modInChanged( int i ); - void modIn2Changed( int i ); - void tabChanged( int tabnum ); - void visualizeToggled( bool value ); + void modOutSecChanged(int i); + void modInChanged(int i); + void modIn2Changed(int i); + void tabChanged(int tabnum); + void visualizeToggled(bool value); void sinWaveClicked(); void triangleWaveClicked(); void sqrWaveClicked(); void sawWaveClicked(); void noiseWaveClicked(); void usrWaveClicked(); - void smoothClicked( void ); - void chooseWavetableFile( ); - void openWavetableFile( QString fileName = "" ); + void smoothClicked(void ); + void chooseWavetableFile(); + void openWavetableFile(QString fileName = ""); void openWavetableFileBtnClicked(); void openSampleFile(); void openSampleFileBtnClicked(); - void modUpClicked( int ); - void modDownClicked( int ); - void i1Clicked( int ); - void i2Clicked( int ); + void modUpClicked(int); + void modDownClicked(int); + void i1Clicked(int); + void i2Clicked(int); void confirmWavetableLoadClicked(); - void tabBtnClicked( int ); + void tabBtnClicked(int); void manualBtnClicked(); @@ -691,186 +691,186 @@ protected slots: private: virtual void modelChanged(); - void wheelEvent( QWheelEvent * _me ); - virtual void dropEvent( QDropEvent * _de ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - - PixmapButton * sinWaveBtn; - PixmapButton * triangleWaveBtn; - PixmapButton * sqrWaveBtn; - PixmapButton * sawWaveBtn; - PixmapButton * whiteNoiseWaveBtn; - PixmapButton * smoothBtn; - PixmapButton * usrWaveBtn; - - PixmapButton * sinWave2Btn; - PixmapButton * triangleWave2Btn; - PixmapButton * sqrWave2Btn; - PixmapButton * sawWave2Btn; - PixmapButton * whiteNoiseWave2Btn; - PixmapButton * smooth2Btn; - PixmapButton * usrWave2Btn; - - PixmapButton * XBtn;// For leaving wavetable loading section - PixmapButton * MatrixXBtn;// For when you send something to the Matrix via right click - - PixmapButton * normalizeBtn; - PixmapButton * desawBtn; - - PixmapButton * openWavetableButton; - PixmapButton * confirmLoadButton; - PixmapButton * openSampleButton; - - PixmapButton * modUpArrow[8]; - PixmapButton * modDownArrow[8]; - PixmapButton * i1Button[8]; - PixmapButton * i2Button[8]; - - PixmapButton * tab1Btn; - PixmapButton * tab2Btn; - PixmapButton * tab3Btn; - PixmapButton * tab4Btn; - PixmapButton * tab5Btn; - PixmapButton * tab6Btn; - - PixmapButton * mainFlipBtn; - PixmapButton * subFlipBtn; - - PixmapButton * manualBtn; - - PixmapButton * removeDCBtn; - ComboBox * oversampleModeBox; - - MicrowaveKnob * morphKnob; - MicrowaveKnob * rangeKnob; - MicrowaveKnob * modifyKnob; - ComboBox * modifyModeBox; - MicrowaveKnob * volKnob; - MicrowaveKnob * panKnob; - MicrowaveKnob * detuneKnob; - MicrowaveKnob * phaseKnob; - MicrowaveKnob * phaseRandKnob; - LedCheckBox * enabledToggle; - LedCheckBox * mutedToggle; - MicrowaveKnob * sampLenKnob; - MicrowaveKnob * morphMaxKnob; - MicrowaveKnob * unisonVoicesKnob; - MicrowaveKnob * unisonDetuneKnob; - MicrowaveKnob * unisonMorphKnob; - MicrowaveKnob * unisonModifyKnob; - LedCheckBox * keytrackingToggle; - MicrowaveKnob * tempoKnob; - LedCheckBox * interpolateToggle; - - LedCheckBox * subEnabledToggle; - LedCheckBox * subMutedToggle; - LedCheckBox * subKeytrackToggle; - LedCheckBox * subNoiseToggle; - MicrowaveKnob * subVolKnob; - MicrowaveKnob * subPanningKnob; - MicrowaveKnob * subDetuneKnob; - MicrowaveKnob * subPhaseKnob; - MicrowaveKnob * subPhaseRandKnob; - MicrowaveKnob * subSampLenKnob; - MicrowaveKnob * subTempoKnob; - MicrowaveKnob * subRateLimitKnob; - MicrowaveKnob * subUnisonNumKnob; - MicrowaveKnob * subUnisonDetuneKnob; - LedCheckBox * subInterpolateToggle; - - LedCheckBox * sampleEnabledToggle; - LedCheckBox * sampleGraphEnabledToggle; - LedCheckBox * sampleMutedToggle; - LedCheckBox * sampleKeytrackingToggle; - LedCheckBox * sampleLoopToggle; - MicrowaveKnob * sampleVolumeKnob; - MicrowaveKnob * samplePanningKnob; - MicrowaveKnob * sampleDetuneKnob; - MicrowaveKnob * samplePhaseKnob; - MicrowaveKnob * samplePhaseRandKnob; - MicrowaveKnob * sampleStartKnob; - MicrowaveKnob * sampleEndKnob; - - ComboBox * modInBox[8]; - LcdSpinBox * modInNumBox[8]; - MicrowaveKnob * modInAmntKnob[8]; - MicrowaveKnob * modInCurveKnob[8]; - ComboBox * modInBox2[8]; - LcdSpinBox * modInNumBox2[8]; - MicrowaveKnob * modInAmntKnob2[8]; - MicrowaveKnob * modInCurveKnob2[8]; - ComboBox * modOutSecBox[8]; - ComboBox * modOutSigBox[8]; - LcdSpinBox * modOutSecNumBox[8]; - LedCheckBox * modEnabledToggle[8]; - ComboBox * modCombineTypeBox[8]; - LedCheckBox * modTypeToggle[8]; - LedCheckBox * modType2Toggle[8]; - - MicrowaveKnob * filtCutoffKnob[8]; - MicrowaveKnob * filtResoKnob[8]; - MicrowaveKnob * filtGainKnob[8]; - ComboBox * filtTypeBox[8]; - ComboBox * filtSlopeBox[8]; - MicrowaveKnob * filtInVolKnob[8]; - MicrowaveKnob * filtOutVolKnob[8]; - MicrowaveKnob * filtWetDryKnob[8]; - MicrowaveKnob * filtBalKnob[8]; - MicrowaveKnob * filtSatuKnob[8]; - MicrowaveKnob * filtFeedbackKnob[8]; - MicrowaveKnob * filtDetuneKnob[8]; - LedCheckBox * filtEnabledToggle[8]; - LedCheckBox * filtMutedToggle[8]; - LedCheckBox * filtKeytrackingToggle[8]; - - MicrowaveKnob * macroKnob[18]; - - LcdSpinBox * subNumBox; - LcdSpinBox * sampNumBox; - LcdSpinBox * mainNumBox; - - ComboBox * oversampleBox; - ComboBox * loadModeBox; - - QLineEdit * modNumText[8]; - - MicrowaveKnob * loadAlgKnob; - MicrowaveKnob * loadChnlKnob; - - MicrowaveKnob * visvolKnob; - - Graph * graph; - LedCheckBox * visualizeToggle; - - QScrollBar * effectScrollBar; - QScrollBar * matrixScrollBar; - - QLabel * filtForegroundLabel; - QLabel * filtBoxesLabel; - QLabel * matrixForegroundLabel; - QLabel * matrixBoxesLabel; - - QPalette pal = QPalette(); - QPixmap tab1ArtworkImg = PLUGIN_NAME::getIconPixmap("tab1_artwork"); - QPixmap tab1FlippedArtworkImg = PLUGIN_NAME::getIconPixmap("tab1_artwork_flipped"); - QPixmap tab2ArtworkImg = PLUGIN_NAME::getIconPixmap("tab2_artwork"); - QPixmap tab2FlippedArtworkImg = PLUGIN_NAME::getIconPixmap("tab2_artwork_flipped"); - QPixmap tab3ArtworkImg = PLUGIN_NAME::getIconPixmap("tab3_artwork"); - QPixmap tab4ArtworkImg = PLUGIN_NAME::getIconPixmap("tab4_artwork"); - QPixmap tab5ArtworkImg = PLUGIN_NAME::getIconPixmap("tab5_artwork"); - QPixmap tab6ArtworkImg = PLUGIN_NAME::getIconPixmap("tab6_artwork"); - QPixmap tab7ArtworkImg = PLUGIN_NAME::getIconPixmap("tab7_artwork"); - - QString wavetableFileName = ""; - - Microwave * microwave; - - float temp1; - float temp2; - - int tabWhenSendingToMatrix; - - Microwave * b = castModel(); + void wheelEvent(QWheelEvent * me); + virtual void dropEvent(QDropEvent * de); + virtual void dragEnterEvent(QDragEnterEvent * dee); + + PixmapButton * m_sinWaveBtn; + PixmapButton * m_triangleWaveBtn; + PixmapButton * m_sqrWaveBtn; + PixmapButton * m_sawWaveBtn; + PixmapButton * m_whiteNoiseWaveBtn; + PixmapButton * m_smoothBtn; + PixmapButton * m_usrWaveBtn; + + PixmapButton * m_sinWave2Btn; + PixmapButton * m_triangleWave2Btn; + PixmapButton * m_sqrWave2Btn; + PixmapButton * m_sawWave2Btn; + PixmapButton * m_whiteNoiseWave2Btn; + PixmapButton * m_smooth2Btn; + PixmapButton * m_usrWave2Btn; + + PixmapButton * m_XBtn;// For leaving wavetable loading section + PixmapButton * m_MatrixXBtn;// For when you send something to the Matrix via right click + + PixmapButton * m_normalizeBtn; + PixmapButton * m_desawBtn; + + PixmapButton * m_openWavetableButton; + PixmapButton * m_confirmLoadButton; + PixmapButton * m_openSampleButton; + + PixmapButton * m_modUpArrow[8]; + PixmapButton * m_modDownArrow[8]; + PixmapButton * m_i1Button[8]; + PixmapButton * m_i2Button[8]; + + PixmapButton * m_tab1Btn; + PixmapButton * m_tab2Btn; + PixmapButton * m_tab3Btn; + PixmapButton * m_tab4Btn; + PixmapButton * m_tab5Btn; + PixmapButton * m_tab6Btn; + + PixmapButton * m_mainFlipBtn; + PixmapButton * m_subFlipBtn; + + PixmapButton * m_manualBtn; + + PixmapButton * m_removeDCBtn; + ComboBox * m_oversampleModeBox; + + MicrowaveKnob * m_morphKnob; + MicrowaveKnob * m_rangeKnob; + MicrowaveKnob * m_modifyKnob; + ComboBox * m_modifyModeBox; + MicrowaveKnob * m_volKnob; + MicrowaveKnob * m_panKnob; + MicrowaveKnob * m_detuneKnob; + MicrowaveKnob * m_phaseKnob; + MicrowaveKnob * m_phaseRandKnob; + LedCheckBox * m_enabledToggle; + LedCheckBox * m_mutedToggle; + MicrowaveKnob * m_sampLenKnob; + MicrowaveKnob * m_morphMaxKnob; + MicrowaveKnob * m_unisonVoicesKnob; + MicrowaveKnob * m_unisonDetuneKnob; + MicrowaveKnob * m_unisonMorphKnob; + MicrowaveKnob * m_unisonModifyKnob; + LedCheckBox * m_keytrackingToggle; + MicrowaveKnob * m_tempoKnob; + LedCheckBox * m_interpolateToggle; + + LedCheckBox * m_subEnabledToggle; + LedCheckBox * m_subMutedToggle; + LedCheckBox * m_subKeytrackToggle; + LedCheckBox * m_subNoiseToggle; + MicrowaveKnob * m_subVolKnob; + MicrowaveKnob * m_subPanningKnob; + MicrowaveKnob * m_subDetuneKnob; + MicrowaveKnob * m_subPhaseKnob; + MicrowaveKnob * m_subPhaseRandKnob; + MicrowaveKnob * m_subSampLenKnob; + MicrowaveKnob * m_subTempoKnob; + MicrowaveKnob * m_subRateLimitKnob; + MicrowaveKnob * m_subUnisonNumKnob; + MicrowaveKnob * m_subUnisonDetuneKnob; + LedCheckBox * m_subInterpolateToggle; + + LedCheckBox * m_sampleEnabledToggle; + LedCheckBox * m_sampleGraphEnabledToggle; + LedCheckBox * m_sampleMutedToggle; + LedCheckBox * m_sampleKeytrackingToggle; + LedCheckBox * m_sampleLoopToggle; + MicrowaveKnob * m_sampleVolumeKnob; + MicrowaveKnob * m_samplePanningKnob; + MicrowaveKnob * m_sampleDetuneKnob; + MicrowaveKnob * m_samplePhaseKnob; + MicrowaveKnob * m_samplePhaseRandKnob; + MicrowaveKnob * m_sampleStartKnob; + MicrowaveKnob * m_sampleEndKnob; + + ComboBox * m_modInBox[8]; + LcdSpinBox * m_modInNumBox[8]; + MicrowaveKnob * m_modInAmntKnob[8]; + MicrowaveKnob * m_modInCurveKnob[8]; + ComboBox * m_modInBox2[8]; + LcdSpinBox * m_modInNumBox2[8]; + MicrowaveKnob * m_modInAmntKnob2[8]; + MicrowaveKnob * m_modInCurveKnob2[8]; + ComboBox * m_modOutSecBox[8]; + ComboBox * m_modOutSigBox[8]; + LcdSpinBox * m_modOutSecNumBox[8]; + LedCheckBox * m_modEnabledToggle[8]; + ComboBox * m_modCombineTypeBox[8]; + LedCheckBox * m_modTypeToggle[8]; + LedCheckBox * m_modType2Toggle[8]; + + MicrowaveKnob * m_filtCutoffKnob[8]; + MicrowaveKnob * m_filtResoKnob[8]; + MicrowaveKnob * m_filtGainKnob[8]; + ComboBox * m_filtTypeBox[8]; + ComboBox * m_filtSlopeBox[8]; + MicrowaveKnob * m_filtInVolKnob[8]; + MicrowaveKnob * m_filtOutVolKnob[8]; + MicrowaveKnob * m_filtWetDryKnob[8]; + MicrowaveKnob * m_filtBalKnob[8]; + MicrowaveKnob * m_filtSatuKnob[8]; + MicrowaveKnob * m_filtFeedbackKnob[8]; + MicrowaveKnob * m_filtDetuneKnob[8]; + LedCheckBox * m_filtEnabledToggle[8]; + LedCheckBox * m_filtMutedToggle[8]; + LedCheckBox * m_filtKeytrackingToggle[8]; + + MicrowaveKnob * m_macroKnob[18]; + + LcdSpinBox * m_subNumBox; + LcdSpinBox * m_sampNumBox; + LcdSpinBox * m_mainNumBox; + + ComboBox * m_oversampleBox; + ComboBox * m_loadModeBox; + + QLineEdit * m_modNumText[8]; + + MicrowaveKnob * m_loadAlgKnob; + MicrowaveKnob * m_loadChnlKnob; + + MicrowaveKnob * m_visvolKnob; + + Graph * m_graph; + LedCheckBox * m_visualizeToggle; + + QScrollBar * m_effectScrollBar; + QScrollBar * m_matrixScrollBar; + + QLabel * m_filtForegroundLabel; + QLabel * m_filtBoxesLabel; + QLabel * m_matrixForegroundLabel; + QLabel * m_matrixBoxesLabel; + + QPalette m_pal = QPalette(); + QPixmap m_tab1ArtworkImg = PLUGIN_NAME::getIconPixmap("tab1_artwork"); + QPixmap m_tab1FlippedArtworkImg = PLUGIN_NAME::getIconPixmap("tab1_artwork_flipped"); + QPixmap m_tab2ArtworkImg = PLUGIN_NAME::getIconPixmap("tab2_artwork"); + QPixmap m_tab2FlippedArtworkImg = PLUGIN_NAME::getIconPixmap("tab2_artwork_flipped"); + QPixmap m_tab3ArtworkImg = PLUGIN_NAME::getIconPixmap("tab3_artwork"); + QPixmap m_tab4ArtworkImg = PLUGIN_NAME::getIconPixmap("tab4_artwork"); + QPixmap m_tab5ArtworkImg = PLUGIN_NAME::getIconPixmap("tab5_artwork"); + QPixmap m_tab6ArtworkImg = PLUGIN_NAME::getIconPixmap("tab6_artwork"); + QPixmap m_tab7ArtworkImg = PLUGIN_NAME::getIconPixmap("tab7_artwork"); + + QString m_wavetableFileName = ""; + + Microwave * m_microwave; + + float m_temp1; + float m_temp2; + + int m_tabWhenSendingToMatrix; + + Microwave * m_b = castModel(); friend class mSynth; }; @@ -880,7 +880,7 @@ class mSynth { MM_OPERATORS public: - mSynth( NotePlayHandle * _nph, + mSynth(NotePlayHandle * nph, float * morph, float * range, float * modify, int * modifyMode, float * vol, float * pan, float * detune, float * phase, float * phaseRand, bool * enabled, bool * muted, float * sampLen, float * morphMax, float * unisonVoices, float * unisonDetune, float * unisonMorph, float * unisonModify, bool * keytracking, float * tempo, bool * interpolate, bool * subEnabled, bool * subMuted, bool * subKeytrack, bool * subNoise, float * subVol, float * subPanning, float * subDetune, float * subPhase, float * subPhaseRand, @@ -892,222 +892,222 @@ class mSynth float * filtCutoff, float * filtReso, float * filtGain, int * filtType, int * filtSlope, float * filtInVol, float * filtOutVol, float * filtWetDry, float * filtBal, float * filtSatu, float * filtFeedback, float * filtDetune, bool * filtEnabled, bool * filtMuted, bool * filtKeytracking, float * macro, - std::vector (&samples)[8][2] ); + std::vector (&samples)[8][2]); virtual ~mSynth(); - void nextStringSample( sampleFrame &outputSample, float (&waveforms)[8][MAINARRAYLEN], float (&subs)[64][SUBWAVELEN], float * sampGraphs, std::vector (&samples)[8][2], int maxFiltEnabled, int maxModEnabled, int maxSubEnabled, int maxSampleEnabled, int maxMainEnabled, int sample_rate, Microwave * mwc, bool removeDC, bool isOversamplingSample, float (&storedsubs)[64][STOREDSUBWAVELEN] ); + void nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8][MAINARRAYLEN], float (&subs)[64][SUBWAVELEN], std::vector (&m_samples)[8][2], float * sampGraphs, int maxMainEnabled, int maxSubEnabled, int maxSampleEnabled, int maxFiltEnabled, int maxModEnabled, int sample_rate, Microwave * mwc, bool removeDC, float (&m_storedsubs)[64][STOREDSUBWAVELEN]); - inline float detuneWithCents( float pitchValue, float detuneValue ); + inline float detuneWithCents(float pitchValue, float detuneValue); - inline void refreshValue( int which, int num, Microwave * mwc ); + inline void refreshValue(int which, int num, Microwave * mwc); - inline float realfmod( float k, float n ); + inline float realfmod(float k, float n); private: - double sample_realindex[8][32] = {{0}}; - double sample_subindex[64][32] = {{0}}; - double sample_sampleindex[8] = {0}; - NotePlayHandle* nph; - - int noteDuration; - float noteFreq; - - float lastMainOscVal[8][2] = {{0}}; - float lastSubVal[64][2] = {{0}}; - float lastSubNoiseVal[64][32] = {{0}}; - double sample_step_sub = 0; - float noiseSampRand = 0; - float lastSampleVal[8][2] = {{0}}; - double sample_step_sample = 0; - - float lastMainOscEnvVal[8][2] = {{0}}; - float lastSubEnvVal[64][2] = {{0}}; - float lastSampleEnvVal[8][2] = {{0}}; - - bool lastMainOscEnvDone[8] = {false}; - bool lastSubEnvDone[64] = {false}; - bool lastSampleEnvDone[8] = {false}; - - int subNoiseDirection[64][32] = {{0}}; - - int loopStart = 0; - int loopEnd = 0; - float currentRangeValInvert = 0; - int currentSampLen = 0; - int currentIndex = 0; - - float filtInputs[8][2] = {{0}};// [filter number][channel] - float filtOutputs[8][2] = {{0}};// [filter number][channel] - float filtPrevSampIn[8][8][5][2] = {{{{0}}}};// [filter number][slope][samples back in time][channel] - float filtPrevSampOut[8][8][5][2] = {{{{0}}}};// [filter number][slope][samples back in time][channel] - float filtModOutputs[8][2] = {{0}};// [filter number][channel] - - std::vector filtDelayBuf[8][2];// [filter number][channel] - - float filty1[2] = {0}; - float filty2[2] = {0}; - float filty3[2] = {0}; - float filty4[2] = {0}; - float filtoldx[2] = {0}; - float filtoldy1[2] = {0}; - float filtoldy2[2] = {0}; - float filtoldy3[2] = {0}; - float filtx[2] = {0}; - - int modValType[128] = {0}; - int modValNum[128] = {0}; - - int numberToReset = 0; - - - float morph[8]; - float range[8]; - float modify[8]; - int modifyMode[8]; - float vol[8]; - float pan[8]; - float detune[8]; - float phase[8]; - float phaseRand[8]; - bool enabled[8]; - bool muted[8]; - float sampLen[8]; - float morphMax[8]; - float unisonVoices[8]; - float unisonDetune[8]; - float unisonMorph[8]; - float unisonModify[8]; - bool keytracking[8]; - float tempo[8]; - bool interpolate[64]; - - bool subEnabled[64]; - bool subMuted[64]; - bool subKeytrack[64]; - bool subNoise[64]; - float subVol[64]; - float subPanning[64]; - float subDetune[64]; - float subPhase[64]; - float subPhaseRand[64]; - float subSampLen[64]; - float subTempo[64]; - float subRateLimit[64]; - float subUnisonNum[64]; - float subUnisonDetune[64]; - bool subInterpolate[64]; - - bool sampleEnabled[8]; - bool sampleMuted[8]; - bool sampleKeytracking[8]; - bool sampleGraphEnabled[8]; - bool sampleLoop[8]; - float sampleVolume[8]; - float samplePanning[8]; - float sampleDetune[8]; - float samplePhase[8]; - float samplePhaseRand[8]; - float sampleStart[8]; - float sampleEnd[8]; - - int modIn[64]; - int modInNum[64]; - float modInAmnt[64]; - float modInCurve[64]; - int modIn2[64]; - int modInNum2[64]; - float modInAmnt2[64]; - float modInCurve2[64]; - int modOutSec[64]; - int modOutSig[64]; - int modOutSecNum[64]; - bool modEnabled[64]; - int modCombineType[64]; - bool modType[64]; - bool modType2[64]; - - float filtCutoff[8]; - float filtReso[8]; - float filtGain[8]; - int filtType[8]; - int filtSlope[8]; - float filtInVol[8]; - float filtOutVol[8]; - float filtWetDry[8]; - float filtBal[8]; - float filtSatu[8]; - float filtFeedback[8]; - float filtDetune[8]; - bool filtEnabled[8]; - bool filtMuted[8]; - bool filtKeytracking[8]; - - float cutoff; - int mode; - float reso; - float dbgain; - float Fs; - float a0; - float a1; - float a2; - float b0; - float b1; - float b2; - float alpha; - float w0; - float A; - float f; - float k; - float p; - float scale; - float r; - - float humanizer[8] = {0}; - - float unisonDetuneAmounts[8][32] = {{0}}; - float subUnisonDetuneAmounts[64][32] = {{0}}; + double m_sample_realindex[8][32] = {{0}}; + double m_sample_subindex[64][32] = {{0}}; + double m_sample_sampleindex[8] = {0}; + NotePlayHandle* m_nph; + + int m_noteDuration; + float m_noteFreq; + + float m_lastMainOscVal[8][2] = {{0}}; + float m_lastSubVal[64][2] = {{0}}; + float m_lastSubNoiseVal[64][32] = {{0}}; + double m_sample_step_sub = 0; + float m_noiseSampRand = 0; + float m_lastSampleVal[8][2] = {{0}}; + double m_sample_step_sample = 0; + + float m_lastMainOscEnvVal[8][2] = {{0}}; + float m_lastSubEnvVal[64][2] = {{0}}; + float m_lastSampleEnvVal[8][2] = {{0}}; + + bool m_lastMainOscEnvDone[8] = {false}; + bool m_lastSubEnvDone[64] = {false}; + bool m_lastSampleEnvDone[8] = {false}; + + int m_subNoiseDirection[64][32] = {{0}}; + + int m_loopStart = 0; + int m_loopEnd = 0; + float m_currentRangeValInvert = 0; + int m_currentSampLen = 0; + int m_currentIndex = 0; + + float m_filtInputs[8][2] = {{0}};// [filter number][channel] + float m_filtOutputs[8][2] = {{0}};// [filter number][channel] + float m_filtPrevSampIn[8][8][5][2] = {{{{0}}}};// [filter number][slope][samples back in time][channel] + float m_filtPrevSampOut[8][8][5][2] = {{{{0}}}};// [filter number][slope][samples back in time][channel] + float m_filtModOutputs[8][2] = {{0}};// [filter number][channel] + + std::vector m_filtDelayBuf[8][2];// [filter number][channel] + + float m_filty1[2] = {0}; + float m_filty2[2] = {0}; + float m_filty3[2] = {0}; + float m_filty4[2] = {0}; + float m_filtoldx[2] = {0}; + float m_filtoldy1[2] = {0}; + float m_filtoldy2[2] = {0}; + float m_filtoldy3[2] = {0}; + float m_filtx[2] = {0}; + + int m_modValType[128] = {0}; + int m_modValNum[128] = {0}; + + int m_numberToReset = 0; + + + float m_morph[8]; + float m_range[8]; + float m_modify[8]; + int m_modifyMode[8]; + float m_vol[8]; + float m_pan[8]; + float m_detune[8]; + float m_phase[8]; + float m_phaseRand[8]; + bool m_enabled[8]; + bool m_muted[8]; + float m_sampLen[8]; + float m_morphMax[8]; + float m_unisonVoices[8]; + float m_unisonDetune[8]; + float m_unisonMorph[8]; + float m_unisonModify[8]; + bool m_keytracking[8]; + float m_tempo[8]; + bool m_interpolate[64]; + + bool m_subEnabled[64]; + bool m_subMuted[64]; + bool m_subKeytrack[64]; + bool m_subNoise[64]; + float m_subVol[64]; + float m_subPanning[64]; + float m_subDetune[64]; + float m_subPhase[64]; + float m_subPhaseRand[64]; + float m_subSampLen[64]; + float m_subTempo[64]; + float m_subRateLimit[64]; + float m_subUnisonNum[64]; + float m_subUnisonDetune[64]; + bool m_subInterpolate[64]; + + bool m_sampleEnabled[8]; + bool m_sampleMuted[8]; + bool m_sampleKeytracking[8]; + bool m_sampleGraphEnabled[8]; + bool m_sampleLoop[8]; + float m_sampleVolume[8]; + float m_samplePanning[8]; + float m_sampleDetune[8]; + float m_samplePhase[8]; + float m_samplePhaseRand[8]; + float m_sampleStart[8]; + float m_sampleEnd[8]; + + int m_modIn[64]; + int m_modInNum[64]; + float m_modInAmnt[64]; + float m_modInCurve[64]; + int m_modIn2[64]; + int m_modInNum2[64]; + float m_modInAmnt2[64]; + float m_modInCurve2[64]; + int m_modOutSec[64]; + int m_modOutSig[64]; + int m_modOutSecNum[64]; + bool m_modEnabled[64]; + int m_modCombineType[64]; + bool m_modType[64]; + bool m_modType2[64]; + + float m_filtCutoff[8]; + float m_filtReso[8]; + float m_filtGain[8]; + int m_filtType[8]; + int m_filtSlope[8]; + float m_filtInVol[8]; + float m_filtOutVol[8]; + float m_filtWetDry[8]; + float m_filtBal[8]; + float m_filtSatu[8]; + float m_filtFeedback[8]; + float m_filtDetune[8]; + bool m_filtEnabled[8]; + bool m_filtMuted[8]; + bool m_filtKeytracking[8]; + + float m_cutoff; + int m_mode; + float m_reso; + float m_dbgain; + float m_Fs; + float m_a0; + float m_a1; + float m_a2; + float m_b0; + float m_b1; + float m_b2; + float m_alpha; + float m_w0; + float m_A; + float m_f; + float m_k; + float m_p; + float m_scale; + float m_r; + + float m_humanizer[8] = {0}; + + float m_unisonDetuneAmounts[8][32] = {{0}}; + float m_subUnisonDetuneAmounts[64][32] = {{0}}; // Usually used for CPU improvements - float temp1; - float temp2; - float temp3; - float temp4; - float temp5; - float temp6; - float temp7; + float m_temp1; + float m_temp2; + float m_temp3; + float m_temp4; + float m_temp5; + float m_temp6; + float m_temp7; - float curModVal[2] = {0}; - float curModVal2[2] = {0}; - float curModValCurve[2] = {0}; - float curModVal2Curve[2] = {0}; - float comboModVal[2] = {0}; - float comboModValMono = 0; + float m_curModVal[2] = {0}; + float m_curModVal2[2] = {0}; + float m_curModValCurve[2] = {0}; + float m_curModVal2Curve[2] = {0}; + float m_comboModVal[2] = {0}; + float m_comboModValMono = 0; - float sample_morerealindex[8][32] = {{0}}; - double sample_step[8][32] = {{0}}; + float m_sample_morerealindex[8][32] = {{0}}; + double m_sample_step[8][32] = {{0}}; - float unisonVoicesMinusOne = 0; - float subUnisonVoicesMinusOne = 0; + float m_unisonVoicesMinusOne = 0; + float m_subUnisonVoicesMinusOne = 0; - int filtFeedbackLoc[8] = {0}; + int m_filtFeedbackLoc[8] = {0}; - float macro[18]; + float m_macro[18]; // For DC offset removal - float averageSampleValue[2] = {0}; + float m_averageSampleValue[2] = {0}; - sample_t mainsample[8][32] = {{0}}; - sample_t subsample[64][32] = {{0}}; - sample_t samplesample[8][2] = {{0}}; + sample_t m_mainsample[8][32] = {{0}}; + sample_t m_subsample[64][32] = {{0}}; + sample_t m_samplesample[8][2] = {{0}}; - float progress; - float progress2; - float progress3; - int intprogress; + float m_progress; + float m_progress2; + float m_progress3; + int m_intprogress; - sampleFrame sampleMainOsc; - sampleFrame sampleSubOsc; + sampleFrame m_sampleMainOsc; + sampleFrame m_sampleSubOsc; friend class Microwave; diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index 09ead171d49..c0035966775 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -33,59 +33,59 @@ #include "Oscillator.h" -Graph::Graph( QWidget * _parent, graphStyle _style, int _width, - int _height ) : - QWidget( _parent ), +Graph::Graph(QWidget * parent, graphStyle style, int width, + int height) : + QWidget(parent), /* TODO: size, background? */ - ModelView( new graphModel( -1.0, 1.0, 128, NULL, true ), this ), - m_graphStyle( _style ) + ModelView(new graphModel(-1.0, 1.0, 128, NULL, true), this), + m_graphStyle(style) { m_mouseDown = false; - m_graphColor = QColor( 0xFF, 0xAA, 0x00 ); + m_graphColor = QColor(0xFF, 0xAA, 0x00); - resize( _width, _height ); - setAcceptDrops( true ); - setCursor( Qt::CrossCursor ); + resize(width, height); + setAcceptDrops(true); + setCursor(Qt::CrossCursor); graphModel * gModel = castModel(); - QObject::connect( gModel, SIGNAL( samplesChanged( int, int ) ), - this, SLOT( updateGraph( int, int ) ) ); + QObject::connect(gModel, SIGNAL(samplesChanged(int, int)), + this, SLOT(updateGraph(int, int))); - QObject::connect( gModel, SIGNAL( lengthChanged( ) ), - this, SLOT( updateGraph( ) ) ); + QObject::connect(gModel, SIGNAL(lengthChanged()), + this, SLOT(updateGraph())); } -void Graph::setForeground( const QPixmap &_pixmap ) +void Graph::setForeground(const QPixmap &pixmap) { - m_foreground = _pixmap; + m_foreground = pixmap; } -void Graph::setGraphColor( QColor _graphcol ) +void Graph::setGraphColor(QColor graphcol) { - m_graphColor = _graphcol; + m_graphColor = graphcol; } /* -void graph::loadSampleFromFile( const QString & _filename ) +void graph::loadSampleFromFile(const QString & filename) { int i; // zero sample_shape - for( i = 0; i < sampleLength; i++ ) + for (i = 0; i < sampleLength; i++) { samplePointer[i] = 0; } // load user shape - sampleBuffer buffer( _filename ); + sampleBuffer buffer(filename); // copy buffer data - int trimSize = fmin( size(), static_cast(buffer.frames()) ); + int trimSize = fmin(size(), static_cast(buffer.frames())); - for( i = 0; i < trimSize; i++ ) + for (i = 0; i < trimSize; i++) { samplePointer[i] = (float)*buffer.data()[i]; } @@ -94,15 +94,15 @@ void graph::loadSampleFromFile( const QString & _filename ) -void Graph::mouseMoveEvent ( QMouseEvent * _me ) +void Graph::mouseMoveEvent (QMouseEvent * me) { // get position - int x = _me->x(); - int y = _me->y(); + int x = me->x(); + int y = me->y(); /* static bool skip = false; - if( skip ) + if (skip) { skip = false; return; @@ -111,29 +111,29 @@ void Graph::mouseMoveEvent ( QMouseEvent * _me ) // avoid mouse leaps int diff = x - m_lastCursorX; -/* if( diff >= 1 ) +/* if (diff >= 1) { - x = qMin( width() - 3, m_lastCursorX + 1 ); + x = qMin(width() - 3, m_lastCursorX + 1); } - else if( diff <= -1 ) + else if (diff <= -1) { - x = qMax( 2, m_lastCursorX - 1 ); + x = qMax(2, m_lastCursorX - 1); }*/ - x = qMax( 2, qMin( x, width()-3 ) ); - y = qMax( 2, qMin( y, height()-3 ) ); + x = qMax(2, qMin(x, width()-3)); + y = qMax(2, qMin(y, height()-3)); - drawLineAt( x, y, m_lastCursorX ); + drawLineAt(x, y, m_lastCursorX); // update mouse - if( diff != 0 ) + if (diff != 0) { m_lastCursorX = x; - QPoint pt = mapToGlobal( QPoint( x, y ) ); + QPoint pt = mapToGlobal(QPoint(x, y)); - QCursor::setPos( pt.x(), pt.y() ); + QCursor::setPos(pt.x(), pt.y()); } // skip = true; @@ -141,80 +141,80 @@ void Graph::mouseMoveEvent ( QMouseEvent * _me ) -void Graph::mousePressEvent( QMouseEvent * _me ) +void Graph::mousePressEvent(QMouseEvent * me) { - if( _me->button() == Qt::LeftButton ) + if (me->button() == Qt::LeftButton) { - if ( !( _me->modifiers() & Qt::ShiftModifier ) ) + if (!(me->modifiers() & Qt::ShiftModifier)) { // get position - int x = _me->x(); - int y = _me->y(); + int x = me->x(); + int y = me->y(); - changeSampleAt( x, y ); + changeSampleAt(x, y); // toggle mouse state m_mouseDown = true; - setCursor( Qt::BlankCursor ); + setCursor(Qt::BlankCursor); m_lastCursorX = x; } else { //when shift-clicking, draw a line from last position to current //position - int x = _me->x(); - int y = _me->y(); + int x = me->x(); + int y = me->y(); - drawLineAt( x, y, m_lastCursorX ); + drawLineAt(x, y, m_lastCursorX); m_mouseDown = true; - setCursor( Qt::BlankCursor ); + setCursor(Qt::BlankCursor); m_lastCursorX = x; } } } -void Graph::drawLineAt( int _x, int _y, int _lastx ) +void Graph::drawLineAt(int x, int y, int lastx) { float minVal = model()->minValue(); float maxVal = model()->maxValue(); - if ( width() <= 4 ) + if (width() <= 4) { return; } - float xscale = static_cast( model()->length() ) / - ( width()-4 ); + float xscale = static_cast(model()->length()) / + (width()-4); //consider border - _x -= 2; - _y -= 2; - _lastx -= 2; + x -= 2; + y -= 2; + lastx -= 2; - _lastx = qMax( 0, qMin( _lastx, width()-5 ) ); + lastx = qMax(0, qMin(lastx, width()-5)); float range = minVal - maxVal; - float val = ( _y*range/( height()-5 ) ) + maxVal; + float val = (y*range/(height()-5)) + maxVal; int sample_begin, sample_end; float lastval; float val_begin, val_end; - if (_lastx > _x) + if (lastx > x) { - sample_begin = (int)((_x) * xscale); - sample_end = (int)ceil((_lastx+1) * xscale); - lastval = model() -> m_samples[ (int)( sample_end - 1 ) ]; + sample_begin = (int)((x) * xscale); + sample_end = (int)ceil((lastx+1) * xscale); + lastval = model() -> m_samples[ (int)(sample_end - 1) ]; val_begin = val; val_end = lastval; } else { - sample_begin = (int)(_lastx * xscale); - sample_end = (int)ceil((_x+1) * xscale); - lastval = model() -> m_samples[ (int)( sample_begin ) ]; + sample_begin = (int)(lastx * xscale); + sample_end = (int)ceil((x+1) * xscale); + lastval = model() -> m_samples[ (int)(sample_begin) ]; val_begin = lastval; val_end = val; @@ -226,53 +226,53 @@ void Graph::drawLineAt( int _x, int _y, int _lastx ) { val_begin = val; } - //int xstep = _x > _lastx ? -1 : 1; - float ystep = ( val_end - val_begin ) / linelen; + //int xstep = x > lastx ? -1 : 1; + float ystep = (val_end - val_begin) / linelen; // draw a line - for ( int i = 0 ; i < linelen; i++ ) + for (int i = 0 ; i < linelen; i++) { - model()->drawSampleAt( sample_begin + i , val_begin + ((i ) * ystep)); + model()->drawSampleAt(sample_begin + i , val_begin + ((i) * ystep)); } - model()->samplesChanged( sample_begin, sample_end ); + model()->samplesChanged(sample_begin, sample_end); } -void Graph::changeSampleAt( int _x, int _y ) +void Graph::changeSampleAt(int x, int y) { float minVal = model()->minValue(); float maxVal = model()->maxValue(); - if ( width() <= 4 ) + if (width() <= 4) { return; } - float xscale = static_cast( model()->length() ) / - ( width()-4 ); + float xscale = static_cast(model()->length()) / + (width()-4); // consider border of background image - _x -= 2; - _y -= 2; + x -= 2; + y -= 2; // subtract max from min because Qt's Y-axis is backwards float range = minVal - maxVal; - float val = ( _y*range/( height()-5 ) ) + maxVal; + float val = (y*range/(height()-5)) + maxVal; - model()->setSampleAt( (int)( _x*xscale ), val ); + model()->setSampleAt((int)(x*xscale), val); } -void Graph::mouseReleaseEvent( QMouseEvent * _me ) +void Graph::mouseReleaseEvent(QMouseEvent * me) { - if( _me->button() == Qt::LeftButton ) + if (me->button() == Qt::LeftButton) { // toggle mouse state m_mouseDown = false; - setCursor( Qt::CrossCursor ); + setCursor(Qt::CrossCursor); update(); emit drawn(); } @@ -280,149 +280,149 @@ void Graph::mouseReleaseEvent( QMouseEvent * _me ) -void Graph::paintEvent( QPaintEvent * ) +void Graph::paintEvent(QPaintEvent *) { - QPainter p( this ); + QPainter p(this); - p.setPen( QPen( m_graphColor, 1 ) ); - QColor gcol = QColor( m_graphColor.red(), m_graphColor.green(), m_graphColor.blue(), 100 ); + p.setPen(QPen(m_graphColor, 1)); + QColor gcol = QColor(m_graphColor.red(), m_graphColor.green(), m_graphColor.blue(), 100); QVector * samps = &(model()->m_samples); int length = model()->length(); const float maxVal = model()->maxValue(); const float minVal = model()->minValue(); - float xscale = (float)( width()-4 ) / length; - float yscale = (float)( height()-4 ) / ( minVal - maxVal ); + float xscale = (float)(width()-4) / length; + float yscale = (float)(height()-4) / (minVal - maxVal); // Max index, more useful below length--; - switch( m_graphStyle ) + switch (m_graphStyle) { case Graph::LinearStyle: - p.setRenderHints( QPainter::Antialiasing, true ); + p.setRenderHints(QPainter::Antialiasing, true); - for( int i=0; i < length; i++ ) + for (int i=0; i < length; i++) { // Needs to be rewritten p.drawLine( 2+static_cast(i*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast(((*samps)[i] - maxVal) * yscale), 2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) + 2+static_cast(((*samps)[i+1] - maxVal) * yscale) ); } // Draw last segment wrapped around p.drawLine(2+static_cast(length*xscale), - 2+static_cast( ( (*samps)[length] - maxVal ) * yscale ), + 2+static_cast(((*samps)[length] - maxVal) * yscale), width()-3, - 2+static_cast( ( (*samps)[0] - maxVal ) * yscale ) ); + 2+static_cast(((*samps)[0] - maxVal) * yscale)); - p.setRenderHints( QPainter::Antialiasing, false ); + p.setRenderHints(QPainter::Antialiasing, false); break; case Graph::NearestStyle: - for( int i=0; i < length; i++ ) + for (int i=0; i < length; i++) { p.drawLine(2+static_cast(i*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast(((*samps)[i] - maxVal) * yscale), 2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) + 2+static_cast(((*samps)[i] - maxVal) * yscale) ); p.drawLine(2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast(((*samps)[i] - maxVal) * yscale), 2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) + 2+static_cast(((*samps)[i+1] - maxVal) * yscale) ); } p.drawLine(2+static_cast(length*xscale), - 2+static_cast( ( (*samps)[length] - maxVal ) * yscale ), + 2+static_cast(((*samps)[length] - maxVal) * yscale), width()-3, - 2+static_cast( ( (*samps)[length] - maxVal ) * yscale ) ); + 2+static_cast(((*samps)[length] - maxVal) * yscale)); break; case Graph::LinearNonCyclicStyle: - p.setRenderHints( QPainter::Antialiasing, true ); + p.setRenderHints(QPainter::Antialiasing, true); - for( int i=0; i < length; i++ ) + for (int i=0; i < length; i++) { // Needs to be rewritten p.drawLine( 2+static_cast(i*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast(((*samps)[i] - maxVal) * yscale), 2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) + 2+static_cast(((*samps)[i+1] - maxVal) * yscale) ); } // Do not draw last segment wrapped around - hence, "non-cyclic" - p.setRenderHints( QPainter::Antialiasing, false ); + p.setRenderHints(QPainter::Antialiasing, false); break; case Graph::BarStyle: - for( int i=0; i <= length; i++ ) + for (int i=0; i <= length; i++) { - p.fillRect( 2+static_cast( i*xscale ), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), - qMax( static_cast(xscale) - 1, 1 ), - qMax( static_cast( ( minVal - maxVal ) * yscale ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), 1 ), - gcol ); - - p.setPen( QPen( m_graphColor, 1.0 ) ); - - p.drawLine( 2+static_cast(i*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), - qMax( static_cast(i*xscale) + static_cast(xscale), 2+static_cast(i*xscale) ), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) + p.fillRect(2+static_cast(i*xscale), + 2+static_cast(((*samps)[i] - maxVal) * yscale), + qMax(static_cast(xscale) - 1, 1), + qMax(static_cast((minVal - maxVal) * yscale) - static_cast(((*samps)[i] - maxVal) * yscale), 1), + gcol); + + p.setPen(QPen(m_graphColor, 1.0)); + + p.drawLine(2+static_cast(i*xscale), + 2+static_cast(((*samps)[i] - maxVal) * yscale), + qMax(static_cast(i*xscale) + static_cast(xscale), 2+static_cast(i*xscale)), + 2+static_cast(((*samps)[i] - maxVal) * yscale) ); } break; case Graph::BarCenterGradStyle: m_foreground.fill(Qt::transparent); - for( int i=0; i <= length; i++ ) + for (int i=0; i <= length; i++) { QLinearGradient gradient(0, 0, 0, height() / 2.f); gradient.setSpread(QGradient::Spread(1));// ReflectSpread, so gradient on bottom half is a reflection of the top half gradient.setColorAt(0, QColor::fromRgbF(m_graphColor.red() / 256.f, m_graphColor.green() / 256.f, m_graphColor.blue() / 256.f, 0.55)); gradient.setColorAt(1, QColor::fromRgbF(m_graphColor.red() / 256.f, m_graphColor.green() / 256.f, m_graphColor.blue() / 256.f, 0)); - if( (*samps)[i] >= 0 )// Graph value is above middle + if ((*samps)[i] >= 0)// Graph value is above middle { - p.fillRect( 2+static_cast( i*xscale ), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), - static_cast( (i+1)*xscale ) - static_cast( i*xscale ), - qMax( static_cast( ( ( minVal - maxVal ) * yscale ) / 2.f ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), 1 ), - gradient ); + p.fillRect(2+static_cast(i*xscale), + 2+static_cast(((*samps)[i] - maxVal) * yscale), + static_cast((i+1)*xscale) - static_cast(i*xscale), + qMax(static_cast(((minVal - maxVal) * yscale) / 2.f) - static_cast(((*samps)[i] - maxVal) * yscale), 1), + gradient); } else// Graph value is below middle { - p.fillRect( 2+static_cast( i*xscale ), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), - static_cast( (i+1)*xscale ) - static_cast( i*xscale ), - static_cast( ( ( minVal - maxVal ) * yscale ) / 2.f ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), - gradient ); + p.fillRect(2+static_cast(i*xscale), + 2+static_cast(((*samps)[i] - maxVal) * yscale), + static_cast((i+1)*xscale) - static_cast(i*xscale), + static_cast(((minVal - maxVal) * yscale) / 2.f) - static_cast(((*samps)[i] - maxVal) * yscale), + gradient); } - p.setPen( QPen( m_graphColor, 1.0 ) ); + p.setPen(QPen(m_graphColor, 1.0)); p.drawLine(2+static_cast(i*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast(((*samps)[i] - maxVal) * yscale), 2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) + 2+static_cast(((*samps)[i] - maxVal) * yscale) ); - if( i != length )// So (*samps)[i+1] doesn't grab something too far + if (i != length)// So (*samps)[i+1] doesn't grab something too far { p.drawLine(2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + 2+static_cast(((*samps)[i] - maxVal) * yscale), 2+static_cast((i+1)*xscale), - 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) + 2+static_cast(((*samps)[i+1] - maxVal) * yscale) ); } } @@ -433,37 +433,37 @@ void Graph::paintEvent( QPaintEvent * ) // draw Pointer - if( m_mouseDown ) + if (m_mouseDown) { - QPoint cursor = mapFromGlobal( QCursor::pos() ); - p.setPen( QColor( 0x70, 0x7C, 0x91 ) ); - p.drawLine( 2, cursor.y(), width()-2, cursor.y() ); - p.drawLine( cursor.x(), 2, cursor.x(), height()-2 ); + QPoint cursor = mapFromGlobal(QCursor::pos()); + p.setPen(QColor(0x70, 0x7C, 0x91)); + p.drawLine(2, cursor.y(), width()-2, cursor.y()); + p.drawLine(cursor.x(), 2, cursor.x(), height()-2); } - p.drawPixmap( 0, 0, m_foreground ); + p.drawPixmap(0, 0, m_foreground); } -void Graph::dropEvent( QDropEvent * _de ) +void Graph::dropEvent(QDropEvent * de) { - QString type = StringPairDrag::decodeKey( _de ); - QString value = StringPairDrag::decodeValue( _de ); + QString type = StringPairDrag::decodeKey(de); + QString value = StringPairDrag::decodeValue(de); - if( type == "samplefile" ) + if (type == "samplefile") { // TODO: call setWaveToUser - // loadSampleFromFile( value ); - _de->accept(); + // loadSampleFromFile(value); + de->accept(); } } -void Graph::dragEnterEvent( QDragEnterEvent * _dee ) +void Graph::dragEnterEvent(QDragEnterEvent * dee) { - if( StringPairDrag::processDragEnterEvent( _dee, - QString( "samplefile" ) ) == false ) + if (StringPairDrag::processDragEnterEvent(dee, + QString("samplefile")) == false) { - _dee->ignore(); + dee->ignore(); } } @@ -473,15 +473,15 @@ void Graph::modelChanged() { graphModel * gModel = castModel(); - QObject::connect( gModel, SIGNAL( samplesChanged( int, int ) ), - this, SLOT( updateGraph( int, int ) ) ); + QObject::connect(gModel, SIGNAL(samplesChanged(int, int)), + this, SLOT(updateGraph(int, int))); - QObject::connect( gModel, SIGNAL( lengthChanged( ) ), - this, SLOT( updateGraph( ) ) ); + QObject::connect(gModel, SIGNAL(lengthChanged()), + this, SLOT(updateGraph())); } -void Graph::updateGraph( int _startPos, int _endPos ) +void Graph::updateGraph(int startPos, int endPos) { // Can optimize by only drawing changed position update(); @@ -490,34 +490,34 @@ void Graph::updateGraph( int _startPos, int _endPos ) void Graph::updateGraph() { - updateGraph( 0, model()->length() - 1 ); + updateGraph(0, model()->length() - 1); } -graphModel::graphModel( float _min, float _max, int _length, - ::Model * _parent, bool _default_constructed, float _step ) : - Model( _parent, tr( "Graph" ), _default_constructed ), - m_samples( _length ), - m_length( _length ), - m_minValue( _min ), - m_maxValue( _max ), - m_step( _step ) +graphModel::graphModel(float min, float max, int length, + ::Model * parent, bool default_constructed, float step) : + Model(parent, tr("Graph"), default_constructed), + m_samples(length), + m_length(length), + m_minValue(min), + m_maxValue(max), + m_step(step) { } -void graphModel::setRange( float _min, float _max ) +void graphModel::setRange(float min, float max) { - if( _min != m_minValue || _max != m_maxValue ) + if (min != m_minValue || max != m_maxValue) { - m_minValue = _min; - m_maxValue = _max; + m_minValue = min; + m_maxValue = max; - if( !m_samples.isEmpty() ) + if (!m_samples.isEmpty()) { // Trim existing values - for( int i=0; i < length(); i++ ) + for (int i=0; i < length(); i++) { - m_samples[i] = fmaxf( _min, fminf( m_samples[i], _max ) ); + m_samples[i] = fmaxf(min, fminf(m_samples[i], max)); } } @@ -527,14 +527,14 @@ void graphModel::setRange( float _min, float _max ) -void graphModel::setLength( int _length ) +void graphModel::setLength(int length) { - if( _length != m_length ) + if (length != m_length) { - m_length = _length; - if( m_samples.size() < m_length ) + m_length = length; + if (m_samples.size() < m_length) { - m_samples.resize( m_length ); + m_samples.resize(m_length); } emit lengthChanged(); } @@ -542,104 +542,104 @@ void graphModel::setLength( int _length ) -void graphModel::setSampleAt( int x, float val ) +void graphModel::setSampleAt(int x, float val) { - drawSampleAt( x, val ); - emit samplesChanged( x, x ); + drawSampleAt(x, val); + emit samplesChanged(x, x); } -void graphModel::setSamples( const float * _samples ) +void graphModel::setSamples(const float * samples) { - std::copy( _samples, _samples + length(), m_samples.begin()); + std::copy(samples, samples + length(), m_samples.begin()); - emit samplesChanged( 0, length()-1 ); + emit samplesChanged(0, length()-1); } void graphModel::setWaveToSine() { - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { m_samples[i] = Oscillator::sinSample( - i / static_cast( length() ) ); + i / static_cast(length())); } - emit samplesChanged( 0, length() - 1 ); + emit samplesChanged(0, length() - 1); }; void graphModel::setWaveToTriangle() { - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { m_samples[i] = Oscillator::triangleSample( - i / static_cast( length() ) ); + i / static_cast(length())); } - emit samplesChanged( 0, length() - 1 ); + emit samplesChanged(0, length() - 1); }; void graphModel::setWaveToSaw() { - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { m_samples[i] = Oscillator::sawSample( - i / static_cast( length() ) ); + i / static_cast(length())); } - emit samplesChanged( 0, length() - 1 ); + emit samplesChanged(0, length() - 1); }; void graphModel::setWaveToSquare() { - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { m_samples[i] = Oscillator::squareSample( - i / static_cast( length() ) ); + i / static_cast(length())); } - emit samplesChanged( 0, length() - 1 ); + emit samplesChanged(0, length() - 1); }; void graphModel::setWaveToNoise() { - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { m_samples[i] = Oscillator::noiseSample( - i / static_cast( length() ) ); + i / static_cast(length())); } - emit samplesChanged( 0, length() - 1 ); + emit samplesChanged(0, length() - 1); }; QString graphModel::setWaveToUser() { SampleBuffer * sampleBuffer = new SampleBuffer; QString fileName = sampleBuffer->openAndSetWaveformFile(); - if( fileName.isEmpty() == false ) + if (fileName.isEmpty() == false) { sampleBuffer->dataReadLock(); - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { m_samples[i] = sampleBuffer->userWaveSample( - i / static_cast( length() ) ); + i / static_cast(length())); } sampleBuffer->dataUnlock(); } - sharedObject::unref( sampleBuffer ); + sharedObject::unref(sampleBuffer); - emit samplesChanged( 0, length() - 1 ); + emit samplesChanged(0, length() - 1); return fileName; }; @@ -651,12 +651,12 @@ void graphModel::smooth() QVector temp = m_samples; // Smoothing - m_samples[0] = ( temp[length()-1] + ( temp[0] * 2 ) + temp[1] ) * 0.25f; - for ( int i=1; i < ( length()-1 ); i++ ) + m_samples[0] = (temp[length()-1] + (temp[0] * 2) + temp[1]) * 0.25f; + for (int i=1; i < (length()-1); i++) { - m_samples[i] = ( temp[i-1] + ( temp[i] * 2 ) + temp[i+1] ) * 0.25f; + m_samples[i] = (temp[i-1] + (temp[i] * 2) + temp[i+1]) * 0.25f; } - m_samples[length()-1] = ( temp[length()-2] + ( temp[length()-1] * 2 ) + temp[0] ) * 0.25f; + m_samples[length()-1] = (temp[length()-2] + (temp[length()-1] * 2) + temp[0]) * 0.25f; emit samplesChanged(0, length()-1); } @@ -667,12 +667,12 @@ void graphModel::smoothNonCyclic() QVector temp = m_samples; // Smoothing - //m_samples[0] = ( ( temp[0] * 3 ) + temp[1] ) * 0.25f; - for ( int i=1; i < ( length()-1 ); i++ ) + //m_samples[0] = ((temp[0] * 3) + temp[1]) * 0.25f; + for (int i=1; i < (length()-1); i++) { - m_samples[i] = ( temp[i-1] + ( temp[i] * 2 ) + temp[i+1] ) * 0.25f; + m_samples[i] = (temp[i-1] + (temp[i] * 2) + temp[i+1]) * 0.25f; } - //m_samples[length()-1] = ( temp[length()-2] + ( temp[length()-1] * 3 ) ) * 0.25f; + //m_samples[length()-1] = (temp[length()-2] + (temp[length()-1] * 3)) * 0.25f; emit samplesChanged(0, length()-1); } @@ -685,14 +685,14 @@ void graphModel::convolve(const float *convolution, const int graphLength = length(); float sum; // make a cyclic convolution - for ( int i = 0; i < graphLength; i++ ) + for (int i = 0; i < graphLength; i++) { sum = 0; - for ( int j = 0; j < convolutionLength; j++ ) + for (int j = 0; j < convolutionLength; j++) { - sum += convolution[j] * temp[( i + j ) % graphLength]; + sum += convolution[j] * temp[(i + j) % graphLength]; } - m_samples[( i + centerOffset ) % graphLength] = sum; + m_samples[(i + centerOffset) % graphLength] = sum; } emit samplesChanged(0, graphLength - 1); } @@ -703,22 +703,22 @@ void graphModel::normalize() float avg = 0.0f; // first correct dc offset by normalizing to average - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) avg += m_samples[i]; avg /= length(); - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) m_samples[i] -= avg; // then maximize - for( int i = 0; i < length(); i++ ) - max = qMax( max, qAbs( m_samples[i] ) ); + for (int i = 0; i < length(); i++) + max = qMax(max, qAbs(m_samples[i])); - for( int i = 0; i < length(); i++ ) - m_samples[i] = qBound( m_minValue, m_samples[i] / max, m_maxValue ); + for (int i = 0; i < length(); i++) + m_samples[i] = qBound(m_minValue, m_samples[i] / max, m_maxValue); // signal changes if any - if( max != 1.0f || avg != 0.0f ) - emit samplesChanged( 0, length()-1 ); + if (max != 1.0f || avg != 0.0f) + emit samplesChanged(0, length()-1); } @@ -727,39 +727,39 @@ void graphModel::invert() { const float range = m_maxValue - m_minValue; - for( int i = 0; i < length(); i++ ) - m_samples[i] = m_minValue + ( range - ( m_samples[i] - m_minValue ) ); + for (int i = 0; i < length(); i++) + m_samples[i] = m_minValue + (range - (m_samples[i] - m_minValue)); - emit samplesChanged( 0, length()-1 ); + emit samplesChanged(0, length()-1); } -void graphModel::shiftPhase( int _deg ) +void graphModel::shiftPhase(int deg) { // calculate offset in samples - const int offset = ( _deg * length() ) / 360; //multiply first because integers + const int offset = (deg * length()) / 360; //multiply first because integers // store values in temporary array QVector temp = m_samples; // shift phase - for( int i = 0; i < length(); i++ ) + for (int i = 0; i < length(); i++) { - int o = ( i + offset ) % length(); - while( o < 0 ) o += length(); + int o = (i + offset) % length(); + while (o < 0) o += length(); m_samples[i] = temp[o]; } - emit samplesChanged( 0, length()-1 ); + emit samplesChanged(0, length()-1); } void graphModel::clear() { const int graph_length = length(); - for( int i = 0; i < graph_length; i++ ) + for (int i = 0; i < graph_length; i++) m_samples[i] = 0; - emit samplesChanged( 0, graph_length - 1 ); + emit samplesChanged(0, graph_length - 1); } @@ -768,19 +768,19 @@ void graphModel::clearInvisible() { const int graph_length = length(); const int full_graph_length = m_samples.size(); - for( int i = graph_length; i < full_graph_length; i++ ) + for (int i = graph_length; i < full_graph_length; i++) m_samples[i] = 0; - emit samplesChanged( graph_length, full_graph_length - 1 ); + emit samplesChanged(graph_length, full_graph_length - 1); } -void graphModel::drawSampleAt( int x, float val ) +void graphModel::drawSampleAt(int x, float val) { //snap to the grid - val -= ( m_step != 0.0 ) ? fmod( val, m_step ) * m_step : 0; + val -= (m_step != 0.0) ? fmod(val, m_step) * m_step : 0; // boundary crop - x = qMax( 0, qMin( length()-1, x ) ); - val = qMax( minValue(), qMin( maxValue(), val ) ); + x = qMax(0, qMin(length()-1, x)); + val = qMax(minValue(), qMin(maxValue(), val)); // change sample shape m_samples[x] = val; From 5f71d7cf9e1c9947a22e8878f1f4df5360c5290c Mon Sep 17 00:00:00 2001 From: root Date: Tue, 4 Jun 2019 17:12:59 -0600 Subject: [PATCH 04/12] Revert Graph style changes and tweak Microwave comments --- include/Graph.h | 114 +++----- plugins/Microwave/Microwave.cpp | 81 +----- src/gui/widgets/Graph.cpp | 489 ++++++++++++++++---------------- 3 files changed, 297 insertions(+), 387 deletions(-) diff --git a/include/Graph.h b/include/Graph.h index d5da70c86ed..4bce31f5ba3 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -1,7 +1,7 @@ /* * Graph.h - a QT widget for displaying and manipulating waveforms * - * Copyright (c)2006-2007 Andreas Brandmaier + * Copyright (c) 2006-2007 Andreas Brandmaier * 2008 Paul Giblock * * This file is part of LMMS - https://lmms.io @@ -9,7 +9,7 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option)any later version. + * 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 @@ -52,21 +52,16 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView BarCenterGradStyle //!< draw color gradient coming from center }; - /** - * @brief Constructor - * @param width Pixel width of widget - * @param height Pixel height of widget - */ - Graph(QWidget * parent, graphStyle style = Graph::LinearStyle, - int width = 132, - int height = 104 + Graph( QWidget * _parent, graphStyle _style = Graph::LinearStyle, + int _width = 132, + int _height = 104 ); - virtual ~Graph()= default; + virtual ~Graph() = default; - void setForeground(const QPixmap & pixmap); + void setForeground( const QPixmap & _pixmap ); - void setGraphColor(const QColor); + void setGraphColor( const QColor ); inline graphModel * model() { @@ -79,31 +74,31 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView } - inline void setGraphStyle(graphStyle s) + inline void setGraphStyle( graphStyle _s ) { - m_graphStyle = s; + m_graphStyle = _s; update(); } signals: void drawn(); protected: - virtual void paintEvent(QPaintEvent * pe); - virtual void dropEvent(QDropEvent * de); - virtual void dragEnterEvent(QDragEnterEvent * dee); - virtual void mousePressEvent(QMouseEvent * me); - virtual void mouseMoveEvent(QMouseEvent * me); - virtual void mouseReleaseEvent(QMouseEvent * me); + virtual void paintEvent( QPaintEvent * _pe ); + virtual void dropEvent( QDropEvent * _de ); + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void mousePressEvent( QMouseEvent * _me ); + virtual void mouseMoveEvent( QMouseEvent * _me ); + virtual void mouseReleaseEvent( QMouseEvent * _me ); protected slots: - void updateGraph(int startPos, int endPos); + void updateGraph( int _startPos, int _endPos ); void updateGraph(); private: virtual void modelChanged(); - void changeSampleAt(int x, int y); - void drawLineAt(int x, int y, int lastx); + void changeSampleAt( int _x, int _y ); + void drawLineAt( int _x, int _y, int _lastx ); QPixmap m_foreground; @@ -117,94 +112,73 @@ protected slots: } ; -/** - @brief 2 dimensional function plot - - Function plot graph with discrete x scale and continous y scale - This makes it possible to display "#x" samples -*/ class LMMS_EXPORT graphModel : public Model { Q_OBJECT public: - /** - * @brief Constructor - * @param min Minimum y value to display - * @param max Maximum y value to display - * @param size Number of samples (e.g. x value) - * @param step Step size on y axis where values snap to, or 0.0f - * for "no snapping" - */ - graphModel(float min, - float max, - int size, - :: Model * parent, - bool default_constructed = false, - float step = 0.0); - - virtual ~graphModel()= default; + graphModel( float _min, + float _max, + int _size, + :: Model * _parent, + bool _default_constructed = false, + float _step = 0.0 ); + + virtual ~graphModel() = default; // TODO: saveSettings, loadSettings? - inline float minValue()const + inline float minValue() const { - return m_minValue; + return( m_minValue ); } - inline float maxValue()const + inline float maxValue() const { - return m_maxValue; + return( m_maxValue ); } - inline int length()const + inline int length() const { return m_length; } - inline const float * samples()const + inline const float * samples() const { - return m_samples.data(); + return( m_samples.data() ); } - //! Make cyclic convolution - //! @param convolution Samples to convolve with - //! @param convolutionLength Number of samples to take for each sum - //! @param centerOffset Offset for resulting values - void convolve(const float *convolution, - const int convolutionLength, const int centerOffset); + void convolve(const float *convolution, const int convolutionLength, const int centerOffset); public slots: - //! Set range of y values - void setRange(float min, float max); + void setRange( float _min, float _max ); + + void setLength( int _size ); - void setLength(int size); - //! Update one sample - void setSampleAt(int x, float val); - //! Update samples array - void setSamples(const float * value); + void setSampleAt( int x, float val ); + void setSamples( const float * _value ); void setWaveToSine(); void setWaveToTriangle(); void setWaveToSaw(); void setWaveToSquare(); void setWaveToNoise(); - QString setWaveToUser(); + QString setWaveToUser( ); void smooth(); void smoothNonCyclic(); void normalize(); void invert(); - void shiftPhase(int deg); + void shiftPhase( int _deg ); void clear(); void clearInvisible(); signals: void lengthChanged(); - void samplesChanged(int startPos, int endPos); + void samplesChanged( int startPos, int endPos ); void rangeChanged(); private: - void drawSampleAt(int x, float val); + void drawSampleAt( int x, float val ); QVector m_samples; int m_length; diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 18c37a0d02e..534995fba8e 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -85,37 +85,10 @@ Plugin::Descriptor PLUGIN_EXPORT microwave_plugin_descriptor = } -/* - ___ - ,' , `. - ,-+-,.' | ,--, - ,-+-. ; , ||,--.'| _ ,-. ,---. .---. - ,--.'|' | ;|| |, ,' ,'/ /| ' ,'\ /. ./| .---. -| | ,', | ':`--'_ ,---. ' | |' | / / | .-'-. ' | ,--.--. /. ./| ,---. -| | / | | ||,' ,'| / \| | ,'. ; ,. : /___/ \: | / \ .-' . ' | / \ -' | : | : |,' | | / / '' : / ' | |: : .-'.. ' ' ..--. .-. |/___/ \: | / / | -; . | ; |--' | | : . ' / | | ' ' | .; :/___/ \: ' \__\/: . .. \ ' .. ' / | -| : | | , ' : |__ ' ; :__; : | | : |. \ ' .\ ," .--.; | \ \ '' ; /| -| : ' |/ | | '.'|' | '.'| , ; \ \ / \ \ ' \ |/ / ,. | \ \ ' | / | -; | |`-' ; : ;| : :---' `----' \ \ |--"; : .' \ \ \ || : | -| ;/ | , / \ \ / \ \ | | , .-./ '---" \ \ / -'---' ---`-' `----' '---" `--`---' `----' - - .----------------. - /_____________ ___\ - ||\ ________ /|+++| - || |: :| |+++| - || |; (◕‿◕) ;| | + | - || |_________| | | - ||/___________\|[_]| - "------------------" - - (Do not m_scroll down if you value your sanity) - -*/ - - +//===============// +//== MICROWAVE ==// +//===============// Microwave::Microwave(InstrumentTrack * instrument_track) : Instrument(instrument_track, µwave_plugin_descriptor), @@ -1403,28 +1376,9 @@ inline void Microwave::fillMainOsc(int which, bool doInterpolate) -/* - - ___ - ,' , `. - ,-+-,.' | ,--, ,---. ,--, - ,-+-. ; , ||,--.'| _ ,-. ,---. .---. /__./|,--.'| .---. - ,--.'|' | ;|| |, ,' ,'/ /| ' ,'\ /. ./| .---. ,---.; ; || |, /. ./| -| | ,', | ':`--'_ ,---. ' | |' | / / | .-'-. ' | ,--.--. /. ./| ,---./___/ \ | |`--'_ ,---. .-'-. ' | -| | / | | ||,' ,'| / \| | ,'. ; ,. : /___/ \: | / \ .-' . ' | / \ ; \ ' |,' ,'| / \ /___/ \: | -' | : | : |,' | | / / '' : / ' | |: : .-'.. ' ' ..--. .-. |/___/ \: | / / \ \ \: |' | | / / | .-'.. ' ' . -; . | ; |--' | | : . ' / | | ' ' | .; :/___/ \: ' \__\/: . .. \ ' .. ' / |; \ ' .| | : . ' / |/___/ \: ' -| : | | , ' : |__ ' ; :__; : | | : |. \ ' .\ ," .--.; | \ \ '' ; /| \ \ '' : |__ ' ; /|. \ ' .\ -| : ' |/ | | '.'|' | '.'| , ; \ \ / \ \ ' \ |/ / ,. | \ \ ' | / | \ ` ;| | '.'|' | / | \ \ ' \ | -; | |`-' ; : ;| : :---' `----' \ \ |--"; : .' \ \ \ || : | : \ |; : ;| : | \ \ |--" -| ;/ | , / \ \ / \ \ | | , .-./ '---" \ \ / '---" | , / \ \ / \ \ | -'---' ---`-' `----' '---" `--`---' `----' ---`-' `----' '---" - - - -*/ - - +//===================// +//== MICROWAVEVIEW ==// +//===================// // Creates the Microwave GUI. Creates all GUI elements. Connects some events to some functions. Calls updateScroll() to put all of the GUI elements in their correct positions. MicrowaveView::MicrowaveView(Instrument * instrument, @@ -3636,26 +3590,9 @@ void MicrowaveView::dragEnterEvent(QDragEnterEvent * dee) -/* - - ___ .--.--. __ ,---, - ,' , `. / / '. ,--.'|_ ,--.' | - ,-+-,.' || : /`. / ,---, | | :,' | | : - ,-+-. ; , ||; | |--` ,-+-. / | : : ' : : : : - ,--.'|' | ||| : ;_ .--, ,--.'|' |.;__,' / : | |,--. -| | ,', | |, \ \ `. /_ ./| | | ,"' || | | | : ' | -| | / | |--' `----. \, ' , ' : | | / | |:__,'| : | | /' : -| : | | , _ \ \ /___/ \: | | | | | | ' : |__ ' : | | | -| : | |/ / /`--' /. \ ' | | | | |/ | | '.'|| | ' | : -| | |`-' '--'. / \ ; : | | |--' ; : ;| : :_:,' -| ;/ `--'---' \ \ ; | |/ | , / | | ,' -'---' : \ \'---' ---`-' `--'' - \ ' ; - `--` -*/ - - - +//============// +//== MSYNTH ==// +//============// // Initializes mSynth (when a new note is played). Clone all of the arrays storing the knob values so they can be changed by modulation. mSynth::mSynth(NotePlayHandle * m_nph, diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index c0035966775..f213ad0ae5a 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -33,59 +33,59 @@ #include "Oscillator.h" -Graph::Graph(QWidget * parent, graphStyle style, int width, - int height) : - QWidget(parent), +Graph::Graph( QWidget * _parent, graphStyle _style, int _width, + int _height ) : + QWidget( _parent ), /* TODO: size, background? */ - ModelView(new graphModel(-1.0, 1.0, 128, NULL, true), this), - m_graphStyle(style) + ModelView( new graphModel( -1.0, 1.0, 128, NULL, true ), this ), + m_graphStyle( _style ) { m_mouseDown = false; - m_graphColor = QColor(0xFF, 0xAA, 0x00); + m_graphColor = QColor( 0xFF, 0xAA, 0x00 ); - resize(width, height); - setAcceptDrops(true); - setCursor(Qt::CrossCursor); + resize( _width, _height ); + setAcceptDrops( true ); + setCursor( Qt::CrossCursor ); graphModel * gModel = castModel(); - QObject::connect(gModel, SIGNAL(samplesChanged(int, int)), - this, SLOT(updateGraph(int, int))); + QObject::connect( gModel, SIGNAL( samplesChanged( int, int ) ), + this, SLOT( updateGraph( int, int ) ) ); - QObject::connect(gModel, SIGNAL(lengthChanged()), - this, SLOT(updateGraph())); + QObject::connect( gModel, SIGNAL( lengthChanged( ) ), + this, SLOT( updateGraph( ) ) ); } -void Graph::setForeground(const QPixmap &pixmap) +void Graph::setForeground( const QPixmap &_pixmap ) { - m_foreground = pixmap; + m_foreground = _pixmap; } -void Graph::setGraphColor(QColor graphcol) +void Graph::setGraphColor( QColor _graphcol ) { - m_graphColor = graphcol; + m_graphColor = _graphcol; } /* -void graph::loadSampleFromFile(const QString & filename) +void graph::loadSampleFromFile( const QString & _filename ) { int i; // zero sample_shape - for (i = 0; i < sampleLength; i++) + for( i = 0; i < sampleLength; i++ ) { samplePointer[i] = 0; } // load user shape - sampleBuffer buffer(filename); + sampleBuffer buffer( _filename ); // copy buffer data - int trimSize = fmin(size(), static_cast(buffer.frames())); + int trimSize = fmin( size(), static_cast(buffer.frames()) ); - for (i = 0; i < trimSize; i++) + for( i = 0; i < trimSize; i++ ) { samplePointer[i] = (float)*buffer.data()[i]; } @@ -94,15 +94,15 @@ void graph::loadSampleFromFile(const QString & filename) -void Graph::mouseMoveEvent (QMouseEvent * me) +void Graph::mouseMoveEvent ( QMouseEvent * _me ) { // get position - int x = me->x(); - int y = me->y(); + int x = _me->x(); + int y = _me->y(); /* static bool skip = false; - if (skip) + if( skip ) { skip = false; return; @@ -111,29 +111,29 @@ void Graph::mouseMoveEvent (QMouseEvent * me) // avoid mouse leaps int diff = x - m_lastCursorX; -/* if (diff >= 1) +/* if( diff >= 1 ) { - x = qMin(width() - 3, m_lastCursorX + 1); + x = qMin( width() - 3, m_lastCursorX + 1 ); } - else if (diff <= -1) + else if( diff <= -1 ) { - x = qMax(2, m_lastCursorX - 1); + x = qMax( 2, m_lastCursorX - 1 ); }*/ - x = qMax(2, qMin(x, width()-3)); - y = qMax(2, qMin(y, height()-3)); + x = qMax( 2, qMin( x, width()-3 ) ); + y = qMax( 2, qMin( y, height()-3 ) ); - drawLineAt(x, y, m_lastCursorX); + drawLineAt( x, y, m_lastCursorX ); // update mouse - if (diff != 0) + if( diff != 0 ) { m_lastCursorX = x; - QPoint pt = mapToGlobal(QPoint(x, y)); + QPoint pt = mapToGlobal( QPoint( x, y ) ); - QCursor::setPos(pt.x(), pt.y()); + QCursor::setPos( pt.x(), pt.y() ); } // skip = true; @@ -141,80 +141,80 @@ void Graph::mouseMoveEvent (QMouseEvent * me) -void Graph::mousePressEvent(QMouseEvent * me) +void Graph::mousePressEvent( QMouseEvent * _me ) { - if (me->button() == Qt::LeftButton) + if( _me->button() == Qt::LeftButton ) { - if (!(me->modifiers() & Qt::ShiftModifier)) + if ( !( _me->modifiers() & Qt::ShiftModifier ) ) { // get position - int x = me->x(); - int y = me->y(); + int x = _me->x(); + int y = _me->y(); - changeSampleAt(x, y); + changeSampleAt( x, y ); // toggle mouse state m_mouseDown = true; - setCursor(Qt::BlankCursor); + setCursor( Qt::BlankCursor ); m_lastCursorX = x; } else { //when shift-clicking, draw a line from last position to current //position - int x = me->x(); - int y = me->y(); + int x = _me->x(); + int y = _me->y(); - drawLineAt(x, y, m_lastCursorX); + drawLineAt( x, y, m_lastCursorX ); m_mouseDown = true; - setCursor(Qt::BlankCursor); + setCursor( Qt::BlankCursor ); m_lastCursorX = x; } } } -void Graph::drawLineAt(int x, int y, int lastx) +void Graph::drawLineAt( int _x, int _y, int _lastx ) { float minVal = model()->minValue(); float maxVal = model()->maxValue(); - if (width() <= 4) + if ( width() <= 4 ) { return; } - float xscale = static_cast(model()->length()) / - (width()-4); + float xscale = static_cast( model()->length() ) / + ( width()-4 ); //consider border - x -= 2; - y -= 2; - lastx -= 2; + _x -= 2; + _y -= 2; + _lastx -= 2; - lastx = qMax(0, qMin(lastx, width()-5)); + _lastx = qMax( 0, qMin( _lastx, width()-5 ) ); float range = minVal - maxVal; - float val = (y*range/(height()-5)) + maxVal; + float val = ( _y*range/( height()-5 ) ) + maxVal; int sample_begin, sample_end; float lastval; float val_begin, val_end; - if (lastx > x) + if (_lastx > _x) { - sample_begin = (int)((x) * xscale); - sample_end = (int)ceil((lastx+1) * xscale); - lastval = model() -> m_samples[ (int)(sample_end - 1) ]; + sample_begin = (int)((_x) * xscale); + sample_end = (int)ceil((_lastx+1) * xscale); + lastval = model() -> m_samples[ (int)( sample_end - 1 ) ]; val_begin = val; val_end = lastval; } else { - sample_begin = (int)(lastx * xscale); - sample_end = (int)ceil((x+1) * xscale); - lastval = model() -> m_samples[ (int)(sample_begin) ]; + sample_begin = (int)(_lastx * xscale); + sample_end = (int)ceil((_x+1) * xscale); + lastval = model() -> m_samples[ (int)( sample_begin ) ]; val_begin = lastval; val_end = val; @@ -226,53 +226,53 @@ void Graph::drawLineAt(int x, int y, int lastx) { val_begin = val; } - //int xstep = x > lastx ? -1 : 1; - float ystep = (val_end - val_begin) / linelen; + //int xstep = _x > _lastx ? -1 : 1; + float ystep = ( val_end - val_begin ) / linelen; // draw a line - for (int i = 0 ; i < linelen; i++) + for ( int i = 0 ; i < linelen; i++ ) { - model()->drawSampleAt(sample_begin + i , val_begin + ((i) * ystep)); + model()->drawSampleAt( sample_begin + i , val_begin + ((i ) * ystep)); } - model()->samplesChanged(sample_begin, sample_end); + model()->samplesChanged( sample_begin, sample_end ); } -void Graph::changeSampleAt(int x, int y) +void Graph::changeSampleAt( int _x, int _y ) { float minVal = model()->minValue(); float maxVal = model()->maxValue(); - if (width() <= 4) + if ( width() <= 4 ) { return; } - float xscale = static_cast(model()->length()) / - (width()-4); + float xscale = static_cast( model()->length() ) / + ( width()-4 ); // consider border of background image - x -= 2; - y -= 2; + _x -= 2; + _y -= 2; // subtract max from min because Qt's Y-axis is backwards float range = minVal - maxVal; - float val = (y*range/(height()-5)) + maxVal; + float val = ( _y*range/( height()-5 ) ) + maxVal; - model()->setSampleAt((int)(x*xscale), val); + model()->setSampleAt( (int)( _x*xscale ), val ); } -void Graph::mouseReleaseEvent(QMouseEvent * me) +void Graph::mouseReleaseEvent( QMouseEvent * _me ) { - if (me->button() == Qt::LeftButton) + if( _me->button() == Qt::LeftButton ) { // toggle mouse state m_mouseDown = false; - setCursor(Qt::CrossCursor); + setCursor( Qt::CrossCursor ); update(); emit drawn(); } @@ -280,149 +280,149 @@ void Graph::mouseReleaseEvent(QMouseEvent * me) -void Graph::paintEvent(QPaintEvent *) +void Graph::paintEvent( QPaintEvent * ) { - QPainter p(this); + QPainter p( this ); - p.setPen(QPen(m_graphColor, 1)); - QColor gcol = QColor(m_graphColor.red(), m_graphColor.green(), m_graphColor.blue(), 100); + p.setPen( QPen( m_graphColor, 1 ) ); + QColor gcol = QColor( m_graphColor.red(), m_graphColor.green(), m_graphColor.blue(), 100 ); QVector * samps = &(model()->m_samples); int length = model()->length(); const float maxVal = model()->maxValue(); const float minVal = model()->minValue(); - float xscale = (float)(width()-4) / length; - float yscale = (float)(height()-4) / (minVal - maxVal); + float xscale = (float)( width()-4 ) / length; + float yscale = (float)( height()-4 ) / ( minVal - maxVal ); // Max index, more useful below length--; - switch (m_graphStyle) + switch( m_graphStyle ) { case Graph::LinearStyle: - p.setRenderHints(QPainter::Antialiasing, true); + p.setRenderHints( QPainter::Antialiasing, true ); - for (int i=0; i < length; i++) + for( int i=0; i < length; i++ ) { // Needs to be rewritten p.drawLine( 2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), 2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i+1] - maxVal) * yscale) + 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) ); } // Draw last segment wrapped around p.drawLine(2+static_cast(length*xscale), - 2+static_cast(((*samps)[length] - maxVal) * yscale), + 2+static_cast( ( (*samps)[length] - maxVal ) * yscale ), width()-3, - 2+static_cast(((*samps)[0] - maxVal) * yscale)); + 2+static_cast( ( (*samps)[0] - maxVal ) * yscale ) ); - p.setRenderHints(QPainter::Antialiasing, false); + p.setRenderHints( QPainter::Antialiasing, false ); break; case Graph::NearestStyle: - for (int i=0; i < length; i++) + for( int i=0; i < length; i++ ) { p.drawLine(2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), 2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale) + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) ); p.drawLine(2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), 2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i+1] - maxVal) * yscale) + 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) ); } p.drawLine(2+static_cast(length*xscale), - 2+static_cast(((*samps)[length] - maxVal) * yscale), + 2+static_cast( ( (*samps)[length] - maxVal ) * yscale ), width()-3, - 2+static_cast(((*samps)[length] - maxVal) * yscale)); + 2+static_cast( ( (*samps)[length] - maxVal ) * yscale ) ); break; case Graph::LinearNonCyclicStyle: - p.setRenderHints(QPainter::Antialiasing, true); + p.setRenderHints( QPainter::Antialiasing, true ); - for (int i=0; i < length; i++) + for( int i=0; i < length; i++ ) { // Needs to be rewritten p.drawLine( 2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), 2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i+1] - maxVal) * yscale) + 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) ); } // Do not draw last segment wrapped around - hence, "non-cyclic" - p.setRenderHints(QPainter::Antialiasing, false); + p.setRenderHints( QPainter::Antialiasing, false ); break; case Graph::BarStyle: - for (int i=0; i <= length; i++) + for( int i=0; i <= length; i++ ) { - p.fillRect(2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), - qMax(static_cast(xscale) - 1, 1), - qMax(static_cast((minVal - maxVal) * yscale) - static_cast(((*samps)[i] - maxVal) * yscale), 1), - gcol); - - p.setPen(QPen(m_graphColor, 1.0)); - - p.drawLine(2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), - qMax(static_cast(i*xscale) + static_cast(xscale), 2+static_cast(i*xscale)), - 2+static_cast(((*samps)[i] - maxVal) * yscale) + p.fillRect( 2+static_cast( i*xscale ), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + qMax( static_cast(xscale) - 1, 1 ), + qMax( static_cast( ( minVal - maxVal ) * yscale ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), 1 ), + gcol ); + + p.setPen( QPen( m_graphColor, 1.0 ) ); + + p.drawLine( 2+static_cast(i*xscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + qMax( static_cast(i*xscale) + static_cast(xscale), 2+static_cast(i*xscale) ), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) ); } break; case Graph::BarCenterGradStyle: m_foreground.fill(Qt::transparent); - for (int i=0; i <= length; i++) + for( int i=0; i <= length; i++ ) { QLinearGradient gradient(0, 0, 0, height() / 2.f); gradient.setSpread(QGradient::Spread(1));// ReflectSpread, so gradient on bottom half is a reflection of the top half gradient.setColorAt(0, QColor::fromRgbF(m_graphColor.red() / 256.f, m_graphColor.green() / 256.f, m_graphColor.blue() / 256.f, 0.55)); gradient.setColorAt(1, QColor::fromRgbF(m_graphColor.red() / 256.f, m_graphColor.green() / 256.f, m_graphColor.blue() / 256.f, 0)); - if ((*samps)[i] >= 0)// Graph value is above middle + if( (*samps)[i] >= 0 )// Graph value is above middle { - p.fillRect(2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), - static_cast((i+1)*xscale) - static_cast(i*xscale), - qMax(static_cast(((minVal - maxVal) * yscale) / 2.f) - static_cast(((*samps)[i] - maxVal) * yscale), 1), - gradient); + p.fillRect( 2+static_cast( i*xscale ), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + static_cast( (i+1)*xscale ) - static_cast( i*xscale ), + qMax( static_cast( ( ( minVal - maxVal ) * yscale ) / 2.f ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), 1 ), + gradient ); } else// Graph value is below middle { - p.fillRect(2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), - static_cast((i+1)*xscale) - static_cast(i*xscale), - static_cast(((minVal - maxVal) * yscale) / 2.f) - static_cast(((*samps)[i] - maxVal) * yscale), - gradient); + p.fillRect( 2+static_cast( i*xscale ), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), + static_cast( (i+1)*xscale ) - static_cast( i*xscale ), + static_cast( ( ( minVal - maxVal ) * yscale ) / 2.f ) - static_cast( ( (*samps)[i] - maxVal ) * yscale ), + gradient ); } - p.setPen(QPen(m_graphColor, 1.0)); + p.setPen( QPen( m_graphColor, 1.0 ) ); p.drawLine(2+static_cast(i*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), 2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale) + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ) ); - if (i != length)// So (*samps)[i+1] doesn't grab something too far + if( i != length )// So (*samps)[i+1] doesn't grab something too far { p.drawLine(2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i] - maxVal) * yscale), + 2+static_cast( ( (*samps)[i] - maxVal ) * yscale ), 2+static_cast((i+1)*xscale), - 2+static_cast(((*samps)[i+1] - maxVal) * yscale) + 2+static_cast( ( (*samps)[i+1] - maxVal ) * yscale ) ); } } @@ -433,37 +433,37 @@ void Graph::paintEvent(QPaintEvent *) // draw Pointer - if (m_mouseDown) + if( m_mouseDown ) { - QPoint cursor = mapFromGlobal(QCursor::pos()); - p.setPen(QColor(0x70, 0x7C, 0x91)); - p.drawLine(2, cursor.y(), width()-2, cursor.y()); - p.drawLine(cursor.x(), 2, cursor.x(), height()-2); + QPoint cursor = mapFromGlobal( QCursor::pos() ); + p.setPen( QColor( 0x70, 0x7C, 0x91 ) ); + p.drawLine( 2, cursor.y(), width()-2, cursor.y() ); + p.drawLine( cursor.x(), 2, cursor.x(), height()-2 ); } - p.drawPixmap(0, 0, m_foreground); + p.drawPixmap( 0, 0, m_foreground ); } -void Graph::dropEvent(QDropEvent * de) +void Graph::dropEvent( QDropEvent * _de ) { - QString type = StringPairDrag::decodeKey(de); - QString value = StringPairDrag::decodeValue(de); + QString type = StringPairDrag::decodeKey( _de ); + QString value = StringPairDrag::decodeValue( _de ); - if (type == "samplefile") + if( type == "samplefile" ) { // TODO: call setWaveToUser - // loadSampleFromFile(value); - de->accept(); + // loadSampleFromFile( value ); + _de->accept(); } } -void Graph::dragEnterEvent(QDragEnterEvent * dee) +void Graph::dragEnterEvent( QDragEnterEvent * _dee ) { - if (StringPairDrag::processDragEnterEvent(dee, - QString("samplefile")) == false) + if( StringPairDrag::processDragEnterEvent( _dee, + QString( "samplefile" ) ) == false ) { - dee->ignore(); + _dee->ignore(); } } @@ -473,15 +473,15 @@ void Graph::modelChanged() { graphModel * gModel = castModel(); - QObject::connect(gModel, SIGNAL(samplesChanged(int, int)), - this, SLOT(updateGraph(int, int))); + QObject::connect( gModel, SIGNAL( samplesChanged( int, int ) ), + this, SLOT( updateGraph( int, int ) ) ); - QObject::connect(gModel, SIGNAL(lengthChanged()), - this, SLOT(updateGraph())); + QObject::connect( gModel, SIGNAL( lengthChanged( ) ), + this, SLOT( updateGraph( ) ) ); } -void Graph::updateGraph(int startPos, int endPos) +void Graph::updateGraph( int _startPos, int _endPos ) { // Can optimize by only drawing changed position update(); @@ -490,34 +490,34 @@ void Graph::updateGraph(int startPos, int endPos) void Graph::updateGraph() { - updateGraph(0, model()->length() - 1); + updateGraph( 0, model()->length() - 1 ); } -graphModel::graphModel(float min, float max, int length, - ::Model * parent, bool default_constructed, float step) : - Model(parent, tr("Graph"), default_constructed), - m_samples(length), - m_length(length), - m_minValue(min), - m_maxValue(max), - m_step(step) +graphModel::graphModel( float _min, float _max, int _length, + ::Model * _parent, bool _default_constructed, float _step ) : + Model( _parent, tr( "Graph" ), _default_constructed ), + m_samples( _length ), + m_length( _length ), + m_minValue( _min ), + m_maxValue( _max ), + m_step( _step ) { } -void graphModel::setRange(float min, float max) +void graphModel::setRange( float _min, float _max ) { - if (min != m_minValue || max != m_maxValue) + if( _min != m_minValue || _max != m_maxValue ) { - m_minValue = min; - m_maxValue = max; + m_minValue = _min; + m_maxValue = _max; - if (!m_samples.isEmpty()) + if( !m_samples.isEmpty() ) { // Trim existing values - for (int i=0; i < length(); i++) + for( int i=0; i < length(); i++ ) { - m_samples[i] = fmaxf(min, fminf(m_samples[i], max)); + m_samples[i] = fmaxf( _min, fminf( m_samples[i], _max ) ); } } @@ -527,14 +527,14 @@ void graphModel::setRange(float min, float max) -void graphModel::setLength(int length) +void graphModel::setLength( int _length ) { - if (length != m_length) + if( _length != m_length ) { - m_length = length; - if (m_samples.size() < m_length) + m_length = _length; + if( m_samples.size() < m_length ) { - m_samples.resize(m_length); + m_samples.resize( m_length ); } emit lengthChanged(); } @@ -542,104 +542,104 @@ void graphModel::setLength(int length) -void graphModel::setSampleAt(int x, float val) +void graphModel::setSampleAt( int x, float val ) { - drawSampleAt(x, val); - emit samplesChanged(x, x); + drawSampleAt( x, val ); + emit samplesChanged( x, x ); } -void graphModel::setSamples(const float * samples) +void graphModel::setSamples( const float * _samples ) { - std::copy(samples, samples + length(), m_samples.begin()); + std::copy( _samples, _samples + length(), m_samples.begin()); - emit samplesChanged(0, length()-1); + emit samplesChanged( 0, length()-1 ); } void graphModel::setWaveToSine() { - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { m_samples[i] = Oscillator::sinSample( - i / static_cast(length())); + i / static_cast( length() ) ); } - emit samplesChanged(0, length() - 1); + emit samplesChanged( 0, length() - 1 ); }; void graphModel::setWaveToTriangle() { - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { m_samples[i] = Oscillator::triangleSample( - i / static_cast(length())); + i / static_cast( length() ) ); } - emit samplesChanged(0, length() - 1); + emit samplesChanged( 0, length() - 1 ); }; void graphModel::setWaveToSaw() { - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { m_samples[i] = Oscillator::sawSample( - i / static_cast(length())); + i / static_cast( length() ) ); } - emit samplesChanged(0, length() - 1); + emit samplesChanged( 0, length() - 1 ); }; void graphModel::setWaveToSquare() { - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { m_samples[i] = Oscillator::squareSample( - i / static_cast(length())); + i / static_cast( length() ) ); } - emit samplesChanged(0, length() - 1); + emit samplesChanged( 0, length() - 1 ); }; void graphModel::setWaveToNoise() { - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { m_samples[i] = Oscillator::noiseSample( - i / static_cast(length())); + i / static_cast( length() ) ); } - emit samplesChanged(0, length() - 1); + emit samplesChanged( 0, length() - 1 ); }; QString graphModel::setWaveToUser() { SampleBuffer * sampleBuffer = new SampleBuffer; QString fileName = sampleBuffer->openAndSetWaveformFile(); - if (fileName.isEmpty() == false) + if( fileName.isEmpty() == false ) { sampleBuffer->dataReadLock(); - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { m_samples[i] = sampleBuffer->userWaveSample( - i / static_cast(length())); + i / static_cast( length() ) ); } sampleBuffer->dataUnlock(); } - sharedObject::unref(sampleBuffer); + sharedObject::unref( sampleBuffer ); - emit samplesChanged(0, length() - 1); + emit samplesChanged( 0, length() - 1 ); return fileName; }; @@ -651,12 +651,12 @@ void graphModel::smooth() QVector temp = m_samples; // Smoothing - m_samples[0] = (temp[length()-1] + (temp[0] * 2) + temp[1]) * 0.25f; - for (int i=1; i < (length()-1); i++) + m_samples[0] = ( temp[length()-1] + ( temp[0] * 2 ) + temp[1] ) * 0.25f; + for ( int i=1; i < ( length()-1 ); i++ ) { - m_samples[i] = (temp[i-1] + (temp[i] * 2) + temp[i+1]) * 0.25f; + m_samples[i] = ( temp[i-1] + ( temp[i] * 2 ) + temp[i+1] ) * 0.25f; } - m_samples[length()-1] = (temp[length()-2] + (temp[length()-1] * 2) + temp[0]) * 0.25f; + m_samples[length()-1] = ( temp[length()-2] + ( temp[length()-1] * 2 ) + temp[0] ) * 0.25f; emit samplesChanged(0, length()-1); } @@ -667,32 +667,31 @@ void graphModel::smoothNonCyclic() QVector temp = m_samples; // Smoothing - //m_samples[0] = ((temp[0] * 3) + temp[1]) * 0.25f; - for (int i=1; i < (length()-1); i++) + //m_samples[0] = ( ( temp[0] * 3 ) + temp[1] ) * 0.25f; + for ( int i=1; i < ( length()-1 ); i++ ) { - m_samples[i] = (temp[i-1] + (temp[i] * 2) + temp[i+1]) * 0.25f; + m_samples[i] = ( temp[i-1] + ( temp[i] * 2 ) + temp[i+1] ) * 0.25f; } - //m_samples[length()-1] = (temp[length()-2] + (temp[length()-1] * 3)) * 0.25f; + //m_samples[length()-1] = ( temp[length()-2] + ( temp[length()-1] * 3 ) ) * 0.25f; emit samplesChanged(0, length()-1); } -void graphModel::convolve(const float *convolution, - const int convolutionLength, const int centerOffset) +//makes a cyclic convolution. +void graphModel::convolve(const float *convolution, const int convolutionLength, const int centerOffset) { // store values in temporary array QVector temp = m_samples; const int graphLength = length(); float sum; - // make a cyclic convolution - for (int i = 0; i < graphLength; i++) + for ( int i = 0; i < graphLength; i++ ) { sum = 0; - for (int j = 0; j < convolutionLength; j++) + for ( int j = 0; j < convolutionLength; j++ ) { - sum += convolution[j] * temp[(i + j) % graphLength]; + sum += convolution[j] * temp[( i + j ) % graphLength]; } - m_samples[(i + centerOffset) % graphLength] = sum; + m_samples[( i + centerOffset ) % graphLength] = sum; } emit samplesChanged(0, graphLength - 1); } @@ -703,22 +702,22 @@ void graphModel::normalize() float avg = 0.0f; // first correct dc offset by normalizing to average - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) avg += m_samples[i]; avg /= length(); - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) m_samples[i] -= avg; // then maximize - for (int i = 0; i < length(); i++) - max = qMax(max, qAbs(m_samples[i])); + for( int i = 0; i < length(); i++ ) + max = qMax( max, qAbs( m_samples[i] ) ); - for (int i = 0; i < length(); i++) - m_samples[i] = qBound(m_minValue, m_samples[i] / max, m_maxValue); + for( int i = 0; i < length(); i++ ) + m_samples[i] = qBound( m_minValue, m_samples[i] / max, m_maxValue ); // signal changes if any - if (max != 1.0f || avg != 0.0f) - emit samplesChanged(0, length()-1); + if( max != 1.0f || avg != 0.0f ) + emit samplesChanged( 0, length()-1 ); } @@ -727,60 +726,60 @@ void graphModel::invert() { const float range = m_maxValue - m_minValue; - for (int i = 0; i < length(); i++) - m_samples[i] = m_minValue + (range - (m_samples[i] - m_minValue)); + for( int i = 0; i < length(); i++ ) + m_samples[i] = m_minValue + ( range - ( m_samples[i] - m_minValue ) ); - emit samplesChanged(0, length()-1); + emit samplesChanged( 0, length()-1 ); } -void graphModel::shiftPhase(int deg) +void graphModel::shiftPhase( int _deg ) { // calculate offset in samples - const int offset = (deg * length()) / 360; //multiply first because integers + const int offset = ( _deg * length() ) / 360; //multiply first because integers // store values in temporary array QVector temp = m_samples; // shift phase - for (int i = 0; i < length(); i++) + for( int i = 0; i < length(); i++ ) { - int o = (i + offset) % length(); - while (o < 0) o += length(); + int o = ( i + offset ) % length(); + while( o < 0 ) o += length(); m_samples[i] = temp[o]; } - emit samplesChanged(0, length()-1); + emit samplesChanged( 0, length()-1 ); } +// Clear visible graph void graphModel::clear() { const int graph_length = length(); - for (int i = 0; i < graph_length; i++) + for( int i = 0; i < graph_length; i++ ) m_samples[i] = 0; - emit samplesChanged(0, graph_length - 1); + emit samplesChanged( 0, graph_length - 1 ); } - // Clear any part of the graph that isn't displayed void graphModel::clearInvisible() { const int graph_length = length(); const int full_graph_length = m_samples.size(); - for (int i = graph_length; i < full_graph_length; i++) + for( int i = graph_length; i < full_graph_length; i++ ) m_samples[i] = 0; - emit samplesChanged(graph_length, full_graph_length - 1); + emit samplesChanged( graph_length, full_graph_length - 1 ); } -void graphModel::drawSampleAt(int x, float val) +void graphModel::drawSampleAt( int x, float val ) { //snap to the grid - val -= (m_step != 0.0) ? fmod(val, m_step) * m_step : 0; + val -= ( m_step != 0.0 ) ? fmod( val, m_step ) * m_step : 0; // boundary crop - x = qMax(0, qMin(length()-1, x)); - val = qMax(minValue(), qMin(maxValue(), val)); + x = qMax( 0, qMin( length()-1, x ) ); + val = qMax( minValue(), qMin( maxValue(), val ) ); // change sample shape m_samples[x] = val; From 6fa589a3198a224dc4d123cbc12ef8a38ad30248 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 5 Jun 2019 07:28:04 -0600 Subject: [PATCH 05/12] Update Graph.h from stable-1.2 to master --- include/Graph.h | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/include/Graph.h b/include/Graph.h index 4bce31f5ba3..3435bb28b71 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -52,6 +52,11 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView BarCenterGradStyle //!< draw color gradient coming from center }; + /** + * @brief Constructor + * @param _width Pixel width of widget + * @param _height Pixel height of widget + */ Graph( QWidget * _parent, graphStyle _style = Graph::LinearStyle, int _width = 132, int _height = 104 @@ -112,10 +117,24 @@ protected slots: } ; +/** + @brief 2 dimensional function plot + + Function plot graph with discrete x scale and continous y scale + This makes it possible to display "#x" samples +*/ class LMMS_EXPORT graphModel : public Model { Q_OBJECT public: + /** + * @brief Constructor + * @param _min Minimum y value to display + * @param _max Maximum y value to display + * @param _size Number of samples (e.g. x value) + * @param _step Step size on y axis where values snap to, or 0.0f + * for "no snapping" + */ graphModel( float _min, float _max, int _size, @@ -147,14 +166,21 @@ class LMMS_EXPORT graphModel : public Model return( m_samples.data() ); } - void convolve(const float *convolution, const int convolutionLength, const int centerOffset); + //! Make cyclic convolution + //! @param convolution Samples to convolve with + //! @param convolutionLength Number of samples to take for each sum + //! @param centerOffset Offset for resulting values + void convolve(const float *convolution, + const int convolutionLength, const int centerOffset); public slots: + //! Set range of y values void setRange( float _min, float _max ); void setLength( int _size ); - + //! Update one sample void setSampleAt( int x, float val ); + //! Update samples array void setSamples( const float * _value ); void setWaveToSine(); @@ -191,3 +217,4 @@ public slots: }; #endif + From 86723c1f9d6a493b6a17d02217a43c2acdbb75d5 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Jun 2019 14:55:26 -0600 Subject: [PATCH 06/12] Remove inclusion of templates.h --- plugins/Microwave/Microwave.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 534995fba8e..ebc6bfe92dd 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -60,7 +60,6 @@ #include "SampleBuffer.h" #include "Song.h" #include "StringPairDrag.h" -#include "templates.h" #include "TextFloat.h" #include "ToolTip.h" From 0ad13cf9fb978a23b63da8ecdb10f22ba4832ff0 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 29 Jun 2019 13:33:08 -0600 Subject: [PATCH 07/12] Rewrite updateScroll function, add more tooltips --- plugins/Microwave/Microwave.cpp | 420 +++++++++++++++++--------------- plugins/Microwave/Microwave.h | 14 +- 2 files changed, 223 insertions(+), 211 deletions(-) diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index ebc6bfe92dd..6a04dd7e5f7 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -227,7 +227,14 @@ Microwave::Microwave(InstrumentTrack * instrument_track) : loadmodemodel(m_loadMode) oversamplemodemodel(m_oversampleMode) - m_oversampleMode.setValue(1);// Sample averaging is default + m_oversampleMode.setValue(0);// Decimate is default + /* Decimate mode downsamples without interpolation, + which actually has decent quality because of + Microwave's non-realtime oversampling. + + Average mode averages all the generated samples together, + which can sometimes result in fewer artifacts but oftentimes + messes up high frequencies.*/ connect(&m_graph, SIGNAL(samplesChanged(int, int)), this, SLOT(samplesChanged(int, int))); @@ -1525,7 +1532,7 @@ MicrowaveView::MicrowaveView(Instrument * instrument, for (int i = 0; i < 18; ++i) { - makeknob(m_macroKnob[i], knobSmallColored, tr("Macro") + " " + QString::number(i+1) + ":", tr("Macro %1: ").arg(i + 1) + tr("This knob's value can be used in the Matrix to control many values at the same time, at different amounts. This is immensely useful for crafting great presets.")); + makeknob(m_macroKnob[i], knobSmallColored, tr("Macro") + " " + QString::number(i+1) + ":", tr("Macro %1: ").arg(i + 1) + tr("This knob's value can be used in the Matrix to control many values at the same time, at different amounts. This is immensely useful for crafting great presets. Right click on this knob for some special Macro-specific knob features.")); } makeknob(m_subVolKnob, knobColored, tr("Volume"), tr("This knob, as you probably expected, controls the volume.")); @@ -1838,24 +1845,30 @@ MicrowaveView::MicrowaveView(Instrument * instrument, connect(m_confirmLoadButton, SIGNAL(clicked()), this, SLOT(confirmWavetableLoadClicked())); ToolTip::add(m_confirmLoadButton, tr("Load Wavetable")); + m_mainNumBox = new LcdSpinBox(2, "microwave", this, "Oscillator Number"); + ToolTip::add(m_mainNumBox, tr("Oscillator Number")); + m_subNumBox = new LcdSpinBox(2, "microwave", this, "Sub Oscillator Number"); + ToolTip::add(m_subNumBox, tr("Oscillator Number")); m_sampNumBox = new LcdSpinBox(2, "microwave", this, "Sample Number"); - - m_mainNumBox = new LcdSpinBox(2, "microwave", this, "Oscillator Number"); + ToolTip::add(m_sampNumBox, tr("Oscillator Number")); m_oversampleBox = new ComboBox(this); m_oversampleBox->setGeometry(0, 0, 42, 22); m_oversampleBox->setFont(pointSize<8>(m_oversampleBox->font())); + ToolTip::add(m_oversampleBox, tr("Oversampling Amount")); m_loadModeBox = new ComboBox(this); m_loadModeBox->setGeometry(0, 0, 202, 22); m_loadModeBox->setFont(pointSize<8>(m_loadModeBox->font())); + ToolTip::add(m_loadModeBox, tr("Oversampling Mode")); m_openSampleButton = new PixmapButton(this); m_openSampleButton->setCursor(QCursor(Qt::PointingHandCursor)); m_openSampleButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); m_openSampleButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); + ToolTip::add(m_oversampleBox, tr("Load Sound Sample")); m_effectScrollBar = new QScrollBar(Qt::Vertical, this); m_effectScrollBar->setSingleStep(1); @@ -1919,7 +1932,6 @@ MicrowaveView::MicrowaveView(Instrument * instrument, connect(m_desawBtn, SIGNAL (clicked ()), this, SLOT (desawClicked())); - // This is a mess, but for some reason just entering a number without a variable didn't work... int ii = 0; connect(m_tab1Btn, &PixmapButton::clicked, this, [this, ii]() { tabBtnClicked(ii); }); ii = 1; @@ -1935,15 +1947,20 @@ MicrowaveView::MicrowaveView(Instrument * instrument, connect(m_mainFlipBtn, SIGNAL (clicked ()), this, SLOT (flipperClicked())); + ToolTip::add(m_mainFlipBtn, tr("Flip to other knobs")); + connect(m_subFlipBtn, SIGNAL (clicked ()), this, SLOT (flipperClicked())); + ToolTip::add(m_subFlipBtn, tr("Flip to other knobs")); connect(m_visualizeToggle, SIGNAL(toggled(bool)), this, SLOT (visualizeToggled(bool))); + ToolTip::add(m_visualizeToggle, tr("Enable wavetable visualizer")); connect(&m_b->m_mainNum, SIGNAL(dataChanged()), this, SLOT(mainNumChanged())); connect(&m_b->m_subNum, SIGNAL(dataChanged()), this, SLOT(subNumChanged())); connect(&m_b->m_sampNum, SIGNAL(dataChanged()), this, SLOT(sampNumChanged())); connect(m_manualBtn, SIGNAL (clicked (bool)), this, SLOT (manualBtnClicked())); + ToolTip::add(m_manualBtn, tr("Open the instruction manual")); for (int i = 0; i < 64; ++i) { @@ -2013,105 +2030,108 @@ void MicrowaveView::modelChanged() } -// If you think you've seen ugly workarounds before, you haven't seen anything yet. -// A very old version of Microwave included the GUI elements visually moving left/right. -// Because of that, the GUI elements were just moved off of the screen rather than having their visibility toggled. -// It is because of this that I traded out the move function with visimove, which prevents the GUI elements from -// leaving the 250x250 GUI, and instead toggles their visibility if they try to leave, in case of things checking for the -// bounds of the GUI elements (e.g. instrument window resizing). +// Moves GUI elements to their correct locations and toggles their visibility when needed void MicrowaveView::updateScroll() { - int m_scrollVal = (m_b->m_scroll) * 250.f; int modScrollVal = (m_matrixScrollBar->value()) / 100.f * 115.f; - int m_effectScrollVal = (m_effectScrollBar->value()) / 100.f * 92.f; - int m_mainFlipped = m_b->m_mainFlipped.value(); - int m_subFlipped = m_b->m_subFlipped.value(); - - int mainIsFlipped = m_mainFlipped * 500.f; - int mainIsNotFlipped = !m_mainFlipped * 500.f; - int m_subIsFlipped = m_subFlipped * 500.f; - int m_subIsNotFlipped = !m_subFlipped * 500.f; - - visimove(m_morphKnob, (m_scrollVal < 250 ? 23 : 1500 + 176) - m_scrollVal, 172 + mainIsFlipped); - visimove(m_rangeKnob, (m_scrollVal < 250 ? 55 : 1500 + 208) - m_scrollVal, 172 + mainIsFlipped); - visimove(m_modifyKnob, 87 - m_scrollVal, 172 + mainIsFlipped); - visimove(m_modifyModeBox, 127 - m_scrollVal, 186 + mainIsFlipped); - visimove(m_volKnob, 23 - m_scrollVal, 172 + mainIsNotFlipped); - visimove(m_panKnob, 55 - m_scrollVal, 172 + mainIsNotFlipped); - visimove(m_detuneKnob, 152 - m_scrollVal, 216 + mainIsFlipped); - visimove(m_phaseKnob, 184 - m_scrollVal, 203 + mainIsNotFlipped); - visimove(m_phaseRandKnob, 209 - m_scrollVal, 203 + mainIsNotFlipped); - visimove(m_enabledToggle, 85 - m_scrollVal, 229); - visimove(m_mutedToggle, 103 - m_scrollVal, 229); - visimove(m_sampLenKnob, 137 - m_scrollVal, 172 + mainIsNotFlipped); - visimove(m_morphMaxKnob, 101 - m_scrollVal, 172 + mainIsNotFlipped); - visimove(m_unisonVoicesKnob, 184 - m_scrollVal, 172); - visimove(m_unisonDetuneKnob, 209 - m_scrollVal, 172); - visimove(m_unisonMorphKnob, 184 - m_scrollVal, 203 + mainIsFlipped); - visimove(m_unisonModifyKnob, 209 - m_scrollVal, 203 + mainIsFlipped); - visimove(m_keytrackingToggle, 121 - m_scrollVal, 229 + mainIsFlipped); - visimove(m_tempoKnob, 152 - m_scrollVal, 216 + mainIsNotFlipped); - visimove(m_interpolateToggle, 121 - m_scrollVal, 229 + mainIsNotFlipped); - - visimove(m_sampleEnabledToggle, 85 + 500 - m_scrollVal, 229); - visimove(m_sampleMutedToggle, 103 + 500 - m_scrollVal, 229); - visimove(m_sampleKeytrackingToggle, 121 + 500 - m_scrollVal, 229); - visimove(m_sampleGraphEnabledToggle, 138 + 500 - m_scrollVal, 229); - visimove(m_sampleLoopToggle, 155 + 500 - m_scrollVal, 229); - visimove(m_sampleVolumeKnob, 23 + 500 - m_scrollVal, 172); - visimove(m_samplePanningKnob, 55 + 500 - m_scrollVal, 172); - visimove(m_sampleDetuneKnob, 93 + 500 - m_scrollVal, 172); - visimove(m_samplePhaseKnob, 180 + 500 - m_scrollVal, 172); - visimove(m_samplePhaseRandKnob, 206 + 500 - m_scrollVal, 172); - visimove(m_sampleStartKnob, 121 + 500 - m_scrollVal, 172); - visimove(m_sampleEndKnob, 145 + 500 - m_scrollVal, 172); + int effectScrollVal = (m_effectScrollBar->value()) / 100.f * 92.f; + int mainFlipped = m_b->m_mainFlipped.value(); + int subFlipped = m_b->m_subFlipped.value(); + + bool inMainTab = m_b->m_scroll == 0; + bool inSubTab = m_b->m_scroll == 1; + bool inSampleTab = m_b->m_scroll == 2; + bool inMatrixTab = m_b->m_scroll == 3; + bool inEffectTab = m_b->m_scroll == 4; + bool inMiscTab = m_b->m_scroll == 5; + bool inWavetableLoadingTab = m_b->m_scroll == 6; + + bool mainIsNotFlipped = inMainTab && !mainFlipped; + bool mainIsFlipped = inMainTab && mainFlipped; + + bool subIsNotFlipped = inSubTab && !subFlipped; + bool subIsFlipped = inSubTab && subFlipped; + + visimove(m_morphKnob, ((m_b->m_scroll == 0) ? 23 : 176), 172, mainIsNotFlipped || inWavetableLoadingTab); + visimove(m_rangeKnob, ((m_b->m_scroll == 0) ? 55 : 208), 172, mainIsNotFlipped || inWavetableLoadingTab); + visimove(m_modifyKnob, 87, 172, mainIsNotFlipped); + visimove(m_modifyModeBox, 127, 186, mainIsNotFlipped); + visimove(m_volKnob, 23, 172, mainIsFlipped); + visimove(m_panKnob, 55, 172, mainIsFlipped); + visimove(m_detuneKnob, 152, 216, mainIsNotFlipped); + visimove(m_phaseKnob, 184, 203, mainIsFlipped); + visimove(m_phaseRandKnob, 209, 203, mainIsFlipped); + visimove(m_enabledToggle, 85, 229, inMainTab); + visimove(m_mutedToggle, 103, 229, inMainTab); + visimove(m_sampLenKnob, 137, 172, mainIsFlipped); + visimove(m_morphMaxKnob, 101, 172, mainIsFlipped); + visimove(m_unisonVoicesKnob, 184, 172, inMainTab); + visimove(m_unisonDetuneKnob, 209, 172, inMainTab); + visimove(m_unisonMorphKnob, 184, 203, mainIsNotFlipped); + visimove(m_unisonModifyKnob, 209, 203, mainIsNotFlipped); + visimove(m_keytrackingToggle, 121, 229, mainIsNotFlipped); + visimove(m_tempoKnob, 152, 216, mainIsFlipped); + visimove(m_interpolateToggle, 121, 229, mainIsFlipped); + + visimove(m_sampleEnabledToggle, 85, 229, inSampleTab); + visimove(m_sampleMutedToggle, 103, 229, inSampleTab); + visimove(m_sampleKeytrackingToggle, 121, 229, inSampleTab); + visimove(m_sampleGraphEnabledToggle, 138, 229, inSampleTab); + visimove(m_sampleLoopToggle, 155, 229, inSampleTab); + visimove(m_sampleVolumeKnob, 23, 172, inSampleTab); + visimove(m_samplePanningKnob, 55, 172, inSampleTab); + visimove(m_sampleDetuneKnob, 93, 172, inSampleTab); + visimove(m_samplePhaseKnob, 180, 172, inSampleTab); + visimove(m_samplePhaseRandKnob, 206, 172, inSampleTab); + visimove(m_sampleStartKnob, 121, 172, inSampleTab); + visimove(m_sampleEndKnob, 145, 172, inSampleTab); for (int i = 0; i < 8; ++i) { - visimove(m_filtCutoffKnob[i], 32 + 1000 - m_scrollVal, i*92+55 - m_effectScrollVal); - visimove(m_filtResoKnob[i], 63 + 1000 - m_scrollVal, i*92+55 - m_effectScrollVal); - visimove(m_filtGainKnob[i], 94 + 1000 - m_scrollVal, i*92+55 - m_effectScrollVal); - - visimove(m_filtTypeBox[i], 128 + 1000 - m_scrollVal, i*92+63 - m_effectScrollVal); - visimove(m_filtSlopeBox[i], 171 + 1000 - m_scrollVal, i*92+63 - m_effectScrollVal); - visimove(m_filtInVolKnob[i], 30 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtOutVolKnob[i], 55 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtWetDryKnob[i], 80 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtBalKnob[i], 105 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtSatuKnob[i], 135 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtFeedbackKnob[i], 167 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtDetuneKnob[i], 192 + 1000 - m_scrollVal, i*92+91 - m_effectScrollVal); - visimove(m_filtEnabledToggle[i], 27 + 1000 - m_scrollVal, i*92+36 - m_effectScrollVal); - visimove(m_filtMutedToggle[i], 166 + 1000 - m_scrollVal, i*92+36 - m_effectScrollVal); - visimove(m_filtKeytrackingToggle[i], 200 + 1000 - m_scrollVal, i*92+36 - m_effectScrollVal); + visimove(m_filtCutoffKnob[i], 32, i*92+55 - effectScrollVal, inEffectTab); + visimove(m_filtResoKnob[i], 63, i*92+55 - effectScrollVal, inEffectTab); + visimove(m_filtGainKnob[i], 94, i*92+55 - effectScrollVal, inEffectTab); + + visimove(m_filtTypeBox[i], 128, i*92+63 - effectScrollVal, inEffectTab); + visimove(m_filtSlopeBox[i], 171, i*92+63 - effectScrollVal, inEffectTab); + visimove(m_filtInVolKnob[i], 30, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtOutVolKnob[i], 55, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtWetDryKnob[i], 80, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtBalKnob[i], 105, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtSatuKnob[i], 135, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtFeedbackKnob[i], 167, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtDetuneKnob[i], 192, i*92+91 - effectScrollVal, inEffectTab); + visimove(m_filtEnabledToggle[i], 27, i*92+36 - effectScrollVal, inEffectTab); + visimove(m_filtMutedToggle[i], 166, i*92+36 - effectScrollVal, inEffectTab); + visimove(m_filtKeytrackingToggle[i], 200, i*92+36 - effectScrollVal, inEffectTab); } - visimove(m_subVolKnob, 23 + 250 - m_scrollVal, 172 + m_subIsFlipped); - visimove(m_subPanningKnob, 55 + 250 - m_scrollVal, 172 + m_subIsFlipped); - visimove(m_subDetuneKnob, 95 + 250 - m_scrollVal, 172 + m_subIsFlipped); - visimove(m_subPhaseKnob, 180 + 250 - m_scrollVal, 172); - visimove(m_subPhaseRandKnob, 206 + 250 - m_scrollVal, 172); - visimove(m_subSampLenKnob, 130 + 250 - m_scrollVal, 172 + m_subIsFlipped); - visimove(m_subTempoKnob, 23 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); - visimove(m_subRateLimitKnob, 55 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); - visimove(m_subUnisonNumKnob, 95 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); - visimove(m_subUnisonDetuneKnob, 130 + 250 - m_scrollVal, 172 + m_subIsNotFlipped); - - if (m_subIsNotFlipped) + visimove(m_subVolKnob, 23, 172, subIsNotFlipped); + visimove(m_subPanningKnob, 55, 172, subIsNotFlipped); + visimove(m_subDetuneKnob, 95, 172, subIsNotFlipped); + visimove(m_subPhaseKnob, 180, 172, inSubTab); + visimove(m_subPhaseRandKnob, 206, 172, inSubTab); + visimove(m_subSampLenKnob, 130, 172, subIsNotFlipped); + visimove(m_subTempoKnob, 23, 172, subIsFlipped); + visimove(m_subRateLimitKnob, 55, 172, subIsFlipped); + visimove(m_subUnisonNumKnob, 95, 172, subIsFlipped); + visimove(m_subUnisonDetuneKnob, 130, 172, subIsFlipped); + + if (subIsNotFlipped) { - visimove(m_subEnabledToggle, 85 + 250 - m_scrollVal, 229); - visimove(m_subMutedToggle, 103 + 250 - m_scrollVal, 229); - visimove(m_subKeytrackToggle, 121 + 250 - m_scrollVal, 229); - visimove(m_subNoiseToggle, 138 + 250 - m_scrollVal, 229); - visimove(m_subInterpolateToggle, 155 + 250 - m_scrollVal, 229); + visimove(m_subEnabledToggle, 85, 229, inSubTab); + visimove(m_subMutedToggle, 103, 229, inSubTab); + visimove(m_subKeytrackToggle, 121, 229, inSubTab); + visimove(m_subNoiseToggle, 138, 229, inSubTab); + visimove(m_subInterpolateToggle, 155, 229, inSubTab); } else { - visimove(m_subEnabledToggle, 85 + 250 - m_scrollVal, 235); - visimove(m_subMutedToggle, 103 + 250 - m_scrollVal, 235); - visimove(m_subKeytrackToggle, 121 + 250 - m_scrollVal, 235); - visimove(m_subNoiseToggle, 138 + 250 - m_scrollVal, 235); - visimove(m_subInterpolateToggle, 155 + 250 - m_scrollVal, 235); + visimove(m_subEnabledToggle, 85, 235, inSubTab); + visimove(m_subMutedToggle, 103, 235, inSubTab); + visimove(m_subKeytrackToggle, 121, 235, inSubTab); + visimove(m_subNoiseToggle, 138, 235, inSubTab); + visimove(m_subInterpolateToggle, 155, 235, inSubTab); } int matrixRemainder = modScrollVal % 460; @@ -2154,26 +2174,26 @@ void MicrowaveView::updateScroll() modInChanged(i+matrixDivide); modIn2Changed(i+matrixDivide); - visimove(m_modInBox[i], 45 + 750 - m_scrollVal, i*115+57 - matrixRemainder); - visimove(m_modInNumBox[i], 90 + 750 - m_scrollVal, i*115+57 - matrixRemainder); - visimove(m_modInAmntKnob[i], 136 + 750 - m_scrollVal, i*115+53 - matrixRemainder); - visimove(m_modInCurveKnob[i], 161 + 750 - m_scrollVal, i*115+53 - matrixRemainder); - visimove(m_modInBox2[i], 45 + 750 - m_scrollVal, i*115+118 - matrixRemainder); - visimove(m_modInNumBox2[i], 90 + 750 - m_scrollVal, i*115+118 - matrixRemainder); - visimove(m_modInAmntKnob2[i], 136 + 750 - m_scrollVal, i*115+114 - matrixRemainder); - visimove(m_modInCurveKnob2[i], 161 + 750 - m_scrollVal, i*115+114 - matrixRemainder); - visimove(m_modOutSecBox[i], 27 + 750 - m_scrollVal, i*115+88 - matrixRemainder); - visimove(m_modOutSigBox[i], 69 + 750 - m_scrollVal, i*115+88 - matrixRemainder); - visimove(m_modOutSecNumBox[i], 112 + 750 - m_scrollVal, i*115+88 - matrixRemainder); - visimove(m_modEnabledToggle[i], 27 + 750 - m_scrollVal, i*115+36 - matrixRemainder); - visimove(m_modCombineTypeBox[i], 149 + 750 - m_scrollVal, i*115+88 - matrixRemainder); - visimove(m_modTypeToggle[i], 195 + 750 - m_scrollVal, i*115+67 - matrixRemainder); - visimove(m_modType2Toggle[i], 195 + 750 - m_scrollVal, i*115+128 - matrixRemainder); - visimove(m_modUpArrow[i], 181 + 750 - m_scrollVal, i*115+37 - matrixRemainder); - visimove(m_modDownArrow[i], 199 + 750 - m_scrollVal, i*115+37 - matrixRemainder); - visimove(m_i1Button[i], 25 + 750 - m_scrollVal, i*115+50 - matrixRemainder); - visimove(m_i2Button[i], 25 + 750 - m_scrollVal, i*115+112 - matrixRemainder); - visimove(m_modNumText[i], 192 + 750 - m_scrollVal, i*115+89 - matrixRemainder); + visimove(m_modInBox[i], 45, i*115+57 - matrixRemainder, inMatrixTab); + visimove(m_modInNumBox[i], 90, i*115+57 - matrixRemainder, inMatrixTab); + visimove(m_modInAmntKnob[i], 136, i*115+53 - matrixRemainder, inMatrixTab); + visimove(m_modInCurveKnob[i], 161, i*115+53 - matrixRemainder, inMatrixTab); + visimove(m_modInBox2[i], 45, i*115+118 - matrixRemainder, inMatrixTab); + visimove(m_modInNumBox2[i], 90, i*115+118 - matrixRemainder, inMatrixTab); + visimove(m_modInAmntKnob2[i], 136, i*115+114 - matrixRemainder, inMatrixTab); + visimove(m_modInCurveKnob2[i], 161, i*115+114 - matrixRemainder, inMatrixTab); + visimove(m_modOutSecBox[i], 27, i*115+88 - matrixRemainder, inMatrixTab); + visimove(m_modOutSigBox[i], 69, i*115+88 - matrixRemainder, inMatrixTab); + visimove(m_modOutSecNumBox[i], 112, i*115+88 - matrixRemainder, inMatrixTab); + visimove(m_modEnabledToggle[i], 27, i*115+36 - matrixRemainder, inMatrixTab); + visimove(m_modCombineTypeBox[i], 149, i*115+88 - matrixRemainder, inMatrixTab); + visimove(m_modTypeToggle[i], 195, i*115+67 - matrixRemainder, inMatrixTab); + visimove(m_modType2Toggle[i], 195, i*115+128 - matrixRemainder, inMatrixTab); + visimove(m_modUpArrow[i], 181, i*115+37 - matrixRemainder, inMatrixTab); + visimove(m_modDownArrow[i], 199, i*115+37 - matrixRemainder, inMatrixTab); + visimove(m_i1Button[i], 25, i*115+50 - matrixRemainder, inMatrixTab); + visimove(m_i2Button[i], 25, i*115+112 - matrixRemainder, inMatrixTab); + visimove(m_modNumText[i], 192, i*115+89 - matrixRemainder, inMatrixTab); } for (int i = 0; i < 8; ++i) @@ -2227,89 +2247,87 @@ void MicrowaveView::updateScroll() refreshMacroColor(m_macroKnob[i], i); } - visimove(m_visvolKnob, 230 - m_scrollVal, 24); - - visimove(m_loadChnlKnob, 1500 + 111 - m_scrollVal, 121); - visimove(m_visualizeToggle, 213 - m_scrollVal, 26); - visimove(m_subNumBox, 250 + 18 - m_scrollVal, 219); - visimove(m_sampNumBox, 500 + 18 - m_scrollVal, 219); - visimove(m_mainNumBox, 18 - m_scrollVal, 219); - visimove(m_graph, m_scrollVal >= 500 ? 500 + 23 - m_scrollVal : 23 , 30); - visimove(m_openWavetableButton, (m_scrollVal < 250 ? 54 : 1500 + 115) - m_scrollVal, m_scrollVal < 250 ? 220 : 24); - visimove(m_openSampleButton, 54 + 500 - m_scrollVal, 220); - - visimove(m_sinWaveBtn, 179 + 250 - m_scrollVal, 212); - visimove(m_triangleWaveBtn, 197 + 250 - m_scrollVal, 212); - visimove(m_sawWaveBtn, 215 + 250 - m_scrollVal, 212); - visimove(m_sqrWaveBtn, 179 + 250 - m_scrollVal, 227); - visimove(m_whiteNoiseWaveBtn, 197 + 250 - m_scrollVal, 227); - visimove(m_smoothBtn, 215 + 250 - m_scrollVal, 227); - visimove(m_usrWaveBtn, 54 + 250 - m_scrollVal, 220); - - visimove(m_sinWave2Btn, 179 + 500 - m_scrollVal, 212); - visimove(m_triangleWave2Btn, 197 + 500 - m_scrollVal, 212); - visimove(m_sawWave2Btn, 215 + 500 - m_scrollVal, 212); - visimove(m_sqrWave2Btn, 179 + 500 - m_scrollVal, 227); - visimove(m_whiteNoiseWave2Btn, 197 + 500 - m_scrollVal, 227); - visimove(m_smooth2Btn, 215 + 500 - m_scrollVal, 227); - visimove(m_usrWave2Btn, 54 + 500 - m_scrollVal, 220); - - visimove(m_oversampleBox, 70 + 1250 - m_scrollVal, 50); - - visimove(m_effectScrollBar, 221 + 1000 - m_scrollVal, 32); - visimove(m_matrixScrollBar, 221 + 750 - m_scrollVal, 32); - - visimove(m_filtForegroundLabel, 1000 - m_scrollVal, 0); - visimove(m_filtBoxesLabel, 1000 + 24 - m_scrollVal, 35 - (m_effectScrollVal % 92)); - - visimove(m_matrixForegroundLabel, 750 - m_scrollVal, 0); - visimove(m_matrixBoxesLabel, 750 + 24 - m_scrollVal, 35 - (modScrollVal % 115)); - - visimove(m_macroKnob[0], 1250 + 59 - m_scrollVal, 127); - visimove(m_macroKnob[1], 1250 + 81 - m_scrollVal, 127); - visimove(m_macroKnob[2], 1250 + 103 - m_scrollVal, 127); - visimove(m_macroKnob[3], 1250 + 125 - m_scrollVal, 127); - visimove(m_macroKnob[4], 1250 + 147 - m_scrollVal, 127); - visimove(m_macroKnob[5], 1250 + 169 - m_scrollVal, 127); - visimove(m_macroKnob[6], 1250 + 59 - m_scrollVal, 147); - visimove(m_macroKnob[7], 1250 + 81 - m_scrollVal, 147); - visimove(m_macroKnob[8], 1250 + 103 - m_scrollVal, 147); - visimove(m_macroKnob[9], 1250 + 125 - m_scrollVal, 147); - visimove(m_macroKnob[10], 1250 + 147 - m_scrollVal, 147); - visimove(m_macroKnob[11], 1250 + 169 - m_scrollVal, 147); - visimove(m_macroKnob[12], 1250 + 59 - m_scrollVal, 167); - visimove(m_macroKnob[13], 1250 + 81 - m_scrollVal, 167); - visimove(m_macroKnob[14], 1250 + 103 - m_scrollVal, 167); - visimove(m_macroKnob[15], 1250 + 125 - m_scrollVal, 167); - visimove(m_macroKnob[16], 1250 + 147 - m_scrollVal, 168); - visimove(m_macroKnob[17], 1250 + 169 - m_scrollVal, 168); - - visimove(m_tab1Btn, 1, 48); - visimove(m_tab2Btn, 1, 63); - visimove(m_tab3Btn, 1, 78); - visimove(m_tab4Btn, 1, 93); - visimove(m_tab5Btn, 1, 108); - visimove(m_tab6Btn, 1, 123); - - visimove(m_mainFlipBtn, 3 - m_scrollVal, 145); - visimove(m_subFlipBtn, 250 + 3 - m_scrollVal, 145); - - visimove(m_manualBtn, 1250 + 49 - m_scrollVal, 199); - - visimove(m_loadModeBox, 1500 + 25 - m_scrollVal, 76); - visimove(m_confirmLoadButton, 1500 + 93 - m_scrollVal, 187); - - visimove(m_XBtn, 231 + 1500 - m_scrollVal, 11); - visimove(m_MatrixXBtn, 229 + 750 - m_scrollVal, 8); - - visimove(m_normalizeBtn, 155 + 1500 - m_scrollVal, 224); - visimove(m_desawBtn, 39 + 1500 - m_scrollVal, 224); - - visimove(m_removeDCBtn, 1250 + 68 - m_scrollVal, 84); - visimove(m_oversampleModeBox, 1250 + 135 - m_scrollVal, 50); + visimove(m_visvolKnob, 230, 24, inMainTab && m_b->m_visualize.value()); + + visimove(m_loadChnlKnob, 111, 121, inWavetableLoadingTab); + visimove(m_visualizeToggle, 213, 26, inMainTab); + visimove(m_mainNumBox, 18, 219, inMainTab); + visimove(m_subNumBox, 18, 219, inSubTab); + visimove(m_sampNumBox, 18, 219, inSampleTab); + visimove(m_graph, 23 , 30, inMainTab || inSubTab || inSampleTab); + visimove(m_openWavetableButton, ((m_b->m_scroll == 0) ? 54 : 115), (m_b->m_scroll == 0) ? 220 : 24, inMainTab || inWavetableLoadingTab); + visimove(m_openSampleButton, 54, 220, inSampleTab); + + visimove(m_sinWaveBtn, 179, 212, inSubTab); + visimove(m_triangleWaveBtn, 197, 212, inSubTab); + visimove(m_sawWaveBtn, 215, 212, inSubTab); + visimove(m_sqrWaveBtn, 179, 227, inSubTab); + visimove(m_whiteNoiseWaveBtn, 197, 227, inSubTab); + visimove(m_smoothBtn, 215, 227, inSubTab); + visimove(m_usrWaveBtn, 54, 220, inSubTab); + + visimove(m_sinWave2Btn, 179, 212, inSampleTab); + visimove(m_triangleWave2Btn, 197, 212, inSampleTab); + visimove(m_sawWave2Btn, 215, 212, inSampleTab); + visimove(m_sqrWave2Btn, 179, 227, inSampleTab); + visimove(m_whiteNoiseWave2Btn, 197, 227, inSampleTab); + visimove(m_smooth2Btn, 215, 227, inSampleTab); + visimove(m_usrWave2Btn, 54, 220, inSampleTab); + + visimove(m_oversampleBox, 70, 50, inMiscTab); + visimove(m_oversampleModeBox, 135, 50, inMiscTab); + visimove(m_removeDCBtn, 68, 84, inMiscTab); + + visimove(m_effectScrollBar, 221, 32, inEffectTab); + visimove(m_matrixScrollBar, 221, 32, inMatrixTab); + + visimove(m_filtForegroundLabel, 0, 0, inEffectTab); + visimove(m_filtBoxesLabel, 24, 35 - (effectScrollVal % 92), inEffectTab); + + visimove(m_matrixForegroundLabel, 0, 0, inMatrixTab); + visimove(m_matrixBoxesLabel, 24, 35 - (modScrollVal % 115), inMatrixTab); + + visimove(m_macroKnob[0], 59, 127, inMiscTab); + visimove(m_macroKnob[1], 81, 127, inMiscTab); + visimove(m_macroKnob[2], 103, 127, inMiscTab); + visimove(m_macroKnob[3], 125, 127, inMiscTab); + visimove(m_macroKnob[4], 147, 127, inMiscTab); + visimove(m_macroKnob[5], 169, 127, inMiscTab); + visimove(m_macroKnob[6], 59, 147, inMiscTab); + visimove(m_macroKnob[7], 81, 147, inMiscTab); + visimove(m_macroKnob[8], 103, 147, inMiscTab); + visimove(m_macroKnob[9], 125, 147, inMiscTab); + visimove(m_macroKnob[10], 147, 147, inMiscTab); + visimove(m_macroKnob[11], 169, 147, inMiscTab); + visimove(m_macroKnob[12], 59, 167, inMiscTab); + visimove(m_macroKnob[13], 81, 167, inMiscTab); + visimove(m_macroKnob[14], 103, 167, inMiscTab); + visimove(m_macroKnob[15], 125, 167, inMiscTab); + visimove(m_macroKnob[16], 147, 168, inMiscTab); + visimove(m_macroKnob[17], 169, 168, inMiscTab); + + visimove(m_tab1Btn, 1, 48, true); + visimove(m_tab2Btn, 1, 63, true); + visimove(m_tab3Btn, 1, 78, true); + visimove(m_tab4Btn, 1, 93, true); + visimove(m_tab5Btn, 1, 108, true); + visimove(m_tab6Btn, 1, 123, true); + + visimove(m_mainFlipBtn, 3, 145, inMainTab); + visimove(m_subFlipBtn, 3, 145, inSubTab); + + visimove(m_manualBtn, 49, 199, inMiscTab); + + visimove(m_loadModeBox, 25, 76, inWavetableLoadingTab); + visimove(m_confirmLoadButton, 93, 187, inWavetableLoadingTab); + + visimove(m_XBtn, 231, 11, inWavetableLoadingTab); + visimove(m_MatrixXBtn, 229, 8, inMatrixTab); + + visimove(m_normalizeBtn, 155, 224, inWavetableLoadingTab); + visimove(m_desawBtn, 39, 224, inWavetableLoadingTab); tabChanged(m_b->m_scroll); - m_visvolKnob->setVisible(m_b->m_visualize.value()); } @@ -4577,6 +4595,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] { m_temp1 = round(sample_rate / detuneWithCents(440.f, m_filtDetune[l])); } + if (m_filtDelayBuf[l][0].size() < m_temp1) { m_filtDelayBuf[l][0].resize(m_temp1); @@ -4785,10 +4804,8 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] } } - //Output results - m_temp1 = m_filtOutVol[l] * 0.01f; - m_filtOutputs[l][0] = m_filtPrevSampOut[l][m][0][0] * m_temp1; - m_filtOutputs[l][1] = m_filtPrevSampOut[l][m][0][1] * m_temp1; + m_filtOutputs[l][0] = m_filtPrevSampOut[l][m][0][0]; + m_filtOutputs[l][1] = m_filtPrevSampOut[l][m][0][1]; } else if (m_mode == 8) @@ -4808,9 +4825,8 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_filtoldy2[i] = m_filty2[i]; m_filtoldy3[i] = m_filty3[i]; } - m_temp1 = m_filtOutVol[l] * 0.01f; - m_filtOutputs[l][0] = m_filty4[0] * m_temp1; - m_filtOutputs[l][1] = m_filty4[1] * m_temp1; + m_filtOutputs[l][0] = m_filty4[0]; + m_filtOutputs[l][1] = m_filty4[1]; } // Calculates Saturation. The algorithm is just y = x ^ (1 - saturation); @@ -4878,6 +4894,10 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_filtDelayBuf[l][0][m_filtFeedbackLoc[l]] = m_filtOutputs[l][0] * m_temp1; m_filtDelayBuf[l][1][m_filtFeedbackLoc[l]] = m_filtOutputs[l][1] * m_temp1; + m_temp1 = m_filtOutVol[l] * 0.01f; + m_filtOutputs[l][0] *= m_temp1; + m_filtOutputs[l][1] *= m_temp1; + m_filtInputs[l][0] = 0; m_filtInputs[l][1] = 0; diff --git a/plugins/Microwave/Microwave.h b/plugins/Microwave/Microwave.h index fdf5e6b35fd..e5584407e75 100644 --- a/plugins/Microwave/Microwave.h +++ b/plugins/Microwave/Microwave.h @@ -250,17 +250,9 @@ name.addItem(tr("Decimate"), make_unique("number_1"));\ name.addItem(tr("Average"), make_unique("number_2")); -#define visimove(name, x, y)\ - if (x >= 0 && x <= 250)\ - {\ - name->move(x, y);\ - name->setVisible(true);\ - }\ - else\ - {\ - name->move(0, 0);\ - name->setVisible(false);\ - } +#define visimove(name, x, y, isVisible)\ + name->move(x, y);\ + name->setVisible(isVisible); // Create the knob, set its tooltip, set its default color From 92b7269ce4dae5f12b05bf121088205084b7a97f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 18 Jul 2019 19:51:40 -0600 Subject: [PATCH 08/12] Fix incorrect graph color bug, make some style fixes, fix some typos --- plugins/Microwave/Microwave.cpp | 605 ++++++++++++++++---------------- plugins/Microwave/Microwave.h | 7 +- 2 files changed, 301 insertions(+), 311 deletions(-) diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 6a04dd7e5f7..b610bf5d206 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -319,6 +319,7 @@ Microwave::Microwave(InstrumentTrack * instrument_track) : valueChanged(150, i); + // Set default macro knob colors m_macroColors[i][0] = 102; m_macroColors[i][1] = 198; m_macroColors[i][2] = 199; @@ -376,6 +377,7 @@ Microwave::Microwave(InstrumentTrack * instrument_track) : for (int i = 0; i < 8; ++i) { + // Make sure Sample Tab samples aren't empty, to prevent a crash. m_samples[i][0].push_back(0); m_samples[i][1].push_back(0); } @@ -412,38 +414,22 @@ QString Microwave::nodeName() const void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) { - // NOTE: Only m_enabled oscillators/sections are saved. This is to prevent ridiculously long project save times, as well as total disk space annihilation. + // NOTE: Only m_enabled oscillators/sections are saved. + //This is to prevent ridiculously long project save times, as well as total disk space annihilation. // Save plugin version thissave.setAttribute("version", "Microwave Official Release 1"); - /* - - VERSION LIST: - - - 0.9: Every version before Microwave Testing Release 4 was mistakenly listed as 0.9. - - - Microwave Testing Release 4 - - Microwave Testing Release 4.1 - - Microwave Testing Release 4.2 - - Microwave Testing Release 5 - - Microwave Testing Release 5.1 - - Microwave Testing Release 5.2 - - - Microwave Official Release 1 - - */ - m_visvol.saveSettings(doc, thissave, "visualizer_volume"); m_loadMode.saveSettings(doc, thissave, "loadingalgorithm"); m_loadChnl.saveSettings(doc, thissave, "loadingchannel"); - m_oversample.saveSettings(doc, thissave, "oversample"); m_oversampleMode.saveSettings(doc, thissave, "oversamplemode"); m_removeDC.saveSettings(doc, thissave, "removeDC"); QString saveString; + // Save wavetables for (int i = 0; i < 8; ++i) { if (m_enabled[i]->value()) @@ -458,6 +444,7 @@ void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) } } + // Save sub oscillator waveforms for (int i = 0; i < 64; ++i) { if (m_subEnabled[i]->value()) @@ -468,10 +455,12 @@ void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) } } + // Save graph in Sample Tab base64::encode((const char *)m_sampGraphs, 1024 * sizeof(float), saveString); thissave.setAttribute("sampGraphs", saveString); + // Save samples int sampleSizes[8] = {0}; for (int i = 0; i < 8; ++i) { @@ -488,10 +477,12 @@ void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) } } + // Save sample lengths (required for loading samples) base64::encode((const char *)sampleSizes, 8 * sizeof(int), saveString); thissave.setAttribute("sampleSizes", saveString); + // Save all other values for (int i = 0; i < m_maxMainEnabled; ++i) { if (m_enabled[i]->value()) @@ -615,125 +606,125 @@ void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) } -void Microwave::loadSettings(const QDomElement & thissave) +void Microwave::loadSettings(const QDomElement & thisload) { - QString microwaveVersion = thissave.attribute("version"); + QString microwaveVersion = thisload.attribute("version"); - m_visvol.loadSettings(thissave, "visualizer_volume"); - m_loadMode.loadSettings(thissave, "loadingalgorithm"); - m_loadChnl.loadSettings(thissave, "loadingchannel"); - - m_oversample.loadSettings(thissave, "oversample"); - m_oversampleMode.loadSettings(thissave, "oversamplemode"); - m_removeDC.loadSettings(thissave, "removeDC"); + m_visvol.loadSettings(thisload, "visualizer_volume"); + m_loadMode.loadSettings(thisload, "loadingalgorithm"); + m_loadChnl.loadSettings(thisload, "loadingchannel"); + m_oversample.loadSettings(thisload, "oversample"); + m_oversampleMode.loadSettings(thisload, "oversamplemode"); + m_removeDC.loadSettings(thisload, "removeDC"); m_graph.setLength(2048); + // Load widget values for (int i = 0; i < 8; ++i) { - m_enabled[i]->loadSettings(thissave, "enabled_"+QString::number(i)); + m_enabled[i]->loadSettings(thisload, "enabled_"+QString::number(i)); if (m_enabled[i]->value()) { - m_morph[i]->loadSettings(thissave, "morph_"+QString::number(i)); - m_range[i]->loadSettings(thissave, "range_"+QString::number(i)); - m_modify[i]->loadSettings(thissave, "modify_"+QString::number(i)); - m_modifyMode[i]->loadSettings(thissave, "modifyMode_"+QString::number(i)); - m_unisonVoices[i]->loadSettings(thissave, "unisonVoices_"+QString::number(i)); - m_unisonDetune[i]->loadSettings(thissave, "unisonDetune_"+QString::number(i)); - m_unisonMorph[i]->loadSettings(thissave, "unisonMorph_"+QString::number(i)); - m_unisonModify[i]->loadSettings(thissave, "unisonModify_"+QString::number(i)); - m_morphMax[i]->loadSettings(thissave, "morphMax_"+QString::number(i)); - m_detune[i]->loadSettings(thissave, "detune_"+QString::number(i)); - m_sampLen[i]->loadSettings(thissave, "sampLen_"+QString::number(i)); - m_phase[i]->loadSettings(thissave, "phase_"+QString::number(i)); - m_phaseRand[i]->loadSettings(thissave, "phaseRand_"+QString::number(i)); - m_vol[i]->loadSettings(thissave, "vol_"+QString::number(i)); - m_muted[i]->loadSettings(thissave, "muted_"+QString::number(i)); - m_pan[i]->loadSettings(thissave, "pan_"+QString::number(i)); - m_keytracking[i]->loadSettings(thissave, "keytracking_"+QString::number(i)); - m_tempo[i]->loadSettings(thissave, "tempo_"+QString::number(i)); - m_interpolate[i]->loadSettings(thissave, "interpolate_"+QString::number(i)); + m_morph[i]->loadSettings(thisload, "morph_"+QString::number(i)); + m_range[i]->loadSettings(thisload, "range_"+QString::number(i)); + m_modify[i]->loadSettings(thisload, "modify_"+QString::number(i)); + m_modifyMode[i]->loadSettings(thisload, "modifyMode_"+QString::number(i)); + m_unisonVoices[i]->loadSettings(thisload, "unisonVoices_"+QString::number(i)); + m_unisonDetune[i]->loadSettings(thisload, "unisonDetune_"+QString::number(i)); + m_unisonMorph[i]->loadSettings(thisload, "unisonMorph_"+QString::number(i)); + m_unisonModify[i]->loadSettings(thisload, "unisonModify_"+QString::number(i)); + m_morphMax[i]->loadSettings(thisload, "morphMax_"+QString::number(i)); + m_detune[i]->loadSettings(thisload, "detune_"+QString::number(i)); + m_sampLen[i]->loadSettings(thisload, "sampLen_"+QString::number(i)); + m_phase[i]->loadSettings(thisload, "phase_"+QString::number(i)); + m_phaseRand[i]->loadSettings(thisload, "phaseRand_"+QString::number(i)); + m_vol[i]->loadSettings(thisload, "vol_"+QString::number(i)); + m_muted[i]->loadSettings(thisload, "muted_"+QString::number(i)); + m_pan[i]->loadSettings(thisload, "pan_"+QString::number(i)); + m_keytracking[i]->loadSettings(thisload, "keytracking_"+QString::number(i)); + m_tempo[i]->loadSettings(thisload, "tempo_"+QString::number(i)); + m_interpolate[i]->loadSettings(thisload, "interpolate_"+QString::number(i)); } - m_filtEnabled[i]->loadSettings(thissave, "filtEnabled_"+QString::number(i)); + m_filtEnabled[i]->loadSettings(thisload, "filtEnabled_"+QString::number(i)); if (m_filtEnabled[i]->value()) { - m_filtInVol[i]->loadSettings(thissave, "filtInVol_"+QString::number(i)); - m_filtType[i]->loadSettings(thissave, "filtType_"+QString::number(i)); - m_filtSlope[i]->loadSettings(thissave, "filtSlope_"+QString::number(i)); - m_filtCutoff[i]->loadSettings(thissave, "filtCutoff_"+QString::number(i)); - m_filtReso[i]->loadSettings(thissave, "filtReso_"+QString::number(i)); - m_filtGain[i]->loadSettings(thissave, "filtGain_"+QString::number(i)); - m_filtSatu[i]->loadSettings(thissave, "filtSatu_"+QString::number(i)); - m_filtWetDry[i]->loadSettings(thissave, "filtWetDry_"+QString::number(i)); - m_filtBal[i]->loadSettings(thissave, "filtBal_"+QString::number(i)); - m_filtOutVol[i]->loadSettings(thissave, "filtOutVol_"+QString::number(i)); - m_filtFeedback[i]->loadSettings(thissave, "filtFeedback_"+QString::number(i)); - m_filtDetune[i]->loadSettings(thissave, "filtDetune_"+QString::number(i)); - m_filtKeytracking[i]->loadSettings(thissave, "filtKeytracking_"+QString::number(i)); - m_filtMuted[i]->loadSettings(thissave, "filtMuted_"+QString::number(i)); + m_filtInVol[i]->loadSettings(thisload, "filtInVol_"+QString::number(i)); + m_filtType[i]->loadSettings(thisload, "filtType_"+QString::number(i)); + m_filtSlope[i]->loadSettings(thisload, "filtSlope_"+QString::number(i)); + m_filtCutoff[i]->loadSettings(thisload, "filtCutoff_"+QString::number(i)); + m_filtReso[i]->loadSettings(thisload, "filtReso_"+QString::number(i)); + m_filtGain[i]->loadSettings(thisload, "filtGain_"+QString::number(i)); + m_filtSatu[i]->loadSettings(thisload, "filtSatu_"+QString::number(i)); + m_filtWetDry[i]->loadSettings(thisload, "filtWetDry_"+QString::number(i)); + m_filtBal[i]->loadSettings(thisload, "filtBal_"+QString::number(i)); + m_filtOutVol[i]->loadSettings(thisload, "filtOutVol_"+QString::number(i)); + m_filtFeedback[i]->loadSettings(thisload, "filtFeedback_"+QString::number(i)); + m_filtDetune[i]->loadSettings(thisload, "filtDetune_"+QString::number(i)); + m_filtKeytracking[i]->loadSettings(thisload, "filtKeytracking_"+QString::number(i)); + m_filtMuted[i]->loadSettings(thisload, "filtMuted_"+QString::number(i)); } - m_sampleEnabled[i]->loadSettings(thissave, "sampleEnabled_"+QString::number(i)); + m_sampleEnabled[i]->loadSettings(thisload, "sampleEnabled_"+QString::number(i)); if (m_sampleEnabled[i]->value()) { - m_sampleGraphEnabled[i]->loadSettings(thissave, "sampleGraphEnabled_"+QString::number(i)); - m_sampleMuted[i]->loadSettings(thissave, "sampleMuted_"+QString::number(i)); - m_sampleKeytracking[i]->loadSettings(thissave, "sampleKeytracking_"+QString::number(i)); - m_sampleLoop[i]->loadSettings(thissave, "sampleLoop_"+QString::number(i)); - m_sampleVolume[i]->loadSettings(thissave, "sampleVolume_"+QString::number(i)); - m_samplePanning[i]->loadSettings(thissave, "samplePanning_"+QString::number(i)); - m_sampleDetune[i]->loadSettings(thissave, "sampleDetune_"+QString::number(i)); - m_samplePhase[i]->loadSettings(thissave, "samplePhase_"+QString::number(i)); - m_samplePhaseRand[i]->loadSettings(thissave, "samplePhaseRand_"+QString::number(i)); - m_sampleStart[i]->loadSettings(thissave, "sampleStart_"+QString::number(i)); - m_sampleEnd[i]->loadSettings(thissave, "sampleEnd_"+QString::number(i)); + m_sampleGraphEnabled[i]->loadSettings(thisload, "sampleGraphEnabled_"+QString::number(i)); + m_sampleMuted[i]->loadSettings(thisload, "sampleMuted_"+QString::number(i)); + m_sampleKeytracking[i]->loadSettings(thisload, "sampleKeytracking_"+QString::number(i)); + m_sampleLoop[i]->loadSettings(thisload, "sampleLoop_"+QString::number(i)); + m_sampleVolume[i]->loadSettings(thisload, "sampleVolume_"+QString::number(i)); + m_samplePanning[i]->loadSettings(thisload, "samplePanning_"+QString::number(i)); + m_sampleDetune[i]->loadSettings(thisload, "sampleDetune_"+QString::number(i)); + m_samplePhase[i]->loadSettings(thisload, "samplePhase_"+QString::number(i)); + m_samplePhaseRand[i]->loadSettings(thisload, "samplePhaseRand_"+QString::number(i)); + m_sampleStart[i]->loadSettings(thisload, "sampleStart_"+QString::number(i)); + m_sampleEnd[i]->loadSettings(thisload, "sampleEnd_"+QString::number(i)); } } for (int i = 0; i < 18; ++i) { - m_macro[i]->loadSettings(thissave, "macro_"+QString::number(i)); + m_macro[i]->loadSettings(thisload, "macro_"+QString::number(i)); } for (int i = 0; i < 64; ++i) { - m_subEnabled[i]->loadSettings(thissave, "subEnabled_"+QString::number(i)); + m_subEnabled[i]->loadSettings(thisload, "subEnabled_"+QString::number(i)); if (m_subEnabled[i]->value()) { - m_subVol[i]->loadSettings(thissave, "subVol_"+QString::number(i)); - m_subPhase[i]->loadSettings(thissave, "subPhase_"+QString::number(i)); - m_subPhaseRand[i]->loadSettings(thissave, "subPhaseRand_"+QString::number(i)); - m_subDetune[i]->loadSettings(thissave, "subDetune_"+QString::number(i)); - m_subMuted[i]->loadSettings(thissave, "subMuted_"+QString::number(i)); - m_subKeytrack[i]->loadSettings(thissave, "subKeytrack_"+QString::number(i)); - m_subSampLen[i]->loadSettings(thissave, "subSampLen_"+QString::number(i)); - m_subNoise[i]->loadSettings(thissave, "subNoise_"+QString::number(i)); - m_subPanning[i]->loadSettings(thissave, "subPanning_"+QString::number(i)); - m_subTempo[i]->loadSettings(thissave, "subTempo_"+QString::number(i)); - m_subRateLimit[i]->loadSettings(thissave, "subRateLimit_"+QString::number(i)); - m_subUnisonNum[i]->loadSettings(thissave, "subUnisonNum_"+QString::number(i)); - m_subUnisonDetune[i]->loadSettings(thissave, "subUnisonDetune_"+QString::number(i)); - m_subInterpolate[i]->loadSettings(thissave, "subInterpolate_"+QString::number(i)); + m_subVol[i]->loadSettings(thisload, "subVol_"+QString::number(i)); + m_subPhase[i]->loadSettings(thisload, "subPhase_"+QString::number(i)); + m_subPhaseRand[i]->loadSettings(thisload, "subPhaseRand_"+QString::number(i)); + m_subDetune[i]->loadSettings(thisload, "subDetune_"+QString::number(i)); + m_subMuted[i]->loadSettings(thisload, "subMuted_"+QString::number(i)); + m_subKeytrack[i]->loadSettings(thisload, "subKeytrack_"+QString::number(i)); + m_subSampLen[i]->loadSettings(thisload, "subSampLen_"+QString::number(i)); + m_subNoise[i]->loadSettings(thisload, "subNoise_"+QString::number(i)); + m_subPanning[i]->loadSettings(thisload, "subPanning_"+QString::number(i)); + m_subTempo[i]->loadSettings(thisload, "subTempo_"+QString::number(i)); + m_subRateLimit[i]->loadSettings(thisload, "subRateLimit_"+QString::number(i)); + m_subUnisonNum[i]->loadSettings(thisload, "subUnisonNum_"+QString::number(i)); + m_subUnisonDetune[i]->loadSettings(thisload, "subUnisonDetune_"+QString::number(i)); + m_subInterpolate[i]->loadSettings(thisload, "subInterpolate_"+QString::number(i)); } - m_modEnabled[i]->loadSettings(thissave, "modEnabled_"+QString::number(i)); + m_modEnabled[i]->loadSettings(thisload, "modEnabled_"+QString::number(i)); if (m_modEnabled[i]->value()) { - m_modIn[i]->loadSettings(thissave, "modIn_"+QString::number(i)); - m_modInNum[i]->loadSettings(thissave, "modInNu"+QString::number(i)); - m_modInAmnt[i]->loadSettings(thissave, "modInAmnt_"+QString::number(i)); - m_modInCurve[i]->loadSettings(thissave, "modInCurve_"+QString::number(i)); - m_modIn2[i]->loadSettings(thissave, "modIn2_"+QString::number(i)); - m_modInNum2[i]->loadSettings(thissave, "modInNum2_"+QString::number(i)); - m_modInAmnt2[i]->loadSettings(thissave, "modAmnt2_"+QString::number(i)); - m_modInCurve2[i]->loadSettings(thissave, "modCurve2_"+QString::number(i)); - m_modOutSec[i]->loadSettings(thissave, "modOutSec_"+QString::number(i)); - m_modOutSig[i]->loadSettings(thissave, "modOutSig_"+QString::number(i)); - m_modOutSecNum[i]->loadSettings(thissave, "modOutSecNu"+QString::number(i)); - m_modCombineType[i]->loadSettings(thissave, "modCombineType_"+QString::number(i)); - m_modType[i]->loadSettings(thissave, "modType_"+QString::number(i)); - m_modType2[i]->loadSettings(thissave, "modType2_"+QString::number(i)); + m_modIn[i]->loadSettings(thisload, "modIn_"+QString::number(i)); + m_modInNum[i]->loadSettings(thisload, "modInNu"+QString::number(i)); + m_modInAmnt[i]->loadSettings(thisload, "modInAmnt_"+QString::number(i)); + m_modInCurve[i]->loadSettings(thisload, "modInCurve_"+QString::number(i)); + m_modIn2[i]->loadSettings(thisload, "modIn2_"+QString::number(i)); + m_modInNum2[i]->loadSettings(thisload, "modInNum2_"+QString::number(i)); + m_modInAmnt2[i]->loadSettings(thisload, "modAmnt2_"+QString::number(i)); + m_modInCurve2[i]->loadSettings(thisload, "modCurve2_"+QString::number(i)); + m_modOutSec[i]->loadSettings(thisload, "modOutSec_"+QString::number(i)); + m_modOutSig[i]->loadSettings(thisload, "modOutSig_"+QString::number(i)); + m_modOutSecNum[i]->loadSettings(thisload, "modOutSecNu"+QString::number(i)); + m_modCombineType[i]->loadSettings(thisload, "modCombineType_"+QString::number(i)); + m_modType[i]->loadSettings(thisload, "modType_"+QString::number(i)); + m_modType2[i]->loadSettings(thisload, "modType2_"+QString::number(i)); } } @@ -741,11 +732,12 @@ void Microwave::loadSettings(const QDomElement & thissave) char * dst = 0; + // Load wavetables for (int j = 0; j < 8; ++j) { if (m_enabled[j]->value()) { - base64::decode(thissave.attribute("waveforms"+QString::number(j)), &dst, &size); + base64::decode(thisload.attribute("waveforms"+QString::number(j)), &dst, &size); for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { m_storedwaveforms[j][i] = ((float*) dst)[i]; @@ -753,11 +745,12 @@ void Microwave::loadSettings(const QDomElement & thissave) } } + // Load sub oscillator waveforms for (int j = 0; j < 64; ++j) { if (m_subEnabled[j]->value()) { - base64::decode(thissave.attribute("subs"+QString::number(j)), &dst, &size); + base64::decode(thisload.attribute("subs"+QString::number(j)), &dst, &size); for (int i = 0; i < STOREDSUBWAVELEN; ++i) { m_storedsubs[j][i] = ((float*) dst)[i]; @@ -765,26 +758,29 @@ void Microwave::loadSettings(const QDomElement & thissave) } } - base64::decode(thissave.attribute("sampGraphs"), &dst, &size); + // Load sample graphs + base64::decode(thisload.attribute("sampGraphs"), &dst, &size); for (int i = 0; i < 1024; ++i) { m_sampGraphs[i] = ((float*) dst)[i]; } + // Load sample lengths (required for loading samples) int m_sampleSizes[8] = {0}; - base64::decode(thissave.attribute("sampleSizes"), &dst, &size); + base64::decode(thisload.attribute("sampleSizes"), &dst, &size); for (int i = 0; i < 8; ++i) { m_sampleSizes[i] = ((int*) dst)[i]; } + // Load samples for (int i = 0; i < 8; ++i) { if (m_sampleEnabled[i]->value()) { for (int j = 0; j < 2; ++j) { - base64::decode(thissave.attribute("samples_"+QString::number(i)+"_"+QString::number(j)), &dst, &size); + base64::decode(thisload.attribute("samples_"+QString::number(i)+"_"+QString::number(j)), &dst, &size); for (int k = 0; k < m_sampleSizes[i]; ++k) { m_samples[i][j].push_back(((float*) dst)[k]); @@ -793,12 +789,13 @@ void Microwave::loadSettings(const QDomElement & thissave) } } + // Load macro tooltips and colors for (int i = 0; i < 18; ++i) { - m_macroTooltips[i] = thissave.attribute("macroTooltips_"+QString::number(i)); - m_macroColors[i][0] = thissave.attribute("macroRed_"+QString::number(i)).toInt(); - m_macroColors[i][1] = thissave.attribute("macroGreen_"+QString::number(i)).toInt(); - m_macroColors[i][2] = thissave.attribute("macroBlue_"+QString::number(i)).toInt(); + m_macroTooltips[i] = thisload.attribute("macroTooltips_"+QString::number(i)); + m_macroColors[i][0] = thisload.attribute("macroRed_"+QString::number(i)).toInt(); + m_macroColors[i][1] = thisload.attribute("macroGreen_"+QString::number(i)).toInt(); + m_macroColors[i][2] = thisload.attribute("macroBlue_"+QString::number(i)).toInt(); } delete[] dst; @@ -824,7 +821,7 @@ void Microwave::loadSettings(const QDomElement & thissave) // When a knob is changed, send the new value to the array holding the knob values, -// as well as the note values within mSynths already initialized (notes already playing) +// and also to the values within mSynths already initialized (notes already playing) void Microwave::valueChanged(int which, int num) { //Send new values to array @@ -1014,7 +1011,7 @@ void Microwave::valueChanged(int which, int num) } -// Set the range of Morph based on Morph Max +// Set the range of Morph and Unison Morph based on Morph Max void Microwave::morphMaxChanged(int i) { m_morph[i]->setRange(m_morph[i]->minValue(), m_morphMax[i]->value(), m_morph[i]->step()); @@ -1022,7 +1019,7 @@ void Microwave::morphMaxChanged(int i) } -// Set the range of morphMax and Modify based on new sample length +// Set the range of morphMax, Modify, and Unison Modify based on new wavetable waveform length void Microwave::sampLenChanged(int i) { m_morphMax[i]->setRange(m_morphMax[i]->minValue(), STOREDMAINARRAYLEN / m_sampLen[i]->value() - 2, m_morphMax[i]->step()); @@ -1031,7 +1028,7 @@ void Microwave::sampLenChanged(int i) } -//Change m_graph length to sample length +//Change graph length to waveform length void Microwave::subSampLenChanged(int num) { if (m_scroll == 1 && m_subNum.value() == num + 1) @@ -1106,21 +1103,21 @@ void Microwave::filtEnabledChanged(int num) } -//Updates sub oscillator inteprolation when the interpolation LED is changed. +//Updates wavetable interpolation when the interpolation LED is changed. void Microwave::interpolateChanged(int num) { fillMainOsc(num, m_interpolate[num]->value()); } -//Updates sub oscillator inteprolation when the interpolation LED is changed. +//Updates sub oscillator interpolation when the interpolation LED is changed. void Microwave::subInterpolateChanged(int num) { fillSubOsc(num, m_subInterpolate[num]->value()); } -//When user drawn on graph, send new values to the correct arrays +//When user draws on graph, send new values to the correct arrays void Microwave::samplesChanged(int begin, int end) { switch ((int)m_scroll) @@ -1218,13 +1215,13 @@ void Microwave::switchMatrixSections(int source, int destination) // we want to make sure it's still attached to the same box after it is moved. for (int i = 0; i < 64; ++i) { - if (m_modOutSec[i]->value() == 4)// Output is being sent to Matrix + if (m_modOutSec[i]->value() == 4)// If output is being sent to Matrix { - if (m_modOutSecNum[i]->value() - 1 == source)// Output was being sent a matrix box that was moved + if (m_modOutSecNum[i]->value() - 1 == source)// If output was being sent a matrix box that was moved { m_modOutSecNum[i]->setValue(destination + 1); } - else if (m_modOutSecNum[i]->value() - 1 == destination)// Output was being sent a matrix box that was moved + else if (m_modOutSecNum[i]->value() - 1 == destination)// If output was being sent a matrix box that was moved { m_modOutSecNum[i]->setValue(source + 1); } @@ -1235,10 +1232,10 @@ void Microwave::switchMatrixSections(int source, int destination) // For when notes are playing. This initializes a new mSynth if the note is new. // It also uses mSynth::nextStringSample to get the synthesizer output. -// This is where oversampling and the m_visualizer are handled. +// This is where oversampling and the visualizer are handled. void Microwave::playNote(NotePlayHandle * n, sampleFrame * working_buffer) { - + // If the note is brand new if (n->m_pluginData == NULL || n->totalFramesPlayed() == 0) { n->m_pluginData = new mSynth( @@ -1257,6 +1254,7 @@ void Microwave::playNote(NotePlayHandle * n, sampleFrame * working_buffer) m_samples); m_mwc = dynamic_cast(n->instrumentTrack()->instrument()); + // Interpolate sub oscillator waveform if it hasn't been done already for (int i = 0; i < 64; ++i) { if (m_subEnabled[i]->value()) @@ -1282,7 +1280,8 @@ void Microwave::playNote(NotePlayHandle * n, sampleFrame * working_buffer) { case 0: { - // Process some samples and ignore the output, depending on the oversampling value. For example, if the oversampling is set to 4x, it will process 4 samples and output 1 of those. + // Process some samples and ignore the output, depending on the oversampling value. + // For example, if the oversampling is set to 4x, it will calculate 4 samples and output 1 of those. for (int i = 0; i < m_oversample.value() + 1; ++i) { ps->nextStringSample(outputSample, m_waveforms, m_subs, m_samples, m_sampGraphs, m_maxMainEnabled, m_maxSubEnabled, m_maxSampleEnabled, m_maxFiltEnabled, m_maxModEnabled, Engine::mixer()->processingSampleRate() * (m_oversample.value() + 1), m_mwc, m_removeDC.value(), m_storedsubs); @@ -1295,6 +1294,7 @@ void Microwave::playNote(NotePlayHandle * n, sampleFrame * working_buffer) case 1: { // Process some number of samples and average them together, depending on the oversampling value. + // For example, if the oversampling is set to 4x, it will calculate 4 samples and take the average of those. for (int i = 0; i < m_oversample.value() + 1; ++i) { ps->nextStringSample(outputSample, m_waveforms, m_subs, m_samples, m_sampGraphs, m_maxMainEnabled, m_maxSubEnabled, m_maxSampleEnabled, m_maxFiltEnabled, m_maxModEnabled, Engine::mixer()->processingSampleRate() * (m_oversample.value() + 1), m_mwc, m_removeDC.value(), m_storedsubs); @@ -1315,11 +1315,11 @@ void Microwave::playNote(NotePlayHandle * n, sampleFrame * working_buffer) working_buffer[frame][chnl] = totalOutputSample[chnl]; } - //update visualizer + // Update visualizer if (m_viewOpen && m_visualize.value() && m_scroll == 0 && ps->m_enabled[m_mainNum.value()-1]) { m_visualizerValues[int((ps->m_sample_realindex[m_mainNum.value()-1][0] / (ps->m_sampLen[m_mainNum.value()-1] * WAVERATIO)) * 204.f)] = ps->m_mainsample[m_mainNum.value()-1][0] * m_visvol.value() * 0.01f; - if (ps->m_noteDuration % 1470 == 1)// Updates around 30 times per second (per note because I'm lazy I guess?) + if (ps->m_noteDuration % 1470 == 1)// Updates around 30 times per second per note { m_graph.setSamples(m_visualizerValues); } @@ -1337,7 +1337,7 @@ void Microwave::deleteNotePluginData(NotePlayHandle * n) } -// Fill m_subs using m_storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. +// Fill m_subs using m_storedsubs, oftentimes making use of libsamplerate for some awesome sinc interpolation. inline void Microwave::fillSubOsc(int which, bool doInterpolate) { if (doInterpolate) @@ -1359,7 +1359,7 @@ inline void Microwave::fillSubOsc(int which, bool doInterpolate) -// Fill m_subs using m_storedsubs, usually (but not always) making use of libsamplerate for some awesome sinc interpolation. +// Fill m_waveforms using m_storedwaveforms, oftentimes making use of libsamplerate for some awesome sinc interpolation. inline void Microwave::fillMainOsc(int which, bool doInterpolate) { if (doInterpolate) @@ -1386,7 +1386,7 @@ inline void Microwave::fillMainOsc(int which, bool doInterpolate) //== MICROWAVEVIEW ==// //===================// -// Creates the Microwave GUI. Creates all GUI elements. Connects some events to some functions. Calls updateScroll() to put all of the GUI elements in their correct positions. +// Creates the Microwave GUI. MicrowaveView::MicrowaveView(Instrument * instrument, QWidget * parent) : InstrumentView(instrument, parent) @@ -1648,13 +1648,16 @@ MicrowaveView::MicrowaveView(Instrument * instrument, } makeknob(m_visvolKnob, knobSmallColored, tr("Visualizer Volume"), tr("This knob works as a vertical zoom knob for the visualizer.")); + m_visvolKnob->setModel(&m_b->m_visvol); makeknob(m_loadChnlKnob, knobColored, tr("Wavetable Loading Channel"), tr("This knob chooses whether to load the left or right audio of the selected sample/wavetable.")); + m_loadChnlKnob->setModel(&m_b->m_loadChnl); m_graph = new Graph(this, Graph::BarCenterGradStyle, 204, 134); m_graph->setAutoFillBackground(true); m_graph->setGraphColor(QColor(121, 222, 239)); + m_graph->setModel(&m_b->m_graph); ToolTip::add(m_graph, tr ("Draw here by dragging your mouse on this graph.")); @@ -1801,10 +1804,12 @@ MicrowaveView::MicrowaveView(Instrument * instrument, m_removeDCBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("remove_dc_offset_button_disabled")); ToolTip::add(m_removeDCBtn, tr("Remove DC Offset")); m_removeDCBtn->setCheckable(true); + m_removeDCBtn->setModel(&m_b->m_removeDC); m_oversampleModeBox = new ComboBox(this); m_oversampleModeBox->setGeometry(0, 0, 42, 22); m_oversampleModeBox->setFont(pointSize<8>(m_oversampleModeBox->font())); + m_oversampleModeBox->setModel(&m_b->m_oversampleMode); m_normalizeBtn = new PixmapButton(this, tr("Normalize Wavetable")); @@ -1847,28 +1852,33 @@ MicrowaveView::MicrowaveView(Instrument * instrument, m_mainNumBox = new LcdSpinBox(2, "microwave", this, "Oscillator Number"); ToolTip::add(m_mainNumBox, tr("Oscillator Number")); + m_mainNumBox->setModel(&m_b->m_mainNum); m_subNumBox = new LcdSpinBox(2, "microwave", this, "Sub Oscillator Number"); ToolTip::add(m_subNumBox, tr("Oscillator Number")); + m_subNumBox->setModel(&m_b->m_subNum); m_sampNumBox = new LcdSpinBox(2, "microwave", this, "Sample Number"); ToolTip::add(m_sampNumBox, tr("Oscillator Number")); + m_sampNumBox->setModel(&m_b->m_sampNum); m_oversampleBox = new ComboBox(this); m_oversampleBox->setGeometry(0, 0, 42, 22); m_oversampleBox->setFont(pointSize<8>(m_oversampleBox->font())); ToolTip::add(m_oversampleBox, tr("Oversampling Amount")); + m_oversampleBox->setModel(&m_b->m_oversample); m_loadModeBox = new ComboBox(this); m_loadModeBox->setGeometry(0, 0, 202, 22); m_loadModeBox->setFont(pointSize<8>(m_loadModeBox->font())); ToolTip::add(m_loadModeBox, tr("Oversampling Mode")); + m_loadModeBox->setModel(&m_b->m_loadMode); m_openSampleButton = new PixmapButton(this); m_openSampleButton->setCursor(QCursor(Qt::PointingHandCursor)); m_openSampleButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); m_openSampleButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("fileload")); - ToolTip::add(m_oversampleBox, tr("Load Sound Sample")); + ToolTip::add(m_openSampleButton, tr("Load Sound Sample")); m_effectScrollBar = new QScrollBar(Qt::Vertical, this); m_effectScrollBar->setSingleStep(1); @@ -1907,7 +1917,6 @@ MicrowaveView::MicrowaveView(Instrument * instrument, ToolTip::add(m_openSampleButton, tr("Open sample")); - connect(m_sinWaveBtn, SIGNAL (clicked ()), this, SLOT (sinWaveClicked())); connect(m_triangleWaveBtn, SIGNAL (clicked ()), this, SLOT (triangleWaveClicked())); connect(m_sawWaveBtn, SIGNAL (clicked ()), this, SLOT (sawWaveClicked())); @@ -1948,12 +1957,15 @@ MicrowaveView::MicrowaveView(Instrument * instrument, connect(m_mainFlipBtn, SIGNAL (clicked ()), this, SLOT (flipperClicked())); ToolTip::add(m_mainFlipBtn, tr("Flip to other knobs")); + m_mainFlipBtn->setModel(&m_b->m_mainFlipped); connect(m_subFlipBtn, SIGNAL (clicked ()), this, SLOT (flipperClicked())); ToolTip::add(m_subFlipBtn, tr("Flip to other knobs")); + m_subFlipBtn->setModel(&m_b->m_subFlipped); connect(m_visualizeToggle, SIGNAL(toggled(bool)), this, SLOT (visualizeToggled(bool))); ToolTip::add(m_visualizeToggle, tr("Enable wavetable visualizer")); + m_visualizeToggle->setModel(&m_b->m_visualize); connect(&m_b->m_mainNum, SIGNAL(dataChanged()), this, SLOT(mainNumChanged())); connect(&m_b->m_subNum, SIGNAL(dataChanged()), this, SLOT(subNumChanged())); @@ -1983,10 +1995,14 @@ MicrowaveView::MicrowaveView(Instrument * instrument, connect(m_b->m_enabled[i], SIGNAL(dataChanged()), this, SLOT(mainNumChanged())); connect(m_b->m_subEnabled[i], SIGNAL(dataChanged()), this, SLOT(subNumChanged())); connect(m_b->m_sampleEnabled[i], SIGNAL(dataChanged()), this, SLOT(sampNumChanged())); + + // This is run here to prevent the graph from being the wrong color on project load + mainNumChanged(); } for (int i = 0; i < 18; ++i) { + // Add custom tooltips to Macro knobs if (!m_b->m_macroTooltips[i].isEmpty()) { ToolTip::add(m_macroKnob[i], tr("Macro %1: ").arg(i + 1) + m_b->m_macroTooltips[i]); @@ -2006,30 +2022,10 @@ MicrowaveView::MicrowaveView(Instrument * instrument, MicrowaveView::~MicrowaveView() { - // This got mad when using the vairable "m_b". if (castModel()) { castModel()->m_viewOpen = false; } } -// Connects knobs/GUI elements to their models -void MicrowaveView::modelChanged() -{ - m_graph->setModel(&m_b->m_graph); - m_visvolKnob->setModel(&m_b->m_visvol); - m_visualizeToggle->setModel(&m_b->m_visualize); - m_subNumBox->setModel(&m_b->m_subNum); - m_sampNumBox->setModel(&m_b->m_sampNum); - m_loadChnlKnob->setModel(&m_b->m_loadChnl); - m_mainNumBox->setModel(&m_b->m_mainNum); - m_oversampleBox->setModel(&m_b->m_oversample); - m_loadModeBox->setModel(&m_b->m_loadMode); - m_mainFlipBtn->setModel(&m_b->m_mainFlipped); - m_subFlipBtn->setModel(&m_b->m_subFlipped); - m_removeDCBtn->setModel(&m_b->m_removeDC); - m_oversampleModeBox->setModel(&m_b->m_oversampleMode); -} - - // Moves GUI elements to their correct locations and toggles their visibility when needed void MicrowaveView::updateScroll() { @@ -2331,7 +2327,7 @@ void MicrowaveView::updateScroll() } - +// Change the tab when the user scrolls over the tab buttons void MicrowaveView::wheelEvent(QWheelEvent * me) { if (me->x() <= 18 && me->y() >= 48 && me->y() <= 138)// If scroll over tab buttons @@ -2353,6 +2349,7 @@ void MicrowaveView::wheelEvent(QWheelEvent * me) } +// Set the graph color depending on whether the oscillator being viewed currently is enabled void MicrowaveView::setGraphEnabledColor(bool isEnabled) { m_graph->setGraphColor(isEnabled ? QColor(121, 222, 239) : QColor(197, 197, 197)); @@ -2730,8 +2727,6 @@ void MicrowaveView::modIn2Changed(int i) // Does what is necessary when the user visits a new tab void MicrowaveView::tabChanged(int tabnum) { - m_b->m_currentTab = tabnum; - updateBackground(); if (tabnum != 3) @@ -2810,15 +2805,14 @@ void MicrowaveView::tabChanged(int tabnum) void MicrowaveView::updateBackground() { - int backgroundnum = m_b->m_currentTab; bool m_mainFlipped = m_b->m_mainFlipped.value(); bool m_subFlipped = m_b->m_subFlipped.value(); - switch (backgroundnum) + switch ((int)m_b->m_scroll) { case 0:// Wavetable { - m_b->m_graph.setLength(204); + m_b->m_graph.setLength(204);// Graph is 204 pixels long mainNumChanged(); if (!m_mainFlipped) @@ -2886,8 +2880,7 @@ void MicrowaveView::updateBackground() } - - +// Change visualizer volume knob visibility when visualize LED is toggled void MicrowaveView::visualizeToggled(bool value) { m_visvolKnob->setVisible(m_b->m_visualize.value()); @@ -2967,6 +2960,7 @@ void MicrowaveView::MatrixXBtnClicked() } +// Normalize wavetable void MicrowaveView::normalizeClicked() { int oscilNum = m_b->m_mainNum.value() - 1; @@ -2976,7 +2970,9 @@ void MicrowaveView::normalizeClicked() float highestVolume = 0; for (int j = 0; j < 2048; ++j) { - highestVolume = abs(m_b->m_storedwaveforms[oscilNum][(i*2048)+j]) > highestVolume ? abs(m_b->m_storedwaveforms[oscilNum][(i*2048)+j]) : highestVolume; + highestVolume = abs(m_b->m_storedwaveforms[oscilNum][(i*2048)+j]) > highestVolume + ? abs(m_b->m_storedwaveforms[oscilNum][(i*2048)+j]) + : highestVolume; } if (highestVolume) { @@ -2995,6 +2991,8 @@ void MicrowaveView::normalizeClicked() m_b->fillMainOsc(oscilNum, m_b->m_interpolate[oscilNum]->value()); } + +// Bend wavetable waveforms so the ends match void MicrowaveView::desawClicked() { int oscilNum = m_b->m_mainNum.value() - 1; @@ -3042,14 +3040,15 @@ void MicrowaveView::modDownClicked(int i) } -//NOTE: Different from Microwave::modEnabledChanged. -//Changes maximum value of the Matrix scroll bar. +// Different from Microwave::modEnabledChanged. +// Changes maximum value of the Matrix scroll bar. void MicrowaveView::modEnabledChanged() { m_matrixScrollBar->setRange(0, qBound(100.f, m_b->m_maxModEnabled * 100.f, 6232.f) + 30.f); } +// Move window to location of Matrix input void MicrowaveView::i1Clicked(int i) { int modScrollVal = m_matrixScrollBar->value() / 100.f * 115.f; @@ -3092,6 +3091,7 @@ void MicrowaveView::i1Clicked(int i) } +// Move window to location of Matrix input void MicrowaveView::i2Clicked(int i) { int modScrollVal = m_matrixScrollBar->value() / 100.f * 115.f; @@ -3141,7 +3141,7 @@ void MicrowaveView::tabBtnClicked(int i) } - +// Run when user sends a knob to the Matrix through its right click menu void MicrowaveView::sendToMatrixAsOutput(int loc1, int loc2, int loc3) { int m_matrixLocation = m_b->m_maxModEnabled; @@ -3154,7 +3154,7 @@ void MicrowaveView::sendToMatrixAsOutput(int loc1, int loc2, int loc3) m_b->m_modOutSecNum[m_matrixLocation]->setValue(loc3 + 1); } - m_tabWhenSendingToMatrix = m_b->m_currentTab; + m_tabWhenSendingToMatrix = m_b->m_scroll; m_MatrixXBtn->show(); @@ -3165,6 +3165,7 @@ void MicrowaveView::sendToMatrixAsOutput(int loc1, int loc2, int loc3) } +// Make knob green and connect to its corresponding Matrix Amount knob void MicrowaveView::switchToMatrixKnob(MicrowaveKnob * theKnob, int loc1, int loc2, int loc3) { for (int i = 0; i < 64; ++i) @@ -3181,6 +3182,7 @@ void MicrowaveView::switchToMatrixKnob(MicrowaveKnob * theKnob, int loc1, int lo } +// Lets user change the tooltip of Macro knobs void MicrowaveView::setMacroTooltip(MicrowaveKnob * theKnob, int which) { bool ok; @@ -3196,7 +3198,7 @@ void MicrowaveView::setMacroTooltip(MicrowaveKnob * theKnob, int which) } - +// Lets user change the color of Macro knobs void MicrowaveView::chooseMacroColor(MicrowaveKnob * theKnob, int which) { QColor new_color = QColorDialog::getColor(QColor(m_b->m_macroColors[which][0], m_b->m_macroColors[which][1], m_b->m_macroColors[which][2])); @@ -3263,7 +3265,7 @@ void MicrowaveView::confirmWavetableLoadClicked() } -// All of the code and algorithms for loading wavetables from m_samples. Please don't expect this code to look neat. +// All of the code and algorithms for loading wavetables from samples. void MicrowaveView::openWavetableFile(QString fileName) { const sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); @@ -3289,23 +3291,23 @@ void MicrowaveView::openWavetableFile(QString fileName) if (!fileName.isEmpty()) { m_sampleBuffer->dataReadLock(); - float lengthOfSample = ((filelength/1000.f)*sample_rate);//in m_samples + float lengthOfSample = ((filelength/1000.f)*sample_rate);//in samples switch (algorithm) { case 0:// Lock waveform edges to zero crossings { - //Clear wavetable + // Clear wavetable for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { m_b->m_storedwaveforms[oscilNum][i] = 0; } - bool above = m_sampleBuffer->userWaveSample(1.f/lengthOfSample, channel) > 0; + bool above = m_sampleBuffer->userWaveSample(1.f / lengthOfSample, channel) > 0; float currentValue = 0; std::vector zeroCrossings; float previousPoint = 0; - //Find zero crossings, and store differences between them in a vector. + // Find zero crossings, and store differences between them in a vector. for (int i = 0; i < lengthOfSample; ++i) { currentValue = m_sampleBuffer->userWaveSample(i / lengthOfSample, channel); @@ -3317,7 +3319,7 @@ void MicrowaveView::openWavetableFile(QString fileName) } } - //Quit if the sample is too short + // Quit if the sample is too short if (zeroCrossings.size() < 3) { break; @@ -3327,7 +3329,7 @@ void MicrowaveView::openWavetableFile(QString fileName) float now = 0; float actualnow = 0; - //Find and list chosen zero crossings + // Find and list chosen zero crossings for (int i = 0; i < zeroCrossings.size() - 1; ++i) { now += zeroCrossings[i]; @@ -3347,7 +3349,7 @@ void MicrowaveView::openWavetableFile(QString fileName) bool breakify = false; - //Take gathered information and cram it into the waveforms. + // Take gathered information and cram it into the waveforms. for (int i = 0; i < betterZC.size() - 1; ++i) { start = betterZC[i]; @@ -3375,17 +3377,17 @@ void MicrowaveView::openWavetableFile(QString fileName) break; } - case 1:// Load m_sample without changes + case 1:// Load sample without changes { for (int i = 0; i < STOREDMAINARRAYLEN; ++i) { if (i <= lengthOfSample * 2.f) { - m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample((i/lengthOfSample) / 2.f, channel); + m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample((i / lengthOfSample) / 2.f, channel); } else// Replace everything else with silence if sample isn't long enough { - m_b->m_morphMax[oscilNum]->setValue(i/m_b->m_sampLen[oscilNum]->value()); + m_b->m_morphMax[oscilNum]->setValue(i / m_b->m_sampLen[oscilNum]->value()); m_b->morphMaxChanged(oscilNum); for (int j = i; j < STOREDMAINARRAYLEN; ++j) { m_b->m_storedwaveforms[oscilNum][j] = 0.f; } break; @@ -3399,11 +3401,11 @@ void MicrowaveView::openWavetableFile(QString fileName) { if (i <= lengthOfSample) { - m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample(i/lengthOfSample, channel); + m_b->m_storedwaveforms[oscilNum][i] = m_sampleBuffer->userWaveSample(i / lengthOfSample, channel); } else { - m_b->m_morphMax[oscilNum]->setValue(i/m_b->m_sampLen[oscilNum]->value()); + m_b->m_morphMax[oscilNum]->setValue(i / m_b->m_sampLen[oscilNum]->value()); m_b->morphMaxChanged(oscilNum); for (int j = i; j < STOREDMAINARRAYLEN; ++j) { m_b->m_storedwaveforms[oscilNum][j] = 0.f; } break; @@ -3413,7 +3415,8 @@ void MicrowaveView::openWavetableFile(QString fileName) } case 3:// Autocorrelation { - // This uses a method called autocorrelation to detect the pitch, maliciously stolen from Instructables. It can get a few Hz off (especially at higher frequencies), so I also compare it with the zero crossings to see if I can get it even more accurate. + // This uses a method called autocorrelation to detect the pitch, most of which was taken from the Instructables website. + // It can get a few Hz off (especially at higher frequencies), so I also compare it with the zero crossings to see if I can get it even more accurate. // Estimate pitch using autocorrelation: @@ -3466,11 +3469,11 @@ void MicrowaveView::openWavetableFile(QString fileName) std::vector crossings; crossings.push_back(0); std::vector crossingsDif; - bool above = (m_sampleBuffer->userWaveSample(1/lengthOfSample, channel) > 0); + bool above = (m_sampleBuffer->userWaveSample(1.f / lengthOfSample, channel) > 0); for (int i = 0; i < checkLength; ++i) { - if ((m_sampleBuffer->userWaveSample(i/lengthOfSample, channel) > 0) != above) + if ((m_sampleBuffer->userWaveSample(i / lengthOfSample, channel) > 0) != above) { above = !above; if (above) @@ -3519,10 +3522,11 @@ void MicrowaveView::openWavetableFile(QString fileName) break; } } + m_sampleBuffer->dataUnlock(); + // Interpolate and store wavetable m_b->m_updateWavetable[oscilNum] = true; - m_b->fillMainOsc(oscilNum, m_b->m_interpolate[oscilNum]->value()); } @@ -3538,7 +3542,7 @@ void MicrowaveView::openSampleFileBtnClicked() } -// Loads m_sample for sample oscillator +// Loads sample for sample oscillator void MicrowaveView::openSampleFile() { const sample_rate_t sample_rate = Engine::mixer()->processingSampleRate(); @@ -3547,6 +3551,7 @@ void MicrowaveView::openSampleFile() SampleBuffer * m_sampleBuffer = new SampleBuffer; QString fileName = m_sampleBuffer->openAndSetWaveformFile(); int filelength = m_sampleBuffer->sampleLength(); + if (fileName.isEmpty() == false) { m_sampleBuffer->dataReadLock(); @@ -3556,8 +3561,8 @@ void MicrowaveView::openSampleFile() for (int i = 0; i < lengthOfSample; ++i) { - m_b->m_samples[oscilNum][0].push_back(m_sampleBuffer->userWaveSample(i/lengthOfSample, 0)); - m_b->m_samples[oscilNum][1].push_back(m_sampleBuffer->userWaveSample(i/lengthOfSample, 1)); + m_b->m_samples[oscilNum][0].push_back(m_sampleBuffer->userWaveSample(i / lengthOfSample, 0)); + m_b->m_samples[oscilNum][1].push_back(m_sampleBuffer->userWaveSample(i / lengthOfSample, 1)); } m_sampleBuffer->dataUnlock(); } @@ -3565,7 +3570,7 @@ void MicrowaveView::openSampleFile() } - +// When a sample file is dragged onto Microwave void MicrowaveView::dropEvent(QDropEvent * de) { QString type = StringPairDrag::decodeKey(de); @@ -3582,6 +3587,7 @@ void MicrowaveView::dropEvent(QDropEvent * de) } +// Accept sample dropping into Microwave void MicrowaveView::dragEnterEvent(QDragEnterEvent * dee) { if (dee->mimeData()->hasFormat(StringPairDrag::mimeType())) @@ -3726,6 +3732,11 @@ mSynth::mSynth(NotePlayHandle * m_nph, m_sample_realindex[i][j] = int(((fastRandf(m_sampLen[i] * WAVERATIO)) * (m_phaseRand[i] * 0.01f))) % int(m_sampLen[i] * WAVERATIO); } + + m_sample_sampleindex[i] = fmod(fastRandf(m_samples[i][0].size()) * (m_samplePhaseRand[i] * 0.01f), + (m_samples[i][0].size() *m_sampleEnd[i]) - (m_samples[i][0].size() * m_sampleStart[i])) + + (m_samples[i][0].size() * m_sampleStart[i]); + m_humanizer[i] = (rand() / float(RAND_MAX)) * 2 - 1;// Generate humanizer values at the beginning of every note } for (int i = 0; i < 64; ++i) @@ -3739,14 +3750,6 @@ mSynth::mSynth(NotePlayHandle * m_nph, } } - for (int i = 0; i < 8; ++i) - { - m_sample_sampleindex[i] = fmod(fastRandf(m_samples[i][0].size()) * (m_samplePhaseRand[i] * 0.01f), - (m_samples[i][0].size() *m_sampleEnd[i]) - (m_samples[i][0].size() * m_sampleStart[i])) + - (m_samples[i][0].size() * m_sampleStart[i]); - m_humanizer[i] = (rand() / float(RAND_MAX)) * 2 - 1;// Generate humanizer values at the beginning of every note - } - m_noteDuration = -1; for (int i = 0; i < 8; ++i) @@ -3773,7 +3776,6 @@ mSynth::~mSynth() } -// The heart of Microwave. As you probably learned in anatomy class, hearts actually aren't too pretty. This is no exception. // This is the part that puts everything together and calculates an audio output. void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8][MAINARRAYLEN], float (&m_subs)[64][SUBWAVELEN], std::vector (&m_samples)[8][2], float * m_sampGraphs, int m_maxMainEnabled, int m_maxSubEnabled, @@ -3799,7 +3801,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_curModVal[1] = 0; break; } - case 1:// Wavetablenumber + case 1:// Wavetable { if (m_modType[l])// If envelope { @@ -4025,8 +4027,12 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] { // Move to a scale of 0 to 1 (from -1 to 1) and then apply the curve. m_temp1 = 1.f / (m_modInCurve[l] * 0.01f); - m_curModValCurve[0] = (m_curModVal[0] <= -1 || m_curModVal[0] >= 1) ? (m_curModVal[0] + 1) * 0.5f : pow((m_curModVal[0] + 1) * 0.5f, m_temp1); - m_curModValCurve[1] = (m_curModVal[1] <= -1 || m_curModVal[1] >= 1) ? (m_curModVal[1] + 1) * 0.5f : pow((m_curModVal[1] + 1) * 0.5f, m_temp1); + m_curModValCurve[0] = (m_curModVal[0] <= -1 || m_curModVal[0] >= 1) + ? (m_curModVal[0] + 1) * 0.5f + : pow((m_curModVal[0] + 1) * 0.5f, m_temp1); + m_curModValCurve[1] = (m_curModVal[1] <= -1 || m_curModVal[1] >= 1) + ? (m_curModVal[1] + 1) * 0.5f + : pow((m_curModVal[1] + 1) * 0.5f, m_temp1); } else { @@ -4036,8 +4042,12 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] if (m_modInCurve2[l] != 100.f) { m_temp1 = 1.f / (m_modInCurve2[l] * 0.01f); - m_curModVal2Curve[0] = (m_curModVal2[0] <= -1 || m_curModVal2[0] >= 1) ? (m_curModVal2[0] + 1) * 0.5f : pow((m_curModVal2[0] + 1) * 0.5f, m_temp1); - m_curModVal2Curve[1] = (m_curModVal2[1] <= -1 || m_curModVal2[1] >= 1) ? (m_curModVal2[1] + 1) * 0.5f : pow((m_curModVal2[1] + 1) * 0.5f, m_temp1); + m_curModVal2Curve[0] = (m_curModVal2[0] <= -1 || m_curModVal2[0] >= 1) + ? (m_curModVal2[0] + 1) * 0.5f + : pow((m_curModVal2[0] + 1) * 0.5f, m_temp1); + m_curModVal2Curve[1] = (m_curModVal2[1] <= -1 || m_curModVal2[1] >= 1) + ? (m_curModVal2[1] + 1) * 0.5f + : pow((m_curModVal2[1] + 1) * 0.5f, m_temp1); } else { @@ -4052,8 +4062,12 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = m_modInCurve[l] * 0.01f; m_temp2 = m_curModVal[0] < 0 ? -1 : 1; m_temp3 = m_modInAmnt[l] * 0.01; - m_curModValCurve[0] = ((m_curModVal[0] <= -1 || m_curModVal[0] >= 1) ? m_curModVal[0] : pow(abs(m_curModVal[0]), 1.f / m_temp1) * m_temp2) + m_temp3; - m_curModValCurve[1] = ((m_curModVal[1] <= -1 || m_curModVal[1] >= 1) ? m_curModVal[1] : pow(abs(m_curModVal[1]), 1.f / m_temp1) * m_temp2) + m_temp3; + m_curModValCurve[0] = ((m_curModVal[0] <= -1 || m_curModVal[0] >= 1) + ? m_curModVal[0] + : pow(abs(m_curModVal[0]), 1.f / m_temp1) * m_temp2) + m_temp3; + m_curModValCurve[1] = ((m_curModVal[1] <= -1 || m_curModVal[1] >= 1) + ? m_curModVal[1] + : pow(abs(m_curModVal[1]), 1.f / m_temp1) * m_temp2) + m_temp3; } else { @@ -4066,8 +4080,12 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = m_modInCurve2[l] * 0.01f; m_temp2 = m_curModVal2[0] < 0 ? -1 : 1; m_temp3 = m_modInAmnt2[l] * 0.01; - m_curModVal2Curve[0] = ((m_curModVal2[0] <= -1 || m_curModVal2[0] >= 1) ? m_curModVal2[0] : pow(abs(m_curModVal2[0]), 1.f / m_temp1) * m_temp2) + m_temp3; - m_curModVal2Curve[1] = ((m_curModVal2[1] <= -1 || m_curModVal2[1] >= 1) ? m_curModVal2[1] : pow(abs(m_curModVal2[0]), 1.f / m_temp1) * m_temp2) + m_temp3; + m_curModVal2Curve[0] = ((m_curModVal2[0] <= -1 || m_curModVal2[0] >= 1) + ? m_curModVal2[0] + : pow(abs(m_curModVal2[0]), 1.f / m_temp1) * m_temp2) + m_temp3; + m_curModVal2Curve[1] = ((m_curModVal2[1] <= -1 || m_curModVal2[1] >= 1) + ? m_curModVal2[1] + : pow(abs(m_curModVal2[0]), 1.f / m_temp1) * m_temp2) + m_temp3; } else { @@ -4577,8 +4595,6 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] //== FILTER ==// //============// - // As much as it may seem like it, this section contains no intentional attempts at obfuscation. - for (int l = 0; l < m_maxFiltEnabled; ++l) { if (m_filtEnabled[l]) @@ -4596,12 +4612,14 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = round(sample_rate / detuneWithCents(440.f, m_filtDetune[l])); } + // Set feedback delay length depending on feedback detune and keytracking if (m_filtDelayBuf[l][0].size() < m_temp1) { m_filtDelayBuf[l][0].resize(m_temp1); m_filtDelayBuf[l][1].resize(m_temp1); } + // Grab the next sample in the delay buffer ++m_filtFeedbackLoc[l]; if (m_filtFeedbackLoc[l] > m_temp1 - 1) { @@ -4627,7 +4645,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_r = m_reso*m_scale; } - // m is the slope number. So if m = 2, then the sound is going from a 24 db to a 36 db slope, for example. + // m is the slope number. So if m = 3, then a 12 db filter is going from a 36 db slope to a 48 db slope, for example. for (int m = 0; m < m_filtSlope[l] + 1; ++m) { if (m) @@ -4639,6 +4657,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] int formulaType = 1; if (m_mode <= 7) { + // Calculate filter coefficients switch (m_mode) { case 0:// LP @@ -4840,8 +4859,12 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] // Balance knob wet if (m_filtBal[l]) { - m_filtOutputs[l][0] *= m_filtBal[l] > 0 ? (100.f - m_filtBal[l]) * 0.01f : 1.f; - m_filtOutputs[l][1] *= m_filtBal[l] < 0 ? (100.f + m_filtBal[l]) * 0.01f : 1.f; + m_filtOutputs[l][0] *= m_filtBal[l] > 0 + ? (100.f - m_filtBal[l]) * 0.01f + : 1.f; + m_filtOutputs[l][1] *= m_filtBal[l] < 0 + ? (100.f + m_filtBal[l]) * 0.01f + : 1.f; } // Wet @@ -4890,6 +4913,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_filtPrevSampOut[l][m][1][1] = m_filtPrevSampOut[l][m][0][1]; } + // Put output into feedback delay buffer m_temp1 = m_filtFeedback[l] * 0.01f; m_filtDelayBuf[l][0][m_filtFeedbackLoc[l]] = m_filtOutputs[l][0] * m_temp1; m_filtDelayBuf[l][1][m_filtFeedbackLoc[l]] = m_filtOutputs[l][1] * m_temp1; @@ -4926,30 +4950,42 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_sample_morerealindex[i][l] = realfmod((m_sample_realindex[i][l] + (m_phase[i] * m_currentSampLen * 0.01f)), m_currentSampLen);// Calculates phase - m_unisonVoicesMinusOne = m_unisonVoices[i] - 1;// m_unisonVoices[i] - 1 is needed many times, which is why m_unisonVoicesMinusOne exists + // m_unisonVoices[i] - 1 is needed many times, which is why m_unisonVoicesMinusOne exists + m_unisonVoicesMinusOne = m_unisonVoices[i] - 1; if (m_tempo[i]) { + // 26400 = 440 Hz * 60 seconds m_temp1 = m_tempo[i] / 26400.f; - // Calculates frequency depending on m_detune and unison detune - m_noteFreq = m_unisonVoicesMinusOne ? detuneWithCents(m_keytracking[i] ? - m_nph->frequency() : 440.f, m_unisonDetuneAmounts[i][l]*m_unisonDetune[i]+m_detune[i]) : - detuneWithCents(m_keytracking[i] ? m_nph->frequency() : 440.f, m_detune[i]); + // Calculates frequency depending on detune and unison detune + m_noteFreq = m_unisonVoicesMinusOne + ? detuneWithCents(m_keytracking[i] + ? m_nph->frequency() + : 440.f, m_unisonDetuneAmounts[i][l]*m_unisonDetune[i]+m_detune[i]) + : detuneWithCents(m_keytracking[i] + ? m_nph->frequency() + : 440.f, m_detune[i]); m_noteFreq *= m_temp1;// Tempo sync } else { - // Calculates frequency depending on m_detune and unison detune - m_noteFreq = m_unisonVoicesMinusOne ? detuneWithCents(m_keytracking[i] ? - m_nph->frequency() : 440.f, m_unisonDetuneAmounts[i][l]*m_unisonDetune[i]+m_detune[i]) : - detuneWithCents(m_keytracking[i] ? m_nph->frequency() : 440.f, m_detune[i]); + // Calculates frequency depending on detune and unison detune + m_noteFreq = m_unisonVoicesMinusOne + ? detuneWithCents(m_keytracking[i] + ? m_nph->frequency() + : 440.f, m_unisonDetuneAmounts[i][l]*m_unisonDetune[i]+m_detune[i]) + : detuneWithCents(m_keytracking[i] + ? m_nph->frequency() + : 440.f, m_detune[i]); } + // Find how far we should move through the waveform m_sample_step[i][l] = m_currentSampLen * (m_noteFreq / sample_rate); - if (m_unisonVoicesMinusOne)// Figures out Morph and Modify values for individual unison voices + // Figures out Morph and Modify values for individual unison voices + if (m_unisonVoicesMinusOne) { if (m_unisonMorph[i]) { @@ -5042,9 +5078,9 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = m_currentSampLen / 2.f; m_sample_morerealindex[i][l] -= m_temp1; m_sample_morerealindex[i][l] /= m_temp1; - m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) ? - pow(m_sample_morerealindex[i][l], 1 / ((m_temp7 * 4) / m_currentSampLen + 1)) : - -pow(-m_sample_morerealindex[i][l], 1 / ((m_temp7 * 4) / m_currentSampLen + 1)); + m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) + ? pow(m_sample_morerealindex[i][l], 1 / ((m_temp7 * 4) / m_currentSampLen + 1)) + : -pow(-m_sample_morerealindex[i][l], 1 / ((m_temp7 * 4) / m_currentSampLen + 1)); m_sample_morerealindex[i][l] *= m_temp1; m_sample_morerealindex[i][l] += m_temp1; break; @@ -5054,9 +5090,9 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = m_currentSampLen / 2.f; m_sample_morerealindex[i][l] -= m_temp1; m_sample_morerealindex[i][l] /= m_temp1; - m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) ? - pow(m_sample_morerealindex[i][l], 1 / (-m_temp7 / m_currentSampLen + 1 )) : - -pow(-m_sample_morerealindex[i][l], 1 / (-m_temp7 / m_currentSampLen + 1)); + m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) + ? pow(m_sample_morerealindex[i][l], 1 / (-m_temp7 / m_currentSampLen + 1 )) + : -pow(-m_sample_morerealindex[i][l], 1 / (-m_temp7 / m_currentSampLen + 1)); m_sample_morerealindex[i][l] *= m_temp1; m_sample_morerealindex[i][l] += m_temp1; break; @@ -5066,9 +5102,9 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = m_currentSampLen / 2.f; m_sample_morerealindex[i][l] -= m_temp1; m_sample_morerealindex[i][l] /= m_temp1; - m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) ? - pow(m_sample_morerealindex[i][l], 1 / (m_temp7 * 4 / m_currentSampLen)) : - -pow(-m_sample_morerealindex[i][l], 1 / (m_temp7 * 4 / m_currentSampLen)); + m_sample_morerealindex[i][l] = (m_sample_morerealindex[i][l] >= 0) + ? pow(m_sample_morerealindex[i][l], 1 / (m_temp7 * 4 / m_currentSampLen)) + : -pow(-m_sample_morerealindex[i][l], 1 / (m_temp7 * 4 / m_currentSampLen)); m_sample_morerealindex[i][l] *= m_temp1; m_sample_morerealindex[i][l] += m_temp1; break; @@ -5105,8 +5141,9 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] } case 22:// Mirror { - m_sample_morerealindex[i][l] = m_sample_morerealindex[i][l] < m_currentSampLen / 2 ? - m_sample_morerealindex[i][l] * 2 : (-m_sample_morerealindex[i][l] + m_currentSampLen) * 2; + m_sample_morerealindex[i][l] = m_sample_morerealindex[i][l] < m_currentSampLen / 2 + ? m_sample_morerealindex[i][l] * 2 + : (-m_sample_morerealindex[i][l] + m_currentSampLen) * 2; m_temp1 = m_temp7 / m_currentSampLen; if (m_temp1 < 0.5) { @@ -5293,7 +5330,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_sample_realindex[i][l] += m_sample_step[i][l]; - // check overflow + // Loop back waveform position when it goes past the end while (m_sample_realindex[i][l] >= m_currentSampLen) { m_sample_realindex[i][l] -= m_currentSampLen; @@ -5321,34 +5358,41 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] for (int l = 0; l < m_subUnisonNum[i]; ++l) { - m_subUnisonVoicesMinusOne = m_subUnisonNum[i] - 1;// m_subUnisonNum[i] - 1 is needed many times, which is why m_subUnisonVoicesMinusOne exists + // m_subUnisonNum[i] - 1 is needed many times, which is why m_subUnisonVoicesMinusOne exists + m_subUnisonVoicesMinusOne = m_subUnisonNum[i] - 1; if (!m_subUnisonVoicesMinusOne) { if (m_subTempo[i]) { + // 26400 = 440 Hz * 60 seconds m_temp1 = m_subTempo[i] / 26400.f; - m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), m_subDetune[i]) * m_temp1 : detuneWithCents(440.f, m_subDetune[i]) * m_temp1; + m_noteFreq = m_subKeytrack[i] + ? detuneWithCents(m_nph->frequency(), m_subDetune[i]) * m_temp1 + : detuneWithCents(440.f, m_subDetune[i]) * m_temp1; } else { - m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), m_subDetune[i]) : detuneWithCents(440.f, m_subDetune[i]); + m_noteFreq = m_subKeytrack[i] + ? detuneWithCents(m_nph->frequency(), m_subDetune[i]) + : detuneWithCents(440.f, m_subDetune[i]); } } else { if (m_subTempo[i]) { + // 26400 = 440 Hz * 60 seconds m_temp1 = m_subTempo[i] / 26400.f; - m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), - m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) * m_temp1 : - detuneWithCents(440.f, m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) * m_temp1; + m_noteFreq = m_subKeytrack[i] + ? detuneWithCents(m_nph->frequency(), m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) * m_temp1 + : detuneWithCents(440.f, m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) * m_temp1; } else { - m_noteFreq = m_subKeytrack[i] ? detuneWithCents(m_nph->frequency(), - m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) : - detuneWithCents(440.f, m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]); + m_noteFreq = m_subKeytrack[i] + ? detuneWithCents(m_nph->frequency(), m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]) + : detuneWithCents(440.f, m_subUnisonDetuneAmounts[i][l]*m_subUnisonDetune[i]+m_subDetune[i]); } } @@ -5364,54 +5408,13 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_sample_subindex[i][l] -= m_temp4; m_lastSubEnvDone[i] = true; } - - /* That is all that is needed for the m_sub oscillator calculations. - - (To the tune of Hallelujah) - - There was a Happy CPU - No processing power to chew through - In this wonderful synthesis brew - Hallelujah - - But with some wavetable synthesis - Your CPU just blows a kiss - And leaves you there despite your miss - Hallelujah - - Hallelujah, Hallelujah, Hallelujah, Halleluuu-uuuuuuuu-uuuujah - - Your music ambition lays there, dead - Can't get your ideas out of your head - Because your computer's slower than lead - Hallelujah - - Sometimes you may try and try - To keep your ping from saying goodbye - Leaving you to die and cry - Hallelujah - - Hallelujah, Hallelujah, Hallelujah, Halleluuu-uuuuuuuu-uuuujah - - But what is this, an alternative? - Sub oscillators supported native - To deter CPU obliteratives - Hallelujah - - Your music has come back to life - CPU problems cut off like a knife - Sub oscillators removing your strife - Hallelujah - - Hallelujah, Hallelujah, Hallelujah, Halleluuu-uuuuuuuu-uuuujah - - *cool outro* - - */ } } else// sub oscillator is noise { + // Choose a random graph sample, move that distance from the previous sample, + // bounce back when upper or lower limits are reached + m_temp2 = m_subVol[i] * 0.01f; for (int l = 0; l < m_subUnisonNum[i]; ++l) { @@ -5443,6 +5446,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] { if (m_sampleLoop[l]) { + // Loop the sample when it moves past the end if (m_sample_sampleindex[l] > sampleSize) { m_sample_sampleindex[l] = m_sample_sampleindex[l] - sampleSize + (m_samples[l][0].size() * m_sampleStart[l]); @@ -5461,6 +5465,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_temp1 = fmod(m_progress, 1); m_progress2 = m_sampGraphs[m_intprogress] * (1 - m_temp1); + // "if" statement prevents wrong value being grabbed when m_intprogress is too high if (m_intprogress < 127) { m_progress3 = m_sampGraphs[m_intprogress+1] * m_temp1; @@ -5515,6 +5520,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] outputSample[0] = 0; outputSample[1] = 0; + // Main Oscillator outputs for (int i = 0; i < m_maxMainEnabled; ++i) { @@ -5666,6 +5672,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] } m_numberToReset = 0; + // Remove DC offset. if (m_removeDC) { m_averageSampleValue[0] = (m_averageSampleValue[0] * 0.999f) + (outputSample[0] * 0.001f); @@ -5680,14 +5687,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] // Takes input of original Hz and the number of cents to m_detune it by, and returns the detuned result in Hz. inline float mSynth::detuneWithCents(float pitchValue, float m_detuneValue) { - if (m_detuneValue)// Avoids expensive exponentiation if no detuning is necessary - { - return pitchValue * std::exp2(m_detuneValue / 1200.f); - } - else - { - return pitchValue; - } + return pitchValue * std::exp2(m_detuneValue / 1200.f); } @@ -5794,13 +5794,6 @@ inline float mSynth::realfmod(float k, float n) - - - - - - - QString MicrowaveManualView::s_manualText= "HOW TO OPERATE YOUR MICROWAVE
" "
" @@ -5988,12 +5981,13 @@ MicrowaveManualView::MicrowaveManualView():QTextEdit(s_manualText) void MicrowaveView::manualBtnClicked() { + // Closes and reopens view to make sure it is on top. MicrowaveManualView::getInstance()->hide(); MicrowaveManualView::getInstance()->show(); } - +// Store corresponding Matrix values, to allow sending a knob to the Matrix through the right click menu void MicrowaveKnob::setMatrixLocation(int loc1, int loc2, int loc3) { m_matrixLocation[0] = loc1; @@ -6027,7 +6021,7 @@ void MicrowaveKnob::setWhichMacroKnob(int which) } - +// Override knob behavior to add in new right click menu options void MicrowaveKnob::contextMenuEvent(QContextMenuEvent *) { // for the case, the user clicked right while pressing left mouse- @@ -6055,6 +6049,7 @@ void MicrowaveKnob::contextMenuEvent(QContextMenuEvent *) } +// Apply special behavior to middle mouse button and alt key void MicrowaveKnob::mousePressEvent(QMouseEvent * me) { if ((me->button() == Qt::LeftButton && gui->mainWindow()->isAltPressed()) || me->button() == Qt::MidButton) diff --git a/plugins/Microwave/Microwave.h b/plugins/Microwave/Microwave.h index e5584407e75..e8c6ebf76fb 100644 --- a/plugins/Microwave/Microwave.h +++ b/plugins/Microwave/Microwave.h @@ -272,10 +272,8 @@ const int STOREDSUBWAVELEN = 2048; const int STOREDMAINWAVELEN = 2048; -// WAVERATIO is how much larger (multiplication) the waveforms are after interpolation. -// I'd like to increase this, but I will not until project saving/loading is sped up in LMMS, since this increases that drastically. -// I would prefer it to be 8, maybe even 16. // This number divided by 4 is the number of megabytes of RAM each wavetable will use up (I think?). +// I'd like to increase this in the future, but the higher this number is, the more time it takes to load Microwave. const int WAVERATIO = 4; const int SUBWAVELEN = STOREDSUBWAVELEN * WAVERATIO; @@ -493,7 +491,6 @@ protected slots: float m_storedwaveforms[8][STOREDMAINARRAYLEN] = {{0}}; float m_waveforms[8][MAINARRAYLEN] = {{0}}; bool m_mainFilled[8] = {false}; - int m_currentTab = 0; float m_storedsubs[64][STOREDSUBWAVELEN] = {{0}}; float m_subs[64][SUBWAVELEN] = {{0}}; bool m_subFilled[64] = {false}; @@ -681,8 +678,6 @@ protected slots: void modEnabledChanged(); private: - virtual void modelChanged(); - void wheelEvent(QWheelEvent * me); virtual void dropEvent(QDropEvent * de); virtual void dragEnterEvent(QDragEnterEvent * dee); From 2bb614c43d848dcd5c55650daff1c6dc377751e3 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 19 Jul 2019 12:53:04 -0600 Subject: [PATCH 09/12] Fix Matrix display bug --- plugins/Microwave/Microwave.cpp | 30 +++++++++++++++--------------- plugins/Microwave/Microwave.h | 6 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index b610bf5d206..15803ce29f6 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -93,7 +93,7 @@ Microwave::Microwave(InstrumentTrack * instrument_track) : Instrument(instrument_track, µwave_plugin_descriptor), m_visvol(100, 0, 1000, 0.01f, this, tr("Visualizer Volume")), m_loadChnl(0, 0, 1, 1, this, tr("Wavetable Loading Channel")), - m_mainNum(1, 1, 8, this, tr("Main Oscillator Number")), + m_mainNum(1, 1, 8, this, tr("Wavetable Oscillator Number")), m_subNum(1, 1, 64, this, tr("Sub Oscillator Number")), m_sampNum(1, 1, 8, this, tr("Sample Number")), m_oversample(this, tr("Oversampling")), @@ -1038,7 +1038,7 @@ void Microwave::subSampLenChanged(int num) } -//Stores the highest enabled main oscillator. Helps with CPU benefit, refer to its use in mSynth::nextStringSample +//Stores the highest enabled wavetable oscillator. Helps with CPU benefit, refer to its use in mSynth::nextStringSample void Microwave::mainEnabledChanged(int num) { for (int i = 0; i < 8; ++i) @@ -2165,11 +2165,6 @@ void MicrowaveView::updateScroll() m_modInCurveKnob2[i]->setMatrixLocation(4, 4, i); } - // Bug evasion. Without this, some display glitches happen in certain conditions. - modOutSecChanged(i+matrixDivide); - modInChanged(i+matrixDivide); - modIn2Changed(i+matrixDivide); - visimove(m_modInBox[i], 45, i*115+57 - matrixRemainder, inMatrixTab); visimove(m_modInNumBox[i], 90, i*115+57 - matrixRemainder, inMatrixTab); visimove(m_modInAmntKnob[i], 136, i*115+53 - matrixRemainder, inMatrixTab); @@ -2190,6 +2185,11 @@ void MicrowaveView::updateScroll() visimove(m_i1Button[i], 25, i*115+50 - matrixRemainder, inMatrixTab); visimove(m_i2Button[i], 25, i*115+112 - matrixRemainder, inMatrixTab); visimove(m_modNumText[i], 192, i*115+89 - matrixRemainder, inMatrixTab); + + // Bug evasion. Without this, some display glitches happen in certain conditions. + modOutSecChanged(i+matrixDivide); + modInChanged(i+matrixDivide); + modIn2Changed(i+matrixDivide); } for (int i = 0; i < 8; ++i) @@ -2526,7 +2526,7 @@ void MicrowaveView::modOutSecChanged(int i) m_modOutSecNumBox[i-matrixDivide]->hide(); break; } - case 1:// Main OSC + case 1:// Wavetable OSC { m_modOutSigBox[i-matrixDivide]->show(); m_modOutSecNumBox[i-matrixDivide]->show(); @@ -2605,7 +2605,7 @@ void MicrowaveView::modInChanged(int i) m_modInNumBox[i-matrixDivide]->hide(); break; } - case 1:// Main OSC + case 1:// Wavetable OSC { m_modInNumBox[i-matrixDivide]->show(); m_b->m_modInNum[i]->setRange(1, 8, 1); @@ -2671,7 +2671,7 @@ void MicrowaveView::modIn2Changed(int i) m_modInNumBox2[i-matrixDivide]->hide(); break; } - case 1:// Main OSC + case 1:// Wavetable OSC { m_modInNumBox2[i-matrixDivide]->show(); m_b->m_modInNum2[i]->setRange(1, 8, 1); @@ -4136,7 +4136,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] { break; } - case 1:// Main Oscillator + case 1:// Wavetable Oscillator { switch (m_modOutSig[l]) { @@ -4936,9 +4936,9 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] } } - //=====================// - //== MAIN OSCILLATOR ==// - //=====================// + //==========================// + //== WAVETABLE OSCILLATOR ==// + //==========================// for (int i = 0; i < m_maxMainEnabled; ++i)// m_maxMainEnabled keeps this from looping 8 times every m_sample, saving some CPU { @@ -5521,7 +5521,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] outputSample[0] = 0; outputSample[1] = 0; - // Main Oscillator outputs + // Wavetable Oscillator outputs for (int i = 0; i < m_maxMainEnabled; ++i) { if (m_enabled[i]) diff --git a/plugins/Microwave/Microwave.h b/plugins/Microwave/Microwave.h index e8c6ebf76fb..05ceb521a19 100644 --- a/plugins/Microwave/Microwave.h +++ b/plugins/Microwave/Microwave.h @@ -79,7 +79,7 @@ #define modinmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Main OSC"), make_unique("sqr"));\ + name->addItem(tr("Wavetable OSC"), make_unique("sqr"));\ name->addItem(tr("Sub OSC"), make_unique("sin"));\ name->addItem(tr("Sample OSC"), make_unique("noise"));\ name->addItem(tr("Filter Output"), make_unique("moog"));\ @@ -91,7 +91,7 @@ #define modsectionsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Main OSC"), make_unique("sqr"));\ + name->addItem(tr("Wavetable OSC"), make_unique("sqr"));\ name->addItem(tr("Sub OSC"), make_unique("sin"));\ name->addItem(tr("Sample OSC"), make_unique("noise"));\ name->addItem(tr("Matrix"), make_unique("ramp"));\ @@ -590,7 +590,7 @@ protected slots: float m_macroArr[18] = {0}; //Above is for passing to mSynth initialization - int m_maxMainEnabled = 0;// The highest number of main oscillator sections that must be looped through + int m_maxMainEnabled = 0;// The highest number of wavetable oscillator sections that must be looped through int m_maxModEnabled = 0;// The highest number of matrix sections that must be looped through int m_maxSubEnabled = 0;// The highest number of sub oscillator sections that must be looped through int m_maxSampleEnabled = 0;// The highest number of sample sections that must be looped through From 3c711cdb1d98eb8a96b239168d8a4c73a66b37fe Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Fri, 19 Jul 2019 17:30:00 -0600 Subject: [PATCH 10/12] Fix new Matrix display bugs --- plugins/Microwave/Microwave.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 15803ce29f6..32f322069da 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -2165,17 +2165,22 @@ void MicrowaveView::updateScroll() m_modInCurveKnob2[i]->setMatrixLocation(4, 4, i); } + // Bug evasion. Without this, some display glitches happen in certain conditions. + modOutSecChanged(i+matrixDivide); + modInChanged(i+matrixDivide); + modIn2Changed(i+matrixDivide); + visimove(m_modInBox[i], 45, i*115+57 - matrixRemainder, inMatrixTab); - visimove(m_modInNumBox[i], 90, i*115+57 - matrixRemainder, inMatrixTab); + visimove(m_modInNumBox[i], 90, i*115+57 - matrixRemainder, inMatrixTab && m_modInNumBox[i]->isVisible()); visimove(m_modInAmntKnob[i], 136, i*115+53 - matrixRemainder, inMatrixTab); visimove(m_modInCurveKnob[i], 161, i*115+53 - matrixRemainder, inMatrixTab); visimove(m_modInBox2[i], 45, i*115+118 - matrixRemainder, inMatrixTab); - visimove(m_modInNumBox2[i], 90, i*115+118 - matrixRemainder, inMatrixTab); + visimove(m_modInNumBox2[i], 90, i*115+118 - matrixRemainder, inMatrixTab && m_modInNumBox2[i]->isVisible()); visimove(m_modInAmntKnob2[i], 136, i*115+114 - matrixRemainder, inMatrixTab); visimove(m_modInCurveKnob2[i], 161, i*115+114 - matrixRemainder, inMatrixTab); visimove(m_modOutSecBox[i], 27, i*115+88 - matrixRemainder, inMatrixTab); - visimove(m_modOutSigBox[i], 69, i*115+88 - matrixRemainder, inMatrixTab); - visimove(m_modOutSecNumBox[i], 112, i*115+88 - matrixRemainder, inMatrixTab); + visimove(m_modOutSigBox[i], 69, i*115+88 - matrixRemainder, inMatrixTab && m_modOutSigBox[i]->isVisible()); + visimove(m_modOutSecNumBox[i], 112, i*115+88 - matrixRemainder, inMatrixTab && m_modOutSecNumBox[i]->isVisible()); visimove(m_modEnabledToggle[i], 27, i*115+36 - matrixRemainder, inMatrixTab); visimove(m_modCombineTypeBox[i], 149, i*115+88 - matrixRemainder, inMatrixTab); visimove(m_modTypeToggle[i], 195, i*115+67 - matrixRemainder, inMatrixTab); @@ -2185,11 +2190,6 @@ void MicrowaveView::updateScroll() visimove(m_i1Button[i], 25, i*115+50 - matrixRemainder, inMatrixTab); visimove(m_i2Button[i], 25, i*115+112 - matrixRemainder, inMatrixTab); visimove(m_modNumText[i], 192, i*115+89 - matrixRemainder, inMatrixTab); - - // Bug evasion. Without this, some display glitches happen in certain conditions. - modOutSecChanged(i+matrixDivide); - modInChanged(i+matrixDivide); - modIn2Changed(i+matrixDivide); } for (int i = 0; i < 8; ++i) From 708764b03ba2bf4a4f3800b76d3c542d3133d570 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 27 Jul 2019 17:26:36 -0600 Subject: [PATCH 11/12] Add Microwave icons, fix filter saturation slope bug, and a bit more --- plugins/Microwave/Microwave.cpp | 88 +++++++---- plugins/Microwave/Microwave.h | 165 +++++++++++---------- plugins/Microwave/asym_l.png | Bin 0 -> 552 bytes plugins/Microwave/asym_r.png | Bin 0 -> 563 bytes plugins/Microwave/bidirectional_add.png | Bin 0 -> 580 bytes plugins/Microwave/bidirectional_multi.png | Bin 0 -> 602 bytes plugins/Microwave/clip.png | Bin 0 -> 445 bytes plugins/Microwave/clip_inverse.png | Bin 0 -> 485 bytes plugins/Microwave/curve.png | Bin 0 -> 464 bytes plugins/Microwave/cut_off_l.png | Bin 0 -> 472 bytes plugins/Microwave/cut_off_r.png | Bin 0 -> 460 bytes plugins/Microwave/detune.png | Bin 0 -> 562 bytes plugins/Microwave/diagonal.png | Bin 0 -> 640 bytes plugins/Microwave/diagonal_morph.png | Bin 0 -> 638 bytes plugins/Microwave/filter_parameters.png | Bin 0 -> 536 bytes plugins/Microwave/flip.png | Bin 0 -> 543 bytes plugins/Microwave/letter_l.png | Bin 194 -> 201 bytes plugins/Microwave/letter_p.png | Bin 349 -> 372 bytes plugins/Microwave/letter_r.png | Bin 460 -> 465 bytes plugins/Microwave/letter_s.png | Bin 514 -> 554 bytes plugins/Microwave/macro.png | Bin 0 -> 406 bytes plugins/Microwave/matrix.png | Bin 0 -> 461 bytes plugins/Microwave/mirror.png | Bin 0 -> 593 bytes plugins/Microwave/morph.png | Bin 0 -> 749 bytes plugins/Microwave/panning.png | Bin 0 -> 500 bytes plugins/Microwave/phase.png | Bin 0 -> 519 bytes plugins/Microwave/pulse.png | Bin 0 -> 291 bytes plugins/Microwave/pulse_width.png | Bin 0 -> 512 bytes plugins/Microwave/range.png | Bin 0 -> 796 bytes plugins/Microwave/sample.png | Bin 0 -> 274 bytes plugins/Microwave/sideways_morph.png | Bin 0 -> 662 bytes plugins/Microwave/sine.png | Bin 0 -> 536 bytes plugins/Microwave/squish_to_center.png | Bin 0 -> 476 bytes plugins/Microwave/stretch_from_center.png | Bin 0 -> 500 bytes plugins/Microwave/sync.png | Bin 0 -> 728 bytes plugins/Microwave/sync_half_inter.png | Bin 0 -> 688 bytes plugins/Microwave/sync_inter.png | Bin 0 -> 629 bytes plugins/Microwave/unidirectional_add.png | Bin 0 -> 372 bytes plugins/Microwave/unidirectional_multi.png | Bin 0 -> 401 bytes plugins/Microwave/unison_detune.png | Bin 0 -> 10006 bytes plugins/Microwave/unison_modify.png | Bin 0 -> 9291 bytes plugins/Microwave/unison_morph.png | Bin 0 -> 775 bytes plugins/Microwave/unison_number.png | Bin 0 -> 393 bytes plugins/Microwave/volume.png | Bin 0 -> 389 bytes plugins/Microwave/volume_input.png | Bin 0 -> 463 bytes plugins/Microwave/volume_output.png | Bin 0 -> 614 bytes plugins/Microwave/wavetable.png | Bin 0 -> 276 bytes plugins/Microwave/weird1.png | Bin 0 -> 729 bytes plugins/Microwave/weird2.png | Bin 0 -> 625 bytes plugins/Microwave/wetdry.png | Bin 0 -> 625 bytes 50 files changed, 139 insertions(+), 114 deletions(-) create mode 100644 plugins/Microwave/asym_l.png create mode 100644 plugins/Microwave/asym_r.png create mode 100644 plugins/Microwave/bidirectional_add.png create mode 100644 plugins/Microwave/bidirectional_multi.png create mode 100644 plugins/Microwave/clip.png create mode 100644 plugins/Microwave/clip_inverse.png create mode 100644 plugins/Microwave/curve.png create mode 100644 plugins/Microwave/cut_off_l.png create mode 100644 plugins/Microwave/cut_off_r.png create mode 100644 plugins/Microwave/detune.png create mode 100644 plugins/Microwave/diagonal.png create mode 100644 plugins/Microwave/diagonal_morph.png create mode 100644 plugins/Microwave/filter_parameters.png create mode 100644 plugins/Microwave/flip.png create mode 100644 plugins/Microwave/macro.png create mode 100644 plugins/Microwave/matrix.png create mode 100644 plugins/Microwave/mirror.png create mode 100644 plugins/Microwave/morph.png create mode 100644 plugins/Microwave/panning.png create mode 100644 plugins/Microwave/phase.png create mode 100644 plugins/Microwave/pulse.png create mode 100644 plugins/Microwave/pulse_width.png create mode 100644 plugins/Microwave/range.png create mode 100644 plugins/Microwave/sample.png create mode 100644 plugins/Microwave/sideways_morph.png create mode 100644 plugins/Microwave/sine.png create mode 100644 plugins/Microwave/squish_to_center.png create mode 100644 plugins/Microwave/stretch_from_center.png create mode 100644 plugins/Microwave/sync.png create mode 100644 plugins/Microwave/sync_half_inter.png create mode 100644 plugins/Microwave/sync_inter.png create mode 100644 plugins/Microwave/unidirectional_add.png create mode 100644 plugins/Microwave/unidirectional_multi.png create mode 100644 plugins/Microwave/unison_detune.png create mode 100644 plugins/Microwave/unison_modify.png create mode 100644 plugins/Microwave/unison_morph.png create mode 100644 plugins/Microwave/unison_number.png create mode 100644 plugins/Microwave/volume.png create mode 100644 plugins/Microwave/volume_input.png create mode 100644 plugins/Microwave/volume_output.png create mode 100644 plugins/Microwave/wavetable.png create mode 100644 plugins/Microwave/weird1.png create mode 100644 plugins/Microwave/weird2.png create mode 100644 plugins/Microwave/wetdry.png diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 15803ce29f6..579756dffe7 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -104,6 +104,9 @@ Microwave::Microwave(InstrumentTrack * instrument_track) : { for (int i = 0; i < 8; ++i) { + m_storedwaveforms[i].reserve(STOREDMAINARRAYLEN); + m_waveforms[i].reserve(MAINARRAYLEN); + m_morph[i] = new FloatModel(0, 0, 254, 0.0001f, this, tr("Morph")); m_range[i] = new FloatModel(1, 1, 16, 0.0001f, this, tr("Range")); m_sampLen[i] = new FloatModel(2048, 1, 16384, 1.f, this, tr("Waveform Sample Length")); @@ -173,6 +176,9 @@ Microwave::Microwave(InstrumentTrack * instrument_track) : for (int i = 0; i < 64; ++i) { + m_storedsubs[i].reserve(STOREDSUBWAVELEN); + m_subs[i].reserve(SUBWAVELEN); + m_subEnabled[i] = new BoolModel(false, this); m_subVol[i] = new FloatModel(100.f, 0.f, 200.f, 0.0001f, this, tr("Volume")); m_subPhase[i] = new FloatModel(0.f, 0.f, 200.f, 0.0001f, this, tr("Phase")); @@ -437,7 +443,7 @@ void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) if (m_updateWavetable[i]) { m_updateWavetable[i] = false; - base64::encode((const char *)m_storedwaveforms[i], + base64::encode((const char *)m_storedwaveforms[i].data(), STOREDMAINARRAYLEN * sizeof(float), m_wavetableSaveStrings[i]); } thissave.setAttribute("waveforms"+QString::number(i), m_wavetableSaveStrings[i]); @@ -449,7 +455,7 @@ void Microwave::saveSettings(QDomDocument & doc, QDomElement & thissave) { if (m_subEnabled[i]->value()) { - base64::encode((const char *)m_storedsubs[i], + base64::encode((const char *)m_storedsubs[i].data(), STOREDSUBWAVELEN * sizeof(float), saveString); thissave.setAttribute("subs"+QString::number(i), saveString); } @@ -1342,7 +1348,7 @@ inline void Microwave::fillSubOsc(int which, bool doInterpolate) { if (doInterpolate) { - srccpy(m_subs[which], const_cast(m_storedsubs[which]), STOREDSUBWAVELEN); + srccpy(m_subs[which].data(), m_storedsubs[which].data(), STOREDSUBWAVELEN); } else { @@ -1364,7 +1370,7 @@ inline void Microwave::fillMainOsc(int which, bool doInterpolate) { if (doInterpolate) { - srccpy(m_waveforms[which], const_cast(m_storedwaveforms[which]), STOREDMAINARRAYLEN); + srccpy(m_waveforms[which].data(), m_storedwaveforms[which].data(), STOREDMAINARRAYLEN); } else { @@ -2165,17 +2171,22 @@ void MicrowaveView::updateScroll() m_modInCurveKnob2[i]->setMatrixLocation(4, 4, i); } + // Bug evasion. Without this, some display glitches happen in certain conditions. + modOutSecChanged(i+matrixDivide); + modInChanged(i+matrixDivide); + modIn2Changed(i+matrixDivide); + visimove(m_modInBox[i], 45, i*115+57 - matrixRemainder, inMatrixTab); - visimove(m_modInNumBox[i], 90, i*115+57 - matrixRemainder, inMatrixTab); + visimove(m_modInNumBox[i], 90, i*115+57 - matrixRemainder, inMatrixTab && m_modInNumBox[i]->isVisible()); visimove(m_modInAmntKnob[i], 136, i*115+53 - matrixRemainder, inMatrixTab); visimove(m_modInCurveKnob[i], 161, i*115+53 - matrixRemainder, inMatrixTab); visimove(m_modInBox2[i], 45, i*115+118 - matrixRemainder, inMatrixTab); - visimove(m_modInNumBox2[i], 90, i*115+118 - matrixRemainder, inMatrixTab); + visimove(m_modInNumBox2[i], 90, i*115+118 - matrixRemainder, inMatrixTab && m_modInNumBox2[i]->isVisible()); visimove(m_modInAmntKnob2[i], 136, i*115+114 - matrixRemainder, inMatrixTab); visimove(m_modInCurveKnob2[i], 161, i*115+114 - matrixRemainder, inMatrixTab); visimove(m_modOutSecBox[i], 27, i*115+88 - matrixRemainder, inMatrixTab); - visimove(m_modOutSigBox[i], 69, i*115+88 - matrixRemainder, inMatrixTab); - visimove(m_modOutSecNumBox[i], 112, i*115+88 - matrixRemainder, inMatrixTab); + visimove(m_modOutSigBox[i], 69, i*115+88 - matrixRemainder, inMatrixTab && m_modOutSigBox[i]->isVisible()); + visimove(m_modOutSecNumBox[i], 112, i*115+88 - matrixRemainder, inMatrixTab && m_modOutSecNumBox[i]->isVisible()); visimove(m_modEnabledToggle[i], 27, i*115+36 - matrixRemainder, inMatrixTab); visimove(m_modCombineTypeBox[i], 149, i*115+88 - matrixRemainder, inMatrixTab); visimove(m_modTypeToggle[i], 195, i*115+67 - matrixRemainder, inMatrixTab); @@ -2185,11 +2196,6 @@ void MicrowaveView::updateScroll() visimove(m_i1Button[i], 25, i*115+50 - matrixRemainder, inMatrixTab); visimove(m_i2Button[i], 25, i*115+112 - matrixRemainder, inMatrixTab); visimove(m_modNumText[i], 192, i*115+89 - matrixRemainder, inMatrixTab); - - // Bug evasion. Without this, some display glitches happen in certain conditions. - modOutSecChanged(i+matrixDivide); - modInChanged(i+matrixDivide); - modIn2Changed(i+matrixDivide); } for (int i = 0; i < 8; ++i) @@ -2318,12 +2324,13 @@ void MicrowaveView::updateScroll() visimove(m_confirmLoadButton, 93, 187, inWavetableLoadingTab); visimove(m_XBtn, 231, 11, inWavetableLoadingTab); - visimove(m_MatrixXBtn, 229, 8, inMatrixTab); visimove(m_normalizeBtn, 155, 224, inWavetableLoadingTab); visimove(m_desawBtn, 39, 224, inWavetableLoadingTab); tabChanged(m_b->m_scroll); + + visimove(m_MatrixXBtn, 229, 8, inMatrixTab && m_MatrixXBtn->isVisible()); } @@ -2346,6 +2353,8 @@ void MicrowaveView::wheelEvent(QWheelEvent * me) } } } + + me->accept(); } @@ -2424,7 +2433,7 @@ void MicrowaveView::mainNumChanged() void MicrowaveView::subNumChanged() { m_b->m_graph.setLength(m_b->m_subSampLen[m_b->m_subNum.value()-1]->value()); - m_b->m_graph.setSamples(m_b->m_storedsubs[m_b->m_subNum.value()-1]); + m_b->m_graph.setSamples(m_b->m_storedsubs[m_b->m_subNum.value()-1].data()); setGraphEnabledColor(m_b->m_subEnabled[m_b->m_subNum.value()-1]->value()); int subNumValue = m_b->m_subNum.value() - 1; @@ -3777,10 +3786,10 @@ mSynth::~mSynth() // This is the part that puts everything together and calculates an audio output. -void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8][MAINARRAYLEN], float (&m_subs)[64][SUBWAVELEN], +void mSynth::nextStringSample(sampleFrame &outputSample, std::vector (&m_waveforms)[8], std::vector (&m_subs)[64], std::vector (&m_samples)[8][2], float * m_sampGraphs, int m_maxMainEnabled, int m_maxSubEnabled, int m_maxSampleEnabled, int m_maxFiltEnabled, int m_maxModEnabled, int sample_rate, Microwave * m_mwc, - bool m_removeDC, float (&m_storedsubs)[64][STOREDSUBWAVELEN]) + bool m_removeDC, std::vector (&m_storedsubs)[64]) { ++m_noteDuration; @@ -3793,6 +3802,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] { if (m_modEnabled[l]) { + // Find where the inputs are coming from switch (m_modIn[l]) { case 0: @@ -4015,15 +4025,18 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] } } - if (m_curModVal[0] ) { m_curModVal[0] *= m_modInAmnt[l] * 0.01f; } - if (m_curModVal[1] ) { m_curModVal[1] *= m_modInAmnt[l] * 0.01f; } + // Apply Amount knob. + m_curModVal[0] *= m_modInAmnt[l] * 0.01f; + m_curModVal[1] *= m_modInAmnt[l] * 0.01f; + // Since it's uncommon to use both inputs, the "if" statement helps performance. if (m_curModVal2[0]) { m_curModVal2[0] *= m_modInAmnt2[l] * 0.01f; } if (m_curModVal2[1]) { m_curModVal2[1] *= m_modInAmnt2[l] * 0.01f; } - // Calculate curve + // Calculate curve and direction if (m_modCombineType[l] <= 1)// Bidirectional { - if (m_modInCurve[l] != 100.f)// The "if" statement is there so unnecessary CPU isn't spent (pow is very expensive) if the curve knob isn't being used. + // The "if" statement is there so unnecessary CPU isn't spent (pow is very expensive) if the curve knob isn't being used. + if (m_modInCurve[l] != 100.f) { // Move to a scale of 0 to 1 (from -1 to 1) and then apply the curve. m_temp1 = 1.f / (m_modInCurve[l] * 0.01f); @@ -4130,6 +4143,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_comboModValMono = (m_comboModVal[0] + m_comboModVal[1]) * 0.5f; + // Send the calcluated value to the output. Keep track of the changed values so they can be reset later on. switch (m_modOutSec[l]) { case 0: @@ -4603,6 +4617,7 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_filtInputs[l][0] *= m_temp1; m_filtInputs[l][1] *= m_temp1; + // Calculate the required size of the delay buffer if (m_filtKeytracking[l]) { m_temp1 = round(sample_rate / detuneWithCents(m_nph->frequency(), m_filtDetune[l])); @@ -4625,7 +4640,6 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] { m_filtFeedbackLoc[l] = 0; } - m_filtInputs[l][0] += m_filtDelayBuf[l][0].at(m_filtFeedbackLoc[l]); m_filtInputs[l][1] += m_filtDelayBuf[l][1].at(m_filtFeedbackLoc[l]); @@ -4848,14 +4862,6 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_filtOutputs[l][1] = m_filty4[1]; } - // Calculates Saturation. The algorithm is just y = x ^ (1 - saturation); - if (m_filtSatu[l]) - { - m_temp1 = 1 - (m_filtSatu[l] * 0.01f); - m_filtOutputs[l][0] = pow(abs(m_filtOutputs[l][0]), m_temp1) * (m_filtOutputs[l][0] < 0 ? -1 : 1); - m_filtOutputs[l][1] = pow(abs(m_filtOutputs[l][1]), m_temp1) * (m_filtOutputs[l][1] < 0 ? -1 : 1); - } - // Balance knob wet if (m_filtBal[l]) { @@ -4918,6 +4924,14 @@ void mSynth::nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8] m_filtDelayBuf[l][0][m_filtFeedbackLoc[l]] = m_filtOutputs[l][0] * m_temp1; m_filtDelayBuf[l][1][m_filtFeedbackLoc[l]] = m_filtOutputs[l][1] * m_temp1; + // Calculates Saturation. The algorithm is just y = x ^ (1 - saturation); + if (m_filtSatu[l]) + { + m_temp1 = 1 - (m_filtSatu[l] * 0.01f); + m_filtOutputs[l][0] = pow(abs(m_filtOutputs[l][0]), m_temp1) * (m_filtOutputs[l][0] < 0 ? -1 : 1); + m_filtOutputs[l][1] = pow(abs(m_filtOutputs[l][1]), m_temp1) * (m_filtOutputs[l][1] < 0 ? -1 : 1); + } + m_temp1 = m_filtOutVol[l] * 0.01f; m_filtOutputs[l][0] *= m_temp1; m_filtOutputs[l][1] *= m_temp1; @@ -5952,7 +5966,7 @@ QString MicrowaveManualView::s_manualText= "==FAQ==
" "
" "
" -"-=WHY WON'T MY MICROWAVE MAKE SOUND?!=-
" +"-=Why won't my Microwave make sound?=-
" "
" "1. Wavetable tab: You need to enable the \"Enabled\" LED (has a power icon next to it), then click the folder button to load a wavetable. After the wavetable is loaded correctly, move the Morph knob and you should hear sound.
" "
" @@ -5961,10 +5975,20 @@ QString MicrowaveManualView::s_manualText= "3. Sample tab: You need to enable the \"Enabled\" LED (has a power icon next to it), then click the folder button to load a sample.
" "
" "
" -"-=WHY WON'T MY FILTERS WORK?!=-
" +"-=Why won't my filters work?=-
" "
" "Make sure the filter is enabled. Take the oscillator you want to send through your filter, enable its Muted LED, use it as an input in the Matrix, set the output as \"Filter Input\", and set the Matrix Amount knob to 100%. This will prevent the original oscillator audio from being sent directly to the audio output, and send the oscillator audio to the filter.
" "
" +"
" +"-=Why do my filters sound incorrect and/or ugly?=-
" +"
" +"When using oversampling, the filter output must be interpolated to sound correct, especially with filters that leave high frequencies in the sound. You can do this by changing the Oversampling Mode in the Miscellaneous tab to \"Average\".
" +"
" +"
" +"-=Why is there sometimes ugly buzzing in my sound?=-
" +"
" +"Oversampling is essential for a high-quality sound. Try turning up the Oversampling, and changing the Oversampling Mode to \"Average\".
" +"
" ; diff --git a/plugins/Microwave/Microwave.h b/plugins/Microwave/Microwave.h index 05ceb521a19..812dfe3325a 100644 --- a/plugins/Microwave/Microwave.h +++ b/plugins/Microwave/Microwave.h @@ -51,96 +51,96 @@ #define setwavemodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Pulse Width"), make_unique("sin"));\ - name->addItem(tr("Weird 1"), make_unique("noise"));\ - name->addItem(tr("Weird 2"), make_unique("noise"));\ - name->addItem(tr("Asym To Right"), make_unique("saw"));\ - name->addItem(tr("Asym To Left"), make_unique("ramp"));\ - name->addItem(tr("Bidirectional Asym"), make_unique("tri"));\ - name->addItem(tr("Squish To Center"), make_unique("exp"));\ - name->addItem(tr("Stretch From Center"), make_unique("sinabs"));\ - name->addItem(tr("Stretch And Squish"), make_unique("tri"));\ - name->addItem(tr("Cut Off Right"), make_unique("saw"));\ - name->addItem(tr("Cut Off Left"), make_unique("ramp"));\ + name->addItem(tr("Pulse Width"), make_unique("pulse_width"));\ + name->addItem(tr("Weird 1"), make_unique("weird1"));\ + name->addItem(tr("Weird 2"), make_unique("weird2"));\ + name->addItem(tr("Asym To Right"), make_unique("asym_r"));\ + name->addItem(tr("Asym To Left"), make_unique("asym_l"));\ + name->addItem(tr("Bidirectional Asym"), make_unique("asym_r"));\ + name->addItem(tr("Squish To Center"), make_unique("squish_to_center"));\ + name->addItem(tr("Stretch From Center"), make_unique("stretch_from_center"));\ + name->addItem(tr("Stretch And Squish"), make_unique("squish_to_center"));\ + name->addItem(tr("Cut Off Right"), make_unique("cut_off_r"));\ + name->addItem(tr("Cut Off Left"), make_unique("cut_off_l"));\ name->addItem(tr("Squarify"), make_unique("sqr"));\ - name->addItem(tr("Pulsify"), make_unique("sqr"));\ - name->addItem(tr("Flip"), make_unique("tri"));\ - name->addItem(tr("Clip"), make_unique("sqr"));\ - name->addItem(tr("Inverse Clip"), make_unique("sqr"));\ + name->addItem(tr("Pulsify"), make_unique("pulse"));\ + name->addItem(tr("Flip"), make_unique("flip"));\ + name->addItem(tr("Clip"), make_unique("clip"));\ + name->addItem(tr("Inverse Clip"), make_unique("clip_inverse"));\ name->addItem(tr("Sine"), make_unique("sin"));\ - name->addItem(tr("Atan"), make_unique("tri"));\ - name->addItem(tr("Sync"), make_unique("saw"));\ - name->addItem(tr("Sync Half Interpolate"), make_unique("saw"));\ - name->addItem(tr("Sync Interpolate"), make_unique("saw"));\ - name->addItem(tr("Mirror"), make_unique("sinabs"));\ - name->addItem(tr("Diagonal Morph"), make_unique("saw"));\ - name->addItem(tr("Sideways Morph"), make_unique("saw")); + name->addItem(tr("Atan"), make_unique("sqrsoft"));\ + name->addItem(tr("Sync"), make_unique("sync"));\ + name->addItem(tr("Sync Half Interpolate"), make_unique("sync_half_inter"));\ + name->addItem(tr("Sync Interpolate"), make_unique("sync_inter"));\ + name->addItem(tr("Mirror"), make_unique("mirror"));\ + name->addItem(tr("Diagonal Morph"), make_unique("diagonal_morph"));\ + name->addItem(tr("Sideways Morph"), make_unique("sideways_morph")); #define modinmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Wavetable OSC"), make_unique("sqr"));\ + name->addItem(tr("Wavetable OSC"), make_unique("wavetable"));\ name->addItem(tr("Sub OSC"), make_unique("sin"));\ - name->addItem(tr("Sample OSC"), make_unique("noise"));\ - name->addItem(tr("Filter Output"), make_unique("moog"));\ - name->addItem(tr("Velocity"), make_unique("letter_v"));\ - name->addItem(tr("Panning"), make_unique("letter_p"));\ + name->addItem(tr("Sample OSC"), make_unique("sample"));\ + name->addItem(tr("Filter Output"), make_unique("filter_lowpass"));\ + name->addItem(tr("Velocity"), make_unique("volume"));\ + name->addItem(tr("Panning"), make_unique("panning"));\ name->addItem(tr("Humanizer"), make_unique("letter_h"));\ - name->addItem(tr("Macro"), make_unique("letter_m")); + name->addItem(tr("Macro"), make_unique("macro")); #define modsectionsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Wavetable OSC"), make_unique("sqr"));\ + name->addItem(tr("Wavetable OSC"), make_unique("wavetable"));\ name->addItem(tr("Sub OSC"), make_unique("sin"));\ - name->addItem(tr("Sample OSC"), make_unique("noise"));\ - name->addItem(tr("Matrix"), make_unique("ramp"));\ - name->addItem(tr("Filter Input"), make_unique("moog"));\ - name->addItem(tr("Filter Parameters"), make_unique("letter_f"));\ - name->addItem(tr("Macro"), make_unique("letter_m")); + name->addItem(tr("Sample OSC"), make_unique("sample"));\ + name->addItem(tr("Matrix"), make_unique("matrix"));\ + name->addItem(tr("Filter Input"), make_unique("filter_lowpass"));\ + name->addItem(tr("Filter Parameters"), make_unique("filter_parameters"));\ + name->addItem(tr("Macro"), make_unique("macro")); #define mainoscsignalsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Morph"), make_unique("tri"));\ - name->addItem(tr("Range"), make_unique("sqr"));\ - name->addItem(tr("Modify"), make_unique("moog"));\ - name->addItem(tr("Detune"), make_unique("saw"));\ - name->addItem(tr("Phase"), make_unique("sin"));\ - name->addItem(tr("Volume"), make_unique("letter_v"));\ - name->addItem(tr("Panning"), make_unique("letter_p"));\ - name->addItem(tr("Unison Number"), make_unique("ramp"));\ - name->addItem(tr("Unison Detune"), make_unique("saw"));\ - name->addItem(tr("Unison Morph"), make_unique("tri"));\ - name->addItem(tr("Unison Modify"), make_unique("moog")); + name->addItem(tr("Morph"), make_unique("morph"));\ + name->addItem(tr("Range"), make_unique("range"));\ + name->addItem(tr("Modify"), make_unique("pulse_width"));\ + name->addItem(tr("Detune"), make_unique("detune"));\ + name->addItem(tr("Phase"), make_unique("phase"));\ + name->addItem(tr("Volume"), make_unique("volume"));\ + name->addItem(tr("Panning"), make_unique("panning"));\ + name->addItem(tr("Unison Voice Number"), make_unique("unison_number"));\ + name->addItem(tr("Unison Detune"), make_unique("unison_detune"));\ + name->addItem(tr("Unison Morph"), make_unique("unison_morph"));\ + name->addItem(tr("Unison Modify"), make_unique("unison_modify")); #define subsignalsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Detune"), make_unique("saw"));\ - name->addItem(tr("Phase"), make_unique("sin"));\ - name->addItem(tr("Volume"), make_unique("letter_v"));\ - name->addItem(tr("Panning"), make_unique("letter_p"));\ + name->addItem(tr("Detune"), make_unique("detune"));\ + name->addItem(tr("Phase"), make_unique("phase"));\ + name->addItem(tr("Volume"), make_unique("volume"));\ + name->addItem(tr("Panning"), make_unique("panning"));\ name->addItem(tr("Length"), make_unique("letter_l"));\ name->addItem(tr("Rate Limit"), make_unique("letter_r"));\ - name->addItem(tr("Unison Voice Number"), make_unique("ramp"));\ - name->addItem(tr("Unison Detune"), make_unique("saw")); + name->addItem(tr("Unison Voice Number"), make_unique("unison_number"));\ + name->addItem(tr("Unison Detune"), make_unique("unison_detune")); #define samplesignalsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Detune"), make_unique("saw"));\ - name->addItem(tr("Phase"), make_unique("sin"));\ - name->addItem(tr("Volume"), make_unique("letter_v"));\ - name->addItem(tr("Panning"), make_unique("letter_p")); + name->addItem(tr("Detune"), make_unique("detune"));\ + name->addItem(tr("Phase"), make_unique("phase"));\ + name->addItem(tr("Volume"), make_unique("volume"));\ + name->addItem(tr("Panning"), make_unique("panning")); #define matrixsignalsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Amount"), make_unique("letter_a"));\ - name->addItem(tr("Curve"), make_unique("letter_c"));\ - name->addItem(tr("Secondary Amount"), make_unique("letter_a"));\ - name->addItem(tr("Secondary Curve"), make_unique("letter_c"));\ + name->addItem(tr("Amount"), make_unique("volume"));\ + name->addItem(tr("Curve"), make_unique("curve"));\ + name->addItem(tr("Secondary Amount"), make_unique("volume"));\ + name->addItem(tr("Secondary Curve"), make_unique("curve"));\ name->addItem(tr("Input Section"), make_unique("letter_i"));\ name->addItem(tr("Input Number"), make_unique("letter_i"));\ name->addItem(tr("Secondary Input Section"), make_unique("letter_i"));\ @@ -152,18 +152,18 @@ #define filtersignalsmodel(name)\ name->clear();\ name->addItem(tr("None"), make_unique("none"));\ - name->addItem(tr("Cutoff Frequency"), make_unique("moog"));\ - name->addItem(tr("Resonance"), make_unique("ramp"));\ - name->addItem(tr("db Gain"), make_unique("ramp"));\ - name->addItem(tr("Filter Type"), make_unique("ramp"));\ - name->addItem(tr("Slope"), make_unique("ramp"));\ - name->addItem(tr("Input Volume"), make_unique("sin"));\ - name->addItem(tr("Output Volume"), make_unique("ramp"));\ + name->addItem(tr("Cutoff Frequency"), make_unique("filter_lowpass"));\ + name->addItem(tr("Resonance"), make_unique("letter_r"));\ + name->addItem(tr("db Gain"), make_unique("volume"));\ + name->addItem(tr("Filter Type"), make_unique("letter_t"));\ + name->addItem(tr("Slope"), make_unique("letter_s"));\ + name->addItem(tr("Input Volume"), make_unique("volume_input"));\ + name->addItem(tr("Output Volume"), make_unique("volume_output"));\ name->addItem(tr("Wet/Dry"), make_unique("ramp"));\ - name->addItem(tr("Balance/Panning"), make_unique("ramp"));\ - name->addItem(tr("Saturation"), make_unique("ramp"));\ - name->addItem(tr("Feedback"), make_unique("ramp"));\ - name->addItem(tr("Detune"), make_unique("ramp")); + name->addItem(tr("Balance/Panning"), make_unique("panning"));\ + name->addItem(tr("Saturation"), make_unique("sqrsoft"));\ + name->addItem(tr("Feedback"), make_unique("letter_f"));\ + name->addItem(tr("Detune"), make_unique("detune")); #define mod8model(name)\ name->clear();\ @@ -207,7 +207,7 @@ name->addItem(tr("Peak"), make_unique("filter_peak"));\ name->addItem(tr("Notch"), make_unique("filter_notch"));\ name->addItem(tr("Allpass"), make_unique("filter_allpass"));\ - name->addItem(tr("Moog Lowpass (Note: Slope is double)"), make_unique("filter_moog")); + name->addItem(tr("Moog Lowpass (2x Slope)"), make_unique("filter_moog")); #define filterslopesmodel(name)\ name->clear();\ @@ -222,10 +222,10 @@ #define modcombinetypemodel(name)\ name->clear();\ - name->addItem(tr("Add Bidirectional"), make_unique("number_1"));\ - name->addItem(tr("Multiply Bidirectional"), make_unique("number_2"));\ - name->addItem(tr("Add Unidirectional"), make_unique("number_3"));\ - name->addItem(tr("Multiply Unidirectional"), make_unique("number_4")); + name->addItem(tr("Add Bidirectional"), make_unique("bidirectional_add"));\ + name->addItem(tr("Multiply Bidirectional"), make_unique("bidirectional_multi"));\ + name->addItem(tr("Add Unidirectional"), make_unique("unidirectional_add"));\ + name->addItem(tr("Multiply Unidirectional"), make_unique("unidirectional_multi")); #define oversamplemodel(name)\ name.clear();\ @@ -273,8 +273,9 @@ const int STOREDSUBWAVELEN = 2048; const int STOREDMAINWAVELEN = 2048; // This number divided by 4 is the number of megabytes of RAM each wavetable will use up (I think?). -// I'd like to increase this in the future, but the higher this number is, the more time it takes to load Microwave. -const int WAVERATIO = 4; +// I'd like to increase this, but the higher this number is, the more time it takes to load Microwave. +// 16 is the ideal value here. +const int WAVERATIO = 16; const int SUBWAVELEN = STOREDSUBWAVELEN * WAVERATIO; const int MAINWAVELEN = STOREDMAINWAVELEN * WAVERATIO; @@ -488,11 +489,11 @@ protected slots: BoolModel m_visualize; - float m_storedwaveforms[8][STOREDMAINARRAYLEN] = {{0}}; - float m_waveforms[8][MAINARRAYLEN] = {{0}}; + std::vector m_storedwaveforms[8]; + std::vector m_waveforms[8]; bool m_mainFilled[8] = {false}; - float m_storedsubs[64][STOREDSUBWAVELEN] = {{0}}; - float m_subs[64][SUBWAVELEN] = {{0}}; + std::vector m_storedsubs[64]; + std::vector m_subs[64]; bool m_subFilled[64] = {false}; float m_sampGraphs[1024] = {0}; std::vector m_samples[8][2]; @@ -883,7 +884,7 @@ class mSynth virtual ~mSynth(); - void nextStringSample(sampleFrame &outputSample, float (&m_waveforms)[8][MAINARRAYLEN], float (&subs)[64][SUBWAVELEN], std::vector (&m_samples)[8][2], float * sampGraphs, int maxMainEnabled, int maxSubEnabled, int maxSampleEnabled, int maxFiltEnabled, int maxModEnabled, int sample_rate, Microwave * mwc, bool removeDC, float (&m_storedsubs)[64][STOREDSUBWAVELEN]); + void nextStringSample(sampleFrame &outputSample, std::vector (&m_waveforms)[8], std::vector (&subs)[64], std::vector (&m_samples)[8][2], float * sampGraphs, int maxMainEnabled, int maxSubEnabled, int maxSampleEnabled, int maxFiltEnabled, int maxModEnabled, int sample_rate, Microwave * mwc, bool removeDC, std::vector (&m_storedsubs)[64]); inline float detuneWithCents(float pitchValue, float detuneValue); diff --git a/plugins/Microwave/asym_l.png b/plugins/Microwave/asym_l.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8b919d77676b20102d0fabae901edb76974c45 GIT binary patch literal 552 zcmV+@0@wYCP)qC7(%=<%Grb1sz#+FvkNE*m{gBNDs6?%q*UNr#0PXISs zInu{Cssfm?1wh-EdWHzA<<%yDH!JrHF(ZQ*YXB~wCnc`>bh(H)o8RawXwr;*mDCr% zkCN(~q?5b7=-SA%TfSXwH=3($&=g^1*ddWxj<3_%guw;5Q^ zyY=$=v8}&47C>RRNyj(|g~y2VKr?XZ&HVs>K=5e`AdpJ+g&$*P+|904xcBCAW&6Ls z0}uwqObJ$2$b-E7_nO*E)zNJUq qeDvO(NM^>JEDvU*iQ$LcIQADL@R%XwSzS;700007pV{YTIaV5lTtb!D2*{m`;M52rh0Gx^}IrO9C#g{TGVh zCT`W35})Xx(10LF5nE~#I<%0Qyxh|vFKH0L-aB2+{oU{U&N=rAjw|udTa&vW0f1V2eh_zp+*th-0A~S2WNg0nYsMMkU(bvK z2>b!?tjsw>=-4EHDu?}mWSt>aH5E6Z*>|MwPJBZW0A(k3G&dY^?%npvK&Yx)c-r__ zxb)?3h$^Xg_XDJaFq>W5O!&F#&uc(=AQTZ$Ay?gbZFERU{9d|dS&xb zwqwF#<|{%4p#oA@)it0EdS89-)t%a2nv)Dk0E=mc#dJ0-UK|^i6Bg1>M{SqZf1hc4 z(MwhCMYj7U|9^P2yK0Mu`1 z+P(>v;>(LS*SF_QTn@I^Iu!(9BR}yCc+tyAarzlzR^$FWMnp%?j{%lfolhv8Kpy}A002ovPDHLkV1l2z B>{|c; literal 0 HcmV?d00001 diff --git a/plugins/Microwave/bidirectional_add.png b/plugins/Microwave/bidirectional_add.png new file mode 100644 index 0000000000000000000000000000000000000000..d114530aae9412a3075cf926400285fc58ef7846 GIT binary patch literal 580 zcmV-K0=xZ*P)Zh03c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0i{VqK~y-)l~cb@ zQ&AW_=iXOd2oj4XlG13zjjcmVi3Wtl#mL}h97s%DNgUlA*ch0c3{h7!fv{l=r8=lD zChb39fT)k)00yBU#CH!1Z69q(`p$IE_xqmjUZ4XC<)8C$o?qX-Qz(Ux3#G6v*2Kx= z3wfjE-)lzpSzDmt8)Naj`00ERHoAV^y=9_k1(rAATrdgo)@z)f3_#Qwnz+Mr8T1F6RB>J4gkuj>8nwti&$I;Tx46I&5tdZ(Nw-B}> z=%ERwGH)rjM9OuatYbR2=s8sy8stmioVA<<)DPjm#D#`{)@7YD_eoub7|GxffOo-o zrYRx-jBSKZo#jiwDHzZC@io$<){MoWQ8W!8_%d<5eT`oyhh9N?K;fvv!oMFLc)5dr zek1upjFq=WS|3t=eY;~UkpQ_5o4K=NwR&$D0N^Dl;QRivpfrGiL=)teD`^1muMAcM zrBC+$44=9Fb~S;2b#TAgk#Wv$udq@7Z!J8Th{bZaS=S)An@ujFs4Bs9+;$4Z@|rIu SE1h`&0000;8uf0(U7$ix9@Zol&|F5rmod zw1uX)7+km#nm03UlYtrH-TS$yiSb!9LkBM0d-%@foO`%H0Hd3yw~}u4U64<1*A~XV zd>aY!s{LRW%9%*SlxTD~I0$XRA#Ih?MK9YL-JuTvKmbU&-W$St3CJ}75Wq;l0DrDuj->&E+18J?NmQrs?n(|CyQP)uHsYl;lL~87k|k zK>D=dGj18%0ZK_k zK~yNueUd>-0#Ojhf3qu;Q5QjIg-Fm-mjY9R((=+b=-h`A`UIUi20?U4(?VPD+9}D1 z+>N>g8P)D|*jt22j-3{DqZJ5R8K%lB*;Ld0HD4 z%fNoAH70di%N@p4^$4u+Lmn6b?6n@47gE6V=79|8*PxMmi-lEn z2%s3#1^O`3R?tv!q79oZkzVx2YG)i=Xv#7kpty{J_{BF&4L1czF>IM_vsgF-11oc#cbeh3#A z>tb*d--W~%`~)qvOY#zMw{^%n9g@hSOYQ^jbk8~5-#O=h|B&K%SM917MCsX0V;{kpOSSaNG<5B0b`2RfqP(a&bD4Vt>f9wK7cB#f=(;? zRgfa^84(LKM?-?>2ACbj&yb0So-Rs;?+I0H)=5>3kARl-^LN0Rch#ywW(v`5XH78X zIP~)e!!Y#o2da9KO4yM-=7Q*pXFH8|m)$pM9yZH4OD|ps-{(rkfQRb5$;9(%CkU7F z*H5=j!Z0&M8!Zpx!F}8XlKkRtM%gG|>We?7TS4{Qb&~90iVIbW2+#jYdrQT<9k}qP zz%LyEd35Z8jXuW8Dab8op>KCnX!qFF bT{Za!6smeDa~Vkm00000NkvXXu0mjf=%mZ< literal 0 HcmV?d00001 diff --git a/plugins/Microwave/curve.png b/plugins/Microwave/curve.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbe972b9974e3233209ec46d42cc8a7aaada7a4 GIT binary patch literal 464 zcmV;>0WbcEP)fQH8Q#%QX=Ur4=4w9AxO_qZp ztv0k=x_w`R6c~#4p79)>b6(!}K)_nNYc2pt5NNghzH2Fp+L&`I2q;RA0f;4^fk0ze z?8-EqK%iw*q`N?x!K7jm0G8{%`Zj0DX(hrs^sKf1sOI7mzAuJ7dk;VdfdVFpE&CWn(A5?SU6pZd&Wg4i&&8wbrgE z_n;@5eo(sH&MQ0Q07=nQEt}kZX0Fj24Ulr$Y5is9#a0_=vm+u?-Ju*;veBcynJ!<~ zBO{a3oqxaeD4vzCY(-0hpW)B)_JzhYJWsCboAIY%p8Wu%yIq_0FBez<00006P)=y zuBad)*mx--2|-(p#qJr4-9XT6q7EE5{4?K~|1jqWZ6bG68UcGAi%w&7`*NngRL@CE z@VK%9y4t7-Y`9Keu_ZiySk8*gWl$tr0E#XF*tR`7d%&HR{?S zr4Sm3gbgMW+Iwi!ud{t0z?(uM=T?)kh#RNFUe7;sdVomxMLt<=3M*s;P~_=*?!xI` ztnZuJ79;~8%2TUH6fr7I16X4Gf54;w-fJ=UPjLRIya#k3+}zIfzPEy7xs&o3%3)|X zp%4$IB-GtOD#=HhKL;- zsYSIFX<0Wlb1a5vnQ8bo_vU{0%kP|Xuh64RseTIbYN)w?xiWsi00}_4^1LqZ-T@-B zJzmAlJIhf)13*08L1Y%8tg5#H9Uz-7HFhJ3i^bZinr0Dbxp`*{AXRDP4Uco6>lP-5 z*%SXa(KP1(L^%FByv{l$fmma0e`KvnC#hQbSg`mzw!VxE^C1CsQdSeqjUFr0e z0LJ#~49=(STH`L_gG$la0vIgJgAV{4eF+m=%ra387?34)F%}CTqKaz(AbdjbQvggR zHAJrS)$n4ghS!ki1!2eWh3tH+>gGcLL#gET0w}2}Wsc_lGf49Q$ZF(zz*9#>5ToYC zFmLs5fv5&D-DIhtKC|&=sk`31e@RIs?rn^xAKP-TTrHE_U3s6CsV-!j$_yquoGR{E(ED;TX&r`>cf#cu%BV7G_ zEoGqSI1cOs$Mb>fxDEm4m>W%XSp`%Cx34rl0_Rpb$vv=T+Y2!vWl ztBhQPF2V>3X9gp%t5>ufXAvPTgdoCD3!w;qX1w#AHZy~zhMnzsc{t}i?}2|*VrcX@ zn<&|+@!EB(yevr|DM&AD=?&Y}vzvybQYruJuZ1MYiNDl+s``8t~HG`F#PCp9T z`94_w2q5mbJwPjn6S3{?}MzU`jL!oyY a>3#!%NyQOKXfAdD0000K zXD2&W1*M+bcSUFh`V_q?a0=u&zz;kOnezD|*+d@WLHRo<)oou8r5%wOG=Cr#i3|fY z+8<9iYT9z*tzOh_)46Y1<7-_3N?R|EDEb6IL{3M;q5Hv}k+UKa2ZD>beL6)zr@rs< z%_aIvV*5R;QXWnjS=F;Vcz{4fpwJO>K%qsbF zD{@qAk8Saaj=NRg?bpfNA!j1wT3iV_6?4sDe$It!0KkDW$0GH2)(m7i)4NlpkN^@0 zrg%IFR0!ONM(SHiN_N_^DjiHhkObfZc@quS)rg3e{MP^;SyqJ?cfygvv!mhgtJQSB Y0TG?R;o&>=l>h($07*qoM6N<$f{T(7ivR!s literal 0 HcmV?d00001 diff --git a/plugins/Microwave/filter_parameters.png b/plugins/Microwave/filter_parameters.png new file mode 100644 index 0000000000000000000000000000000000000000..04a1f8f63ead58b748546ab86d853fc37149cd8d GIT binary patch literal 536 zcmV+z0_XjSP)~%A;u8?KVO3WGcuPlFfd9pn`+%=U|^VxEYE0s z<{dvf8|McGBEdffhEJcFKdWEW7JC5`V`3l?FflOj@%`bdKocV!FfuX)SsZ__K#?K; z|1ks88r;w@86O=?{Bh)Xz$$bDrHcqo5~=c-^}p-+IfcGe||Hlx6NZ@ zG3co_K295Cd>yknS|1bDp&hROfmzZe)<+2DK$CqIPb-=B<3 ztX%voXHA4YGB7YO;!PS%Oy9mf*Bi literal 0 HcmV?d00001 diff --git a/plugins/Microwave/flip.png b/plugins/Microwave/flip.png new file mode 100644 index 0000000000000000000000000000000000000000..43fa5f483acd653fd7373da5966e1b988a5fd204 GIT binary patch literal 543 zcmV+)0^t3LP)dDUG2Fz8|C%&d`NTZ2NE zhxQmiu!UvwLYtVKD@1Msz{#J6`5%I7)g-+S;Fk8%JD_>sXEQE6Y~7mv+`n+?5mF!Q z?()lY)`)rlNJn{z)d8G?nGif1tg~NHAMZZ^_=vLk&}{ZApLIDbV>S=yFf4HZ;KfxJ zsTXFBf!}7fxU}1yb{3jN_H`6iGpso0v+Oi@MPYC9l~s2JhrppId>UrW`!4~QE08xE zegf%rc)c#pQ2A{-6L~rqM>rZ7?}7bRT&h%)?@xfIXTkv0Bs~GnORi?-o506bTv{CY z=YQxJz}ugxa4ZwU;s4+cfXv+vM^qdeHWeO(Z(9r2_|5H`7Y~Fshpgi0DU6|7(!GIH hHuICM_{#dg{|gh8n%#>44eS5_002ovPDHLkV1fv{=q3OF literal 0 HcmV?d00001 diff --git a/plugins/Microwave/letter_l.png b/plugins/Microwave/letter_l.png index f2850e5fbd9566e4b5f9118ae23a17e27539fbd6..8b248dee678b59ccddc4dd7b50e6563100db561a 100644 GIT binary patch delta 118 zcmX@ac#=`EGr-TCmrII^fq{Y7)59eQNb`d*2OE&IzBbisqM{)uyO_AS)fJQ5YbHkP z+iQ8cIEHAPPu{TW%isN1m%jfmd4j=*N2DR}?BZGM8`Ip9jE)-G`nj#T&BGAf#ibB- Sa-{~)CccP*pCkvantf@_;dep>d zeG6qz7sn8d^T``_efhip>eBcBB|k8zu_+x`vB+^{$HagqLb*Z=kAHG1`PR!f1I=LY MboFyt=akR{09NoK8vpKk6X69Sk^uGq^)FI(CdI@G0WiP(K1d(b zSye_=Yx(J&KZ9!v=GuboyuDD@TU~2CXN)JfX|#ieb8CNL)5x8NC2IgFn*hLoMr8TP z(L2o^G5xh1Pl@~^dOj^g&)#EAqFAND2LJ#707*qoM6N<$f_r{=$N&HU delta 267 zcmV+m0rdX#0^I^3iBL{Q4GJ0x0000DNk~Le000090000F2nGNE05-_w4Ur)+2?Pcg z9vvdV++&ejFMqyCL_t(2&ttT@^!+~r68QiB{~rbhh8GMB|M&g;^QZZoG5;M#bVaBd z{(b!WRQz$$gzpH$ zpFc?q3=9m63=ED;xUBm2_WKnmQy8ZrHX%-JDDy1~x>TgX{`(xF0>VZtOw2PG7#JA- zGcfEY=)2#){+cskO8o!(|NsA||Ns48{PWKrlQX7#H(8K_0GEk49X{9<0RUoNQDuMt ROgsPp002ovPDHLkV1k>cbIbq$ diff --git a/plugins/Microwave/letter_r.png b/plugins/Microwave/letter_r.png index 65c302f31db68c8aa7324d11d3d621494def3992..a650208eb5af9f0fdcee18fc45c48a6f30597bf7 100644 GIT binary patch delta 384 zcmV-`0e}9?1JMH^iBL{Q4GJ0x0000DNk~Le0000F0000F2nGNE06W%|N|7Nk2?rJz zHzip-)>)BTFMl#gL_t(2&y`ZWOG0rJz32B{mZX7$wp8TeB1%Ll^(Qpg=Fk!}H^cp<)b#(Oy2bI(0kZG2MxfTSZL&lJ`i zM;~4-hA(9ZlzRZc05Gkfa;9Nave%upkzzX?gq;q;ZhyAM2mP-Usm}l?1z4UpOFlWM zFNbe?@7=8*E0Xdqc7Y-v!#MNb?QW+R*JKGmR2k|tS$Pb3-h8tXd8ppEH%Q%3!0c3Hvf$5lJ~_~2@wYYG z^Og35uSuJ03!!t8bpX*=B(~}M&!n?2BBFqTSeEi7uI`mfBwGqdWY!Bge+@gyJ6iKd eM8tqubkpC_4|Oe0^`JEX00000fhe11Iz;g8%l6@ zY3k#L6iy9N%Z&z65(+7>MVtE~C{3mNo`w?QUhefw51hk!4(DL4@kRLulD3GvP*}5V zeRRDTxf*gx8~|Vdm{w5PfMHmfo6fpRTuFyeNrzBrwtvP4{qGd1&jBa}6g{0KXAbJi zk-OeUcl-C1q`burP~>xX2VCsQeQ+r;mmCYKLlF^B$}X|96%i4wdHLRd+Z!2!(aF4jjGQ^pWZ`e6oq4N0 z;hVX(5JbKpSqBh{N8?)~dnWAz5fKICrC3zH;_806M6#uT%ZV>&eod8A|eI? Zg&*k+buBCML+tPvVhVFMo?kL_t(2&z+LJOJh+G#m~9#5}!s%l(1_d!d5{PiA3YZMbN@VwDd37 za%&rl#ZnusZLBQ(1H{gcLPEkr*JK-))s%wkYT`$dP4?Y8HnH;s;;$N*!kK@0*gfLw{lp%Js=jYT{Jz*MgM$#Fv&l7Ia{qReO~gL=wwL+d2_MdY_{ z?c#myE|$3{cKEgbabxT^u@X2P0GQ5KOC+Q9Mm>2t9z8>wC;$!sn5R+^??4HV2LQMC z!$$JxI@YcMQ>Ty9j@E}HwTKu9&V=H@O6Jes#$Iu*@1dmu0E~MNDIL-DYXqVabb#Izo2mX#ol{(N3J7sxJ*Ij&aAzkVJRpN8j$V`1GjOGm9Wbq9eVP8Dj> zY6}s$_8X09ZzB5UqiNqa3FUB!!Wj@l03raY03$91vS0pJ+Ps(?xCJ|xuMHu}BMzh5r zMhwh$gFirQE`v1Wi~B;*QR3RVwAK2~`B^Hl^n0dvc=9AK0ig5fv8l$ZULe#Yh*kg= zkb4o?vtl>>o~X~nai&dsktE4xlp)zwNu|BW3dv>>xql6un|{l`#*){miXi_Jx7N*x z6CVILbdgJwtSb}?y(fKjr{$^&fCd2jnNA@DCBOv$c=e5Iz55Tbav~EaAEVlsJ(5O5 zECi=Q@!=%-^iteTO*Fg%00E%Se@~c*St2+=()?ANNEYH2kGgBt_&*;%e6EdFdi~T) zD5xnaj(Pxqb#9hn2ZqkR=Bf3nh`Ul@;&Y*}QMwWj6=TMfcKuwEuK8 zsojKIjbFc=QtrM~O|*zuh$ldZK*r8ld$!`7Pf*upuPEoVA^-pY07*qoM6N<$g12R* Ak<4`Gxi%20Lh(qb%;?lt>e}IF6t5B7cVh1OSS{wv75u|7l zK_{!&xsJ}R3brT>h!!!RixAU%*P&n9FV$Voba}Ya zq62dqdHh$+3*odd^Pmw=Anh0Atd239?Dd=*@NUh5&_q3oy>~-`#hjBczgsU%!|bPg zIKu312;IL5zHB;+6BRTGy=|?s)s7(c&Z*Kpu&@(gy`;zIHu8a>C9GA%hyD;;YC9uL z2`iabB_8XJx{h&uw=0`JGAzhBWQ*8NeK%$ADwnU}QH=UfX)rw`xY%}HmY?& zysmys3U@mbw(z55r)JuD5>o4HJ{a6Vr>MID%Z+%8H|54xmm2Z$c|>3KY*1{Z@EB76 zr+MLX(0q6_z71jvu3&4VaBIMNU03lE-*fWRe=)xS^^Ru`$Tvr700000NkvXXu0mjf DoPxz@ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/mirror.png b/plugins/Microwave/mirror.png new file mode 100644 index 0000000000000000000000000000000000000000..99dd0e4eb36123160f50f2eff88a6aa839176f37 GIT binary patch literal 593 zcmV-X0UVxf)QDv1GV30hLxS!j&0-~(voC&0#D3oT7d z>{u~Dj2dG|wDAuF&;ne8E(z?r$KpOV>_!T2buu$&&Ya0y(euvFe;t)e*A%iDIbMxH zb29fACu$FRYtG)Tv@S?BZ!%PW|4O` zHAg=qgtK65s`bX|WJZ|H!jah$Fol@ z?Yuo7qG$nx=rT&4`a<43I9`luc04N_Eey9xav~$jkUaf~+UZ`5N1TcVFzuq{PM}b> zC?om-PJbWT>e^$bmjyZol+!_Ft-!vrJ%9;_*5euFU1N*i#qsn*Jd>jNPRY_+*&yA; zM)0}!hU1o(!vNcc`u<;vWFNxP_|PNU53&0MuXD%Sz2rBSYb}X8;8n~faBpdH=u4;I f;=;!Y|M~s`M3}-{TBvNj00000NkvXXu0mjfe{28l literal 0 HcmV?d00001 diff --git a/plugins/Microwave/morph.png b/plugins/Microwave/morph.png new file mode 100644 index 0000000000000000000000000000000000000000..3d1c68ed4820cedde55145b28d6dcb1659097b4f GIT binary patch literal 749 zcmVyKJxws4HvsF?UO`QCS1*pP;{=q~R$_gpULT*3}Dq{prha2ag%)_Xib zB2wG&2msEG&m4PQet0_7d}E z$jvTlEi7CP852bsTP-%wA{hIBQx{g$`WXU%(idL~kgnP#WCs&80N6v8xv0{*Ot6)4_fQIa6pA0vGS$0RA~SCS*=rVwbO2z*F(uSJv$9|y9Epwq z@Ug9W8oi!201zpG%&hhM8L;x)_T2E=Zn00<=w!xs66BJQ{Wbbb;sfpV0X$0%*|Eii zVLj?+#vR3K&as{>s;#X}005Y&H2SSw6Uwhx_3X?-=E6f59{}#L}uCq%PEZ+{O6c f>g#)+`!D<#F{=E7Mbi!r00000NkvXXu0mjfhu1*N literal 0 HcmV?d00001 diff --git a/plugins/Microwave/panning.png b/plugins/Microwave/panning.png new file mode 100644 index 0000000000000000000000000000000000000000..d3d7d1654319631801f90914164133bdf9698848 GIT binary patch literal 500 zcmVQH|B9sa6oLo=yFiltPK z*c$M;UdXMb-t#@%pKWoTG%Lurox;%jY&+-(Qr@gv8 zmD@zwH-7l8bF=#>a#a}=G}1qE?EvHhyP9^ynYawP@~V3N7{I;jdy3$aagIde1&yWB zDCIVsi6Hb8CR1>Ca-=CD-+$Ay3~=ZEI!3t#*+XPI8srmz)9uHi=(d8!Z}Yw#Pb{q$ zhKi_OXInJAz`p4U?v_TcM5GL?{CtsX0S$n9ad;8g7C!iFJ5=6 zCFjuWv#rxdso5-z-TXGtfj+Nh=lEZlS~zWd qd%#2F`F7p-7fTOQ#G!&SIivko81s}o)9E@-r=->x{6bXx(-$6wcMJZAS38jEg zL5Yx&<06-cL<)!+jIa@kY3P8vp}0jkTei;I?C!j?&%QIe@}_jPAxIk373AAP!0z$9 z_m4JXrg-@}blmr#LjZo>D@e9f{jD(ZoFu~OkGI}fD?s+Bwy1_ZQ1^c{7&pc-3knNj zSQF$>mC@<%)%8{oHTpRM=og>>6#V?FzY zy5pLOZ+_+ac7Pj%RIXg@k87^m6+x9h%??ew1_sJ-LqN0#Kn(Rnh^X!Z1j0ar5R$T; zxlM$q=mmg;O%RbD+udX*h&i{b!3Ma7)=3BDsBmsi4K@lQ=1!V=HNT6H(+{=Sjxlb>|h*KT4LoomV002ov JPDHLkV1gb9-Wvb_ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/pulse.png b/plugins/Microwave/pulse.png new file mode 100644 index 0000000000000000000000000000000000000000..369c75d9cc702d62b901056424e4a563a72a8243 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^{2TT$X?><>&pI^U07I%=kTgyHb9{bo-U3d8t0E*G~_zuAkg}-zHGaY z;|0Bh)ci~rjwdcVn<8#j3!E27UU=grZ_YMjb&pMAP8~w3Y75rSPTcpb_e^s4Ws|N; zmhDG(%;6PaoSZgCbV8V+#Ug!!^AZJ0)>C)q&MoLNy-^Q+vunuL-T*pZ@ag3`@}yC gESequb@gFc4FVdQ&MBb@075`%?f?J) literal 0 HcmV?d00001 diff --git a/plugins/Microwave/pulse_width.png b/plugins/Microwave/pulse_width.png new file mode 100644 index 0000000000000000000000000000000000000000..926369154ae949050d50ee4f1579e511327684b3 GIT binary patch literal 512 zcmV+b0{{JqP)uaW7kF4j=!gTO&usI05tPq0DIta+2bQ9{$`e+1H`i9^E= zFghVpR5WPV6}@O$6qxtyiS+Pv)d;oWP!Ta;?fw;v!*hb%l>zJBH%6(xY? zLi-ai{JR(&t}NfK1_{l@_Px~XufPWYD?X|^K>#iS7(KP(-E`*izX1A4U7J7Fc0QK% z3$2&VssYR?07;wg?_BzYDFA+k^>bAL{Q$PM5{MOmQ0&#K05VhpVs|Tn=pcx_y@LSF zrS?st9s>iyyLL)Wk|j@P5^oH9`Pk5E3RW9n6pK25%(U@%X>J)j7-Pq)*{jjU{ewfr z4hV%X2oTL@!GzG0BJy0B4d8B9dFy=sr_&A_$V5ANVD}+`{Wfnk^1sD+sN$j0%mIKP z`byBZqxRt7ZY#_sQ++aRrA`18(oQ8nQN(Qk1)ZIondt%QX_B7pBR|t&U0e9FA~XVg z2Wp1-*S8w2N)wdteF&NbYQT%2Fvb7q#!{zt+?{}He`R9;0000pQ4}pAFc%dJxM>j)RMIMfCWL~* zOd@a`M={Nk7Bk`_B1?N{rPDYw&FlYei%AK?=q&F!oO{o`mjIxuf2JA$4BzI1{RgZI z0MPFBxi!eimwnwHx7(e@3Lty?*ebm+`yi8M1OOH?aN_6N;u4vD1ON;yK*0l+cU?~V zz+VPc{?A?z7Yk4~69;ouD$CCE7fX>UTFtR(6KLHZ@>e>PC#0u5$DGdZ06@EYr(=M~ z%5>uiE5~RPqMM^EM|-5@noWh`PJM1y4$=)oqIl7YneVwAwT&7pZiZk7h#bVUWt?&_ zLnf611py!+3d{jf5M&|S&Lzhia)Gk|z`DEv0D`1U5Yf|eBw8ytf-ES6SQAl}hgk6? z2J8S}(33lZBLC=nm=V>{Qon!iU}gthqZYwtTb&lUV-kA#92t8CDgTpFkxs?cGOvnX^dWKj-i{p0o z^c`W=&jVry01)wORv6MrocuuMg?K literal 0 HcmV?d00001 diff --git a/plugins/Microwave/sample.png b/plugins/Microwave/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..cc5ef077ab1b8ec27aea5ade17736c3ce9e79ec4 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DYhhUcNYe8hC>X`3>j{LL^umP zB8wRqxP?KOkzv*x37{Z*iKnkC`(t)tVJWL4CvUC=3eER)aSYKo|MucWKE^_UBMme#`5WZE$R=nOF3URH3@LFejhN$Fx=pPMD3Oj90!~@t!5+&Z4nA` zab@%^asG1shPVu~&iBsroQV(Gtk>O0_{urKcS1s=t=o#^c2mCYxR<;iSdzq*lec9( R_ziR_gQu&X%Q~loCIEc6We@-W literal 0 HcmV?d00001 diff --git a/plugins/Microwave/sideways_morph.png b/plugins/Microwave/sideways_morph.png new file mode 100644 index 0000000000000000000000000000000000000000..1cfa788b8544540b100a6377f8221ac926215e46 GIT binary patch literal 662 zcmV;H0%`q;P)5r00006VoOIv0A~Q; z0RL98FAo3!010qNS#tmYE+YT{E+YYWr9XB6000McNliru;|B;10|X6DjiUen0wYO8 zK~yNum6K0M({UKaKksjAu| zA6Scxf03t5bN5=@kj}+a_|RbGGNm_nIq}n^by1a(xM@wO>UgiKMpX4YfTFV{o@^$b zG)=#O>tzW$z<_JN<`MCzGn)?W-B;Eikw|RIdwf~YI^aISn<1mR|0izm7L=>@Cr~~M zj5)~Ih6s6&ceE&;iAI9w{8nyUQ7?dB7ak*W1hht>M__SXiSeX$4LB{ZXzOxELwc@D z(USnE-n$(-cmniY0W%Se1p1BD($Z}xy~WHOeZIOMD1*hIZ?mC27p9U{4@x_#U)^px zSJwEM6xwY>?z^ovxpBXob0t?eVODjZ;kF6FwNT%&`1OmXf4dAAz%EzM2uHyD(r z(VF{iBNaYuF56!U1VL31Fgl`z5lLbBK2%$OH=2Vf93YsD$eBN1%GFE20##q81Lok$5l^PAB> zBwswR>e+u_cB>jCegC6m8^FOG0CRQ(aA7u@uS6IDP?2SCVi#}%vIC$>sf~6rCGJM& zd*G>I8(8{KRSp2eC=~$8QGD-Ht+;&^URj9;Q|JbgM!EMKc<^iSe*Ckfv@Gk)a@pXTYt1 zAaL}rMw^rUZveC_J*;D-0%Kw_0}N$3;tA-OclY?(5Ufs5|1x16Ksw~HH*+^jqy$+u z?0OOpYGjj50+`66Kfengs`(_+Sy%wh07dM1vs!#);Y a;C=(aewTBxy1e}W0000?0clA@ zK~y-)ozgK&TTvLs@&9|0VC-f=h}X%jEtM`YM~7S*>>~XFO-miRw1YztgmmdDxRoyM z3Yq)_4kq_jdvA)HS)2run+y)^pi`39AwdY3q&M$$4m|weJns=k%&OnEs=X2-Z&8jy zccJ)L&Wr+rd?r-Y4OCOWt5La;0Dy?x_D}je=eLWofgwzL-=+psX#vaDk9Ma5OoFYx zL@DRB4`Tyjx)l}k9zf`QuzqyBQfaL`0QRJ@Iti)eGi7>g0@o;SjM18{M!UxP%}*rE zZ|g<%Ts8VU4hdg72c0K8L-^6(5;I0f)PXwiLWF(mHOu3W^Q?0h=AEz7m8HOSwoQ=F zgrV!a1U>={kayOP{!DsOP*}JcDlv4OLzUFJDioxcOYeU0D&0iYPFN5xPfMhHH zAaEB?1^GF+&c+4+(%tlT;08!d1yl-ie+4ZM{&BP0Nv;uha=)VN+S$LSlXCYvDs^T; SM~ANf0000(R*6F7uce_b2pcJ;B&uUzULg##VPHy9}>84&gX04 z>$9{QSQnHL6&ICXHnwN6U}bGBLCpPmyYn*|ZVpaYfnMMUz-3u99AF;6@%I3d$HC>T z<~_j#urJppfKa5el4`EXDpD)A?b$!mo~*a~lav*lQD6f6M+aL?J=`z}oM8jFS#Mtd z+vfKtX~LeI2Zdc^_UO}{q2r!3R|YaGZ?zUel6)&Q+Rp(>jrJn)WneH5Ms>_*cc+Io z0N&lo4xCVPLQUoE)?-{R9A3(Kg?O7oEbZRTp8hWiQ{WW9@IFMfsIOlI0;DL19Ss0e z0KvT$(*!#=PKthv00Q6qaCf*F1$#%Q#kBSTxaoE5)Y-?GtWc&0;G)BuXgJ>xKP&FW qrO&R0OWTLzme`7%L(rFQ_WL))BZHscyz>D70000lbB~L0Fofx%&+0tS<^DJa4jh{wc3+E=$hKGN&I z7c(Qh`Dbh6_@8im>ACu%x%>9#;TE6V*e&h?Oirbj%|~y314w=E-gsR6G!`IffW0t! zvphe%6N#DtFjVY*Z7jgXpizt($%|j~q>^T@KYTk4pb%%r0>HthaqEwRNkE{p03>ED z=EIzq5J!gkcn46CXnbU50sH~d`L+A|HDD6lAbAP=0eL(?Py?1L6a58H2eh(q?sT1? z5;#j_3Dm_j{v!g@K-)cEL24V$_fx84-T_k~R+oVioruufd2@RNFl0%(Y`Y_=NTGif zyTlX>(nZiac?f9kwC;uPpT1ud;n%f&*8t08GONN}>^u(ior2m(Et4)7T875P_UlXF zJ7I5g{$InvY`fS3J`%_vt(edOWyTksQfa#oT85MZb=9itz{~KZ0DFqw0v&-eLO3Jb zMb44FMU=uVo730@&<8dIe}!Sw(jHb5I8sVEreWMAIY*o^p^aQ178PTODS_+QLkCGb zwYUc9NK`W5R6rdOGt81mr3fuxPS&ABTd=08h7O+HT=|ETCS(Sm;vffqlcX*hgRAkA%ZjQkAU?Ud+A-`)+UEbxkM|u<-aZ3g4;!4I2?u)s0000< KMNUMnLSTXltwl8e literal 0 HcmV?d00001 diff --git a/plugins/Microwave/sync_half_inter.png b/plugins/Microwave/sync_half_inter.png new file mode 100644 index 0000000000000000000000000000000000000000..6a8a6759bdfec86113be7414ef020c2f80aa6820 GIT binary patch literal 688 zcmV;h0#E&kP)nXxc1SSEwSc+R58jSFI4r`l`pqfh5(tqmV=hNc#) zZ=1zN&Ed)V^zcOeI>7Km9Kh~Eu@xXvY!Z}?kI(hK6EHN< z_+e;r@w-CyLMs3J0?LNxt=LpKe4}w-Wa81q4FSSGi8x=#EfD>Kzx~yNy&ds1)X4+R zTKak8F9b4_3-uXzaogtJorW@I$wYo&1ad-V6V0s1l_g9@6wg3-JX@{UJ#iEjP zPz8JGWwx|#YYb1-M~nJXqnP`=J}7vGG#~O#K^doq&Zr>ghB@Qv;iE?J|^|^ngTelS{e}t_Gz`E_Hn!$YVC6n6S8Sr2{}y!93DF z!?MG5f{H{%owa*G?8lsGzij;yPK+VWf}aW3Kvkd_Fdwj6u$(#Sm;uZyqd$#DfL~`% z?OlmG$G%)J{81#Z2Hp*BuC?0>zyQ+YS1C1s9B4$xHDH&lYwIp_`YNZ5e(Wf#fd`D5 z-Q9ijz!$QYXHVo$Kz&F{w@&VOggAHmSmnw(VD^yOGe`5^Q_orrVtYXI<~QY4!5r00006VoOIv0A~Q; z0RL98FAo3!010qNS#tmYE+YT{E+YYWr9XB6000McNliru;|B;12sS2d1?T_(0s=`y zK~yNujgZYtRB;rBpL6b%me!)o(NR;<3KTNZ8WJ>XA+24vYZJ7pKOtI2i#F}rv=55P zP2lK43pJvJra>mnbqtd}oWhy=ds_s;)G+k!&N5)YJ2H zxh|W_KdNdlko(YzF?xPF9>YlkTkdp{l+wUfFzaqQuz$?p^4ZBx9siu*Nh+;~uZbAI zErqjA2wmnTpkPvu%wmIrnV$mIDmJjl(+2D2oN=ke#G09R5|jqkFuH+b67NC%yL|xX za`|hR6-^okPJ5r00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmYE+YT{E+YYWr9XB6000McNliru;|CTOG#Dy*$%_C00Rc%w zK~yNurIO2S!axv)|Jk*)IdVk`k~@em!9KDbqyyZ7D*!4;2}uW`gEc-`${|h#w#36n zXkd480R)y3Kl0t?@z1RO9YPD!&3;KlPh=^{^|)%*1-kLVlFKlw-y&1{w*|Uv_(L23 z@b6RfP8O?Nk1GnZg8?wZ0GN3tFr1VfuRUj7BEh3yw@7aeaC|Ft)+L|%u>b(-_zR1s z@PgO+P@;mY)w!Oe_z#h({b#cahTZ|3aIui$D>B5r00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmYE+YT{E+YYWr9XB6000McNliru;|CTOG!n|JAe8_B0Uk+2 zK~yNuos&IM0znW)U(fQBl42PwCvXjL37H#k1MvoO0_6mF1aBZW7+n)A1NH_GtZPar zS~FuHYavy*3oq=huY11k9-)Mbr?*=XITI_RnQkw4^NMN=eBc*xl0Wp!d$^sDqQgJp z2nhd%+9mkmw$NEOdex^XfK=SV z&91PZR{Btp)LD1FD?EtEEcRL~9bzxZhRvWk@0u(Eh?D#}e$MAb(b59ek^(IiC=)07 z1eoCE*N#-N&^1}40%d>}FkRdARjNCy%BQRX)!&E#`gQ8zK{Eg*Kj&-prl2YQMClqo v?ANrR8sVo~-=(^<>Y7Z8lEI5USps|me93ZFN6gC^00000NkvXXu0mjfw(g?j literal 0 HcmV?d00001 diff --git a/plugins/Microwave/unison_detune.png b/plugins/Microwave/unison_detune.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1600a16cd1884f60872af065d7c8bb8941753f GIT binary patch literal 10006 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 CKD6-w literal 0 HcmV?d00001 diff --git a/plugins/Microwave/unison_modify.png b/plugins/Microwave/unison_modify.png new file mode 100644 index 0000000000000000000000000000000000000000..ae92cdfce3f7bf8c3cc08cd02ce073c151b6da69 GIT binary patch literal 9291 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 TmPM&k2{6<%(=FCMf93xG=JkzZ literal 0 HcmV?d00001 diff --git a/plugins/Microwave/unison_morph.png b/plugins/Microwave/unison_morph.png new file mode 100644 index 0000000000000000000000000000000000000000..2a2c7ca572c28c9ed2f8805eb2e92a08b336759a GIT binary patch literal 775 zcmV+i1Ni)jP)Dliqh~Fff8-*9+P;$;AfQJ zM?kgf_W26(*!zdk@7`fK+}2#L)8G#>(@3M zs{QN(lmgRVhqSR}zjj-&XeQzV>nMK&Q*o=qd00pc44>Xvkm9-~^z{+`6sWu8ZXXN2 z&j;uZ6c)f#3;@cOTn3P_^@urxn10f>zYvL}i)FnTr0S|X?lZ2a{sq9p#G387)fPVv zC3_*v8vHN1y9crXz%?0nx+e4yS5#kdMfI=eqpP<7;1@!p2`7^%JIVk6002ovPDHLk FV1gScPe=d& literal 0 HcmV?d00001 diff --git a/plugins/Microwave/unison_number.png b/plugins/Microwave/unison_number.png new file mode 100644 index 0000000000000000000000000000000000000000..eba21366204f8f5a47922cc02b34b7974d8040dd GIT binary patch literal 393 zcmV;40e1e0P)%A?YvW4|=E0ca0 nulK%$TBj%u&{yQR>)L0ZAW>xD9i!k#00000NkvXXu0mjfw& zK~y-)osp|f17Q?|zyIeiA>5HAeFH=VfnBv(34#Ozf&{|@5Q4+-06YU8QIA_LyP^%~ z3Ov~r4MCQs?H&ZQ*+RE_ndFEw$(+j!%RTv zO_p%^W5WYhM!gk8O&Ja^XKu8f!+W5vrd*aPwEXA}g`M0saq3PG?){r4a*W76inX-C zM#CY(DeyIBl{O%&v)&k)v-n#-5Xp>4Qxc_x20);vpr7CuvNATY#0{V!6RvWA(r0N= z0GL;&=1t)}+mAv)u7RaOKen9eje-k-o}hFgb6U>kt=61?RK^hx23Id`t(nU~JBVES jDLgM_|L((kJ=uQ)g_24*jn{sg00000NkvXXu0mjf&H|gn literal 0 HcmV?d00001 diff --git a/plugins/Microwave/volume_input.png b/plugins/Microwave/volume_input.png new file mode 100644 index 0000000000000000000000000000000000000000..db802c6e3c792fa724403405748e0ac58f767dca GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+k!3HE-=Cy!0Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-yOe+o)6x6pX+R-`%#er@=ltB<)VvZPmw_Q5zdW@l zHANw*Qo-FXRNp5vue4%LVDmQy21Wx<7sn8b)5!@6LK>Cs|J=osmAn==zpvNJE@#_h z!X55^K+7*+^Tk`6|4T+jJgj;ARs7%TWugDnSKKW4`SHI_lM+u)PtTH@IU8O)s1FO| zWJ`&@$k<&KDD9?E^kRm=2G5hm2AeiM{3^uVK24B$_a-ss!}s@lyh}WktsG;_3>%4~ zA`32Weq%pp=fS?83{1OU0Ew6g#J literal 0 HcmV?d00001 diff --git a/plugins/Microwave/volume_output.png b/plugins/Microwave/volume_output.png new file mode 100644 index 0000000000000000000000000000000000000000..bfe1d3a225ef8ac0e2ecd6ccfd8e3185c2778d83 GIT binary patch literal 614 zcmV-s0-61ZP);v703c~p zSad^gZEa<4bN~PV002;LcV%*AWFTUBAV*GBFHC7}b$FangZ2Ob0mn&1K~y-)m6JO@WHA8?@6nkIq|bWj}#PIM;z6#EktaV8d=l%moO#DS>T1W~Z1 zAOx%(_$av<6hUIHiTAO$gOaMXN$Q3(IP0wMu-NPk?6QuRHx6#s%x=K5^B;Ye#8>_s zK3uI1wDu3K?)26d&V2Qs1DfsJ3zhoo!n04MzVPJB;0eGZ)SZ1@;mLA+7DkHzvfVuP zSY`dfcF`%Xs^~=;?(LP#T6mYCdW}H4BPxxh(OkcNSO6e63}Cn;QuS{a83`rY{25{5 zS>1xWl>$Q5I*1jfSl!g*6%!46!U_nWYeLLvf~ViZ<~sn0(`d%CQFE)?qWTkx<{u}a z;tLcrZ%^lM7}ws|=Vum*<)AU-4L)`za}oeJ{^Ilbf4XhV6ktYFlADqn`(VSMD#CjM zjmDiQJ5-=&AEs@V*e&+NVr{%7-`4iHk)uvH_vX}rQIHA%#Y*k2g7vOLvUDcDQeAxT z!^N7XXwU%xKw#FP%=ez{>1l}_YeI}d^>@k?W1!a9caN9U*)XV5^uE_<-fCt16V|4W z(l$$dw`zHUu}yJFtvQ$axxhKOZGh{`Q-|LF0(Wn^5yfFxSO5S307*qoM6N<$g7wc9 AbpQYW literal 0 HcmV?d00001 diff --git a/plugins/Microwave/wavetable.png b/plugins/Microwave/wavetable.png new file mode 100644 index 0000000000000000000000000000000000000000..358e2edda12ba78e0bee62f63b17689d9ae4f0be GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DYhhUcNd2LAh=-f^2tCE&H|6f zVg?3oVGw3ym^DWND9B#o>Fdh=m|aYm#o}Z{c@9uWAu}YR#5q4VH#M&W$Yo#%$S+SV zN=;Ens#I|I3)T0@%qy*!6WII>C{^m|;uxZFJ~=@m;{ZqU4Ed^W^F?~q-!74ml#q~! zn82D}GS$cc1hij+sXu$GS@o6&UgHgCPBsRKBpUyHe^;BQ{(W4dbPK=1!^tYg1k}8k zCoW)YiE*65J%M@htBWUGu7;%6y|`Ilqo=51Z@|ECbP0l+XkK Df^}7c literal 0 HcmV?d00001 diff --git a/plugins/Microwave/weird1.png b/plugins/Microwave/weird1.png new file mode 100644 index 0000000000000000000000000000000000000000..15c136e45289499e42f9731def6fdbdcc587f6b6 GIT binary patch literal 729 zcmV;~0w(>5P) zK~y-)os!RMlvfyqpL4%Sl$fX)E1gM<;zVezAVMG$ijGRR#cfxD3thN&=c-#p@L$kB zpitO}maBh27 zPgsAV3i4y)q0L~+;awScD>2#=mMe~9=0q6W3}&kYel0Q56BbYfcm&QS{zx|*)rm@2 zt?2(ND|EMb*7ms29iY9X7zTlVKWlv+%MRh0@L_;zJ)Mr`VyI51M-690s5ofeumtZn z^vyvfh>yWtWvYZ27eYjfz_9Unvf>3$JBwR3_Dz&*%?SpN)tkG)J7-Src~R)6u$Zx0 z1Q+l8H2QS1-dK`48?D|-PmAz|EFXx8R_@hCe(!FeENB_h6{#wF0U*S%yeJsPTIe)Y zJD4?P*C6gE(RsnIAB9P!KxhJu5VIrL^8n%RAIIJqOX5klw4LX1XkvD@4<@^XsCaWy@*j9+#9PgN1CYh-nMHGjSL^0C4D``w`pk*UGPiQ=y8x z%GSDNhF6_2LmPZVt7=Ag4g3J=19kxHc+)ILXm-P!T5%Lizc-#Ph1qF1zjwum8RezI12#>7ia$n-KCDMf@2-U zLByA|AZbK#XqQeVm|%j7&=i{I-s4c)^y$ml?mc|&IrrQv4n^g2?<%m_SS;oC=RS4s zg-8+bW^LgTE|;u#mQ2}qlr2~4ogB1?B?Wt~U;udt-1jjzF}otC+T3b)KOyWivdicg zXi(x5Eum)??1BA19W$Acf_^&BwOb!MBUpL6c^=5(0fR((2i)Du&41{YfnQkI2$7!& zksraVP$&X@fR*Y*AMmkD&fQ+^;|rvM7ScMz(-4nfTyXpFaF|(Ys4d4jgc%4UD2q>o z&RmLxw!CeCra`#MO6Or^r9%k51nPl~Rup9^YW=-9xeiPL#27DtS3*Ud)M^N2lir{C z)7@!QCok+mXqmzda78S1kAp&~NLsn}k($ojte|Ml^~|~BWSWq*6SDoS*o-E|tcjxY zM_WyXb~cL`+rj#c>f{JIsTs^334%q|J5c6#7!IelBRRv`M<$(i>t7|V1LKM4C)#_v z@XaE(5M*VUTC)7K-EytwF>9JJ?w#*@=XdMLEgQZT8L1pC9lHAN(nUYOf*-o=FY_q? zjq1c}q$=o12-XgJAO0X5%f=sTYf#eGAU{mAJ76!J^mJ`;Dwq2Q043dQW23Gx00000 LNkvXXu0mjfcHbIN literal 0 HcmV?d00001 diff --git a/plugins/Microwave/wetdry.png b/plugins/Microwave/wetdry.png new file mode 100644 index 0000000000000000000000000000000000000000..88b294fa8fdbd93cab1599b0f13f450491859887 GIT binary patch literal 625 zcmV-%0*?KOP)jH1_hy!X44!LjR#F*_WQ;|N!gM_oZC0^-n=*O143ozs}q*%&*DFe!jG%@?}yA- zs~UhNSI0-nyZx1|IJf9A0Faiq@0^iW0Kj4L>h0m5M3OZL4|`Sg1CihpATw66u{h99 zvba@Ac#Y|>a}zT};oR4Y-a-Tzl$JaD@pYmm{S ze%<|cO(1tPn=U6ke=a<<^1f}&*B>oSoG56L1-r1B*;z)>q}ON$)PBuMJzY*6-7uMH z^omzIzwVs;3;>9+O_~k>fPqd~9mW!HH z1ppSEGasR8Hr`el_ukFzFcAPu2~c8FQr5g5pbcLjmx4e1vJ2SXY-fKDN2&?0{$j;B zzP2YYrQ0RZJS9TUBx<}NrpxhI=R+6Zrq4D7M%EDO36IN@=iZY+-07$(1(hb?Ybka5 zM;Ns19D4%7g@pHIdXH@YfKqqYZk;LufL*A~^!qxkkuwcG67Ky4&?3D*jNu+200000 LNkvXXu0mjf6Ppco literal 0 HcmV?d00001 From 43e026b48ce1076084e9ab0048a89e96b901a05a Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Jul 2019 11:16:35 -0600 Subject: [PATCH 12/12] Fix typo --- plugins/Microwave/Microwave.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Microwave/Microwave.cpp b/plugins/Microwave/Microwave.cpp index 579756dffe7..1eb7527ae2b 100644 --- a/plugins/Microwave/Microwave.cpp +++ b/plugins/Microwave/Microwave.cpp @@ -5699,9 +5699,9 @@ void mSynth::nextStringSample(sampleFrame &outputSample, std::vector (&m_ // Takes input of original Hz and the number of cents to m_detune it by, and returns the detuned result in Hz. -inline float mSynth::detuneWithCents(float pitchValue, float m_detuneValue) +inline float mSynth::detuneWithCents(float pitchValue, float detuneValue) { - return pitchValue * std::exp2(m_detuneValue / 1200.f); + return pitchValue * std::exp2(detuneValue / 1200.f); }