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
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: uana_xform.cpp
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Rebecca Fiebrink (fiebrink@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
33 #include "uana_xform.h"
34 #include "chuck_type.h"
36 #include "chuck_instr.h"
37 #include "chuck_lang.h"
38 #include "util_buffers.h"
39 #include "util_xforms.h"
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
);
56 static t_CKUINT FFT_offset_data
= 0;
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
);
73 static t_CKUINT IFFT_offset_data
= 0;
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
);
90 static t_CKUINT Flip_offset_data
= 0;
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;
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
);
124 static t_CKUINT DCT_offset_data
= 0;
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;
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
);
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()
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(),
173 FFT_tick
, FFT_tock
, FFT_pmsg
) )
177 FFT_offset_data
= type_engine_import_mvar( env
, "int", "@FFT_data", FALSE
);
178 if( FFT_offset_data
== CK_INVALID_OFFSET
) goto error
;
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
;
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
;
191 func
= make_new_mfun( "int", "windowSize", FFT_cget_windowSize
);
192 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
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
) )
219 IFFT_offset_data
= type_engine_import_mvar( env
, "int", "@IFFT_data", FALSE
);
220 if( IFFT_offset_data
== CK_INVALID_OFFSET
) goto error
;
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
;
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
;
233 func
= make_new_mfun( "int", "windowSize", IFFT_cget_windowSize
);
234 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
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" );
258 QUERY
->add_sfun( QUERY
, Windowing_rectangle
, "float[]", "rectangle" );
259 QUERY
->add_arg( QUERY
, "int", "size" );
262 QUERY
->add_sfun( QUERY
, Windowing_triangle
, "float[]", "triangle" );
263 QUERY
->add_arg( QUERY
, "int", "size" );
266 QUERY
->add_sfun( QUERY
, Windowing_hann
, "float[]", "hann" );
267 QUERY
->add_arg( QUERY
, "int", "size" );
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" );
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();
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
) )
299 Flip_offset_data
= type_engine_import_mvar( env
, "int", "@Flip_data", FALSE
);
300 if( Flip_offset_data
== CK_INVALID_OFFSET
) goto error
;
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
;
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
;
313 func
= make_new_mfun( "int", "windowSize", Flip_cget_windowSize
);
314 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
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
) )
341 UnFlip_offset_data
= type_engine_import_mvar( env
, "int", "@UnFlip_data", FALSE
);
342 if( UnFlip_offset_data
== CK_INVALID_OFFSET
) goto error
;
345 func
= make_new_mfun( "void", "transform", UnFlip_take
);
346 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
354 func
= make_new_mfun( "int", "windowSize", UnFlip_cget_windowSize
);
355 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
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(),
378 DCT_tick
, DCT_tock
, DCT_pmsg
) )
382 DCT_offset_data
= type_engine_import_mvar( env
, "int", "@DCT_data", FALSE
);
383 if( DCT_offset_data
== CK_INVALID_OFFSET
) goto error
;
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
;
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
;
396 func
= make_new_mfun( "int", "windowSize", DCT_cget_windowSize
);
397 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
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
) )
424 IDCT_offset_data
= type_engine_import_mvar( env
, "int", "@IDCT_data", FALSE
);
425 if( IDCT_offset_data
== CK_INVALID_OFFSET
) goto error
;
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
;
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
;
438 func
= make_new_mfun( "int", "windowSize", IDCT_cget_windowSize
);
439 if( !type_engine_import_mfun( env
, func
) ) goto error
;
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
;
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
);
460 // end the class import
461 type_engine_import_class_end( env
);
469 //-----------------------------------------------------------------------------
471 // desc: standalone object for FFT UAna
472 //-----------------------------------------------------------------------------
477 virtual ~FFT_object();
480 t_CKBOOL
resize( t_CKINT size
);
481 t_CKBOOL
window( Chuck_Array8
* window
, t_CKINT win_size
);
483 void transform( Chuck_Array8
* frame
);
484 void copyTo( Chuck_Array16
* cmp
);
492 t_CKINT m_window_size
;
493 // sample accumulation buffer
498 t_CKCOMPLEX
* m_spectrum
;
504 //-----------------------------------------------------------------------------
505 // name: FFT_object()
507 //-----------------------------------------------------------------------------
508 FFT_object::FFT_object()
511 m_size
= 512; // TODO: default
513 m_window_size
= m_size
;
517 this->window( NULL
, m_window_size
);
519 this->resize( m_size
);
525 //-----------------------------------------------------------------------------
526 // name: ~FFT_object()
528 //-----------------------------------------------------------------------------
529 FFT_object::~FFT_object()
532 SAFE_DELETE_ARRAY( m_window
);
533 SAFE_DELETE_ARRAY( m_buffer
);
534 SAFE_DELETE_ARRAY( m_spectrum
);
542 //-----------------------------------------------------------------------------
544 // desc: set FFT size
545 //-----------------------------------------------------------------------------
546 t_CKBOOL
FFT_object::resize( t_CKINT size
)
553 for( ; size
&= size
-1; x
= size
);
557 EM_log( CK_LOG_FINE
, "FFT resize %d -> %d", m_size
, size
);
560 SAFE_DELETE_ARRAY( m_buffer
);
561 SAFE_DELETE_ARRAY( m_spectrum
);
563 m_buffer
= new SAMPLE
[size
];
564 m_spectrum
= new t_CKCOMPLEX
[size
/2];
566 if( !m_buffer
|| !m_spectrum
)
569 fprintf( stderr
, "[chuck]: FFT failed to allocate %ld, %ld buffers...\n",
572 SAFE_DELETE_ARRAY( m_buffer
);
573 SAFE_DELETE_ARRAY( m_spectrum
);
579 memset( m_buffer
, 0, size
* sizeof(SAMPLE
) );
580 memset( m_spectrum
, 0, size
/2 * sizeof(t_CKCOMPLEX
) );
583 // if no window specified, then set accum size
586 m_window_size
= m_size
;
588 m_accum
.resize( m_window_size
);
597 //-----------------------------------------------------------------------------
600 //-----------------------------------------------------------------------------
601 t_CKBOOL
FFT_object::window( Chuck_Array8
* win
, t_CKINT win_size
)
604 assert( win_size
>= 0 );
606 // in any case, clean up
607 SAFE_DELETE_ARRAY( m_window
);
614 m_window
= new SAMPLE
[win_size
];
619 fprintf( stderr
, "[chuck]: FFT failed to allocate %ldxSAMPLE window...\n",
626 memset( m_window
, 0, win_size
* sizeof(SAMPLE
) );
629 m_window_size
= win_size
;
632 for( t_CKINT i
= 0; i
< win_size
; i
++ )
635 win
->get( i
, &sample
);
637 m_window
[i
] = (SAMPLE
)sample
;
643 m_window_size
= m_size
;
647 m_accum
.resize( m_window_size
);
655 //-----------------------------------------------------------------------------
658 //-----------------------------------------------------------------------------
659 void FFT_object::transform( )
661 // buffer could be null
662 if( m_buffer
== NULL
&& m_spectrum
== NULL
)
665 fprintf( stderr
, "[chuck]: FFT failure due to NULL buffer...\n" );
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
677 apply_window( m_buffer
, m_window
, m_window_size
);
679 memset( m_buffer
+ m_window_size
, 0, (m_size
- m_window_size
)*sizeof(SAMPLE
) );
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 //-----------------------------------------------------------------------------
698 //-----------------------------------------------------------------------------
699 void FFT_object::transform( Chuck_Array8
* frame
)
701 // convert to right type
702 t_CKINT amount
= ck_min( frame
->size(), m_size
);
705 for( t_CKINT i
= 0; i
< amount
; i
++ )
712 for( t_CKINT j
= amount
; j
< m_size
; j
++ )
722 //-----------------------------------------------------------------------------
725 //-----------------------------------------------------------------------------
726 void FFT_object::copyTo( Chuck_Array16
* cmp
)
728 // buffer could be null
729 if( m_buffer
== NULL
&& m_spectrum
== NULL
)
738 t_CKINT amount
= m_size
/2;
740 cmp
->set_size( amount
);
743 for( i
= 0; i
< amount
; i
++ )
744 cmp
->set( i
, m_spectrum
[i
] );
748 t_CKINT left = cmp->size();
749 t_CKINT amount, i, j, sum = 0, which = 0;
755 amount = ck_min( m_size, left );
759 for( i = 0; i < amount; i++ )
760 cmp->set( i+sum, m_spectrum[i] );
762 for( i = 0, j = m_size-1; i < amount; i++, j-- )
763 cmp->set( i+sum, m_spectrum[j] );
776 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
791 //-----------------------------------------------------------------------------
792 CK_DLL_DTOR( FFT_dtor
)
794 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
796 OBJ_MEMBER_UINT(SELF
, FFT_offset_data
) = 0;
800 //-----------------------------------------------------------------------------
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
);
816 //-----------------------------------------------------------------------------
819 //-----------------------------------------------------------------------------
820 CK_DLL_PMSG( FFT_pmsg
)
826 //-----------------------------------------------------------------------------
829 //-----------------------------------------------------------------------------
830 CK_DLL_TOCK( FFT_tock
)
833 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
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
]) );
861 //-----------------------------------------------------------------------------
864 //-----------------------------------------------------------------------------
865 CK_DLL_MFUN( FFT_transform
)
868 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
870 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
872 fft
->transform( arr
);
876 //-----------------------------------------------------------------------------
879 //-----------------------------------------------------------------------------
880 CK_DLL_CTRL( FFT_ctrl_window
)
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
);
887 fft
->window( arr
, arr
!= NULL
? arr
->size() : 0 );
889 RETURN
->v_object
= arr
;
893 //-----------------------------------------------------------------------------
896 //-----------------------------------------------------------------------------
897 CK_DLL_CGET( FFT_cget_window
)
899 // TODO: implement this!
900 RETURN
->v_object
= NULL
;
904 //-----------------------------------------------------------------------------
905 // name: windowSize()
907 //-----------------------------------------------------------------------------
908 CK_DLL_CGET( FFT_cget_windowSize
)
911 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
913 RETURN
->v_int
= fft
->m_window_size
;
917 //-----------------------------------------------------------------------------
920 //-----------------------------------------------------------------------------
921 CK_DLL_CTRL( FFT_ctrl_size
)
924 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
926 t_CKINT size
= GET_NEXT_INT(ARGS
);
928 if( size
<= 0 ) goto invalid_size
;
932 RETURN
->v_int
= fft
->m_size
;
939 "[chuck](IFFT): InvalidTransformSizeException (%d)\n", size
);
948 SHRED
->is_running
= FALSE
;
949 SHRED
->is_done
= TRUE
;
954 //-----------------------------------------------------------------------------
957 //-----------------------------------------------------------------------------
958 CK_DLL_CGET( FFT_cget_size
)
961 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
963 RETURN
->v_int
= fft
->m_size
;
967 //-----------------------------------------------------------------------------
970 //-----------------------------------------------------------------------------
971 CK_DLL_MFUN( FFT_spectrum
)
974 FFT_object
* fft
= (FFT_object
*)OBJ_MEMBER_UINT(SELF
, FFT_offset_data
);
976 Chuck_Array16
* arr
= (Chuck_Array16
*)GET_NEXT_OBJECT(ARGS
);
981 EM_log( CK_LOG_WARNING
, "(via FFT): null array passed to spectrum(...)" );
992 //-----------------------------------------------------------------------------
994 // desc: standalone object for IFFT UAna
995 //-----------------------------------------------------------------------------
1000 virtual ~IFFT_object();
1003 t_CKBOOL
resize( t_CKINT size
);
1004 t_CKBOOL
window( Chuck_Array8
* window
, t_CKINT win_size
);
1006 void transform( Chuck_Array16
* cmp
);
1007 void copyTo( Chuck_Array8
* samples
);
1015 t_CKINT m_window_size
;
1016 // sample deccumulation buffer
1017 DeccumBuffer m_deccum
;
1027 //-----------------------------------------------------------------------------
1028 // name: IFFT_object()
1029 // desc: constructor
1030 //-----------------------------------------------------------------------------
1031 IFFT_object::IFFT_object()
1034 m_size
= 512; // TODO: default
1036 m_window_size
= m_size
;
1039 // initialize window
1040 this->window( NULL
, m_window_size
);
1042 this->resize( m_size
);
1048 //-----------------------------------------------------------------------------
1049 // name: ~IFFT_object()
1051 //-----------------------------------------------------------------------------
1052 IFFT_object::~IFFT_object()
1055 SAFE_DELETE_ARRAY( m_window
);
1056 SAFE_DELETE_ARRAY( m_buffer
);
1057 SAFE_DELETE_ARRAY( m_inverse
);
1065 //-----------------------------------------------------------------------------
1067 // desc: set IFFT size
1068 //-----------------------------------------------------------------------------
1069 t_CKBOOL
IFFT_object::resize( t_CKINT size
)
1076 for( ; size
&= size
-1; x
= size
);
1080 EM_log( CK_LOG_FINE
, "IFFT resize %d -> %d", m_size
, size
);
1083 SAFE_DELETE_ARRAY( m_buffer
);
1084 SAFE_DELETE_ARRAY( m_inverse
);
1086 m_buffer
= new SAMPLE
[size
];
1087 m_inverse
= new SAMPLE
[size
];
1089 if( !m_buffer
|| !m_inverse
)
1092 fprintf( stderr
, "[chuck]: IFFT failed to allocate %ld, %ld buffers...\n",
1095 SAFE_DELETE_ARRAY( m_buffer
);
1096 SAFE_DELETE_ARRAY( m_inverse
);
1102 memset( m_buffer
, 0, size
* sizeof(SAMPLE
) );
1103 memset( m_inverse
, 0, size
* sizeof(SAMPLE
) );
1107 m_deccum
.resize( m_size
);
1108 // if no window specified, then set accum size
1110 m_window_size
= m_size
;
1118 //-----------------------------------------------------------------------------
1121 //-----------------------------------------------------------------------------
1122 t_CKBOOL
IFFT_object::window( Chuck_Array8
* win
, t_CKINT win_size
)
1125 assert( win_size
>= 0 );
1127 // in any case, clean up
1128 SAFE_DELETE_ARRAY( m_window
);
1135 m_window
= new SAMPLE
[win_size
];
1140 fprintf( stderr
, "[chuck]: IFFT failed to allocate %ldxSAMPLE window...\n",
1147 memset( m_window
, 0, win_size
* sizeof(SAMPLE
) );
1150 m_window_size
= win_size
;
1153 for( t_CKINT i
= 0; i
< win_size
; i
++ )
1156 win
->get( i
, &sample
);
1158 m_window
[i
] = (SAMPLE
)sample
;
1164 m_window_size
= m_size
;
1173 //-----------------------------------------------------------------------------
1174 // name: transform()
1176 //-----------------------------------------------------------------------------
1177 void IFFT_object::transform( )
1179 // buffer could be null
1180 if( m_buffer
== NULL
&& m_inverse
== NULL
)
1183 fprintf( stderr
, "[chuck]: IFFT failure due to NULL buffer...\n" );
1189 assert( m_window_size
<= m_size
);
1191 rfft( m_buffer
, m_size
/2, FFT_INVERSE
);
1193 memcpy( m_inverse
, m_buffer
, m_size
* sizeof(SAMPLE
) );
1194 // apply window, if there is one
1196 apply_window( m_inverse
, m_window
, m_window_size
);
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()
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 );
1216 for( t_CKINT i
= 0; i
< amount
; i
++ )
1220 m_buffer
[i
*2] = v
.re
;
1221 m_buffer
[i
*2+1] = v
.im
;
1224 for( t_CKINT j
= amount
; j
< m_size
/2; j
++ )
1225 m_buffer
[j
*2] = m_buffer
[j
*2+1] = 0;
1234 //-----------------------------------------------------------------------------
1237 //-----------------------------------------------------------------------------
1238 void IFFT_object::copyTo( Chuck_Array8
* samples
)
1240 // buffer could be null
1241 if( m_buffer
== NULL
&& m_inverse
== NULL
)
1245 // samples->zero( 0, samples->size() );
1251 t_CKINT amount
= m_size
; // ck_min( m_size, samples->size() );
1253 samples
->set_size( amount
);
1256 for( t_CKINT i
= 0; i
< amount
; i
++ )
1257 samples
->set( i
, m_inverse
[i
] );
1260 // if( amount < samples->size() )
1261 // samples->set_size( amount );
1267 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
1294 //-----------------------------------------------------------------------------
1295 CK_DLL_TICK( IFFT_tick
)
1297 // accumulate samples
1298 IFFT_object
* ifft
= (IFFT_object
*)OBJ_MEMBER_UINT(SELF
, IFFT_offset_data
);
1300 ifft
->m_deccum
.get( out
);
1306 //-----------------------------------------------------------------------------
1309 //-----------------------------------------------------------------------------
1310 CK_DLL_PMSG( IFFT_pmsg
)
1316 //-----------------------------------------------------------------------------
1319 //-----------------------------------------------------------------------------
1320 CK_DLL_TOCK( IFFT_tock
)
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 )
1328 Chuck_UAnaBlobProxy
* BLOB_IN
= UANA
->getIncomingBlob( 0 );
1330 assert( BLOB_IN
!= NULL
);
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 );
1337 assert( ifft
->m_buffer
!= NULL
);
1338 // copy into transform buffer
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
;
1351 // otherwise zero out
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
] );
1373 //-----------------------------------------------------------------------------
1376 //-----------------------------------------------------------------------------
1377 CK_DLL_MFUN( IFFT_transform
)
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
);
1384 if( cmp
== NULL
) goto null_pointer
;
1386 if( cmp
->size()*2 > ifft
->m_size
)
1387 ifft
->resize( cmp
->size()*2 );
1389 ifft
->transform( cmp
);
1394 // we have a problem
1396 "[chuck](IFFT): NullPointerException (argument is NULL)\n");
1403 SHRED
->is_running
= FALSE
;
1404 SHRED
->is_done
= TRUE
;
1409 //-----------------------------------------------------------------------------
1412 //-----------------------------------------------------------------------------
1413 CK_DLL_CTRL( IFFT_ctrl_window
)
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
);
1420 ifft
->window( arr
, arr
!= NULL
? arr
->size() : 0 );
1422 RETURN
->v_object
= arr
;
1426 //-----------------------------------------------------------------------------
1429 //-----------------------------------------------------------------------------
1430 CK_DLL_CGET( IFFT_cget_window
)
1432 // TODO: implement this
1433 RETURN
->v_object
= NULL
;
1437 //-----------------------------------------------------------------------------
1438 // name: windowSize()
1440 //-----------------------------------------------------------------------------
1441 CK_DLL_CGET( IFFT_cget_windowSize
)
1444 IFFT_object
* ifft
= (IFFT_object
*)OBJ_MEMBER_UINT(SELF
, IFFT_offset_data
);
1446 RETURN
->v_int
= ifft
->m_window_size
;
1450 //-----------------------------------------------------------------------------
1453 //-----------------------------------------------------------------------------
1454 CK_DLL_CTRL( IFFT_ctrl_size
)
1457 IFFT_object
* ifft
= (IFFT_object
*)OBJ_MEMBER_UINT(SELF
, IFFT_offset_data
);
1459 t_CKINT size
= GET_NEXT_INT(ARGS
);
1461 if( size
<= 0 ) goto invalid_size
;
1463 ifft
->resize( size
);
1465 RETURN
->v_int
= ifft
->m_size
;
1470 // we have a problem
1472 "[chuck](IFFT): InvalidTransformSizeException (%d)\n", size
);
1481 SHRED
->is_running
= FALSE
;
1482 SHRED
->is_done
= TRUE
;
1487 //-----------------------------------------------------------------------------
1490 //-----------------------------------------------------------------------------
1491 CK_DLL_CGET( IFFT_cget_size
)
1494 IFFT_object
* ifft
= (IFFT_object
*)OBJ_MEMBER_UINT(SELF
, IFFT_offset_data
);
1496 RETURN
->v_int
= ifft
->m_size
;
1500 //-----------------------------------------------------------------------------
1503 //-----------------------------------------------------------------------------
1504 CK_DLL_MFUN( IFFT_inverse
)
1507 IFFT_object
* ifft
= (IFFT_object
*)OBJ_MEMBER_UINT(SELF
, IFFT_offset_data
);
1509 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
1514 EM_log( CK_LOG_WARNING
, "(via IFFT): null array passed to samples(...)" );
1519 ifft
->copyTo( arr
);
1523 //-----------------------------------------------------------------------------
1524 // name: prepare_window()
1526 //-----------------------------------------------------------------------------
1527 static t_CKBOOL
prepare_window( void * ARGS
, Chuck_VM_Shred
* SHRED
, t_CKINT
& size
)
1530 size
= GET_NEXT_INT(ARGS
);
1535 EM_log( CK_LOG_WARNING
, "(via Windowing): negative window size..." );
1540 if( size
!= Windowing_array
->size() )
1541 Windowing_array
->set_size( size
);
1543 if( size
!= Windowing_array
->size() )
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
;
1557 // we have a problem
1559 "[chuck](Windowing): OutOfMemoryException (allocating FLOAT[%d])\n",
1567 SHRED
->is_running
= FALSE
;
1568 SHRED
->is_done
= TRUE
;
1575 //-----------------------------------------------------------------------------
1578 //-----------------------------------------------------------------------------
1579 CK_DLL_SFUN( Windowing_hamming
)
1581 // prepare the thing
1583 if( !prepare_window( ARGS
, SHRED
, size
) )
1587 hamming( float_array
, size
);
1589 for( t_CKINT i
= 0; i
< size
; i
++ )
1590 Windowing_array
->set( i
, (t_CKFLOAT
)float_array
[i
] );
1592 RETURN
->v_object
= Windowing_array
;
1596 //-----------------------------------------------------------------------------
1599 //-----------------------------------------------------------------------------
1600 CK_DLL_SFUN( Windowing_hann
)
1602 // prepare the thing
1604 if( !prepare_window( ARGS
, SHRED
, size
) )
1608 hanning( float_array
, size
);
1610 for( t_CKINT i
= 0; i
< size
; i
++ )
1611 Windowing_array
->set( i
, (t_CKFLOAT
)float_array
[i
] );
1613 RETURN
->v_object
= Windowing_array
;
1617 //-----------------------------------------------------------------------------
1618 // name: blackmanHarris()
1620 //-----------------------------------------------------------------------------
1621 CK_DLL_SFUN( Windowing_blackmanHarris
)
1623 // prepare the thing
1625 if( !prepare_window( ARGS
, SHRED
, size
) )
1629 blackman( float_array
, size
);
1631 for( t_CKINT i
= 0; i
< size
; i
++ )
1632 Windowing_array
->set( i
, (t_CKFLOAT
)float_array
[i
] );
1634 RETURN
->v_object
= Windowing_array
;
1638 //-----------------------------------------------------------------------------
1639 // name: rectangle()
1641 //-----------------------------------------------------------------------------
1642 CK_DLL_SFUN( Windowing_rectangle
)
1644 // prepare the thing
1646 if( !prepare_window( ARGS
, SHRED
, size
) )
1650 for( t_CKINT i
= 0; i
< size
; i
++ )
1651 Windowing_array
->set( i
, 1 );
1653 RETURN
->v_object
= Windowing_array
;
1657 //-----------------------------------------------------------------------------
1658 // name: Windowing_triangle()
1660 //-----------------------------------------------------------------------------
1661 CK_DLL_SFUN( Windowing_triangle
)
1663 // prepare the thing
1665 if( !prepare_window( ARGS
, SHRED
, size
) )
1669 bartlett( float_array
, size
);
1671 for( t_CKINT i
= 0; i
< size
; i
++ )
1672 Windowing_array
->set( i
, (t_CKFLOAT
)float_array
[i
] );
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
)
1689 if( !matrix
) return;
1692 for( i
= 0; i
< N
; i
++ )
1693 SAFE_DELETE_ARRAY( matrix
[i
] );
1696 SAFE_DELETE_ARRAY( matrix
);
1702 //-----------------------------------------------------------------------------
1703 // name: Flip_object
1704 // desc: standalone object for Flip UAna
1705 //-----------------------------------------------------------------------------
1710 virtual ~Flip_object();
1713 t_CKBOOL
resize( t_CKINT size
);
1714 t_CKBOOL
window( Chuck_Array8
* window
, t_CKINT win_size
);
1716 void transform( Chuck_Array8
* frame
);
1717 void copyTo( Chuck_Array8
* val
);
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()
1743 m_size
= 512; // TODO: default
1745 m_window_size
= m_size
;
1746 // initialize window
1747 this->window( NULL
, m_window_size
);
1749 this->resize( m_size
);
1755 //-----------------------------------------------------------------------------
1756 // name: ~Flip_object()
1758 //-----------------------------------------------------------------------------
1759 Flip_object::~Flip_object()
1762 SAFE_DELETE_ARRAY( m_window
);
1763 SAFE_DELETE_ARRAY( m_buffer
);
1771 //-----------------------------------------------------------------------------
1773 // desc: set Flip size
1774 //-----------------------------------------------------------------------------
1775 t_CKBOOL
Flip_object::resize( t_CKINT size
)
1781 EM_log( CK_LOG_FINE
, "Flip resize %d -> %d", m_size
, size
);
1784 SAFE_DELETE_ARRAY( m_buffer
);
1786 m_buffer
= new SAMPLE
[size
];
1791 fprintf( stderr
, "[chuck]: Flip failed to allocate %ld buffer...\n",
1794 SAFE_DELETE_ARRAY( m_buffer
);
1800 memset( m_buffer
, 0, size
* sizeof(SAMPLE
) );
1803 // if no window specified, then set accum size
1806 m_window_size
= m_size
;
1808 m_accum
.resize( m_window_size
);
1817 //-----------------------------------------------------------------------------
1820 //-----------------------------------------------------------------------------
1821 t_CKBOOL
Flip_object::window( Chuck_Array8
* win
, t_CKINT win_size
)
1824 assert( win_size
>= 0 );
1826 // in any case, clean up
1827 SAFE_DELETE_ARRAY( m_window
);
1834 m_window
= new SAMPLE
[win_size
];
1839 fprintf( stderr
, "[chuck]: Flip failed to allocate %ldxSAMPLE window...\n",
1846 memset( m_window
, 0, win_size
* sizeof(SAMPLE
) );
1849 m_window_size
= win_size
;
1852 for( t_CKINT i
= 0; i
< win_size
; i
++ )
1855 win
->get( i
, &sample
);
1857 m_window
[i
] = (SAMPLE
)sample
;
1863 m_window_size
= m_size
;
1867 m_accum
.resize( m_window_size
);
1875 //-----------------------------------------------------------------------------
1876 // name: transform()
1878 //-----------------------------------------------------------------------------
1879 void Flip_object::transform( )
1881 // buffer could be null
1882 if( m_buffer
== NULL
)
1885 fprintf( stderr
, "[chuck]: Flip failure due to NULL buffer...\n" );
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
1897 apply_window( m_buffer
, m_window
, m_window_size
);
1899 memset( m_buffer
+ m_window_size
, 0, (m_size
- m_window_size
)*sizeof(SAMPLE
) );
1905 //-----------------------------------------------------------------------------
1906 // name: transform()
1908 //-----------------------------------------------------------------------------
1909 void Flip_object::transform( Chuck_Array8
* frame
)
1911 // convert to right type
1912 t_CKINT amount
= ck_min( frame
->size(), m_size
);
1915 for( t_CKINT i
= 0; i
< amount
; i
++ )
1918 frame
->get( i
, &v
);
1922 for( t_CKINT j
= amount
; j
< m_size
; j
++ )
1932 //-----------------------------------------------------------------------------
1935 //-----------------------------------------------------------------------------
1936 void Flip_object::copyTo( Chuck_Array8
* val
)
1938 // buffer could be null
1939 if( m_buffer
== NULL
)
1948 t_CKINT amount
= m_size
;
1950 val
->set_size( amount
);
1953 for( i
= 0; i
< amount
; i
++ )
1954 val
->set( i
, m_buffer
[i
] );
1960 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
);
2000 //-----------------------------------------------------------------------------
2003 //-----------------------------------------------------------------------------
2004 CK_DLL_PMSG( Flip_pmsg
)
2010 //-----------------------------------------------------------------------------
2013 //-----------------------------------------------------------------------------
2014 CK_DLL_TOCK( Flip_tock
)
2017 Flip_object
* flip
= (Flip_object
*)OBJ_MEMBER_UINT(SELF
, Flip_offset_data
);
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
] );
2036 //-----------------------------------------------------------------------------
2039 //-----------------------------------------------------------------------------
2040 CK_DLL_MFUN( Flip_take
)
2043 Flip_object
* flip
= (Flip_object
*)OBJ_MEMBER_UINT(SELF
, Flip_offset_data
);
2045 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
2047 flip
->transform( arr
);
2051 //-----------------------------------------------------------------------------
2054 //-----------------------------------------------------------------------------
2055 CK_DLL_CTRL( Flip_ctrl_window
)
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
);
2062 flip
->window( arr
, arr
!= NULL
? arr
->size() : 0 );
2063 // return it through
2064 RETURN
->v_object
= arr
;
2068 //-----------------------------------------------------------------------------
2071 //-----------------------------------------------------------------------------
2072 CK_DLL_CGET( Flip_cget_window
)
2074 // TODO: implement this!
2075 RETURN
->v_object
= NULL
;
2079 //-----------------------------------------------------------------------------
2080 // name: windowSize()
2082 //-----------------------------------------------------------------------------
2083 CK_DLL_CGET( Flip_cget_windowSize
)
2086 Flip_object
* flip
= (Flip_object
*)OBJ_MEMBER_UINT(SELF
, Flip_offset_data
);
2088 RETURN
->v_int
= flip
->m_window_size
;
2092 //-----------------------------------------------------------------------------
2095 //-----------------------------------------------------------------------------
2096 CK_DLL_CTRL( Flip_ctrl_size
)
2099 Flip_object
* flip
= (Flip_object
*)OBJ_MEMBER_UINT(SELF
, Flip_offset_data
);
2101 t_CKINT size
= GET_NEXT_INT(ARGS
);
2103 if( size
<= 0 ) goto invalid_size
;
2105 flip
->resize( size
);
2107 RETURN
->v_int
= flip
->m_size
;
2112 // we have a problem
2114 "[chuck](IFFT): InvalidTransformSizeException (%d)\n", size
);
2123 SHRED
->is_running
= FALSE
;
2124 SHRED
->is_done
= TRUE
;
2129 //-----------------------------------------------------------------------------
2132 //-----------------------------------------------------------------------------
2133 CK_DLL_CGET( Flip_cget_size
)
2136 Flip_object
* flip
= (Flip_object
*)OBJ_MEMBER_UINT(SELF
, Flip_offset_data
);
2138 RETURN
->v_int
= flip
->m_size
;
2142 //-----------------------------------------------------------------------------
2145 //-----------------------------------------------------------------------------
2146 CK_DLL_MFUN( Flip_output
)
2149 Flip_object
* flip
= (Flip_object
*)OBJ_MEMBER_UINT(SELF
, Flip_offset_data
);
2151 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
2156 EM_log( CK_LOG_WARNING
, "(via Flip): null array passed to spectrum(...)" );
2161 flip
->copyTo( arr
);
2167 //-----------------------------------------------------------------------------
2168 // name: UnFlip_object
2169 // desc: standalone object for UnFlip UAna
2170 //-----------------------------------------------------------------------------
2171 struct UnFlip_object
2175 virtual ~UnFlip_object();
2178 t_CKBOOL
resize( t_CKINT size
);
2179 t_CKBOOL
window( Chuck_Array8
* window
, t_CKINT win_size
);
2181 void transform( Chuck_Array8
* val
);
2182 void copyTo( Chuck_Array8
* samples
);
2190 t_CKINT m_window_size
;
2191 // sample deccumulation buffer
2192 DeccumBuffer m_deccum
;
2200 //-----------------------------------------------------------------------------
2201 // name: UnFlip_object()
2202 // desc: constructor
2203 //-----------------------------------------------------------------------------
2204 UnFlip_object::UnFlip_object()
2207 m_size
= 512; // TODO: default
2209 m_window_size
= m_size
;
2211 // initialize window
2212 this->window( NULL
, m_window_size
);
2214 this->resize( m_size
);
2220 //-----------------------------------------------------------------------------
2221 // name: ~UnFlip_object()
2223 //-----------------------------------------------------------------------------
2224 UnFlip_object::~UnFlip_object()
2227 SAFE_DELETE_ARRAY( m_window
);
2228 SAFE_DELETE_ARRAY( m_buffer
);
2236 //-----------------------------------------------------------------------------
2238 // desc: set UnFlip size
2239 //-----------------------------------------------------------------------------
2240 t_CKBOOL
UnFlip_object::resize( t_CKINT size
)
2246 EM_log( CK_LOG_FINE
, "UnFlip resize %d -> %d", m_size
, size
);
2249 SAFE_DELETE_ARRAY( m_buffer
);
2251 m_buffer
= new SAMPLE
[size
];
2256 fprintf( stderr
, "[chuck]: UnFlip failed to allocate %ld buffer...\n",
2259 SAFE_DELETE_ARRAY( m_buffer
);
2265 memset( m_buffer
, 0, size
* sizeof(SAMPLE
) );
2269 m_deccum
.resize( m_size
);
2270 // if no window specified, then set accum size
2272 m_window_size
= m_size
;
2280 //-----------------------------------------------------------------------------
2283 //-----------------------------------------------------------------------------
2284 t_CKBOOL
UnFlip_object::window( Chuck_Array8
* win
, t_CKINT win_size
)
2287 assert( win_size
>= 0 );
2289 // in any case, clean up
2290 SAFE_DELETE_ARRAY( m_window
);
2297 m_window
= new SAMPLE
[win_size
];
2302 fprintf( stderr
, "[chuck]: UnFlip failed to allocate %ldxSAMPLE window...\n",
2309 memset( m_window
, 0, win_size
* sizeof(SAMPLE
) );
2312 m_window_size
= win_size
;
2315 for( t_CKINT i
= 0; i
< win_size
; i
++ )
2318 win
->get( i
, &sample
);
2320 m_window
[i
] = (SAMPLE
)sample
;
2326 m_window_size
= m_size
;
2335 //-----------------------------------------------------------------------------
2336 // name: transform()
2338 //-----------------------------------------------------------------------------
2339 void UnFlip_object::transform( )
2341 // buffer could be null
2342 if( m_buffer
== NULL
)
2345 fprintf( stderr
, "[chuck]: UnFlip failure due to NULL buffer...\n" );
2351 assert( m_window_size
<= m_size
);
2352 // apply window, if there is one
2354 apply_window( m_buffer
, m_window
, m_window_size
);
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()
2367 //-----------------------------------------------------------------------------
2368 void UnFlip_object::transform( Chuck_Array8
* val
)
2370 // convert to right type
2371 t_CKINT amount
= ck_min( val
->size(), m_size
);
2374 for( t_CKINT i
= 0; i
< amount
; i
++ )
2381 for( t_CKINT j
= amount
; j
< m_size
; j
++ )
2391 //-----------------------------------------------------------------------------
2394 //-----------------------------------------------------------------------------
2395 void UnFlip_object::copyTo( Chuck_Array8
* samples
)
2397 // buffer could be null
2398 if( m_buffer
== NULL
)
2402 // samples->zero( 0, samples->size() );
2408 t_CKINT amount
= m_size
; // ck_min( m_size, samples->size() );
2410 samples
->set_size( amount
);
2413 for( t_CKINT i
= 0; i
< amount
; i
++ )
2414 samples
->set( i
, m_buffer
[i
] );
2420 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
2447 //-----------------------------------------------------------------------------
2448 CK_DLL_TICK( UnFlip_tick
)
2450 // accumulate samples
2451 UnFlip_object
* unflip
= (UnFlip_object
*)OBJ_MEMBER_UINT(SELF
, UnFlip_offset_data
);
2453 unflip
->m_deccum
.get( out
);
2459 //-----------------------------------------------------------------------------
2462 //-----------------------------------------------------------------------------
2463 CK_DLL_PMSG( UnFlip_pmsg
)
2469 //-----------------------------------------------------------------------------
2472 //-----------------------------------------------------------------------------
2473 CK_DLL_TOCK( UnFlip_tock
)
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 )
2481 Chuck_UAnaBlobProxy
* BLOB_IN
= UANA
->getIncomingBlob( 0 );
2483 assert( BLOB_IN
!= NULL
);
2485 Chuck_Array8
& val
= BLOB_IN
->fvals();
2486 // resize if necessary
2487 if( val
.size() > unflip
->m_size
)
2488 unflip
->resize( val
.size() );
2490 assert( unflip
->m_buffer
!= NULL
);
2491 // copy into transform buffer
2493 for( t_CKINT i
= 0; i
< unflip
->m_size
; i
++ )
2497 unflip
->m_buffer
[i
] = v
;
2501 unflip
->transform();
2503 // otherwise zero out
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
] );
2524 //-----------------------------------------------------------------------------
2527 //-----------------------------------------------------------------------------
2528 CK_DLL_MFUN( UnFlip_take
)
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
);
2535 if( val
== NULL
) goto null_pointer
;
2537 if( val
->size() > unflip
->m_size
)
2538 unflip
->resize( val
->size() );
2540 unflip
->transform( val
);
2545 // we have a problem
2547 "[chuck](UnFlip): NullPointerException (argument is NULL)\n");
2554 SHRED
->is_running
= FALSE
;
2555 SHRED
->is_done
= TRUE
;
2560 //-----------------------------------------------------------------------------
2563 //-----------------------------------------------------------------------------
2564 CK_DLL_CTRL( UnFlip_ctrl_window
)
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
);
2571 unflip
->window( arr
, arr
!= NULL
? arr
->size() : 0 );
2573 RETURN
->v_object
= arr
;
2577 //-----------------------------------------------------------------------------
2580 //-----------------------------------------------------------------------------
2581 CK_DLL_CGET( UnFlip_cget_window
)
2583 // TODO: implement this
2584 RETURN
->v_object
= NULL
;
2588 //-----------------------------------------------------------------------------
2589 // name: windowSize()
2591 //-----------------------------------------------------------------------------
2592 CK_DLL_CGET( UnFlip_cget_windowSize
)
2595 UnFlip_object
* unflip
= (UnFlip_object
*)OBJ_MEMBER_UINT(SELF
, UnFlip_offset_data
);
2597 RETURN
->v_int
= unflip
->m_window_size
;
2601 //-----------------------------------------------------------------------------
2604 //-----------------------------------------------------------------------------
2605 CK_DLL_CTRL( UnFlip_ctrl_size
)
2608 UnFlip_object
* unflip
= (UnFlip_object
*)OBJ_MEMBER_UINT(SELF
, UnFlip_offset_data
);
2610 t_CKINT size
= GET_NEXT_INT(ARGS
);
2612 if( size
<= 0 ) goto invalid_size
;
2614 unflip
->resize( size
);
2616 RETURN
->v_int
= unflip
->m_size
;
2621 // we have a problem
2623 "[chuck](UnFlip): InvalidTransformSizeException (%d)\n", size
);
2632 SHRED
->is_running
= FALSE
;
2633 SHRED
->is_done
= TRUE
;
2638 //-----------------------------------------------------------------------------
2641 //-----------------------------------------------------------------------------
2642 CK_DLL_CGET( UnFlip_cget_size
)
2645 UnFlip_object
* unflip
= (UnFlip_object
*)OBJ_MEMBER_UINT(SELF
, UnFlip_offset_data
);
2647 RETURN
->v_int
= unflip
->m_size
;
2651 //-----------------------------------------------------------------------------
2654 //-----------------------------------------------------------------------------
2655 CK_DLL_MFUN( UnFlip_output
)
2658 UnFlip_object
* unflip
= (UnFlip_object
*)OBJ_MEMBER_UINT(SELF
, UnFlip_offset_data
);
2660 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
2665 EM_log( CK_LOG_WARNING
, "(via UnFlip): null array passed to samples(...)" );
2670 unflip
->copyTo( arr
);
2676 //-----------------------------------------------------------------------------
2678 // desc: standalone object for DCT UAna
2679 //-----------------------------------------------------------------------------
2684 virtual ~DCT_object();
2687 t_CKBOOL
resize( t_CKINT size
);
2688 t_CKBOOL
window( Chuck_Array8
* window
, t_CKINT win_size
);
2690 void transform( const t_CKFLOAT
* in
, t_CKCOMPLEX
* out
);
2691 void copyTo( Chuck_Array8
* frame
);
2699 t_CKINT m_window_size
;
2700 // sample accumulation buffer
2701 AccumBuffer m_accum
;
2707 SAMPLE
* m_spectrum
;
2713 //-----------------------------------------------------------------------------
2714 // name: DCT_object()
2715 // desc: constructor
2716 //-----------------------------------------------------------------------------
2717 DCT_object::DCT_object()
2720 m_size
= 512; // TODO: default
2722 m_window_size
= m_size
;
2726 // initialize window
2727 this->window( NULL
, m_window_size
);
2729 this->resize( m_size
);
2735 //-----------------------------------------------------------------------------
2736 // name: ~DCT_object()
2738 //-----------------------------------------------------------------------------
2739 DCT_object::~DCT_object()
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
);
2753 //-----------------------------------------------------------------------------
2755 // desc: set DCT size
2756 //-----------------------------------------------------------------------------
2757 t_CKBOOL
DCT_object::resize( t_CKINT size
)
2765 SAFE_DELETE_ARRAY( m_buffer
);
2766 delete_matrix( m_matrix
, m_size
);
2767 SAFE_DELETE_ARRAY( m_spectrum
);
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
];
2775 if( !m_buffer
|| !m_spectrum
|| !m_matrix
)
2778 fprintf( stderr
, "[chuck]: DCT failed to allocate %ld, %ld buffers...\n",
2781 SAFE_DELETE_ARRAY( m_buffer
);
2782 delete_matrix( m_matrix
, size
);
2783 SAFE_DELETE_ARRAY( m_spectrum
);
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
);
2795 // if no window specified, then set accum size
2798 m_window_size
= m_size
;
2800 m_accum
.resize( m_window_size
);
2809 //-----------------------------------------------------------------------------
2812 //-----------------------------------------------------------------------------
2813 t_CKBOOL
DCT_object::window( Chuck_Array8
* win
, t_CKINT win_size
)
2816 assert( win_size
>= 0 );
2818 // in any case, clean up
2819 SAFE_DELETE_ARRAY( m_window
);
2826 m_window
= new SAMPLE
[win_size
];
2831 fprintf( stderr
, "[chuck]: DCT failed to allocate %ldxSAMPLE window...\n",
2838 memset( m_window
, 0, win_size
* sizeof(SAMPLE
) );
2841 m_window_size
= win_size
;
2844 for( t_CKINT i
= 0; i
< win_size
; i
++ )
2847 win
->get( i
, &sample
);
2849 m_window
[i
] = (SAMPLE
)sample
;
2855 m_window_size
= m_size
;
2859 m_accum
.resize( m_window_size
);
2867 //-----------------------------------------------------------------------------
2868 // name: transform()
2870 //-----------------------------------------------------------------------------
2871 void DCT_object::transform( )
2873 // buffer could be null
2874 if( m_buffer
== NULL
&& m_spectrum
== NULL
)
2877 fprintf( stderr
, "[chuck]: DCT failure due to NULL buffer...\n" );
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
2889 apply_window( m_buffer
, m_window
, m_window_size
);
2891 memset( m_buffer
+ m_window_size
, 0, (m_size
- m_window_size
)*sizeof(SAMPLE
) );
2893 the_dct_now( m_buffer
, m_matrix
, m_size
, m_spectrum
, m_size
);
2899 //-----------------------------------------------------------------------------
2902 //-----------------------------------------------------------------------------
2903 void DCT_object::copyTo( Chuck_Array8
* frame
)
2905 // buffer could be null
2906 if( m_buffer
== NULL
&& m_spectrum
== NULL
)
2915 t_CKINT amount
= m_size
;
2917 frame
->set_size( amount
);
2920 for( i
= 0; i
< amount
; i
++ )
2921 frame
->set( i
, m_spectrum
[i
] );
2925 t_CKINT left = frame->size();
2926 t_CKINT amount, i, sum = 0, which = 0;
2932 amount = ck_min( m_size, left );
2936 for( i = 0; i < amount; i++ )
2937 frame->set( i+sum, m_spectrum[i] );
2939 for( i = 0; i < amount; i++ )
2940 frame->set( i+sum, 0.0 );
2945 if( !which ) which = 1;
2953 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
2968 //-----------------------------------------------------------------------------
2969 CK_DLL_DTOR( DCT_dtor
)
2971 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
2973 OBJ_MEMBER_UINT(SELF
, DCT_offset_data
) = 0;
2977 //-----------------------------------------------------------------------------
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
);
2993 //-----------------------------------------------------------------------------
2996 //-----------------------------------------------------------------------------
2997 CK_DLL_PMSG( DCT_pmsg
)
3003 //-----------------------------------------------------------------------------
3006 //-----------------------------------------------------------------------------
3007 CK_DLL_TOCK( DCT_tock
)
3010 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
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
] );
3029 //-----------------------------------------------------------------------------
3032 //-----------------------------------------------------------------------------
3033 CK_DLL_MFUN( DCT_transform
)
3036 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
3038 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
3042 //-----------------------------------------------------------------------------
3045 //-----------------------------------------------------------------------------
3046 CK_DLL_CTRL( DCT_ctrl_window
)
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
);
3053 dct
->window( arr
, arr
!= NULL
? arr
->size() : 0 );
3057 //-----------------------------------------------------------------------------
3060 //-----------------------------------------------------------------------------
3061 CK_DLL_CGET( DCT_cget_window
)
3066 //-----------------------------------------------------------------------------
3067 // name: windowSize()
3069 //-----------------------------------------------------------------------------
3070 CK_DLL_CGET( DCT_cget_windowSize
)
3073 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
3075 RETURN
->v_int
= dct
->m_window_size
;
3079 //-----------------------------------------------------------------------------
3082 //-----------------------------------------------------------------------------
3083 CK_DLL_CTRL( DCT_ctrl_size
)
3086 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
3088 t_CKINT size
= GET_NEXT_INT(ARGS
);
3090 if( size
<= 0 ) goto invalid_size
;
3092 dct
->resize( size
);
3094 RETURN
->v_int
= dct
->m_size
;
3099 // we have a problem
3101 "[chuck](IDCT): InvalidTransformSizeException (%d)\n", size
);
3110 SHRED
->is_running
= FALSE
;
3111 SHRED
->is_done
= TRUE
;
3116 //-----------------------------------------------------------------------------
3119 //-----------------------------------------------------------------------------
3120 CK_DLL_CGET( DCT_cget_size
)
3123 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
3125 RETURN
->v_int
= dct
->m_size
;
3129 //-----------------------------------------------------------------------------
3132 //-----------------------------------------------------------------------------
3133 CK_DLL_MFUN( DCT_spectrum
)
3136 DCT_object
* dct
= (DCT_object
*)OBJ_MEMBER_UINT(SELF
, DCT_offset_data
);
3138 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
3143 EM_log( CK_LOG_WARNING
, "(via DCT): null array passed to spectrum(...)" );
3154 //-----------------------------------------------------------------------------
3155 // name: IDCT_object
3156 // desc: standalone object for IDCT UAna
3157 //-----------------------------------------------------------------------------
3162 virtual ~IDCT_object();
3165 t_CKBOOL
resize( t_CKINT size
);
3166 t_CKBOOL
window( Chuck_Array8
* window
, t_CKINT win_size
);
3168 void transform( Chuck_Array8
* frame
);
3169 void copyTo( Chuck_Array8
* samples
);
3177 t_CKINT m_window_size
;
3178 // sample deccumulation buffer
3179 DeccumBuffer m_deccum
;
3191 //-----------------------------------------------------------------------------
3192 // name: IDCT_object()
3193 // desc: constructor
3194 //-----------------------------------------------------------------------------
3195 IDCT_object::IDCT_object()
3198 m_size
= 512; // TODO: default
3200 m_window_size
= m_size
;
3204 // initialize window
3205 this->window( NULL
, m_window_size
);
3207 this->resize( m_size
);
3213 //-----------------------------------------------------------------------------
3214 // name: ~IDCT_object()
3216 //-----------------------------------------------------------------------------
3217 IDCT_object::~IDCT_object()
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
);
3231 //-----------------------------------------------------------------------------
3233 // desc: set IDCT size
3234 //-----------------------------------------------------------------------------
3235 t_CKBOOL
IDCT_object::resize( t_CKINT size
)
3243 SAFE_DELETE_ARRAY( m_buffer
);
3244 delete_matrix( m_matrix
, m_size
);
3245 SAFE_DELETE_ARRAY( m_inverse
);
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
)
3255 fprintf( stderr
, "[chuck]: IDCT failed to allocate %ld, %ld, %ldx%ld buffers...\n",
3256 size
, size
, size
, size
);
3258 SAFE_DELETE_ARRAY( m_buffer
);
3259 delete_matrix( m_matrix
, size
);
3260 SAFE_DELETE_ARRAY( m_inverse
);
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
);
3273 m_deccum
.resize( m_size
);
3274 // if no window specified, then set accum size
3276 m_window_size
= m_size
;
3284 //-----------------------------------------------------------------------------
3287 //-----------------------------------------------------------------------------
3288 t_CKBOOL
IDCT_object::window( Chuck_Array8
* win
, t_CKINT win_size
)
3291 assert( win_size
>= 0 );
3293 // in any case, clean up
3294 SAFE_DELETE_ARRAY( m_window
);
3301 m_window
= new SAMPLE
[win_size
];
3306 fprintf( stderr
, "[chuck]: IDCT failed to allocate %ldxSAMPLE window...\n",
3313 memset( m_window
, 0, win_size
* sizeof(SAMPLE
) );
3316 m_window_size
= win_size
;
3319 for( t_CKINT i
= 0; i
< win_size
; i
++ )
3322 win
->get( i
, &sample
);
3324 m_window
[i
] = (SAMPLE
)sample
;
3330 m_window_size
= m_size
;
3339 //-----------------------------------------------------------------------------
3340 // name: transform()
3342 //-----------------------------------------------------------------------------
3343 void IDCT_object::transform( )
3345 // buffer could be null
3346 if( m_buffer
== NULL
&& m_inverse
== NULL
)
3349 fprintf( stderr
, "[chuck]: IDCT failure due to NULL buffer...\n" );
3355 assert( m_window_size
<= m_size
);
3357 the_inverse_dct_now( m_buffer
, m_matrix
, m_size
, m_inverse
, m_size
);
3358 // apply window, if there is one
3360 apply_window( m_inverse
, m_window
, m_window_size
);
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()
3373 //-----------------------------------------------------------------------------
3374 void IDCT_object::transform( Chuck_Array8
* frame
)
3376 // convert to right type
3377 t_CKINT amount
= ck_min( frame
->size(), m_size
);
3380 for( t_CKINT i
= 0; i
< amount
; i
++ )
3383 frame
->get( i
, &v
);
3387 for( t_CKINT j
= amount
; j
< m_size
; j
++ )
3397 //-----------------------------------------------------------------------------
3400 //-----------------------------------------------------------------------------
3401 void IDCT_object::copyTo( Chuck_Array8
* samples
)
3403 // buffer could be null
3404 if( m_buffer
== NULL
&& m_inverse
== NULL
)
3413 t_CKINT amount
= m_size
; // ck_min( m_size, samples->size() );
3415 samples
->set_size( amount
);
3418 for( t_CKINT i
= 0; i
< amount
; i
++ )
3419 samples
->set( i
, m_inverse
[i
] );
3422 // if( amount < samples->size() )
3423 // samples->set_size( amount );
3429 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
3456 //-----------------------------------------------------------------------------
3457 CK_DLL_TICK( IDCT_tick
)
3459 // accumulate samples
3460 IDCT_object
* idct
= (IDCT_object
*)OBJ_MEMBER_UINT(SELF
, IDCT_offset_data
);
3462 idct
->m_deccum
.get( out
);
3468 //-----------------------------------------------------------------------------
3471 //-----------------------------------------------------------------------------
3472 CK_DLL_PMSG( IDCT_pmsg
)
3478 //-----------------------------------------------------------------------------
3481 //-----------------------------------------------------------------------------
3482 CK_DLL_TOCK( IDCT_tock
)
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 )
3490 Chuck_UAnaBlobProxy
* BLOB_IN
= UANA
->getIncomingBlob( 0 );
3492 assert( BLOB_IN
!= NULL
);
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 );
3499 assert( idct
->m_buffer
!= NULL
);
3500 // copy into transform buffer
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
;
3513 // otherwise zero out
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
] );
3535 //-----------------------------------------------------------------------------
3538 //-----------------------------------------------------------------------------
3539 CK_DLL_MFUN( IDCT_transform
)
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
);
3546 if( frame
== NULL
) goto null_pointer
;
3548 if( frame
->size() > idct
->m_size
)
3549 idct
->resize( frame
->size() );
3551 idct
->transform( frame
);
3556 // we have a problem
3558 "[chuck](IDCT): NullPointerException (argument is NULL)\n");
3565 SHRED
->is_running
= FALSE
;
3566 SHRED
->is_done
= TRUE
;
3571 //-----------------------------------------------------------------------------
3574 //-----------------------------------------------------------------------------
3575 CK_DLL_CTRL( IDCT_ctrl_window
)
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
);
3582 idct
->window( arr
, arr
!= NULL
? arr
->size() : 0 );
3586 //-----------------------------------------------------------------------------
3589 //-----------------------------------------------------------------------------
3590 CK_DLL_CGET( IDCT_cget_window
)
3595 //-----------------------------------------------------------------------------
3596 // name: windowSize()
3598 //-----------------------------------------------------------------------------
3599 CK_DLL_CGET( IDCT_cget_windowSize
)
3602 IDCT_object
* idct
= (IDCT_object
*)OBJ_MEMBER_UINT(SELF
, IDCT_offset_data
);
3604 RETURN
->v_int
= idct
->m_window_size
;
3608 //-----------------------------------------------------------------------------
3611 //-----------------------------------------------------------------------------
3612 CK_DLL_CTRL( IDCT_ctrl_size
)
3615 IDCT_object
* idct
= (IDCT_object
*)OBJ_MEMBER_UINT(SELF
, IDCT_offset_data
);
3617 t_CKINT size
= GET_NEXT_INT(ARGS
);
3619 if( size
<= 0 ) goto invalid_size
;
3621 idct
->resize( size
);
3623 RETURN
->v_int
= idct
->m_size
;
3628 // we have a problem
3630 "[chuck](IDCT): InvalidTransformSizeException (%d)\n", size
);
3639 SHRED
->is_running
= FALSE
;
3640 SHRED
->is_done
= TRUE
;
3645 //-----------------------------------------------------------------------------
3648 //-----------------------------------------------------------------------------
3649 CK_DLL_CGET( IDCT_cget_size
)
3652 IDCT_object
* idct
= (IDCT_object
*)OBJ_MEMBER_UINT(SELF
, IDCT_offset_data
);
3654 RETURN
->v_int
= idct
->m_size
;
3658 //-----------------------------------------------------------------------------
3661 //-----------------------------------------------------------------------------
3662 CK_DLL_MFUN( IDCT_inverse
)
3665 IDCT_object
* idct
= (IDCT_object
*)OBJ_MEMBER_UINT(SELF
, IDCT_offset_data
);
3667 Chuck_Array8
* arr
= (Chuck_Array8
*)GET_NEXT_OBJECT(ARGS
);
3672 EM_log( CK_LOG_WARNING
, "(via IDCT): null array passed to samples(...)" );
3677 idct
->copyTo( arr
);