Why is including this small header breaking my project? (Resolved)


#1

I’m trying to implement the JUCE based State Variable Filter posted here:

It relies on three files, of which one is a simple utility header. It is a simple file with just this for contents:

/*
==============================================================================

ParameterSmoother.h
Created: 1 May 2015 12:43:46am
Author:  Jordan Harris

==============================================================================
*/

/*
    Useful DSP utilities. For instance, calculating frequency from a given 
    pitch (MIDI) value, or vice versa.
*/

//==============================================================================


#ifndef DSP_UTILITIES
#define DSP_UTILITIES

#pragma once
#include "JuceHeader.h"


//==============================================================================

// Calculates the frequency of a given pitch (MIDI) value.
double pitchToFreq(double pitch)
{
    return pow(2, (pitch - 69) / 12) * 440;
}

//==============================================================================
// Calculates the pitch (MIDI) of a given frequency value
double freqToPitch(double freq)
{
    return 69 + 12 * log2(freq / 440);
}


//==============================================================================

/** 
    Takes a value as input and clips it according to the min and max values.
    Returns the input if (minValue <= in <= maxValue). 
    If (in < minValue), then return minValue.
    If (in > maxValue), then return maxValue.
*/

double clipMinMax(double in, double minValue, double maxValue)
{
    if (in < minValue)
        return minValue;
    else if (in > maxValue)
        return maxValue;
    else
        return in;
}

//==============================================================================

/** 
    Takes a value as input and clips it according to the min value.
    Returns the input if (minValue <= in). 
    If (in < minValue), then return minValue.
*/
double clipMin(double in, double minValue)
{
    if (in < minValue)
        return minValue;
    else
        return in;
}

//==============================================================================

/**
    Crossfades linearly between two values (in0, in1). The value returned is 
    determined by the value of the xFadeCtrl argument.
    xFadeCtrl Range: 0->1
    - xFadeCtrl = 0    (only in0 comes through)
    - xFadeCtrl = 0.5  (equal mix of in0 and in1)
    - xfadeCtrl = 1    (only in1 comes through)
*/
double xFadeLin(double xFadeCtrl, double in0, double in1)
{
    // Clip the xFade parameter to only have range of 0->1
    xFadeCtrl = clipMinMax(xFadeCtrl, 0.0, 1.0);
    // Perform crossfading and return the value
    return (in0 * (1.0 - xFadeCtrl) + in1 * xFadeCtrl);
}

//==============================================================================

/**
    Parabolic Controller Shaper:
    "Bends" the controller curve torwards the X or Y axis.
    input range: (-1..0..1) maps to output range: (-1..0..1).
    bend range: (-1..0..1)
    - bend = -1 (max bend towards X axis)
    - bend = 0 (don't bend)
    - bend = 1 (max bend towards Y axis)
*/

double parCtrlShaper(double input, double bend)
{
    // clip input and bend because the shaper only works in that range.
    input = clipMinMax(input, -1.0, 1.0);
    bend = clipMinMax(bend, -1.0, 1.0);
    return input * ((bend + 1) - abs(input) * bend);
}

//==============================================================================

/**
    Normalizes a range of values to the range 0->1.
    (start/end should probably be the range of a parameter)
    - input: the value to be normalized
    - start: the start of the input's range
    - end: the end of the input's range
    Note: (start < end) and (start > end) are both valid.
*/

double normalizeRange(double input, double start, double end)
{
    return (input - start) / (end - start);
}


double resonanceToQ(double resonance)
{
    return 1.0 / (2.0 * (1.0 - resonance));
}

//==============================================================================


#endif  // DSP_UTILITIES

However, if I add that file to my project and put an include for it in any of my other headers, it breaks my project.

When I try to debug in Visual Studio 2017, here is what I get for errors:

1>PluginProcessor.obj : warning LNK4006: "double __cdecl pitchToFreq(double)" (?pitchToFreq@@YANN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl freqToPitch(double)" (?freqToPitch@@YANN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl clipMinMax(double,double,double)" (?clipMinMax@@YANNNN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl clipMin(double,double)" (?clipMin@@YANNN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl xFadeLin(double,double,double)" (?xFadeLin@@YANNNN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl parCtrlShaper(double,double)" (?parCtrlShaper@@YANNN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl normalizeRange(double,double,double)" (?normalizeRange@@YANNNN@Z) already defined in PluginEditor.obj; second definition ignored
1>PluginProcessor.obj : warning LNK4006: "double __cdecl resonanceToQ(double)" (?resonanceToQ@@YANN@Z) already defined in PluginEditor.obj; second definition ignored
1>AudioPlugIn_SharedCode.vcxproj -> F:\JUCE\PROJECTS\AudioPlugIn (no knobs)\Builds\VisualStudio2017\x64\Debug\Shared Code\AudioPlugIn.lib
1>Done building project "AudioPlugIn_SharedCode.vcxproj".
2>------ Build started: Project: AudioPlugIn_StandalonePlugin, Configuration: Debug x64 ------
2>LINK : F:\JUCE\PROJECTS\AudioPlugIn (no knobs)\Builds\VisualStudio2017\x64\Debug\Standalone Plugin\\AudioPlugIn.exe not found or not built by the last incremental link; performing full link
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl pitchToFreq(double)" (?pitchToFreq@@YANN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl freqToPitch(double)" (?freqToPitch@@YANN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl clipMinMax(double,double,double)" (?clipMinMax@@YANNNN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl clipMin(double,double)" (?clipMin@@YANNN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl xFadeLin(double,double,double)" (?xFadeLin@@YANNNN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl parCtrlShaper(double,double)" (?parCtrlShaper@@YANNN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl normalizeRange(double,double,double)" (?normalizeRange@@YANNNN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>AudioPlugIn.lib(PluginEditor.obj) : error LNK2005: "double __cdecl resonanceToQ(double)" (?resonanceToQ@@YANN@Z) already defined in AudioPlugIn.lib(PluginProcessor.obj)
2>F:\JUCE\PROJECTS\AudioPlugIn (no knobs)\Builds\VisualStudio2017\x64\Debug\Standalone Plugin\\AudioPlugIn.exe : fatal error LNK1169: one or more multiply defined symbols found
2>Done building project "AudioPlugIn_StandalonePlugin.vcxproj" -- FAILED.
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I have been googling the problem but I can’t figure out what it is. As soon as I delete the include to this header, my project builds perfectly. Is there any reason this might be happening?

Thanks


#2

Problem solved. I needed to put “inline” before the functions since they’re from a header.