*** empty log message ***
[chuck-blob.git] / v2 / uana_xform.cpp
blobfcd208361ced76334fc022019edc4198c524a65c
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: uana_xform.cpp
27 // desc: ...
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Rebecca Fiebrink (fiebrink@cs.princeton.edu)
31 // date: Spring 2007
32 //-----------------------------------------------------------------------------
33 #include "uana_xform.h"
34 #include "chuck_type.h"
35 #include "chuck_vm.h"
36 #include "chuck_instr.h"
37 #include "chuck_lang.h"
38 #include "util_buffers.h"
39 #include "util_xforms.h"
42 // FFT
43 CK_DLL_CTOR( FFT_ctor );
44 CK_DLL_DTOR( FFT_dtor );
45 CK_DLL_TICK( FFT_tick );
46 CK_DLL_PMSG( FFT_pmsg );
47 CK_DLL_TOCK( FFT_tock );
48 CK_DLL_CTRL( FFT_ctrl_window );
49 CK_DLL_CGET( FFT_cget_window );
50 CK_DLL_CGET( FFT_cget_windowSize );
51 CK_DLL_CTRL( FFT_ctrl_size );
52 CK_DLL_CGET( FFT_cget_size );
53 CK_DLL_MFUN( FFT_transform );
54 CK_DLL_MFUN( FFT_spectrum );
55 // static FFT offset
56 static t_CKUINT FFT_offset_data = 0;
59 // IFFT
60 CK_DLL_CTOR( IFFT_ctor );
61 CK_DLL_DTOR( IFFT_dtor );
62 CK_DLL_TICK( IFFT_tick );
63 CK_DLL_PMSG( IFFT_pmsg );
64 CK_DLL_TOCK( IFFT_tock );
65 CK_DLL_CTRL( IFFT_ctrl_window );
66 CK_DLL_CGET( IFFT_cget_window );
67 CK_DLL_CGET( IFFT_cget_windowSize );
68 CK_DLL_CTRL( IFFT_ctrl_size );
69 CK_DLL_CGET( IFFT_cget_size );
70 CK_DLL_MFUN( IFFT_transform );
71 CK_DLL_MFUN( IFFT_inverse );
72 // static IFFT offset
73 static t_CKUINT IFFT_offset_data = 0;
76 // Flip
77 CK_DLL_CTOR( Flip_ctor );
78 CK_DLL_DTOR( Flip_dtor );
79 CK_DLL_TICK( Flip_tick );
80 CK_DLL_PMSG( Flip_pmsg );
81 CK_DLL_TOCK( Flip_tock );
82 CK_DLL_CTRL( Flip_ctrl_window );
83 CK_DLL_CGET( Flip_cget_window );
84 CK_DLL_CGET( Flip_cget_windowSize );
85 CK_DLL_CTRL( Flip_ctrl_size );
86 CK_DLL_CGET( Flip_cget_size );
87 CK_DLL_MFUN( Flip_take );
88 CK_DLL_MFUN( Flip_output );
89 // static Flip offset
90 static t_CKUINT Flip_offset_data = 0;
93 // UnFlip
94 CK_DLL_CTOR( UnFlip_ctor );
95 CK_DLL_DTOR( UnFlip_dtor );
96 CK_DLL_TICK( UnFlip_tick );
97 CK_DLL_PMSG( UnFlip_pmsg );
98 CK_DLL_TOCK( UnFlip_tock );
99 CK_DLL_CTRL( UnFlip_ctrl_window );
100 CK_DLL_CGET( UnFlip_cget_window );
101 CK_DLL_CGET( UnFlip_cget_windowSize );
102 CK_DLL_CTRL( UnFlip_ctrl_size );
103 CK_DLL_CGET( UnFlip_cget_size );
104 CK_DLL_MFUN( UnFlip_take );
105 CK_DLL_MFUN( UnFlip_output );
106 // static UnFlip offset
107 static t_CKUINT UnFlip_offset_data = 0;
110 // DCT
111 CK_DLL_CTOR( DCT_ctor );
112 CK_DLL_DTOR( DCT_dtor );
113 CK_DLL_TICK( DCT_tick );
114 CK_DLL_PMSG( DCT_pmsg );
115 CK_DLL_TOCK( DCT_tock );
116 CK_DLL_CTRL( DCT_ctrl_window );
117 CK_DLL_CGET( DCT_cget_window );
118 CK_DLL_CGET( DCT_cget_windowSize );
119 CK_DLL_CTRL( DCT_ctrl_size );
120 CK_DLL_CGET( DCT_cget_size );
121 CK_DLL_MFUN( DCT_transform );
122 CK_DLL_MFUN( DCT_spectrum );
123 // static DCT offset
124 static t_CKUINT DCT_offset_data = 0;
127 // IDCT
128 CK_DLL_CTOR( IDCT_ctor );
129 CK_DLL_DTOR( IDCT_dtor );
130 CK_DLL_TICK( IDCT_tick );
131 CK_DLL_PMSG( IDCT_pmsg );
132 CK_DLL_TOCK( IDCT_tock );
133 CK_DLL_CTRL( IDCT_ctrl_window );
134 CK_DLL_CGET( IDCT_cget_window );
135 CK_DLL_CGET( IDCT_cget_windowSize );
136 CK_DLL_CTRL( IDCT_ctrl_size );
137 CK_DLL_CGET( IDCT_cget_size );
138 CK_DLL_MFUN( IDCT_transform );
139 CK_DLL_MFUN( IDCT_inverse );
140 // static IDCT offset
141 static t_CKUINT IDCT_offset_data = 0;
144 // Windowing
145 CK_DLL_SFUN( Windowing_hamming );
146 CK_DLL_SFUN( Windowing_hann );
147 CK_DLL_SFUN( Windowing_blackmanHarris );
148 CK_DLL_SFUN( Windowing_rectangle );
149 CK_DLL_SFUN( Windowing_triangle );
150 // static array
151 static Chuck_Array8 * Windowing_array = NULL;
152 static FLOAT * float_array = NULL;
153 static t_CKINT float_array_size = 0;
158 //-----------------------------------------------------------------------------
159 // name: xform_query()
160 // desc: ...
161 //-----------------------------------------------------------------------------
162 DLL_QUERY xform_query( Chuck_DL_Query * QUERY )
164 Chuck_Env * env = Chuck_Env::instance();
166 Chuck_DL_Func * func = NULL;
168 //---------------------------------------------------------------------
169 // init as base class: FFT
170 //---------------------------------------------------------------------
171 if( !type_engine_import_uana_begin( env, "FFT", "UAna", env->global(),
172 FFT_ctor, FFT_dtor,
173 FFT_tick, FFT_tock, FFT_pmsg ) )
174 return FALSE;
176 // member variable
177 FFT_offset_data = type_engine_import_mvar( env, "int", "@FFT_data", FALSE );
178 if( FFT_offset_data == CK_INVALID_OFFSET ) goto error;
180 // transform
181 func = make_new_mfun( "void", "transform", FFT_transform );
182 func->add_arg( "float[]", "from" );
183 if( !type_engine_import_mfun( env, func ) ) goto error;
185 // window
186 func = make_new_mfun( "float[]", "window", FFT_ctrl_window );
187 func->add_arg( "float[]", "win" );
188 if( !type_engine_import_mfun( env, func ) ) goto error;
190 // windowSize
191 func = make_new_mfun( "int", "windowSize", FFT_cget_windowSize );
192 if( !type_engine_import_mfun( env, func ) ) goto error;
194 // size
195 func = make_new_mfun( "int", "size", FFT_ctrl_size );
196 func->add_arg( "int", "size" );
197 if( !type_engine_import_mfun( env, func ) ) goto error;
198 func = make_new_mfun( "int", "size", FFT_cget_size );
199 if( !type_engine_import_mfun( env, func ) ) goto error;
201 // spectrum
202 func = make_new_mfun( "void", "spectrum", FFT_spectrum );
203 func->add_arg( "complex[]", "buffer" );
204 if( !type_engine_import_mfun( env, func ) ) goto error;
206 // end the class import
207 type_engine_import_class_end( env );
210 //---------------------------------------------------------------------
211 // init as base class: IFFT
212 //---------------------------------------------------------------------
213 if( !type_engine_import_uana_begin( env, "IFFT", "UAna", env->global(),
214 IFFT_ctor, IFFT_dtor,
215 IFFT_tick, IFFT_tock, IFFT_pmsg ) )
216 return FALSE;
218 // member variable
219 IFFT_offset_data = type_engine_import_mvar( env, "int", "@IFFT_data", FALSE );
220 if( IFFT_offset_data == CK_INVALID_OFFSET ) goto error;
222 // transform
223 func = make_new_mfun( "void", "transform", IFFT_transform );
224 func->add_arg( "complex[]", "from" );
225 if( !type_engine_import_mfun( env, func ) ) goto error;
227 // window
228 func = make_new_mfun( "float[]", "window", IFFT_ctrl_window );
229 func->add_arg( "float[]", "win" );
230 if( !type_engine_import_mfun( env, func ) ) goto error;
232 // windowSize
233 func = make_new_mfun( "int", "windowSize", IFFT_cget_windowSize );
234 if( !type_engine_import_mfun( env, func ) ) goto error;
236 // size
237 func = make_new_mfun( "int", "size", IFFT_ctrl_size );
238 func->add_arg( "int", "size" );
239 if( !type_engine_import_mfun( env, func ) ) goto error;
240 func = make_new_mfun( "int", "size", IFFT_cget_size );
241 if( !type_engine_import_mfun( env, func ) ) goto error;
243 // spectrum
244 func = make_new_mfun( "void", "samples", IFFT_inverse );
245 func->add_arg( "float[]", "buffer" );
246 if( !type_engine_import_mfun( env, func ) ) goto error;
248 // end the class import
249 type_engine_import_class_end( env );
252 //---------------------------------------------------------------------
253 // init as base class: Windowing
254 //---------------------------------------------------------------------
255 QUERY->begin_class( QUERY, "Windowing", "Object" );
257 // add rectangle
258 QUERY->add_sfun( QUERY, Windowing_rectangle, "float[]", "rectangle" );
259 QUERY->add_arg( QUERY, "int", "size" );
261 // add triangle
262 QUERY->add_sfun( QUERY, Windowing_triangle, "float[]", "triangle" );
263 QUERY->add_arg( QUERY, "int", "size" );
265 // add hann
266 QUERY->add_sfun( QUERY, Windowing_hann, "float[]", "hann" );
267 QUERY->add_arg( QUERY, "int", "size" );
269 // add hamming
270 QUERY->add_sfun( QUERY, Windowing_hamming, "float[]", "hamming" );
271 QUERY->add_arg( QUERY, "int", "size" );
273 // add blackman-harris
274 QUERY->add_sfun( QUERY, Windowing_blackmanHarris, "float[]", "blackmanHarris" );
275 QUERY->add_arg( QUERY, "int", "size" );
277 // done
278 QUERY->end_class( QUERY );
280 // initialize static data
281 Windowing_array = new Chuck_Array8();
282 initialize_object( Windowing_array, &t_array );
283 // TODO: yes? reference count
284 Windowing_array->add_ref();
285 // set size
286 float_array_size = 16384;
287 float_array = new FLOAT[float_array_size];
290 //---------------------------------------------------------------------
291 // init as base class: Flip
292 //---------------------------------------------------------------------
293 if( !type_engine_import_uana_begin( env, "Flip", "UAna", env->global(),
294 Flip_ctor, Flip_dtor,
295 Flip_tick, Flip_tock, Flip_pmsg ) )
296 return FALSE;
298 // member variable
299 Flip_offset_data = type_engine_import_mvar( env, "int", "@Flip_data", FALSE );
300 if( Flip_offset_data == CK_INVALID_OFFSET ) goto error;
302 // transform
303 func = make_new_mfun( "void", "transform", Flip_take );
304 func->add_arg( "float[]", "from" );
305 if( !type_engine_import_mfun( env, func ) ) goto error;
307 // window
308 func = make_new_mfun( "float[]", "window", Flip_ctrl_window );
309 func->add_arg( "float[]", "win" );
310 if( !type_engine_import_mfun( env, func ) ) goto error;
312 // windowSize
313 func = make_new_mfun( "int", "windowSize", Flip_cget_windowSize );
314 if( !type_engine_import_mfun( env, func ) ) goto error;
316 // size
317 func = make_new_mfun( "int", "size", Flip_ctrl_size );
318 func->add_arg( "int", "size" );
319 if( !type_engine_import_mfun( env, func ) ) goto error;
320 func = make_new_mfun( "int", "size", Flip_cget_size );
321 if( !type_engine_import_mfun( env, func ) ) goto error;
323 // output
324 func = make_new_mfun( "void", "output", Flip_output );
325 func->add_arg( "float[]", "buffer" );
326 if( !type_engine_import_mfun( env, func ) ) goto error;
328 // end the class import
329 type_engine_import_class_end( env );
332 //---------------------------------------------------------------------
333 // init as base class: pilF
334 //---------------------------------------------------------------------
335 if( !type_engine_import_uana_begin( env, "pilF", "UAna", env->global(),
336 UnFlip_ctor, UnFlip_dtor,
337 UnFlip_tick, UnFlip_tock, UnFlip_pmsg ) )
338 return FALSE;
340 // member variable
341 UnFlip_offset_data = type_engine_import_mvar( env, "int", "@UnFlip_data", FALSE );
342 if( UnFlip_offset_data == CK_INVALID_OFFSET ) goto error;
344 // go
345 func = make_new_mfun( "void", "transform", UnFlip_take );
346 if( !type_engine_import_mfun( env, func ) ) goto error;
348 // window
349 func = make_new_mfun( "float[]", "window", UnFlip_ctrl_window );
350 func->add_arg( "float[]", "win" );
351 if( !type_engine_import_mfun( env, func ) ) goto error;
353 // windowSize
354 func = make_new_mfun( "int", "windowSize", UnFlip_cget_windowSize );
355 if( !type_engine_import_mfun( env, func ) ) goto error;
357 // size
358 func = make_new_mfun( "int", "size", UnFlip_ctrl_size );
359 func->add_arg( "int", "size" );
360 if( !type_engine_import_mfun( env, func ) ) goto error;
361 func = make_new_mfun( "int", "size", UnFlip_cget_size );
362 if( !type_engine_import_mfun( env, func ) ) goto error;
364 // output
365 func = make_new_mfun( "void", "output", UnFlip_output );
366 func->add_arg( "float[]", "buffer" );
367 if( !type_engine_import_mfun( env, func ) ) goto error;
369 // end the class import
370 type_engine_import_class_end( env );
373 //---------------------------------------------------------------------
374 // init as base class: DCT
375 //---------------------------------------------------------------------
376 if( !type_engine_import_uana_begin( env, "DCT", "UAna", env->global(),
377 DCT_ctor, DCT_dtor,
378 DCT_tick, DCT_tock, DCT_pmsg ) )
379 return FALSE;
381 // member variable
382 DCT_offset_data = type_engine_import_mvar( env, "int", "@DCT_data", FALSE );
383 if( DCT_offset_data == CK_INVALID_OFFSET ) goto error;
385 // transform
386 func = make_new_mfun( "void", "transform", DCT_transform );
387 func->add_arg( "float[]", "from" );
388 if( !type_engine_import_mfun( env, func ) ) goto error;
390 // window
391 func = make_new_mfun( "float[]", "window", DCT_ctrl_window );
392 func->add_arg( "float[]", "win" );
393 if( !type_engine_import_mfun( env, func ) ) goto error;
395 // windowSize
396 func = make_new_mfun( "int", "windowSize", DCT_cget_windowSize );
397 if( !type_engine_import_mfun( env, func ) ) goto error;
399 // size
400 func = make_new_mfun( "int", "size", DCT_ctrl_size );
401 func->add_arg( "int", "size" );
402 if( !type_engine_import_mfun( env, func ) ) goto error;
403 func = make_new_mfun( "int", "size", DCT_cget_size );
404 if( !type_engine_import_mfun( env, func ) ) goto error;
406 // spectrum
407 func = make_new_mfun( "void", "spectrum", DCT_spectrum );
408 func->add_arg( "float[]", "buffer" );
409 if( !type_engine_import_mfun( env, func ) ) goto error;
411 // end the class import
412 type_engine_import_class_end( env );
415 //---------------------------------------------------------------------
416 // init as base class: IDCT
417 //---------------------------------------------------------------------
418 if( !type_engine_import_uana_begin( env, "IDCT", "UAna", env->global(),
419 IDCT_ctor, IDCT_dtor,
420 IDCT_tick, IDCT_tock, IDCT_pmsg ) )
421 return FALSE;
423 // member variable
424 IDCT_offset_data = type_engine_import_mvar( env, "int", "@IDCT_data", FALSE );
425 if( IDCT_offset_data == CK_INVALID_OFFSET ) goto error;
427 // transform
428 func = make_new_mfun( "void", "transform", IDCT_transform );
429 func->add_arg( "complex[]", "from" );
430 if( !type_engine_import_mfun( env, func ) ) goto error;
432 // window
433 func = make_new_mfun( "float[]", "window", IDCT_ctrl_window );
434 func->add_arg( "float[]", "win" );
435 if( !type_engine_import_mfun( env, func ) ) goto error;
437 // windowSize
438 func = make_new_mfun( "int", "windowSize", IDCT_cget_windowSize );
439 if( !type_engine_import_mfun( env, func ) ) goto error;
441 // size
442 func = make_new_mfun( "int", "size", IDCT_ctrl_size );
443 func->add_arg( "int", "size" );
444 if( !type_engine_import_mfun( env, func ) ) goto error;
445 func = make_new_mfun( "int", "size", IDCT_cget_size );
446 if( !type_engine_import_mfun( env, func ) ) goto error;
448 // spectrum
449 func = make_new_mfun( "void", "samples", IDCT_inverse );
450 func->add_arg( "float[]", "buffer" );
451 if( !type_engine_import_mfun( env, func ) ) goto error;
453 // end the class import
454 type_engine_import_class_end( env );
456 return TRUE;
458 error:
460 // end the class import
461 type_engine_import_class_end( env );
463 return FALSE;
469 //-----------------------------------------------------------------------------
470 // name: FFT_object
471 // desc: standalone object for FFT UAna
472 //-----------------------------------------------------------------------------
473 struct FFT_object
475 public:
476 FFT_object();
477 virtual ~FFT_object();
479 public:
480 t_CKBOOL resize( t_CKINT size );
481 t_CKBOOL window( Chuck_Array8 * window, t_CKINT win_size );
482 void transform( );
483 void transform( Chuck_Array8 * frame );
484 void copyTo( Chuck_Array16 * cmp );
486 public:
487 // size of FFT
488 t_CKINT m_size;
489 // window
490 SAMPLE * m_window;
491 // window size
492 t_CKINT m_window_size;
493 // sample accumulation buffer
494 AccumBuffer m_accum;
495 // FFT buffer
496 SAMPLE * m_buffer;
497 // result
498 t_CKCOMPLEX * m_spectrum;
504 //-----------------------------------------------------------------------------
505 // name: FFT_object()
506 // desc: constructor
507 //-----------------------------------------------------------------------------
508 FFT_object::FFT_object()
510 // initialize
511 m_size = 512; // TODO: default
512 m_window = NULL;
513 m_window_size = m_size;
514 m_buffer = NULL;
515 m_spectrum = NULL;
516 // initialize window
517 this->window( NULL, m_window_size );
518 // allocate buffer
519 this->resize( m_size );
525 //-----------------------------------------------------------------------------
526 // name: ~FFT_object()
527 // desc: destructor
528 //-----------------------------------------------------------------------------
529 FFT_object::~FFT_object()
531 // clean up
532 SAFE_DELETE_ARRAY( m_window );
533 SAFE_DELETE_ARRAY( m_buffer );
534 SAFE_DELETE_ARRAY( m_spectrum );
535 m_window_size = 0;
536 m_size = 0;
542 //-----------------------------------------------------------------------------
543 // name: resize()
544 // desc: set FFT size
545 //-----------------------------------------------------------------------------
546 t_CKBOOL FFT_object::resize( t_CKINT size )
548 // sanity check
549 assert( size > 0 );
551 // next power of 2
552 t_CKINT x = --size;
553 for( ; size &= size-1; x = size );
554 size = x*2;
556 // log
557 EM_log( CK_LOG_FINE, "FFT resize %d -> %d", m_size, size );
559 // reallocate
560 SAFE_DELETE_ARRAY( m_buffer );
561 SAFE_DELETE_ARRAY( m_spectrum );
562 m_size = 0;
563 m_buffer = new SAMPLE[size];
564 m_spectrum = new t_CKCOMPLEX[size/2];
565 // check it
566 if( !m_buffer || !m_spectrum )
568 // out of memory
569 fprintf( stderr, "[chuck]: FFT failed to allocate %ld, %ld buffers...\n",
570 size, size/2 );
571 // clean
572 SAFE_DELETE_ARRAY( m_buffer );
573 SAFE_DELETE_ARRAY( m_spectrum );
574 // done
575 return FALSE;
578 // zero it
579 memset( m_buffer, 0, size * sizeof(SAMPLE) );
580 memset( m_spectrum, 0, size/2 * sizeof(t_CKCOMPLEX) );
581 // set
582 m_size = size;
583 // if no window specified, then set accum size
584 if( !m_window )
586 m_window_size = m_size;
587 // resize
588 m_accum.resize( m_window_size );
591 return TRUE;
597 //-----------------------------------------------------------------------------
598 // name: window()
599 // desc: set window
600 //-----------------------------------------------------------------------------
601 t_CKBOOL FFT_object::window( Chuck_Array8 * win, t_CKINT win_size )
603 // sanity check
604 assert( win_size >= 0 );
606 // in any case, clean up
607 SAFE_DELETE_ARRAY( m_window );
608 // reset
609 m_window_size = 0;
611 // could be NULL
612 if( win != NULL )
614 m_window = new SAMPLE[win_size];
615 // check it
616 if( !m_window )
618 // out of memory
619 fprintf( stderr, "[chuck]: FFT failed to allocate %ldxSAMPLE window...\n",
620 m_size );
621 // done
622 return FALSE;
625 // zero it
626 memset( m_window, 0, win_size * sizeof(SAMPLE) );
628 // set window
629 m_window_size = win_size;
630 // copy
631 t_CKFLOAT sample;
632 for( t_CKINT i = 0; i < win_size; i++ )
634 // get
635 win->get( i, &sample );
636 // set
637 m_window[i] = (SAMPLE)sample;
640 else
642 // set
643 m_window_size = m_size;
646 // resize
647 m_accum.resize( m_window_size );
649 return TRUE;
655 //-----------------------------------------------------------------------------
656 // name: transform()
657 // desc: ...
658 //-----------------------------------------------------------------------------
659 void FFT_object::transform( )
661 // buffer could be null
662 if( m_buffer == NULL && m_spectrum == NULL )
664 // out of memory
665 fprintf( stderr, "[chuck]: FFT failure due to NULL buffer...\n" );
666 // bye
667 return;
670 // sanity
671 assert( m_window_size <= m_size );
673 // get the last buffer of samples
674 m_accum.get( m_buffer, m_window_size );
675 // apply window, if there is one
676 if( m_window )
677 apply_window( m_buffer, m_window, m_window_size );
678 // zero pad
679 memset( m_buffer + m_window_size, 0, (m_size - m_window_size)*sizeof(SAMPLE) );
680 // go for it
681 rfft( m_buffer, m_size/2, FFT_FORWARD );
682 // copy into the result
683 SAMPLE * ptr = m_buffer;
684 for( t_CKINT i = 0; i < m_size/2; i++ )
686 // real and imaginary
687 m_spectrum[i].re = *ptr++;
688 m_spectrum[i].im = *ptr++;
695 //-----------------------------------------------------------------------------
696 // name: transform()
697 // desc: ...
698 //-----------------------------------------------------------------------------
699 void FFT_object::transform( Chuck_Array8 * frame )
701 // convert to right type
702 t_CKINT amount = ck_min( frame->size(), m_size );
703 // copy
704 t_CKFLOAT v;
705 for( t_CKINT i = 0; i < amount; i++ )
707 // real and imag
708 frame->get( i, &v );
709 m_buffer[i] = v;
711 // zero pad
712 for( t_CKINT j = amount; j < m_size; j++ )
713 m_buffer[j] = 0;
715 // um
716 this->transform();
722 //-----------------------------------------------------------------------------
723 // name: copyTo()
724 // desc: ...
725 //-----------------------------------------------------------------------------
726 void FFT_object::copyTo( Chuck_Array16 * cmp )
728 // buffer could be null
729 if( m_buffer == NULL && m_spectrum == NULL )
731 // zero out
732 cmp->clear();
733 // bye
734 return;
737 // get amount
738 t_CKINT amount = m_size/2;
739 // allocate
740 cmp->set_size( amount );
742 t_CKINT i;
743 for( i = 0; i < amount; i++ )
744 cmp->set( i, m_spectrum[i] );
747 // copy modulo 2*pi
748 t_CKINT left = cmp->size();
749 t_CKINT amount, i, j, sum = 0, which = 0;
751 // go
752 while( left )
754 // get
755 amount = ck_min( m_size, left );
757 // go over spectrum
758 if( which == 0 )
759 for( i = 0; i < amount; i++ )
760 cmp->set( i+sum, m_spectrum[i] );
761 else
762 for( i = 0, j = m_size-1; i < amount; i++, j-- )
763 cmp->set( i+sum, m_spectrum[j] );
765 // update
766 left -= amount;
767 sum += amount;
768 which = !which;
776 //-----------------------------------------------------------------------------
777 // name:
778 // desc:
779 //-----------------------------------------------------------------------------
780 CK_DLL_CTOR( FFT_ctor )
782 // allocate the fft object
783 FFT_object * fft = new FFT_object;
784 OBJ_MEMBER_UINT( SELF, FFT_offset_data ) = (t_CKUINT)fft;
788 //-----------------------------------------------------------------------------
789 // name:
790 // desc:
791 //-----------------------------------------------------------------------------
792 CK_DLL_DTOR( FFT_dtor )
794 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
795 SAFE_DELETE( fft );
796 OBJ_MEMBER_UINT(SELF, FFT_offset_data) = 0;
800 //-----------------------------------------------------------------------------
801 // name:
802 // desc:
803 //-----------------------------------------------------------------------------
804 CK_DLL_TICK( FFT_tick )
806 // accumulate samples
807 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
808 fft->m_accum.put( in );
809 // zero output
810 *out = 0;
812 return TRUE;
816 //-----------------------------------------------------------------------------
817 // name:
818 // desc:
819 //-----------------------------------------------------------------------------
820 CK_DLL_PMSG( FFT_pmsg )
822 return TRUE;
826 //-----------------------------------------------------------------------------
827 // name:
828 // desc:
829 //-----------------------------------------------------------------------------
830 CK_DLL_TOCK( FFT_tock )
832 // get object
833 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
834 // take transform
835 fft->transform();
836 // microsoft blows
837 t_CKINT i;
839 // get cvals of output BLOB
840 Chuck_Array16 & cvals = BLOB->cvals();
841 // ensure capacity == resulting size
842 if( cvals.size() != fft->m_size/2 )
843 cvals.set_size( fft->m_size/2 );
844 // copy the result in
845 for( i = 0; i < fft->m_size/2; i++ )
846 cvals.set( i, fft->m_spectrum[i] );
848 // get fvals of output BLOB; fill with magnitude spectrum
849 Chuck_Array8 & fvals = BLOB->fvals();
850 // ensure size == resulting size
851 if( fvals.size() != fft->m_size/2 )
852 fvals.set_size( fft->m_size/2 );
853 // copy the result in
854 for( i = 0; i < fft->m_size/2; i++ )
855 fvals.set( i, __modulus(fft->m_spectrum[i]) );
857 return TRUE;
861 //-----------------------------------------------------------------------------
862 // name:
863 // desc:
864 //-----------------------------------------------------------------------------
865 CK_DLL_MFUN( FFT_transform )
867 // get object
868 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
869 // get array
870 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
871 // do it
872 fft->transform( arr );
876 //-----------------------------------------------------------------------------
877 // name:
878 // desc:
879 //-----------------------------------------------------------------------------
880 CK_DLL_CTRL( FFT_ctrl_window )
882 // get object
883 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
884 // get window (can be NULL)
885 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
886 // set it
887 fft->window( arr, arr != NULL ? arr->size() : 0 );
888 // return it through
889 RETURN->v_object = arr;
893 //-----------------------------------------------------------------------------
894 // name:
895 // desc:
896 //-----------------------------------------------------------------------------
897 CK_DLL_CGET( FFT_cget_window )
899 // TODO: implement this!
900 RETURN->v_object = NULL;
904 //-----------------------------------------------------------------------------
905 // name: windowSize()
906 // desc:
907 //-----------------------------------------------------------------------------
908 CK_DLL_CGET( FFT_cget_windowSize )
910 // get object
911 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
912 // return
913 RETURN->v_int = fft->m_window_size;
917 //-----------------------------------------------------------------------------
918 // name: size()
919 // desc: ...
920 //-----------------------------------------------------------------------------
921 CK_DLL_CTRL( FFT_ctrl_size )
923 // get object
924 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
925 // get arg
926 t_CKINT size = GET_NEXT_INT(ARGS);
927 // sanity check
928 if( size <= 0 ) goto invalid_size;
929 // set size
930 fft->resize( size );
931 // set RETURN
932 RETURN->v_int = fft->m_size;
934 return;
936 invalid_size:
937 // we have a problem
938 fprintf( stderr,
939 "[chuck](IFFT): InvalidTransformSizeException (%d)\n", size );
940 goto done;
942 done:
943 // set RETURN type
944 RETURN->v_int = 0;
945 // do something!
946 if( SHRED != NULL )
948 SHRED->is_running = FALSE;
949 SHRED->is_done = TRUE;
954 //-----------------------------------------------------------------------------
955 // name:
956 // desc:
957 //-----------------------------------------------------------------------------
958 CK_DLL_CGET( FFT_cget_size )
960 // get object
961 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
962 // set RETURN
963 RETURN->v_int = fft->m_size;
967 //-----------------------------------------------------------------------------
968 // name:
969 // desc:
970 //-----------------------------------------------------------------------------
971 CK_DLL_MFUN( FFT_spectrum )
973 // get object
974 FFT_object * fft = (FFT_object *)OBJ_MEMBER_UINT(SELF, FFT_offset_data);
975 // get array
976 Chuck_Array16 * arr = (Chuck_Array16 *)GET_NEXT_OBJECT(ARGS);
977 // check for null
978 if( !arr )
980 // log
981 EM_log( CK_LOG_WARNING, "(via FFT): null array passed to spectrum(...)" );
982 return;
985 // copy it
986 fft->copyTo( arr );
992 //-----------------------------------------------------------------------------
993 // name: IFFT_object
994 // desc: standalone object for IFFT UAna
995 //-----------------------------------------------------------------------------
996 struct IFFT_object
998 public:
999 IFFT_object();
1000 virtual ~IFFT_object();
1002 public:
1003 t_CKBOOL resize( t_CKINT size );
1004 t_CKBOOL window( Chuck_Array8 * window, t_CKINT win_size );
1005 void transform( );
1006 void transform( Chuck_Array16 * cmp );
1007 void copyTo( Chuck_Array8 * samples );
1009 public:
1010 // size of IFFT
1011 t_CKINT m_size;
1012 // window
1013 SAMPLE * m_window;
1014 // window size
1015 t_CKINT m_window_size;
1016 // sample deccumulation buffer
1017 DeccumBuffer m_deccum;
1018 // IFFT buffer
1019 SAMPLE * m_buffer;
1020 // result
1021 SAMPLE * m_inverse;
1027 //-----------------------------------------------------------------------------
1028 // name: IFFT_object()
1029 // desc: constructor
1030 //-----------------------------------------------------------------------------
1031 IFFT_object::IFFT_object()
1033 // initialize
1034 m_size = 512; // TODO: default
1035 m_window = NULL;
1036 m_window_size = m_size;
1037 m_buffer = NULL;
1038 m_inverse = NULL;
1039 // initialize window
1040 this->window( NULL, m_window_size );
1041 // allocate buffer
1042 this->resize( m_size );
1048 //-----------------------------------------------------------------------------
1049 // name: ~IFFT_object()
1050 // desc: destructor
1051 //-----------------------------------------------------------------------------
1052 IFFT_object::~IFFT_object()
1054 // clean up
1055 SAFE_DELETE_ARRAY( m_window );
1056 SAFE_DELETE_ARRAY( m_buffer );
1057 SAFE_DELETE_ARRAY( m_inverse );
1058 m_window_size = 0;
1059 m_size = 0;
1065 //-----------------------------------------------------------------------------
1066 // name: resize()
1067 // desc: set IFFT size
1068 //-----------------------------------------------------------------------------
1069 t_CKBOOL IFFT_object::resize( t_CKINT size )
1071 // sanity check
1072 assert( size > 0 );
1074 // next power of 2
1075 t_CKINT x = --size;
1076 for( ; size &= size-1; x = size );
1077 size = x*2;
1079 // log
1080 EM_log( CK_LOG_FINE, "IFFT resize %d -> %d", m_size, size );
1082 // reallocate
1083 SAFE_DELETE_ARRAY( m_buffer );
1084 SAFE_DELETE_ARRAY( m_inverse );
1085 m_size = 0;
1086 m_buffer = new SAMPLE[size];
1087 m_inverse = new SAMPLE[size];
1088 // check it
1089 if( !m_buffer || !m_inverse )
1091 // out of memory
1092 fprintf( stderr, "[chuck]: IFFT failed to allocate %ld, %ld buffers...\n",
1093 size/2, size );
1094 // clean
1095 SAFE_DELETE_ARRAY( m_buffer );
1096 SAFE_DELETE_ARRAY( m_inverse );
1097 // done
1098 return FALSE;
1101 // zero it
1102 memset( m_buffer, 0, size * sizeof(SAMPLE) );
1103 memset( m_inverse, 0, size * sizeof(SAMPLE) );
1104 // set
1105 m_size = size;
1106 // set deccum size
1107 m_deccum.resize( m_size );
1108 // if no window specified, then set accum size
1109 if( !m_window )
1110 m_window_size = m_size;
1112 return TRUE;
1118 //-----------------------------------------------------------------------------
1119 // name: window()
1120 // desc: set window
1121 //-----------------------------------------------------------------------------
1122 t_CKBOOL IFFT_object::window( Chuck_Array8 * win, t_CKINT win_size )
1124 // sanity check
1125 assert( win_size >= 0 );
1127 // in any case, clean up
1128 SAFE_DELETE_ARRAY( m_window );
1129 // reset
1130 m_window_size = 0;
1132 // could be NULL
1133 if( win != NULL )
1135 m_window = new SAMPLE[win_size];
1136 // check it
1137 if( !m_window )
1139 // out of memory
1140 fprintf( stderr, "[chuck]: IFFT failed to allocate %ldxSAMPLE window...\n",
1141 m_size );
1142 // done
1143 return FALSE;
1146 // zero it
1147 memset( m_window, 0, win_size * sizeof(SAMPLE) );
1149 // set window
1150 m_window_size = win_size;
1151 // copy
1152 t_CKFLOAT sample;
1153 for( t_CKINT i = 0; i < win_size; i++ )
1155 // get
1156 win->get( i, &sample );
1157 // set
1158 m_window[i] = (SAMPLE)sample;
1161 else
1163 // set
1164 m_window_size = m_size;
1167 return TRUE;
1173 //-----------------------------------------------------------------------------
1174 // name: transform()
1175 // desc: ...
1176 //-----------------------------------------------------------------------------
1177 void IFFT_object::transform( )
1179 // buffer could be null
1180 if( m_buffer == NULL && m_inverse == NULL )
1182 // out of memory
1183 fprintf( stderr, "[chuck]: IFFT failure due to NULL buffer...\n" );
1184 // bye
1185 return;
1188 // sanity
1189 assert( m_window_size <= m_size );
1190 // go for it
1191 rfft( m_buffer, m_size/2, FFT_INVERSE );
1192 // copy
1193 memcpy( m_inverse, m_buffer, m_size * sizeof(SAMPLE) );
1194 // apply window, if there is one
1195 if( m_window )
1196 apply_window( m_inverse, m_window, m_window_size );
1197 // zero
1198 memset( m_inverse + m_window_size, 0, (m_size-m_window_size)*sizeof(SAMPLE) );
1199 // put in deccum buffer
1200 m_deccum.put( m_inverse, m_size );
1206 //-----------------------------------------------------------------------------
1207 // name: transform()
1208 // desc: ...
1209 //-----------------------------------------------------------------------------
1210 void IFFT_object::transform( Chuck_Array16 * cmp )
1212 // convert to right type
1213 t_CKINT amount = ck_min( cmp->size(), m_size/2 );
1214 // copy
1215 t_CKCOMPLEX v;
1216 for( t_CKINT i = 0; i < amount; i++ )
1218 // real and imag
1219 cmp->get( i, &v );
1220 m_buffer[i*2] = v.re;
1221 m_buffer[i*2+1] = v.im;
1223 // zero pad
1224 for( t_CKINT j = amount; j < m_size/2; j++ )
1225 m_buffer[j*2] = m_buffer[j*2+1] = 0;
1227 // um
1228 this->transform();
1234 //-----------------------------------------------------------------------------
1235 // name: copyTo()
1236 // desc: ...
1237 //-----------------------------------------------------------------------------
1238 void IFFT_object::copyTo( Chuck_Array8 * samples )
1240 // buffer could be null
1241 if( m_buffer == NULL && m_inverse == NULL )
1243 // zero out
1244 samples->clear();
1245 // samples->zero( 0, samples->size() );
1246 // bye
1247 return;
1250 // the amount
1251 t_CKINT amount = m_size; // ck_min( m_size, samples->size() );
1252 // allocate
1253 samples->set_size( amount );
1255 // go over
1256 for( t_CKINT i = 0; i < amount; i++ )
1257 samples->set( i, m_inverse[i] );
1259 // any left
1260 // if( amount < samples->size() )
1261 // samples->set_size( amount );
1267 //-----------------------------------------------------------------------------
1268 // name:
1269 // desc:
1270 //-----------------------------------------------------------------------------
1271 CK_DLL_CTOR( IFFT_ctor )
1273 // allocate the ifft object
1274 IFFT_object * ifft = new IFFT_object;
1275 OBJ_MEMBER_UINT( SELF, IFFT_offset_data ) = (t_CKUINT)ifft;
1279 //-----------------------------------------------------------------------------
1280 // name:
1281 // desc:
1282 //-----------------------------------------------------------------------------
1283 CK_DLL_DTOR( IFFT_dtor )
1285 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1286 SAFE_DELETE( ifft );
1287 OBJ_MEMBER_UINT(SELF, IFFT_offset_data) = 0;
1291 //-----------------------------------------------------------------------------
1292 // name:
1293 // desc:
1294 //-----------------------------------------------------------------------------
1295 CK_DLL_TICK( IFFT_tick )
1297 // accumulate samples
1298 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1299 // get output
1300 ifft->m_deccum.get( out );
1302 return TRUE;
1306 //-----------------------------------------------------------------------------
1307 // name:
1308 // desc:
1309 //-----------------------------------------------------------------------------
1310 CK_DLL_PMSG( IFFT_pmsg )
1312 return TRUE;
1316 //-----------------------------------------------------------------------------
1317 // name:
1318 // desc:
1319 //-----------------------------------------------------------------------------
1320 CK_DLL_TOCK( IFFT_tock )
1322 // get object
1323 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1324 // TODO: get buffer from stream, and set in ifft
1325 if( UANA->numIncomingUAnae() > 0 )
1327 // get first
1328 Chuck_UAnaBlobProxy * BLOB_IN = UANA->getIncomingBlob( 0 );
1329 // sanity check
1330 assert( BLOB_IN != NULL );
1331 // get the array
1332 Chuck_Array16 & cmp = BLOB_IN->cvals();
1333 // resize if necessary
1334 if( cmp.size()*2 > ifft->m_size )
1335 ifft->resize( cmp.size()*2 );
1336 // sanity check
1337 assert( ifft->m_buffer != NULL );
1338 // copy into transform buffer
1339 t_CKCOMPLEX cval;
1340 for( t_CKINT i = 0; i < ifft->m_size/2; i++ )
1342 // copy complex value in
1343 cmp.get( i, &cval );
1344 ifft->m_buffer[i*2] = cval.re;
1345 ifft->m_buffer[i*2+1] = cval.im;
1348 // take transform
1349 ifft->transform();
1351 // otherwise zero out
1352 else
1354 // sanity check
1355 assert( ifft->m_buffer != NULL );
1356 memset( ifft->m_buffer, 0, sizeof(SAMPLE)*ifft->m_size );
1357 memset( ifft->m_inverse, 0, sizeof(SAMPLE)*ifft->m_size );
1360 // get fvals of output BLOB
1361 Chuck_Array8 & fvals = BLOB->fvals();
1362 // ensure size == resulting size
1363 if( fvals.size() != ifft->m_size )
1364 fvals.set_size( ifft->m_size );
1365 // copy the result in
1366 for( t_CKINT i = 0; i < ifft->m_size; i++ )
1367 fvals.set( i, ifft->m_inverse[i] );
1369 return TRUE;
1373 //-----------------------------------------------------------------------------
1374 // name:
1375 // desc:
1376 //-----------------------------------------------------------------------------
1377 CK_DLL_MFUN( IFFT_transform )
1379 // get object
1380 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1381 // get complex array
1382 Chuck_Array16 * cmp = (Chuck_Array16 *)GET_NEXT_OBJECT(ARGS);
1383 // sanity
1384 if( cmp == NULL ) goto null_pointer;
1385 // resize if bigger
1386 if( cmp->size()*2 > ifft->m_size )
1387 ifft->resize( cmp->size()*2 );
1388 // transform it
1389 ifft->transform( cmp );
1391 return;
1393 null_pointer:
1394 // we have a problem
1395 fprintf( stderr,
1396 "[chuck](IFFT): NullPointerException (argument is NULL)\n");
1397 goto done;
1399 done:
1400 // do something!
1401 if( SHRED != NULL )
1403 SHRED->is_running = FALSE;
1404 SHRED->is_done = TRUE;
1409 //-----------------------------------------------------------------------------
1410 // name:
1411 // desc:
1412 //-----------------------------------------------------------------------------
1413 CK_DLL_CTRL( IFFT_ctrl_window )
1415 // get object
1416 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data );
1417 // get win (can be NULL)
1418 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
1419 // set it
1420 ifft->window( arr, arr != NULL ? arr->size() : 0 );
1421 // return
1422 RETURN->v_object = arr;
1426 //-----------------------------------------------------------------------------
1427 // name:
1428 // desc:
1429 //-----------------------------------------------------------------------------
1430 CK_DLL_CGET( IFFT_cget_window )
1432 // TODO: implement this
1433 RETURN->v_object = NULL;
1437 //-----------------------------------------------------------------------------
1438 // name: windowSize()
1439 // desc:
1440 //-----------------------------------------------------------------------------
1441 CK_DLL_CGET( IFFT_cget_windowSize )
1443 // get object
1444 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1445 // return
1446 RETURN->v_int = ifft->m_window_size;
1450 //-----------------------------------------------------------------------------
1451 // name: size()
1452 // desc: ...
1453 //-----------------------------------------------------------------------------
1454 CK_DLL_CTRL( IFFT_ctrl_size )
1456 // get object
1457 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1458 // get arg
1459 t_CKINT size = GET_NEXT_INT(ARGS);
1460 // sanity
1461 if( size <= 0 ) goto invalid_size;
1462 // set size
1463 ifft->resize( size );
1464 // set RETURN
1465 RETURN->v_int = ifft->m_size;
1467 return;
1469 invalid_size:
1470 // we have a problem
1471 fprintf( stderr,
1472 "[chuck](IFFT): InvalidTransformSizeException (%d)\n", size );
1473 goto done;
1475 done:
1476 // set RETURN type
1477 RETURN->v_int = 0;
1478 // do something!
1479 if( SHRED != NULL )
1481 SHRED->is_running = FALSE;
1482 SHRED->is_done = TRUE;
1487 //-----------------------------------------------------------------------------
1488 // name:
1489 // desc:
1490 //-----------------------------------------------------------------------------
1491 CK_DLL_CGET( IFFT_cget_size )
1493 // get object
1494 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1495 // set RETURN
1496 RETURN->v_int = ifft->m_size;
1500 //-----------------------------------------------------------------------------
1501 // name:
1502 // desc:
1503 //-----------------------------------------------------------------------------
1504 CK_DLL_MFUN( IFFT_inverse )
1506 // get object
1507 IFFT_object * ifft = (IFFT_object *)OBJ_MEMBER_UINT(SELF, IFFT_offset_data);
1508 // get array
1509 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
1510 // check for null
1511 if( !arr )
1513 // log
1514 EM_log( CK_LOG_WARNING, "(via IFFT): null array passed to samples(...)" );
1515 return;
1518 // copy it
1519 ifft->copyTo( arr );
1523 //-----------------------------------------------------------------------------
1524 // name: prepare_window()
1525 // desc: ...
1526 //-----------------------------------------------------------------------------
1527 static t_CKBOOL prepare_window( void * ARGS, Chuck_VM_Shred * SHRED, t_CKINT & size )
1529 // get arg
1530 size = GET_NEXT_INT(ARGS);
1531 // sanity
1532 if( size <= 0 )
1534 // log
1535 EM_log( CK_LOG_WARNING, "(via Windowing): negative window size..." );
1536 return FALSE;
1539 // resize the thing
1540 if( size != Windowing_array->size() )
1541 Windowing_array->set_size( size );
1542 // sanity
1543 if( size != Windowing_array->size() )
1544 goto out_of_memory;
1545 // resize if necessary
1546 if( size > float_array_size )
1548 float_array_size = size;
1549 SAFE_DELETE_ARRAY( float_array );
1550 float_array = new FLOAT[float_array_size];
1551 if( !float_array ) goto out_of_memory;
1554 return TRUE;
1556 out_of_memory:
1557 // we have a problem
1558 fprintf( stderr,
1559 "[chuck](Windowing): OutOfMemoryException (allocating FLOAT[%d])\n",
1560 float_array_size );
1561 goto done;
1563 done:
1564 // do something!
1565 if( SHRED != NULL )
1567 SHRED->is_running = FALSE;
1568 SHRED->is_done = TRUE;
1571 return FALSE;
1575 //-----------------------------------------------------------------------------
1576 // name: hamming()
1577 // desc: ...
1578 //-----------------------------------------------------------------------------
1579 CK_DLL_SFUN( Windowing_hamming )
1581 // prepare the thing
1582 t_CKINT size = 0;
1583 if( !prepare_window( ARGS, SHRED, size ) )
1584 return;
1586 // get the window
1587 hamming( float_array, size );
1588 // copy it
1589 for( t_CKINT i = 0; i < size; i++ )
1590 Windowing_array->set( i, (t_CKFLOAT)float_array[i] );
1591 // return
1592 RETURN->v_object = Windowing_array;
1596 //-----------------------------------------------------------------------------
1597 // name: hann()
1598 // desc: ...
1599 //-----------------------------------------------------------------------------
1600 CK_DLL_SFUN( Windowing_hann )
1602 // prepare the thing
1603 t_CKINT size = 0;
1604 if( !prepare_window( ARGS, SHRED, size ) )
1605 return;
1607 // get the window
1608 hanning( float_array, size );
1609 // copy it
1610 for( t_CKINT i = 0; i < size; i++ )
1611 Windowing_array->set( i, (t_CKFLOAT)float_array[i] );
1612 // return
1613 RETURN->v_object = Windowing_array;
1617 //-----------------------------------------------------------------------------
1618 // name: blackmanHarris()
1619 // desc: ...
1620 //-----------------------------------------------------------------------------
1621 CK_DLL_SFUN( Windowing_blackmanHarris )
1623 // prepare the thing
1624 t_CKINT size = 0;
1625 if( !prepare_window( ARGS, SHRED, size ) )
1626 return;
1628 // get the window
1629 blackman( float_array, size );
1630 // copy it
1631 for( t_CKINT i = 0; i < size; i++ )
1632 Windowing_array->set( i, (t_CKFLOAT)float_array[i] );
1633 // return
1634 RETURN->v_object = Windowing_array;
1638 //-----------------------------------------------------------------------------
1639 // name: rectangle()
1640 // desc: ...
1641 //-----------------------------------------------------------------------------
1642 CK_DLL_SFUN( Windowing_rectangle )
1644 // prepare the thing
1645 t_CKINT size = 0;
1646 if( !prepare_window( ARGS, SHRED, size ) )
1647 return;
1649 // 1's
1650 for( t_CKINT i = 0; i < size; i++ )
1651 Windowing_array->set( i, 1 );
1652 // return
1653 RETURN->v_object = Windowing_array;
1657 //-----------------------------------------------------------------------------
1658 // name: Windowing_triangle()
1659 // desc: ...
1660 //-----------------------------------------------------------------------------
1661 CK_DLL_SFUN( Windowing_triangle )
1663 // prepare the thing
1664 t_CKINT size = 0;
1665 if( !prepare_window( ARGS, SHRED, size ) )
1666 return;
1668 // get the window
1669 bartlett( float_array, size );
1670 // copy it
1671 for( t_CKINT i = 0; i < size; i++ )
1672 Windowing_array->set( i, (t_CKFLOAT)float_array[i] );
1673 // return
1674 RETURN->v_object = Windowing_array;
1680 //-----------------------------------------------------------------------------
1681 // name: delete_matrix()
1682 // desc: deallocates NxN matrix
1683 //-----------------------------------------------------------------------------
1684 static void delete_matrix( SAMPLE ** matrix, t_CKUINT N )
1686 t_CKUINT i;
1688 // check
1689 if( !matrix ) return;
1691 // delete
1692 for( i = 0; i < N; i++ )
1693 SAFE_DELETE_ARRAY( matrix[i] );
1695 // delete
1696 SAFE_DELETE_ARRAY( matrix );
1702 //-----------------------------------------------------------------------------
1703 // name: Flip_object
1704 // desc: standalone object for Flip UAna
1705 //-----------------------------------------------------------------------------
1706 struct Flip_object
1708 public:
1709 Flip_object();
1710 virtual ~Flip_object();
1712 public:
1713 t_CKBOOL resize( t_CKINT size );
1714 t_CKBOOL window( Chuck_Array8 * window, t_CKINT win_size );
1715 void transform( );
1716 void transform( Chuck_Array8 * frame );
1717 void copyTo( Chuck_Array8 * val );
1719 public:
1720 // buffer
1721 SAMPLE * m_buffer;
1722 // size of Flip
1723 t_CKINT m_size;
1724 // window
1725 SAMPLE * m_window;
1726 // window size
1727 t_CKINT m_window_size;
1728 // sample accumulation buffer
1729 AccumBuffer m_accum;
1735 //-----------------------------------------------------------------------------
1736 // name: Flip_object()
1737 // desc: constructor
1738 //-----------------------------------------------------------------------------
1739 Flip_object::Flip_object()
1741 // initialize
1742 m_buffer = NULL;
1743 m_size = 512; // TODO: default
1744 m_window = NULL;
1745 m_window_size = m_size;
1746 // initialize window
1747 this->window( NULL, m_window_size );
1748 // allocate buffer
1749 this->resize( m_size );
1755 //-----------------------------------------------------------------------------
1756 // name: ~Flip_object()
1757 // desc: destructor
1758 //-----------------------------------------------------------------------------
1759 Flip_object::~Flip_object()
1761 // clean up
1762 SAFE_DELETE_ARRAY( m_window );
1763 SAFE_DELETE_ARRAY( m_buffer );
1764 m_window_size = 0;
1765 m_size = 0;
1771 //-----------------------------------------------------------------------------
1772 // name: resize()
1773 // desc: set Flip size
1774 //-----------------------------------------------------------------------------
1775 t_CKBOOL Flip_object::resize( t_CKINT size )
1777 // sanity check
1778 assert( size > 0 );
1780 // log
1781 EM_log( CK_LOG_FINE, "Flip resize %d -> %d", m_size, size );
1783 // reallocate
1784 SAFE_DELETE_ARRAY( m_buffer );
1785 m_size = 0;
1786 m_buffer = new SAMPLE[size];
1787 // check it
1788 if( !m_buffer )
1790 // out of memory
1791 fprintf( stderr, "[chuck]: Flip failed to allocate %ld buffer...\n",
1792 size );
1793 // clean
1794 SAFE_DELETE_ARRAY( m_buffer );
1795 // done
1796 return FALSE;
1799 // zero it
1800 memset( m_buffer, 0, size * sizeof(SAMPLE) );
1801 // set
1802 m_size = size;
1803 // if no window specified, then set accum size
1804 if( !m_window )
1806 m_window_size = m_size;
1807 // resize
1808 m_accum.resize( m_window_size );
1811 return TRUE;
1817 //-----------------------------------------------------------------------------
1818 // name: window()
1819 // desc: set window
1820 //-----------------------------------------------------------------------------
1821 t_CKBOOL Flip_object::window( Chuck_Array8 * win, t_CKINT win_size )
1823 // sanity check
1824 assert( win_size >= 0 );
1826 // in any case, clean up
1827 SAFE_DELETE_ARRAY( m_window );
1828 // reset
1829 m_window_size = 0;
1831 // could be NULL
1832 if( win != NULL )
1834 m_window = new SAMPLE[win_size];
1835 // check it
1836 if( !m_window )
1838 // out of memory
1839 fprintf( stderr, "[chuck]: Flip failed to allocate %ldxSAMPLE window...\n",
1840 m_size );
1841 // done
1842 return FALSE;
1845 // zero it
1846 memset( m_window, 0, win_size * sizeof(SAMPLE) );
1848 // set window
1849 m_window_size = win_size;
1850 // copy
1851 t_CKFLOAT sample;
1852 for( t_CKINT i = 0; i < win_size; i++ )
1854 // get
1855 win->get( i, &sample );
1856 // set
1857 m_window[i] = (SAMPLE)sample;
1860 else
1862 // set
1863 m_window_size = m_size;
1866 // resize
1867 m_accum.resize( m_window_size );
1869 return TRUE;
1875 //-----------------------------------------------------------------------------
1876 // name: transform()
1877 // desc: ...
1878 //-----------------------------------------------------------------------------
1879 void Flip_object::transform( )
1881 // buffer could be null
1882 if( m_buffer == NULL )
1884 // out of memory
1885 fprintf( stderr, "[chuck]: Flip failure due to NULL buffer...\n" );
1886 // bye
1887 return;
1890 // sanity
1891 assert( m_window_size <= m_size );
1893 // get the last buffer of samples
1894 m_accum.get( m_buffer, m_window_size );
1895 // apply window, if there is one
1896 if( m_window )
1897 apply_window( m_buffer, m_window, m_window_size );
1898 // zero pad
1899 memset( m_buffer + m_window_size, 0, (m_size - m_window_size)*sizeof(SAMPLE) );
1905 //-----------------------------------------------------------------------------
1906 // name: transform()
1907 // desc: ...
1908 //-----------------------------------------------------------------------------
1909 void Flip_object::transform( Chuck_Array8 * frame )
1911 // convert to right type
1912 t_CKINT amount = ck_min( frame->size(), m_size );
1913 // copy
1914 t_CKFLOAT v;
1915 for( t_CKINT i = 0; i < amount; i++ )
1917 // real and imag
1918 frame->get( i, &v );
1919 m_buffer[i] = v;
1921 // zero pad
1922 for( t_CKINT j = amount; j < m_size; j++ )
1923 m_buffer[j] = 0;
1925 // um
1926 this->transform();
1932 //-----------------------------------------------------------------------------
1933 // name: copyTo()
1934 // desc: ...
1935 //-----------------------------------------------------------------------------
1936 void Flip_object::copyTo( Chuck_Array8 * val )
1938 // buffer could be null
1939 if( m_buffer == NULL )
1941 // zero out
1942 val->clear();
1943 // bye
1944 return;
1947 // get amount
1948 t_CKINT amount = m_size;
1949 // allocate
1950 val->set_size( amount );
1952 t_CKINT i;
1953 for( i = 0; i < amount; i++ )
1954 val->set( i, m_buffer[i] );
1960 //-----------------------------------------------------------------------------
1961 // name:
1962 // desc:
1963 //-----------------------------------------------------------------------------
1964 CK_DLL_CTOR( Flip_ctor )
1966 // allocate the Flip object
1967 Flip_object * flip = new Flip_object;
1968 OBJ_MEMBER_UINT( SELF, Flip_offset_data ) = (t_CKUINT)flip;
1972 //-----------------------------------------------------------------------------
1973 // name:
1974 // desc:
1975 //-----------------------------------------------------------------------------
1976 CK_DLL_DTOR( Flip_dtor )
1978 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
1979 SAFE_DELETE( flip );
1980 OBJ_MEMBER_UINT(SELF, Flip_offset_data) = 0;
1984 //-----------------------------------------------------------------------------
1985 // name:
1986 // desc:
1987 //-----------------------------------------------------------------------------
1988 CK_DLL_TICK( Flip_tick )
1990 // accumulate samples
1991 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
1992 flip->m_accum.put( in );
1993 // zero output
1994 *out = 0;
1996 return TRUE;
2000 //-----------------------------------------------------------------------------
2001 // name:
2002 // desc:
2003 //-----------------------------------------------------------------------------
2004 CK_DLL_PMSG( Flip_pmsg )
2006 return TRUE;
2010 //-----------------------------------------------------------------------------
2011 // name:
2012 // desc:
2013 //-----------------------------------------------------------------------------
2014 CK_DLL_TOCK( Flip_tock )
2016 // get object
2017 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2018 // take transform
2019 flip->transform();
2020 // microsoft blows
2021 t_CKINT i;
2023 // get fvals of output BLOB
2024 Chuck_Array8 & fvals = BLOB->fvals();
2025 // ensure capacity == resulting size
2026 if( fvals.size() != flip->m_size )
2027 fvals.set_size( flip->m_size );
2028 // copy the result in
2029 for( i = 0; i < flip->m_size; i++ )
2030 fvals.set( i, flip->m_buffer[i] );
2032 return TRUE;
2036 //-----------------------------------------------------------------------------
2037 // name:
2038 // desc:
2039 //-----------------------------------------------------------------------------
2040 CK_DLL_MFUN( Flip_take )
2042 // get object
2043 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2044 // get array
2045 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
2046 // do it
2047 flip->transform( arr );
2051 //-----------------------------------------------------------------------------
2052 // name:
2053 // desc:
2054 //-----------------------------------------------------------------------------
2055 CK_DLL_CTRL( Flip_ctrl_window )
2057 // get object
2058 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2059 // get window (can be NULL)
2060 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
2061 // set it
2062 flip->window( arr, arr != NULL ? arr->size() : 0 );
2063 // return it through
2064 RETURN->v_object = arr;
2068 //-----------------------------------------------------------------------------
2069 // name:
2070 // desc:
2071 //-----------------------------------------------------------------------------
2072 CK_DLL_CGET( Flip_cget_window )
2074 // TODO: implement this!
2075 RETURN->v_object = NULL;
2079 //-----------------------------------------------------------------------------
2080 // name: windowSize()
2081 // desc:
2082 //-----------------------------------------------------------------------------
2083 CK_DLL_CGET( Flip_cget_windowSize )
2085 // get object
2086 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2087 // return
2088 RETURN->v_int = flip->m_window_size;
2092 //-----------------------------------------------------------------------------
2093 // name: size()
2094 // desc: ...
2095 //-----------------------------------------------------------------------------
2096 CK_DLL_CTRL( Flip_ctrl_size )
2098 // get object
2099 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2100 // get arg
2101 t_CKINT size = GET_NEXT_INT(ARGS);
2102 // sanity check
2103 if( size <= 0 ) goto invalid_size;
2104 // set size
2105 flip->resize( size );
2106 // set RETURN
2107 RETURN->v_int = flip->m_size;
2109 return;
2111 invalid_size:
2112 // we have a problem
2113 fprintf( stderr,
2114 "[chuck](IFFT): InvalidTransformSizeException (%d)\n", size );
2115 goto done;
2117 done:
2118 // set RETURN type
2119 RETURN->v_int = 0;
2120 // do something!
2121 if( SHRED != NULL )
2123 SHRED->is_running = FALSE;
2124 SHRED->is_done = TRUE;
2129 //-----------------------------------------------------------------------------
2130 // name:
2131 // desc:
2132 //-----------------------------------------------------------------------------
2133 CK_DLL_CGET( Flip_cget_size )
2135 // get object
2136 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2137 // set RETURN
2138 RETURN->v_int = flip->m_size;
2142 //-----------------------------------------------------------------------------
2143 // name:
2144 // desc:
2145 //-----------------------------------------------------------------------------
2146 CK_DLL_MFUN( Flip_output )
2148 // get object
2149 Flip_object * flip = (Flip_object *)OBJ_MEMBER_UINT(SELF, Flip_offset_data);
2150 // get array
2151 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
2152 // check for null
2153 if( !arr )
2155 // log
2156 EM_log( CK_LOG_WARNING, "(via Flip): null array passed to spectrum(...)" );
2157 return;
2160 // copy it
2161 flip->copyTo( arr );
2167 //-----------------------------------------------------------------------------
2168 // name: UnFlip_object
2169 // desc: standalone object for UnFlip UAna
2170 //-----------------------------------------------------------------------------
2171 struct UnFlip_object
2173 public:
2174 UnFlip_object();
2175 virtual ~UnFlip_object();
2177 public:
2178 t_CKBOOL resize( t_CKINT size );
2179 t_CKBOOL window( Chuck_Array8 * window, t_CKINT win_size );
2180 void transform( );
2181 void transform( Chuck_Array8 * val );
2182 void copyTo( Chuck_Array8 * samples );
2184 public:
2185 // size of IFFT
2186 t_CKINT m_size;
2187 // window
2188 SAMPLE * m_window;
2189 // window size
2190 t_CKINT m_window_size;
2191 // sample deccumulation buffer
2192 DeccumBuffer m_deccum;
2193 // UnFlip buffer
2194 SAMPLE * m_buffer;
2200 //-----------------------------------------------------------------------------
2201 // name: UnFlip_object()
2202 // desc: constructor
2203 //-----------------------------------------------------------------------------
2204 UnFlip_object::UnFlip_object()
2206 // initialize
2207 m_size = 512; // TODO: default
2208 m_window = NULL;
2209 m_window_size = m_size;
2210 m_buffer = NULL;
2211 // initialize window
2212 this->window( NULL, m_window_size );
2213 // allocate buffer
2214 this->resize( m_size );
2220 //-----------------------------------------------------------------------------
2221 // name: ~UnFlip_object()
2222 // desc: destructor
2223 //-----------------------------------------------------------------------------
2224 UnFlip_object::~UnFlip_object()
2226 // clean up
2227 SAFE_DELETE_ARRAY( m_window );
2228 SAFE_DELETE_ARRAY( m_buffer );
2229 m_window_size = 0;
2230 m_size = 0;
2236 //-----------------------------------------------------------------------------
2237 // name: resize()
2238 // desc: set UnFlip size
2239 //-----------------------------------------------------------------------------
2240 t_CKBOOL UnFlip_object::resize( t_CKINT size )
2242 // sanity check
2243 assert( size > 0 );
2245 // log
2246 EM_log( CK_LOG_FINE, "UnFlip resize %d -> %d", m_size, size );
2248 // reallocate
2249 SAFE_DELETE_ARRAY( m_buffer );
2250 m_size = 0;
2251 m_buffer = new SAMPLE[size];
2252 // check it
2253 if( !m_buffer )
2255 // out of memory
2256 fprintf( stderr, "[chuck]: UnFlip failed to allocate %ld buffer...\n",
2257 size );
2258 // clean
2259 SAFE_DELETE_ARRAY( m_buffer );
2260 // done
2261 return FALSE;
2264 // zero it
2265 memset( m_buffer, 0, size * sizeof(SAMPLE) );
2266 // set
2267 m_size = size;
2268 // set deccum size
2269 m_deccum.resize( m_size );
2270 // if no window specified, then set accum size
2271 if( !m_window )
2272 m_window_size = m_size;
2274 return TRUE;
2280 //-----------------------------------------------------------------------------
2281 // name: window()
2282 // desc: set window
2283 //-----------------------------------------------------------------------------
2284 t_CKBOOL UnFlip_object::window( Chuck_Array8 * win, t_CKINT win_size )
2286 // sanity check
2287 assert( win_size >= 0 );
2289 // in any case, clean up
2290 SAFE_DELETE_ARRAY( m_window );
2291 // reset
2292 m_window_size = 0;
2294 // could be NULL
2295 if( win != NULL )
2297 m_window = new SAMPLE[win_size];
2298 // check it
2299 if( !m_window )
2301 // out of memory
2302 fprintf( stderr, "[chuck]: UnFlip failed to allocate %ldxSAMPLE window...\n",
2303 m_size );
2304 // done
2305 return FALSE;
2308 // zero it
2309 memset( m_window, 0, win_size * sizeof(SAMPLE) );
2311 // set window
2312 m_window_size = win_size;
2313 // copy
2314 t_CKFLOAT sample;
2315 for( t_CKINT i = 0; i < win_size; i++ )
2317 // get
2318 win->get( i, &sample );
2319 // set
2320 m_window[i] = (SAMPLE)sample;
2323 else
2325 // set
2326 m_window_size = m_size;
2329 return TRUE;
2335 //-----------------------------------------------------------------------------
2336 // name: transform()
2337 // desc: ...
2338 //-----------------------------------------------------------------------------
2339 void UnFlip_object::transform( )
2341 // buffer could be null
2342 if( m_buffer == NULL )
2344 // out of memory
2345 fprintf( stderr, "[chuck]: UnFlip failure due to NULL buffer...\n" );
2346 // bye
2347 return;
2350 // sanity
2351 assert( m_window_size <= m_size );
2352 // apply window, if there is one
2353 if( m_window )
2354 apply_window( m_buffer, m_window, m_window_size );
2355 // zero
2356 memset( m_buffer + m_window_size, 0, (m_size-m_window_size)*sizeof(SAMPLE) );
2357 // put in deccum buffer
2358 m_deccum.put( m_buffer, m_size );
2364 //-----------------------------------------------------------------------------
2365 // name: transform()
2366 // desc: ...
2367 //-----------------------------------------------------------------------------
2368 void UnFlip_object::transform( Chuck_Array8 * val )
2370 // convert to right type
2371 t_CKINT amount = ck_min( val->size(), m_size );
2372 // copy
2373 t_CKFLOAT v;
2374 for( t_CKINT i = 0; i < amount; i++ )
2376 // real and imag
2377 val->get( i, &v );
2378 m_buffer[i] = v;
2380 // zero pad
2381 for( t_CKINT j = amount; j < m_size; j++ )
2382 m_buffer[j] = 0;
2384 // um
2385 this->transform();
2391 //-----------------------------------------------------------------------------
2392 // name: copyTo()
2393 // desc: ...
2394 //-----------------------------------------------------------------------------
2395 void UnFlip_object::copyTo( Chuck_Array8 * samples )
2397 // buffer could be null
2398 if( m_buffer == NULL )
2400 // zero out
2401 samples->clear();
2402 // samples->zero( 0, samples->size() );
2403 // bye
2404 return;
2407 // the amount
2408 t_CKINT amount = m_size; // ck_min( m_size, samples->size() );
2409 // allocate
2410 samples->set_size( amount );
2412 // go over
2413 for( t_CKINT i = 0; i < amount; i++ )
2414 samples->set( i, m_buffer[i] );
2420 //-----------------------------------------------------------------------------
2421 // name:
2422 // desc:
2423 //-----------------------------------------------------------------------------
2424 CK_DLL_CTOR( UnFlip_ctor )
2426 // allocate the UnFlip object
2427 UnFlip_object * unflip = new UnFlip_object;
2428 OBJ_MEMBER_UINT( SELF, UnFlip_offset_data ) = (t_CKUINT)unflip;
2432 //-----------------------------------------------------------------------------
2433 // name:
2434 // desc:
2435 //-----------------------------------------------------------------------------
2436 CK_DLL_DTOR( UnFlip_dtor )
2438 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2439 SAFE_DELETE( unflip );
2440 OBJ_MEMBER_UINT(SELF, UnFlip_offset_data) = 0;
2444 //-----------------------------------------------------------------------------
2445 // name:
2446 // desc:
2447 //-----------------------------------------------------------------------------
2448 CK_DLL_TICK( UnFlip_tick )
2450 // accumulate samples
2451 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2452 // get output
2453 unflip->m_deccum.get( out );
2455 return TRUE;
2459 //-----------------------------------------------------------------------------
2460 // name:
2461 // desc:
2462 //-----------------------------------------------------------------------------
2463 CK_DLL_PMSG( UnFlip_pmsg )
2465 return TRUE;
2469 //-----------------------------------------------------------------------------
2470 // name:
2471 // desc:
2472 //-----------------------------------------------------------------------------
2473 CK_DLL_TOCK( UnFlip_tock )
2475 // get object
2476 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2477 // TODO: get buffer from stream, and set in UnFlip
2478 if( UANA->numIncomingUAnae() > 0 )
2480 // get first
2481 Chuck_UAnaBlobProxy * BLOB_IN = UANA->getIncomingBlob( 0 );
2482 // sanity check
2483 assert( BLOB_IN != NULL );
2484 // get the array
2485 Chuck_Array8 & val = BLOB_IN->fvals();
2486 // resize if necessary
2487 if( val.size() > unflip->m_size )
2488 unflip->resize( val.size() );
2489 // sanity check
2490 assert( unflip->m_buffer != NULL );
2491 // copy into transform buffer
2492 t_CKFLOAT v;
2493 for( t_CKINT i = 0; i < unflip->m_size; i++ )
2495 // copy value in
2496 val.get( i, &v );
2497 unflip->m_buffer[i] = v;
2500 // take transform
2501 unflip->transform();
2503 // otherwise zero out
2504 else
2506 // sanity check
2507 assert( unflip->m_buffer != NULL );
2508 memset( unflip->m_buffer, 0, sizeof(SAMPLE)*unflip->m_size );
2511 // get fvals of output BLOB
2512 Chuck_Array8 & fvals = BLOB->fvals();
2513 // ensure size == resulting size
2514 if( fvals.size() != unflip->m_size )
2515 fvals.set_size( unflip->m_size );
2516 // copy the result in
2517 for( t_CKINT i = 0; i < unflip->m_size; i++ )
2518 fvals.set( i, unflip->m_buffer[i] );
2520 return TRUE;
2524 //-----------------------------------------------------------------------------
2525 // name:
2526 // desc:
2527 //-----------------------------------------------------------------------------
2528 CK_DLL_MFUN( UnFlip_take )
2530 // get object
2531 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2532 // get complex array
2533 Chuck_Array8 * val = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
2534 // sanity
2535 if( val == NULL ) goto null_pointer;
2536 // resize if bigger
2537 if( val->size() > unflip->m_size )
2538 unflip->resize( val->size() );
2539 // transform it
2540 unflip->transform( val );
2542 return;
2544 null_pointer:
2545 // we have a problem
2546 fprintf( stderr,
2547 "[chuck](UnFlip): NullPointerException (argument is NULL)\n");
2548 goto done;
2550 done:
2551 // do something!
2552 if( SHRED != NULL )
2554 SHRED->is_running = FALSE;
2555 SHRED->is_done = TRUE;
2560 //-----------------------------------------------------------------------------
2561 // name:
2562 // desc:
2563 //-----------------------------------------------------------------------------
2564 CK_DLL_CTRL( UnFlip_ctrl_window )
2566 // get object
2567 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data );
2568 // get win (can be NULL)
2569 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
2570 // set it
2571 unflip->window( arr, arr != NULL ? arr->size() : 0 );
2572 // return
2573 RETURN->v_object = arr;
2577 //-----------------------------------------------------------------------------
2578 // name:
2579 // desc:
2580 //-----------------------------------------------------------------------------
2581 CK_DLL_CGET( UnFlip_cget_window )
2583 // TODO: implement this
2584 RETURN->v_object = NULL;
2588 //-----------------------------------------------------------------------------
2589 // name: windowSize()
2590 // desc:
2591 //-----------------------------------------------------------------------------
2592 CK_DLL_CGET( UnFlip_cget_windowSize )
2594 // get object
2595 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2596 // return
2597 RETURN->v_int = unflip->m_window_size;
2601 //-----------------------------------------------------------------------------
2602 // name: size()
2603 // desc: ...
2604 //-----------------------------------------------------------------------------
2605 CK_DLL_CTRL( UnFlip_ctrl_size )
2607 // get object
2608 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2609 // get arg
2610 t_CKINT size = GET_NEXT_INT(ARGS);
2611 // sanity
2612 if( size <= 0 ) goto invalid_size;
2613 // set size
2614 unflip->resize( size );
2615 // set RETURN
2616 RETURN->v_int = unflip->m_size;
2618 return;
2620 invalid_size:
2621 // we have a problem
2622 fprintf( stderr,
2623 "[chuck](UnFlip): InvalidTransformSizeException (%d)\n", size );
2624 goto done;
2626 done:
2627 // set RETURN type
2628 RETURN->v_int = 0;
2629 // do something!
2630 if( SHRED != NULL )
2632 SHRED->is_running = FALSE;
2633 SHRED->is_done = TRUE;
2638 //-----------------------------------------------------------------------------
2639 // name:
2640 // desc:
2641 //-----------------------------------------------------------------------------
2642 CK_DLL_CGET( UnFlip_cget_size )
2644 // get object
2645 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2646 // set RETURN
2647 RETURN->v_int = unflip->m_size;
2651 //-----------------------------------------------------------------------------
2652 // name:
2653 // desc:
2654 //-----------------------------------------------------------------------------
2655 CK_DLL_MFUN( UnFlip_output )
2657 // get object
2658 UnFlip_object * unflip = (UnFlip_object *)OBJ_MEMBER_UINT(SELF, UnFlip_offset_data);
2659 // get array
2660 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
2661 // check for null
2662 if( !arr )
2664 // log
2665 EM_log( CK_LOG_WARNING, "(via UnFlip): null array passed to samples(...)" );
2666 return;
2669 // copy it
2670 unflip->copyTo( arr );
2676 //-----------------------------------------------------------------------------
2677 // name: DCT_object
2678 // desc: standalone object for DCT UAna
2679 //-----------------------------------------------------------------------------
2680 struct DCT_object
2682 public:
2683 DCT_object();
2684 virtual ~DCT_object();
2686 public:
2687 t_CKBOOL resize( t_CKINT size );
2688 t_CKBOOL window( Chuck_Array8 * window, t_CKINT win_size );
2689 void transform( );
2690 void transform( const t_CKFLOAT * in, t_CKCOMPLEX * out );
2691 void copyTo( Chuck_Array8 * frame );
2693 public:
2694 // size of DCT
2695 t_CKINT m_size;
2696 // window
2697 SAMPLE * m_window;
2698 // window size
2699 t_CKINT m_window_size;
2700 // sample accumulation buffer
2701 AccumBuffer m_accum;
2702 // DCT buffer
2703 SAMPLE * m_buffer;
2704 // DCT matrix
2705 SAMPLE ** m_matrix;
2706 // result
2707 SAMPLE * m_spectrum;
2713 //-----------------------------------------------------------------------------
2714 // name: DCT_object()
2715 // desc: constructor
2716 //-----------------------------------------------------------------------------
2717 DCT_object::DCT_object()
2719 // initialize
2720 m_size = 512; // TODO: default
2721 m_window = NULL;
2722 m_window_size = m_size;
2723 m_buffer = NULL;
2724 m_matrix = NULL;
2725 m_spectrum = NULL;
2726 // initialize window
2727 this->window( NULL, m_window_size );
2728 // allocate buffer
2729 this->resize( m_size );
2735 //-----------------------------------------------------------------------------
2736 // name: ~DCT_object()
2737 // desc: destructor
2738 //-----------------------------------------------------------------------------
2739 DCT_object::~DCT_object()
2741 // clean up
2742 SAFE_DELETE_ARRAY( m_window );
2743 SAFE_DELETE_ARRAY( m_buffer );
2744 delete_matrix( m_matrix, m_size );
2745 SAFE_DELETE_ARRAY( m_spectrum );
2746 m_window_size = 0;
2747 m_size = 0;
2753 //-----------------------------------------------------------------------------
2754 // name: resize()
2755 // desc: set DCT size
2756 //-----------------------------------------------------------------------------
2757 t_CKBOOL DCT_object::resize( t_CKINT size )
2759 t_CKUINT i;
2761 // sanity check
2762 assert( size > 0 );
2764 // reallocate
2765 SAFE_DELETE_ARRAY( m_buffer );
2766 delete_matrix( m_matrix, m_size );
2767 SAFE_DELETE_ARRAY( m_spectrum );
2768 m_size = 0;
2769 m_buffer = new SAMPLE[size];
2770 m_spectrum = new SAMPLE[size];
2771 m_matrix = new SAMPLE *[size];
2772 for( i = 0; i < size; i++ ) m_matrix[i] = new SAMPLE[size];
2774 // check it
2775 if( !m_buffer || !m_spectrum || !m_matrix )
2777 // out of memory
2778 fprintf( stderr, "[chuck]: DCT failed to allocate %ld, %ld buffers...\n",
2779 size, size/2 );
2780 // clean
2781 SAFE_DELETE_ARRAY( m_buffer );
2782 delete_matrix( m_matrix, size );
2783 SAFE_DELETE_ARRAY( m_spectrum );
2784 // done
2785 return FALSE;
2788 // zero it
2789 memset( m_buffer, 0, size * sizeof(SAMPLE) );
2790 memset( m_spectrum, 0, size * sizeof(SAMPLE) );
2791 // compute dct matrix
2792 the_dct_matrix( m_matrix, size );
2793 // set
2794 m_size = size;
2795 // if no window specified, then set accum size
2796 if( !m_window )
2798 m_window_size = m_size;
2799 // resize
2800 m_accum.resize( m_window_size );
2803 return TRUE;
2809 //-----------------------------------------------------------------------------
2810 // name: window()
2811 // desc: set window
2812 //-----------------------------------------------------------------------------
2813 t_CKBOOL DCT_object::window( Chuck_Array8 * win, t_CKINT win_size )
2815 // sanity check
2816 assert( win_size >= 0 );
2818 // in any case, clean up
2819 SAFE_DELETE_ARRAY( m_window );
2820 // reset
2821 m_window_size = 0;
2823 // could be NULL
2824 if( win != NULL )
2826 m_window = new SAMPLE[win_size];
2827 // check it
2828 if( !m_window )
2830 // out of memory
2831 fprintf( stderr, "[chuck]: DCT failed to allocate %ldxSAMPLE window...\n",
2832 m_size );
2833 // done
2834 return FALSE;
2837 // zero it
2838 memset( m_window, 0, win_size * sizeof(SAMPLE) );
2840 // set window
2841 m_window_size = win_size;
2842 // copy
2843 t_CKFLOAT sample;
2844 for( t_CKINT i = 0; i < win_size; i++ )
2846 // get
2847 win->get( i, &sample );
2848 // set
2849 m_window[i] = (SAMPLE)sample;
2852 else
2854 // set
2855 m_window_size = m_size;
2858 // resize
2859 m_accum.resize( m_window_size );
2861 return TRUE;
2867 //-----------------------------------------------------------------------------
2868 // name: transform()
2869 // desc: ...
2870 //-----------------------------------------------------------------------------
2871 void DCT_object::transform( )
2873 // buffer could be null
2874 if( m_buffer == NULL && m_spectrum == NULL )
2876 // out of memory
2877 fprintf( stderr, "[chuck]: DCT failure due to NULL buffer...\n" );
2878 // bye
2879 return;
2882 // sanity
2883 assert( m_window_size <= m_size );
2885 // get the last buffer of samples
2886 m_accum.get( m_buffer, m_window_size );
2887 // apply window, if there is one
2888 if( m_window )
2889 apply_window( m_buffer, m_window, m_window_size );
2890 // zero pad
2891 memset( m_buffer + m_window_size, 0, (m_size - m_window_size)*sizeof(SAMPLE) );
2892 // go for it
2893 the_dct_now( m_buffer, m_matrix, m_size, m_spectrum, m_size );
2899 //-----------------------------------------------------------------------------
2900 // name: copyTo()
2901 // desc: ...
2902 //-----------------------------------------------------------------------------
2903 void DCT_object::copyTo( Chuck_Array8 * frame )
2905 // buffer could be null
2906 if( m_buffer == NULL && m_spectrum == NULL )
2908 // zero out
2909 frame->clear();
2910 // bye
2911 return;
2914 // amount
2915 t_CKINT amount = m_size;
2916 // allocate
2917 frame->set_size( amount );
2919 t_CKINT i;
2920 for( i = 0; i < amount; i++ )
2921 frame->set( i, m_spectrum[i] );
2924 // copy modulo 2*pi
2925 t_CKINT left = frame->size();
2926 t_CKINT amount, i, sum = 0, which = 0;
2928 // go
2929 while( left )
2931 // get
2932 amount = ck_min( m_size, left );
2934 // go over spectrum
2935 if( which == 0 )
2936 for( i = 0; i < amount; i++ )
2937 frame->set( i+sum, m_spectrum[i] );
2938 else
2939 for( i = 0; i < amount; i++ )
2940 frame->set( i+sum, 0.0 );
2942 // update
2943 left -= amount;
2944 sum += amount;
2945 if( !which ) which = 1;
2953 //-----------------------------------------------------------------------------
2954 // name:
2955 // desc:
2956 //-----------------------------------------------------------------------------
2957 CK_DLL_CTOR( DCT_ctor )
2959 // allocate the dct object
2960 DCT_object * dct = new DCT_object;
2961 OBJ_MEMBER_UINT( SELF, DCT_offset_data ) = (t_CKUINT)dct;
2965 //-----------------------------------------------------------------------------
2966 // name:
2967 // desc:
2968 //-----------------------------------------------------------------------------
2969 CK_DLL_DTOR( DCT_dtor )
2971 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
2972 SAFE_DELETE( dct );
2973 OBJ_MEMBER_UINT(SELF, DCT_offset_data) = 0;
2977 //-----------------------------------------------------------------------------
2978 // name:
2979 // desc:
2980 //-----------------------------------------------------------------------------
2981 CK_DLL_TICK( DCT_tick )
2983 // accumulate samples
2984 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
2985 dct->m_accum.put( in );
2986 // zero output
2987 *out = 0;
2989 return TRUE;
2993 //-----------------------------------------------------------------------------
2994 // name:
2995 // desc:
2996 //-----------------------------------------------------------------------------
2997 CK_DLL_PMSG( DCT_pmsg )
2999 return TRUE;
3003 //-----------------------------------------------------------------------------
3004 // name:
3005 // desc:
3006 //-----------------------------------------------------------------------------
3007 CK_DLL_TOCK( DCT_tock )
3009 // get object
3010 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3011 // take transform
3012 dct->transform();
3013 // microsoft blows
3014 t_CKINT i;
3016 // get cvals of output BLOB
3017 Chuck_Array8 & fvals = BLOB->fvals();
3018 // ensure capacity == resulting size
3019 if( fvals.size() != dct->m_size )
3020 fvals.set_size( dct->m_size );
3021 // copy the result in
3022 for( i = 0; i < dct->m_size; i++ )
3023 fvals.set( i, dct->m_spectrum[i] );
3025 return TRUE;
3029 //-----------------------------------------------------------------------------
3030 // name:
3031 // desc:
3032 //-----------------------------------------------------------------------------
3033 CK_DLL_MFUN( DCT_transform )
3035 // get object
3036 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3037 // get array
3038 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
3042 //-----------------------------------------------------------------------------
3043 // name:
3044 // desc:
3045 //-----------------------------------------------------------------------------
3046 CK_DLL_CTRL( DCT_ctrl_window )
3048 // get object
3049 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3050 // get window (can be NULL)
3051 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
3052 // set it
3053 dct->window( arr, arr != NULL ? arr->size() : 0 );
3057 //-----------------------------------------------------------------------------
3058 // name:
3059 // desc:
3060 //-----------------------------------------------------------------------------
3061 CK_DLL_CGET( DCT_cget_window )
3066 //-----------------------------------------------------------------------------
3067 // name: windowSize()
3068 // desc:
3069 //-----------------------------------------------------------------------------
3070 CK_DLL_CGET( DCT_cget_windowSize )
3072 // get object
3073 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3074 // return
3075 RETURN->v_int = dct->m_window_size;
3079 //-----------------------------------------------------------------------------
3080 // name: size()
3081 // desc: ...
3082 //-----------------------------------------------------------------------------
3083 CK_DLL_CTRL( DCT_ctrl_size )
3085 // get object
3086 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3087 // get arg
3088 t_CKINT size = GET_NEXT_INT(ARGS);
3089 // sanity check
3090 if( size <= 0 ) goto invalid_size;
3091 // set size
3092 dct->resize( size );
3093 // set RETURN
3094 RETURN->v_int = dct->m_size;
3096 return;
3098 invalid_size:
3099 // we have a problem
3100 fprintf( stderr,
3101 "[chuck](IDCT): InvalidTransformSizeException (%d)\n", size );
3102 goto done;
3104 done:
3105 // set RETURN type
3106 RETURN->v_int = 0;
3107 // do something!
3108 if( SHRED != NULL )
3110 SHRED->is_running = FALSE;
3111 SHRED->is_done = TRUE;
3116 //-----------------------------------------------------------------------------
3117 // name:
3118 // desc:
3119 //-----------------------------------------------------------------------------
3120 CK_DLL_CGET( DCT_cget_size )
3122 // get object
3123 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3124 // set RETURN
3125 RETURN->v_int = dct->m_size;
3129 //-----------------------------------------------------------------------------
3130 // name:
3131 // desc:
3132 //-----------------------------------------------------------------------------
3133 CK_DLL_MFUN( DCT_spectrum )
3135 // get object
3136 DCT_object * dct = (DCT_object *)OBJ_MEMBER_UINT(SELF, DCT_offset_data);
3137 // get array
3138 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
3139 // check for null
3140 if( !arr )
3142 // log
3143 EM_log( CK_LOG_WARNING, "(via DCT): null array passed to spectrum(...)" );
3144 return;
3147 // copy it
3148 dct->copyTo( arr );
3154 //-----------------------------------------------------------------------------
3155 // name: IDCT_object
3156 // desc: standalone object for IDCT UAna
3157 //-----------------------------------------------------------------------------
3158 struct IDCT_object
3160 public:
3161 IDCT_object();
3162 virtual ~IDCT_object();
3164 public:
3165 t_CKBOOL resize( t_CKINT size );
3166 t_CKBOOL window( Chuck_Array8 * window, t_CKINT win_size );
3167 void transform( );
3168 void transform( Chuck_Array8 * frame );
3169 void copyTo( Chuck_Array8 * samples );
3171 public:
3172 // size of IDCT
3173 t_CKINT m_size;
3174 // window
3175 SAMPLE * m_window;
3176 // window size
3177 t_CKINT m_window_size;
3178 // sample deccumulation buffer
3179 DeccumBuffer m_deccum;
3180 // IDCT buffer
3181 SAMPLE * m_buffer;
3182 // IDCT matrix
3183 SAMPLE ** m_matrix;
3184 // result
3185 SAMPLE * m_inverse;
3191 //-----------------------------------------------------------------------------
3192 // name: IDCT_object()
3193 // desc: constructor
3194 //-----------------------------------------------------------------------------
3195 IDCT_object::IDCT_object()
3197 // initialize
3198 m_size = 512; // TODO: default
3199 m_window = NULL;
3200 m_window_size = m_size;
3201 m_buffer = NULL;
3202 m_matrix = NULL;
3203 m_inverse = NULL;
3204 // initialize window
3205 this->window( NULL, m_window_size );
3206 // allocate buffer
3207 this->resize( m_size );
3213 //-----------------------------------------------------------------------------
3214 // name: ~IDCT_object()
3215 // desc: destructor
3216 //-----------------------------------------------------------------------------
3217 IDCT_object::~IDCT_object()
3219 // clean up
3220 SAFE_DELETE_ARRAY( m_window );
3221 SAFE_DELETE_ARRAY( m_buffer );
3222 delete_matrix( m_matrix, m_size );
3223 SAFE_DELETE_ARRAY( m_inverse );
3224 m_window_size = 0;
3225 m_size = 0;
3231 //-----------------------------------------------------------------------------
3232 // name: resize()
3233 // desc: set IDCT size
3234 //-----------------------------------------------------------------------------
3235 t_CKBOOL IDCT_object::resize( t_CKINT size )
3237 t_CKUINT i;
3239 // sanity check
3240 assert( size > 0 );
3242 // reallocate
3243 SAFE_DELETE_ARRAY( m_buffer );
3244 delete_matrix( m_matrix, m_size );
3245 SAFE_DELETE_ARRAY( m_inverse );
3246 m_size = 0;
3247 m_buffer = new SAMPLE[size];
3248 m_matrix = new SAMPLE *[size];
3249 for( i = 0; i < size; i++ ) m_matrix[i] = new SAMPLE[size];
3250 m_inverse = new SAMPLE[size];
3251 // check it TODO: check individual m_matrix[i]
3252 if( !m_buffer || !m_inverse || !m_matrix )
3254 // out of memory
3255 fprintf( stderr, "[chuck]: IDCT failed to allocate %ld, %ld, %ldx%ld buffers...\n",
3256 size, size, size, size );
3257 // clean
3258 SAFE_DELETE_ARRAY( m_buffer );
3259 delete_matrix( m_matrix, size );
3260 SAFE_DELETE_ARRAY( m_inverse );
3261 // done
3262 return FALSE;
3265 // zero it
3266 memset( m_buffer, 0, size * sizeof(SAMPLE) );
3267 memset( m_inverse, 0, size * sizeof(SAMPLE) );
3268 // compute IDCT matrix
3269 the_inverse_dct_matrix( m_matrix, size );
3270 // set
3271 m_size = size;
3272 // set deccum size
3273 m_deccum.resize( m_size );
3274 // if no window specified, then set accum size
3275 if( !m_window )
3276 m_window_size = m_size;
3278 return TRUE;
3284 //-----------------------------------------------------------------------------
3285 // name: window()
3286 // desc: set window
3287 //-----------------------------------------------------------------------------
3288 t_CKBOOL IDCT_object::window( Chuck_Array8 * win, t_CKINT win_size )
3290 // sanity check
3291 assert( win_size >= 0 );
3293 // in any case, clean up
3294 SAFE_DELETE_ARRAY( m_window );
3295 // reset
3296 m_window_size = 0;
3298 // could be NULL
3299 if( win != NULL )
3301 m_window = new SAMPLE[win_size];
3302 // check it
3303 if( !m_window )
3305 // out of memory
3306 fprintf( stderr, "[chuck]: IDCT failed to allocate %ldxSAMPLE window...\n",
3307 m_size );
3308 // done
3309 return FALSE;
3312 // zero it
3313 memset( m_window, 0, win_size * sizeof(SAMPLE) );
3315 // set window
3316 m_window_size = win_size;
3317 // copy
3318 t_CKFLOAT sample;
3319 for( t_CKINT i = 0; i < win_size; i++ )
3321 // get
3322 win->get( i, &sample );
3323 // set
3324 m_window[i] = (SAMPLE)sample;
3327 else
3329 // set
3330 m_window_size = m_size;
3333 return TRUE;
3339 //-----------------------------------------------------------------------------
3340 // name: transform()
3341 // desc: ...
3342 //-----------------------------------------------------------------------------
3343 void IDCT_object::transform( )
3345 // buffer could be null
3346 if( m_buffer == NULL && m_inverse == NULL )
3348 // out of memory
3349 fprintf( stderr, "[chuck]: IDCT failure due to NULL buffer...\n" );
3350 // bye
3351 return;
3354 // sanity
3355 assert( m_window_size <= m_size );
3356 // go for it
3357 the_inverse_dct_now( m_buffer, m_matrix, m_size, m_inverse, m_size );
3358 // apply window, if there is one
3359 if( m_window )
3360 apply_window( m_inverse, m_window, m_window_size );
3361 // zero
3362 memset( m_inverse + m_window_size, 0, (m_size-m_window_size)*sizeof(SAMPLE) );
3363 // put in deccum buffer
3364 m_deccum.put( m_inverse, m_size );
3370 //-----------------------------------------------------------------------------
3371 // name: transform()
3372 // desc: ...
3373 //-----------------------------------------------------------------------------
3374 void IDCT_object::transform( Chuck_Array8 * frame )
3376 // convert to right type
3377 t_CKINT amount = ck_min( frame->size(), m_size );
3378 // copy
3379 t_CKFLOAT v;
3380 for( t_CKINT i = 0; i < amount; i++ )
3382 // real and imag
3383 frame->get( i, &v );
3384 m_buffer[i] = v;
3386 // zero pad
3387 for( t_CKINT j = amount; j < m_size; j++ )
3388 m_buffer[j] = 0;
3390 // um
3391 this->transform();
3397 //-----------------------------------------------------------------------------
3398 // name: copyTo()
3399 // desc: ...
3400 //-----------------------------------------------------------------------------
3401 void IDCT_object::copyTo( Chuck_Array8 * samples )
3403 // buffer could be null
3404 if( m_buffer == NULL && m_inverse == NULL )
3406 // zero out
3407 samples->clear();
3408 // bye
3409 return;
3412 // the amount
3413 t_CKINT amount = m_size; // ck_min( m_size, samples->size() );
3414 // allocate
3415 samples->set_size( amount );
3417 // go over
3418 for( t_CKINT i = 0; i < amount; i++ )
3419 samples->set( i, m_inverse[i] );
3421 // any left
3422 // if( amount < samples->size() )
3423 // samples->set_size( amount );
3429 //-----------------------------------------------------------------------------
3430 // name:
3431 // desc:
3432 //-----------------------------------------------------------------------------
3433 CK_DLL_CTOR( IDCT_ctor )
3435 // allocate the idct object
3436 IDCT_object * idct = new IDCT_object;
3437 OBJ_MEMBER_UINT( SELF, IDCT_offset_data ) = (t_CKUINT)idct;
3441 //-----------------------------------------------------------------------------
3442 // name:
3443 // desc:
3444 //-----------------------------------------------------------------------------
3445 CK_DLL_DTOR( IDCT_dtor )
3447 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3448 SAFE_DELETE( idct );
3449 OBJ_MEMBER_UINT(SELF, IDCT_offset_data) = 0;
3453 //-----------------------------------------------------------------------------
3454 // name:
3455 // desc:
3456 //-----------------------------------------------------------------------------
3457 CK_DLL_TICK( IDCT_tick )
3459 // accumulate samples
3460 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3461 // get output
3462 idct->m_deccum.get( out );
3464 return TRUE;
3468 //-----------------------------------------------------------------------------
3469 // name:
3470 // desc:
3471 //-----------------------------------------------------------------------------
3472 CK_DLL_PMSG( IDCT_pmsg )
3474 return TRUE;
3478 //-----------------------------------------------------------------------------
3479 // name:
3480 // desc:
3481 //-----------------------------------------------------------------------------
3482 CK_DLL_TOCK( IDCT_tock )
3484 // get object
3485 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3486 // TODO: get buffer from stream, and set in idct
3487 if( UANA->numIncomingUAnae() > 0 )
3489 // get first
3490 Chuck_UAnaBlobProxy * BLOB_IN = UANA->getIncomingBlob( 0 );
3491 // sanity check
3492 assert( BLOB_IN != NULL );
3493 // get the array
3494 Chuck_Array16 & cmp = BLOB_IN->cvals();
3495 // resize if necessary
3496 if( cmp.size()*2 > idct->m_size )
3497 idct->resize( cmp.size()*2 );
3498 // sanity check
3499 assert( idct->m_buffer != NULL );
3500 // copy into transform buffer
3501 t_CKCOMPLEX cval;
3502 for( t_CKINT i = 0; i < idct->m_size/2; i++ )
3504 // copy complex value in
3505 cmp.get( i, &cval );
3506 idct->m_buffer[i*2] = cval.re;
3507 idct->m_buffer[i*2+1] = cval.im;
3510 // take transform
3511 idct->transform();
3513 // otherwise zero out
3514 else
3516 // sanity check
3517 assert( idct->m_buffer != NULL );
3518 memset( idct->m_buffer, 0, sizeof(SAMPLE)*idct->m_size );
3519 memset( idct->m_inverse, 0, sizeof(SAMPLE)*idct->m_size );
3522 // get fvals of output BLOB
3523 Chuck_Array8 & fvals = BLOB->fvals();
3524 // ensure size == resulting size
3525 if( fvals.size() != idct->m_size )
3526 fvals.set_size( idct->m_size );
3527 // copy the result in
3528 for( t_CKINT i = 0; i < idct->m_size; i++ )
3529 fvals.set( i, idct->m_inverse[i] );
3531 return TRUE;
3535 //-----------------------------------------------------------------------------
3536 // name:
3537 // desc:
3538 //-----------------------------------------------------------------------------
3539 CK_DLL_MFUN( IDCT_transform )
3541 // get object
3542 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3543 // get complex array
3544 Chuck_Array8 * frame = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
3545 // sanity
3546 if( frame == NULL ) goto null_pointer;
3547 // resize if bigger
3548 if( frame->size() > idct->m_size )
3549 idct->resize( frame->size() );
3550 // transform it
3551 idct->transform( frame );
3553 return;
3555 null_pointer:
3556 // we have a problem
3557 fprintf( stderr,
3558 "[chuck](IDCT): NullPointerException (argument is NULL)\n");
3559 goto done;
3561 done:
3562 // do something!
3563 if( SHRED != NULL )
3565 SHRED->is_running = FALSE;
3566 SHRED->is_done = TRUE;
3571 //-----------------------------------------------------------------------------
3572 // name:
3573 // desc:
3574 //-----------------------------------------------------------------------------
3575 CK_DLL_CTRL( IDCT_ctrl_window )
3577 // get object
3578 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data );
3579 // get win (can be NULL)
3580 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
3581 // set it
3582 idct->window( arr, arr != NULL ? arr->size() : 0 );
3586 //-----------------------------------------------------------------------------
3587 // name:
3588 // desc:
3589 //-----------------------------------------------------------------------------
3590 CK_DLL_CGET( IDCT_cget_window )
3595 //-----------------------------------------------------------------------------
3596 // name: windowSize()
3597 // desc:
3598 //-----------------------------------------------------------------------------
3599 CK_DLL_CGET( IDCT_cget_windowSize )
3601 // get object
3602 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3603 // return
3604 RETURN->v_int = idct->m_window_size;
3608 //-----------------------------------------------------------------------------
3609 // name: size()
3610 // desc: ...
3611 //-----------------------------------------------------------------------------
3612 CK_DLL_CTRL( IDCT_ctrl_size )
3614 // get object
3615 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3616 // get arg
3617 t_CKINT size = GET_NEXT_INT(ARGS);
3618 // sanity
3619 if( size <= 0 ) goto invalid_size;
3620 // set size
3621 idct->resize( size );
3622 // set RETURN
3623 RETURN->v_int = idct->m_size;
3625 return;
3627 invalid_size:
3628 // we have a problem
3629 fprintf( stderr,
3630 "[chuck](IDCT): InvalidTransformSizeException (%d)\n", size );
3631 goto done;
3633 done:
3634 // set RETURN type
3635 RETURN->v_int = 0;
3636 // do something!
3637 if( SHRED != NULL )
3639 SHRED->is_running = FALSE;
3640 SHRED->is_done = TRUE;
3645 //-----------------------------------------------------------------------------
3646 // name:
3647 // desc:
3648 //-----------------------------------------------------------------------------
3649 CK_DLL_CGET( IDCT_cget_size )
3651 // get object
3652 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3653 // set RETURN
3654 RETURN->v_int = idct->m_size;
3658 //-----------------------------------------------------------------------------
3659 // name:
3660 // desc:
3661 //-----------------------------------------------------------------------------
3662 CK_DLL_MFUN( IDCT_inverse )
3664 // get object
3665 IDCT_object * idct = (IDCT_object *)OBJ_MEMBER_UINT(SELF, IDCT_offset_data);
3666 // get array
3667 Chuck_Array8 * arr = (Chuck_Array8 *)GET_NEXT_OBJECT(ARGS);
3668 // check for null
3669 if( !arr )
3671 // log
3672 EM_log( CK_LOG_WARNING, "(via IDCT): null array passed to samples(...)" );
3673 return;
3676 // copy it
3677 idct->copyTo( arr );