1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #ifndef SPECTMORPH_LIVEDECODER_HH
4 #define SPECTMORPH_LIVEDECODER_HH
5 
6 #include "smwavset.hh"
7 #include "smsinedecoder.hh"
8 #include "smnoisedecoder.hh"
9 #include "smlivedecodersource.hh"
10 #include "smpolyphaseinter.hh"
11 #include "smalignedarray.hh"
12 #include <vector>
13 
14 namespace SpectMorph {
15 
16 class LiveDecoder
17 {
18   struct PartialState
19   {
20     float freq;
21     float phase;
22   };
23   std::vector<PartialState> pstate[2], *last_pstate;
24 
25   struct PortamentoState {
26     std::vector<float> buffer;
27     double             pos;
28     bool               active;
29 
30     enum { DELTA = 32 };
31   } portamento_state;
32 
33   WavSet             *smset;
34   Audio              *audio;
35 
36   IFFTSynth          *ifft_synth;
37   NoiseDecoder       *noise_decoder;
38   LiveDecoderSource  *source;
39   PolyPhaseInter     *pp_inter;
40 
41   bool                sines_enabled;
42   bool                noise_enabled;
43   bool                debug_fft_perf_enabled;
44   bool                original_samples_enabled;
45   bool                loop_enabled;
46   bool                start_skip_enabled;
47 
48   size_t              frame_size, frame_step;
49   size_t              zero_values_at_start_scaled;
50   size_t              loop_start_scaled;
51   size_t              loop_end_scaled;
52   int                 loop_point;
53   float               current_freq;
54   float               current_mix_freq;
55 
56   size_t              have_samples;
57   size_t              block_size;
58   size_t              pos;
59   double              env_pos;
60   size_t              frame_idx;
61   double              original_sample_pos;
62   double              original_samples_norm_factor;
63 
64   int                 noise_seed;
65 
66   AlignedArray<float,16> *sse_samples;
67 
68   // unison
69   int                 unison_voices;
70   std::vector<float>  unison_phases[2];
71   std::vector<float>  unison_freq_factor;
72   float               unison_gain;
73   Random              unison_phase_random_gen;
74 
75   // vibrato
76   bool                vibrato_enabled;
77   float               vibrato_depth;
78   float               vibrato_frequency;
79   float               vibrato_attack;
80   float               vibrato_phase;   // state
81   float               vibrato_env;     // state
82 
83   // timing related
84   double              start_env_pos = 0;
85   bool                in_process    = false;
86 
87   // active/done
88   enum class DoneState {
89     DONE,
90     ACTIVE,
91     ALMOST_DONE
92   };
93   DoneState           done_state = DoneState::DONE;
94 
95   Audio::LoopType     get_loop_type();
96 
97   void process_internal (size_t       n_values,
98                          float       *audio_out,
99                          float        portamento_stretch);
100 
101   void portamento_grow (double end_pos, float portamento_stretch);
102   void portamento_shrink();
103 
104   void process_portamento (size_t       n_values,
105                            const float *freq_in,
106                            float       *audio_out);
107   void process_vibrato (size_t       n_values,
108                         const float *freq_in,
109                         float       *audio_out);
110   LiveDecoder();
111 public:
112   LiveDecoder (WavSet *smset);
113   LiveDecoder (LiveDecoderSource *source);
114   ~LiveDecoder();
115 
116   void enable_noise (bool ne);
117   void enable_sines (bool se);
118   void enable_debug_fft_perf (bool dfp);
119   void enable_original_samples (bool eos);
120   void enable_loop (bool eloop);
121   void enable_start_skip (bool ess);
122   void set_noise_seed (int seed);
123   void set_unison_voices (int voices, float detune);
124   void set_vibrato (bool enable_vibrato, float depth, float frequency, float attack);
125 
126   void precompute_tables (float mix_freq);
127   void retrigger (int channel, float freq, int midi_velocity, float mix_freq);
128   void process (size_t       n_values,
129                 const float *freq_in,
130                 float       *audio_out);
131 
132   double current_pos() const;
133   double fundamental_note() const;
134 
135   static size_t compute_loop_frame_index (size_t index, Audio *audio);
136   bool done() const;
137 
138   double time_offset_ms() const;
139 };
140 
141 }
142 #endif
143