Hi,
Doing upsampling/downsampling (without anything in the middle) changes the gain of the signal.
Is that expected?
The gain change is highly dependant on the signal you pass through.
The worst case seems to be with white noise, giving peaks at +7db when using filterHalfBandPolyphaseIIR, and about +6dB with filterHalfBandFIREquiripple.
as a test I just run white noise through upsampling/downsampling (full PIP below).
for (int i = 0; i < buffer.getNumChannels(); ++i)
{
for (int j = 0; j < buffer.getNumSamples(); ++j)
{
float noise = Random::getSystemRandom().nextFloat() * 2.f - 1.f;
buffer.setSample (i, j, noise);
}
}
dsp::AudioBlock<float> block (buffer);
oversampling.processSamplesUp (block);
oversampling.processSamplesDown (block);
> Full PIP plugin
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: OversamplingTest
dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, juce_audio_plugin_client, juce_audio_processors, juce_audio_utils, juce_core,
juce_data_structures, juce_dsp, juce_events, juce_graphics, juce_gui_basics,
juce_gui_extra
exporters: XCODE_MAC
moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1
type: AudioProcessor
mainClass: MyPlugin
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class MyPlugin : public juce::AudioProcessor
{
public:
//==============================================================================
MyPlugin()
: AudioProcessor (BusesProperties().withInput ("Input", juce::AudioChannelSet::stereo())
.withOutput ("Output", juce::AudioChannelSet::stereo()))
{
}
void prepareToPlay (double sampleRate, int samplesPerBlock) override
{
oversampling.initProcessing ((size_t) samplesPerBlock);
oversampling.reset();
}
void processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&) override
{
juce::ScopedNoDenormals noDenormals;
// override the input buffer with noise
for (int i = 0; i < buffer.getNumChannels(); ++i)
{
for (int j = 0; j < buffer.getNumSamples(); ++j)
{
float noise = Random::getSystemRandom().nextFloat() * 2.f - 1.f;
buffer.setSample (i, j, noise);
}
}
// oversampling
dsp::AudioBlock<float> block (buffer);
oversampling.processSamplesUp (block);
oversampling.processSamplesDown (block);
}
void releaseResources() override {}
//==============================================================================
juce::AudioProcessorEditor* createEditor() override { return nullptr; }
bool hasEditor() const override { return false; }
const juce::String getName() const override { return "OversamplingTest"; }
bool acceptsMidi() const override { return false; }
bool producesMidi() const override { return false; }
double getTailLengthSeconds() const override { return 0; }
int getNumPrograms() override { return 1; }
int getCurrentProgram() override { return 0; }
void setCurrentProgram (int) override {}
const juce::String getProgramName (int) override { return {}; }
void changeProgramName (int, const juce::String&) override {}
void getStateInformation (juce::MemoryBlock& destData) override {}
void setStateInformation (const void* data, int sizeInBytes) override {}
//==============================================================================
bool isBusesLayoutSupported (const BusesLayout& layouts) const override
{
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
return false;
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
return false;
return true;
}
private:
//==============================================================================
const size_t OversamplingFactor = 2;
dsp::Oversampling<float> oversampling { 2, OversamplingFactor, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, true };
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MyPlugin)
};