To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / examples / AmplitudeFollower.cpp

History | View | Annotate | Download (6.21 KB)

1
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2

    
3
/*
4
    Vamp
5

6
    An API for audio analysis and feature extraction plugins.
7

8
    Centre for Digital Music, Queen Mary, University of London.
9
    This file copyright 2006 Dan Stowell.
10
  
11
    Permission is hereby granted, free of charge, to any person
12
    obtaining a copy of this software and associated documentation
13
    files (the "Software"), to deal in the Software without
14
    restriction, including without limitation the rights to use, copy,
15
    modify, merge, publish, distribute, sublicense, and/or sell copies
16
    of the Software, and to permit persons to whom the Software is
17
    furnished to do so, subject to the following conditions:
18

19
    The above copyright notice and this permission notice shall be
20
    included in all copies or substantial portions of the Software.
21

22
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
26
    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27
    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29

30
    Except as contained in this notice, the names of the Centre for
31
    Digital Music; Queen Mary, University of London; and Chris Cannam
32
    shall not be used in advertising or otherwise to promote the sale,
33
    use or other dealings in this Software without prior written
34
    authorization.
35
*/
36

    
37
#include "AmplitudeFollower.h"
38

    
39
#include <cmath>
40

    
41
#include <string>
42
#include <vector>
43
#include <iostream>
44
#include <algorithm>
45

    
46
using std::string;
47
using std::vector;
48
using std::cerr;
49
using std::endl;
50

    
51
/**
52
 * An implementation of SuperCollider's amplitude-follower algorithm
53
 * as a simple Vamp plugin.
54
 */
55

    
56
AmplitudeFollower::AmplitudeFollower(float inputSampleRate) :
57
    Plugin(inputSampleRate),
58
    m_stepSize(0),
59
    m_previn(0.0f),
60
    m_clampcoef(0.01f),
61
    m_relaxcoef(0.01f)
62
{
63
}
64

    
65
AmplitudeFollower::~AmplitudeFollower()
66
{
67
}
68

    
69
string
70
AmplitudeFollower::getIdentifier() const
71
{
72
    return "amplitudefollower";
73
}
74

    
75
string
76
AmplitudeFollower::getName() const
77
{
78
    return "Amplitude Follower";
79
}
80

    
81
string
82
AmplitudeFollower::getDescription() const
83
{
84
    return "Track the amplitude of the audio signal";
85
}
86

    
87
string
88
AmplitudeFollower::getMaker() const
89
{
90
    return "Vamp SDK Example Plugins";
91
}
92

    
93
int
94
AmplitudeFollower::getPluginVersion() const
95
{
96
    return 1;
97
}
98

    
99
string
100
AmplitudeFollower::getCopyright() const
101
{
102
    return "Code copyright 2006 Dan Stowell; method from SuperCollider.  Freely redistributable (BSD license)";
103
}
104

    
105
bool
106
AmplitudeFollower::initialise(size_t channels, size_t stepSize, size_t blockSize)
107
{
108
    if (channels < getMinChannelCount() ||
109
        channels > getMaxChannelCount()) {
110
        cerr << "ERROR: AmplitudeFollower::initialise: "
111
             << "channel count " << channels << " out of supported range"
112
             << endl;
113
        return false;
114
    }
115

    
116
    m_stepSize = std::min(stepSize, blockSize);
117
    
118
    // Translate the coefficients 
119
    // from their "convenient" 60dB convergence-time values
120
    // to real coefficients
121
    m_clampcoef = m_clampcoef==0.0 ? 0.0 : exp(log(0.1)/(m_clampcoef * m_inputSampleRate));
122
    m_relaxcoef = m_relaxcoef==0.0 ? 0.0 : exp(log(0.1)/(m_relaxcoef * m_inputSampleRate));
123

    
124
    return true;
125
}
126

    
127
void
128
AmplitudeFollower::reset()
129
{
130
    m_previn = 0.0f;
131
}
132

    
133
AmplitudeFollower::OutputList
134
AmplitudeFollower::getOutputDescriptors() const
135
{
136
    OutputList list;
137

    
138
    OutputDescriptor sca;
139
    sca.identifier = "amplitude";
140
    sca.name = "Amplitude";
141
    sca.description = "The peak tracked amplitude for the current processing block";
142
    sca.unit = "V";
143
    sca.hasFixedBinCount = true;
144
    sca.binCount = 1;
145
    sca.hasKnownExtents = false;
146
    sca.isQuantized = false;
147
    sca.sampleType = OutputDescriptor::OneSamplePerStep;
148
    list.push_back(sca);
149

    
150
    return list;
151
}
152

    
153
AmplitudeFollower::ParameterList
154
AmplitudeFollower::getParameterDescriptors() const
155
{
156
    ParameterList list;
157
        
158
    ParameterDescriptor att;
159
    att.identifier = "attack";
160
    att.name = "Attack time";
161
    att.description = "The 60dB convergence time for an increase in amplitude";
162
    att.unit = "s";
163
    att.minValue = 0.0f;
164
    att.maxValue = 1.f;
165
    att.defaultValue = 0.01f;
166
    att.isQuantized = false;
167
    
168
    list.push_back(att);
169
    
170
    ParameterDescriptor dec;
171
    dec.identifier = "release";
172
    dec.name = "Release time";
173
    dec.description = "The 60dB convergence time for a decrease in amplitude";
174
    dec.unit = "s";
175
    dec.minValue = 0.0f;
176
    dec.maxValue = 1.f;
177
    dec.defaultValue = 0.01f;
178
    dec.isQuantized = false;
179
    
180
    list.push_back(dec);
181
    
182
    return list;
183
}
184

    
185
void AmplitudeFollower::setParameter(std::string paramid, float newval)
186
{
187
    if (paramid == "attack") {
188
        m_clampcoef = newval;
189
    } else if (paramid == "release") {
190
        m_relaxcoef = newval;
191
    }
192
}
193

    
194
float AmplitudeFollower::getParameter(std::string paramid) const
195
{
196
    if (paramid == "attack") {
197
        return m_clampcoef;
198
    } else if (paramid == "release") {
199
        return m_relaxcoef;
200
    }
201

    
202
    return 0.0f;
203
}
204

    
205
AmplitudeFollower::FeatureSet
206
AmplitudeFollower::process(const float *const *inputBuffers,
207
                           Vamp::RealTime /* timestamp */)
208
{
209
    if (m_stepSize == 0) {
210
        cerr << "ERROR: AmplitudeFollower::process: "
211
             << "AmplitudeFollower has not been initialised"
212
             << endl;
213
        return FeatureSet();
214
    }
215

    
216
    float previn = m_previn;
217

    
218
    FeatureSet returnFeatures;
219
        
220
    float val;
221
    float peak = 0.0f;
222

    
223
    for (size_t i = 0; i < m_stepSize; ++i) {
224

    
225
        val = fabs(inputBuffers[0][i]);
226
                
227
        if (val < previn) {
228
            val = val + (previn - val) * m_relaxcoef;
229
        } else {
230
            val = val + (previn - val) * m_clampcoef;
231
        }
232

    
233
        if (val > peak) peak = val;
234
        previn = val;
235
    }
236

    
237
    m_previn = previn;
238

    
239
    // Now store the "feature" (peak amp) for this sample
240
    Feature feature;
241
    feature.hasTimestamp = false;
242
    feature.values.push_back(peak);
243
    returnFeatures[0].push_back(feature);
244

    
245
    return returnFeatures;
246
}
247

    
248
AmplitudeFollower::FeatureSet
249
AmplitudeFollower::getRemainingFeatures()
250
{
251
    return FeatureSet();
252
}
253