Merge pull request #12 from LMMS/master

from master
This commit is contained in:
Dave
2014-12-22 21:34:46 +00:00
59 changed files with 3659 additions and 106 deletions

View File

@@ -15,7 +15,7 @@ INCLUDE(FindPkgConfig)
SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "0")
SET(VERSION_PATCH "99")
SET(VERSION_PATCH "100")
#SET(VERSION_SUFFIX "")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
IF(VERSION_SUFFIX)

Binary file not shown.

View File

@@ -654,6 +654,63 @@ Wenn Sie daran interessiert sind LMMS in eine andere Sprache zu übersetzen oder
<translation>Plugin entfe&amp;rnen</translation>
</message>
</context>
<context>
<name>DelayControls</name>
<message>
<source>Delay Samples</source>
<translation>Samples verzögern</translation>
</message>
<message>
<source>Feedback</source>
<translation>Rückkopplung</translation>
</message>
<message>
<source>Lfo Frequency</source>
<translation>LFO-Frequenz</translation>
</message>
<message>
<source>Lfo Amount</source>
<translation>LFO-Stärke</translation>
</message>
</context>
<context>
<name>DelayControlsDialog</name>
<message>
<source>Delay</source>
<translation>Verzögerung</translation>
</message>
<message>
<source>Delay Time</source>
<translation>Verzögerungszeit</translation>
</message>
<message>
<source>Regen</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Feedback Amount</source>
<translation>Rückkopplungsstärke</translation>
</message>
<message>
<source>Rate</source>
<translation>Rate</translation>
</message>
<message>
<source>Lfo</source>
<translation>LFO</translation>
</message>
<message>
<source>Lfo Amt</source>
<translation>LFO-Stärke</translation>
</message>
</context>
<context>
<name>DetuningHelper</name>
<message>
<source>Note detuning</source>
<translation>Noten-Verstimmung</translation>
</message>
</context>
<context>
<name>DualFilterControlDialog</name>
<message>
@@ -780,6 +837,13 @@ Wenn Sie daran interessiert sind LMMS in eine andere Sprache zu übersetzen oder
<translation>Vokalformant-Filter</translation>
</message>
</context>
<context>
<name>DummyEffect</name>
<message>
<source>NOT FOUND</source>
<translation>NICHT GEFUNDEN</translation>
</message>
</context>
<context>
<name>Effect</name>
<message>
@@ -3294,7 +3358,7 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS.</tra
</message>
<message>
<source>Bandlimited Ramp wave</source>
<translation type="unfinished"></translation>
<translation>Bandbegrenzte Sägezahnwelle</translation>
</message>
<message>
<source>Bandlimited Square wave</source>
@@ -3330,7 +3394,7 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS.</tra
</message>
<message>
<source>Digital Ramp wave</source>
<translation type="unfinished"></translation>
<translation>Digitale Sägezahnwelle</translation>
</message>
<message>
<source>Digital Square wave</source>
@@ -3350,7 +3414,7 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS.</tra
</message>
<message>
<source>Ramp wave</source>
<translation type="unfinished"></translation>
<translation>Sägezahnwelle</translation>
</message>
<message>
<source>Square wave</source>
@@ -4085,6 +4149,21 @@ Grund: »%2«</translation>
<translation>LMMS Plugin %1 hat keinen Plugin-Deskriptor namens %2!</translation>
</message>
</context>
<context>
<name>PluginBrowser</name>
<message>
<source>Instrument plugins</source>
<translation>Instrument-Plugins</translation>
</message>
<message>
<source>Instrument browser</source>
<translation>Instrument-Browser</translation>
</message>
<message>
<source>Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track.</source>
<translation>Ziehen Sie ein Instrument entweder in den Song-Editor, den Beat+Bassline-Editor oder in eine existierende Instrumentspur.</translation>
</message>
</context>
<context>
<name>ProjectRenderer</name>
<message>
@@ -6990,10 +7069,6 @@ Doppelklicken auf eines der Plugins zeigt Informaitonen über die Ports an.</tra
</context>
<context>
<name>pluginBrowser</name>
<message>
<source>Instrument plugins</source>
<translation>Instrument-Plugins</translation>
</message>
<message>
<source>VST-host for using VST(i)-plugins within LMMS</source>
<translation>VST-Host zum Benutzen von VST(i)-Plugins innerhalb von LMMS</translation>
@@ -7056,14 +7131,6 @@ This chip was used in the Commodore 64 computer.</source>
<translation>Emulation des MOS6581 und MOS8580 SID Chips.
Dieser Chip wurde in Commodore 64 Computern genutzt.</translation>
</message>
<message>
<source>Instrument browser</source>
<translation>Instrument-Browser</translation>
</message>
<message>
<source>Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track.</source>
<translation>Ziehen Sie ein Instrument entweder in den Song-Editor, den Beat+Bassline-Editor oder in eine existierende Instrumentspur.</translation>
</message>
<message>
<source>Player for SoundFont files</source>
<translation>Wiedergabe von SoundFont-Dateien</translation>
@@ -7148,6 +7215,10 @@ Dieser Chip wurde in Commodore 64 Computern genutzt.</translation>
<source>Carla Patchbay Instrument</source>
<translation>Carla Patchbay Instrument</translation>
</message>
<message>
<source>A native delay plugin</source>
<translation>Ein natives Verzögerung-Plugin</translation>
</message>
</context>
<context>
<name>projectNotes</name>
@@ -7476,6 +7547,57 @@ Latenz: %2 ms</translation>
<translation>Wiedergabe-Courser im AudioFileProcessor anzeigen</translation>
</message>
</context>
<context>
<name>setupWidget</name>
<message>
<source>OSS (Open Sound System)</source>
<translation>OSS (Open Sound System)</translation>
</message>
<message>
<source>SDL (Simple DirectMedia Layer)</source>
<translation>SDL (Simple DirectMedia Layer)</translation>
</message>
<message>
<source>ALSA-Sequencer (Advanced Linux Sound Architecture)</source>
<translation>ALSA-Sequencer (Advanced Linux Sound Architecture)</translation>
</message>
<message>
<source>JACK (JACK Audio Connection Kit)</source>
<translation>JACK (JACK Audio Connection Kit)</translation>
</message>
<message>
<source>ALSA Raw-MIDI (Advanced Linux Sound Architecture)</source>
<translation>ALSA Raw-MIDI (Advanced Linux Sound Architecture)</translation>
</message>
<message>
<source>PulseAudio (bad latency!)</source>
<translation>PulseAudio (Schlechte Latenz!)</translation>
</message>
<message>
<source>Dummy (no sound output)</source>
<translation>Dummy (Keine Soundausgabe)</translation>
</message>
<message>
<source>Dummy (no MIDI support)</source>
<translation>Dummy (Keine MIDI-Unterstützung)</translation>
</message>
<message>
<source>WinMM MIDI</source>
<translation>WinMM MIDI</translation>
</message>
<message>
<source>OSS Raw-MIDI (Open Sound System)</source>
<translation>OSS Raw-MIDI (Open Sound System)</translation>
</message>
<message>
<source>ALSA (Advanced Linux Sound Architecture)</source>
<translation>ALSA (Advanced Linux Sound Architecture)</translation>
</message>
<message>
<source>PortAudio</source>
<translation>PortAudio</translation>
</message>
</context>
<context>
<name>sf2Instrument</name>
<message>
@@ -7902,6 +8024,13 @@ Latenz: %2 ms</translation>
<translation>Rechts-nach-rechts</translation>
</message>
</context>
<context>
<name>tabWidget</name>
<message>
<source>Settings for %1</source>
<translation>Einstellungen für %1</translation>
</message>
</context>
<context>
<name>timeLine</name>
<message>

View File

@@ -1,20 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE lmms-project>
<lmms-project version="1.0" creator="LMMS" creatorversion="1.0.98" type="instrumenttracksettings">
<lmms-project version="1.0" creator="LMMS" creatorversion="1.0.99" type="instrumenttracksettings">
<head/>
<instrumenttracksettings muted="0" type="0" name="Kick power" solo="0">
<instrumenttrack pan="0" fxch="0" scale_type="linear" pitchrange="1" pitch="0" basenote="57" vol="100">
<instrumenttrack pan="0" fxch="0" pitchrange="1" pitch="0" basenote="57" vol="100">
<instrument name="kicker">
<kicker decay_numerator="4" decay_denominator="4" distend="0.8" click="0.25" endnote="0" version="1" decay="594" syncmode="0" noise="0" slope="0.33" dist="1.2" env="0.163" scale_type="linear" startnote="0" startfreq="130" endfreq="5" gain="1"/>
<kicker decay_numerator="4" decay_denominator="4" distend="0.8" click="0.25" endnote="0" version="1" decay="360" syncmode="0" noise="0.2" slope="0.372" dist="1.2" env="0.163" startnote="0" startfreq="145" endfreq="30" gain="1"/>
</instrument>
<eldata scale_type="linear" fres="0.5" ftype="0" fcut="14000" fwet="0">
<elvol lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4" scale_type="linear"/>
<elcut lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4" scale_type="linear"/>
<elres lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4" scale_type="linear"/>
<eldata fres="0.5" ftype="0" fcut="14000" fwet="0">
<elvol lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
<elcut lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
<elres lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
</eldata>
<chordcreator chord="0" scale_type="linear" chordrange="1" chord-enabled="0"/>
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" scale_type="linear" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
<midiport inputcontroller="0" fixedoutputvelocity="-1" inputchannel="0" scale_type="linear" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
<midiport inputcontroller="0" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
<fxchain numofeffects="0" enabled="0"/>
</instrumenttrack>
</instrumenttracksettings>

View File

@@ -0,0 +1,161 @@
<?xml version="1.0"?>
<!DOCTYPE lmms-project>
<lmms-project version="1.0" creator="LMMS" creatorversion="1.0.99" type="instrumenttracksettings">
<head/>
<instrumenttracksettings muted="0" type="0" name="Snare March" solo="0">
<instrumenttrack pan="0" fxch="0" pitchrange="1" pitch="0" basenote="57" vol="100">
<instrument name="kicker">
<kicker decay_numerator="4" decay_denominator="4" distend="0" click="1" endnote="0" version="1" decay="240" syncmode="0" noise="0.85" slope="1" dist="0" env="0.644" startnote="0" startfreq="229" endfreq="195" gain="1"/>
</instrument>
<eldata fres="0.56" ftype="3" fcut="929" fwet="1">
<elvol lspd_denominator="4" sustain="0.294" pdel="0" userwavefile="" dec="0.453" lamt="0" syncmode="0" latt="0" rel="0.1" amt="1" x100="0" att="0" lpdel="0" hold="0" lshp="2" lspd="0.0997" ctlenvamt="0" lspd_numerator="4"/>
<elcut lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="2" lspd="0.001" ctlenvamt="0" lspd_numerator="4"/>
<elres lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
</eldata>
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
<midiport inputcontroller="0" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
<fxchain numofeffects="6" enabled="1">
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="1" on="1">
<ladspacontrols ports="10">
<port02 data="0"/>
<port03 data="0"/>
<port04 data="2.07"/>
<port05 data="3.51"/>
<port06 data="-47.97"/>
<port07 data="-12.69"/>
<port08 data="-47.97"/>
<port09 data="-47.34"/>
<port010 data="-47.97"/>
<port011 data="9.99"/>
</ladspacontrols>
<key>
<attribute value="caps" name="file"/>
<attribute value="Eq2x2" name="plugin"/>
</key>
</effect>
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="0.5" on="0">
<ladspacontrols ports="4">
<port02 data="0.370265"/>
<port03 data="0"/>
<port04 data="0.9995"/>
<port05 data="0.10875"/>
</ladspacontrols>
<key>
<attribute value="caps" name="file"/>
<attribute value="Plate2x2" name="plugin"/>
</key>
</effect>
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="1" on="1">
<ladspacontrols ports="9">
<port07>
<data scale_type="log" value="0.4" id="6315252"/>
</port07>
<port08>
<data scale_type="log" value="2000.25" id="2498139"/>
</port08>
<port09 data="0"/>
<port010 data="1"/>
<port011 data="0.5"/>
<port012 data="1"/>
<port013 data="0"/>
<port014>
<data scale_type="log" value="659.34" id="5231681"/>
</port014>
<port015>
<data scale_type="log" value="4862.63" id="1579810"/>
</port015>
</ladspacontrols>
<key>
<attribute value="calf" name="file"/>
<attribute value="Reverb" name="plugin"/>
</key>
</effect>
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="0.18" on="1">
<ladspacontrols ports="13">
<port04 data="0"/>
<port05 data="1.02375"/>
<port06 data="0.96"/>
<port07 data="0.50125"/>
<port012 data="5.049"/>
<port013 data="10"/>
<port015>
<data scale_type="log" value="20000" id="8103466"/>
</port015>
<port016>
<data scale_type="log" value="10" id="4889780"/>
</port016>
<port017>
<data scale_type="log" value="20000" id="6261168"/>
</port017>
<port018>
<data scale_type="log" value="10" id="4037431"/>
</port018>
<port019>
<data scale_type="log" value="215.82" id="6293968"/>
</port019>
<port020 data="15.9973"/>
<port021>
<data scale_type="log" value="0.9999" id="2846145"/>
</port021>
</ladspacontrols>
<key>
<attribute value="calf" name="file"/>
<attribute value="Saturator" name="plugin"/>
</key>
</effect>
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="1" on="1">
<ladspacontrols ports="13">
<port04 data="0"/>
<port05 data="1.02375"/>
<port06 data="0.96"/>
<port07 data="1"/>
<port012 data="5.049"/>
<port013 data="10"/>
<port015>
<data scale_type="log" value="20000" id="7709628"/>
</port015>
<port016>
<data scale_type="log" value="10" id="7480205"/>
</port016>
<port017>
<data scale_type="log" value="20000" id="4036038"/>
</port017>
<port018>
<data scale_type="log" value="10" id="1042561"/>
</port018>
<port019>
<data scale_type="log" value="721.71" id="92193"/>
</port019>
<port020 data="1.31484"/>
<port021>
<data scale_type="log" value="0.100237" id="7520542"/>
</port021>
</ladspacontrols>
<key>
<attribute value="calf" name="file"/>
<attribute value="Saturator" name="plugin"/>
</key>
</effect>
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="1" on="1">
<ladspacontrols ports="10">
<port02 data="-47.97"/>
<port03 data="-10.8"/>
<port04 data="0"/>
<port05 data="0"/>
<port06 data="0"/>
<port07 data="0"/>
<port08 data="0"/>
<port09 data="0"/>
<port010 data="0.72"/>
<port011 data="2.52"/>
</ladspacontrols>
<key>
<attribute value="caps" name="file"/>
<attribute value="Eq2x2" name="plugin"/>
</key>
</effect>
</fxchain>
</instrumenttrack>
</instrumenttracksettings>
</lmms-project>

View File

@@ -16,10 +16,11 @@ DMG_BACKGROUND_IMG="dmg_branding.png"
cp "@CMAKE_SOURCE_DIR@/data/${DMG_BACKGROUND_IMG}" .
# you should not need to change these
OS_VER=`sw_vers -productVersion|cut -d"." -f1-2`
APP_LOWERCASE=$(echo $APP_NAME|tr '[:upper:]' '[:lower:]')
APP_EXE="${APP_NAME}.app/Contents/MacOS/${APP_LOWERCASE}"
VOL_NAME="${APP_NAME} ${VERSION}" # volume name will be "SuperCoolApp 1.0.0"
VOL_NAME="${APP_LOWERCASE}-${VERSION}-mac${OS_VER}" # volume name will be "SuperCoolApp 1.0.0"
DMG_TMP="${VOL_NAME}-temp.dmg"
DMG_FINAL="${VOL_NAME}.dmg" # final DMG name will be "SuperCoolApp 1.0.0.dmg"
STAGING_DIR="./Install" # we copy all our stuff into this dir

View File

