diff --git a/ports/chuck.hash b/ports/chuck.hash index c66b6ed..5ba5068 100644 --- a/ports/chuck.hash +++ b/ports/chuck.hash @@ -1 +1 @@ -416a1ffb4a3df426721b3b9397f79b77b966dee4 +2856c7d09ad0c66a73abbe3c5ee9c26b3c6afea5 diff --git a/ports/rtaudio.hash b/ports/rtaudio.hash index f274d6a..397efed 100644 --- a/ports/rtaudio.hash +++ b/ports/rtaudio.hash @@ -1 +1 @@ -29f078484fc78b073c45daabc0832ebf609d029d +a6c198729121ca06af9304670430b2959f7ffbbd diff --git a/ports/rtaudio.port b/ports/rtaudio.port index f229e72..8475591 100644 --- a/ports/rtaudio.port +++ b/ports/rtaudio.port @@ -4,9 +4,9 @@ DOWNLOADS := rtaudio.archive OWNER := ehmry REPO := rtaudio -REV := bde69fff7cf263552e27b33ca0db63e8c239e20e +REV := 4dc7017ccbae09231a4f8a48ac11a388171e95b3 URL(rtaudio) := https://github.com/$(OWNER)/$(REPO)/archive/$(REV).tar.gz -SHA(rtaudio) := e519e49d636818d2dcb95fc0fc3daf1e8c59704b +SHA(rtaudio) := 83414b09e48757d91f60fc936402501ec1a6bb8c DIR(rtaudio) := src/lib/rtaudio DIRS := include/RtAudio diff --git a/run/chuck.run b/run/chuck.run new file mode 100644 index 0000000..e5e1b30 --- /dev/null +++ b/run/chuck.run @@ -0,0 +1,131 @@ +assert_spec x86 + +# Xmllint throws errors on inline chuck code +proc check_xml_syntax {xml_file} { } + +# +# Build +# + +set build_components { + core init + app/chuck + drivers/audio + drivers/timer +} + +source ${genode_dir}/repos/base/run/platform_drv.inc +append_platform_drv_build_components + +build $build_components + +create_boot_directory + +# +# Config +# + +append config { + + + + + + + + + + + + + + + + + + + } + +append_platform_drv_config + +append config { + + + + + + + + + + + + +// another candidate for lamest demo + +// patch +SinOsc s => JCRev r => dac; +.5 => r.gain; +.075 => r.mix; + +// note number +20 => float note; + +// go up to 127 +while( note < 128 ) +{ + // convert MIDI note to hz + Std.mtof( note ) => s.freq; + // turn down the volume gradually + .5 - (note/256.0) => s.gain; + + // move up by whole step + note + 2 => note; + + // advance time + .125::second => now; +} + +// turn off s +0 => s.gain; +// wait a bit +2::second => now; + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# + +append boot_modules { + core init ld.lib.so + timer + chuck + libogg.lib.so + libFLAC.lib.so + libsndfile.lib.so + libvorbis.lib.so + pthread.lib.so + stdcxx.lib.so + libc.lib.so + libm.lib.so +} [audio_drv_binary] { +} + +append_platform_drv_boot_modules + +build_boot_image $boot_modules + +append qemu_args " -m 128 -nographic -soundhw es1370 " + +run_genode_until {child "chuck" exited with exit value 0} 60 diff --git a/run/chuck_keyboard.run b/run/chuck_keyboard.run new file mode 100644 index 0000000..0b20029 --- /dev/null +++ b/run/chuck_keyboard.run @@ -0,0 +1,193 @@ +assert_spec x86 + +# Xmllint throws errors on inline chuck code +proc check_xml_syntax {xml_file} { } + +# +# Build +# + +set build_components { + core init + app/chuck + drivers/audio + drivers/timer +} + +source ${genode_dir}/repos/base/run/platform_drv.inc +append_platform_drv_build_components + +lappend_if [have_spec ps2] build_components drivers/input/spec/ps2 +lappend_if [have_spec sdl] build_components drivers/framebuffer/spec/sdl + +build $build_components + +create_boot_directory + +# +# Config +# + +append config { + + + + + + + + + + + + + + + + + + + } + +append_platform_drv_config + +append_if [have_spec ps2] config { + + + + + + + + + + + + + + + } + +append_if [have_spec sdl] config { + + + + + + + + + + + + + } + +append config { + + + + + + + + + + + + +// HID +Hid hi; +HidMsg msg; + +// which keyboard +0 => int device; +// get from command line +if( me.args() ) me.arg(0) => Std.atoi => device; + +// open keyboard (get device number from command line) +if( !hi.openKeyboard( device ) ) me.exit(); +<<< "keyboard '" + hi.name() + "' ready", "" >>>; + +// patch +BeeThree organ => JCRev r => Echo e => Echo e2 => dac; +r => dac; + +// set delays +240::ms => e.max => e.delay; +480::ms => e2.max => e2.delay; +// set gains +.6 => e.gain; +.3 => e2.gain; +.05 => r.mix; +0 => organ.gain; + +// infinite event loop +while( true ) +{ + // wait for event + hi => now; + + // get message + while( hi.recv( msg ) ) + { + // check + if( msg.isButtonDown() ) + { + Std.mtof( msg.which + 45 ) => float freq; + if( freq > 20000 ) continue; + + freq => organ.freq; + .5 => organ.gain; + 1 => organ.noteOn; + + 80::ms => now; + } + else + { + 0 => organ.noteOff; + } + } +} + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# + +append boot_modules { + core init ld.lib.so + timer + chuck + libogg.lib.so + libFLAC.lib.so + libsndfile.lib.so + libvorbis.lib.so + pthread.lib.so + stdcxx.lib.so + libc.lib.so + libm.lib.so +} [audio_drv_binary] { +} + +lappend_if [have_spec ps2] boot_modules ps2_drv +lappend_if [have_spec sdl] boot_modules fb_sdl + +append_platform_drv_boot_modules + +build_boot_image $boot_modules + +append qemu_args " -m 128 -nographic -soundhw es1370 " + +run_genode_until forever diff --git a/run/chuck_mouse.run b/run/chuck_mouse.run new file mode 100644 index 0000000..8bc37e6 --- /dev/null +++ b/run/chuck_mouse.run @@ -0,0 +1,227 @@ +assert_spec x86 + +# Xmllint throws errors on inline chuck code +proc check_xml_syntax {xml_file} { } + +# +# Build +# + +set build_components { + core init + app/chuck + drivers/audio + drivers/timer +} + +source ${genode_dir}/repos/base/run/platform_drv.inc +append_platform_drv_build_components + +lappend_if [have_spec ps2] build_components drivers/input/spec/ps2 +lappend_if [have_spec sdl] build_components drivers/framebuffer/spec/sdl + +build $build_components + +create_boot_directory + +# +# Config +# + +append config { + + + + + + + + + + + + + + + + + + + } + +append_platform_drv_config + +append_if [have_spec ps2] config { + + + + + + + + + + + + + + + } + +append_if [have_spec sdl] config { + + + + + + + + + + + + + } + +append config { + + + + + + + + + + + + +// name: mouse-fm.ck +// desc: uses first X/Y axes of a mouse to control mf and index for FM +// author: Spencer Salazar + +// which mouse +0 => int device; +// get from command line +if( me.args() ) me.arg(0) => Std.atoi => device; + +// modulator to carrier +SinOsc m => SinOsc c => Envelope e => dac; + +// carrier frequency +220 => c.freq; +// modulator frequency +550 => m.freq; +// index of modulation +1000 => m.gain; + +// phase modulation is FM synthesis (sync is 2) +2 => c.sync; + +// attack +10::ms => e.duration; +.5 => e.gain; +// variables +int base; +float a0; +float a1; +float a2; +int count; + +// start things +set( base, a0, a1, a2 ); + +// hid objects +Hid hi; +HidMsg msg; + +// try +if( !hi.openMouse( device ) ) me.exit(); +<<< "mouse '" + hi.name() + "' ready...", "" >>>; + +// infinite time loop +while( true ) +{ + // wait on event + hi => now; + // loop over messages + while( hi.recv( msg ) ) + { + if( msg.isMouseMotion() ) + { + msg.deltaX * .001 + a0 => a0; + //else if( msg.which == 1 ) msg.fdata => a1; + msg.deltaY * .001 + a1 => a1; + set( base, a0, a1, a2 ); + } + + else if( msg.isButtonDown() ) + { + msg.which => base; + count++; + if( count == 1 ) e.keyOn(); + set( base, a0, a1, a2 ); + } + + else if( msg.isButtonUp() ) + { + msg.which => base; + count--; + if( !count ) e.keyOff(); + } + } +} + +// mapping function +fun void set( int base, float v0, float v1, float v2 ) +{ + // modulator frequency + ( 500 + 5*base + ( 500 * v0) ) => m.freq; + // carrier frequency + ( 220 + (220 * v2) ) => c.freq; + // index of modulation + ( 1000 * (v1+1) ) => m.gain; + <<< "carrier:", c.freq(), "modulator:", m.freq(), "index:", m.gain() >>>; +} + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# + +append boot_modules { + core init ld.lib.so + timer + chuck + libogg.lib.so + libFLAC.lib.so + libsndfile.lib.so + libvorbis.lib.so + pthread.lib.so + stdcxx.lib.so + libc.lib.so + libm.lib.so +} [audio_drv_binary] { +} + +lappend_if [have_spec ps2] boot_modules ps2_drv +lappend_if [have_spec sdl] boot_modules fb_sdl + +append_platform_drv_boot_modules + +build_boot_image $boot_modules + +append qemu_args " -m 128 -nographic -soundhw es1370 " + +run_genode_until forever diff --git a/src/app/chuck/component.cc b/src/app/chuck/component.cc index 23a4ac1..62c4b5b 100644 --- a/src/app/chuck/component.cc +++ b/src/app/chuck/component.cc @@ -43,6 +43,7 @@ #include "chuck_console.h" #include "chuck_globals.h" +#include "util_hid.h" #include "util_math.h" #include "util_string.h" #include "util_thread.h" @@ -57,13 +58,13 @@ struct Main : Chuck_System Attached_rom_dataspace config_rom { env, "config" }; - Timer::Connection timer; + Timer::Connection timer { env, "chuck" }; void load_config() { /* compile the config in sequence */ config_rom.xml().for_each_sub_node([&] (Xml_node const node) { - if (node.has_type("file")) + if (node.has_type("file")) { try { Xml_attribute path_attr = node.attribute("path"); std::string path(path_attr.value_base(), path_attr.value_size()); @@ -77,25 +78,27 @@ struct Main : Chuck_System else log("compiled ", path.c_str()); } catch (...) { - error("failed to parse file node"); + error("failed to parse file node ",node); } + } - else if (node.has_type("code")) + else if (node.has_type("code")) { try { - Xml_attribute path_attr = node.attribute("path"); std::string code(node.content_base(), node.content_size()); std::string args; if (node.has_attribute("args")) { Xml_attribute args_attr = node.attribute("args"); args = std::string(args_attr.value_base(), args_attr.value_size()); } - if (!compileCode(code, args)) + if (!compileCode(code, args)) { error("compilation failed"); - else + log(code.c_str()); + } else log("compiled ", code.c_str()); } catch (...) { error("failed to parse code node"); } + } }); } @@ -390,12 +393,16 @@ Main::Main(Genode::Env &env) : env(env) Genode::memset( input, 0, sizeof(SAMPLE)*buffer_size*adc_chans ); Genode::memset( output, 0, sizeof(SAMPLE)*buffer_size*dac_chans ); - //timer.sigh(timeout_handler); - //timer.trigger_periodic(100000); + timer.sigh(timeout_handler); + timer.trigger_periodic(100000); }; +#include -void Libc::Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { + init_rtaudio(env); + init_input(env); + static Main inst(env); } diff --git a/src/app/chuck/patch b/src/app/chuck/patch index c4fb77f..bc6359e 100644 --- a/src/app/chuck/patch +++ b/src/app/chuck/patch @@ -219,7 +219,7 @@ index e78b19d..ea349e8 100644 // // return FALSE; diff --git a/src/util_hid.cpp b/src/util_hid.cpp -index 9c26e2d..b66e87a 100644 +index 9c26e2d..aea2eb7 100644 --- a/src/util_hid.cpp +++ b/src/util_hid.cpp @@ -3725,7 +3725,7 @@ t_CKINT WiiRemote::disconnect() @@ -231,115 +231,138 @@ index 9c26e2d..b66e87a 100644 return 0; } -@@ -7679,6 +7679,122 @@ const char * Keyboard_name( int k ) +@@ -7679,6 +7679,145 @@ const char * Keyboard_name( int k ) return keyboards->at( k )->name; } +#elif defined(__PLATFORM_GENODE__) + ++#include +#include ++#include + -+static Genode::Signal_context g_input_sig_ctx; -+static Genode::Signal_receiver g_input_sig_rec; ++static Genode::Env *g_input_env; + -+static Input::Connection *g_input_session; ++void init_input(Genode::Env &env) ++{ ++ g_input_env = &env; ++} ++ ++Genode::Constructible g_input_session; + +static int g_input_count = 0; + -+void Genode_input_init() ++void Hid_init() +{ -+ if( g_input_session == nullptr ) try { -+ g_input_session = new Input::Connection; -+ g_input_session->sigh(g_input_sig_rec.manage(&g_input_sig_ctx)); -+ g_input_count = g_input_count < 1 ? 1 : g_input_count+1; -+ } catch ( ... ) { } ++ if ( !g_input_session.constructed() ) { ++ if ( !g_input_env ) { ++ Genode::error("platform input not initialized with 'init_input'"); ++ throw -1; ++ } ++ g_input_session.construct( *g_input_env ); ++ } ++ g_input_count = g_input_count < 1 ? 1 : g_input_count+1; +} + -+void Genode_input_quit() ++// A synchronous RPC poll ++void Hid_poll() +{ -+ if( --g_input_count > 0 ) { -+ delete g_input_session; -+ g_input_sig_rec.dissolve(&g_input_sig_ctx); -+ g_input_session = nullptr; -+ } ++ g_input_session->for_each_event( [&] ( Input::Event const &ev ) { ++ HidMsg msg; ++ ++ switch (ev.type()) { ++ case Input::Event::MOTION: ++ msg.device_type = CK_HID_DEV_MOUSE; ++ msg.type = CK_HID_MOUSE_MOTION; ++ msg.idata[0] = ev.ax(); ++ msg.idata[1] = ev.ay(); ++ break; ++ ++ case Input::Event::WHEEL: ++ msg.device_type = CK_HID_DEV_MOUSE; ++ msg.type = CK_HID_MOUSE_WHEEL; ++ msg.idata[0] = 0; ++ msg.idata[1] = ev.ry(); ++ break; ++ ++ case Input::Event::PRESS: ++ if (ev.code() == Input::BTN_MOUSE) ++ msg.device_type = CK_HID_DEV_MOUSE; ++ else ++ msg.device_type = CK_HID_DEV_KEYBOARD; ++ msg.type = CK_HID_BUTTON_DOWN; ++ msg.idata[1] = ev.code(); ++ msg.idata[2] = ev.utf8().b0; ++ break; ++ ++ case Input::Event::RELEASE: ++ if (ev.code() == Input::BTN_MOUSE) ++ msg.device_type = CK_HID_DEV_MOUSE; ++ else ++ msg.device_type = CK_HID_DEV_KEYBOARD; ++ msg.type = CK_HID_BUTTON_UP; ++ msg.idata[1] = ev.code(); ++ msg.idata[2] = ev.utf8().b0; ++ break; ++ ++ case Input::Event::FOCUS: ++ case Input::Event::LEAVE: ++ case Input::Event::TOUCH: ++ case Input::Event::INVALID: return; ++ } ++ ++ msg.eid = ev.code(); ++ ++ HidInManager::push_message( msg ); ++ }); +} + -+void Genode_input_poll() ++void Hid_quit() +{ -+ if ( !g_input_sig_rec.pending() ) -+ return; -+ do { g_input_sig_rec.wait_for_signal(); } -+ while ( g_input_sig_rec.pending() ); -+ -+ g_input_session->for_each_event( [&] ( Input::Event const &ev ) { -+ HidMsg msg; -+ -+ switch (ev.type()) { -+ case Input::Event::MOTION: -+ msg.device_type = CK_HID_DEV_MOUSE; -+ msg.type = CK_HID_MOUSE_MOTION; -+ msg.idata[0] = ev.ax(); -+ msg.idata[1] = ev.ay(); -+ break; -+ -+ case Input::Event::WHEEL: -+ msg.device_type = CK_HID_DEV_MOUSE; -+ msg.type = CK_HID_MOUSE_WHEEL; -+ msg.idata[1] = ev.ry(); -+ break; -+ -+ case Input::Event::PRESS: -+ case Input::Event::RELEASE: -+ case Input::Event::FOCUS: -+ case Input::Event::LEAVE: -+ case Input::Event::TOUCH: -+ case Input::Event::INVALID: return; -+ } -+ -+ HidInManager::push_message( msg ); -+ }); ++ if ( --g_input_count <= 0 && g_input_session.constructed() ) ++ g_input_session.destruct(); +} + -+void Hid_init() { } -+void Hid_poll() { } -+void Hid_quit() { } ++void Joystick_init() ++{ ++ Genode::warning("Genode joystick input not implemented"); ++} + -+void Joystick_init() { } +void Joystick_poll() { } +void Joystick_quit() { } +void Joystick_probe() { } -+int Joystick_count() { return -1; } ++int Joystick_count() { return 0; } +int Joystick_open( int js ) { return -1; } +int Joystick_open_async( int js ) { return -1; } +int Joystick_open( const char * name ) { return -1; } +int Joystick_close( int js ) { return -1; }; +int Joystick_send( int js, const HidMsg * msg ) { return -1; } -+const char * Joystick_name( int js ) { return ""; } ++const char * Joystick_name( int js ) { return "Genode Input session"; } + -+void Mouse_init() { Genode_input_init(); } -+ -+void Mouse_poll() { Genode_input_poll(); } -+ -+void Mouse_quit() { Genode_input_quit(); } ++void Mouse_init() { Hid_init(); } ++void Mouse_poll() { } ++void Mouse_quit() { Hid_quit(); } + +void Mouse_probe() { } -+int Mouse_count() { return ( g_input_session == nullptr ) ? 1 : -1; } -+int Mouse_open( int m ) { return ( g_input_session == nullptr ) ? 1 : -1; } -+int Mouse_open( const char * name ) { return ( g_input_session == nullptr ) ? 1 : -1; } ++int Mouse_count() { return g_input_session.constructed() ? 1 : 0; } ++int Mouse_open( int m ) { return g_input_session.constructed() ? 0 : -1; } ++int Mouse_open( const char * name ) { return g_input_session.constructed() ? 0 : -1; } +int Mouse_close( int m ) { return 0; } +int Mouse_send( int m, const HidMsg * msg ) { return -1; } -+const char * Mouse_name( int m ) { return ""; } ++const char * Mouse_name( int m ) { return "Genode Input session"; } +int Mouse_buttons( int m ) { return 0; } + -+void Keyboard_init() { } ++void Keyboard_init() { Hid_init(); } +void Keyboard_poll() { } -+void Keyboard_quit() { } ++void Keyboard_quit() { Hid_quit(); } +void Keyboard_probe() { } -+int Keyboard_count() { return -1; } -+int Keyboard_open( int kb ) { return -1; } -+int Keyboard_open( const char * name ) { return -1; } -+int Keyboard_close( int kb ) { return -1; } -+const char * Keyboard_name( int kb ) { return ""; } ++int Keyboard_count() { return g_input_session.constructed() ? 1 : 0; } ++ ++int Keyboard_open( int kb ) { return g_input_session.constructed() ? 0 : -1; } ++ ++int Keyboard_open( const char * name ) { return g_input_session.constructed() ? 0 : -1; } ++int Keyboard_close( int kb ) { return 0; } ++const char * Keyboard_name( int kb ) { return "Genode Input session"; } + +t_CKINT TiltSensor_setPollRate( t_CKINT usec ) +{ @@ -354,6 +377,33 @@ index 9c26e2d..b66e87a 100644 #endif +@@ -7735,7 +7874,7 @@ extern int Tablet_open( int ts ) { return -1; } + extern int Tablet_close( int ts ) { return -1; } + extern const char * Tablet_name( int ts ) { return NULL; } + +-#endif ++#endif // __PLATFORM_GENODE__ + + + #ifdef __CHIP_MODE__ +diff --git a/src/util_hid.h b/src/util_hid.h +index 7fa87d3..5527d90 100644 +--- a/src/util_hid.h ++++ b/src/util_hid.h +@@ -32,7 +32,13 @@ + #ifndef __UTIL_HID_H__ + #define __UTIL_HID_H__ + ++#ifdef __PLATFORM_GENODE__ + ++#include ++ ++void init_input(Genode::Env &env); ++ ++#endif // __PLATFORM_GENODE__ + + + //----------------------------------------------------------------------------- diff --git a/src/util_sndfile.h b/src/util_sndfile.h index 2a62fd7..a4f4f3b 100644 --- a/src/util_sndfile.h diff --git a/src/app/chuck/target.mk b/src/app/chuck/target.mk index f4cf9f0..444814e 100644 --- a/src/app/chuck/target.mk +++ b/src/app/chuck/target.mk @@ -1,6 +1,6 @@ TARGET := chuck -LIBS = stdcxx libc pthread rtaudio rtmidi liblo libsndfile base libogg libvorbis libFLAC +LIBS = stdcxx libc pthread rtaudio liblo libsndfile base libogg libvorbis libFLAC CHUCK_DIR = $(call select_from_ports,chuck)/src/app/chuck/src