Skip to content

Commit

Permalink
Move the lions share of basic_dsp to basic-blocks (surge-synthesizer#…
Browse files Browse the repository at this point in the history
…6953)

In prepartion for moving out the FX and more sharing with
SC, move a big chunk of basic_dsp to sst-basic-blocks submodule,
add tests there, port, etc...

Addresses surge-synthesizer#6946
  • Loading branch information
baconpaul authored Apr 18, 2023
1 parent f8c6d85 commit 7e47e26
Show file tree
Hide file tree
Showing 43 changed files with 441 additions and 900 deletions.
1 change: 0 additions & 1 deletion src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ add_library(${PROJECT_NAME}
dsp/utilities/DSPUtils.h
dsp/utilities/SSEComplex.h
dsp/utilities/SSESincDelayLine.h
dsp/vembertech/basic_dsp.cpp
dsp/vembertech/basic_dsp.h
dsp/vembertech/lipol.cpp
dsp/vembertech/lipol.h
Expand Down
98 changes: 52 additions & 46 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "UserDefaults.h"
#include "filesystem/import.h"
#include "Effect.h"
#include "globals.h"

#include <algorithm>
#include <thread>
Expand All @@ -33,7 +34,12 @@

#include "SurgeMemoryPools.h"

#include "sst/basic-blocks/mechanics/block-ops.h"
#include "sst/basic-blocks/dsp/Clippers.h"

using namespace std;
namespace mech = sst::basic_blocks::mechanics;
namespace sdsp = sst::basic_blocks::dsp;

using CMSKey = ControllerModulationSourceVector<1>; // sigh see #4286 for failed first try

Expand Down Expand Up @@ -4197,8 +4203,8 @@ void SurgeSynthesizer::process()

if (halt_engine)
{
clear_block(output[0], BLOCK_SIZE_QUAD);
clear_block(output[1], BLOCK_SIZE_QUAD);
mech::clear_block<BLOCK_SIZE>(output[0]);
mech::clear_block<BLOCK_SIZE>(output[1]);
return;
}
else if (patchid_queue >= 0 || has_patchid_file)
Expand All @@ -4224,8 +4230,8 @@ void SurgeSynthesizer::process()

patchLoadThread = std::make_unique<std::thread>(loadPatchInBackgroundThread, this);

clear_block(output[0], BLOCK_SIZE_QUAD);
clear_block(output[1], BLOCK_SIZE_QUAD);
mech::clear_block<BLOCK_SIZE>(output[0]);
mech::clear_block<BLOCK_SIZE>(output[1]);
return;
}
}
Expand All @@ -4245,35 +4251,35 @@ void SurgeSynthesizer::process()
// process inputs (upsample & halfrate)
if (process_input)
{
hardclip_block8(input[0], BLOCK_SIZE_QUAD);
hardclip_block8(input[1], BLOCK_SIZE_QUAD);
copy_block(input[0], storage.audio_in_nonOS[0], BLOCK_SIZE_QUAD);
copy_block(input[1], storage.audio_in_nonOS[1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block8<BLOCK_SIZE>(input[0]);
sdsp::hardclip_block8<BLOCK_SIZE>(input[1]);
mech::copy_from_to<BLOCK_SIZE>(input[0], storage.audio_in_nonOS[0]);
mech::copy_from_to<BLOCK_SIZE>(input[1], storage.audio_in_nonOS[1]);
halfbandIN.process_block_U2(input[0], input[1], storage.audio_in[0], storage.audio_in[1],
BLOCK_SIZE_OS);
}
else
{
clear_block(storage.audio_in[0], BLOCK_SIZE_OS_QUAD);
clear_block(storage.audio_in[1], BLOCK_SIZE_OS_QUAD);
clear_block(storage.audio_in_nonOS[1], BLOCK_SIZE_QUAD);
clear_block(storage.audio_in_nonOS[1], BLOCK_SIZE_QUAD);
mech::clear_block<BLOCK_SIZE_OS>(storage.audio_in[0]);
mech::clear_block<BLOCK_SIZE_OS>(storage.audio_in[1]);
mech::clear_block<BLOCK_SIZE>(storage.audio_in_nonOS[1]);
mech::clear_block<BLOCK_SIZE>(storage.audio_in_nonOS[1]);
}

// TODO: FIX SCENE ASSUMPTION
float fxsendout alignas(16)[n_send_slots][2][BLOCK_SIZE];
bool play_scene[n_scenes];

{
clear_block(sceneout[0][0], BLOCK_SIZE_OS_QUAD);
clear_block(sceneout[0][1], BLOCK_SIZE_OS_QUAD);
clear_block(sceneout[1][0], BLOCK_SIZE_OS_QUAD);
clear_block(sceneout[1][1], BLOCK_SIZE_OS_QUAD);
mech::clear_block<BLOCK_SIZE_OS>(sceneout[0][0]);
mech::clear_block<BLOCK_SIZE_OS>(sceneout[0][1]);
mech::clear_block<BLOCK_SIZE_OS>(sceneout[1][0]);
mech::clear_block<BLOCK_SIZE_OS>(sceneout[1][1]);

for (int i = 0; i < n_send_slots; ++i)
{
clear_block(fxsendout[i][0], BLOCK_SIZE_QUAD);
clear_block(fxsendout[i][1], BLOCK_SIZE_QUAD);
mech::clear_block<BLOCK_SIZE>(fxsendout[i][0]);
mech::clear_block<BLOCK_SIZE>(fxsendout[i][1]);
}
}

Expand Down Expand Up @@ -4401,8 +4407,8 @@ void SurgeSynthesizer::process()
if (s == 0 && storage.otherscene_clients > 0)
{
// Make available for scene B
copy_block(sceneout[0][0], storage.audio_otherscene[0], BLOCK_SIZE_OS_QUAD);
copy_block(sceneout[0][1], storage.audio_otherscene[1], BLOCK_SIZE_OS_QUAD);
mech::copy_from_to<BLOCK_SIZE_OS>(sceneout[0][0], storage.audio_otherscene[0]);
mech::copy_from_to<BLOCK_SIZE_OS>(sceneout[0][1], storage.audio_otherscene[1]);
}

iter = voices[s].begin();
Expand All @@ -4425,12 +4431,12 @@ void SurgeSynthesizer::process()
switch (storage.sceneHardclipMode[0])
{
case SurgeStorage::HARDCLIP_TO_18DBFS:
hardclip_block8(sceneout[0][0], BLOCK_SIZE_OS_QUAD);
hardclip_block8(sceneout[0][1], BLOCK_SIZE_OS_QUAD);
sdsp::hardclip_block8<BLOCK_SIZE_OS>(sceneout[0][0]);
sdsp::hardclip_block8<BLOCK_SIZE_OS>(sceneout[0][1]);
break;
case SurgeStorage::HARDCLIP_TO_0DBFS:
hardclip_block(sceneout[0][0], BLOCK_SIZE_OS_QUAD);
hardclip_block(sceneout[0][1], BLOCK_SIZE_OS_QUAD);
sdsp::hardclip_block<BLOCK_SIZE_OS>(sceneout[0][0]);
sdsp::hardclip_block<BLOCK_SIZE_OS>(sceneout[0][1]);
break;
case SurgeStorage::BYPASS_HARDCLIP:
break;
Expand All @@ -4444,12 +4450,12 @@ void SurgeSynthesizer::process()
switch (storage.sceneHardclipMode[1])
{
case SurgeStorage::HARDCLIP_TO_18DBFS:
hardclip_block8(sceneout[1][0], BLOCK_SIZE_OS_QUAD);
hardclip_block8(sceneout[1][1], BLOCK_SIZE_OS_QUAD);
sdsp::hardclip_block8<BLOCK_SIZE_OS>(sceneout[1][0]);
sdsp::hardclip_block8<BLOCK_SIZE_OS>(sceneout[1][1]);
break;
case SurgeStorage::HARDCLIP_TO_0DBFS:
hardclip_block(sceneout[1][0], BLOCK_SIZE_OS_QUAD);
hardclip_block(sceneout[1][1], BLOCK_SIZE_OS_QUAD);
sdsp::hardclip_block<BLOCK_SIZE_OS>(sceneout[1][0]);
sdsp::hardclip_block<BLOCK_SIZE_OS>(sceneout[1][1]);
break;
case SurgeStorage::BYPASS_HARDCLIP:
break;
Expand Down Expand Up @@ -4492,12 +4498,12 @@ void SurgeSynthesizer::process()
switch (storage.sceneHardclipMode[cls])
{
case SurgeStorage::HARDCLIP_TO_18DBFS:
hardclip_block8(sceneout[cls][0], BLOCK_SIZE_QUAD);
hardclip_block8(sceneout[cls][1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block8<BLOCK_SIZE>(sceneout[cls][0]);
sdsp::hardclip_block8<BLOCK_SIZE>(sceneout[cls][1]);
break;
case SurgeStorage::HARDCLIP_TO_0DBFS:
hardclip_block(sceneout[cls][0], BLOCK_SIZE_QUAD);
hardclip_block(sceneout[cls][1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block<BLOCK_SIZE>(sceneout[cls][0]);
sdsp::hardclip_block<BLOCK_SIZE>(sceneout[cls][1]);
break;
default:
break;
Expand Down Expand Up @@ -4537,12 +4543,12 @@ void SurgeSynthesizer::process()
switch (storage.sceneHardclipMode[cls])
{
case SurgeStorage::HARDCLIP_TO_18DBFS:
hardclip_block8(sceneout[cls][0], BLOCK_SIZE_QUAD);
hardclip_block8(sceneout[cls][1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block8<BLOCK_SIZE>(sceneout[cls][0]);
sdsp::hardclip_block8<BLOCK_SIZE>(sceneout[cls][1]);
break;
case SurgeStorage::HARDCLIP_TO_0DBFS:
hardclip_block(sceneout[cls][0], BLOCK_SIZE_QUAD);
hardclip_block(sceneout[cls][1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block<BLOCK_SIZE>(sceneout[cls][0]);
sdsp::hardclip_block<BLOCK_SIZE>(sceneout[cls][1]);
break;
default:
break;
Expand All @@ -4551,10 +4557,10 @@ void SurgeSynthesizer::process()

// sum scenes
// TODO: FIX SCENE ASSUMPTION
copy_block(sceneout[0][0], output[0], BLOCK_SIZE_QUAD);
copy_block(sceneout[0][1], output[1], BLOCK_SIZE_QUAD);
accumulate_block(sceneout[1][0], output[0], BLOCK_SIZE_QUAD);
accumulate_block(sceneout[1][1], output[1], BLOCK_SIZE_QUAD);
mech::copy_from_to<BLOCK_SIZE>(sceneout[0][0], output[0]);
mech::copy_from_to<BLOCK_SIZE>(sceneout[0][1], output[1]);
mech::accumulate_from_to<BLOCK_SIZE>(sceneout[1][0], output[0]);
mech::accumulate_from_to<BLOCK_SIZE>(sceneout[1][1], output[1]);

bool sendused[4] = {false, false, false, false};
// add send effects
Expand Down Expand Up @@ -4603,19 +4609,19 @@ void SurgeSynthesizer::process()
float a = storage.vu_falloff;
vu_peak[0] = min(2.f, a * vu_peak[0]);
vu_peak[1] = min(2.f, a * vu_peak[1]);
vu_peak[0] = max(vu_peak[0], get_absmax(output[0], BLOCK_SIZE_QUAD));
vu_peak[1] = max(vu_peak[1], get_absmax(output[1], BLOCK_SIZE_QUAD));
vu_peak[0] = max(vu_peak[0], mech::blockAbsMax<BLOCK_SIZE>(output[0]));
vu_peak[1] = max(vu_peak[1], mech::blockAbsMax<BLOCK_SIZE>(output[1]));

switch (storage.hardclipMode)
{
case SurgeStorage::HARDCLIP_TO_18DBFS:
hardclip_block8(output[0], BLOCK_SIZE_QUAD);
hardclip_block8(output[1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block8<BLOCK_SIZE>(output[0]);
sdsp::hardclip_block8<BLOCK_SIZE>(output[1]);
break;

case SurgeStorage::HARDCLIP_TO_0DBFS:
hardclip_block(output[0], BLOCK_SIZE_QUAD);
hardclip_block(output[1], BLOCK_SIZE_QUAD);
sdsp::hardclip_block<BLOCK_SIZE>(output[0]);
sdsp::hardclip_block<BLOCK_SIZE>(output[1]);
break;
case SurgeStorage::BYPASS_HARDCLIP:
break;
Expand Down
111 changes: 111 additions & 0 deletions src/common/dsp/CXOR.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// Created by Paul Walker on 4/18/23.
//

#ifndef SURGE_CXOR_H
#define SURGE_CXOR_H

inline void cxor43_0_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
dst[i] = fmin(fmax(src1[i], src2[i]), -fmin(src1[i], src2[i]));
}
}

inline void cxor43_1_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
const auto v1 = fmax(src1[i], src2[i]);
const auto cx = fmin(v1, -fmin(src1[i], src2[i]));
dst[i] = fmin(v1, -fmin(cx, v1));
}
}

inline void cxor43_2_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
const auto v1 = fmax(src1[i], src2[i]);
const auto cx = fmin(v1, -fmin(src1[i], src2[i]));
dst[i] = fmin(src1[i], -fmin(cx, v1));
}
}

inline void cxor43_3_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
const auto cx = fmin(fmax(src1[i], src2[i]), -fmin(src1[i], src2[i]));
dst[i] = fmin(-fmin(cx, src2[i]), fmax(src1[i], -src2[i]));
}
}

inline void cxor43_4_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
const auto cx = fmin(fmax(src1[i], src2[i]), -fmin(src1[i], src2[i]));
dst[i] = fmin(-fmin(cx, src2[i]), fmax(src1[i], -cx));
}
}

inline void cxor93_0_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
auto p = src1[i] + src2[i];
auto m = src1[i] - src2[i];
dst[i] = fmin(fmax(p, m), -fmin(p, m));
}
}

inline void cxor93_1_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
dst[i] = src1[i] - fmin(fmax(src2[i], fmin(src1[i], 0)), fmax(src1[i], 0));
}
}

inline void cxor93_2_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
auto p = src2[i] + src1[i];
auto mf = src2[i] - src1[i];
dst[i] = fmin(src2[i], fmax(0, fmin(p, mf)));
}
}

inline void cxor93_3_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
auto p = src2[i] + src1[i];
auto mf = src2[i] - src1[i];
dst[i] = fmin(fmax(src2[i], p), fmax(0, fmin(p, mf)));
}
}

