3803 lines · 101.4 KB · C++
RawDownload
/*----------------------------------------------------------------------------  ChucK Concurrent, On-the-fly Audio Programming Language    Compiler and Virtual Machine   Copyright (c) 2004 Ge Wang and Perry R. Cook.  All rights reserved.    http://chuck.stanford.edu/    http://chuck.cs.princeton.edu/   This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.   This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.   You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: uana_xform.cpp// desc: unit analyzer transforms//// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)//         Rebecca Fiebrink (fiebrink@cs.princeton.edu)// date: Spring 2007//-----------------------------------------------------------------------------#include "uana_xform.h"#include "chuck_type.h"#include "chuck_vm.h"#include "chuck_compile.h"#include "chuck_instr.h"#include "chuck_lang.h"#include "util_buffers.h"#include "util_xforms.h"  // FFTCK_DLL_CTOR( FFT_ctor );CK_DLL_DTOR( FFT_dtor );CK_DLL_TICK( FFT_tick );CK_DLL_PMSG( FFT_pmsg );CK_DLL_TOCK( FFT_tock );CK_DLL_CTRL( FFT_ctrl_window );CK_DLL_CGET( FFT_cget_window );CK_DLL_CGET( FFT_cget_windowSize );CK_DLL_CTRL( FFT_ctrl_size );CK_DLL_CGET( FFT_cget_size );CK_DLL_MFUN( FFT_transform );CK_DLL_MFUN( FFT_spectrum );// static FFT offsetstatic t_CKUINT FFT_offset_data = 0;  // IFFTCK_DLL_CTOR( IFFT_ctor );CK_DLL_DTOR( IFFT_dtor );CK_DLL_TICK( IFFT_tick );CK_DLL_PMSG( IFFT_pmsg );CK_DLL_TOCK( IFFT_tock );CK_DLL_CTRL( IFFT_ctrl_window );CK_DLL_CGET( IFFT_cget_window );CK_DLL_CGET( IFFT_cget_windowSize );CK_DLL_CTRL( IFFT_ctrl_size );CK_DLL_CGET( IFFT_cget_size );CK_DLL_MFUN( IFFT_transform );CK_DLL_MFUN( IFFT_inverse );// static IFFT offsetstatic t_CKUINT IFFT_offset_data = 0;  // FlipCK_DLL_CTOR( Flip_ctor );CK_DLL_DTOR( Flip_dtor );CK_DLL_TICK( Flip_tick );CK_DLL_PMSG( Flip_pmsg );CK_DLL_TOCK( Flip_tock );CK_DLL_CTRL( Flip_ctrl_window );CK_DLL_CGET( Flip_cget_window );CK_DLL_CGET( Flip_cget_windowSize );CK_DLL_CTRL( Flip_ctrl_size );CK_DLL_CGET( Flip_cget_size );CK_DLL_MFUN( Flip_take );CK_DLL_MFUN( Flip_output );// static Flip offsetstatic t_CKUINT Flip_offset_data = 0;  // UnFlipCK_DLL_CTOR( UnFlip_ctor );CK_DLL_DTOR( UnFlip_dtor );CK_DLL_TICK( UnFlip_tick );CK_DLL_PMSG( UnFlip_pmsg );CK_DLL_TOCK( UnFlip_tock );CK_DLL_CTRL( UnFlip_ctrl_window );CK_DLL_CGET( UnFlip_cget_window );CK_DLL_CGET( UnFlip_cget_windowSize );CK_DLL_CTRL( UnFlip_ctrl_size );CK_DLL_CGET( UnFlip_cget_size );CK_DLL_MFUN( UnFlip_take );CK_DLL_MFUN( UnFlip_output );// static UnFlip offsetstatic t_CKUINT UnFlip_offset_data = 0;  // DCTCK_DLL_CTOR( DCT_ctor );CK_DLL_DTOR( DCT_dtor );CK_DLL_TICK( DCT_tick );CK_DLL_PMSG( DCT_pmsg );CK_DLL_TOCK( DCT_tock );CK_DLL_CTRL( DCT_ctrl_window );CK_DLL_CGET( DCT_cget_window );CK_DLL_CGET( DCT_cget_windowSize );CK_DLL_CTRL( DCT_ctrl_size );CK_DLL_CGET( DCT_cget_size );CK_DLL_MFUN( DCT_transform );CK_DLL_MFUN( DCT_spectrum );// static DCT offsetstatic t_CKUINT DCT_offset_data = 0;  // IDCTCK_DLL_CTOR( IDCT_ctor );CK_DLL_DTOR( IDCT_dtor );CK_DLL_TICK( IDCT_tick );CK_DLL_PMSG( IDCT_pmsg );CK_DLL_TOCK( IDCT_tock );CK_DLL_CTRL( IDCT_ctrl_window );CK_DLL_CGET( IDCT_cget_window );CK_DLL_CGET( IDCT_cget_windowSize );CK_DLL_CTRL( IDCT_ctrl_size );CK_DLL_CGET( IDCT_cget_size );CK_DLL_MFUN( IDCT_transform );CK_DLL_MFUN( IDCT_inverse );// static IDCT offsetstatic t_CKUINT IDCT_offset_data = 0;  // WindowingCK_DLL_SFUN( Windowing_hamming );CK_DLL_SFUN( Windowing_hann );CK_DLL_SFUN( Windowing_blackmanHarris );CK_DLL_SFUN( Windowing_rectangle );CK_DLL_SFUN( Windowing_triangle );// static arraystatic Chuck_Array8 * Windowing_array = NULL;static FLOAT * float_array = NULL;static t_CKINT float_array_size = 0;    //-----------------------------------------------------------------------------// name: xform_query()// desc: ...//-----------------------------------------------------------------------------DLL_QUERY xform_query( Chuck_DL_Query * QUERY ){    Chuck_Env * env = QUERY->env();    Chuck_DL_Func * func = NULL;     std::string doc;     //---------------------------------------------------------------------    // init as base class: FFT    //---------------------------------------------------------------------     doc = "computes the Fast Fourier Transform on incoming audio samples, and outputs the result via its UAnaBlob as both the complex spectrum and the magnitude spectrum. A buffering mechanism maintains the previous FFTsize # of samples, allowing FFT's to be taken at any point in time, on demand (via .upchuck() or by upchucking a downstream UAna. The window size (along with an arbitrary window shape) is controlled via the .window method. The hop size is complete dynamic, and is throttled by how time is advanced.";     if( !type_engine_import_uana_begin( env, "FFT", "UAna", env->global(),                                        FFT_ctor, FFT_dtor,                                        FFT_tick, FFT_tock, FFT_pmsg,                                        CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE,                                        doc.c_str()) )        return FALSE;     // member variable    FFT_offset_data = type_engine_import_mvar( env, "int", "@FFT_data", FALSE );    if( FFT_offset_data == CK_INVALID_OFFSET ) goto error;     // add examples    if( !type_engine_import_add_ex( env, "analysis/fft.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "analysis/fft2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "analysis/fft3.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "analysis/ifft.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "ai/genre-classify/feature-extract.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "ai/genre-classify/genre-classify.ck" ) ) goto error;     // transform    func = make_new_mfun( "void", "transform", FFT_transform );    func->add_arg( "float[]", "from" );    func->doc = "Manually take FFT (as opposed to using .upchuck() / upchuck operator)";    if( !type_engine_import_mfun( env, func ) ) goto error;     // window    func = make_new_mfun( "float[]", "window", FFT_ctrl_window );    func->add_arg( "float[]", "win" );    func->doc = "Set/get the transform window/size";    if( !type_engine_import_mfun( env, func ) ) goto error;     // windowSize    func = make_new_mfun( "int", "windowSize", FFT_cget_windowSize );    func->doc = "Get the current window size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // size    func = make_new_mfun( "int", "size", FFT_ctrl_size );    func->add_arg( "int", "size" );    func->doc = "Set the FFT-size.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "int", "size", FFT_cget_size );    func->doc = "Get the FFT-size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // spectrum    func = make_new_mfun( "void", "spectrum", FFT_spectrum );    func->add_arg( "complex[]", "buffer" );    func->doc = "Manually retrieve the results of a transform.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // end the class import    type_engine_import_class_end( env );      //---------------------------------------------------------------------    // init as base class: IFFT    //---------------------------------------------------------------------     doc = "computes the inverse Fast Fourier Transform on incoming spectral frames (on demand), and overlap-adds the results into its internal buffer, ready to be sent to other UGen's connected via =>. The window size (along with an arbitrary window shape) is controlled via the .window method.";     if( !type_engine_import_uana_begin( env, "IFFT", "UAna", env->global(),                                        IFFT_ctor, IFFT_dtor,                                        IFFT_tick, IFFT_tock, IFFT_pmsg,                                        CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE,                                        doc.c_str()) )        return FALSE;     // member variable    IFFT_offset_data = type_engine_import_mvar( env, "int", "@IFFT_data", FALSE );    if( IFFT_offset_data == CK_INVALID_OFFSET ) goto error;     // transform    func = make_new_mfun( "void", "transform", IFFT_transform );    func->add_arg( "complex[]", "from" );    func->doc = "Manually take IFFT (as opposed to using .upchuck() / upchuck operator)";    if( !type_engine_import_mfun( env, func ) ) goto error;     // window    func = make_new_mfun( "float[]", "window", IFFT_ctrl_window );    func->add_arg( "float[]", "win" );    func->doc = "Set/get the transform window/size";    if( !type_engine_import_mfun( env, func ) ) goto error;     // windowSize    func = make_new_mfun( "int", "windowSize", IFFT_cget_windowSize );    func->doc = "Get the current window size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // size    func = make_new_mfun( "int", "size", IFFT_ctrl_size );    func->add_arg( "int", "size" );    func->doc = "Set the IFFT-size.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "int", "size", IFFT_cget_size );    func->doc = "Get the IFFT-size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // spectrum    func = make_new_mfun( "void", "samples", IFFT_inverse );    func->add_arg( "float[]", "buffer" );    func->doc = "Manually take IFFT (as opposed to using .upchuck() / upchuck operator)";    if( !type_engine_import_mfun( env, func ) ) goto error;     // add examples    if( !type_engine_import_add_ex( env, "analysis/ifft.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "analysis/ifft2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "analysis/ifft3.ck" ) ) goto error;     // end the class import    type_engine_import_class_end( env );      //---------------------------------------------------------------------    // init as base class: Windowing    //---------------------------------------------------------------------    QUERY->begin_class( QUERY, "Windowing", "Object" );     // add rectangle    QUERY->add_sfun( QUERY, Windowing_rectangle, "float[]", "rectangle" );    QUERY->add_arg( QUERY, "int", "size" );     // add triangle    QUERY->add_sfun( QUERY, Windowing_triangle, "float[]", "triangle" );    QUERY->add_arg( QUERY, "int", "size" );     // add hann    QUERY->add_sfun( QUERY, Windowing_hann, "float[]", "hann" );    QUERY->add_arg( QUERY, "int", "size" );     // add hamming    QUERY->add_sfun( QUERY, Windowing_hamming, "float[]", "hamming" );    QUERY->add_arg( QUERY, "int", "size" );     // add blackman-harris    QUERY->add_sfun( QUERY, Windowing_blackmanHarris, "float[]", "blackmanHarris" );    QUERY->add_arg( QUERY, "int", "size" );     // add examples | 1.5.0.0 (ge)    QUERY->add_ex( QUERY, "analysis/win.ck" );    QUERY->add_ex( QUERY, "analysis/xsynth.ck" );    QUERY->add_ex( QUERY, "analysis/tracking/pitch-track.ck" );    QUERY->add_ex( QUERY, "ai/features/rolloff2.ck" );    QUERY->add_ex( QUERY, "analysis/win.ck" );    QUERY->add_ex( QUERY, "ai/genre-classify/feature-extract.ck" );    QUERY->add_ex( QUERY, "ai/genre-classify/genre-classify.ck" );     // done    QUERY->end_class( QUERY );     // initialize static data    Windowing_array = new Chuck_Array8();    initialize_object( Windowing_array, QUERY->env()->t_array );    // TODO: yes? reference count    Windowing_array->add_ref();    // set size    float_array_size = 16384;    float_array = new FLOAT[float_array_size];      //---------------------------------------------------------------------    // init as base class: Flip    //---------------------------------------------------------------------     doc = "Turn N (size) audio samples into a Unit Analyzer audio analysis frame.";     if( !type_engine_import_uana_begin( env, "Flip", "UAna", env->global(),                                        Flip_ctor, Flip_dtor,                                        Flip_tick, Flip_tock, Flip_pmsg,                                        CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE,                                        doc.c_str()) )        return FALSE;     // member variable    Flip_offset_data = type_engine_import_mvar( env, "int", "@Flip_data", FALSE );    if( Flip_offset_data == CK_INVALID_OFFSET ) goto error;     // add examples    if( !type_engine_import_add_ex( env, "analysis/flip.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "analysis/autocorr.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "ai/features/zerox.ck" ) ) goto error;     // transform    func = make_new_mfun( "void", "transform", Flip_take );    func->add_arg( "float[]", "from" );    func->doc = "Manually take Flip (as opposed to using .upchuck() / upchuck operator).";    if( !type_engine_import_mfun( env, func ) ) goto error;     // window    func = make_new_mfun( "float[]", "window", Flip_ctrl_window );    func->add_arg( "float[]", "win" );    func->doc = "Set/get the transform window/size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // windowSize    func = make_new_mfun( "int", "windowSize", Flip_cget_windowSize );    func->doc = "Get the current window size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // size    func = make_new_mfun( "int", "size", Flip_ctrl_size );    func->add_arg( "int", "size" );    func->doc = "Set the Flip size.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "int", "size", Flip_cget_size );    func->doc = "Get the Flip size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // output    func = make_new_mfun( "void", "output", Flip_output );    func->add_arg( "float[]", "buffer" );    func->doc = "Manually take Flip (as opposed to using .upchuck() / upchuck operator)";    if( !type_engine_import_mfun( env, func ) ) goto error;     // end the class import    type_engine_import_class_end( env );     // deprecate    type_engine_register_deprecate( env, "pilF", "UnFlip" );     //---------------------------------------------------------------------    // init as base class: pilF    //---------------------------------------------------------------------     doc = "turns UAna frames into audio samples, via overlap add.";     if( !type_engine_import_uana_begin( env, "UnFlip", "UAna", env->global(),                                        UnFlip_ctor, UnFlip_dtor,                                        UnFlip_tick, UnFlip_tock, UnFlip_pmsg,                                        CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE,                                        doc.c_str()) )        return FALSE;     // member variable    UnFlip_offset_data = type_engine_import_mvar( env, "int", "@UnFlip_data", FALSE );    if( UnFlip_offset_data == CK_INVALID_OFFSET ) goto error;     // go    func = make_new_mfun( "void", "transform", UnFlip_take );    func->doc = "Manually take pilF (as opposed to using .upchuck() / upchuck operator).";    if( !type_engine_import_mfun( env, func ) ) goto error;     // window    func = make_new_mfun( "float[]", "window", UnFlip_ctrl_window );    func->add_arg( "float[]", "win" );    func->doc = "Set/get the transform window/size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // windowSize    func = make_new_mfun( "int", "windowSize", UnFlip_cget_windowSize );    func->doc = "Get the current window size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // size    func = make_new_mfun( "int", "size", UnFlip_ctrl_size );    func->add_arg( "int", "size" );    func->doc = "Set the pilF size.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "int", "size", UnFlip_cget_size );    func->doc = "Get the pilF size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // output    func = make_new_mfun( "void", "output", UnFlip_output );    func->add_arg( "float[]", "buffer" );    func->doc = "Manually take pilF (as opposed to using .upchuck() / upchuck operator)";    if( !type_engine_import_mfun( env, func ) ) goto error;     // add example    if( !type_engine_import_add_ex( env, "analysis/flip.ck" ) ) goto error;     // end the class import    type_engine_import_class_end( env );      //---------------------------------------------------------------------    // init as base class: DCT    //---------------------------------------------------------------------     doc = "computes the Discrete Cosine Transform on incoming audio samples, and outputs the result via its UAnaBlob as real values in the D.C. spectrum. A buffering mechanism maintains the previous DCT size # of samples, allowing DCT to be taken at any point in time, on demand (via .upchuck() or by upchucking a downstream UAna; see UAna documentation). The window size (along with an arbitrary window shape) is controlled via the .window method. The hop size is complete dynamic, and is throttled by how time is advanced.";     if( !type_engine_import_uana_begin( env, "DCT", "UAna", env->global(),                                        DCT_ctor, DCT_dtor,                                        DCT_tick, DCT_tock, DCT_pmsg,                                        CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE, CK_NO_VALUE,                                        doc.c_str()) )        return FALSE;     // add examples    if( !type_engine_import_add_ex( env, "analysis/dct.ck" ) ) goto error;     // member variable    DCT_offset_data = type_engine_import_mvar( env, "int", "@DCT_data", FALSE );    if( DCT_offset_data == CK_INVALID_OFFSET ) goto error;     // transform    func = make_new_mfun( "void", "transform", DCT_transform );    func->add_arg( "float[]", "from" );    func->doc = "Manually take DCT (as opposed to using .upchuck() / upchuck operator).";    if( !type_engine_import_mfun( env, func ) ) goto error;     // window    func = make_new_mfun( "float[]", "window", DCT_ctrl_window );    func->add_arg( "float[]", "win" );    func->doc = "Set/get the transform window/size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // windowSize    func = make_new_mfun( "int", "windowSize", DCT_cget_windowSize );    func->doc = "Get the current window size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // size    func = make_new_mfun( "int", "size", DCT_ctrl_size );    func->add_arg( "int", "size" );    func->doc = "Set the DCT size.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "int", "size", DCT_cget_size );    func->doc = "Get the DCT size.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // spectrum    func = make_new_mfun( "void", "spectrum", DCT_spectrum );    func->add_arg( "float[]", "buffer" );    func->doc = "Manually retrieve the results of a transform.";

Lines 1–500 of 3803.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t