5671 lines · 187.6 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: ugen_xxx.cpp// desc: non-specific unit generators//// author: Ge Wang (gewang@cs.princeton.edu)//         Ananya Misra (amisra@cs.princeton.edu)//         Perry R. Cook (prc@cs.princeton.edu)//         Dan Trueman (dtrueman@princeton.edu)//         Matt Hoffman (for Dyno)// date: Spring 2004//       Summer 2005 - updated//-----------------------------------------------------------------------------#include "ugen_xxx.h"#include "chuck_type.h"#include "chuck_ugen.h"#include "chuck_vm.h"#include "chuck_compile.h"#include "chuck_instr.h"#include "util_math.h" #include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <limits.h> #ifndef __DISABLE_SNDBUF__#if defined(__CK_SNDFILE_NATIVE__)#include <sndfile.h>#else#include "util_sndfile.h"#endif#endif #ifdef __ANDROID__#include "util_platforms.h"#endif #include <fstream>using namespace std;  // subgraphCK_DLL_CTOR( subgraph_ctor ); // foogenCK_DLL_CTOR( foogen_ctor );CK_DLL_DTOR( foogen_dtor );CK_DLL_TICK( foogen_tick );  // LiSa queryDLL_QUERY lisa_query( Chuck_DL_Query * query ); // sample ratestatic t_CKUINT g_srateXxx; // offsetstatic t_CKUINT subgraph_offset_inlet = 0;static t_CKUINT subgraph_offset_outlet = 0;static t_CKUINT foogen_offset_data = 0;static t_CKUINT stereo_offset_left = 0;static t_CKUINT stereo_offset_right = 0;static t_CKUINT stereo_offset_pan = 0;static t_CKUINT stereo_offset_panType = 0;static t_CKUINT cnoise_offset_data = 0;static t_CKUINT impulse_offset_data = 0;static t_CKUINT step_offset_data = 0;static t_CKUINT delayp_offset_data = 0;static t_CKUINT sndbuf_offset_data = 0;static t_CKUINT dyno_offset_data = 0;// static t_CKUINT zerox_offset_data = 0;    // panning types enumerationenum PanTypesEnum{    PAN_WTF_UNITY = 0, // default in dac/adc    PAN_EQ_POWER, // default in Pan2    PAN_LINEAR // not supported};    //-----------------------------------------------------------------------------// name: xxx_query()// desc: ...//-----------------------------------------------------------------------------DLL_QUERY xxx_query( Chuck_DL_Query * QUERY ){    g_srateXxx = QUERY->srate;    // get the env    Chuck_Env * env = QUERY->env();     Chuck_DL_Func * func = NULL;    std::string doc;     // deprecate    type_engine_register_deprecate( env, "dac", "DAC" );    type_engine_register_deprecate( env, "adc", "ADC" );    type_engine_register_deprecate( env, "pan2", "Pan2" );    type_engine_register_deprecate( env, "mix2", "Mix2" );    type_engine_register_deprecate( env, "gain", "Gain" );    type_engine_register_deprecate( env, "noise", "Noise" );    type_engine_register_deprecate( env, "cnoise", "CNoise" );    type_engine_register_deprecate( env, "impulse", "Impulse" );    type_engine_register_deprecate( env, "step", "Step" );    type_engine_register_deprecate( env, "halfrect", "HalfRect" );    type_engine_register_deprecate( env, "fullrect", "FullRect" );    type_engine_register_deprecate( env, "zerox", "ZeroX" );    type_engine_register_deprecate( env, "delayp", "DelayP" );    type_engine_register_deprecate( env, "sndbuf", "SndBuf" );    // 1.5.0.0 (ge) removed deprecate; allow both    // type_engine_register_deprecate( env, "Chubgraph", "Chugraph" );     //! \section audio output     //-------------------------------------------------------------------------    // init as base class: Subgraph    //-------------------------------------------------------------------------    doc = "base class for subgraph-based user-created in-language unit generators.";    if( !type_engine_import_ugen_begin( env, "Chugraph", "UGen", env->global(),                                        subgraph_ctor, NULL, NULL, NULL, 1, 1, doc.c_str() ) )        return FALSE;     // add examples    if( !type_engine_import_add_ex( env, "extend/chugraph.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "class/dinky.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "class/try.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "deep/ks-chord.ck" ) ) goto error;     doc = "terminal for sources chucked into this ugen.";    subgraph_offset_inlet = type_engine_import_mvar( env, "UGen", "inlet", TRUE, doc.c_str() );    if( subgraph_offset_inlet == CK_INVALID_OFFSET ) goto error;     doc = "terminal for the output of this ugen.";    subgraph_offset_outlet = type_engine_import_mvar( env, "UGen", "outlet", TRUE, doc.c_str() );    if( subgraph_offset_outlet == CK_INVALID_OFFSET ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;      //-------------------------------------------------------------------------    // init as base class: FooGen    //-------------------------------------------------------------------------    doc = "base class for user-created in-language unit generators.";    if( !type_engine_import_ugen_begin( env, "Chugen", "UGen", env->global(),                                        foogen_ctor, foogen_dtor, foogen_tick, NULL, 1, 1,                                        doc.c_str() ) )        return FALSE;     if( !type_engine_import_add_ex( env, "extend/chugen.ck" ) ) goto error;     foogen_offset_data = type_engine_import_mvar( env, "int", "@foogen_data", FALSE );    if( foogen_offset_data == CK_INVALID_OFFSET ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;      //-------------------------------------------------------------------------    // init as base class: UGen_Multi    //-------------------------------------------------------------------------    doc = "base class for multi-channel unit generators.";    if( !type_engine_import_ugen_begin( env, "UGen_Multi", "UGen", env->global(),                                        multi_ctor, (f_dtor)NULL, (f_tick)NULL, (f_pmsg)NULL, 0, 0, doc.c_str() ) )        return FALSE;     // add chan    func = make_new_mfun( "UGen", "chan", multi_cget_chan );    func->add_arg( "int", "which" );    func->doc = "get UGen representing a specific channel of this UGen, or null if no such channel is available.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // add pan    /* func = make_new_mfun( "float", "pan", multi_ctrl_pan );    func->add_arg( "float", "val" );    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "float", "pan", multi_cget_pan );    if( !type_engine_import_mfun( env, func ) ) goto error; */     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;      //---------------------------------------------------------------------    // init as base class: UGen_Stereo    //---------------------------------------------------------------------    doc = "base class for stereo unit generators.";    if( !type_engine_import_ugen_begin( env, "UGen_Stereo", "UGen_Multi", env->global(),                                        stereo_ctor, NULL, NULL, NULL, 2, 2, doc.c_str() ) )        return FALSE;     // add left    doc = "left channel (same as .chan(0)).";    stereo_offset_left = type_engine_import_mvar( env, "UGen", "left", FALSE, doc.c_str() );    if( stereo_offset_left == CK_INVALID_OFFSET ) goto error;     // add right    doc = "right channel (same as .chan(1)).";    stereo_offset_right = type_engine_import_mvar( env, "UGen", "right", FALSE, doc.c_str() );    if( stereo_offset_right == CK_INVALID_OFFSET ) goto error;     // add pan    stereo_offset_pan = type_engine_import_mvar( env, "float", "@pan", FALSE );    if( stereo_offset_pan == CK_INVALID_OFFSET ) goto error;     // add panning law (see PanTypesEnum)    stereo_offset_panType = type_engine_import_mvar( env, "int", "@panType", FALSE );    if( stereo_offset_panType == CK_INVALID_OFFSET ) goto error;     // add pan    func = make_new_mfun( "float", "pan", stereo_ctrl_pan );    func->add_arg( "float", "val" );    func->doc = "pan between left and right channels, in range [-1,1], with -1 being far-left, 1 far-right, and 0 centered.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "float", "pan", stereo_cget_pan );    func->doc = "pan between left and right channels, in range [-1,1], with -1 being far-left, 1 far-right, and 0 centered.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // add panType    func = make_new_mfun( "int", "panType", stereo_ctrl_panType );    func->add_arg( "int", "val" );    func->doc = "set the panning type: (1) constant power panning, (0) unity gain anti-panning.";    if( !type_engine_import_mfun( env, func ) ) goto error;    func = make_new_mfun( "int", "panType", stereo_cget_panType );    func->doc = "get the panning type: (1) constant power panning, (0) unity gain anti-panning.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;     // add dac    //! digital/analog converter    //! abstraction for underlying audio output device    //---------------------------------------------------------------------    // init as base class: dac    //---------------------------------------------------------------------    env->t_dac = type_engine_import_ugen_begin( env, "DAC", "UGen_Stereo", env->global(),                                                NULL, NULL, NULL, NULL, 2, 2 );    if( !env->t_dac )        return FALSE;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;     // add adc    //! analog/digital converter    //! abstraction for underlying audio input device    //---------------------------------------------------------------------    // init as base class: adc    //---------------------------------------------------------------------    env->t_adc = type_engine_import_ugen_begin( env, "ADC", "UGen_Stereo", env->global(),                                                (f_ctor)NULL, (f_dtor)NULL, (f_tick)NULL,                                                (f_pmsg)NULL, 0, 2 );    if( !env->t_adc )        return FALSE;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;     //---------------------------------------------------------------------    // init as base class: pan2    //---------------------------------------------------------------------    doc = "a mono-to-stereo unit generator for stereo panning.";    if( !type_engine_import_ugen_begin( env, "Pan2", "UGen_Stereo", env->global(),                                        pan2_ctor, NULL, NULL, NULL, 2, 2, doc.c_str() ) )        return FALSE;     // add examples | 1.5.0.0 (ge)    if( !type_engine_import_add_ex( env, "basic/chirp2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/array.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/powerup2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/moe2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/larry2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/curly2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/ugen-array.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stereo/stereo-noise.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "stk/honkeytonk-algo1.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "hanoi++.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "hanoi2.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "hanoi3.ck" ) ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;     //---------------------------------------------------------------------    // init as base class: mix2    //---------------------------------------------------------------------    doc = "a stereo-to-mono unit generator for mixing stereo signal to mono.";    if( !type_engine_import_ugen_begin( env, "Mix2", "UGen_Stereo", env->global(),                                        NULL, NULL, NULL, NULL, 2, 2, doc.c_str() ) )        return FALSE;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;     // add blackhole    //! sample rate sample sucker    //! ( like dac, ticks ugens, but no more )    //! see \example pwm.ck    //QUERY->ugen_add( QUERY, "blackhole", NULL );    // set funcs    //QUERY->ugen_func( QUERY, NULL, NULL, bunghole_tick, NULL );     // add bunghole    //! sample rate sample sucker    //! ( like dac, ticks ugens, but no more )    //QUERY->ugen_add( QUERY, "bunghole", NULL );    // set funcs    //QUERY->ugen_func( QUERY, NULL, NULL, bunghole_tick, NULL );     // add gain    //! gain control    //! (NOTE - all unit generators can themselves change their gain)    //! (this is a way to add N outputs together and scale them)    //! used in \example i-robot.ck    //---------------------------------------------------------------------    // init as base class: gain    //---------------------------------------------------------------------    doc = "a gain control unit generator. (All unit generators can already change their own gain; this is an explicit way to add multiple outputs together and scale them.)";    if( !type_engine_import_ugen_begin( env, "Gain", "UGen", env->global(),                                        NULL, NULL, NULL, NULL, doc.c_str() ) )        return FALSE;     if( !type_engine_import_add_ex( env, "basic/i-robot.ck" ) ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;    /*! \example        noise n => gain g => dac;    sinosc s => g;    .3 => g.gain;    while( true ) { 100::ms => now; }    */     //! \section wave forms     // add noise    //! white noise generator    //! see \example noise.ck \example powerup.ck    //---------------------------------------------------------------------    // init as base class: noise    //---------------------------------------------------------------------    doc = "a white noise generator.";    if( !type_engine_import_ugen_begin( env, "Noise", "UGen", env->global(),                                        NULL, NULL, noise_tick, NULL, doc.c_str() ) )        return FALSE;     if( !type_engine_import_add_ex( env, "basic/wind.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "shred/powerup.ck" ) ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;//zzz     // add cnoise    /*QUERY->ugen_add( QUERY, "cnoise", NULL );    QUERY->ugen_func( QUERY, cnoise_ctor, cnoise_dtor, cnoise_tick, NULL );    QUERY->ugen_ctrl( QUERY, cnoise_ctrl_mode, NULL, "string", "mode" );    QUERY->ugen_ctrl( QUERY, cnoise_ctrl_fprob, NULL, "float", "fprob" );*/     //---------------------------------------------------------------------    // init as base class: cnoise    //---------------------------------------------------------------------    doc = "a noise generator with multiple noise synthesis modes.";    if( !type_engine_import_ugen_begin( env, "CNoise", "UGen", env->global(),                                        cnoise_ctor, cnoise_dtor, cnoise_tick, NULL, doc.c_str() ) )        return FALSE;     // add member variable    cnoise_offset_data = type_engine_import_mvar( env, "int", "@cnoise_data", FALSE );    if( cnoise_offset_data == CK_INVALID_OFFSET ) goto error;     // add ctrl: mode    func = make_new_mfun( "string", "mode", cnoise_ctrl_mode );    func->add_arg( "string", "mode" );    func->doc = "Noise synthesis mode. Supported modes are &quot;white&quot;, &quot;pink&quot;, &quot;flip&quot;, and &quot;xor&quot;.";    if( !type_engine_import_mfun( env, func ) ) goto error;    // add cget: mode    //func = make_new_mfun( "string", "mode", cnoise_cget_mode );    //if( !type_engine_import_mfun( env, func ) ) goto error;     // add ctrl: fprob    func = make_new_mfun( "float", "fprob", cnoise_ctrl_fprob );    func->doc = "Probability [0-1] used for calculating XOR noise.";    func->add_arg( "float", "fprob" );    if( !type_engine_import_mfun( env, func ) ) goto error;    // add cget: fprob    //func = make_new_mfun( "float", "fprob", cnoise_cget_fprob );    //if( !type_engine_import_mfun( env, func ) ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;      // add impulse    //! pulse generator - can set the value of the current sample    //! default for each sample is 0 if not set        //QUERY->ugen_add( QUERY, "impulse", NULL );    // set funcs        //QUERY->ugen_func( QUERY, impulse_ctor, impulse_dtor, impulse_tick, NULL );    // ctrl func        //QUERY->ugen_ctrl( QUERY, impulse_ctrl_value, impulse_cget_value, "float", "value" );        //QUERY->ugen_ctrl( QUERY, impulse_ctrl_value, impulse_cget_value, "float", "next" ); //! set value of next sample    /*! \example        impulse i => dac;     while( true ) {        1.0 => i.next;        100::ms => now;    }    */    //---------------------------------------------------------------------    // init as base class: impulse    //---------------------------------------------------------------------    doc = "An impulse generator. Can be used to set the value of the next sample; default for each sample is 0 if not set. Additionally, this can be used to generate a digital signal, one sample at a time.";    if( !type_engine_import_ugen_begin( env, "Impulse", "UGen", env->global(),                                        impulse_ctor, impulse_dtor, impulse_tick, NULL, doc.c_str() ) )        return FALSE;     // add ctrl: value    //func = make_new_mfun( "float", "value", impulse_ctrl_value );    //func->add_arg( "float", "value" );    //if( !type_engine_import_mfun( env, func ) ) goto error;    // add cget: value    //func = make_new_mfun( "float", "value", impulse_cget_value );    //if( !type_engine_import_mfun( env, func ) ) goto error;     // add member variable    impulse_offset_data = type_engine_import_mvar( env, "int", "@impulse_data", FALSE );    if( impulse_offset_data == CK_INVALID_OFFSET ) goto error;     // add ctrl: next    func = make_new_mfun( "float", "next", impulse_ctrl_next );    func->add_arg( "float", "next" );    func->doc = "set the value of next sample. (Note: if you are using the UGen.last() method to read the output of the impulse, the value set by Impulse.next() does not appear as the output until after the next sample boundary. In this case, there is a consistent 1::samp offset between setting .next(...) and reading that value using .last().)";    if( !type_engine_import_mfun( env, func ) ) goto error;    // add cget: next    func = make_new_mfun( "float", "next", impulse_cget_next );    func->doc = "get value of next sample to be generated.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // add examples    if( !type_engine_import_add_ex( env, "basic/imp.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "basic/comb.ck" ) ) goto error;    if( !type_engine_import_add_ex( env, "deep/chant.ck" ) ) goto error;     // end import    if( !type_engine_import_class_end( env ) )        return FALSE;     // add step    //! step generator - like impulse, but once a value is set,    //! it is held for all following samples, until value is set again    //! see \example step.ck        //QUERY->ugen_add( QUERY, "step", NULL );    // set funcs        //QUERY->ugen_func( QUERY, step_ctor, step_dtor, step_tick, NULL );    // ctrl func

Lines 1–500 of 5671.

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