@@ -75,68 +75,69 @@ public:
inline void setCoeffs( float freq )
{
// wc
const float wc = F_2PI * freq / m_sampleRate;
const float wc2 = wc * wc;
const float wc3 = wc2 * wc;
const double wc = D_2PI * freq;
const double wc2 = wc * wc;
const double wc3 = wc2 * wc;
m_wc4 = wc2 * wc2;
// k
const float k = wc / tan( wc * 0.5 );
const float k2 = k * k;
const float k3 = k2 * k;
const double k = wc / tan( D_PI * freq / m_sampleRate );
const double k2 = k * k;
const double k3 = k2 * k;
m_k4 = k2 * k2;
// a
static const double sqrt2 = sqrt( 2.0 );
const float sq_tmp1 = sqrt2 * wc3 * k;
const float sq_tmp2 = sqrt2 * wc * k3;
m_a = 1.0f / ( 4.0f * wc2 * k2 + 2.0f * sq_tmp1 + m_k4 + 2.0f * sq_tmp2 + m_wc4 );
const double sq_tmp1 = sqrt2 * wc3 * k;
const double sq_tmp2 = sqrt2 * wc * k3;
m_a = 1.0 / ( 4.0 * wc2 * k2 + 2.0 * sq_tmp1 + m_k4 + 2.0 * sq_tmp2 + m_wc4 );
// b
m_b1 = ( 4.0f * ( m_wc4 + sq_tmp1 - m_k4 - sq_tmp2 ) ) * m_a;
m_b2 = ( 6.0f * m_wc4 - 8.0f * wc2 * k2 + 6.0f * m_k4 ) * m_a;
m_b3 = ( 4.0f * ( m_wc4 - sq_tmp1 + sq_tmp2 - m_k4 ) ) * m_a;
m_b4 = ( m_k4 - 2.0f * sq_tmp1 + m_wc4 - 2.0f * sq_tmp2 + 4.0f * wc2 * k2 ) * m_a;
m_b1 = ( 4.0 * ( m_wc4 + sq_tmp1 - m_k4 - sq_tmp2 ) ) * m_a;
m_b2 = ( 6.0 * m_wc4 - 8.0 * wc2 * k2 + 6.0 * m_k4 ) * m_a;
m_b3 = ( 4.0 * ( m_wc4 - sq_tmp1 + sq_tmp2 - m_k4 ) ) * m_a;
m_b4 = ( m_k4 - 2.0 * sq_tmp1 + m_wc4 - 2.0 * sq_tmp2 + 4.0 * wc2 * k2 ) * m_a;
}
inline void setLowpass( float freq )
{
setCoeffs( freq );
m_a0 = m_wc4 * m_a;
m_a1 = 4.0f * m_a0;
m_a2 = 6.0f * m_a0;
m_a1 = 4.0 * m_a0;
m_a2 = 6.0 * m_a0;
}
inline void setHighpass( float freq )
{
setCoeffs( freq );
m_a0 = m_k4 * m_a;
m_a1 = 4.0f * m_a0;
m_a2 = 6.0f * m_a0;
m_a1 = -4.0 * m_a0;
m_a2 = 6.0 * m_a0;
}
inline float update( float in, ch_cnt_t ch )
{
const float a0in = m_a0 * in;
const float a1in = m_a1 * in;
const float out = m_z1[ch] + a0in;
const double x = in - ( m_z1[ch] * m_b1 ) - ( m_z2[ch] * m_b2 ) -
( m_z3[ch] * m_b3 ) - ( m_z4[ch] * m_b4 );
const double y = ( m_a0 * x ) + ( m_z1[ch] * m_a1 ) + ( m_z2[ch] * m_a2 ) +
( m_z3[ch] * m_a1 ) + ( m_z4[ch] * m_a0 );
m_z4[ch] = m_z3[ch];
m_z3[ch] = m_z2[ch];
m_z2[ch] = m_z1[ch];
m_z1[ch] = x;
m_z1[ch] = a1in + m_z2[ch] - ( m_b1 * out );
m_z2[ch] = ( m_a2 * in ) + m_z3[ch] - ( m_b2 * out );
m_z3[ch] = a1in + m_z4[ch] - ( m_b3 * out );
m_z4[ch] = a0in - ( m_b4 * out );
return out;
return y;
}
private:
float m_sampleRate;
float m_wc4;
float m_k4;
float m_a, m_a0, m_a1, m_a2;
float m_b1, m_b2, m_b3, m_b4;
double m_wc4;
double m_k4;
double m_a, m_a0, m_a1, m_a2;
double m_b1, m_b2, m_b3, m_b4;
typedef float frame[CHANNELS];
typedef double frame[CHANNELS];
frame m_z1, m_z2, m_z3, m_z4;
};
typedef LinkwitzRiley<2> StereoLinkwitzRiley;

363
include/Delay.h Normal file
View File

