diff -r 98974e3f5c1b src/chuck_compile.cpp --- a/src/chuck_compile.cpp Thu Oct 02 17:09:16 2008 -0400 +++ b/src/chuck_compile.cpp Thu Oct 02 17:33:43 2008 -0400 @@ -36,6 +36,7 @@ #include "chuck_otf.h" #include "ugen_osc.h" +#include "ugen_sfont.h" #include "ugen_xxx.h" #include "ugen_filter.h" #include "ugen_stk.h" @@ -527,6 +528,8 @@ t_CKBOOL load_internal_modules( Chuck_Co type_engine_load_context( env, context ); // load + EM_log( CK_LOG_SEVERE, "module sfont..." ); + load_module( env, sfont_query, "sfont", "global" ); EM_log( CK_LOG_SEVERE, "module osc..." ); load_module( env, osc_query, "osc", "global" ); EM_log( CK_LOG_SEVERE, "module xxx..." ); diff -r 98974e3f5c1b src/makefile.alsa --- a/src/makefile.alsa Thu Oct 02 17:09:16 2008 -0400 +++ b/src/makefile.alsa Thu Oct 02 17:33:43 2008 -0400 @@ -5,7 +5,7 @@ INCLUDES= INCLUDES= CFLAGS?= -O3 FLAGS= -D__LINUX_ALSA__ -c $(CFLAGS) -LIBS=-lasound -lstdc++ -ldl -lm +LIBS=-lasound -lstdc++ -ldl -lm -lfluidsynth SF_OBJ=util_sndfile.o ifneq ($(CHUCK_DEBUG),) @@ -30,11 +30,11 @@ OBJS= chuck.tab.o chuck.yy.o chuck_abs chuck_compile.o chuck_dl.o chuck_oo.o chuck_lang.o chuck_ugen.o \ chuck_main.o chuck_otf.o chuck_stats.o chuck_bbq.o chuck_shell.o \ chuck_console.o chuck_globals.o digiio_rtaudio.o hidio_sdl.o \ - midiio_rtmidi.o rtaudio.o rtmidi.o ugen_osc.o ugen_filter.o \ + midiio_rtmidi.o rtaudio.o rtmidi.o ugen_analysis.o ugen_sfont.o ugen_osc.o ugen_filter.o \ ugen_stk.o ugen_xxx.o ulib_machine.o ulib_math.o ulib_std.o \ ulib_opsc.o util_buffers.o util_console.o util_string.o util_thread.o \ util_opsc.o util_math.o util_network.o util_raw.o util_xforms.o \ - util_hid.o uana_xform.o uana_extract.o $(SF_OBJ) + util_hid.o $(SF_OBJ) chuck: $(OBJS) $(CXX) -o chuck $(OBJS) $(LIBS) @@ -141,6 +141,12 @@ rtmidi.o: rtmidi.h rtmidi.cpp rtmidi.o: rtmidi.h rtmidi.cpp $(CXX) $(FLAGS) rtmidi.cpp +ugen_analysis.o: ugen_analysis.h ugen_analysis.cpp + $(CXX) $(FLAGS) ugen_analysis.cpp + +ugen_sfont.o: ugen_sfont.h ugen_sfont.cpp + $(CXX) $(FLAGS) ugen_sfont.cpp + ugen_osc.o: ugen_osc.h ugen_osc.cpp $(CXX) $(FLAGS) ugen_osc.cpp @@ -198,11 +204,5 @@ util_sndfile.o: util_sndfile.h util_sndf util_sndfile.o: util_sndfile.h util_sndfile.c $(CC) $(FLAGS) util_sndfile.c -uana_xform.o: uana_xform.h uana_xform.cpp - $(CXX) $(FLAGS) uana_xform.cpp - -uana_extract.o: uana_extract.h uana_extract.cpp - $(CXX) $(FLAGS) uana_extract.cpp - clean: rm -f chuck *~ *.o chuck.output chuck.tab.h chuck.tab.c chuck.yy.c diff -r 98974e3f5c1b src/makefile.osx --- a/src/makefile.osx Thu Oct 02 17:09:16 2008 -0400 +++ b/src/makefile.osx Thu Oct 02 17:33:43 2008 -0400 @@ -6,7 +6,7 @@ INCLUDES= INCLUDES= FLAGS=-D__MACOSX_CORE__ -c LIBS=-framework CoreAudio -framework CoreMIDI -framework CoreFoundation \ - -framework IOKit -framework Carbon -lstdc++ -lm + -framework IOKit -framework Carbon -lstdc++ -lm -lfluidsynth SF_OBJ=util_sndfile.o ifneq ($(CHUCK_STAT),) @@ -37,7 +37,7 @@ OBJS= chuck.tab.o chuck.yy.o chuck_abs chuck_compile.o chuck_dl.o chuck_oo.o chuck_lang.o chuck_ugen.o \ chuck_main.o chuck_otf.o chuck_stats.o chuck_bbq.o chuck_shell.o \ chuck_console.o chuck_globals.o digiio_rtaudio.o hidio_sdl.o \ - midiio_rtmidi.o rtaudio.o rtmidi.o ugen_osc.o ugen_filter.o \ + midiio_rtmidi.o rtaudio.o rtmidi.o ugen_osc.o ugen_filter.o ugen_sfont.o \ ugen_stk.o ugen_xxx.o ulib_machine.o ulib_math.o ulib_std.o \ ulib_opsc.o util_buffers.o util_console.o util_math.o util_network.o \ util_raw.o util_string.o util_thread.o util_xforms.o util_opsc.o \ @@ -148,6 +148,9 @@ rtmidi.o: rtmidi.h rtmidi.cpp rtmidi.o: rtmidi.h rtmidi.cpp $(CXX) $(FLAGS) rtmidi.cpp +ugen_sfont.o: ugen_sfont.h ugen_sfont.cpp + $(CXX) $(FLAGS) ugen_sfont.cpp + ugen_osc.o: ugen_osc.h ugen_osc.cpp $(CXX) $(FLAGS) ugen_osc.cpp diff -r 98974e3f5c1b src/ugen_sfont.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ugen_sfont.cpp Thu Oct 02 17:33:43 2008 -0400 @@ -0,0 +1,1114 @@ +/*---------------------------------------------------------------------------- + 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.cs.princeton.edu/ + http://soundlab.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_sfont.cpp +// desc: SoundFont Unit Generators +// +// author: Kyle Super (ksuper@princeton.edu) +// date: Spring 2007 +//---------------------------------------------------------------------------- + +#include "ugen_sfont.h" +#include "chuck_type.h" +#include "util_math.h" +#include +#include +#include +#include + +static t_CKUINT g_srate = 0; +static t_CKUINT sfont_offset_data = 0; + +static float PI = (float)(4. * atan( 1. )); +static float TWOPI = (float)(8. * atan( 1. )); + +//---------------------------------------------------------------------------- +// name: sfont_query() +// desc: Setup SoundFont Unit Generators +//---------------------------------------------------------------------------- +DLL_QUERY sfont_query( Chuck_DL_Query * QUERY ) { + g_srate = QUERY->srate; + Chuck_Env * env = Chuck_Env::instance(); + Chuck_DL_Func * func = NULL; + type_engine_register_deprecate( env, "sfont", "SFont" ); + + //--------------------------------------------------------------------- + // init as base class: SFont + //--------------------------------------------------------------------- + if( !type_engine_import_ugen_begin( env, "SFont", "UGen", env->global(), + sfont_ctor, sfont_dtor, sfont_tick, NULL ) ) + return FALSE; + + // member variable + sfont_offset_data = type_engine_import_mvar( env, "int", "@sfont_data", FALSE ); + if( sfont_offset_data == CK_INVALID_OFFSET ) goto error; + + // add ctrl/cget: channel + func = make_new_mfun( "int", "channel", sfont_ctrl_channel ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "channel", sfont_cget_channel ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: freq + func = make_new_mfun( "float", "freq", sfont_ctrl_key ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "freq", sfont_cget_key ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: veloc + //func = make_new_mfun( "int", "veloc", sfont_ctrl_veloc ); + //func->add_arg( "int", "value" ); + //if( !type_engine_import_mfun( env, func ) ) goto error; + //func = make_new_mfun( "int", "veloc", sfont_cget_veloc ); + //if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: read + func = make_new_mfun( "string", "read", sfont_ctrl_read ); + func->add_arg( "string", "read" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: noteon + func = make_new_mfun( "float", "noteOn", sfont_ctrl_noteon ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: noteoff + func = make_new_mfun( "float", "noteOff", sfont_ctrl_noteoff ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: norm + func = make_new_mfun( "float", "norm", sfont_ctrl_norm ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "norm", sfont_cget_norm ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: midi_chan + func = make_new_mfun( "int", "midiChan", sfont_ctrl_midi_chan ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "midiChan", sfont_cget_midi_chan ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: reverb + func = make_new_mfun( "int", "reverb", sfont_ctrl_reverb ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "reverb", sfont_cget_reverb ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: chorus + func = make_new_mfun( "int", "chorus", sfont_ctrl_chorus ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "chorus", sfont_cget_chorus ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: interp + func = make_new_mfun( "int", "interp", sfont_ctrl_interp ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "interp", sfont_cget_interp ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: reverb_room + func = make_new_mfun( "float", "reverbRoom", sfont_ctrl_reverb_room ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "reverbRoom", sfont_cget_reverb_room ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: reverb_damp + func = make_new_mfun( "float", "reverbDamp", sfont_ctrl_reverb_damp ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "reverbDamp", sfont_cget_reverb_damp ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: reverb_width + func = make_new_mfun( "float", "reverbWidth", sfont_ctrl_reverb_width ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "reverbWidth", sfont_cget_reverb_width ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: reverb_level + func = make_new_mfun( "float", "reverbLevel", sfont_ctrl_reverb_level ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "reverbLevel", sfont_cget_reverb_level ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: chorus_delay + func = make_new_mfun( "int", "chorusDelay", sfont_ctrl_chorus_delay ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "chorusDelay", sfont_cget_chorus_delay ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: chorus_level + func = make_new_mfun( "float", "chorusLevel", sfont_ctrl_chorus_level ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "chorusLevel", sfont_cget_chorus_level ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: chorus_speed + func = make_new_mfun( "float", "chorusSpeed", sfont_ctrl_chorus_speed ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "chorusSpeed", sfont_cget_chorus_speed ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: chorus_depth + func = make_new_mfun( "float", "chorusDepth", sfont_ctrl_chorus_depth ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "chorusDepth", sfont_cget_chorus_depth ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: chorus_type + func = make_new_mfun( "int", "chorusType", sfont_ctrl_chorus_type ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "chorusType", sfont_cget_chorus_type ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: midi + func = make_new_mfun( "string", "midiRead", sfont_ctrl_midi ); + func->add_arg( "string", "read" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: midi_play + func = make_new_mfun( "void", "midiPlay", sfont_ctrl_midi_play ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: midi_stop + func = make_new_mfun( "void", "midiStop", sfont_ctrl_midi_stop ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: midi_bpm + func = make_new_mfun( "int", "midiBPM", sfont_ctrl_midi_bpm ); + func->add_arg( "int", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "int", "midiBPM", sfont_cget_midi_bpm ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: cc + func = make_new_mfun( "void", "controlChange", sfont_ctrl_cc ); + func->add_arg( "int", "ctrl" ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: pbend + func = make_new_mfun( "void", "pbend", sfont_ctrl_pbend ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: wheel + func = make_new_mfun( "void", "wheel", sfont_ctrl_wheel ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: program + func = make_new_mfun( "void", "program", sfont_ctrl_program ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: bank + func = make_new_mfun( "void", "bank", sfont_ctrl_bank ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl: reset + func = make_new_mfun( "void", "reset", sfont_ctrl_reset ); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // add ctrl/cget: pan + func = make_new_mfun( "float", "pan", sfont_ctrl_pan ); + func->add_arg( "float", "value" ); + if( !type_engine_import_mfun( env, func ) ) goto error; + func = make_new_mfun( "float", "pan", sfont_cget_pan); + if( !type_engine_import_mfun( env, func ) ) goto error; + + // end the class import + if( !type_engine_import_class_end( env ) ) + return FALSE; + + // end class imports + return TRUE; +error: + type_engine_import_class_end( env ); + return FALSE; +} + +//---------------------------------------------------------------------------- +// name: sfont +// desc: SoundFont Unit Generator +//---------------------------------------------------------------------------- +struct sfont_data { + + // declarations + fluid_settings_t * settings; + fluid_synth_t * synth; + fluid_player_t * player; + int channel, id, midi_chan, reverb, chorus, interp, chorus_n, chorus_t, bpm; + bool init, read, midi; + double gain, reverb_r, reverb_d, reverb_w, reverb_l, chorus_l, chorus_s, chorus_d, pan, key; + + // constructor + sfont_data() { + settings = NULL; + synth = NULL; + player = NULL; + channel = 0; + id = 0; + midi_chan = 16; + reverb = 1; + chorus = 1; + interp = 2; + chorus_n = 3; + chorus_t = 0; + bpm = 125; + init = false; + read = false; + midi = false; + gain = 0.2; + reverb_r = 0.2; + reverb_d = 0.0; + reverb_w = 0.5; + reverb_l = 0.9; + chorus_l = 2.0; + chorus_s = 0.3; + chorus_d = 8.0; + pan = 0.0; + key = 0.0; + } +}; + +//---------------------------------------------------------------------------- +// name: sfont_ctor() +// desc: Create SoundFont Data +//---------------------------------------------------------------------------- +CK_DLL_CTOR( sfont_ctor ) { + sfont_data * d = new sfont_data; + OBJ_MEMBER_UINT( SELF, sfont_offset_data ) = (t_CKUINT)d; +} + +//---------------------------------------------------------------------------- +// name: sfont_dtor() +// desc: Destroy SoundFont Data +//---------------------------------------------------------------------------- +CK_DLL_DTOR( sfont_dtor ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + + // delete data structures + if( d->synth != NULL ) { + delete_fluid_synth( d->synth ); + d->synth = NULL; + } + if( d->settings != NULL ) { + delete_fluid_settings( d->settings ); + d->settings = NULL; + } + if( d->player != NULL ) { + delete_fluid_player( d->player ); + d->player = NULL; + } + delete (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); +} + +//---------------------------------------------------------------------------- +// name: fluid_synth_init +// desc: Initialize FluidSynth +//---------------------------------------------------------------------------- +static void fluid_synth_init( sfont_data * d ) { + + // delete prior data structures + d->init = false; + if( d->synth != NULL ) { + delete_fluid_synth( d->synth ); + d->synth = NULL; + } + if( d->settings != NULL ) { + delete_fluid_settings( d->settings ); + d->settings = NULL; + } + + // create new data structures + d->settings = new_fluid_settings(); + if( d->settings == NULL ) { + fprintf( stderr, "[chuck](via sfont): Failed to create the settings\n" ); + exit(-1); + } + d->synth = new_fluid_synth( d->settings ); + if( d->synth == NULL ) { + fprintf( stderr, "[chuck](via sfont): Failed to create the synthesizer\n" ); + exit(-1); + } + d->init = true; + + // set various settings + fluid_settings_setnum( d->settings, "synth.sample-rate", g_srate ); + fluid_settings_setnum( d->settings, "synth.gain", d->gain ); + fluid_settings_getnum( d->settings, "synth.gain", &(d->gain) ); + fluid_settings_setint( d->settings, "synth.midi-channels", d->midi_chan ); + fluid_settings_getint( d->settings, "synth.midi-channels", &(d->midi_chan) ); + if( d->reverb ) + fluid_settings_setstr( d->settings, "synth.reverb.active", "yes" ); + else + fluid_settings_setstr( d->settings, "synth.reverb.active", "no" ); + if( d->chorus ) + fluid_settings_setstr( d->settings, "synth.chorus.active", "yes" ); + else + fluid_settings_setstr( d->settings, "synth.chorus.active", "no" ); + if( d->interp == 0 ) + fluid_synth_set_interp_method( d->synth, -1, 0 ); + else if( d->interp == 1 ) + fluid_synth_set_interp_method( d->synth, -1, 1 ); + else if( d->interp == 2 ) + fluid_synth_set_interp_method( d->synth, -1, 4 ); + else + fluid_synth_set_interp_method( d->synth, -1, 7 ); + fluid_synth_set_reverb( d->synth, d->reverb_r, d->reverb_d, d->reverb_w, d->reverb_l ); + fluid_synth_set_chorus( d->synth, d->chorus_n, d->chorus_l, d->chorus_s, d->chorus_d, d->chorus_t ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_channel() +// desc: Set Note Channel +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_channel ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT channel = GET_CK_INT( ARGS ); + d->channel = channel; + RETURN->v_int = d->channel; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_channel() +// desc: Get Note Channel +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_channel ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->channel; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_key() +// desc: Set Note Key +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_key ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + float key = GET_CK_FLOAT( ARGS ); + d->key = key; + RETURN->v_float = d->key; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_key() +// desc: Get Note Key +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_key ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->key; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_veloc() +// desc: Set Note Velocity +//---------------------------------------------------------------------------- +//CK_DLL_CTRL( sfont_ctrl_veloc ) { +// sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); +// t_CKINT velocity = GET_CK_INT( ARGS ); +// d->velocity = velocity; +// RETURN->v_int = d->velocity; +//} + +//---------------------------------------------------------------------------- +// name: sfont_cget_veloc() +// desc: Get Note Velocity +//---------------------------------------------------------------------------- +//CK_DLL_CTRL( sfont_cget_veloc ) { +// sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); +// RETURN->v_int = d->velocity; +//} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_norm() +// desc: Set Gain Factor +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_norm ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double gain = GET_CK_FLOAT( ARGS ); + if( gain < 0.0 || gain > 10.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper gain value\n" ); + } else { + if( d->init ) { + fluid_settings_setnum( d->settings, "synth.gain", gain ); + fluid_settings_getnum( d->settings, "synth.gain", &(d->gain) ); + } else { + d->gain = gain; + } + } + RETURN->v_float = d->gain; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_norm() +// desc: Get Gain Factor +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_norm ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->gain; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_midi_chan() +// desc: Set Midi Channels +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_midi_chan ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT midi_chan = GET_CK_INT( ARGS ); + if( midi_chan < 16 || midi_chan > 256 ) { + fprintf( stderr, "[chuck](via sfont): Improper number of midi channels\n" ); + } else { + if( d->init ) { + fluid_settings_setint( d->settings, "synth.midi-channels", midi_chan ); + fluid_settings_getint( d->settings, "synth.midi-channels", &(d->midi_chan) ); + } else { + d->midi_chan = midi_chan; + } + } + RETURN->v_int = d->midi_chan; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_midi_chan() +// desc: Get Midi Channels +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_midi_chan ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->midi_chan; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_reverb +// desc: Set Reverb +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_reverb ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT reverb = GET_CK_INT( ARGS ); + if( reverb < 0 || reverb > 1 ) { + fprintf( stderr, "[chuck](via sfont): Improper reverb value\n" ); + } else { + if( d->init ) { + if( reverb ) + fluid_settings_setstr( d->settings, "synth.reverb.active", "yes" ); + else + fluid_settings_setstr( d->settings, "synth.reverb.active", "no" ); + } + d->reverb = reverb; + } + RETURN->v_int = d->reverb; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_reverb() +// desc: Get Reverb +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_reverb ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->reverb; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_chorus +// desc: Set Chorus +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_chorus ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT chorus = GET_CK_INT( ARGS ); + if( chorus < 0 || chorus > 1 ) { + fprintf( stderr, "[chuck](via sfont): Improper chorus value\n" ); + } else { + if( d->init ) { + if( chorus ) + fluid_settings_setstr( d->settings, "synth.chorus.active", "yes" ); + else + fluid_settings_setstr( d->settings, "synth.chorus.active", "no" ); + } + d->chorus = chorus; + } + RETURN->v_int = d->chorus; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_chorus() +// desc: Get Chorus +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_chorus ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->chorus; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_interp +// desc: Set Interp Method +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_interp ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT interp = GET_CK_INT( ARGS ); + if( interp < 0 || interp > 3 ) { + fprintf( stderr, "[chuck](via sfont): Improper interp method\n" ); + } else { + if( d->init ) { + if( interp == 0 ) + fluid_synth_set_interp_method( d->synth, -1, 0 ); + else if( interp == 1 ) + fluid_synth_set_interp_method( d->synth, -1, 1 ); + else if( interp == 2 ) + fluid_synth_set_interp_method( d->synth, -1, 4 ); + else + fluid_synth_set_interp_method( d->synth, -1, 7 ); + } + d->interp = interp; + } + RETURN->v_int = d->interp; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_interp() +// desc: Get Interp Method +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_interp ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->interp; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_reverb_room() +// desc: Set Reverb Room Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_reverb_room ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < 0.0 || val > 1.2 ) { + fprintf( stderr, "[chuck](via sfont): Improper room value\n" ); + } else { + d->reverb_r = val; + if( d->init ) + fluid_synth_set_reverb( d->synth, d->reverb_r, d->reverb_d, d->reverb_w, d->reverb_l ); + } + RETURN->v_float = d->reverb_r; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_reverb_room +// desc: Get Reverb Room Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_reverb_room ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->reverb_r; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_reverb_damp() +// desc: Set Reverb Damp Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_reverb_damp ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < 0.0 || val > 1.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper damp value\n" ); + } else { + d->reverb_d = val; + if( d->init ) + fluid_synth_set_reverb( d->synth, d->reverb_r, d->reverb_d, d->reverb_w, d->reverb_l ); + } + RETURN->v_float = d->reverb_d; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_reverb_damp +// desc: Get Reverb damp Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_reverb_damp ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->reverb_d; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_reverb_width() +// desc: Set Reverb Width Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_reverb_width ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < 0.0 || val > 100.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper width value\n" ); + } else { + d->reverb_w = val; + if( d->init ) + fluid_synth_set_reverb( d->synth, d->reverb_r, d->reverb_d, d->reverb_w, d->reverb_l ); + } + RETURN->v_float = d->reverb_w; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_reverb_width +// desc: Get Reverb Width Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_reverb_width ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->reverb_w; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_reverb_level() +// desc: Set Reverb Level Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_reverb_level ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < -30.0 || val > 30.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper reverb level value\n" ); + } else { + d->reverb_l = val; + if( d->init ) + fluid_synth_set_reverb( d->synth, d->reverb_r, d->reverb_d, d->reverb_w, d->reverb_l ); + } + RETURN->v_float = d->reverb_l; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_reverb_level +// desc: Get Reverb Level Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_reverb_level ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->reverb_l; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_chorus_delay +// desc: Set Chorus Delay +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_chorus_delay ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT val = GET_CK_INT( ARGS ); + if( val < 0 || val > 99 ) { + fprintf( stderr, "[chuck](via sfont): Improper chorus delay value\n" ); + } else { + d->chorus_n = val; + if( d->init ) + fluid_synth_set_chorus( d->synth, d->chorus_n, d->chorus_l, d->chorus_s, d->chorus_d, d->chorus_t ); + } + RETURN->v_int = d->chorus_n; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_chorus_delay() +// desc: Get Chorus Delay +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_chorus_delay ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->chorus_n; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_chorus_level() +// desc: Set Chorus Level Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_chorus_level ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < 0.0 || val > 10.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper chorus level value\n" ); + } else { + d->chorus_l = val; + if( d->init ) + fluid_synth_set_chorus( d->synth, d->chorus_n, d->chorus_l, d->chorus_s, d->chorus_d, d->chorus_t ); + } + RETURN->v_float = d->chorus_l; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_chorus_level +// desc: Get Chorus Level Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_chorus_level ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->chorus_l; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_chorus_speed() +// desc: Set Chorus Speed Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_chorus_speed ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < 0.29 || val > 5.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper chorus speed value\n" ); + } else { + d->chorus_s = val; + if( d->init ) + fluid_synth_set_chorus( d->synth, d->chorus_n, d->chorus_l, d->chorus_s, d->chorus_d, d->chorus_t ); + } + RETURN->v_float = d->chorus_s; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_chorus_speed() +// desc: Get Chorus Speed Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_chorus_speed ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->chorus_s; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_chorus_depth() +// desc: Set Chorus Depth Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_chorus_depth ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double val = GET_CK_FLOAT( ARGS ); + if( val < 0.0 || val > 46.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper chorus depth value\n" ); + } else { + d->chorus_d = val; + if( d->init ) + fluid_synth_set_chorus( d->synth, d->chorus_n, d->chorus_l, d->chorus_s, d->chorus_d, d->chorus_t ); + } + RETURN->v_float = d->chorus_d; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_chorus_depth +// desc: Get Chorus Depth Size +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_chorus_depth ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->chorus_d; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_chorus_type +// desc: Set Chorus Type +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_chorus_type ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT val = GET_CK_INT( ARGS ); + if( val < 0 || val > 1 ) { + fprintf( stderr, "[chuck](via sfont): Improper chorus type value\n" ); + } else { + d->chorus_t = val; + if( d->init ) + fluid_synth_set_chorus( d->synth, d->chorus_n, d->chorus_l, d->chorus_s, d->chorus_d, d->chorus_t ); + } + RETURN->v_int = d->chorus_t; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_chorus_type() +// desc: Get Chorus Type +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_chorus_type ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->chorus_t; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_read() +// desc: Read SoundFont File +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_read ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + const char * filename = GET_CK_STRING( ARGS )->str.c_str(); + + // initialize data structures + if( !d->init ) + fluid_synth_init( d ); + + // delete prior data + if( fluid_synth_sfcount( d->synth ) ) { + if( fluid_synth_sfunload( d->synth, d->id, true ) == -1 ) { + fprintf( stderr, "[chuck](via sfont): Unable to unload soundfont\n" ); + return; + } + } + d->read = false; + + // load new soundfont + if( fluid_is_soundfont( (char *)filename ) ) { + d->id = fluid_synth_sfload( d->synth, filename, true ); + if( d->id == -1 ) { + fprintf( stderr, "[chuck](via sfont): Unable to load soundfont\n" ); + return; + } + } else { + fprintf( stderr, "[chuck](via sfont): Not a soundfont file\n" ); + return; + } + d->read = true; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_noteon() +// desc: Turn Note On +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_noteon ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + float val = GET_CK_FLOAT( ARGS ); + if( d->init && d->read ) + fluid_synth_noteon( d->synth, d->channel, ftom( d->key ), val ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_noteoff() +// desc: Turn Note Off +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_noteoff ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->init && d->read ) + fluid_synth_noteoff( d->synth, d->channel, ftom( d->key ) ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_midi() +// desc: Read midi File +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_midi ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + const char * filename = GET_CK_STRING( ARGS )->str.c_str(); + + // delete prior data + if( d->player != NULL ) { + delete_fluid_player( d->player ); + d->player = NULL; + } + d->midi = false; + + // check prereqs + if( !d->init ) { + fprintf( stderr, "[chuck](via sfont): Load SoundFont first\n" ); + return; + } + + // load new midi player + if( fluid_is_midifile( (char *)filename ) ) { + d->player = new_fluid_player( d->synth ); + if( d->player == NULL ) { + fprintf( stderr, "[chuck](via sfont): Error creating midi player\n" ); + return; + } + fluid_player_add( d->player, (char *)filename ); + } else { + fprintf( stderr, "[chuck](via sfont): Not a midi file\n" ); + return; + } + d->midi = true; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_midi_play() +// desc: Turn Midi On +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_midi_play ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->midi ) + fluid_player_play( d->player ); + else + fprintf( stderr, "[chuck](via sfont): Load midi file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_midi_stop() +// desc: Turn Midi Off +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_midi_stop ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->midi ) { + delete_fluid_player( d->player ); + d->player = NULL; + d->midi = false; + for( int i = 0; i < d->midi_chan; i++ ) + fluid_synth_cc( d->synth, i, 123, 0 ); + } else + fprintf( stderr, "[chuck](via sfont): Load midi file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_midi_bpm +// desc: Set Midi bpm +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_midi_bpm ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT val = GET_CK_INT( ARGS ); + if( val < 0 ) { + fprintf( stderr, "[chuck](via sfont): Improper midi bpm value\n" ); + } else { + d->bpm = val; + if( d->player ) + fluid_player_set_bpm( d->player, d->bpm ); + } + RETURN->v_int = d->bpm; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_midi_bpm() +// desc: Get Midi bpm +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_midi_bpm ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_int = d->bpm; +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_cc +// desc: Control Change +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_cc ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + t_CKINT i = GET_NEXT_INT(ARGS); + t_CKFLOAT f = GET_NEXT_FLOAT(ARGS); + if( d->init && d->read ) + fluid_synth_cc( d->synth, d->channel, i, f ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_pbend +// desc: Control Pitch Bend +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_pbend ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->init && d->read ) + fluid_synth_pitch_bend( d->synth, d->channel, ftom( d->key ) ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_wheel +// desc: Control Wheel Sensitivity +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_wheel ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->init && d->read ) + fluid_synth_pitch_wheel_sens( d->synth, d->channel, ftom( d->key ) ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_program +// desc: Program Change +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_program ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->init && d->read ) + fluid_synth_program_change( d->synth, d->channel, ftom( d->key ) ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_bank +// desc: Bank Select +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_bank ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->init && d->read ) + fluid_synth_bank_select( d->synth, d->channel, ftom( d->key ) ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_reset +// desc: Reset Patches +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_reset ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + if( d->init && d->read ) + fluid_synth_system_reset( d->synth ); + else + fprintf( stderr, "[chuck](via sfont): Load SoundFont file first\n" ); +} + +//---------------------------------------------------------------------------- +// name: sfont_ctrl_pan() +// desc: Set Pan Factor +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_ctrl_pan ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + double pan = GET_CK_FLOAT( ARGS ); + if( pan < -1.0 || pan > 1.0 ) { + fprintf( stderr, "[chuck](via sfont): Improper pan value\n" ); + } else { + d->pan = pan; + } + RETURN->v_float = d->pan; +} + +//---------------------------------------------------------------------------- +// name: sfont_cget_pan() +// desc: Get Pan Factor +//---------------------------------------------------------------------------- +CK_DLL_CTRL( sfont_cget_pan ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + RETURN->v_float = d->pan; +} + +//---------------------------------------------------------------------------- +// name: sfont_tick() +// desc: Return Samples +//---------------------------------------------------------------------------- +CK_DLL_TICK( sfont_tick ) { + sfont_data * d = (sfont_data *)OBJ_MEMBER_UINT( SELF, sfont_offset_data ); + + // generate audio samples + SAMPLE lsample = 0.0; + SAMPLE rsample = 0.0; + if( d->init && d->read ) { + if( fluid_synth_write_float( d->synth, 1, &lsample, 0, 0, &rsample, 0, 0 ) ) { + fprintf( stderr, "[chuck](via sfont): Error creating audio samples\n" ); + lsample = 0.0; + rsample = 0.0; + } + } + + // return audio samples + double p = (d->pan + 1.0) / 2.0; + *out = ((1-p)*lsample + p*rsample); + return TRUE; +} diff -r 98974e3f5c1b src/ugen_sfont.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ugen_sfont.h Thu Oct 02 17:33:43 2008 -0400 @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------- + 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.cs.princeton.edu/ + http://soundlab.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_sfont.h +// desc: ... +// +// author: Kyle Super (ksuper@princeton.edu) +// date: Spring 2007 +//---------------------------------------------------------------------------- + +#ifndef __UGEN_SFONT_H__ +#define __UGEN_SFONT_H__ + +#include "chuck_dl.h" + +// query +DLL_QUERY sfont_query( Chuck_DL_Query * QUERY ); + +// sfont +CK_DLL_CTOR( sfont_ctor ); +CK_DLL_DTOR( sfont_dtor ); +CK_DLL_CTRL( sfont_ctrl_channel ); +CK_DLL_CTRL( sfont_cget_channel ); +CK_DLL_CTRL( sfont_ctrl_key ); +CK_DLL_CTRL( sfont_cget_key ); +//CK_DLL_CTRL( sfont_ctrl_veloc ); +//CK_DLL_CTRL( sfont_cget_veloc ); +CK_DLL_CTRL( sfont_ctrl_read ); +CK_DLL_CTRL( sfont_ctrl_noteon ); +CK_DLL_CTRL( sfont_ctrl_noteoff ); +CK_DLL_CTRL( sfont_ctrl_norm ); +CK_DLL_CTRL( sfont_cget_norm ); +CK_DLL_CTRL( sfont_ctrl_midi_chan ); +CK_DLL_CTRL( sfont_cget_midi_chan ); +CK_DLL_CTRL( sfont_ctrl_reverb ); +CK_DLL_CTRL( sfont_cget_reverb ); +CK_DLL_CTRL( sfont_ctrl_chorus ); +CK_DLL_CTRL( sfont_cget_chorus ); +CK_DLL_CTRL( sfont_ctrl_interp ); +CK_DLL_CTRL( sfont_cget_interp ); +CK_DLL_CTRL( sfont_ctrl_reverb_room ); +CK_DLL_CTRL( sfont_cget_reverb_room ); +CK_DLL_CTRL( sfont_ctrl_reverb_damp ); +CK_DLL_CTRL( sfont_cget_reverb_damp ); +CK_DLL_CTRL( sfont_ctrl_reverb_width ); +CK_DLL_CTRL( sfont_cget_reverb_width ); +CK_DLL_CTRL( sfont_ctrl_reverb_level ); +CK_DLL_CTRL( sfont_cget_reverb_level ); +CK_DLL_CTRL( sfont_ctrl_chorus_delay ); +CK_DLL_CTRL( sfont_cget_chorus_delay ); +CK_DLL_CTRL( sfont_ctrl_chorus_level ); +CK_DLL_CTRL( sfont_cget_chorus_level ); +CK_DLL_CTRL( sfont_ctrl_chorus_speed ); +CK_DLL_CTRL( sfont_cget_chorus_speed ); +CK_DLL_CTRL( sfont_ctrl_chorus_depth ); +CK_DLL_CTRL( sfont_cget_chorus_depth ); +CK_DLL_CTRL( sfont_ctrl_chorus_type ); +CK_DLL_CTRL( sfont_cget_chorus_type ); +CK_DLL_CTRL( sfont_ctrl_midi ); +CK_DLL_CTRL( sfont_ctrl_midi_play ); +CK_DLL_CTRL( sfont_ctrl_midi_stop ); +CK_DLL_CTRL( sfont_ctrl_midi_bpm ); +CK_DLL_CTRL( sfont_cget_midi_bpm ); +CK_DLL_CTRL( sfont_ctrl_cc ); +CK_DLL_CTRL( sfont_ctrl_pbend ); +CK_DLL_CTRL( sfont_ctrl_wheel ); +CK_DLL_CTRL( sfont_ctrl_program ); +CK_DLL_CTRL( sfont_ctrl_bank ); +CK_DLL_CTRL( sfont_ctrl_reset ); +CK_DLL_CTRL( sfont_ctrl_pan ); +CK_DLL_CTRL( sfont_cget_pan ); +CK_DLL_TICK( sfont_tick ); + +#endif