inline void cxor93_4_block(float *__restrict src1, float *__restrict src2, float *__restrict dst,
unsigned int nquads)
{
for (auto i = 0U; i < nquads << 2; ++i)
{
auto p = src2[i] + src1[i];
auto mf = src2[i] - src1[i];
dst[i] = fmax(fmin(fmax(-src1[i], src2[i]), mf), fmin(p, -p));
}
}
#endif // SURGE_CXOR_H
12 changes: 12 additions & 0 deletions src/common/dsp/Effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

#include "DSPUtils.h"
#include "SurgeStorage.h"
#include "lipol.h"

#include "sst/basic-blocks/dsp/MidSide.h"

/* base class */

Expand Down Expand Up @@ -79,6 +82,15 @@ class alignas(16) Effect
return x;
}

inline void applyWidth(float *__restrict L, float *__restrict R, lipol_ps &width)
{
namespace sdsp = sst::basic_blocks::dsp;
float M alignas(16)[BLOCK_SIZE], S alignas(16)[BLOCK_SIZE];
sdsp::encodeMS<BLOCK_SIZE>(L, R, M, S);
width.multiply_block(S, BLOCK_SIZE_QUAD);
sdsp::decodeMS<BLOCK_SIZE>(M, S, L, R);
}

protected:
SurgeStorage *storage;
FxStorage *fxdata;
Expand Down
Loading

0 comments on commit 7e47e26

Please sign in to comment.