@@ -0,0 +1,363 @@
/*
* Delay.h - Delay effect objects to use as building blocks in DSP
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 DELAY_H
#define DELAY_H
#include "lmms_basics.h"
#include "lmms_math.h"
#include "interpolation.h"
#include "MemoryManager.h"
// brief usage
// Classes:
// CombFeedback: a feedback comb filter - basically a simple delay line, makes a comb shape in the freq response
// CombFeedfwd: a feed-forward comb filter - an "inverted" comb filter, can be combined with CombFeedback to create a net allpass if negative gain is used
// CombFeedbackDualtap: same as CombFeedback but takes two delay values
// AllpassDelay: an allpass delay - combines feedback and feed-forward - has flat frequency response
// all classes are templated with channel count, any arbitrary channel count can be used for each fx
// Methods (for all classes):
// setDelay sets delay amount in frames. It's up to you to make this samplerate-agnostic.
// Fractions are allowed - linear interpolation is used to deal with them
// CombFeedbackDualTap is a special case: it requires 2 delay times
// setMaxDelay (re)sets the maximum allowed delay, in frames
// NOTE: for performance reasons, there's no bounds checking at setDelay, so make sure you set maxDelay >= delay!
// clearHistory clears the delay buffer
// setGain sets the feedback/feed-forward gain, in linear amplitude, negative values are allowed
// 1.0 is full feedback/feed-forward, -1.0 is full negative feedback/feed-forward
// update runs the fx for one frame - takes as arguments input and number of channel to run, returns output
template<ch_cnt_t CHANNELS>
class CombFeedback
{
public:
typedef double frame[CHANNELS];
CombFeedback( int maxDelay ) :
m_size( maxDelay ),
m_position( 0 ),
m_feedBack( 0.0 ),
m_delay( 0 ),
m_fraction( 0.0 )
{
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~CombFeedback()
{
MM_FREE( m_buffer );
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
MM_FREE( m_buffer );
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
m_position %= m_size;
}
inline void clearHistory()
{
memset( m_buffer, 0, sizeof( frame ) * m_size );
}
inline void setDelay( double delay )
{
m_delay = static_cast<int>( ceil( delay ) );
m_fraction = 1.0 - ( delay - floor( delay ) );
}
inline void setGain( double gain )
{
m_gain = gain;
}
inline double update( double in, ch_cnt_t ch )
{
int readPos = m_position - m_delay;
if( readPos < 0 ) { readPos += m_size; }
const double y = linearInterpolate( m_buffer[readPos][ch], m_buffer[( readPos + 1 ) % m_size][ch], m_fraction );
++m_position %= m_size;
m_buffer[m_position][ch] = in + m_gain * y;
return y;
}
private:
frame * m_buffer;
int m_size;
int m_position;
double m_gain;
int m_delay;
double m_fraction;
};
template<ch_cnt_t CHANNELS>
class CombFeedfwd
{
typedef double frame[CHANNELS];
CombFeedfwd( int maxDelay ) :
m_size( maxDelay ),
m_position( 0 ),
m_feedBack( 0.0 ),
m_delay( 0 ),
m_fraction( 0.0 )
{
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~CombFeedfwd()
{
MM_FREE( m_buffer );
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
MM_FREE( m_buffer );
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
m_position %= m_size;
}
inline void clearHistory()
{
memset( m_buffer, 0, sizeof( frame ) * m_size );
}
inline void setDelay( double delay )
{
m_delay = static_cast<int>( ceil( delay ) );
m_fraction = 1.0 - ( delay - floor( delay ) );
}
inline void setGain( double gain )
{
m_gain = gain;
}
inline double update( double in, ch_cnt_t ch )
{
int readPos = m_position - m_delay;
if( readPos < 0 ) { readPos += m_size; }
const double y = linearInterpolate( m_buffer[readPos][ch], m_buffer[( readPos + 1 ) % m_size][ch], m_fraction ) + in * m_gain;
++m_position %= m_size;
m_buffer[m_position][ch] = in;
return y;
}
private:
frame * m_buffer;
int m_size;
int m_position;
double m_gain;
int m_delay;
double m_fraction;
};
template<ch_cnt_t CHANNELS>
class CombFeedbackDualtap
{
typedef double frame[CHANNELS];
CombFeedbackDualtap( int maxDelay ) :
m_size( maxDelay ),
m_position( 0 ),
m_feedBack( 0.0 ),
m_delay( 0 ),
m_fraction( 0.0 )
{
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~CombFeedbackDualtap()
{
MM_FREE( m_buffer );
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
MM_FREE( m_buffer );
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
m_position %= m_size;
}
inline void clearHistory()
{
memset( m_buffer, 0, sizeof( frame ) * m_size );
}
inline void setDelays( double delay1, double delay2 )
{
m_delay1 = static_cast<int>( ceil( delay1 ) );
m_fraction1 = 1.0 - ( delay1 - floor( delay1 ) );
m_delay2 = static_cast<int>( ceil( delay2 ) );
m_fraction2 = 1.0 - ( delay2 - floor( delay2 ) );
}
inline void setGain( double gain )
{
m_gain = gain;
}
inline double update( double in, ch_cnt_t ch )
{
int readPos1 = m_position - m_delay1;
if( readPos1 < 0 ) { readPos1 += m_size; }
int readPos2 = m_position - m_delay2;
if( readPos2 < 0 ) { readPos2 += m_size; }
const double y = linearInterpolate( m_buffer[readPos1][ch], m_buffer[( readPos1 + 1 ) % m_size][ch], m_fraction1 ) +
linearInterpolate( m_buffer[readPos2][ch], m_buffer[( readPos2 + 1 ) % m_size][ch], m_fraction2 );
++m_position %= m_size;
m_buffer[m_position][ch] = in + m_gain * y;
return y;
}
private:
frame * m_buffer;
int m_size;
int m_position;
double m_gain;
int m_delay1;
int m_delay2;
double m_fraction1;
double m_fraction2;
};
template<ch_cnt_t CHANNELS>
class AllpassDelay
{
public:
typedef double frame[CHANNELS];
AllpassDelay( int maxDelay ) :
m_size( maxDelay ),
m_position( 0 ),
m_feedBack( 0.0 ),
m_delay( 0 ),
m_fraction( 0.0 )
{
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~AllpassDelay()
{
MM_FREE( m_buffer );
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
MM_FREE( m_buffer );
m_buffer = MM_ALLOC( frame, maxDelay );
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
m_position %= m_size;
}
inline void clearHistory()
{
memset( m_buffer, 0, sizeof( frame ) * m_size );
}
inline void setDelay( double delay )
{
m_delay = static_cast<int>( ceil( delay ) );
m_fraction = 1.0 - ( delay - floor( delay ) );
}
inline void setGain( double gain )
{
m_gain = gain;
}
inline double update( double in, ch_cnt_t ch )
{
int readPos = m_position - m_delay;
if( readPos < 0 ) { readPos += m_size; }
const double y = linearInterpolate( m_buffer[readPos][ch], m_buffer[( readPos + 1 ) % m_size][ch], m_fraction ) + in * -m_gain;
const double x = in + m_gain * y;
++m_position %= m_size;
m_buffer[m_position][ch] = x;
return y;
}
private:
frame * m_buffer;
int m_size;
int m_position;
double m_gain;
int m_delay;
double m_fraction;
};
// convenience typedefs for stereo effects
typedef CombFeedback<2> StereoCombFeedback;
typedef CombFeedfwd<2> StereoCombFeedfwd;
typedef CombFeedbackDualtap<2> StereoCombFeedbackDualtap;
typedef AllpassDelay<2> StereoAllpassDelay;
#endif

View File

@@ -57,7 +57,7 @@
class TextFloat;
class Fader : public QWidget, public FloatModelView
class EXPORT Fader : public QWidget, public FloatModelView
{
Q_OBJECT
public:
@@ -103,7 +103,7 @@ private:
float fRange = m_model->maxValue() - m_model->minValue();
float realVal = m_model->value() - m_model->minValue();
return height() - ( ( height() - ( *s_knob ).height() ) * ( realVal / fRange ) );
return height() - ( ( height() - m_knob->height() ) * ( realVal / fRange ) );
}
FloatModel * m_model;

View File

@@ -148,9 +148,11 @@ public:
private:
FloatModel m_volumeModel;
FloatModel m_panningModel;
AudioPort m_audioPort;
friend class SampleTrackView;
} ;
@@ -181,6 +183,7 @@ private:
EffectRackView * m_effectRack;
QWidget * m_effWindow;
Knob * m_volumeKnob;
Knob * m_panningKnob;
} ;

View File

@@ -71,9 +71,9 @@ inline float cubicInterpolate( float v0, float v1, float v2, float v3, float x )
float frcu = frsq*v0;
float t1 = v3 + 3*v1;
return( v1 + 0.5f * frcu + x * ( v2 - frcu * ( 1.0f/6.0f ) -
t1 * ( 1.0f/6.0f ) - v0 / 3.0f ) + frsq * x * ( t1 *
( 1.0f/6.0f ) - 0.5f * v2 ) + frsq * ( 0.5f * v2 - v1 ) );
return( v1 + fastFmaf( 0.5f, frcu, x ) * ( v2 - frcu * ( 1.0f/6.0f ) -
fastFmaf( t1, ( 1.0f/6.0f ), -v0 ) * ( 1.0f/3.0f ) ) + frsq * x * ( t1 *
( 1.0f/6.0f ) - 0.5f * v2 ) + frsq * fastFmaf( 0.5f, v2, -v1 ) );
}
@@ -102,7 +102,7 @@ inline float optimalInterpolate( float v0, float v1, float x )
const float c2 = even * -0.004541102062639801;
const float c3 = odd * -1.57015627178718420;
return ( ( c3*z + c2 ) * z + c1 ) * z + c0;
return fastFmaf( fastFmaf( fastFmaf( c3, z, c2 ), z, c1 ), z, c0 );
}
@@ -119,7 +119,7 @@ inline float optimal4pInterpolate( float v0, float v1, float v2, float v3, float
const float c2 = even1 * -0.246185007019907091 + even2 * 0.24614027139700284;
const float c3 = odd1 * -0.36030925263849456 + odd2 * 0.10174985775982505;
return ( ( c3*z + c2 ) * z + c1 ) * z + c0;
return fastFmaf( fastFmaf( fastFmaf( c3, z, c2 ), z, c1 ), z, c0 );
}
@@ -130,7 +130,7 @@ inline float lagrangeInterpolate( float v0, float v1, float v2, float v3, float
const float c1 = v2 - v0 * ( 1.0f / 3.0f ) - v1 * 0.5f - v3 * ( 1.0f / 6.0f );
const float c2 = 0.5f * (v0 + v2) - v1;
const float c3 = ( 1.0f/6.0f ) * ( v3 - v0 ) + 0.5f * ( v1 - v2 );
return ( ( c3*x + c2 ) * x + c1 ) * x + c0;
return fastFmaf( fastFmaf( fastFmaf( c3, x, c2 ), x, c1 ), x, c0 );
}

View File

@@ -6,9 +6,11 @@ ADD_SUBDIRECTORY(Bitcrush)
ADD_SUBDIRECTORY(carlabase)
ADD_SUBDIRECTORY(carlapatchbay)
ADD_SUBDIRECTORY(carlarack)
ADD_SUBDIRECTORY(CrossoverEQ)
ADD_SUBDIRECTORY(delay)
ADD_SUBDIRECTORY(DualFilter)
ADD_SUBDIRECTORY(dynamics_processor)
ADD_SUBDIRECTORY(Eq)
ADD_SUBDIRECTORY(flanger)
ADD_SUBDIRECTORY(flp_import)
ADD_SUBDIRECTORY(HydrogenImport)

View File

@@ -0,0 +1,3 @@
INCLUDE(BuildPlugin)
BUILD_PLUGIN(crossovereq CrossoverEQ.cpp CrossoverEQControls.cpp CrossoverEQControlDialog.cpp MOCFILES CrossoverEQControls.h CrossoverEQControlDialog.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")

View File

@@ -0,0 +1,219 @@
/*
* CrossoverEQ.cpp - A native 4-band Crossover Equalizer
* good for simulating tonestacks or simple peakless (flat-band) equalization
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 "CrossoverEQ.h"
#include "lmms_math.h"
#include "embed.cpp"
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT crossovereq_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Crossover Equalizer",
QT_TRANSLATE_NOOP( "pluginBrowser", "A 4-band Crossover Equalizer" ),
"Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>",
0x0100,
Plugin::Effect,
new PluginPixmapLoader( "logo" ),
NULL,
NULL
};
}
CrossoverEQEffect::CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ) :
Effect( &crossovereq_plugin_descriptor, parent, key ),
m_controls( this ),
m_sampleRate( Engine::mixer()->processingSampleRate() ),
m_lp1( m_sampleRate ),
m_lp2( m_sampleRate ),
m_lp3( m_sampleRate ),
m_hp2( m_sampleRate ),
m_hp3( m_sampleRate ),
m_hp4( m_sampleRate ),
m_needsUpdate( true )
{
m_tmp1 = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() );
m_tmp2 = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() );
m_work = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() );
}
CrossoverEQEffect::~CrossoverEQEffect()
{
MM_FREE( m_tmp1 );
MM_FREE( m_tmp2 );
MM_FREE( m_work );
}
void CrossoverEQEffect::sampleRateChanged()
{
m_sampleRate = Engine::mixer()->processingSampleRate();
m_lp1.setSampleRate( m_sampleRate );
m_lp2.setSampleRate( m_sampleRate );
m_lp3.setSampleRate( m_sampleRate );
m_hp2.setSampleRate( m_sampleRate );
m_hp3.setSampleRate( m_sampleRate );
m_hp4.setSampleRate( m_sampleRate );
m_needsUpdate = true;
}
bool CrossoverEQEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
{
if( !isEnabled() || !isRunning () )
{
return( false );
}
// filters update
if( m_needsUpdate || m_controls.m_xover12.isValueChanged() )
{
m_lp1.setLowpass( m_controls.m_xover12.value() );
m_lp1.clearHistory();
m_hp2.setHighpass( m_controls.m_xover12.value() );
m_hp2.clearHistory();
}
if( m_needsUpdate || m_controls.m_xover23.isValueChanged() )
{
m_lp2.setLowpass( m_controls.m_xover23.value() );
m_lp2.clearHistory();
m_hp3.setHighpass( m_controls.m_xover23.value() );
m_hp3.clearHistory();
}
if( m_needsUpdate || m_controls.m_xover34.isValueChanged() )
{
m_lp3.setLowpass( m_controls.m_xover34.value() );
m_lp3.clearHistory();
m_hp4.setHighpass( m_controls.m_xover34.value() );
m_hp4.clearHistory();
}
// gain values update
if( m_needsUpdate || m_controls.m_gain1.isValueChanged() )
{
m_gain1 = dbvToAmp( m_controls.m_gain1.value() );
}
if( m_needsUpdate || m_controls.m_gain2.isValueChanged() )
{
m_gain2 = dbvToAmp( m_controls.m_gain2.value() );
}
if( m_needsUpdate || m_controls.m_gain3.isValueChanged() )
{
m_gain3 = dbvToAmp( m_controls.m_gain3.value() );
}
if( m_needsUpdate || m_controls.m_gain4.isValueChanged() )
{
m_gain4 = dbvToAmp( m_controls.m_gain4.value() );
}
// mute values update
const bool mute1 = m_controls.m_mute1.value();
const bool mute2 = m_controls.m_mute2.value();
const bool mute3 = m_controls.m_mute3.value();
const bool mute4 = m_controls.m_mute4.value();
m_needsUpdate = false;
memset( m_work, 0, sizeof( sampleFrame ) * frames );
// run temp bands
for( int f = 0; f < frames; ++f )
{
m_tmp1[f][0] = m_lp2.update( buf[f][0], 0 );
m_tmp1[f][1] = m_lp2.update( buf[f][1], 1 );
m_tmp2[f][0] = m_hp3.update( buf[f][0], 0 );
m_tmp2[f][1] = m_hp3.update( buf[f][1], 1 );
}
// run band 1
if( ! mute1 )
{
for( int f = 0; f < frames; ++f )
{
m_work[f][0] += m_lp1.update( m_tmp1[f][0], 0 ) * m_gain1;
m_work[f][1] += m_lp1.update( m_tmp1[f][1], 1 ) * m_gain1;
}
}
// run band 2
if( ! mute2 )
{
for( int f = 0; f < frames; ++f )
{
m_work[f][0] += m_hp2.update( m_tmp1[f][0], 0 ) * m_gain2;
m_work[f][1] += m_hp2.update( m_tmp1[f][1], 1 ) * m_gain2;
}
}
// run band 3
if( ! mute3 )
{
for( int f = 0; f < frames; ++f )
{
m_work[f][0] += m_lp3.update( m_tmp2[f][0], 0 ) * m_gain3;
m_work[f][1] += m_lp3.update( m_tmp2[f][1], 1 ) * m_gain3;
}
}
// run band 4
if( ! mute4 )
{
for( int f = 0; f < frames; ++f )
{
m_work[f][0] += m_hp4.update( m_tmp2[f][0], 0 ) * m_gain4;
m_work[f][1] += m_hp4.update( m_tmp2[f][1], 1 ) * m_gain4;
}
}
const float d = dryLevel();
const float w = wetLevel();
double outSum = 0.0;
for( int f = 0; f < frames; ++f )
{
buf[f][0] = d * buf[f][0] + w * m_work[f][0];
buf[f][1] = d * buf[f][1] + w * m_work[f][1];
outSum = buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
}
checkGate( outSum );
return isRunning();
}
extern "C"
{
// necessary for getting instance out of shared lib
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
{
return new CrossoverEQEffect( parent, static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>( data ) );
}
}

View File

@@ -0,0 +1,77 @@
/*
* CrossoverEQ.h - A native 4-band Crossover Equalizer
* good for simulating tonestacks or simple peakless (flat-band) equalization
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 CROSSOVEREQ_H
#define CROSSOVEREQ_H
#include "Effect.h"
#include "CrossoverEQControls.h"
#include "ValueBuffer.h"
#include "lmms_math.h"
#include "BasicFilters.h"
class CrossoverEQEffect : public Effect
{
public:
CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key );
virtual ~CrossoverEQEffect();
virtual bool processAudioBuffer( sampleFrame* buf, const fpp_t frames );
virtual EffectControls* controls()
{
return &m_controls;
}
private:
CrossoverEQControls m_controls;
void sampleRateChanged();
float m_sampleRate;
float m_gain1;
float m_gain2;
float m_gain3;
float m_gain4;
StereoLinkwitzRiley m_lp1;
StereoLinkwitzRiley m_lp2;
StereoLinkwitzRiley m_lp3;
StereoLinkwitzRiley m_hp2;
StereoLinkwitzRiley m_hp3;
StereoLinkwitzRiley m_hp4;
sampleFrame * m_tmp1;
sampleFrame * m_tmp2;
sampleFrame * m_work;
bool m_needsUpdate;
friend class CrossoverEQControls;
};
#endif

View File

@@ -0,0 +1,115 @@
/*
* CrossoverEQControlDialog.cpp - A native 4-band Crossover Equalizer
* good for simulating tonestacks or simple peakless (flat-band) equalization
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 <QLayout>
#include <QLabel>
#include "CrossoverEQControlDialog.h"
#include "CrossoverEQControls.h"
#include "embed.h"
#include "ToolTip.h"
#include "LedCheckbox.h"
#include "Knob.h"
#include "Fader.h"
CrossoverEQControlDialog::CrossoverEQControlDialog( CrossoverEQControls * controls ) :
EffectControlDialog( controls )
{
setAutoFillBackground( true );
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
setPalette( pal );
setFixedSize( 167, 188 );
// knobs
Knob * xover12 = new Knob( knobBright_26, this );
xover12->move( 29, 15 );
xover12->setModel( & controls->m_xover12 );
xover12->setLabel( "1/2" );
xover12->setHintText( tr( "Band 1/2 Crossover:" ), " Hz" );
Knob * xover23 = new Knob( knobBright_26, this );
xover23->move( 69, 15 );
xover23->setModel( & controls->m_xover23 );
xover23->setLabel( "2/3" );
xover23->setHintText( tr( "Band 2/3 Crossover:" ), " Hz" );
Knob * xover34 = new Knob( knobBright_26, this );
xover34->move( 109, 15 );
xover34->setModel( & controls->m_xover34 );
xover34->setLabel( "3/4" );
xover34->setHintText( tr( "Band 3/4 Crossover:" ), " Hz" );
m_fader_bg = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_bg" ) );
m_fader_empty = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_empty" ) );
m_fader_knob = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_knob2" ) );
// faders
Fader * gain1 = new Fader( &controls->m_gain1, "Band 1 Gain", this,
&m_fader_bg, &m_fader_empty, &m_fader_knob );
gain1->move( 7, 56 );
gain1->setDisplayConversion( false );
gain1->setHintText( tr( "Band 1 Gain:" ), " dBV" );
Fader * gain2 = new Fader( &controls->m_gain2, "Band 2 Gain", this,
&m_fader_bg, &m_fader_empty, &m_fader_knob );
gain2->move( 47, 56 );
gain2->setDisplayConversion( false );
gain2->setHintText( tr( "Band 2 Gain:" ), " dBV" );
Fader * gain3 = new Fader( &controls->m_gain3, "Band 3 Gain", this,
&m_fader_bg, &m_fader_empty, &m_fader_knob );
gain3->move( 87, 56 );
gain3->setDisplayConversion( false );
gain3->setHintText( tr( "Band 3 Gain:" ), " dBV" );
Fader * gain4 = new Fader( &controls->m_gain4, "Band 4 Gain", this,
&m_fader_bg, &m_fader_empty, &m_fader_knob );
gain4->move( 127, 56 );
gain4->setDisplayConversion( false );
gain4->setHintText( tr( "Band 4 Gain:" ), " dBV" );
// leds
LedCheckBox * mute1 = new LedCheckBox( "M", this, tr( "Band 1 Mute" ), LedCheckBox::Red );
mute1->move( 11, 158 );
mute1->setModel( & controls->m_mute1 );
ToolTip::add( mute1, tr( "Mute Band 1" ) );
LedCheckBox * mute2 = new LedCheckBox( "M", this, tr( "Band 2 Mute" ), LedCheckBox::Red );
mute2->move( 51, 158 );
mute2->setModel( & controls->m_mute2 );
ToolTip::add( mute2, tr( "Mute Band 2" ) );
LedCheckBox * mute3 = new LedCheckBox( "M", this, tr( "Band 3 Mute" ), LedCheckBox::Red );
mute3->move( 91, 158 );
mute3->setModel( & controls->m_mute3 );
ToolTip::add( mute3, tr( "Mute Band 3" ) );
LedCheckBox * mute4 = new LedCheckBox( "M", this, tr( "Band 4 Mute" ), LedCheckBox::Red );
mute4->move( 131, 158 );
mute4->setModel( & controls->m_mute4 );
ToolTip::add( mute4, tr( "Mute Band 4" ) );
}

View File

@@ -0,0 +1,50 @@
/*
* CrossoverEQControlDialog.h - A native 4-band Crossover Equalizer
* good for simulating tonestacks or simple peakless (flat-band) equalization
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 CROSSOVEREQ_CONTROL_DIALOG_H
#define CROSSOVEREQ_CONTROL_DIALOG_H
#include <QPixmap>
#include "EffectControlDialog.h"
class CrossoverEQControls;
class CrossoverEQControlDialog : public EffectControlDialog
{
Q_OBJECT
public:
CrossoverEQControlDialog( CrossoverEQControls * controls );
virtual ~CrossoverEQControlDialog()
{
}
private:
QPixmap m_fader_bg;
QPixmap m_fader_empty;
QPixmap m_fader_knob;
};
#endif

View File

@@ -0,0 +1,116 @@
/*
* CrossoverEQControls.cpp - A native 4-band Crossover Equalizer
* good for simulating tonestacks or simple peakless (flat-band) equalization
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 "CrossoverEQControls.h"
#include "CrossoverEQ.h"
CrossoverEQControls::CrossoverEQControls( CrossoverEQEffect * eff ) :
EffectControls( eff ),
m_effect( eff ),
m_xover12( 125.f, 50.f, 10000.f, 1.0f, this, "Band 1/2 Crossover" ),
m_xover23( 1250.f, 50.f, 20000.f, 1.0f, this, "Band 2/3 Crossover" ),
m_xover34( 5000.f, 50.f, 20000.f, 1.0f, this, "Band 3/4 Crossover" ),
m_gain1( 0.f, -60.f, 30.f, 0.1f, this, "Band 1 Gain" ),
m_gain2( 0.f, -60.f, 30.f, 0.1f, this, "Band 2 Gain" ),
m_gain3( 0.f, -60.f, 30.f, 0.1f, this, "Band 3 Gain" ),
m_gain4( 0.f, -60.f, 30.f, 0.1f, this, "Band 4 Gain" ),
m_mute1( false, this, "Mute Band 1" ),
m_mute2( false, this, "Mute Band 2" ),
m_mute3( false, this, "Mute Band 3" ),
m_mute4( false, this, "Mute Band 4" )
{
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) );
connect( &m_xover12, SIGNAL( dataChanged() ), this, SLOT( xover12Changed() ) );
connect( &m_xover23, SIGNAL( dataChanged() ), this, SLOT( xover23Changed() ) );
connect( &m_xover34, SIGNAL( dataChanged() ), this, SLOT( xover34Changed() ) );
m_xover12.setScaleLogarithmic( true );
m_xover23.setScaleLogarithmic( true );
m_xover34.setScaleLogarithmic( true );
}
void CrossoverEQControls::saveSettings( QDomDocument & doc, QDomElement & elem )
{
m_xover12.saveSettings( doc, elem, "xover12" );
m_xover23.saveSettings( doc, elem, "xover23" );
m_xover34.saveSettings( doc, elem, "xover34" );
m_gain1.saveSettings( doc, elem, "gain1" );
m_gain2.saveSettings( doc, elem, "gain2" );
m_gain3.saveSettings( doc, elem, "gain3" );
m_gain4.saveSettings( doc, elem, "gain4" );
m_mute1.saveSettings( doc, elem, "mute1" );
m_mute2.saveSettings( doc, elem, "mute2" );
m_mute3.saveSettings( doc, elem, "mute3" );
m_mute4.saveSettings( doc, elem, "mute4" );
}
void CrossoverEQControls::loadSettings( const QDomElement & elem )
{
m_xover12.loadSettings( elem, "xover12" );
m_xover23.loadSettings( elem, "xover23" );
m_xover34.loadSettings( elem, "xover34" );
m_gain1.loadSettings( elem, "gain1" );
m_gain2.loadSettings( elem, "gain2" );
m_gain3.loadSettings( elem, "gain3" );
m_gain4.loadSettings( elem, "gain4" );
m_mute1.loadSettings( elem, "mute1" );
m_mute2.loadSettings( elem, "mute2" );
m_mute3.loadSettings( elem, "mute3" );
m_mute4.loadSettings( elem, "mute4" );
m_effect->m_needsUpdate = true;
}
void CrossoverEQControls::xover12Changed()
{
float v = m_xover12.value();
if( m_xover23.value() < v ) { m_xover23.setValue( v ); }
if( m_xover34.value() < v ) { m_xover34.setValue( v ); }
}
void CrossoverEQControls::xover23Changed()
{
float v = m_xover23.value();
if( m_xover12.value() > v ) { m_xover12.setValue( v ); }
if( m_xover34.value() < v ) { m_xover34.setValue( v ); }
}
void CrossoverEQControls::xover34Changed()
{
float v = m_xover34.value();
if( m_xover12.value() > v ) { m_xover12.setValue( v ); }
if( m_xover23.value() > v ) { m_xover23.setValue( v ); }
}
void CrossoverEQControls::sampleRateChanged()
{
m_effect->sampleRateChanged();
}

View File

@@ -0,0 +1,86 @@
/*
* CrossoverEQControls.h - A native 4-band Crossover Equalizer
* good for simulating tonestacks or simple peakless (flat-band) equalization
*
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - http://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 CROSSOVEREQ_CONTROLS_H
#define CROSSOVEREQ_CONTROLS_H
#include "EffectControls.h"
#include "CrossoverEQControlDialog.h"
class CrossoverEQEffect;
class CrossoverEQControls : public EffectControls
{
Q_OBJECT
public:
CrossoverEQControls( CrossoverEQEffect * eff );
virtual ~CrossoverEQControls() {}
virtual void saveSettings( QDomDocument & doc, QDomElement & elem );
virtual void loadSettings( const QDomElement & elem );
inline virtual QString nodeName() const
{
return( "crossoevereqcontrols" );
}
virtual int controlCount()
{
return( 11 );
}
virtual EffectControlDialog * createView()
{
return( new CrossoverEQControlDialog( this ) );
}
private slots:
void xover12Changed();
void xover23Changed();
void xover34Changed();
void sampleRateChanged();
private:
CrossoverEQEffect * m_effect;
FloatModel m_xover12;
FloatModel m_xover23;
FloatModel m_xover34;
FloatModel m_gain1;
FloatModel m_gain2;
FloatModel m_gain3;
FloatModel m_gain4;
BoolModel m_mute1;
BoolModel m_mute2;
BoolModel m_mute3;
BoolModel m_mute4;
friend class CrossoverEQControlDialog;
friend class CrossoverEQEffect;
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

View File

@@ -39,7 +39,7 @@ DualFilterControls::DualFilterControls( DualFilterEffect* effect ) :
m_enabled1Model( true, this, tr( "Filter 1 enabled" ) ),
m_filter1Model( this, tr( "Filter 1 type" ) ),
m_cut1Model( 7000.0f, 1.0f, 14000.0f, 1.0f, this, tr( "Cutoff 1 frequency" ) ),
m_cut1Model( 7000.0f, 1.0f, 20000.0f, 1.0f, this, tr( "Cutoff 1 frequency" ) ),
m_res1Model( 0.5, BasicFilters<0>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance 1" ) ),
m_gain1Model( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Gain 1" ) ),
@@ -47,7 +47,7 @@ DualFilterControls::DualFilterControls( DualFilterEffect* effect ) :
m_enabled2Model( true, this, tr( "Filter 2 enabled" ) ),
m_filter2Model( this, tr( "Filter 2 type" ) ),
m_cut2Model( 7000.0f, 1.0f, 14000.0f, 1.0f, this, tr( "Cutoff 2 frequency" ) ),
m_cut2Model( 7000.0f, 1.0f, 20000.0f, 1.0f, this, tr( "Cutoff 2 frequency" ) ),
m_res2Model( 0.5, BasicFilters<0>::minQ(), 10.0, 0.01, this, tr( "Q/Resonance 2" ) ),
m_gain2Model( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Gain 2" ) )
{

View File

@@ -0,0 +1,6 @@
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS})
LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS})
LINK_LIBRARIES(${FFTW3F_LIBRARIES})
BUILD_PLUGIN(eq EqEffect.cpp EqControls.cpp EqControlsDialog.cpp EqFilter.h EqParameterWidget.cpp EqFader.h EqSpectrumView.h
MOCFILES EqControls.h EqParameterWidget.h EqFader.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")

195
plugins/Eq/EqControls.cpp Normal file
View File

@@ -0,0 +1,195 @@
/*
* eqcontrols.cpp - defination of EqControls class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 <QtXml/QDomElement>
#include "EqControls.h"
#include "EqEffect.h"
EqControls::EqControls( EqEffect *effect ) :
EffectControls( effect ),
m_effect( effect ),
m_inGainModel( 1.0, 0.0, 2.0, 0.001, this, tr( "Input gain") ),
m_outGainModel( 1.0, 0.0, 2.0, 0.001, this, tr( "Output gain" ) ),
m_lowShelfGainModel( 0.0 , -40, 40, 0.001, this, tr( "Low shelf gain" ) ),
m_para1GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 1 gain" ) ),
m_para2GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 2 gain" ) ),
m_para3GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 3 gain" ) ),
m_para4GainModel( 0.0 , -40, 40, 0.001, this, tr( "Peak 4 gain" ) ),
m_highShelfGainModel( 0.0 , -40, 40, 0.001, this, tr( "High Shelf gain" ) ),
m_hpResModel( 0.707,0.003, 10.0 , 0.001, this, tr( "HP res" ) ),
m_lowShelfResModel( 1.4,0.0, 10.0 , 0.001, this , tr( "Low Shelf res" ) ),
m_para1ResModel( 1.4 ,0.55, 10.0 , 0.001, this , tr( "Peak 1 res" ) ),
m_para2ResModel( 1.4, 0.55, 10.0 , 0.001, this , tr( "Peak 2 res" ) ),
m_para3ResModel( 1.4, 0.55, 10.0 , 0.001, this , tr( "Peak 3 res" ) ),
m_para4ResModel( 1.4, 0.55, 10.0 , 0.001, this , tr( "Peak 4 res" ) ),
m_highShelfResModel( 1.4, 0.001, 10.0 , 0.001, this , tr( "High Shelf res" ) ),
m_lpResModel( 0.707,0.003, 10.0 , 0.001, this , tr( "LP res" ) ),
m_hpFeqModel( 31.0, 30.0, 20000, 0.001, this , tr( "HP freq" ) ),
m_lowShelfFreqModel( 80.0, 25.0, 20000, 0.001, this , tr( "Low Shelf freq" ) ),
m_para1FreqModel( 120.0, 27.0, 20000, 0.001, this , tr( "Peak 1 freq" ) ),
m_para2FreqModel( 250.0, 27.0, 20000, 0.001, this, tr( "Peak 2 freq" ) ),
m_para3FreqModel( 2000.0, 27.0, 20000, 0.001, this , tr( "Peak 3 freq" ) ),
m_para4FreqModel( 4000.0, 27.0, 20000, 0.001, this , tr( "Peak 4 freq" ) ),
m_highShelfFreqModel( 12000.0, 27.0, 20000, 0.001, this , tr( "High shelf freq" ) ),
m_lpFreqModel( 18000.0, 27.0, 20000, 0.001, this , tr( "LP freq" ) ),
m_hpActiveModel( false, this , tr( "HP active" ) ),
m_lowShelfActiveModel( false, this , tr( "Low shelf active" ) ),
m_para1ActiveModel(false, this , tr( "Peak 1 active" ) ),
m_para2ActiveModel( false, this , tr( "Peak 2 active" ) ),
m_para3ActiveModel( false, this , tr( "Peak 3 active" ) ),
m_para4ActiveModel( false, this , tr( "Peak 4 active" ) ),
m_highShelfActiveModel( false, this , tr( "High shelf active" ) ),
m_lpActiveModel( false, this , tr( "LP active" ) ),
m_lp12Model( false, this , tr( "LP 12" ) ),
m_lp24Model( false, this , tr( "LP 24" ) ),
m_lp48Model( false, this , tr( "LP 48" ) ),
m_hp12Model( false, this , tr( "HP 12" ) ),
m_hp24Model( false, this , tr( "HP 24" ) ),
m_hp48Model( false, this , tr( "HP 48" ) ),
m_analyzeModel( true, this , tr( "Analyze enable" ) ),
m_lpTypeModel( 0,0,2,this, tr( "low pass type") ) ,
m_hpTypeModel( 0,0,2,this, tr( "high pass type") )
{
m_hpFeqModel.setScaleLogarithmic( true );
m_lowShelfFreqModel.setScaleLogarithmic( true );
m_para1FreqModel.setScaleLogarithmic( true );
m_para2FreqModel.setScaleLogarithmic( true );
m_para3FreqModel.setScaleLogarithmic( true );
m_para4FreqModel.setScaleLogarithmic( true );
m_highShelfFreqModel.setScaleLogarithmic( true );
m_lpFreqModel.setScaleLogarithmic( true );
m_para1GainModel.setScaleLogarithmic( true );
m_inPeakL = 0;
m_inPeakR = 0;
m_outPeakL = 0;
m_outPeakR = 0;
m_lowShelfPeakL = 0; m_lowShelfPeakR = 0;
m_para1PeakL = 0; m_para1PeakR = 0;
m_para2PeakL = 0; m_para2PeakR = 0;
m_para3PeakL = 0; m_para3PeakR = 0;
m_para4PeakL = 0; m_para4PeakR = 0;
m_highShelfPeakL = 0; m_highShelfPeakR = 0;
m_inProgress = false;
}
void EqControls::loadSettings( const QDomElement &_this )
{
m_inGainModel.loadSettings( _this, "Inputgain" );
m_outGainModel.loadSettings( _this, "Outputgain");
m_lowShelfGainModel.loadSettings( _this , "Lowshelfgain" );
m_para1GainModel.loadSettings( _this, "Peak1gain" );
m_para2GainModel.loadSettings( _this, "Peak2gain" );
m_para3GainModel.loadSettings( _this, "Peak3gain" );
m_para4GainModel.loadSettings( _this, "Peak4gain" );
m_highShelfGainModel.loadSettings( _this , "HighShelfgain");
m_hpResModel.loadSettings( _this ,"HPres");
m_lowShelfResModel.loadSettings( _this, "LowShelfres" );
m_para1ResModel.loadSettings( _this ,"Peak1res" );
m_para2ResModel.loadSettings( _this ,"Peak2res" );
m_para3ResModel.loadSettings( _this ,"Peak3res" );
m_para4ResModel.loadSettings( _this ,"Peak4res" );
m_highShelfResModel.loadSettings( _this, "HighShelfres" );
m_lpResModel.loadSettings( _this, "LPres");
m_hpFeqModel.loadSettings( _this, "HPfreq" );
m_lowShelfFreqModel.loadSettings( _this, "LowShelffreq" );
m_para1FreqModel.loadSettings( _this, "Peak1freq" );
m_para2FreqModel.loadSettings( _this, "Peak2freq" );
m_para3FreqModel.loadSettings( _this, "Peak3freq" );
m_para4FreqModel.loadSettings( _this, "Peak4freq" );
m_highShelfFreqModel.loadSettings( _this, "Highshelffreq" );
m_lpFreqModel.loadSettings( _this, "LPfreq" );
m_hpActiveModel.loadSettings( _this, "HPactive" );
m_lowShelfActiveModel.loadSettings( _this, "Lowshelfactive" );
m_para1ActiveModel.loadSettings( _this, "Peak1active");
m_para2ActiveModel.loadSettings( _this, "Peak2active");
m_para3ActiveModel.loadSettings( _this, "Peak3active");
m_para4ActiveModel.loadSettings( _this, "Peak4active");
m_highShelfActiveModel.loadSettings( _this, "Highshelfactive" );
m_lpActiveModel.loadSettings( _this, "LPactive" );
m_lp12Model.loadSettings( _this , "LP12" );
m_lp24Model.loadSettings( _this , "LP24" );
m_lp48Model.loadSettings( _this , "LP48" );
m_hp12Model.loadSettings( _this , "HP12" );
m_hp24Model.loadSettings( _this , "HP24" );
m_hp48Model.loadSettings( _this , "HP48" );
m_analyzeModel.loadSettings( _this, "Analyzeenable");
m_lpTypeModel.loadSettings( _this, "LP" );
m_hpTypeModel.loadSettings( _this, "HP" );
}
void EqControls::saveSettings( QDomDocument &doc, QDomElement &parent )
{
m_inGainModel.saveSettings( doc, parent, "Inputgain" );
m_outGainModel.saveSettings( doc, parent, "Outputgain");
m_lowShelfGainModel.saveSettings( doc, parent , "Lowshelfgain" );
m_para1GainModel.saveSettings( doc, parent, "Peak1gain" );
m_para2GainModel.saveSettings( doc, parent, "Peak2gain" );
m_para3GainModel.saveSettings( doc, parent, "Peak3gain" );
m_para4GainModel.saveSettings( doc, parent, "Peak4gain" );
m_highShelfGainModel.saveSettings( doc, parent, "HighShelfgain");
m_hpResModel.saveSettings( doc, parent ,"HPres");
m_lowShelfResModel.saveSettings( doc, parent, "LowShelfres" );
m_para1ResModel.saveSettings( doc, parent,"Peak1res" );
m_para2ResModel.saveSettings( doc, parent,"Peak2res" );
m_para3ResModel.saveSettings( doc, parent,"Peak3res" );
m_para4ResModel.saveSettings( doc, parent,"Peak4res" );
m_highShelfResModel.saveSettings( doc, parent, "HighShelfres" );
m_lpResModel.saveSettings( doc, parent, "LPres");
m_hpFeqModel.saveSettings( doc, parent, "HPfreq" );
m_lowShelfFreqModel.saveSettings( doc, parent, "LowShelffreq" );
m_para1FreqModel.saveSettings( doc, parent, "Peak1freq" );
m_para2FreqModel.saveSettings( doc, parent, "Peak2freq" );
m_para3FreqModel.saveSettings( doc, parent, "Peak3freq" );
m_para4FreqModel.saveSettings( doc, parent, "Peak4freq" );
m_highShelfFreqModel.saveSettings( doc, parent, "Highshelffreq" );
m_lpFreqModel.saveSettings( doc, parent, "LPfreq" );
m_hpActiveModel.saveSettings( doc, parent, "HPactive" );
m_lowShelfActiveModel.saveSettings( doc, parent, "Lowshelfactive" );
m_para1ActiveModel.saveSettings( doc, parent, "Peak1active" );
m_para2ActiveModel.saveSettings( doc, parent, "Peak2active" );
m_para3ActiveModel.saveSettings( doc, parent, "Peak3active" );
m_para4ActiveModel.saveSettings( doc, parent, "Peak4active" );
m_highShelfActiveModel.saveSettings( doc, parent, "Highshelfactive" );
m_lpActiveModel.saveSettings( doc, parent, "LPactive" );
m_lp12Model.saveSettings( doc, parent, "LP12" );
m_lp24Model.saveSettings( doc, parent, "LP24" );
m_lp48Model.saveSettings( doc, parent, "LP48" );
m_hp12Model.saveSettings( doc, parent, "HP12" );
m_hp24Model.saveSettings( doc, parent, "HP24" );
m_hp48Model.saveSettings( doc, parent, "HP48" );
m_analyzeModel.saveSettings( doc, parent, "Analyzeenable");
m_lpTypeModel.saveSettings( doc, parent, "LP" );
m_hpTypeModel.saveSettings( doc, parent, "HP" );
}

134
plugins/Eq/EqControls.h Normal file
View File

@@ -0,0 +1,134 @@
/*
* eqcontrols.h - defination of EqControls class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQCONTROLS_H
#define EQCONTROLS_H
#include "EffectControls.h"
#include "EqControlsDialog.h"
#include "Knob.h"
class EqEffect;
class EqControls : public EffectControls
{
Q_OBJECT
public:
explicit EqControls( EqEffect* effect );
virtual ~EqControls()
{
}
virtual void saveSettings ( QDomDocument& doc, QDomElement& parent );
virtual void loadSettings ( const QDomElement &_this );
inline virtual QString nodeName() const
{
return "Eq";
}
virtual int controlCount()
{
return 39;
}
virtual EffectControlDialog* createView()
{
return new EqControlsDialog( this );
}
float m_inPeakL;
float m_inPeakR;
float m_outPeakL;
float m_outPeakR;
float m_lowShelfPeakL, m_lowShelfPeakR;
float m_para1PeakL, m_para1PeakR;
float m_para2PeakL, m_para2PeakR;
float m_para3PeakL, m_para3PeakR;
float m_para4PeakL, m_para4PeakR;
float m_highShelfPeakL, m_highShelfPeakR;
EqAnalyser m_inFftBands;
EqAnalyser m_outFftBands;
bool m_inProgress;
private:
EqEffect* m_effect;
FloatModel m_inGainModel;
FloatModel m_outGainModel;
FloatModel m_lowShelfGainModel;
FloatModel m_para1GainModel;
FloatModel m_para2GainModel;
FloatModel m_para3GainModel;
FloatModel m_para4GainModel;
FloatModel m_highShelfGainModel;
FloatModel m_hpResModel;
FloatModel m_lowShelfResModel;
FloatModel m_para1ResModel;
FloatModel m_para2ResModel;
FloatModel m_para3ResModel;
FloatModel m_para4ResModel;
FloatModel m_highShelfResModel;
FloatModel m_lpResModel;
FloatModel m_hpFeqModel;
FloatModel m_lowShelfFreqModel;
FloatModel m_para1FreqModel;
FloatModel m_para2FreqModel;
FloatModel m_para3FreqModel;
FloatModel m_para4FreqModel;
FloatModel m_highShelfFreqModel;
FloatModel m_lpFreqModel;
BoolModel m_hpActiveModel;
BoolModel m_lowShelfActiveModel;
BoolModel m_para1ActiveModel;
BoolModel m_para2ActiveModel;
BoolModel m_para3ActiveModel;
BoolModel m_para4ActiveModel;
BoolModel m_highShelfActiveModel;
BoolModel m_lpActiveModel;
BoolModel m_lp12Model;
BoolModel m_lp24Model;
BoolModel m_lp48Model;
BoolModel m_hp12Model;
BoolModel m_hp24Model;
BoolModel m_hp48Model;
BoolModel m_analyzeModel;
IntModel m_lpTypeModel;
IntModel m_hpTypeModel;
friend class EqControlsDialog;
friend class EqEffect;
};
#endif // EQCONTROLS_H

View File

@@ -0,0 +1,171 @@
/*
* eqcontrolsdialog.cpp - defination of EqControlsDialog class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 "EqControlsDialog.h"
#include "EqControls.h"
#include "embed.h"
#include "Fader.h"
#include "EqFader.h"
#include "Engine.h"
#include "AutomatableButton.h"
#include "QWidget"
#include "MainWindow.h"
#include "LedCheckbox.h"
EqControlsDialog::EqControlsDialog( EqControls *controls ) :
EffectControlDialog( controls )
{
m_controls = controls;
setAutoFillBackground( true );
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
setPalette( pal );
setFixedSize( 350, 275 );
m_inSpec = new EqSpectrumView( &controls->m_inFftBands, this);
m_inSpec->move( 51, 2 );
m_inSpec->color = QColor( 238, 154, 120, 80 );
m_outSpec = new EqSpectrumView( &controls->m_outFftBands, this);
m_outSpec->move( 51, 2 );
m_outSpec->color = QColor(145, 205, 22, 80);
m_parameterWidget = new EqParameterWidget( this );
m_parameterWidget->move( 51, 2 );
setBand( 0, &controls->m_hpActiveModel, &controls->m_hpFeqModel, &controls->m_hpResModel, 0, QColor(255 ,255, 255), tr( "HP" ) ,0,0);
setBand( 1, &controls->m_lowShelfActiveModel, &controls->m_lowShelfFreqModel, &controls->m_lowShelfResModel, &controls->m_lowShelfGainModel, QColor(255 ,255, 255), tr( "Low Shelf" ), &controls->m_lowShelfPeakL , &controls->m_lowShelfPeakR );
setBand( 2, &controls->m_para1ActiveModel, &controls->m_para1FreqModel, &controls->m_para1ResModel, &controls->m_para1GainModel, QColor(255 ,255, 255), tr( "Peak 1" ), &controls->m_para1PeakL, &controls->m_para1PeakR );
setBand( 3, &controls->m_para2ActiveModel, &controls->m_para2FreqModel, &controls->m_para2ResModel, &controls->m_para2GainModel, QColor(255 ,255, 255), tr( "Peak 2" ), &controls->m_para2PeakL, &controls->m_para2PeakR );
setBand( 4, &controls->m_para3ActiveModel, &controls->m_para3FreqModel, &controls->m_para3ResModel, &controls->m_para3GainModel, QColor(255 ,255, 255), tr( "Peak 3" ), &controls->m_para3PeakL, &controls->m_para3PeakR );
setBand( 5, &controls->m_para4ActiveModel, &controls->m_para4FreqModel, &controls->m_para4ResModel, &controls->m_para4GainModel, QColor(255 ,255, 255), tr( "Peak 4" ), &controls->m_para4PeakL, &controls->m_para4PeakR );
setBand( 6, &controls->m_highShelfActiveModel, &controls->m_highShelfFreqModel, &controls->m_highShelfResModel, &controls->m_highShelfGainModel, QColor(255 ,255, 255), tr( "High Shelf" ), &controls->m_highShelfPeakL, &controls->m_highShelfPeakR );
setBand( 7, &controls->m_lpActiveModel, &controls->m_lpFreqModel, &controls->m_lpResModel, 0, QColor(255 ,255, 255), tr( "LP" ) ,0,0);
int cw = width()/8; //the chanel width in pixels
int ko = ( cw * 0.5 ) - ((new Knob( knobBright_26, 0 ))->width() * 0.5 );
m_inGainFader = new EqFader( &controls->m_inGainModel, tr( "In Gain" ), this, &controls->m_inPeakL, &controls->m_inPeakR);
m_inGainFader->move( 10, 5 );
m_outGainFader = new EqFader( &controls->m_outGainModel, tr( "Out Gain" ), this, &controls->m_outPeakL, &controls->m_outPeakR );
m_outGainFader->move( 315, 5 );
//gain faders
int fo = (cw * 0.5) - (m_outGainFader->width() * 0.5 );
for( int i = 1; i < m_parameterWidget->bandCount() - 1; i++)
{
m_gainFader = new EqFader( m_parameterWidget->getBandModels(i)->gain, tr( "" ), this ,m_parameterWidget->getBandModels( i )->peakL, m_parameterWidget->getBandModels( i )->peakR );
m_gainFader->move( cw * i + fo , 123 );
m_gainFader->setMinimumHeight(80);
m_gainFader->resize(m_gainFader->width() , 80);
m_gainFader->setDisplayConversion( false );
m_gainFader->setHintText( tr( "Gain") , "dB");
}
for( int i = 0; i < m_parameterWidget->bandCount() ; i++)
{
m_resKnob = new Knob( knobBright_26, this );
if(i ==0 || i == 7)
{
m_resKnob->move( cw * i + ko , 190 );
} else
{
m_resKnob->move( cw * i + ko , 205 );
}
m_resKnob->setVolumeKnob(false);
m_resKnob->setModel( m_parameterWidget->getBandModels( i )->res );
m_resKnob->setHintText( tr( "Resonance:") , "");
m_freqKnob = new Knob( knobBright_26, this );
if( i == 0 || i == 7 )
{
m_freqKnob->move( cw * i + ko, 222 );
} else
{
m_freqKnob->move(cw * i + ko, 235 );
}
m_freqKnob->setVolumeKnob( false );
m_freqKnob->setModel( m_parameterWidget->getBandModels( i )->freq );
m_freqKnob->setHintText( tr( "Frequency:" ), "Hz" );
m_activeBox = new LedCheckBox( m_parameterWidget->getBandModels( i )->name , this , "" , LedCheckBox::Green );
m_activeBox->move( cw * i + fo + 3, 260 );
m_activeBox->setModel( m_parameterWidget->getBandModels( i )->active );
}
//hp filter type
m_hp12Box = new LedCheckBox( tr( "12dB" ), this , "" , LedCheckBox::Green );
m_hp12Box->move( cw*0 + ko, 170 );
m_hp12Box->setModel( &controls->m_hp12Model );
m_hp24Box = new LedCheckBox( tr( "24dB" ), this , "" , LedCheckBox::Green );
m_hp24Box->move( cw*0 + ko, 150 );
m_hp24Box->setModel( &controls->m_hp24Model );
m_hp48Box = new LedCheckBox( tr( "48dB" ), this , "" , LedCheckBox::Green );
m_hp48Box->move( cw*0 + ko, 130 );
m_hp48Box->setModel( &controls->m_hp48Model );
//LP filter type
m_lp12Box = new LedCheckBox( tr( "12dB"), this , "" , LedCheckBox::Green );
m_lp12Box->move( cw*7 + ko -5 , 170 );
m_lp12Box->setModel( &controls->m_lp12Model );
m_lp24Box = new LedCheckBox( tr( "24dB"), this , "" , LedCheckBox::Green );
m_lp24Box->move( cw*7 + ko - 5, 150 );
m_lp24Box->setModel( &controls->m_lp24Model );
m_lp48Box = new LedCheckBox( tr( "48dB"), this , "" , LedCheckBox::Green );
m_lp48Box->move( cw*7 + ko - 5, 130 );
m_lp48Box->setModel( &controls->m_lp48Model );
automatableButtonGroup *lpBtnGrp = new automatableButtonGroup(this,tr ( "lp grp" ) );
lpBtnGrp->addButton( m_lp12Box);
lpBtnGrp->addButton( m_lp24Box );
lpBtnGrp->addButton( m_lp48Box );
lpBtnGrp->setModel( &m_controls->m_lpTypeModel, false);
automatableButtonGroup *hpBtnGrp = new automatableButtonGroup( this, tr( "hp grp" ) );
hpBtnGrp->addButton( m_hp12Box );
hpBtnGrp->addButton( m_hp24Box );
hpBtnGrp->addButton( m_hp48Box );
hpBtnGrp->setModel( &m_controls->m_hpTypeModel,false);
//Analize Box
m_analyzeBox = new LedCheckBox( tr( "Analyze" ), this , "" , LedCheckBox::Green );
m_analyzeBox->move( cw*1 + ko + 5, 15 );
m_analyzeBox->setModel( &controls->m_analyzeModel );
}
void EqControlsDialog::mouseDoubleClickEvent(QMouseEvent *event)
{
m_originalHeight = parentWidget()->height() == 150 ? m_originalHeight : parentWidget()->height() ;
parentWidget()->setFixedHeight( parentWidget()->height() == m_originalHeight ? 150 : m_originalHeight );
update();
}

View File

@@ -0,0 +1,94 @@
/*
* eqcontrolsdialog.h - defination of EqControlsDialog class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQCONTROLSDIALOG_H
#define EQCONTROLSDIALOG_H
#include "EffectControlDialog.h"
#include "Fader.h"
#include "Knob.h"
#include "LedCheckbox.h"
#include "EqParameterWidget.h"
#include "MainWindow.h"
#include "qpushbutton.h"
#include "EqSpectrumView.h"
class EqControls;
class EqControlsDialog : public EffectControlDialog
{
public:
EqControlsDialog( EqControls* controls );
virtual ~EqControlsDialog()
{
}
EqBand * setBand(EqControls *controls);
private slots:
void updateVuMeters();
private:
EqControls * m_controls;
Fader* m_inGainFader;
Fader* m_outGainFader;
Fader* m_gainFader;
Knob* m_resKnob;
Knob* m_freqKnob;
LedCheckBox* m_activeBox;
LedCheckBox* m_lp12Box;
LedCheckBox* m_lp24Box;
LedCheckBox* m_lp48Box;
LedCheckBox* m_hp12Box;
LedCheckBox* m_hp24Box;
LedCheckBox* m_hp48Box;
LedCheckBox* m_analyzeBox;
EqParameterWidget* m_parameterWidget;
EqSpectrumView* m_inSpec;
EqSpectrumView* m_outSpec;
virtual void mouseDoubleClickEvent(QMouseEvent *event);
EqBand* setBand( int index, BoolModel* active, FloatModel* freq, FloatModel* res, FloatModel* gain, QColor color, QString name, float* peakL, float* peakR)
{
EqBand* filterModels = m_parameterWidget->getBandModels( index );
filterModels->active = active;
filterModels->freq = freq;
filterModels->res = res;
filterModels->color = color;
filterModels->gain = gain;
filterModels->peakL = peakL;
filterModels->peakR = peakR;
return filterModels;
}
int m_originalHeight;
};
#endif // EQCONTROLSDIALOG_H

375
plugins/Eq/EqEffect.cpp Normal file
View File

@@ -0,0 +1,375 @@
/*
* eqeffect.cpp - defination of EqEffect class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 "EqEffect.h"
#include "embed.cpp"
#include "lmms_math.h"
#include "BasicFilters.h"
#include "interpolation.h"
#include "Engine.h"
#include "MainWindow.h"
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT eq_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Eq",
QT_TRANSLATE_NOOP( "pluginBrowser", "A native eq plugin" ),
"Dave French <contact/dot/dave/dot/french3/at/googlemail/dot/com>",
0x0100,
Plugin::Effect,
new PluginPixmapLoader( "logo" ),
NULL,
NULL
} ;
}
EqEffect::EqEffect(Model *parent, const Plugin::Descriptor::SubPluginFeatures::Key *key) :
Effect( &eq_plugin_descriptor, parent, key ),
m_eqControls( this ),
m_upBufFrames( 0 )
{
m_dFilterCount = 4;
m_downsampleFilters = new EqLinkwitzRiley[m_dFilterCount];
for( int i = 0; i < m_dFilterCount; i++)
{
m_downsampleFilters[i].setFrequency(21000);
m_downsampleFilters[i].setSR(Engine::mixer()->processingSampleRate() * 2 );
}
m_upBuf = 0;
}
EqEffect::~EqEffect()
{
if(m_upBuf)
{
delete m_upBuf;
}
}
bool EqEffect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
{
if( !isEnabled() || !isRunning () )
{
return( false );
}
m_eqControls.m_inProgress = true;
double outSum = 0.0;
const float outGain = m_eqControls.m_outGainModel.value();
const int sampleRate = Engine::mixer()->processingSampleRate() * 2;
sampleFrame m_inPeak = { 0, 0 };
if(m_eqControls.m_analyzeModel.value() )
{
m_eqControls.m_inFftBands.analyze( buf, frames );
}
else
{
m_eqControls.m_inFftBands.clear();
}
upsample( buf, frames );
gain(m_upBuf , m_upBufFrames, m_eqControls.m_inGainModel.value(), &m_inPeak );
m_eqControls.m_inPeakL = m_eqControls.m_inPeakL < m_inPeak[0] ? m_inPeak[0] : m_eqControls.m_inPeakL;
m_eqControls.m_inPeakR = m_eqControls.m_inPeakR < m_inPeak[1] ? m_inPeak[0] : m_eqControls.m_inPeakR;
if(m_eqControls.m_hpActiveModel.value() ){
m_hp12.setSampleRate( sampleRate );
m_hp12.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp12.setQ( m_eqControls.m_hpResModel.value() );
m_hp12.processBuffer( m_upBuf , m_upBufFrames );
if( m_eqControls.m_hp24Model.value() || m_eqControls.m_hp48Model.value() )
{
m_hp24.setSampleRate( sampleRate );
m_hp24.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp24.setQ( m_eqControls.m_hpResModel.value() );
m_hp24.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_hp48Model.value() )
{
m_hp480.setSampleRate( sampleRate );
m_hp480.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp480.setQ( m_eqControls.m_hpResModel.value() );
m_hp480.processBuffer( m_upBuf , m_upBufFrames );
m_hp481.setSampleRate( sampleRate );
m_hp481.setFrequency( m_eqControls.m_hpFeqModel.value() );
m_hp481.setQ( m_eqControls.m_hpResModel.value() );
m_hp481.processBuffer( m_upBuf , m_upBufFrames );
}
}
if( m_eqControls.m_lowShelfActiveModel.value() )
{
m_lowShelf.setSampleRate( sampleRate );
m_lowShelf.setFrequency( m_eqControls.m_lowShelfFreqModel.value() );
m_lowShelf.setQ( m_eqControls.m_lowShelfResModel .value() );
m_lowShelf.setGain( m_eqControls.m_lowShelfGainModel.value() );
m_lowShelf.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para1ActiveModel.value() )
{
m_para1.setSampleRate(sampleRate );
m_para1.setFrequency( m_eqControls.m_para1FreqModel.value() );
m_para1.setQ( m_eqControls.m_para1ResModel.value() );
m_para1.setGain( m_eqControls.m_para1GainModel.value() );
m_para1.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para2ActiveModel.value() )
{
m_para2.setSampleRate( sampleRate );
m_para2.setFrequency( m_eqControls.m_para2FreqModel.value() );
m_para2.setQ( m_eqControls.m_para2ResModel.value() );
m_para2.setGain( m_eqControls.m_para2GainModel.value() );
m_para2.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para3ActiveModel.value() )
{
m_para3.setSampleRate( sampleRate);
m_para3.setFrequency( m_eqControls.m_para3FreqModel.value() );
m_para3.setQ( m_eqControls.m_para3ResModel.value() );
m_para3.setGain( m_eqControls.m_para3GainModel.value() );
m_para3.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_para4ActiveModel.value() )
{
m_para4.setSampleRate( sampleRate );
m_para4.setFrequency( m_eqControls.m_para4FreqModel.value() );
m_para4.setQ( m_eqControls.m_para4ResModel.value() );
m_para4.setGain( m_eqControls.m_para4GainModel.value() );
m_para4.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_highShelfActiveModel.value() )
{
m_highShelf.setSampleRate( sampleRate );
m_highShelf.setFrequency( m_eqControls.m_highShelfFreqModel.value() );
m_highShelf.setQ( m_eqControls.m_highShelfResModel.value() );
m_highShelf.setGain( m_eqControls.m_highShelfGainModel.value() );
m_highShelf.processBuffer( m_upBuf , m_upBufFrames );
}
if(m_eqControls.m_lpActiveModel.value() ){
m_lp12.setSampleRate( sampleRate );
m_lp12.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp12.setQ( m_eqControls.m_lpResModel.value() );
m_lp12.processBuffer( m_upBuf , m_upBufFrames );
if( m_eqControls.m_lp24Model.value() || m_eqControls.m_lp48Model.value() )
{
m_lp24.setSampleRate( sampleRate );
m_lp24.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp24.setQ( m_eqControls.m_lpResModel.value() );
m_lp24.processBuffer( m_upBuf , m_upBufFrames );
}
if( m_eqControls.m_lp48Model.value() )
{
m_lp480.setSampleRate( sampleRate );
m_lp480.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp480.setQ( m_eqControls.m_lpResModel.value() );
m_lp480.processBuffer( m_upBuf , m_upBufFrames );
m_lp481.setSampleRate( sampleRate );
m_lp481.setFrequency( m_eqControls.m_lpFreqModel.value() );
m_lp481.setQ( m_eqControls.m_lpResModel.value() );
m_lp481.processBuffer( m_upBuf , m_upBufFrames );
}
}
sampleFrame outPeak = { 0, 0 };
gain( m_upBuf , m_upBufFrames, outGain, &outPeak );
m_eqControls.m_outPeakL = m_eqControls.m_outPeakL < outPeak[0] ? outPeak[0] : m_eqControls.m_outPeakL;
m_eqControls.m_outPeakR = m_eqControls.m_outPeakR < outPeak[1] ? outPeak[0] : m_eqControls.m_outPeakR;
for( int i =0; i < m_dFilterCount; i++)
{
m_downsampleFilters[i].processBuffer(m_upBuf , m_upBufFrames );
}
downSample( buf, frames );
for( fpp_t f = 0; f < frames; ++f )
{
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
}
checkGate( outSum / frames );
if(m_eqControls.m_analyzeModel.value() )
{
m_eqControls.m_outFftBands.analyze( buf, frames );
}
else
{
m_eqControls.m_outFftBands.clear();
}
setBandPeaks( &m_eqControls.m_outFftBands , ( int )( sampleRate * 0.5 ) );
m_eqControls.m_inProgress = false;
return isRunning();
}
void EqEffect::gain( sampleFrame *buf, const fpp_t frames, float scale, sampleFrame* peak )
{
peak[0][0] = 0.0f; peak[0][1] = 0.0f;
for( fpp_t f = 0; f < frames; ++f )
{
buf[f][0] *= scale;
buf[f][1] *= scale;
if( fabs( buf[f][0] ) > peak[0][0] )
{
peak[0][0] = fabs( buf[f][0] );
}
if( fabs( buf[f][1] ) > peak[0][1] )
{
peak[0][1] = fabs( buf[f][0] );
}
}
}
sampleFrame m_lastUpFrame;
void EqEffect::upsample( sampleFrame *buf, const fpp_t frames )
{
if( m_upBufFrames != frames * 2 )
{
if( m_upBuf )
{
delete m_upBuf;
}
m_upBuf = new sampleFrame[frames * 2];
m_upBufFrames = frames * 2;
}
for( int f = 0, f2 = 0; f < frames; ++f, f2 += 2 )
{
m_upBuf[f2][0] = linearInterpolate( m_lastUpFrame[0],buf[f][0], 0.5 );
m_upBuf[f2][1] = linearInterpolate( m_lastUpFrame[1],buf[f][1], 0.5 );
m_upBuf[f2+1][0] = buf[f][0];
m_upBuf[f2+1][1] = buf[f][1];
m_lastUpFrame[0] = buf[f][0];
m_lastUpFrame[1] = buf[f][1];
}
}
void EqEffect::downSample( sampleFrame *buf, const fpp_t frames )
{
for( int f = 0, f2 = 0; f < frames; ++f, f2 += 2 )
{
buf[f][0] = m_upBuf[f2+1][0];
buf[f][1] = m_upBuf[f2+1][1];
}
}
float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr )
{
float peak = -60;
float * b = fft->m_bands;
float h = 0;
for(int x = 0; x < MAX_BANDS; x++, b++)
{
if( bandToFreq( x ,sr) >= minF && bandToFreq( x,sr ) <= maxF )
{
h = 20*( log10( *b / fft->m_energy ) );
peak = h > peak ? h : peak;
}
}
return (peak+100)/100;
}
void EqEffect::setBandPeaks(EqAnalyser *fft, int samplerate )
{
m_eqControls.m_lowShelfPeakR = m_eqControls.m_lowShelfPeakL =
peakBand( 0,
m_eqControls.m_lowShelfFreqModel.value(), fft , samplerate );
m_eqControls.m_para1PeakL = m_eqControls.m_para1PeakR =
peakBand( m_eqControls.m_para1FreqModel.value()
- (m_eqControls.m_para1FreqModel.value() / m_eqControls.m_para1ResModel.value() * 0.5),
m_eqControls.m_para1FreqModel.value()
+ (m_eqControls.m_para1FreqModel.value() / m_eqControls.m_para1ResModel.value() * 0.5),
fft , samplerate );
m_eqControls.m_para2PeakL = m_eqControls.m_para2PeakR =
peakBand( m_eqControls.m_para2FreqModel.value()
- (m_eqControls.m_para2FreqModel.value() / m_eqControls.m_para2ResModel.value() * 0.5),
m_eqControls.m_para2FreqModel.value()
+ (m_eqControls.m_para2FreqModel.value() / m_eqControls.m_para2ResModel.value() * 0.5),
fft , samplerate );
m_eqControls.m_para3PeakL = m_eqControls.m_para3PeakR =
peakBand( m_eqControls.m_para3FreqModel.value()
- (m_eqControls.m_para3FreqModel.value() / m_eqControls.m_para3ResModel.value() * 0.5),
m_eqControls.m_para3FreqModel.value()
+ (m_eqControls.m_para3FreqModel.value() / m_eqControls.m_para3ResModel.value() * 0.5),
fft , samplerate );
m_eqControls.m_para4PeakL = m_eqControls.m_para4PeakR =
peakBand( m_eqControls.m_para4FreqModel.value()
- (m_eqControls.m_para4FreqModel.value() / m_eqControls.m_para4ResModel.value() * 0.5),
m_eqControls.m_para4FreqModel.value()
+ (m_eqControls.m_para4FreqModel.value() / m_eqControls.m_para4ResModel.value() * 0.5),
fft , samplerate );
m_eqControls.m_highShelfPeakL = m_eqControls.m_highShelfPeakR =
peakBand( m_eqControls.m_highShelfFreqModel.value(),
samplerate * 0.5 , fft, samplerate );
}
extern "C"
{
//needed for getting plugin out of shared lib
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model* parent, void* data )
{
return new EqEffect( parent , static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>( data ) );
}
}

89
plugins/Eq/EqEffect.h Normal file
View File

@@ -0,0 +1,89 @@
/* eqeffect.h - defination of EqEffect class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQEFFECT_H
#define EQEFFECT_H
#include "Effect.h"
#include "EqControls.h"
#include "lmms_math.h"
#include "BasicFilters.h"
#include "EqFilter.h"
class EqEffect : public Effect
{
public:
EqEffect( Model* parent , const Descriptor::SubPluginFeatures::Key* key );
virtual ~EqEffect();
virtual bool processAudioBuffer( sampleFrame *buf, const fpp_t frames );
virtual EffectControls* controls()
{
return &m_eqControls;
}
void gain( sampleFrame *buf, const fpp_t frames, float scale, sampleFrame* peak );
private:
EqControls m_eqControls;
EqHp12Filter m_hp12;
EqHp12Filter m_hp24;
EqHp12Filter m_hp480;
EqHp12Filter m_hp481;
EqLowShelfFilter m_lowShelf;
EqPeakFilter m_para1;
EqPeakFilter m_para2;
EqPeakFilter m_para3;
EqPeakFilter m_para4;
EqHighShelfFilter m_highShelf;
EqLp12Filter m_lp12;
EqLp12Filter m_lp24;
EqLp12Filter m_lp480;
EqLp12Filter m_lp481;
EqLinkwitzRiley* m_downsampleFilters;
int m_dFilterCount;
sampleFrame* m_upBuf;
fpp_t m_upBufFrames;
void upsample( sampleFrame *buf, const fpp_t frames );
void downSample( sampleFrame *buf, const fpp_t frames );
void analyze( sampleFrame *buf, const fpp_t frames, EqAnalyser* fft );
float peakBand(float minF, float maxF,EqAnalyser*, int);
inline float bandToFreq ( int index , int sampleRate )
{
return index * sampleRate / (MAX_BANDS * 2);
}
void setBandPeaks( EqAnalyser *fft , int);
};
#endif // EQEFFECT_H

101
plugins/Eq/EqFader.h Normal file
View File

@@ -0,0 +1,101 @@
/* eqfader.h - defination of EqFader class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQFADER_H
#define EQFADER_H
#include "Fader.h"
#include "EffectControls.h"
#include "MainWindow.h"
#include "qwidget.h"
#include "TextFloat.h"
#include "qlist.h"
class EqFader : public Fader
{
public:
Q_OBJECT
public:
EqFader( FloatModel * model, const QString & name, QWidget * parent, float* lPeak, float* rPeak ) :
Fader( model, name, parent)
{
setMinimumSize( 23, 116 );
setMaximumSize( 23, 116 );
resize( 23, 116 );
m_lPeak = lPeak;
m_rPeak = rPeak;
connect( Engine::mainWindow(), SIGNAL( periodicUpdate() ), this, SLOT( updateVuMeters() ) );
m_model = model;
setPeak_L( 0 );
setPeak_R( 0 );
}
~EqFader()
{
}
private slots:
void updateVuMeters()
{
const float opl = getPeak_L();
const float opr = getPeak_R();
const float fall_off = 1.2;
if( *m_lPeak > opl )
{
setPeak_L( *m_lPeak );
*m_lPeak = 0;
}
else
{
setPeak_L( opl/fall_off );
}
if( *m_rPeak > opr )
{
setPeak_R( *m_rPeak );
*m_rPeak = 0;
}
else
{
setPeak_R( opr/fall_off );
}
update();
}
private:
float* m_lPeak;
float* m_rPeak;
FloatModel* m_model;
};
#endif // EQFADER_H

388
plugins/Eq/EqFilter.h Normal file
View File

@@ -0,0 +1,388 @@
/*
* eqfilter.cpp - defination of EqFilterclass.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQFILTER_H
#define EQFILTER_H
#include "BasicFilters.h"
#include "lmms_math.h"
///
/// \brief The EqFilter class.
/// A wrapper for the StereoBiQuad class, giving it freq, res, and gain controls.
/// It is designed to process periods in one pass, with recalculation of coefficents
/// upon parameter changes. The intention is to use this as a bass class, children override
/// the calcCoefficents() function, providing the coefficents a1, a2, b0, b1, b2.
///
class EqFilter : public StereoBiQuad
{
public:
EqFilter()
{
}
virtual inline void setSampleRate( int sampleRate )
{
if( sampleRate != m_sampleRate )
{
m_sampleRate = sampleRate;
calcCoefficents();
}
}
virtual inline void setFrequency( float freq ){
if ( freq != m_freq )
{
m_freq = freq;
calcCoefficents();
}
}
virtual void setQ( float res )
{
if ( res != m_res )
{
m_res = res;
calcCoefficents();
}
}
virtual void setGain( float gain )
{
if ( gain != m_gain )
{
m_gain = gain;
calcCoefficents();
}
}
///
/// \brief processBuffer
/// \param buf Audio Buffer
/// \param frames Count of sampleFrames in Audio Buffer
///
virtual void processBuffer( sampleFrame* buf, const fpp_t frames )
{
for ( fpp_t f = 0 ; f < frames ; ++f)
{
buf[f][0] = update( buf[f][0] , 0);
buf[f][1] = update( buf[f][1] , 1);
}
}
protected:
///
/// \brief calcCoefficents
/// Override this in child classes to provide the coefficents, based on
/// Freq, Res and Gain
virtual void calcCoefficents(){
setCoeffs( 0, 0, 0, 0, 0 );
}
float m_sampleRate;
float m_freq;
float m_res;
float m_gain;
};
///
/// \brief The EqHp12Filter class
/// A 2 pole High Pass Filter
/// Coefficent calculations from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
class EqHp12Filter : public EqFilter
{
public :
virtual void calcCoefficents()
{
// calc intermediate
float w0 = F_2PI * m_freq / m_sampleRate;
float c = cosf( w0 );
float s = sinf( w0 );
float alpha = s / ( 2 * m_res );
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
//calc coefficents
b0 = ( 1 + c ) * 0.5;
b1 = ( -( 1 + c ) );
b2 = ( 1 + c ) * 0.5;
a0 = 1 + alpha;
a1 = ( -2 * c );
a2 = 1 - alpha;
//normalise
b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;
setCoeffs( a1, a2, b0, b1, b2 );
}
};
///
/// \brief The EqLp12Filter class.
/// A 2 pole low pass filter
/// Coefficent calculations from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
///
class EqLp12Filter : public EqFilter
{
public :
virtual void calcCoefficents()
{
// calc intermediate
float w0 = F_2PI * m_freq / m_sampleRate;
float c = cosf( w0 );
float s = sinf( w0 );
float alpha = s / ( 2 * m_res );
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
//calc coefficents
b0 = ( 1 - c ) * 0.5;
b1 = 1 - c;
b2 = ( 1 - c ) * 0.5;
a0 = 1 + alpha;
a1 = -2 * c;
a2 = 1 - alpha;
//normalise
b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;
setCoeffs( a1, a2, b0, b1, b2 );
}
};
///
/// \brief The EqPeakFilter class
/// A Peak Filter
/// Coefficent calculations from http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
///
class EqPeakFilter : public EqFilter
{
public:
virtual void calcCoefficents()
{
// calc intermediate
float w0 = F_2PI * m_freq / m_sampleRate;
float c = cosf( w0 );
float s = sinf( w0 );
float A = pow( 10, m_gain * 0.025);
float alpha = s / ( 2 * m_res );
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
//calc coefficents
b0 = 1 + alpha*A;
b1 = -2*c;
b2 = 1 - alpha*A;
a0 = 1 + alpha/A;
a1 = -2*c;
a2 = 1 - alpha/A;
//normalise
b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;
setCoeffs( a1, a2, b0, b1, b2 );
}
};
class EqLowShelfFilter : public EqFilter
{
public :
virtual void calcCoefficents()
{
// calc intermediate
float w0 = F_2PI * m_freq / m_sampleRate;
float c = cosf( w0 );
float s = sinf( w0 );
float A = pow( 10, m_gain * 0.025);
// float alpha = s / ( 2 * m_res );
float beta = sqrt( A ) / m_res;
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
//calc coefficents
b0 = A * ( ( A+1 ) - ( A-1 ) * c + beta * s );
b1 = 2 * A * ( ( A - 1 ) - ( A + 1 ) * c) ;
b2 = A * ( ( A + 1 ) - ( A - 1 ) * c - beta * s);
a0 = ( A + 1 ) + ( A - 1 ) * c + beta * s;
a1 = -2 * ( ( A - 1 ) + ( A + 1 ) * c );
a2 = ( A + 1 ) + ( A - 1) * c - beta * s;
//normalise
b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;
setCoeffs( a1, a2, b0, b1, b2 );
}
};
class EqHighShelfFilter : public EqFilter
{
public :
virtual void calcCoefficents()
{
// calc intermediate
float w0 = F_2PI * m_freq / m_sampleRate;
float c = cosf( w0 );
float s = sinf( w0 );
float A = pow( 10, m_gain * 0.025 );
float beta = sqrt( A ) / m_res;
float a0, a1, a2, b0, b1, b2; // coeffs to calculate
//calc coefficents
b0 = A *( ( A +1 ) + ( A - 1 ) * c + beta * s);
b1 = -2 * A * ( ( A - 1 ) + ( A + 1 ) * c );
b2 = A * ( ( A + 1 ) + ( A - 1 ) * c - beta * s);
a0 = ( A + 1 ) - ( A - 1 ) * c + beta * s;
a1 = 2 * ( ( A - 1 ) - ( A + 1 ) * c );
a2 = ( A + 1) - ( A - 1 ) * c - beta * s;
//normalise
b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;
setCoeffs( a1, a2, b0, b1, b2 );
}
};
class EqLinkwitzRiley : public StereoLinkwitzRiley
{
public:
EqLinkwitzRiley() :
StereoLinkwitzRiley( 44100),
m_freq(0 ),
m_sr( 1 )
{
}
virtual inline void setSR( int sampleRate )
{
if( sampleRate != m_sr )
{
m_sr = sampleRate;
setLowpass(m_freq);
setSampleRate( sampleRate );
}
}
virtual inline void setFrequency( float freq ){
if ( freq != m_freq )
{
m_freq = freq;
setLowpass(m_freq);
}
}
virtual void processBuffer( sampleFrame* buf, const fpp_t frames )
{
for ( fpp_t f = 0 ; f < frames ; ++f)
{
buf[f][0] = update( buf[f][0] , 0);
buf[f][1] = update( buf[f][1] , 1);
}
}
protected:
float m_freq;
int m_sr;
};
#endif // EQFILTER_H

View File

@@ -0,0 +1,221 @@
/*
* eqparameterwidget.cpp - defination of EqParameterWidget class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 "EqParameterWidget.h"
#include "QPainter"
#include "qwidget.h"
#include "lmms_math.h"
#include "MainWindow.h"
#include "QMouseEvent"
EqParameterWidget::EqParameterWidget( QWidget *parent ) :
QWidget( parent ),
m_bands ( 0 ),
m_selectedBand ( 0 )
{
m_bands = new EqBand[8];
resize( 250, 116 );
// connect( Engine::mainWindow(), SIGNAL( periodicUpdate() ), this, SLOT( update() ) );
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(100);
float totalLength = log10( 21000 );
m_pixelsPerUnitWidth = width( ) / totalLength ;
float totalHeight = 80;
m_pixelsPerUnitHeight = (height() - 4) / ( totalHeight );
m_scale = 1.5;
m_pixelsPerOctave = freqToXPixel( 10000 ) - freqToXPixel( 5000 );
}
EqParameterWidget::~EqParameterWidget()
{
if(m_bands)
{
delete[] m_bands;
m_bands = 0;
}
}
void EqParameterWidget::paintEvent( QPaintEvent *event )
{
QPainter painter( this );
//Draw Frequecy maker lines
painter.setPen( QPen( QColor( 100, 100, 100, 200 ), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin ) );
for( int x = 20 ; x < 100; x += 10)
{
painter.drawLine( freqToXPixel( x ) , 0, freqToXPixel( x ) , height() );
}
for( int x = 100 ; x < 1000; x += 100)
{
painter.drawLine( freqToXPixel( x ) , 0, freqToXPixel( x ) , height() );
}
for( int x = 1000 ; x < 11000; x += 1000)
{
painter.drawLine( freqToXPixel( x ) , 0, freqToXPixel( x ) , height() );
}
//draw 0dB line
painter.drawLine(0, gainToYPixel( 0 ) , width(), gainToYPixel( 0 ) );
for( int i = 0 ; i < bandCount() ; i++ )
{
m_bands[i].color.setAlpha( m_bands[i].active->value() ? activeAplha() : inactiveAlpha() );
painter.setPen( QPen( m_bands[i].color, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin ) );
float x = freqToXPixel( m_bands[i].freq->value() );
float y = height() * 0.5;
float gain = 1;
if( m_bands[i].gain )
{
gain = m_bands[i].gain->value();
}
y = gainToYPixel( gain );
float bw = m_bands[i].freq->value() / m_bands[i].res->value();
m_bands[i].x = x; m_bands[i].y = y;
const int radius = 7;
painter.drawEllipse( x - radius , y - radius, radius * 2 ,radius * 2 );
QString msg = QString ( "%1" ).arg ( QString::number (i + 1) );
painter.drawText(x - ( radius * 0.5 ), y + ( radius * 0.85 ), msg );
painter.setPen( QPen( m_bands[i].color, 1, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin ) );
if( i == 0 || i == bandCount() - 1 )
{
painter.drawLine(x , y, x, y - (m_bands[i].res->value() * 4 ) );
}
else
{
painter.drawLine(freqToXPixel(m_bands[i].freq->value()-(bw * 0.5)),y,freqToXPixel(m_bands[i].freq->value()+(bw * 0.5)),y);
}
}
}
void EqParameterWidget::mousePressEvent( QMouseEvent *event )
{
m_oldX = event->x(); m_oldY = event->y();
m_selectedBand = selectNearestHandle( event->x(), event->y() );
m_mouseAction = none;
if ( event->button() == Qt::LeftButton ) m_mouseAction = drag;
if ( event->button() == Qt::RightButton ) m_mouseAction = res;
}
void EqParameterWidget::mouseReleaseEvent( QMouseEvent *event )
{
m_selectedBand = 0;
m_mouseAction = none;
}
void EqParameterWidget::mouseMoveEvent( QMouseEvent *event )
{
int deltaX = event->x() - m_oldX;
int deltaR = event->y() - m_oldY;
m_oldX = event->x(); m_oldY = event->y();
if(m_selectedBand && m_selectedBand->active->value() )
{
switch ( m_mouseAction ) {
case none :
break;
case drag:
if( m_selectedBand->freq ) m_selectedBand->freq->setValue( xPixelToFreq( m_oldX ) );
if( m_selectedBand->gain )m_selectedBand->gain->setValue( yPixelToGain( m_oldY ) );
break;
case res:
if( m_selectedBand->res )m_selectedBand->res->incValue( deltaX * resPixelMultiplyer() );
if( m_selectedBand->res )m_selectedBand->res->incValue( (-deltaR) * resPixelMultiplyer() );
break;
default:
break;
}
}
}
void EqParameterWidget::mouseDoubleClickEvent( QMouseEvent *event )
{
EqBand* selected = selectNearestHandle( event->x() , event->y() );
if( selected )
{
selected->active->setValue( selected->active->value() ? 0 : 1 );
}
}
EqBand* EqParameterWidget::selectNearestHandle( const int x, const int y )
{
EqBand* selectedModel = 0;
float* distanceToHandles = new float[bandCount()];
//calc distance to each handle
for( int i = 0 ; i < bandCount() ; i++ )
{
int xOffset = m_bands[i].x - x;
int yOffset = m_bands[i].y - y;
distanceToHandles[i] = fabs( sqrt( ( xOffset * xOffset ) + ( yOffset * yOffset ) ) );
}
//select band
int shortestBand = 0;
for ( int i = 1 ; i < bandCount() ; i++ )
{
if ( distanceToHandles [i] < distanceToHandles[shortestBand] ){
shortestBand = i;
}
}
if(distanceToHandles[shortestBand] < maxDistanceFromHandle() )
{
selectedModel = &m_bands[shortestBand];
}
delete distanceToHandles;
return selectedModel;
}
EqBand::EqBand() :
gain ( 0 ),
res ( 0 ),
freq ( 0 ),
color ( QColor( 255, 255, 255 ) ),
x( 0 ),
y( 0 ),
name ( QString( "" ) ),
peakL( 0 ),
peakR( 0 )
{
}

View File

@@ -0,0 +1,161 @@
/*
* eqparameterwidget.cpp - defination of EqParameterWidget class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQPARAMETERWIDGET_H
#define EQPARAMETERWIDGET_H
#include <QWidget>
#include "EffectControls.h"
class EqBand
{
public :
EqBand();
FloatModel* gain;
FloatModel* res;
FloatModel* freq;
BoolModel* active;
QColor color;
int x;
int y;
QString name;
float* peakL;
float* peakR;
};
class EqParameterWidget : public QWidget
{
public:
explicit EqParameterWidget( QWidget *parent = 0 );
~EqParameterWidget();
const int bandCount()
{
return 8;
}
const int maxDistanceFromHandle()
{
return 20;
}
EqBand* getBandModels( int i )
{
return &m_bands[i];
}
const int activeAplha()
{
return 200;
}
const int inactiveAlpha()
{
return 100;
}
const float resPixelMultiplyer()
{
return 100;
}
signals:
public slots:
protected:
virtual void paintEvent ( QPaintEvent * event );
virtual void mousePressEvent(QMouseEvent * event );
virtual void mouseReleaseEvent(QMouseEvent * event);
virtual void mouseMoveEvent(QMouseEvent * event);
virtual void mouseDoubleClickEvent(QMouseEvent * event);
private:
EqBand *m_bands;
float m_pixelsPerUnitWidth;
float m_pixelsPerUnitHeight;
float m_pixelsPerOctave;
float m_scale;
EqBand* m_selectedBand;
EqBand* selectNearestHandle( const int x, const int y );
enum MouseAction { none, drag, res } m_mouseAction;
int m_oldX, m_oldY;
int *m_xGridBands;
inline int freqToXPixel( float freq )
{
return ( log10( freq ) * m_pixelsPerUnitWidth * m_scale ) - ( width() * 0.5 );
}
inline float xPixelToFreq( int x )
{
return pow( 10, ( x + ( width() * 0.5 ) ) / ( m_pixelsPerUnitWidth * m_scale ) );
}
inline int gainToYPixel( float gain )
{
return ( height() - 3) - ( gain * m_pixelsPerUnitHeight ) - ( (height() -3 ) * 0.5);
}
inline float yPixelToGain( int y )
{
return ( ( 0.5 * height() ) - y) / m_pixelsPerUnitHeight;
}
};
#endif // EQPARAMETERWIDGET_H

218
plugins/Eq/EqSpectrumView.h Normal file
View File

@@ -0,0 +1,218 @@
/* eqspectrumview.h - defination of EqSpectrumView class.
*
* Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
*
* This file is part of LMMS - http://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 EQSPECTRUMVIEW_H
#define EQSPECTRUMVIEW_H
#include "qpainter.h"
//#include "eqeffect.h"
#include "qwidget.h"
#include "fft_helpers.h"
#include "Engine.h"
const int MAX_BANDS = 2048;
class EqAnalyser
{
public:
fftwf_plan m_fftPlan;
fftwf_complex * m_specBuf;
float m_absSpecBuf[FFT_BUFFER_SIZE+1];
float m_buffer[FFT_BUFFER_SIZE*2];
int m_framesFilledUp;
float m_bands[MAX_BANDS];
float m_energy;
int m_sr;
EqAnalyser() :
m_framesFilledUp ( 0 ),
m_energy ( 0 ),
m_sr ( 1 )
{
m_inProgress=false;
m_specBuf = (fftwf_complex *) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) * sizeof( fftwf_complex ) );
m_fftPlan = fftwf_plan_dft_r2c_1d( FFT_BUFFER_SIZE*2, m_buffer, m_specBuf, FFTW_MEASURE );
clear();
}
virtual ~EqAnalyser()
{
fftwf_destroy_plan( m_fftPlan );
fftwf_free( m_specBuf );
}
bool getInProgress()
{
return m_inProgress;
}
void clear()
{
m_framesFilledUp = 0;
m_energy = 0;
memset( m_buffer, 0, sizeof( m_buffer ) );
memset( m_bands, 0, sizeof( m_bands ) );
}
void analyze( sampleFrame *buf, const fpp_t frames )
{
m_inProgress=true;
const int FFT_BUFFER_SIZE = 2048;
fpp_t f = 0;
if( frames > FFT_BUFFER_SIZE )
{
m_framesFilledUp = 0;
f = frames - FFT_BUFFER_SIZE;
}
// meger channels
for( ; f < frames; ++f )
{
m_buffer[m_framesFilledUp] =
( buf[f][0] + buf[f][1] ) * 0.5;
++m_framesFilledUp;
}
if( m_framesFilledUp < FFT_BUFFER_SIZE )
{
m_inProgress = false;
return;
}
m_sr = Engine::mixer()->processingSampleRate();
const int LOWEST_FREQ = 0;
const int HIGHEST_FREQ = m_sr / 2;
fftwf_execute( m_fftPlan );
absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 );
compressbands( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1,
MAX_BANDS,
( int )( LOWEST_FREQ * ( FFT_BUFFER_SIZE + 1 ) / ( float )( m_sr / 2 ) ),
( int )( HIGHEST_FREQ * ( FFT_BUFFER_SIZE + 1) / ( float )( m_sr / 2 ) ) );
m_energy = maximum( m_bands, MAX_BANDS ) / maximum( m_buffer, FFT_BUFFER_SIZE );
m_framesFilledUp = 0;
m_inProgress = false;
}
private:
bool m_inProgress;
};
class EqSpectrumView : public QWidget
{
public:
explicit EqSpectrumView( EqAnalyser * b, QWidget * _parent = 0 ):
QWidget( _parent ),
m_sa( b )
{
setFixedSize( 250, 116 );
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(2000);
setAttribute( Qt::WA_TranslucentBackground, true );
m_skipBands = MAX_BANDS * 0.5;
float totalLength = log10( 21000);
m_pixelsPerUnitWidth = width( ) / totalLength ;
m_scale = 1.5;
color = QColor( 255, 255, 255, 255 );
}
virtual ~EqSpectrumView()
{
}
QColor color;
EqAnalyser *m_sa;
QPainterPath pp;
virtual void paintEvent( QPaintEvent* event )
{
const int fh = height();
const int LOWER_Y = -60; // dB
QPainter p( this );
p.setPen( QPen( color, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin ) );
const float e = m_sa->m_energy;
if( e <= 0 )
{
//dont draw anything
return;
}
if(m_sa->getInProgress() ){
p.fillPath( pp ,QBrush( color ) );
return;
}
pp = QPainterPath();
float * b = m_sa->m_bands;
int h;
pp.moveTo( 0,height() );
for( int x = 0; x < MAX_BANDS; ++x, ++b )
{
h = (int)( fh * 2.0 / 3.0 * ( 20 * ( log10 ( *b / e ) ) - LOWER_Y ) / (-LOWER_Y ) );
if( h < 0 ) h = 0; else if( h >= fh ) continue;
pp.lineTo( freqToXPixel(bandToFreq( x ) ), fh-h );
}
pp.lineTo( width(), height() );
pp.closeSubpath();
p.fillPath( pp, QBrush( color ) );
p.drawPath( pp );
}
inline int bandToXPixel( float band )
{
return ( log10( band - m_skipBands ) * m_pixelsPerUnitWidth * m_scale );
}
inline float bandToFreq ( int index )
{
return index * m_sa->m_sr / (MAX_BANDS * 2 );
}
inline int freqToXPixel( float freq )
{
return ( log10( freq ) * m_pixelsPerUnitWidth * m_scale ) - ( width() * 0.5 );
}
private:
float m_pixelsPerUnitWidth;
float m_scale;
int m_skipBands;
} ;
#endif // EQSPECTRUMVIEW_H

BIN
plugins/Eq/artwork.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
plugins/Eq/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -74,7 +74,11 @@ static fftw_real *real_in, *real_out, *comp_in, *comp_out;
unsigned int fft_length[IMPULSES];
#ifdef __clang__
void impulse2freq(int id, float *imp, unsigned int length, fftw_real *out)
#else
inline void impulse2freq(int id, float *imp, unsigned int length, fftw_real *out)
#endif
{
fftw_real impulse_time[MAX_FFT_LENGTH];
#ifdef FFTW3

View File

@@ -31,6 +31,7 @@
#include "ConfigManager.h"
VstSubPluginFeatures::VstSubPluginFeatures( Plugin::PluginTypes _type ) :
SubPluginFeatures( _type )
{
@@ -52,16 +53,40 @@ void VstSubPluginFeatures::fillDescriptionWidget( QWidget * _parent,
void VstSubPluginFeatures::listSubPluginKeys( const Plugin::Descriptor * _desc,
KeyList & _kl ) const
{
QStringList dlls = QDir( ConfigManager::inst()->vstDir() ).
entryList( QStringList() << "*.dll",
QDir::Files, QDir::Name );
QStringList *dlls = new QStringList();
const QString path = QString("");
addPluginsFromDir(dlls, path );
// TODO: eval m_type
for( QStringList::ConstIterator it = dlls.begin();
it != dlls.end(); ++it )
for( QStringList::ConstIterator it = dlls->begin();
it != dlls->end(); ++it )
{
EffectKey::AttributeMap am;
am["file"] = *it;
_kl.push_back( Key( _desc, QFileInfo( *it ).baseName(), am ) );
}
delete dlls;
}
void VstSubPluginFeatures::addPluginsFromDir( QStringList* filenames, QString path ) const
{
QStringList dirs = QDir ( ConfigManager::inst()->vstDir() + path ).
entryList( QStringList() << "*" ,
QDir::Dirs, QDir::Name );
for( int i = 0; i < dirs.size(); i++ )
{
if( dirs.at( i )[0] != '.' )
{
addPluginsFromDir( filenames, path+QDir::separator() + dirs.at( i ) );
}
}
QStringList dlls = QDir( ConfigManager::inst()->vstDir() + path ).
entryList( QStringList() << "*.dll",
QDir::Files, QDir::Name );
for( int i = 0; i < dlls.size(); i++ )
{
QString fName = path + QDir::separator() + dlls.at( i );
fName.remove( 0, 1 );
filenames->append( fName );
}
}

View File

@@ -40,8 +40,13 @@ public:
virtual void listSubPluginKeys( const Plugin::Descriptor * _desc,
KeyList & _kl ) const;
private:
void addPluginsFromDir(QStringList* filenames, QString path) const;
} ;
#endif

View File

@@ -742,6 +742,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
m_to( m_sampleBuffer.frames() ),
m_last_from( 0 ),
m_last_to( 0 ),
m_last_amp( 0 ),
m_startKnob( 0 ),
m_endKnob( 0 ),
m_loopKnob( 0 ),

View File

@@ -251,16 +251,16 @@ intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opco
switch (opcode)
{
case HOST_OPCODE_NULL:
case NATIVE_HOST_OPCODE_NULL:
break;
case HOST_OPCODE_UPDATE_PARAMETER:
case HOST_OPCODE_UPDATE_MIDI_PROGRAM:
case HOST_OPCODE_RELOAD_PARAMETERS:
case HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
case HOST_OPCODE_RELOAD_ALL:
case NATIVE_HOST_OPCODE_UPDATE_PARAMETER:
case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM:
case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS:
case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
case NATIVE_HOST_OPCODE_RELOAD_ALL:
// nothing
break;
case HOST_OPCODE_UI_UNAVAILABLE:
case NATIVE_HOST_OPCODE_UI_UNAVAILABLE:
handleUiClosed();
break;
}
@@ -459,7 +459,7 @@ PluginView* CarlaInstrument::instantiateView(QWidget* parent)
void CarlaInstrument::sampleRateChanged()
{
fDescriptor->dispatcher(fHandle, PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, handleGetSampleRate());
fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, handleGetSampleRate());
}
// -------------------------------------------------------------------

View File

@@ -788,16 +788,18 @@ void lb302Synth::processNote( NotePlayHandle * _n )
void lb302Synth::play( sampleFrame * _working_buffer )
{
m_notesMutex.lock();
while( ! m_notes.isEmpty() )
{
processNote( m_notes.takeFirst() );
};
m_notesMutex.unlock();
const fpp_t frames = Engine::mixer()->framesPerPeriod();
process( _working_buffer, frames );
instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL );
release_frame = 0;
// release_frame = 0; //removed for issue # 1432
}

View File

@@ -497,7 +497,7 @@ void opl2instrument::loadPatch(unsigned char inst[14]) {
void opl2instrument::tuneEqual(int center, float Hz) {
float tmp;
for(int n=0; n<128; ++n) {
tmp = Hz*pow( 2, ( n - center ) / 12.0 + pitchbend / 1200.0 );
tmp = Hz*pow( 2.0, ( n - center ) * ( 1.0 / 12.0 ) + pitchbend * ( 1.0 / 1200.0 ) );
fnums[n] = Hz2fnum( tmp );
}
}
@@ -505,7 +505,7 @@ void opl2instrument::tuneEqual(int center, float Hz) {
// Find suitable F number in lowest possible block
int opl2instrument::Hz2fnum(float Hz) {
for(int block=0; block<8; ++block) {
unsigned int fnum = Hz * pow(2, 20-block) / 49716;
unsigned int fnum = Hz * pow( 2.0, 20.0 - (double)block ) * ( 1.0 / 49716.0 );
if(fnum<1023) {
return fnum + (block << 10);
}

View File

@@ -361,11 +361,11 @@ void papuInstrument::playNote( NotePlayHandle * _n,
//PRNG Frequency = (1048576 Hz / (ratio + 1)) / 2 ^ (shiftclockfreq + 1)
char sopt=0;
char ropt=1;
float fopt = 524288.0 / ( ropt * pow( 2, sopt+1 ) );
float fopt = 524288.0 / ( ropt * pow( 2.0, sopt + 1.0 ) );
float f;
for ( char s=0; s<16; s++ )
for ( char r=0; r<8; r++ ) {
f = 524288.0 / ( r * pow( 2, s+1 ) );
f = 524288.0 / ( r * pow( 2.0, s + 1.0 ) );
if( fabs( freq-fopt ) > fabs( freq-f ) ) {
fopt = f;
ropt = r;

View File

@@ -172,10 +172,11 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable )
QString p = m_plugin;
if( QFileInfo( p ).dir().isRelative() )
{
p = ConfigManager::inst()->vstDir() + QDir::separator() + p;
}
if( QFileInfo( p ).dir().isRelative() )
{
p = ConfigManager::inst()->vstDir() + p;
}
sendMessage( message( IdVstLoadPlugin ).addString( QSTR_TO_STDSTR( p ) ) );
@@ -420,7 +421,7 @@ void VstPlugin::setParameterDump( const QMap<QString, QString> & _pdump )
{
( *it ).section( ':', 0, 0 ).toInt(),
"",
( *it ).section( ':', 1, 1 ).toFloat()
( *it ).section( ':', 2, -1 ).toFloat()
} ;
m.addInt( item.index );
m.addString( item.shortLabel );

View File

@@ -89,6 +89,7 @@ LocalZynAddSubFx::LocalZynAddSubFx() :
LocalZynAddSubFx::~LocalZynAddSubFx()
{
delete m_master;
delete m_ioEngine;
if( --s_instanceCount == 0 )
{

View File

@@ -290,7 +290,13 @@ void ConfigManager::loadConfigFile()
node = node.nextSibling();
}
if( value( "paths", "artwork" ) != "" )
// don't use dated theme folders as they break the UI (i.e. 0.4 != 1.0, etc)
bool use_artwork_path =
root.attribute( "version" ).startsWith(
QString::number( LMMS_VERSION_MAJOR ) + "." +
QString::number( LMMS_VERSION_MINOR ) );
if( use_artwork_path && value( "paths", "artwork" ) != "" )
{
m_artworkDir = value( "paths", "artwork" );
if( !QDir( m_artworkDir ).exists() )

View File

@@ -205,8 +205,11 @@ Controller * Controller::create( ControllerTypes _ct, Model * _parent )
if( dummy )
c = dummy;
else
{
c = new Controller( DummyController, NULL,
QString() );
dummy = c;
}
break;
case Controller::LfoController:

View File

@@ -131,7 +131,7 @@ bool RemotePlugin::init( const QString &pluginExecutable,
m_failed = false;
}
QString exec = ConfigManager::inst()->pluginDir() +
QDir::separator() + pluginExecutable;
pluginExecutable;
QStringList args;
// swap in and out for bidirectional communication

View File

@@ -957,6 +957,7 @@ void SampleBuffer::visualize( QPainter & _p, const QRect & _dr,
_p.drawPolyline( l, nb_frames / fpp );
_p.drawPolyline( r, nb_frames / fpp );
delete[] l;
delete[] r;
}

View File

@@ -619,6 +619,7 @@ void Song::stop()
void Song::startExport()
{
stop();
m_playPos[Mode_PlaySong].setTicks( 0 );
playSong();

View File

@@ -194,12 +194,13 @@ void FxMixerView::refreshDisplay()
for( int i = 1; i<m_fxChannelViews.size(); ++i )
{
chLayout->removeWidget(m_fxChannelViews[i]->m_fxLine);
m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );
delete m_fxChannelViews[i]->m_fader;
delete m_fxChannelViews[i]->m_muteBtn;
delete m_fxChannelViews[i]->m_soloBtn;
delete m_fxChannelViews[i]->m_fxLine;
delete m_fxChannelViews[i]->m_rackView;
delete m_fxChannelViews[i];
m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );
}
m_channelAreaWidget->adjustSize();
@@ -363,16 +364,15 @@ void FxMixerView::deleteChannel(int index)
// delete the view
chLayout->removeWidget(m_fxChannelViews[index]->m_fxLine);
m_racksLayout->removeWidget( m_fxChannelViews[index]->m_rackView );
delete m_fxChannelViews[index]->m_fader;
delete m_fxChannelViews[index]->m_muteBtn;
delete m_fxChannelViews[index]->m_soloBtn;
delete m_fxChannelViews[index]->m_fxLine;
delete m_fxChannelViews[index]->m_rackView;
delete m_fxChannelViews[index];
m_channelAreaWidget->adjustSize();
// delete the fx rack
m_racksLayout->removeWidget( m_fxChannelViews[index]->m_rackView );
// make sure every channel knows what index it is
for(int i=0; i<m_fxChannelViews.size(); ++i)
{

View File

@@ -70,6 +70,11 @@
#include "TextFloat.h"
#if QT_VERSION < 0x040800
#define MiddleButton MidButton
#endif
typedef AutomationPattern::timeMap timeMap;

View File

@@ -29,6 +29,8 @@
#include <QScrollArea>
#include "PluginBrowser.h"
#include <algorithm> // for std::sort
#include "embed.h"
#include "debug.h"
#include "templates.h"

View File

@@ -170,7 +170,7 @@ void Fader::mouseMoveEvent( QMouseEvent *mouseEvent )
{
int dy = m_moveStartPoint - mouseEvent->globalY();
float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - ( *s_knob ).height() );
float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - ( *m_knob ).height() );
model()->setValue( m_startValue + delta );
@@ -186,7 +186,7 @@ void Fader::mousePressEvent( QMouseEvent* mouseEvent )
if( mouseEvent->button() == Qt::LeftButton &&
! ( mouseEvent->modifiers() & Qt::ControlModifier ) )
{
if( mouseEvent->y() >= knobPosY() - ( *s_knob ).height() && mouseEvent->y() < knobPosY() )
if( mouseEvent->y() >= knobPosY() - ( *m_knob ).height() && mouseEvent->y() < knobPosY() )
{
updateTextFloat();
s_textFloat->show();
@@ -346,13 +346,16 @@ void Fader::paintEvent( QPaintEvent * ev)
// background
painter.drawPixmap( ev->rect(), *m_back, ev->rect() );
// peak leds
//float fRange = abs( m_fMaxPeak ) + abs( m_fMinPeak );
int height = m_back->height();
int width = m_back->width() / 2;
int center = m_back->width() - width;
int peak_L = calculateDisplayPeak( m_fPeakValue_L - m_fMinPeak );
int persistentPeak_L = qMax<int>( 3, calculateDisplayPeak( m_persistentPeak_L - m_fMinPeak ) );
painter.drawPixmap( QRect( 0, peak_L, 11, 116 - peak_L ), *m_leds, QRect( 0, peak_L, 11, 116 - peak_L ) );
painter.drawPixmap( QRect( 0, peak_L, width, height - peak_L ), *m_leds, QRect( 0, peak_L, width, height - peak_L ) );
if( m_persistentPeak_L > 0.05 )
{
@@ -363,7 +366,7 @@ void Fader::paintEvent( QPaintEvent * ev)
int peak_R = calculateDisplayPeak( m_fPeakValue_R - m_fMinPeak );
int persistentPeak_R = qMax<int>( 3, calculateDisplayPeak( m_persistentPeak_R - m_fMinPeak ) );
painter.drawPixmap( QRect( 11, peak_R, 11, 116 - peak_R ), *m_leds, QRect( 11, peak_R, 11, 116 - peak_R ) );
painter.drawPixmap( QRect( center, peak_R, width, height - peak_R ), *m_leds, QRect( center, peak_R, width, height - peak_R ) );
if( m_persistentPeak_R > 0.05 )
{
@@ -373,7 +376,7 @@ void Fader::paintEvent( QPaintEvent * ev)
}
// knob
painter.drawPixmap( 0, knobPosY() - ( *m_knob ).height(), *s_knob );
painter.drawPixmap( 0, knobPosY() - m_knob->height(), *m_knob );
}

View File

@@ -87,7 +87,7 @@ const char * volume_help = QT_TRANSLATE_NOOP( "InstrumentTrack",
const int INSTRUMENT_WIDTH = 254;
const int INSTRUMENT_HEIGHT = INSTRUMENT_WIDTH;
const int PIANO_HEIGHT = 84;
const int PIANO_HEIGHT = 82;
const int INSTRUMENT_WINDOW_CACHE_SIZE = 8;

View File

@@ -47,6 +47,7 @@
#include "EffectRackView.h"
#include "TrackLabelButton.h"
#include "ConfigManager.h"
#include "panning_constants.h"
SampleTCO::SampleTCO( Track * _track ) :
@@ -405,9 +406,12 @@ SampleTrack::SampleTrack( TrackContainer* tc ) :
Track( Track::SampleTrack, tc ),
m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 1.0, this,
tr( "Volume" ) ),
m_audioPort( tr( "Sample track" ), true, &m_volumeModel, NULL )
m_panningModel( DefaultPanning, PanningLeft, PanningRight, 0.1f,
this, tr( "Panning" ) ),
m_audioPort( tr( "Sample track" ), true, &m_volumeModel, &m_panningModel )
{
setName( tr( "Sample track" ) );
m_panningModel.setCenterValue( DefaultPanning );
}
@@ -492,6 +496,7 @@ void SampleTrack::saveTrackSpecificSettings( QDomDocument & _doc,
_this.setAttribute( "icon", tlb->pixmapFile() );
#endif
m_volumeModel.saveSettings( _doc, _this, "vol" );
m_panningModel.saveSettings( _doc, _this, "pan" );
}
@@ -513,6 +518,7 @@ void SampleTrack::loadTrackSpecificSettings( const QDomElement & _this )
node = node.nextSibling();
}
m_volumeModel.loadSettings( _this, "vol" );
m_panningModel.loadSettings( _this, "pan" );
}
@@ -550,6 +556,14 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
m_volumeKnob->setLabel( tr( "VOL" ) );
m_volumeKnob->show();
m_panningKnob = new Knob( knobSmall_17, getTrackSettingsWidget(),
tr( "Panning" ) );
m_panningKnob->setModel( &_t->m_panningModel );
m_panningKnob->setHintText( tr( "Panning:" ), "%" );
m_panningKnob->move( DEFAULT_SETTINGS_WIDGET_WIDTH-24, 2 );
m_panningKnob->setLabel( tr( "PAN" ) );
m_panningKnob->show();
m_effectRack = new EffectRackView( _t->audioPort()->effects() );
m_effectRack->setFixedSize( 240, 242 );