float *FFTRealSelect::sel_bin(float *e_ptr, float *o_ptr) {
29 | return (o_ptr);
30 | }
31 |
32 | template <>
33 | inline float *FFTRealSelect<0>::sel_bin(float *e_ptr, float *o_ptr) {
34 | return (e_ptr);
35 | }
36 |
37 | }
38 |
39 | #endif
40 |
41 | #undef ffft_FFTRealSelect_CURRENT_CODEHEADER
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/FFTReal/FFTRealUseTrigo.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 |
3 | FFTRealUseTrigo.h
4 | By Laurent de Soras
5 |
6 | --- Legal stuff ---
7 |
8 | This program is free software. It comes without any warranty, to
9 | the extent permitted by applicable law. You can redistribute it
10 | and/or modify it under the terms of the Do What The Fuck You Want
11 | To Public License, Version 2, as published by Sam Hocevar. See
12 | http://sam.zoy.org/wtfpl/COPYING for more details.
13 |
14 | *Tab=3***********************************************************************/
15 |
16 | #if defined(ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
17 | #error Recursive inclusion of FFTRealUseTrigo code header.
18 | #endif
19 | #define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
20 |
21 | #if !defined(ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
22 | #define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
23 |
24 |
25 |
26 | #include "ffft/OscSinCos.h"
27 |
28 | namespace ffft {
29 |
30 |
31 |
32 | template void FFTRealUseTrigo::prepare(OscType &osc) {
33 | osc.clear_buffers();
34 | }
35 |
36 | template <> inline void FFTRealUseTrigo<0>::prepare(OscType &osc) {
37 |
38 | }
39 |
40 | template
41 | void FFTRealUseTrigo::iterate(OscType &osc, DataType &c, DataType &s,
42 | const DataType cos_ptr[], long index_c,
43 | long index_s) {
44 | osc.step();
45 | c = osc.get_cos();
46 | s = osc.get_sin();
47 | }
48 |
49 | template <>
50 | inline void FFTRealUseTrigo<0>::iterate(OscType &osc, DataType &c, DataType &s,
51 | const DataType cos_ptr[], long index_c,
52 | long index_s) {
53 | c = cos_ptr[index_c];
54 | s = cos_ptr[index_s];
55 | }
56 |
57 |
58 |
59 |
60 |
61 | }
62 |
63 | #endif
64 |
65 | #undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
66 |
67 |
68 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/LPFCombFilter.h:
--------------------------------------------------------------------------------
1 | /*
2 | CLPFCombFilter: implements a comb filter of length D with
3 | feedback gain m_fComb_g and LPF gain
4 | m_fLPF_g
5 |
6 | Can be used alone or as a base class.
7 |
8 |
9 |
10 | */
11 |
12 | // Inherited Base Class functions:
13 | /*
14 | void init(int nDelayLength);
15 | void resetDelay();
16 | void setDelay_mSec(float fmSec);
17 | void setOutputAttenuation_dB(float fAttendB);
18 |
19 | // NEED TO OVERRIDE
20 | bool processAudio(float *pInput, float *pOutput);
21 | */
22 | #pragma once
23 | #include "CDelay.h"
24 |
25 | // derived from CDelay
26 | class CLPFCombFilter : public CDelay {
27 | public:
28 | // constructor/destructor
29 | CLPFCombFilter();
30 | ~CLPFCombFilter();
31 |
32 | // members
33 | protected:
34 | float m_fComb_g; // one Comb coefficient
35 | float m_fLPF_g; // one LPF coefficient
36 | float m_fLPF_z1; // one sample delay
37 |
38 | public:
39 | // set our g value directly
40 | void setComb_g(float fCombg) { m_fComb_g = fCombg; }
41 |
42 | // set our g value using RT60
43 | void setComb_g_with_RTSixty(float fRT) {
44 | float fExponent = -3.0f * m_fDelayInSamples * (1.0f / m_nSampleRate);
45 | fRT /= 1000.0; // RT is in mSec!
46 |
47 | m_fComb_g = powf((float)10.0, fExponent / fRT);
48 | }
49 |
50 | // set the LPF gain
51 | // NOTE: call setComb_g_with_RTSixty FIRST, then this
52 | void setLPF_g(float fOverAllGain) {
53 | // g2 = g*(1-g1)
54 | m_fLPF_g = (float)fOverAllGain * (1.0f - m_fComb_g);
55 | }
56 |
57 | // overrides
58 | // init
59 | void init(int nDelayLength);
60 |
61 | // process something
62 | bool processAudio(float *pInput, float *pOutput);
63 | };
64 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/MikeFilter.h:
--------------------------------------------------------------------------------
1 | //
2 | // MikeFilter.h
3 | //
4 | // Created by Mike Gazzaruso, revision history on Github.
5 | //
6 | //
7 |
8 | #pragma once
9 |
10 | class MikeFilter {
11 | public:
12 | MikeFilter();
13 | void calc_filter_coeffs(double const frequency, double const sample_rate);
14 |
15 | float filter(float in0);
16 |
17 | private:
18 | // filter coeffs
19 | float b0a0, b1a0, b2a0, a1a0, a2a0;
20 |
21 | // in/out history
22 | float ou1, ou2, in1, in2;
23 | };
24 |
25 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/OnePoleLPF.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class COnePoleLPF {
4 | public:
5 | // constructor/Destructor
6 | COnePoleLPF();
7 | ~COnePoleLPF();
8 |
9 | // members
10 | protected:
11 | float m_fLPF_g; // one gain coefficient
12 | float m_fLPF_z1; // one delay
13 |
14 | public:
15 | // set our one and only gain coefficient
16 | void setLPF_g(float fLPFg) { m_fLPF_g = fLPFg; }
17 |
18 | // function to init
19 | void init();
20 |
21 | // function to process audio
22 | bool processAudio(float *pInput, float *pOutput);
23 | };
24 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/OscSinCos.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 |
3 | OscSinCos.h
4 | By Laurent de Soras
5 |
6 | --- Legal stuff ---
7 |
8 | This program is free software. It comes without any warranty, to
9 | the extent permitted by applicable law. You can redistribute it
10 | and/or modify it under the terms of the Do What The Fuck You Want
11 | To Public License, Version 2, as published by Sam Hocevar. See
12 | http://sam.zoy.org/wtfpl/COPYING for more details.
13 |
14 | *Tab=3***********************************************************************/
15 |
16 | #if defined(ffft_OscSinCos_CURRENT_CODEHEADER)
17 | #error Recursive inclusion of OscSinCos code header.
18 | #endif
19 | #define ffft_OscSinCos_CURRENT_CODEHEADER
20 |
21 | #if !defined(ffft_OscSinCos_CODEHEADER_INCLUDED)
22 | #define ffft_OscSinCos_CODEHEADER_INCLUDED
23 |
24 |
25 |
26 | #include
27 |
28 | namespace std {}
29 |
30 | namespace ffft {
31 |
32 |
33 |
34 | template
35 | OscSinCos::OscSinCos()
36 | : _pos_cos(1), _pos_sin(0), _step_cos(1), _step_sin(0) {
37 |
38 | }
39 |
40 | template void OscSinCos::set_step(double angle_rad) {
41 | using namespace std;
42 |
43 | _step_cos = static_cast(cos(angle_rad));
44 | _step_sin = static_cast(sin(angle_rad));
45 | }
46 |
47 | template
48 | typename OscSinCos::DataType OscSinCos::get_cos() const {
49 | return (_pos_cos);
50 | }
51 |
52 | template
53 | typename OscSinCos::DataType OscSinCos::get_sin() const {
54 | return (_pos_sin);
55 | }
56 |
57 | template void OscSinCos::step() {
58 | const DataType old_cos = _pos_cos;
59 | const DataType old_sin = _pos_sin;
60 |
61 | _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
62 | _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
63 | }
64 |
65 | template void OscSinCos::clear_buffers() {
66 | _pos_cos = static_cast(1);
67 | _pos_sin = static_cast(0);
68 | }
69 |
70 |
71 |
72 |
73 |
74 | }
75 |
76 | #endif
77 |
78 | #undef ffft_OscSinCos_CURRENT_CODEHEADER
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/RageProcessor.h:
--------------------------------------------------------------------------------
1 | //
2 | // RageProcessor.h
3 | //
4 | // Created by Mike Gazzaruso, revision history on Github.
5 | // Copyright © 2015 Mike Gazzaruso. All rights reserved.
6 | //
7 |
8 | #pragma once
9 | #include "MikeFilter.h"
10 |
11 | class RageProcessor {
12 | public:
13 | RageProcessor(int iSampleRate);
14 | float doRage(float fCurrentSample, float fKhorne, float fNurgle);
15 | MikeFilter filterToneZ;
16 | void setNumStages(int theStages);
17 |
18 | private:
19 | int iSampleRate, iNumStages;
20 | };
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/def.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 |
3 | def.h
4 | By Laurent de Soras
5 |
6 | --- Legal stuff ---
7 |
8 | This program is free software. It comes without any warranty, to
9 | the extent permitted by applicable law. You can redistribute it
10 | and/or modify it under the terms of the Do What The Fuck You Want
11 | To Public License, Version 2, as published by Sam Hocevar. See
12 | http://sam.zoy.org/wtfpl/COPYING for more details.
13 |
14 | *Tab=3***********************************************************************/
15 |
16 | #if !defined(ffft_def_HEADER_INCLUDED)
17 | #define ffft_def_HEADER_INCLUDED
18 |
19 | #if defined(_MSC_VER)
20 | #pragma once
21 | #pragma warning(4 : 4250) // "Inherits via dominance."
22 | #endif
23 |
24 |
25 |
26 | namespace ffft {
27 |
28 | const double PI = 3.1415926535897932384626433832795;
29 | const double SQRT2 = 1.41421356237309514547462185873883;
30 |
31 | #if defined(_MSC_VER)
32 |
33 | #define ffft_FORCEINLINE __forceinline
34 |
35 | #else
36 |
37 | #define ffft_FORCEINLINE inline
38 |
39 | #endif
40 |
41 | }
42 |
43 | #endif
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/include/pluginconstants.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // includes for the project
4 |
5 | // this #define enables the following constants form math.h
6 | #define _MATH_DEFINES_DEFINED
7 | /*
8 | #define M_E 2.71828182845904523536
9 | #define M_LOG2E 1.44269504088896340736
10 | #define M_LOG10E 0.434294481903251827651
11 | #define M_LN2 0.693147180559945309417
12 | #define M_LN10 2.30258509299404568402
13 | #define M_PI 3.14159265358979323846
14 | #define M_PI_2 1.57079632679489661923
15 | #define M_PI_4 0.785398163397448309616
16 | #define M_1_PI 0.318309886183790671538
17 | #define M_2_PI 0.636619772367581343076
18 | #define M_2_SQRTPI 1.12837916709551257390
19 | #define M_SQRT2 1.41421356237309504880
20 | #define M_SQRT1_2 0.707106781186547524401
21 | */
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | // For WIN vs MacOS
28 | // XCode requires these be defined for compatibility
29 |
30 | typedef unsigned int UINT;
31 | typedef unsigned long DWORD;
32 | typedef unsigned char UCHAR;
33 | typedef unsigned char BYTE;
34 |
35 | const UINT DETECT_MODE_PEAK = 0;
36 | const UINT DETECT_MODE_MS = 1;
37 | const UINT DETECT_MODE_RMS = 2;
38 | const UINT DETECT_MODE_NONE = 3;
39 |
40 | // More #defines for MacOS/XCode
41 | #ifndef max
42 | #define max(a, b) (((a) > (b)) ? (a) : (b))
43 | #endif
44 | #ifndef min
45 | #define min(a, b) (((a) < (b)) ? (a) : (b))
46 | #endif
47 |
48 | #ifndef itoa
49 | #define itoa(value, string, radix) sprintf(string, "%d", value)
50 | #endif
51 |
52 | #ifndef ltoa
53 | #define ltoa(value, string, radix) sprintf(string, "%u", value)
54 | #endif
55 |
56 | // a few more constants from student suggestions
57 | #define pi 3.1415926535897932384626433832795
58 | #define sqrt2over2 0.707106781186547524401 // same as M_SQRT1_2
59 |
60 | // constants for dealing with overflow or underflow
61 | #define FLT_EPSILON_PLUS \
62 | 1.192092896e-07 /* smallest such that 1.0+FLT_EPSILON != 1.0 */
63 | #define FLT_EPSILON_MINUS \
64 | -1.192092896e-07 /* smallest such that 1.0-FLT_EPSILON != 1.0 */
65 | #define FLT_MIN_PLUS 1.175494351e-38 /* min positive value */
66 | #define FLT_MIN_MINUS -1.175494351e-38 /* min negative value */
67 |
68 | // basic enums
69 | enum { intData, floatData, doubleData, UINTData, nonData };
70 | enum { JS_ONESHOT, JS_LOOP, JS_SUSTAIN, JS_LOOP_BACKANDFORTH };
71 |
72 | // © by Mike Gazzaruso, 2014
73 |
74 | /*
75 | Function: lagrpol() implements n-order Lagrange Interpolation
76 |
77 | Inputs: double* x Pointer to an array containing
78 | the x-coordinates of the input values double* y Pointer to an array
79 | containing the y-coordinates of the input values
80 | int n The order of the
81 | interpolator, this is also the length of the x,y input arrays double xbar
82 | The x-coorinates whose y-value we want to interpolate
83 |
84 | Returns The interpolated value y at xbar. xbar ideally is
85 | between the middle two values in the input array, but can be anywhere within
86 | the limits, which is needed for interpolating the first few or last few
87 | samples in a table with a fixed size.
88 | */
89 | inline double lagrpol(double *x, double *y, int n, double xbar) {
90 | int i, j;
91 | double fx = 0.0;
92 | double l = 1.0;
93 | for (i = 0; i < n; i++) {
94 | l = 1.0;
95 | for (j = 0; j < n; j++) {
96 | if (j != i)
97 | l *= (xbar - x[j]) / (x[i] - x[j]);
98 | }
99 | fx += l * y[i];
100 | }
101 | return (fx);
102 | }
103 |
104 | inline float dLinTerp(float x1, float x2, float y1, float y2, float x) {
105 | float denom = x2 - x1;
106 | if (denom == 0)
107 | return y1; // should not ever happen
108 |
109 | // calculate decimal position of x
110 | float dx = (x - x1) / (x2 - x1);
111 |
112 | // use weighted sum method of interpolating
113 | float result = dx * y2 + (1 - dx) * y1;
114 |
115 | return result;
116 | }
117 |
118 | inline bool normalizeBuffer(double *pInputBuffer, UINT uBufferSize) {
119 | double fMax = 0;
120 |
121 | for (UINT j = 0; j < uBufferSize; j++) {
122 | if ((fabs(pInputBuffer[j])) > fMax)
123 | fMax = fabs(pInputBuffer[j]);
124 | }
125 |
126 | if (fMax > 0) {
127 | for (UINT j = 0; j < uBufferSize; j++)
128 | pInputBuffer[j] = pInputBuffer[j] / fMax;
129 | }
130 |
131 | return true;
132 | }
133 |
134 | const float DIGITAL_TC = -2.0; // log(1%)
135 | const float ANALOG_TC = -0.43533393574791066201247090699309f; // (log(36.7%)
136 | const float METER_UPDATE_INTERVAL_MSEC = 15.0;
137 | const float METER_MIN_DB = -60.0;
138 |
139 | class CEnvelopeDetector {
140 | public:
141 | CEnvelopeDetector(double samplerate);
142 | ~CEnvelopeDetector();
143 |
144 | // Call the Init Function to initialize and setup all at once; this can be
145 | // called as many times as you want
146 | void init(float samplerate, float attack_in_ms, float release_in_ms,
147 | bool bAnalogTC, UINT uDetect, bool bLogDetector);
148 |
149 | // these functions allow you to change modes and attack/release one at a time
150 | // during realtime operation
151 | void setTCModeAnalog(bool bAnalogTC); // {m_bAnalogTC = bAnalogTC;}
152 |
153 | // THEN do these after init
154 | void setAttackDuration(float attack_in_ms);
155 | void setReleaseDuration(float release_in_ms);
156 |
157 | // Use these "codes"
158 | // DETECT PEAK = 0
159 | // DETECT MS = 1
160 | // DETECT RMS = 2
161 | //
162 | void setDetectMode(UINT uDetect) { m_uDetectMode = uDetect; }
163 |
164 | void setSampleRate(float f) { m_fSampleRate = f; }
165 |
166 | void setLogDetect(bool b) { m_bLogDetector = b; }
167 |
168 | // call this to detect; it returns the peak ms or rms value at that instant
169 | float detect(float fInput);
170 |
171 | // call this from your prepareForPlay() function each time to reset the
172 | // detector
173 | void prepareForPlay();
174 |
175 | protected:
176 | int m_nSample;
177 | float m_fAttackTime;
178 | float m_fReleaseTime;
179 | float m_fAttackTime_mSec;
180 | float m_fReleaseTime_mSec;
181 | float m_fSampleRate;
182 | float m_fEnvelope;
183 | UINT m_uDetectMode;
184 | bool m_bAnalogTC;
185 | bool m_bLogDetector;
186 | };
187 |
--------------------------------------------------------------------------------
/Sources/CDevoloopAudioKit/pluginobjects.cpp:
--------------------------------------------------------------------------------
1 | #include "pluginconstants.h"
2 |
3 | // This file contains the object implementations for the objects declared in
4 | // "pluginconstants.h"
5 | //
6 | // Note about Helper Objects: DO NOT MODIFY THESE OBJECTS. If you need to do so,
7 | // create a derived class and modify it. These objects may be updated from time
8 | // to time so they need to be left alone.
9 |
10 | // CEnvelopeDetector Implementation
11 | // ----------------------------------------------------------------
12 | //
13 | CEnvelopeDetector::CEnvelopeDetector(double samplerate) {
14 | m_fAttackTime_mSec = 0.0;
15 | m_fReleaseTime_mSec = 0.0;
16 | m_fAttackTime = 0.0;
17 | m_fReleaseTime = 0.0;
18 | m_fSampleRate = (float)samplerate;
19 | m_fEnvelope = 0.0;
20 | m_uDetectMode = 0;
21 | m_nSample = 0;
22 | m_bAnalogTC = false;
23 | m_bLogDetector = false;
24 | }
25 |
26 | CEnvelopeDetector::~CEnvelopeDetector() {}
27 |
28 | void CEnvelopeDetector::prepareForPlay() {
29 | m_fEnvelope = 0.0;
30 | m_nSample = 0;
31 | }
32 |
33 | void CEnvelopeDetector::init(float samplerate, float attack_in_ms,
34 | float release_in_ms, bool bAnalogTC, UINT uDetect,
35 | bool bLogDetector) {
36 | m_fEnvelope = 0.0;
37 | m_fSampleRate = samplerate;
38 | m_bAnalogTC = bAnalogTC;
39 | m_fAttackTime_mSec = attack_in_ms;
40 | m_fReleaseTime_mSec = release_in_ms;
41 | m_uDetectMode = uDetect;
42 | m_bLogDetector = bLogDetector;
43 |
44 | // set themm_uDetectMode = uDetect;
45 | setAttackDuration(attack_in_ms);
46 | setReleaseDuration(release_in_ms);
47 | }
48 |
49 | void CEnvelopeDetector::setAttackDuration(float attack_in_ms) {
50 | m_fAttackTime_mSec = attack_in_ms;
51 |
52 | if (m_bAnalogTC)
53 | m_fAttackTime = expf(ANALOG_TC / (attack_in_ms * m_fSampleRate * 0.001f));
54 | else
55 | m_fAttackTime = expf(DIGITAL_TC / (attack_in_ms * m_fSampleRate * 0.001f));
56 | }
57 |
58 | void CEnvelopeDetector::setReleaseDuration(float release_in_ms) {
59 | m_fReleaseTime_mSec = release_in_ms;
60 |
61 | if (m_bAnalogTC)
62 | m_fReleaseTime = expf(ANALOG_TC / (release_in_ms * m_fSampleRate * 0.001f));
63 | else
64 | m_fReleaseTime =
65 | expf(DIGITAL_TC / (release_in_ms * m_fSampleRate * 0.001f));
66 | }
67 |
68 | void CEnvelopeDetector::setTCModeAnalog(bool bAnalogTC) {
69 | m_bAnalogTC = bAnalogTC;
70 | setAttackDuration(m_fAttackTime_mSec);
71 | setReleaseDuration(m_fReleaseTime_mSec);
72 | }
73 |
74 | float CEnvelopeDetector::detect(float fInput) {
75 | switch (m_uDetectMode) {
76 | case 0:
77 | fInput = fabsf(fInput);
78 | break;
79 | case 1:
80 | fInput = fabsf(fInput) * fabsf(fInput);
81 | break;
82 | case 2:
83 | fInput = powf((float)fabsf(fInput) * (float)fabsf(fInput), (float)0.5);
84 | break;
85 | default:
86 | fInput = (float)fabsf(fInput);
87 | break;
88 | }
89 |
90 | // float fOld = m_fEnvelope;
91 | if (fInput > m_fEnvelope)
92 | m_fEnvelope = m_fAttackTime * (m_fEnvelope - fInput) + fInput;
93 | else
94 | m_fEnvelope = m_fReleaseTime * (m_fEnvelope - fInput) + fInput;
95 |
96 | if (m_fEnvelope > 0.0 && m_fEnvelope < FLT_MIN_PLUS)
97 | m_fEnvelope = 0;
98 | if (m_fEnvelope < 0.0 && m_fEnvelope > FLT_MIN_MINUS)
99 | m_fEnvelope = 0;
100 |
101 | // bound them; can happen when using pre-detector gains of more than 1.0
102 | m_fEnvelope = min(m_fEnvelope, 1.0);
103 | m_fEnvelope = max(m_fEnvelope, 0.0);
104 |
105 | // 16-bit scaling!
106 | if (m_bLogDetector) {
107 | if (m_fEnvelope <= 0)
108 | return -96.0; // 16 bit noise floor
109 |
110 | return 20.0f * log10f(m_fEnvelope);
111 | }
112 |
113 | return m_fEnvelope;
114 | }
115 |
--------------------------------------------------------------------------------
/Sources/DevoloopAudioKit/DevoloopAudioKit.swift:
--------------------------------------------------------------------------------
1 | struct DevoloopAudioKit {
2 | var text = "Hello, World!"
3 | }
4 |
--------------------------------------------------------------------------------
/Sources/DevoloopAudioKit/DynaRageCompressor.swift:
--------------------------------------------------------------------------------
1 | // Copyright AudioKit. All Rights Reserved.
2 |
3 | import AudioKit
4 | import AudioKitEX
5 | import AVFoundation
6 | import CAudioKitEX
7 |
8 | /// DynaRage Tube Compressor | Based on DynaRage Tube Compressor RE for Reason
9 | /// by Devoloop Srls
10 | ///
11 | public class DynaRageCompressor: Node {
12 | let input: Node
13 |
14 | /// Connected nodes
15 | public var connections: [Node] { [input] }
16 |
17 | /// Underlying AVAudioNode
18 | public var avAudioNode = instantiate(effect: "dyrc")
19 |
20 | // MARK: - Parameters
21 |
22 | /// Specification details for ratio
23 | public static let ratioDef = NodeParameterDef(
24 | identifier: "ratio",
25 | name: "Ratio to compress with, a value > 1 will compress",
26 | address: akGetParameterAddress("DynaRageCompressorParameterRatio"),
27 | defaultValue: 1,
28 | range: 1.0 ... 20.0,
29 | unit: .generic
30 | )
31 |
32 | /// Ratio to compress with, a value > 1 will compress
33 | @Parameter(ratioDef) public var ratio: AUValue
34 |
35 | /// Specification details for threshold
36 | public static let thresholdDef = NodeParameterDef(
37 | identifier: "threshold",
38 | name: "Threshold (in dB) 0 = max",
39 | address: akGetParameterAddress("DynaRageCompressorParameterThreshold"),
40 | defaultValue: 0.0,
41 | range: -100.0 ... 0.0,
42 | unit: .decibels
43 | )
44 |
45 | /// Threshold (in dB) 0 = max
46 | @Parameter(thresholdDef) public var threshold: AUValue
47 |
48 | /// Specification details for attack duration
49 | public static let attackDurationDef = NodeParameterDef(
50 | identifier: "attackDuration",
51 | name: "Attack Duration",
52 | address: akGetParameterAddress("DynaRageCompressorParameterAttackDuration"),
53 | defaultValue: 0.1,
54 | range: 0.1 ... 500.0,
55 | unit: .seconds
56 | )
57 |
58 | /// Attack dration
59 | @Parameter(attackDurationDef) public var attackDuration: AUValue
60 |
61 | /// Specification details for release duration
62 | public static let releaseDurationDef = NodeParameterDef(
63 | identifier: "releaseDuration",
64 | name: "Release Duration",
65 | address: akGetParameterAddress("DynaRageCompressorParameterReleaseDuration"),
66 | defaultValue: 0.1,
67 | range: 1.0 ... 20.0,
68 | unit: .seconds
69 | )
70 |
71 | /// Release duration
72 | @Parameter(releaseDurationDef) public var releaseDuration: AUValue
73 |
74 | /// Specification details for rage amount
75 | public static let rageDef = NodeParameterDef(
76 | identifier: "rage",
77 | name: "Rage",
78 | address: akGetParameterAddress("DynaRageCompressorParameterRage"),
79 | defaultValue: 0.1,
80 | range: 0.1 ... 20.0,
81 | unit: .generic
82 | )
83 |
84 | /// Rage Amount
85 | @Parameter(rageDef) public var rage: AUValue
86 |
87 | /// Specification details for range enabling
88 | public static let rageEnabledDef = NodeParameterDef(
89 | identifier: "rageEnabled",
90 | name: "Rage Enabled",
91 | address: akGetParameterAddress("DynaRageCompressorParameterRageEnabled"),
92 | defaultValue: 1.0,
93 | range: 0.0 ... 1.0,
94 | unit: .boolean
95 | )
96 |
97 | /// Rage ON/OFF Switch
98 | @Parameter(rageEnabledDef) public var rageEnabled: Bool
99 |
100 | // MARK: - Initialization
101 |
102 | /// Initialize this compressor node
103 | ///
104 | /// - Parameters:
105 | /// - input: Input node to process
106 | /// - ratio: Ratio to compress with, a value > 1 will compress
107 | /// - threshold: Threshold (in dB) 0 = max
108 | /// - attackDuration: Attack duration in seconds
109 | /// - releaseDuration: Release duration in seconds
110 | ///
111 | public init(
112 | _ input: Node,
113 | ratio: AUValue = ratioDef.defaultValue,
114 | threshold: AUValue = thresholdDef.defaultValue,
115 | attackDuration: AUValue = attackDurationDef.defaultValue,
116 | releaseDuration: AUValue = releaseDurationDef.defaultValue,
117 | rage: AUValue = rageDef.defaultValue,
118 | rageEnabled: Bool = rageEnabledDef.defaultValue == 1.0
119 | ) {
120 | self.input = input
121 |
122 | setupParameters()
123 |
124 | self.ratio = ratio
125 | self.threshold = threshold
126 | self.attackDuration = attackDuration
127 | self.releaseDuration = releaseDuration
128 | self.rage = rage
129 | self.rageEnabled = rageEnabled
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/Sources/DevoloopAudioKit/RhinoGuitarProcessor.swift:
--------------------------------------------------------------------------------
1 | // Copyright AudioKit. All Rights Reserved.
2 |
3 | import AudioKit
4 | import AudioKitEX
5 | import AVFoundation
6 | import CAudioKitEX
7 |
8 | /// Guitar head and cab simulator.
9 | ///
10 | public class RhinoGuitarProcessor: Node {
11 | let input: Node
12 |
13 | /// Connected nodes
14 | public var connections: [Node] { [input] }
15 |
16 | /// Underlying AVAudioNode
17 | public var avAudioNode = instantiate(effect: "rhgp")
18 |
19 | // MARK: - Parameters
20 |
21 | /// Specification details for pre gain
22 | public static let preGainDef = NodeParameterDef(
23 | identifier: "preGain",
24 | name: "PreGain",
25 | address: akGetParameterAddress("RhinoGuitarProcessorParameterPreGain"),
26 | defaultValue: 5.0,
27 | range: 0.0 ... 10.0,
28 | unit: .generic
29 | )
30 |
31 | /// Gain applied before processing.
32 | @Parameter(preGainDef) public var preGain: AUValue
33 |
34 | /// Specification details for post gain
35 | public static let postGainDef = NodeParameterDef(
36 | identifier: "postGain",
37 | name: "PostGain",
38 | address: akGetParameterAddress("RhinoGuitarProcessorParameterPostGain"),
39 | defaultValue: 0.7,
40 | range: 0.0 ... 1.0,
41 | unit: .linearGain
42 | )
43 |
44 | /// Gain applied after processing.
45 | @Parameter(postGainDef) public var postGain: AUValue
46 |
47 | /// Specification details for low gain
48 | public static let lowGainDef = NodeParameterDef(
49 | identifier: "lowGain",
50 | name: "Low Frequency Gain",
51 | address: akGetParameterAddress("RhinoGuitarProcessorParameterLowGain"),
52 | defaultValue: 0.0,
53 | range: -1.0 ... 1.0,
54 | unit: .generic
55 | )
56 |
57 | /// Amount of Low frequencies.
58 | @Parameter(lowGainDef) public var lowGain: AUValue
59 |
60 | /// Specification details for mid gain
61 | public static let midGainDef = NodeParameterDef(
62 | identifier: "midGain",
63 | name: "Mid Frequency Gain",
64 | address: akGetParameterAddress("RhinoGuitarProcessorParameterMidGain"),
65 | defaultValue: 0.0,
66 | range: -1.0 ... 1.0,
67 | unit: .generic
68 | )
69 |
70 | /// Amount of Middle frequencies.
71 | @Parameter(midGainDef) public var midGain: AUValue
72 |
73 | /// Specification details for high gain
74 | public static let highGainDef = NodeParameterDef(
75 | identifier: "highGain",
76 | name: "High Frequency Gain",
77 | address: akGetParameterAddress("RhinoGuitarProcessorParameterHighGain"),
78 | defaultValue: 0.0,
79 | range: -1.0 ... 1.0,
80 | unit: .generic
81 | )
82 |
83 | /// Amount of High frequencies.
84 | @Parameter(highGainDef) public var highGain: AUValue
85 |
86 | /// Specification details for distortion
87 | public static let distortionDef = NodeParameterDef(
88 | identifier: "distortion",
89 | name: "Distortion",
90 | address: akGetParameterAddress("RhinoGuitarProcessorParameterDistortion"),
91 | defaultValue: 1.0,
92 | range: 1.0 ... 20.0,
93 | unit: .generic
94 | )
95 |
96 | /// Distortion Amount
97 | @Parameter(distortionDef) public var distortion: AUValue
98 |
99 | // MARK: - Initialization
100 |
101 | /// Initialize this Rhino head and cab simulator node
102 | ///
103 | /// - Parameters:
104 | /// - input: Input node to process
105 | /// - preGain: Determines the amount of gain applied to the signal before processing.
106 | /// - postGain: Gain applied after processing.
107 | /// - lowGain: Amount of Low frequencies.
108 | /// - midGain: Amount of Middle frequencies.
109 | /// - highGain: Amount of High frequencies.
110 | /// - distortion: Distortion Amount
111 | ///
112 | public init(
113 | _ input: Node,
114 | preGain: AUValue = preGainDef.defaultValue,
115 | postGain: AUValue = postGainDef.defaultValue,
116 | lowGain: AUValue = lowGainDef.defaultValue,
117 | midGain: AUValue = midGainDef.defaultValue,
118 | highGain: AUValue = highGainDef.defaultValue,
119 | distortion: AUValue = distortionDef.defaultValue
120 | ) {
121 | self.input = input
122 |
123 | setupParameters()
124 |
125 | self.preGain = preGain
126 | self.postGain = postGain
127 | self.lowGain = lowGain
128 | self.midGain = midGain
129 | self.highGain = highGain
130 | self.distortion = distortion
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/Tests/DevoloopAudioKitTests/GenericNodeTests.swift:
--------------------------------------------------------------------------------
1 | // Copyright AudioKit. All Rights Reserved.
2 |
3 | import AudioKit
4 | import AVFoundation
5 | import DevoloopAudioKit
6 | import XCTest
7 |
8 | class GenericNodeTests: XCTestCase {
9 | func nodeParameterTest(md5: String, factory: (Node) -> Node, m1MD5: String = "", audition: Bool = false) {
10 | let url = Bundle.module.url(forResource: "12345", withExtension: "wav", subdirectory: "TestResources")!
11 | let player = AudioPlayer(url: url)!
12 | let node = factory(player)
13 |
14 | let duration = node.parameters.count + 1
15 |
16 | let engine = AudioEngine()
17 | var bigBuffer: AVAudioPCMBuffer?
18 |
19 | engine.output = node
20 |
21 | /// Do the default parameters first
22 | if bigBuffer == nil {
23 | let audio = engine.startTest(totalDuration: 1.0)
24 | player.play()
25 | player.isLooping = true
26 | audio.append(engine.render(duration: 1.0))
27 | bigBuffer = AVAudioPCMBuffer(pcmFormat: audio.format, frameCapacity: audio.frameLength * UInt32(duration))
28 |
29 | bigBuffer?.append(audio)
30 | }
31 |
32 | for i in 0 ..< node.parameters.count {
33 | let node = factory(player)
34 | engine.output = node
35 |
36 | let param = node.parameters[i]
37 |
38 | node.start()
39 |
40 | param.value = param.def.range.lowerBound
41 | param.ramp(to: param.def.range.upperBound, duration: 1)
42 |
43 | let audio = engine.startTest(totalDuration: 1.0)
44 | audio.append(engine.render(duration: 1.0))
45 |
46 | bigBuffer?.append(audio)
47 | }
48 |
49 | XCTAssertFalse(bigBuffer!.isSilent)
50 |
51 | if audition { bigBuffer!.audition() }
52 |
53 | XCTAssertTrue([md5, m1MD5].contains(bigBuffer!.md5), "\(node)\nFAILEDMD5 \(bigBuffer!.md5)")
54 | }
55 |
56 | func testEffects() {
57 | nodeParameterTest(md5: "4038dc9888744626dc769da6f5da4d06", factory: { input in DynaRageCompressor(input) })
58 | nodeParameterTest(md5: "a4d00e9a117e58eec42c01023b40a15a", factory: { input in RhinoGuitarProcessor(input) })
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Tests/DevoloopAudioKitTests/TestResources/12345.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AudioKit/DevoloopAudioKit/57145b06ac528eb4cb03b0d3369c2f514648b695/Tests/DevoloopAudioKitTests/TestResources/12345.wav
--------------------------------------------------------------------------------
/images/dynarage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AudioKit/DevoloopAudioKit/57145b06ac528eb4cb03b0d3369c2f514648b695/images/dynarage.jpg
--------------------------------------------------------------------------------