Merge branch 'stable-1.1'
Conflicts: include/basic_filters.h src/core/FxMixer.cpp
This commit is contained in:
@@ -61,10 +61,14 @@ public:
|
||||
static const int FxLineHeight;
|
||||
|
||||
private:
|
||||
static void drawFxLine( QPainter* p, const FxLine *fxLine, const QString& name, bool isActive, bool sendToThis, bool receiveFromThis );
|
||||
|
||||
FxMixerView * m_mv;
|
||||
LcdWidget* m_lcd;
|
||||
int m_channelIndex;
|
||||
QBrush m_backgroundActive;
|
||||
static QPixmap * s_sendBgArrow;
|
||||
static QPixmap * s_receiveBgArrow;
|
||||
|
||||
private slots:
|
||||
void renameChannel();
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
#include "ThreadableJob.h"
|
||||
|
||||
|
||||
|
||||
class FxRoute;
|
||||
typedef QVector<FxRoute *> FxRouteVector;
|
||||
|
||||
class FxChannel : public ThreadableJob
|
||||
{
|
||||
@@ -58,11 +59,10 @@ class FxChannel : public ThreadableJob
|
||||
bool m_queued; // are we queued up for rendering yet?
|
||||
|
||||
// pointers to other channels that this one sends to
|
||||
QVector<fx_ch_t> m_sends;
|
||||
QVector<FloatModel *> m_sendAmount;
|
||||
FxRouteVector m_sends;
|
||||
|
||||
// pointers to other channels that send to this one
|
||||
QVector<fx_ch_t> m_receives;
|
||||
FxRouteVector m_receives;
|
||||
|
||||
virtual bool requiresProcessing() const { return true; }
|
||||
|
||||
@@ -71,6 +71,45 @@ class FxChannel : public ThreadableJob
|
||||
};
|
||||
|
||||
|
||||
class FxRoute : public QObject
|
||||
{
|
||||
public:
|
||||
FxRoute( FxChannel * from, FxChannel * to, float amount );
|
||||
virtual ~FxRoute();
|
||||
|
||||
fx_ch_t senderIndex() const
|
||||
{
|
||||
return m_from->m_channelIndex;
|
||||
}
|
||||
|
||||
fx_ch_t receiverIndex() const
|
||||
{
|
||||
return m_to->m_channelIndex;
|
||||
}
|
||||
|
||||
FloatModel * amount() const
|
||||
{
|
||||
return m_amount;
|
||||
}
|
||||
|
||||
FxChannel * sender() const
|
||||
{
|
||||
return m_from;
|
||||
}
|
||||
|
||||
FxChannel * receiver() const
|
||||
{
|
||||
return m_to;
|
||||
}
|
||||
|
||||
void updateName();
|
||||
|
||||
private:
|
||||
FxChannel * m_from;
|
||||
FxChannel * m_to;
|
||||
FloatModel * m_amount;
|
||||
};
|
||||
|
||||
|
||||
class EXPORT FxMixer : public JournallingObject, public Model
|
||||
{
|
||||
@@ -100,13 +139,16 @@ public:
|
||||
// it is safe to call even if the send already exists
|
||||
void createChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel,
|
||||
float amount = 1.0f);
|
||||
void createRoute( FxChannel * from, FxChannel * to, float amount );
|
||||
|
||||
// delete the connection made by createChannelSend
|
||||
void deleteChannelSend(fx_ch_t fromChannel, fx_ch_t toChannel);
|
||||
void deleteChannelSend( FxRoute * route );
|
||||
|
||||
// determine if adding a send from sendFrom to
|
||||
// sendTo would result in an infinite mixer loop.
|
||||
bool isInfiniteLoop(fx_ch_t fromChannel, fx_ch_t toChannel);
|
||||
bool checkInfiniteLoop( FxChannel * from, FxChannel * to );
|
||||
|
||||
// return the FloatModel of fromChannel sending its output to the input of
|
||||
// toChannel. NULL if there is no send.
|
||||
@@ -129,11 +171,16 @@ public:
|
||||
// reset a channel's name, fx, sends, etc
|
||||
void clearChannel(fx_ch_t channelIndex);
|
||||
|
||||
// rename channels when moving etc. if they still have their original name
|
||||
void validateChannelName( int index, int oldIndex );
|
||||
|
||||
inline fx_ch_t numChannels() const
|
||||
{
|
||||
return m_fxChannels.size();
|
||||
}
|
||||
|
||||
FxRouteVector m_fxRoutes;
|
||||
|
||||
private:
|
||||
// the fx channels in the mixer. index 0 is always master.
|
||||
QVector<FxChannel *> m_fxChannels;
|
||||
@@ -142,7 +189,7 @@ private:
|
||||
void allocateChannelsTo(int num);
|
||||
QMutex m_sendsMutex;
|
||||
|
||||
void addChannelLeaf( int _ch, sampleFrame * _buf );
|
||||
void addChannelLeaf( FxChannel * ch, sampleFrame * buf );
|
||||
|
||||
friend class MixerWorkerThread;
|
||||
friend class FxMixerView;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* basic_filters.h - simple but powerful filter-class with most used filters
|
||||
*
|
||||
* original file by ???
|
||||
* original file by ???
|
||||
* modified and enhanced by Tobias Doerffel
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -26,8 +26,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BASIC_FILTERS_H
|
||||
#define _BASIC_FILTERS_H
|
||||
#ifndef BASIC_FILTERS_H
|
||||
#define BASIC_FILTERS_H
|
||||
|
||||
#ifndef __USE_XOPEN
|
||||
#define __USE_XOPEN
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "Mixer.h"
|
||||
#include "templates.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "interpolation.h"
|
||||
|
||||
//#include <iostream>
|
||||
//#include <cstdlib>
|
||||
@@ -127,16 +128,16 @@ public:
|
||||
// reset in/out history for simple filters
|
||||
m_ou1[_chnl] = m_ou2[_chnl] = m_in1[_chnl] =
|
||||
m_in2[_chnl] = 0.0f;
|
||||
|
||||
|
||||
// reset in/out history for moog-filter
|
||||
m_y1[_chnl] = m_y2[_chnl] = m_y3[_chnl] = m_y4[_chnl] =
|
||||
m_oldx[_chnl] = m_oldy1[_chnl] =
|
||||
m_oldy2[_chnl] = m_oldy3[_chnl] = 0.0f;
|
||||
|
||||
|
||||
// reset in/out history for RC-filters
|
||||
m_rclp0[_chnl] = m_rcbp0[_chnl] = m_rchp0[_chnl] = m_rclast0[_chnl] = 0.0f;
|
||||
m_rclp1[_chnl] = m_rcbp1[_chnl] = m_rchp1[_chnl] = m_rclast1[_chnl] = 0.0f;
|
||||
|
||||
|
||||
for(int i=0; i<6; i++)
|
||||
m_vfbp[i][_chnl] = m_vfhp[i][_chnl] = m_vflast[i][_chnl] = 0.0f;
|
||||
}
|
||||
@@ -186,130 +187,135 @@ public:
|
||||
// (C) 1998 ... 2009 S.Fendt. Released under the GPL v2.0 or any later version.
|
||||
|
||||
case Lowpass_RC12:
|
||||
case Bandpass_RC12:
|
||||
case Highpass_RC12:
|
||||
{
|
||||
sample_t lp, hp, bp;
|
||||
|
||||
sample_t in;
|
||||
|
||||
// 4-times oversampled... (even the moog-filter would benefit from this)
|
||||
sample_t lp, bp, hp, in;
|
||||
for( int n = 4; n != 0; --n )
|
||||
{
|
||||
in = _in0 + m_rcbp0[_chnl] * m_rcq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
|
||||
lp = (lp > +1.f) ? +1.f : lp;
|
||||
lp = (lp < -1.f) ? -1.f : lp;
|
||||
lp = qBound( -1.0f, lp, 1.0f );
|
||||
|
||||
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_rclast0[_chnl] = in;
|
||||
m_rclp0[_chnl] = lp;
|
||||
m_rchp0[_chnl] = hp;
|
||||
m_rcbp0[_chnl] = bp;
|
||||
}
|
||||
return lp;
|
||||
break;
|
||||
}
|
||||
case Highpass_RC12:
|
||||
case Bandpass_RC12:
|
||||
{
|
||||
sample_t hp, bp, in;
|
||||
for( int n = 4; n != 0; --n )
|
||||
{
|
||||
in = _in0 + m_rcbp0[_chnl] * m_rcq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
if( m_type == Lowpass_RC12 )
|
||||
out = lp;
|
||||
else if( m_type == Bandpass_RC12 )
|
||||
out = bp;
|
||||
else
|
||||
out = hp;
|
||||
|
||||
return( out );
|
||||
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_rclast0[_chnl] = in;
|
||||
m_rchp0[_chnl] = hp;
|
||||
m_rcbp0[_chnl] = bp;
|
||||
}
|
||||
return m_type == Highpass_RC12 ? hp : bp;
|
||||
break;
|
||||
}
|
||||
|
||||
case Lowpass_RC24:
|
||||
case Bandpass_RC24:
|
||||
case Highpass_RC24:
|
||||
{
|
||||
sample_t lp, hp, bp;
|
||||
|
||||
sample_t in;
|
||||
|
||||
sample_t lp, bp, hp, in;
|
||||
for( int n = 4; n != 0; --n )
|
||||
{
|
||||
// first stage is as for the 12dB case...
|
||||
in = _in0 + m_rcbp0[_chnl] * m_rcq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
|
||||
lp = (lp > +1.f) ? +1.f : lp;
|
||||
lp = (lp < -1.f) ? -1.f : lp;
|
||||
lp = qBound( -1.0f, lp, 1.0f );
|
||||
|
||||
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_rclast0[_chnl] = in;
|
||||
m_rclp0[_chnl] = lp;
|
||||
m_rcbp0[_chnl] = bp;
|
||||
m_rchp0[_chnl] = hp;
|
||||
|
||||
// second stage gets the output of the first stage as input...
|
||||
in = lp + m_rcbp1[_chnl] * m_rcq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
lp = in * m_rcb + m_rclp1[_chnl] * m_rca;
|
||||
lp = qBound( -1.0f, lp, 1.0f );
|
||||
|
||||
hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_rclast1[_chnl] = in;
|
||||
m_rclp1[_chnl] = lp;
|
||||
m_rcbp1[_chnl] = bp;
|
||||
m_rchp1[_chnl] = hp;
|
||||
}
|
||||
return lp;
|
||||
break;
|
||||
}
|
||||
case Highpass_RC24:
|
||||
case Bandpass_RC24:
|
||||
{
|
||||
sample_t hp, bp, in;
|
||||
for( int n = 4; n != 0; --n )
|
||||
{
|
||||
// first stage is as for the 12dB case...
|
||||
in = _in0 + m_rcbp0[_chnl] * m_rcq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_rclast0[_chnl] = in;
|
||||
m_rchp0[_chnl] = hp;
|
||||
m_rcbp0[_chnl] = bp;
|
||||
|
||||
// second stage gets the output of the first stage as input...
|
||||
if( m_type == Lowpass_RC24 )
|
||||
{
|
||||
in = lp + m_rcbp1[_chnl] * m_rcq;
|
||||
}
|
||||
else if( m_type == Bandpass_RC24 )
|
||||
{
|
||||
in = bp + m_rcbp1[_chnl] * m_rcq;
|
||||
}
|
||||
else
|
||||
{
|
||||
in = hp + m_rcbp1[_chnl] * m_rcq;
|
||||
}
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = m_type == Highpass_RC24
|
||||
? hp + m_rcbp1[_chnl] * m_rcq
|
||||
: bp + m_rcbp1[_chnl] * m_rcq;
|
||||
|
||||
lp = in * m_rcb + m_rclp1[_chnl] * m_rca;
|
||||
lp = (lp > +1.f) ? +1.f : lp;
|
||||
lp = (lp < -1.f) ? -1.f : lp;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_rclast1[_chnl] = in;
|
||||
m_rclp1[_chnl] = lp;
|
||||
m_rchp1[_chnl] = hp;
|
||||
m_rcbp1[_chnl] = bp;
|
||||
}
|
||||
|
||||
// output is second stage-lowpass...
|
||||
if( m_type == Lowpass_RC24 )
|
||||
{
|
||||
out = lp;
|
||||
}
|
||||
else if( m_type == Bandpass_RC24 )
|
||||
{
|
||||
out = bp;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = hp;
|
||||
}
|
||||
|
||||
return out;
|
||||
return m_type == Highpass_RC24 ? hp : bp;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -317,116 +323,97 @@ public:
|
||||
{
|
||||
sample_t hp, bp, in;
|
||||
|
||||
out = 0;
|
||||
for(int o=0; o<4; o++)
|
||||
{
|
||||
// first formant
|
||||
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
out = 0;
|
||||
for(int o=0; o<4; o++)
|
||||
{
|
||||
// first formant
|
||||
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0];
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0];
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_vflast[0][_chnl] = in;
|
||||
m_vfhp[0][_chnl] = hp;
|
||||
m_vfbp[0][_chnl] = bp;
|
||||
m_vflast[0][_chnl] = in;
|
||||
m_vfhp[0][_chnl] = hp;
|
||||
m_vfbp[0][_chnl] = bp;
|
||||
|
||||
in = bp + m_vfbp[2][_chnl] * m_vfq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = bp + m_vfbp[2][_chnl] * m_vfq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_vfc[0] * ( m_vfhp[2][_chnl] + in - m_vflast[2][_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = m_vfc[0] * ( m_vfhp[2][_chnl] + in - m_vflast[2][_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_vfb[0] + m_vfbp[2][_chnl] * m_vfa[0];
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = hp * m_vfb[0] + m_vfbp[2][_chnl] * m_vfa[0];
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_vflast[2][_chnl] = in;
|
||||
m_vfhp[2][_chnl] = hp;
|
||||
m_vfbp[2][_chnl] = bp;
|
||||
m_vflast[2][_chnl] = in;
|
||||
m_vfhp[2][_chnl] = hp;
|
||||
m_vfbp[2][_chnl] = bp;
|
||||
|
||||
in = bp + m_vfbp[4][_chnl] * m_vfq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = bp + m_vfbp[4][_chnl] * m_vfq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_vfc[0] * ( m_vfhp[4][_chnl] + in - m_vflast[4][_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = m_vfc[0] * ( m_vfhp[4][_chnl] + in - m_vflast[4][_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_vfb[0] + m_vfbp[4][_chnl] * m_vfa[0];
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = hp * m_vfb[0] + m_vfbp[4][_chnl] * m_vfa[0];
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_vflast[4][_chnl] = in;
|
||||
m_vfhp[4][_chnl] = hp;
|
||||
m_vfbp[4][_chnl] = bp;
|
||||
m_vflast[4][_chnl] = in;
|
||||
m_vfhp[4][_chnl] = hp;
|
||||
m_vfbp[4][_chnl] = bp;
|
||||
|
||||
out += bp;
|
||||
out += bp;
|
||||
|
||||
// second formant
|
||||
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
// second formant
|
||||
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_vfc[1] * ( m_vfhp[1][_chnl] + in - m_vflast[1][_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = m_vfc[1] * ( m_vfhp[1][_chnl] + in - m_vflast[1][_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_vfb[1] + m_vfbp[1][_chnl] * m_vfa[1];
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = hp * m_vfb[1] + m_vfbp[1][_chnl] * m_vfa[1];
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_vflast[1][_chnl] = in;
|
||||
m_vfhp[1][_chnl] = hp;
|
||||
m_vfbp[1][_chnl] = bp;
|
||||
m_vflast[1][_chnl] = in;
|
||||
m_vfhp[1][_chnl] = hp;
|
||||
m_vfbp[1][_chnl] = bp;
|
||||
|
||||
in = bp + m_vfbp[3][_chnl] * m_vfq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = bp + m_vfbp[3][_chnl] * m_vfq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_vfc[1] * ( m_vfhp[3][_chnl] + in - m_vflast[3][_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = m_vfc[1] * ( m_vfhp[3][_chnl] + in - m_vflast[3][_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_vfb[1] + m_vfbp[3][_chnl] * m_vfa[1];
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = hp * m_vfb[1] + m_vfbp[3][_chnl] * m_vfa[1];
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_vflast[3][_chnl] = in;
|
||||
m_vfhp[3][_chnl] = hp;
|
||||
m_vfbp[3][_chnl] = bp;
|
||||
m_vflast[3][_chnl] = in;
|
||||
m_vfhp[3][_chnl] = hp;
|
||||
m_vfbp[3][_chnl] = bp;
|
||||
|
||||
in = bp + m_vfbp[5][_chnl] * m_vfq;
|
||||
in = (in > +1.f) ? +1.f : in;
|
||||
in = (in < -1.f) ? -1.f : in;
|
||||
in = bp + m_vfbp[5][_chnl] * m_vfq;
|
||||
in = qBound( -1.0f, in, 1.0f );
|
||||
|
||||
hp = m_vfc[1] * ( m_vfhp[5][_chnl] + in - m_vflast[5][_chnl] );
|
||||
hp = (hp > +1.f) ? +1.f : hp;
|
||||
hp = (hp < -1.f) ? -1.f : hp;
|
||||
hp = m_vfc[1] * ( m_vfhp[5][_chnl] + in - m_vflast[5][_chnl] );
|
||||
hp = qBound( -1.0f, hp, 1.0f );
|
||||
|
||||
bp = hp * m_vfb[1] + m_vfbp[5][_chnl] * m_vfa[1];
|
||||
bp = (bp > +1.f) ? +1.f : bp;
|
||||
bp = (bp < -1.f) ? -1.f : bp;
|
||||
bp = hp * m_vfb[1] + m_vfbp[5][_chnl] * m_vfa[1];
|
||||
bp = qBound( -1.0f, bp, 1.0f );
|
||||
|
||||
m_vflast[5][_chnl] = in;
|
||||
m_vfhp[5][_chnl] = hp;
|
||||
m_vfbp[5][_chnl] = bp;
|
||||
m_vflast[5][_chnl] = in;
|
||||
m_vfhp[5][_chnl] = hp;
|
||||
m_vfbp[5][_chnl] = bp;
|
||||
|
||||
out += bp;
|
||||
}
|
||||
|
||||
return( out/2.0f );
|
||||
out += bp;
|
||||
}
|
||||
return( out/2.0f );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// filter
|
||||
out = m_b0a0*_in0 +
|
||||
@@ -458,9 +445,6 @@ public:
|
||||
/*, const bool _q_is_bandwidth = false*/ )
|
||||
{
|
||||
// temp coef vars
|
||||
_freq = qBound(minFreq(), _freq, 20000.0f); // limit freq and q for not getting
|
||||
// bad noise out of the filter...
|
||||
|
||||
_q = qMax( _q, minQ() );
|
||||
|
||||
if( m_type == Lowpass_RC12 ||
|
||||
@@ -470,41 +454,39 @@ public:
|
||||
m_type == Bandpass_RC24 ||
|
||||
m_type == Highpass_RC24 )
|
||||
{
|
||||
if( _freq < 50.f )
|
||||
{
|
||||
_freq = 50.f;
|
||||
}
|
||||
|
||||
_freq = qBound( 50.0f, _freq, 20000.0f );
|
||||
|
||||
m_rca = 1.0f - (1.0f/(m_sampleRate*4)) / ( (1.0f/(_freq*2.0f*M_PI)) + (1.0f/(m_sampleRate*4)) );
|
||||
m_rcb = 1.0f - m_rca;
|
||||
m_rcc = (1.0f/(_freq*2.0f*M_PI)) / ( (1.0f/(_freq*2.0f*M_PI)) + (1.0f/(m_sampleRate*4)) );
|
||||
|
||||
|
||||
// Stretch Q/resonance, as self-oscillation reliably starts at a q of ~2.5 - ~2.6
|
||||
m_rcq = _q/4.f;
|
||||
m_rcq = _q * 0.25f;
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_type == Formantfilter )
|
||||
{
|
||||
_freq = qBound( minFreq(), _freq, 20000.0f ); // limit freq and q for not getting bad noise out of the filter...
|
||||
|
||||
// formats for a, e, i, o, u, a
|
||||
const float _f[5][2] = { { 1000, 1400 }, { 500, 2300 },
|
||||
static const float _f[5][2] = { { 1000, 1400 }, { 500, 2300 },
|
||||
{ 320, 3200 },
|
||||
{ 500, 1000 },
|
||||
{ 320, 800 } };
|
||||
static const float freqRatio = 4.0f / 14000.0f;
|
||||
|
||||
// Stretch Q/resonance
|
||||
m_vfq = _q/4.f;
|
||||
m_vfq = _q * 0.25f;
|
||||
|
||||
// frequency in lmms ranges from 1Hz to 14000Hz
|
||||
const int vowel = (int)( floor( _freq/14000.f * 4.f ) );
|
||||
const float fract = ( _freq/14000.f * 4.f ) -
|
||||
(float)vowel;
|
||||
const float vowelf = _freq * freqRatio;
|
||||
const int vowel = static_cast<int>( vowelf );
|
||||
const float fract = vowelf - vowel;
|
||||
|
||||
// interpolate between formant frequencies
|
||||
const float f0 = _f[vowel+0][0] * ( 1.0f - fract ) +
|
||||
_f[vowel+1][0] * ( fract );
|
||||
|
||||
const float f1 = _f[vowel+0][1] * ( 1.0f - fract ) +
|
||||
_f[vowel+1][1] * ( fract );
|
||||
// interpolate between formant frequencies
|
||||
const float f0 = linearInterpolate( _f[vowel+0][0], _f[vowel+1][0], fract );
|
||||
const float f1 = linearInterpolate( _f[vowel+0][1], _f[vowel+1][1], fract );
|
||||
|
||||
m_vfa[0] = 1.0f - (1.0f/(m_sampleRate*4)) /
|
||||
( (1.0f/(f0*2.0f*M_PI)) +
|
||||
@@ -521,10 +503,13 @@ public:
|
||||
m_vfc[1] = (1.0f/(f1*2.0f*M_PI)) /
|
||||
( (1.0f/(f1*2.0f*M_PI)) +
|
||||
(1.0f/(m_sampleRate*4)) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if( m_type == Moog )
|
||||
{
|
||||
_freq = qBound( minFreq(), _freq, 20000.0f );
|
||||
|
||||
// [ 0 - 0.5 ]
|
||||
const float f = _freq / m_sampleRate;
|
||||
// (Empirical tunning)
|
||||
@@ -542,6 +527,7 @@ public:
|
||||
}
|
||||
|
||||
// other filters
|
||||
_freq = qBound( minFreq(), _freq, 20000.0f );
|
||||
const float omega = F_2PI * _freq / m_sampleRate;
|
||||
const float tsin = sinf( omega );
|
||||
const float tcos = cosf( omega );
|
||||
@@ -617,7 +603,7 @@ private:
|
||||
|
||||
// coeffs for formant-filters
|
||||
float m_vfa[4], m_vfb[4], m_vfc[4], m_vfq;
|
||||
|
||||
|
||||
typedef sample_t frame[CHANNELS];
|
||||
|
||||
// in/out history
|
||||
@@ -625,7 +611,7 @@ private:
|
||||
|
||||
// in/out history for moog-filter
|
||||
frame m_y1, m_y2, m_y3, m_y4, m_oldx, m_oldy1, m_oldy2, m_oldy3;
|
||||
|
||||
|
||||
// in/out history for RC-type-filters
|
||||
frame m_rcbp0, m_rclp0, m_rchp0, m_rclast0;
|
||||
frame m_rcbp1, m_rclp1, m_rchp1, m_rclast1;
|
||||
|
||||
Reference in New Issue
Block a user