Skip to content

Commit

Permalink
Merge branch 'better-portamento'
Browse files Browse the repository at this point in the history
* better-portamento:
  TESTS: test-porta.sh: slightly improved test
  TESTS: rename window function hanning -> hann window
  LIB: rename window function hanning -> hann window
  TODO++
  TESTS: testifftsynth: minor improvement for negative phase test
  LIB: LiveDecoder: fix phase truncation loop
  LIB: IFFTSynth: support negative phases
  TESTS: testifftsynth: test support for negative phases
  TESTS: test portamento slide during make check
  TESTS: testifftsynth: provide "correct" portamento result; fade in/out
  TESTS: testifftsynth: check portamento spectrum during test suite run
  LIB: LiveDecoder: minor cleanups
  LIB: IFFTSynth: inline quantized_freq
  LIB: LiveDecoder: fix sample skipping at start of each note
  LIB: LiveDecoder: fix envelope decoding for new portamento
  LIB: LiveDecoder: refactor noise generation into its own method
  LIB: LiveDecoder: refactor sample generation into its own method
  LIB: LiveDecoder: optimize sample generation
  LIB: LiveDecoder: process multiple samples in inner loop for vibrato
  LIB: LiveDecoder: we don't really need have_samples anymore
  LIB: LiveDecoder: use Block::sum2() to allow auto vectorization
  LIB: implement sum2 for block utils, allow inlining
  LIB: adjust hann window spectral expansion
  TESTS: adapt noise tests to API change
  LIB: overwrite output spectrum for hanning noise generator (performance)
  TESTS: update tests for recent hanning-window-noise changes
  LIB: simplify noise generation by using hanning window (performance)
  LIB: LiveDecoder: make turning off sine synthesis work again
  TOOLS: smrunplan: don't reinitialize the memory area (performance)
  LIB: LiveDecoder: properly enter done state once there are no more blocks
  LIB: LiveDecoder: optimize constant frequency case somewhat more
  LIB: LiveDecoder: optimize vibrato performance for constant base freq
  LIB: LiveDecoder: move sine sample generation to its own method
  LIB: LiveDecoder: use overlap-add synthesis if possible (performance)
  LIB: LiveDecoder: skip interpolation if speed is close to 1 (performance)
  TESTS: adapt noise tests to NoiseDecoder API change
  SRC: smplay: adapt to NoiseDecoder API change
  LIB: LiveDecoder: implement noise generator for new style portamento
  LIB: LiveDecoder: fix crashes for ultra-fast upwards portamento
  LIB: LiveDecoder: cleanup phase adjustment code
  LIB: LiveDecoder: fix portamento envelope stepping
  LIB: LiveDecoder: fix unison for new portamento
  LIB: LiveDecoder: use polyphase interpolation for portamento
  TESTS: testifftsynth portasweep: analyze main lobe / side lobe height
  TESTS: testifftsynth: add portamento slide test
  LIB: LiveDecoder: adjust anti-alias filter to match new portamento
  LIB: LiveDecoder: fix small phase jumps between blocks during portamento
  LIB: LiveDecoder: take frequency quantization into account for phases
  LIB: LiveDecoder: compute portamento stretch before rendering new block
  LIB: LiveDecoder: move portamento interpolation to process_internal
  LIB: LiveDecoder: re-enable portamento related interpolation
  LIB: LiveDecoder: implement hacky prototype for better portamento support

Signed-off-by: Stefan Westerfeld <[email protected]>
  • Loading branch information
swesterfeld committed Feb 12, 2024
2 parents 28c42fe + 1bb1b61 commit f672000
Show file tree
Hide file tree
Showing 21 changed files with 804 additions and 429 deletions.
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
NEWER TODOS:
- portamento should also affect filter cutoff (key tracking)
- 1-instrument-wav-source contains the data - not a good idea!
- LV2 archive storage doesn't seem to work
- fix asan issues in PandaResampler
Expand Down
24 changes: 0 additions & 24 deletions lib/smblockutils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,6 @@

using namespace SpectMorph;

void
Block::add (guint n_values,
float *ovalues,
const float *ivalues)
{
// auto vectorization for simple cases is quite good these days,
// so we don't provide an SSE intrinsics implementation

for (guint i = 0; i < n_values; i++)
ovalues[i] += ivalues[i];
}

