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