diff --git a/README.md b/README.md index 7361a3b..85f3b07 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,23 @@ Then, to receive OSC messages from within a Guile program: (do-stuff ...))) ``` -Or, to send messages (with parameters): - +If the separate server thread doesn't work for you, there's also a blocking +server option: + +``` +(use-modules (open-sound-control server)) + +(define s (make-osc-server "osc.udp://:7770")) + +(add-osc-method s ....) + +(osc-recv s) ;; Blocks for 1 second, or until a message is received +``` + +You can even have multiple blocking servers at once: `(osc-recv server1 server2)`. + +To send messages (with parameters): + ``` (use-modules (open-sound-control client)) diff --git a/guile-osc.c b/guile-osc.c index 84cb285..71122e1 100644 --- a/guile-osc.c +++ b/guile-osc.c @@ -27,6 +27,7 @@ static SCM osc_server_thread_type; +static SCM osc_server_type; static SCM osc_method_type; static SCM osc_address_type; @@ -59,6 +60,27 @@ static void finalize_osc_server_thread(SCM obj) } +static SCM make_osc_server(SCM url_obj) +{ + const char *url = scm_to_utf8_stringn(url_obj, NULL); + lo_server srv = lo_server_new_from_url(url, error_callback); + if ( srv == NULL ) { + return SCM_BOOL_F; + } else { + return scm_make_foreign_object_1(osc_server_type, srv); + } +} + + +static void finalize_osc_server(SCM obj) +{ + lo_server srv; + scm_assert_foreign_object_type(osc_server_type, obj); + srv = scm_foreign_object_ref(obj, 0); + lo_server_free(srv); +} + + static SCM make_osc_address(SCM url_obj) { lo_address addr; @@ -203,15 +225,11 @@ static int method_callback(const char *path, const char *types, lo_arg **argv, static SCM add_osc_method(SCM server_obj, SCM path_obj, SCM argtypes_obj, SCM proc) { - lo_server_thread srv; lo_method method; char *path; char *argtypes; struct method_callback_data *data; - scm_assert_foreign_object_type(osc_server_thread_type, server_obj); - srv = scm_foreign_object_ref(server_obj, 0); - argtypes = scm_to_utf8_stringn(argtypes_obj, NULL); data = malloc(sizeof(struct method_callback_data)); @@ -219,8 +237,28 @@ static SCM add_osc_method(SCM server_obj, SCM path_obj, SCM argtypes_obj, scm_gc_protect_object(proc); path = scm_to_utf8_stringn(path_obj, NULL); - method = lo_server_thread_add_method(srv, path, argtypes, - method_callback, data); + + if ( SCM_IS_A_P(server_obj, osc_server_thread_type) ) { + lo_server_thread srv; + srv = scm_foreign_object_ref(server_obj, 0); + method = lo_server_thread_add_method(srv, path, argtypes, + method_callback, data); + } else if ( SCM_IS_A_P(server_obj, osc_server_type) ) { + lo_server srv; + srv = scm_foreign_object_ref(server_obj, 0); + method = lo_server_add_method(srv, path, argtypes, + method_callback, data); + } else { + scm_error_scm(scm_from_utf8_symbol("argument-error"), + scm_from_locale_string("add-osc-method"), + scm_from_locale_string("Not an OSC server object"), + SCM_EOL, + SCM_BOOL_F); + free(path); + free(argtypes); + return SCM_UNSPECIFIED; + } + free(path); free(argtypes); @@ -228,6 +266,35 @@ static SCM add_osc_method(SCM server_obj, SCM path_obj, SCM argtypes_obj, } +static SCM osc_recv(SCM rest) +{ + int i; + int n_srv; + lo_server *servers; + int *rcv; + + SCM le = scm_length(rest); + n_srv = scm_to_int(le); + + servers = malloc(n_srv*sizeof(lo_server)); + rcv = malloc(n_srv*sizeof(int)); + if ( (servers == NULL) || (rcv == NULL) ) return SCM_UNSPECIFIED; + + for ( i=0; i +;; +;; This file is part of Guile-OSC. +;; +;; Guile-OSC 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 3 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, see . +;; +(define-module (open-sound-control server) + #:use-module (open-sound-control api) + #:re-export (make-osc-server + add-osc-method + osc-recv))