void
Block::mul (guint n_values,
float *ovalues,
const float *ivalues)
{
// auto vectorization for simple cases is quite good these days,
// so we don't provide an SSE intrinsics implementation

for (guint i = 0; i < n_values; i++)
ovalues[i] *= ivalues[i];
}

void
Block::range (guint n_values,
const float *ivalues,
Expand Down
27 changes: 21 additions & 6 deletions lib/smblockutils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,27 @@ namespace SpectMorph
class Block
{
public:
static void mul (guint n_values,
float *ovalues,
const float *ivalues);
static void add (guint n_values,
float *ovalues,
const float *ivalues);
// auto vectorization for simple cases is quite good these days,
// so we don't provide an SSE intrinsics implementation for the block functions
//
static void
mul (guint n_values, float *__restrict__ ovalues, const float *__restrict__ ivalues)
{
for (guint i = 0; i < n_values; i++)
ovalues[i] *= ivalues[i];
}
static void
add (guint n_values, float *__restrict__ ovalues, const float *__restrict__ ivalues)
{
for (guint i = 0; i < n_values; i++)
ovalues[i] += ivalues[i];
}
static void
sum2 (guint n_values, float *__restrict__ ovalues, const float *__restrict__ ivalues, const float *__restrict__ ivalues2)
{
for (guint i = 0; i < n_values; i++)
ovalues[i] = ivalues[i] + ivalues2[i];
}
static void range (guint n_values,
const float *ivalues,
float& min_value,
Expand Down
10 changes: 0 additions & 10 deletions lib/smifftsynth.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,6 @@ IFFTSynth::get_samples (float *samples,
}
}

double
IFFTSynth::quantized_freq (double mf_freq)
{
const int freq256 = sm_round_positive (mf_freq * freq256_factor);
const double qfreq = freq256 * (1 / 256.0);
const double mf_qfreq = qfreq / block_size * mix_freq;

return mf_qfreq;
}

void
IFFTSynth::precompute_tables()
{
Expand Down
31 changes: 26 additions & 5 deletions lib/smifftsynth.hh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class IFFTSynth
static std::vector<float> sin_table;

public:
enum WindowType { WIN_BLACKMAN_HARRIS_92, WIN_HANNING };
enum WindowType { WIN_BLACKMAN_HARRIS_92, WIN_HANN };
enum OutputMode { REPLACE, ADD };

IFFTSynth (size_t block_size, double mix_freq, WindowType win_type);
Expand All @@ -47,16 +47,22 @@ public:
}

float*
fft_buffer()
fft_input()
{
return fft_in;
}

float*
fft_output()
{
return fft_out;
}

inline void render_partial (double freq, double mag, double phase);
void get_samples (float *samples, OutputMode output_mode = REPLACE);
void precompute_tables();

double quantized_freq (double freq);
inline double quantized_freq (double freq);
};

struct IFFTSynthTable
Expand All @@ -66,6 +72,9 @@ struct IFFTSynthTable
float *win_scale;
};

/*
* phase can be in range [-2*pi..2*pi]
*/
inline void
IFFTSynth::render_partial (double mf_freq, double mag, double phase)
{
Expand All @@ -80,8 +89,10 @@ IFFTSynth::render_partial (double mf_freq, double mag, double phase)

// rotation for initial phase; scaling for magnitude

/* the following block computes sincos (phase + phase_adjust) */
int iarg = sm_round_positive (phase * (SIN_TABLE_SIZE / (2 * M_PI)));
/* the following block computes sincos (phase + phase_adjust)
* - we add 2 * SIN_TABLE_SIZE here to support negative phases
*/
int iarg = sm_round_positive (phase * (SIN_TABLE_SIZE / (2 * M_PI)) + 2 * SIN_TABLE_SIZE);

// adjust phase to get the same output like vector sin (smmath.hh)
// phase_adjust = freq256 * (M_PI / 256.0) - M_PI / 2;
Expand Down Expand Up @@ -137,6 +148,16 @@ IFFTSynth::render_partial (double mf_freq, double mag, double phase)
}
}

inline double
IFFTSynth::quantized_freq (double mf_freq)
{
const int freq256 = sm_round_positive (mf_freq * freq256_factor);
const double qfreq = freq256 * (1 / 256.0);
const double mf_qfreq = qfreq / block_size * mix_freq;

return mf_qfreq;
}

}

#endif
Loading

0 comments on commit f672000

Please sign in to comment.