1 #include <clunk/context.h>
2 #include <clunk/backend/sdl/backend.h>
3 #include <clunk/source.h>
4 #include <clunk/wav_file.h>
5 #include <stdlib.h>
6 #ifdef _WINDOWS
7 # include <Windows.h>
8 # define usleep(us) ::Sleep(((us) + 999) / 1000)
9 #else
10 # include <unistd.h>
11 #endif
12 #include <clunk/ref_mdct_context.h>
13
14 #define WINDOW_BITS 9
15
16 typedef clunk::mdct_context<WINDOW_BITS, clunk::vorbis_window_func, float> mdct_type;
17 typedef clunk::fft_context<WINDOW_BITS - 2, float> fft_type;
18
19 template<typename mdct_type>
20 struct mdct_test {
21 mdct_type _mdct;
22 float _input[mdct_type::N];
23 float _overlap[mdct_type::N2];
24
mdct_testmdct_test25 mdct_test(): _input(), _overlap() { }
dumpmdct_test26 void dump(int n = mdct_type::N)
27 {
28 for(int i = 0; i < n; ++i)
29 printf("%+1.1g ", _mdct.data[i]);
30 }
31
feedmdct_test32 void feed()
33 {
34 //printf("feeding ");
35 for(int i = 0; i < mdct_type::N2; ++i)
36 {
37 float v = (rand() % 11) - 5;
38 _input[i] = _input[i + mdct_type::N2];
39 _input[i + mdct_type::N2] = v;
40 //printf("%+g ", v);
41 }
42 printf("\ninput: ");
43 for(int i = 0; i < mdct_type::N; ++i)
44 {
45 _mdct.data[i] = _input[i];
46 }
47 dump();
48 _mdct.apply_window();
49 _mdct.mdct();
50 //printf("\n\tfreq: "); dump();
51 _mdct.imdct();
52 _mdct.apply_window();
53
54 for(int i = 0; i < mdct_type::N2; ++i)
55 _mdct.data[i] += _overlap[i];
56
57 for(int i = 0; i < mdct_type::N2; ++i)
58 _overlap[i] = _mdct.data[mdct_type::N2 + i];
59
60 printf("\nresult: "); dump(mdct_type::N2);
61 printf("\n");
62 }
63 };
64
main(int argc,char * argv[])65 int main(int argc, char *argv[]) {
66
67 if (argc > 1 && argv[1][0] == 'b' && argv[1][1] == 'm') {
68 mdct_type mdct;
69 for(int i = 0; i < 1000000; ++i)
70 mdct.mdct();
71 return 0;
72 }
73 if (argc > 1 && argv[1][0] == 'b' && argv[1][1] == 'f') {
74 fft_type fft;
75 for(int i = 0; i < 2000000; ++i)
76 fft.fft();
77 return 0;
78 }
79 if (argc > 1 && argv[1][0] == 't') {
80 fft_type fft;
81 for(int i = 0; i < fft_type::N; ++i) {
82 fft.data[i] = std::complex<float>((float)((i / 4) & 1), 0);
83 }
84 fft.fft();
85 for(int i = 0; i < fft_type::N; ++i) {
86 printf("%f, %f = %f\n", fft.data[i].real(), fft.data[i].imag(), std::abs(fft.data[i]));
87 }
88 fft.ifft();
89
90 for(int i = 0; i < fft_type::N; ++i) {
91 fft.data[i] -= std::complex<float>((float)((i / 4) & 1), 0);
92 printf("%f, %f\n", fft.data[i].real(), fft.data[i].imag());
93 }
94
95 return 0;
96 }
97 if (argc > 1 && argv[1][0] == 'f')
98 {
99 printf("reference: \n");
100 mdct_test<clunk::ref_mdct_context<3, clunk::sin_window_func, float> > test;
101 test.feed();
102 test.feed();
103 test.feed();
104 test.feed();
105 printf("fft based: \n");
106 mdct_test<clunk::mdct_context<3, clunk::sin_window_func, float> > test2;
107 test2.feed();
108 test2.feed();
109 test2.feed();
110 test2.feed();
111 return 0;
112 }
113
114 clunk::sdl::Backend backend(44100, 2, 1024);
115 clunk::Context &context = backend.get_context();
116
117 clunk::Object * o = context.create_object();
118 clunk::Sample * s = clunk::WavFile::load(context, "scissors.wav");
119 clunk::Sample * h = clunk::WavFile::load(context, "helicopter.wav");
120
121 static const int d = 3, n = 72;
122 clunk::DistanceModel dm(clunk::DistanceModel::Exponent, false);
123 dm.rolloff_factor = 0.7f;
124 context.set_distance_model(dm);
125
126 context.save("test_out.raw");
127 backend.start();
128 /* o->play("l", new clunk::Source(s, false, clunk::v3f(-d, 0, 0)));
129 sleep(1);
130 //o->play("c", new clunk::Source(s, false, clunk::v3f(0, 0, 0)));
131 //sleep(1);
132 o->play("r", new clunk::Source(s, false, clunk::v3f(d, 0, 0)));
133 sleep(1);
134
135 o->play("u", new clunk::Source(s, false, clunk::v3f(0, d, 0)));
136 sleep(1);
137
138 o->play("b", new clunk::Source(s, false, clunk::v3f(0, 0, d)));
139 sleep(1);
140 */
141 o->play("h", new clunk::Source(h, true));
142
143 for(int i = 0; i <= n; ++i) {
144 float a = float(2 * M_PI * i / n);
145 clunk::v3f pos(cos(a) * d, sin(a) * d * 2, 1);
146 o->set_position(pos);
147 printf("%g %g %g\n", pos.x, pos.y, pos.z);
148 usleep(100000);
149 }
150
151 /* for(int i = 0; i <= n; ++i) {
152 float a = M_PI * i / n;
153 o->play("s", new clunk::Source(s, false, clunk::v3f(cos(a), -0.25f, sin(a)) * d));
154 usleep(500000);
155 }
156 */ backend.stop();
157 return 0;
158 }
159