1158 lines · 39.7 KB · C++
RawDownload
/*----------------------------------------------------------------------------  ChucK Concurrent, On-the-fly Audio Programming Language    Compiler and Virtual Machine   Copyright (c) 2003 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: chuck_main.cpp// desc: chuck entry point | command line host//// v1.3.5.3: migration to chuck_system.* (see for more details)//// author: Ge Wang | http://www.gewang.com///         (see chuck_system.*)//-----------------------------------------------------------------------------#include "chuck.h"#include "chuck_audio.h"#include "chuck_console.h"#include "util_string.h"#include <signal.h> #if defined(__PLATFORM_WIN32__)  #include <windows.h>#else  #include <unistd.h>  #include <pthread.h>#endif  //-----------------------------------------------------------------------------// function prototypes//-----------------------------------------------------------------------------t_CKBOOL init_shell( Chuck_Shell * shell, Chuck_Shell_UI * ui, Chuck_VM * vm );void * shell_cb( void * p );bool go( int argc, const char ** argv );void global_cleanup();void all_stop();void all_detach();void usage();void uh();t_CKBOOL get_count( const char * arg, t_CKUINT * out );void cb( t_CKSAMPLE * in, t_CKSAMPLE * out, t_CKUINT numFrames,         t_CKUINT numInChans, t_CKUINT numOutChans, void * data ); // C functionsextern "C" void signal_int( int sig_num );extern "C" void signal_pipe( int sig_num );   //-----------------------------------------------------------------------------// global variables//-----------------------------------------------------------------------------// the one ChucK, for command line hostChucK * the_chuck;// thread id for shellCHUCK_THREAD g_tid_shell = 0;// default destination host namechar g_otf_dest[256] = "127.0.0.1";// otf listener portt_CKINT g_otf_port = 8888; // the shellChuck_Shell * g_shell = NULL;// shell shutdown flagt_CKBOOL g_shutdown_shell = FALSE;// global variablest_CKUINT g_sigpipe_mode = 0;// flag for Std.system( string )t_CKBOOL g_enable_system_cmd = FALSE;// flag for enabling shell, ge: 1.3.5.3t_CKBOOL g_enable_shell = FALSE;// flag for audio enable, ge: 1.3.5.3t_CKBOOL g_enable_realtime_audio = TRUE;// added 1.3.2.0 // moved from VM 1.3.5.3f_mainthreadhook g_main_thread_hook = NULL;f_mainthreadquit g_main_thread_quit = NULL;void * g_main_thread_bindle = NULL;// num vms running; used to quit le_cb thread // added 1.3.6.0t_CKUINT g_num_vms_running = 0;   // priority stuff#if defined(__MACOSX_CORE__)t_CKINT g_priority = XThreadUtil::get_max_priority(); // was 80t_CKINT g_priority_low = XThreadUtil::get_min_priority(); // was 60#elif defined(__PLATFORM_WIN32__) && !defined(__WINDOWS_PTHREAD__)t_CKINT g_priority = THREAD_PRIORITY_HIGHEST;t_CKINT g_priority_low = THREAD_PRIORITY_HIGHEST;#elset_CKINT g_priority = 0x7fffffff;t_CKINT g_priority_low = 0x7fffffff;#endif    //-----------------------------------------------------------------------------// name: main()// desc: ...//-----------------------------------------------------------------------------#ifndef __CHUCK_NO_MAIN__int main( int argc, const char ** argv )#elseint chuck_main( int argc, const char ** argv )#endif // __CHUCK_NO_MAIN__{    // parse, init, run!    go( argc, argv );     // clean up    global_cleanup();        return 0;}    //-----------------------------------------------------------------------------// name: cb()// desc: audio callback//-----------------------------------------------------------------------------void cb( t_CKSAMPLE * in, t_CKSAMPLE * out, t_CKUINT numFrames,         t_CKUINT numInChans, t_CKUINT numOutChans, void * data ){    // TODO: check channel numbers        // call up to ChucK    the_chuck->run( in, out, numFrames );}    //-----------------------------------------------------------------------------// name: version()// desc: ...//-----------------------------------------------------------------------------static void version(){    CK_FPRINTF_STDERR( "\n" );    CK_FPRINTF_STDERR( "chuck version: %s\n", ChucK::version() );        // platform string    string platform = "";    // binary architecture string;    string archs = ""; #if defined(__PLATFORM_WIN32__)    #if defined(__WINDOWS_ASIO__) && defined(__WINDOWS_DS__)        platform = "microsoft windows + DS + ASIO";    #elif defined(__WINDOWS_ASIO__)        platform = "microsoft windows + ASIO";    #elif defined(__WINDOWS_DS__)        platform = "microsoft windows + DS";    #else        platform = "microsoft windows (??)";    #endif#elif defined(__LINUX_ALSA__)    platform = "linux (alsa)";#elif defined(__LINUX_OSS__)    platform = "linux (oss)";#elif defined(__LINUX_JACK__) || defined(__UNIX_JACK__)    platform = "linux (jack)";#elif defined(__LINUX_PULSE__)    platform = "linux (pulse)";#elif defined(__MACOSX_CORE__) && defined(__LITTLE_ENDIAN__)    platform = "macOS";#elif defined(__MACOSX_CORE__)    platform = "macOS (powerpc)";#else    platform = "unspecified platform";#endif // check for universal binary#if defined(__MACOSX_UB__)    archs = " [universal binary]";#endif     CK_FPRINTF_STDERR( "   %s : %ld-bit%s\n", platform.c_str(), machine_intsize(), archs.c_str() );    CK_FPRINTF_STDERR( "   http://chuck.cs.princeton.edu/\n" );    CK_FPRINTF_STDERR( "   http://chuck.stanford.edu/\n\n" );}   //-----------------------------------------------------------------------------// name: usage()// desc: ...//-----------------------------------------------------------------------------void usage(){    // (note: optional colon added 1.3.0.0)    CK_FPRINTF_STDERR( "usage: chuck --[options|commands] [+-=^] file1 file2 file3 ...\n" );    CK_FPRINTF_STDERR( "   [options] = halt|loop|audio|silent|dump|nodump|about|probe|\n" );    CK_FPRINTF_STDERR( "               channels:<N>|out:<N>|in:<N>|dac:<N>|adc:<N>|driver:<name>|\n" );    CK_FPRINTF_STDERR( "               srate:<N>|bufsize:<N>|bufnum:<N>|shell|empty|\n" );    CK_FPRINTF_STDERR( "               remote:<hostname>|port:<N>|verbose:<N>|level:<N>|\n" );    CK_FPRINTF_STDERR( "               callback|deprecate:{stop|warn|ignore}|\n" );    CK_FPRINTF_STDERR( "               chugin-load:{on|off}|chugin-path:<path>|chugin:<name>\n" );    CK_FPRINTF_STDERR( "   [commands] = add|remove|replace|remove.all|status|time|kill\n" );    CK_FPRINTF_STDERR( "   [+-=^] = shortcuts for add, remove, replace, status\n" );    version();}    //-----------------------------------------------------------------------------// name: get_count()// desc: get the thing after -- or - as number//-----------------------------------------------------------------------------t_CKBOOL get_count( const char * arg, t_CKUINT * out ){    // no comment    if( !strncmp( arg, "--", 2 ) ) arg += 2;    else if( !strncmp( arg, "-", 1 ) ) arg += 1;    else return FALSE;        // end of string    if( *arg == '\0' ) return FALSE;    // not digit    if( *arg < '0' || *arg > '9' ) return FALSE;        // number    *out = (t_CKUINT)atoi( arg );        return TRUE;}    //-----------------------------------------------------------------------------// name: signal_int()// desc: handler for ctrl-c (SIGINT).  NB: on windows this is triggered//       in a separate thread. global_cleanup requires a mutex.//-----------------------------------------------------------------------------extern "C" void signal_int( int sig_num ){    // log    CK_FPRINTF_STDERR( "[chuck]: cleaning up...\n" );    // clean up everything!    global_cleanup();    // exit with code    exit( 130 ); // 130 -> terminated by ctrl-c}    //-----------------------------------------------------------------------------// name: signal_pipe()// desc: ...//-----------------------------------------------------------------------------extern "C" void signal_pipe( int sig_num ){    fprintf( stderr, "[chuck]: sigpipe handled - broken pipe (no connection)...\n" );    if( g_sigpipe_mode )    {        // clean up everything!        global_cleanup();        // later        exit( 2 );    }}    //-----------------------------------------------------------------------------// name: global_cleanup()// desc: ...//-----------------------------------------------------------------------------void global_cleanup(){    // make sure we don't double clean    static bool s_already_cleaning = false;     // check | 1.4.2.1 (ge) added    if( s_already_cleaning )    {        // log | 1.4.2.1 (ge) added        EM_log( CK_LOG_INFO, "additional global cleanup not needed..." );        // done        return;    }     // log | 1.4.2.1 (ge) added    EM_log( CK_LOG_SYSTEM, "global cleanup initiating..." );    // set flag    s_already_cleaning = true;     // static XMutex s_mutex;    // s_mutex.acquire();     // REFACTOR-2017: shut down audio system    all_stop();     // request MIDI, etc. files be closed    // REFACTOR-2017: TODO; RESOLVED: used to be all_detach()    // need to call this before deleting the_chuck/the VM    ChucK::globalCleanup();        // delete the chuck    SAFE_DELETE( the_chuck );     // delete shell and set to NULL | 1.4.1.0    if( g_enable_shell ) SAFE_DELETE( g_shell );     // wait for the shell, if it is running    // does the VM reset its priority to normal before exiting?    //if( g_enable_shell )    //    while( g_shell != NULL )    //        usleep(10000);     // REFACTOR-2017 TODO: Cancel otf, le_cb threads? Does this happen in ~ChucK()?    // things don't work so good on windows...#if !defined(__PLATFORM_WIN32__) || defined(__WINDOWS_PTHREAD__)//    if( g_tid_otf ) pthread_cancel( g_tid_otf );//    if( g_tid_whatever ) pthread_cancel( g_tid_whatever );#else    // close handle//    if( g_tid_otf ) CloseHandle( g_tid_otf );#endif     // 1.4.2.1 (ge) | commented    // s_mutex.release();}     //-----------------------------------------------------------------------------// name: all_stop()// desc: ...//-----------------------------------------------------------------------------void all_stop(){    if( g_enable_realtime_audio )    {        ChuckAudio::shutdown();    }    // REFACTOR-2017: TODO: other things? le_cb?}    //-----------------------------------------------------------------------------// name: init_shell()// desc: ...//-----------------------------------------------------------------------------t_CKBOOL init_shell( Chuck_Shell * shell, Chuck_Shell_UI * ui, Chuck_VM * vm ){    // initialize shell UI    if( !ui->init() )    {        CK_FPRINTF_STDERR( "[chuck]: error starting shell UI...\n" );        return FALSE;    }        // initialize    if( !shell->init( vm, ui ) )    {        CK_FPRINTF_STDERR( "[chuck]: error starting shell...\n" );        return FALSE;    }        return TRUE;}    //-----------------------------------------------------------------------------// name: check_shell_shutdown()// desc: check if we need to take action on shell//-----------------------------------------------------------------------------t_CKBOOL check_shell_shutdown(){    if( g_enable_shell && g_shutdown_shell )    {        // set to false so we don't do this multiple time        g_shutdown_shell = FALSE;        // cleanup        global_cleanup();        // return yes        return TRUE;    }        return FALSE;}    //-----------------------------------------------------------------------------// name: shell_cb// desc: thread routine//-----------------------------------------------------------------------------void * shell_cb( void * p ){    Chuck_Shell * shell;    // log    EM_log( CK_LOG_INFO, "starting thread routine for shell..." );        // assuming this is absolutely necessary, an assert may be better    assert( p != NULL );        shell = (Chuck_Shell *) p;        //atexit( wait_for_shell );        // run the shell    shell->run();        // flag to effect global shutdown from main thread    g_shutdown_shell = TRUE;     EM_log( CK_LOG_INFO, "exiting thread routine for shell..." );        return NULL;}    //-----------------------------------------------------------------------------// name: go()// desc: parse args, init stuff, run!//-----------------------------------------------------------------------------bool go( int argc, const char ** argv ){    t_CKBOOL vm_halt = TRUE;    t_CKINT srate = SAMPLE_RATE_DEFAULT;    t_CKBOOL force_srate = FALSE; // added 1.3.1.2    t_CKINT buffer_size = BUFFER_SIZE_DEFAULT;    t_CKINT num_buffers = NUM_BUFFERS_DEFAULT;    t_CKINT dac = 0;    t_CKINT adc = 0;    std::string dac_name = ""; // added 1.3.0.0    std::string adc_name = ""; // added 1.3.0.0    t_CKINT dac_chans = 2;    t_CKINT adc_chans = 2;    t_CKINT adc_chans_before_rtaudio = adc_chans; // added 1.5.0.0    t_CKBOOL dump = FALSE;    t_CKBOOL probe = FALSE;    t_CKBOOL set_priority = FALSE;    t_CKBOOL auto_depend = FALSE;    t_CKBOOL block = FALSE;    // t_CKBOOL enable_shell = FALSE;    t_CKBOOL syntax_check_only = FALSE;    t_CKBOOL no_vm = FALSE;    t_CKBOOL load_hid = FALSE;    t_CKBOOL enable_server = TRUE;    t_CKBOOL do_watchdog = TRUE;    t_CKINT  adaptive_size = 0;    t_CKINT  log_level = CK_LOG_CORE;    t_CKINT  deprecate_level = 1; // 1 == warn    t_CKINT  chugin_load = 1; // 1 == auto (variable added 1.3.0.0)    // whether to make this new VM the one that receives OTF commands    t_CKBOOL update_otf_vm = TRUE;    string   filename = "";    vector<string> args;    char const *audioDriver = NULL;        // list of search pathes (added 1.3.0.0)    std::list<std::string> dl_search_path;    // initial chug-in path (added 1.3.0.0)    std::string initial_chugin_path;    // if set as environment variable (added 1.3.0.0)    if( getenv( g_chugin_path_envvar ) )    {        // get it from the env var        initial_chugin_path = getenv( g_chugin_path_envvar );    }    else    {

Lines 1–500 of 1158.

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