1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #include "smmain.hh"
4 #include "smrandom.hh"
5 #include "smencoder.hh"
6 #include "smlivedecoder.hh"
7 #include "smfft.hh"
8 
9 #include <vector>
10 
11 #include <assert.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 
15 using namespace SpectMorph;
16 
17 using std::vector;
18 using std::max;
19 using std::min;
20 
21 size_t
make_odd(size_t n)22 make_odd (size_t n)
23 {
24   if (n & 1)
25     return n;
26   return n - 1;
27 }
28 
29 void
encode_decode(vector<float> & audio_in,vector<float> & audio_out)30 encode_decode (vector<float>& audio_in, vector<float>& audio_out)
31 {
32   EncoderParams enc_params;
33   enc_params.mix_freq = 44100;
34   enc_params.zeropad = 4;
35   enc_params.fundamental_freq = 440;
36   enc_params.frame_size_ms = 40;
37   enc_params.frame_step_ms = enc_params.frame_size_ms / 4.0;
38   enc_params.frame_size = make_odd (enc_params.mix_freq * 0.001 * enc_params.frame_size_ms);
39   enc_params.frame_step = enc_params.mix_freq * 0.001 * enc_params.frame_step_ms;
40 
41   /* compute block size from frame size (smallest 2^k value >= frame_size) */
42   uint64 block_size = 1;
43   while (block_size < enc_params.frame_size)
44     block_size *= 2;
45   enc_params.block_size = block_size;
46   vector<float> window (block_size);
47 
48   for (guint i = 0; i < window.size(); i++)
49     {
50       if (i < enc_params.frame_size)
51         window[i] = window_cos (2.0 * i / enc_params.frame_size - 1.0);
52       else
53         window[i] = 0;
54     }
55   enc_params.window = window;
56 
57   Encoder encoder (enc_params);
58 
59   WavData wav_data (audio_in, 1, enc_params.mix_freq, 32);
60 
61   const char *sm_file = "testaafilter.tmp.sm";
62   encoder.encode (wav_data, 0, 1, false, true);
63   encoder.save (sm_file);
64 
65   WavSet wav_set;
66   LiveDecoder decoder (&wav_set);
67 
68   WavSetWave new_wave;
69   new_wave.midi_note = 60; // doesn't matter
70   new_wave.channel = 0;
71   new_wave.path = sm_file;
72   wav_set.waves.push_back (new_wave);
73 
74   wav_set.save ("testaafilter.tmp.smset", true);
75 
76   wav_set = WavSet();
77   Error error = wav_set.load ("testaafilter.tmp.smset");
78   assert (!error);
79 
80   decoder.enable_noise (false);
81   for (double freq = 10; freq < 70000; freq = min (freq * 1.1, freq + 10))
82     {
83       decoder.retrigger (0, freq, 127, enc_params.mix_freq);
84       decoder.process (audio_out.size(), nullptr, &audio_out[0]);
85       float peak = 0;
86       for (size_t i = 0; i < audio_out.size(); i++)
87         {
88           peak = max (peak, fabs (audio_out[i]));
89         }
90       printf ("%f %.17g\n", freq, peak);
91     }
92 }
93 
94 int
main(int argc,char ** argv)95 main (int argc, char **argv)
96 {
97   Random random;
98 
99   Main main (&argc, &argv);
100 
101   vector<float> audio_in (44100);
102   vector<float> audio_out (audio_in.size());
103 
104   size_t fade = audio_in.size() / 8;
105   for (size_t i = 0; i < audio_in.size(); i++)
106     {
107       audio_in[i] = sin (i * 440 * 2 * M_PI / 44100);
108       if (i < fade)
109         audio_in[i] *= double (i) / fade;
110       size_t ri = audio_in.size() - i;
111       if (ri < fade)
112         audio_in[i] *= double (ri) / fade;
113     }
114 
115   encode_decode (audio_in, audio_out);
116 
117 /*
118   for (size_t i = 0; i < audio_out.size(); i++)
119     printf ("%d %f %f\n", i, audio_in[i], audio_out[i]);
120  */
121 
122   unlink ("testaafilter.tmp.sm");
123   unlink ("testaafilter.tmp.smset");
124 }
125