@@ -2,6 +2,8 @@ mod midi_io;
2
2
mod osc_io;
3
3
4
4
use clap:: { Arg , Command } ;
5
+ use osc_io:: OscSender ;
6
+ use std:: io:: { self , BufRead } ;
5
7
use std:: str:: FromStr ;
6
8
use std:: net:: { SocketAddrV4 } ;
7
9
@@ -153,17 +155,14 @@ impl OscToMidi{
153
155
if OscToMidi :: verbose ( ) {
154
156
println ! ( "Ignored message on OSC address: {:?}" , msg. addr. as_str( ) ) ;
155
157
}
156
-
157
-
158
158
}
159
159
}
160
160
161
161
OscPacket :: Bundle ( bundle) => {
162
162
println ! ( "OSC Bundle: {:?}" , bundle) ;
163
163
}
164
164
}
165
-
166
- 0
165
+ return 0 ;
167
166
}
168
167
}
169
168
@@ -209,6 +208,66 @@ fn is_host_with_port(v: &str) -> Result<String,String>{
209
208
}
210
209
}
211
210
211
+ fn osc_send ( osc_target_host_address : & str , verbose : bool ) {
212
+
213
+ let stdin = io:: stdin ( ) ;
214
+
215
+ let osc_sender = OscSender :: new ( osc_target_host_address. to_string ( ) ) ;
216
+ for line in stdin. lock ( ) . lines ( ) {
217
+ let line = line. unwrap ( ) ; // Handle potential error
218
+ let mut tokens: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
219
+
220
+
221
+ // do not send empty messages
222
+ if tokens. len ( ) == 0 {
223
+ if verbose {
224
+ print ! ( "Empty message; nothing send\n " ) ;
225
+ }
226
+ continue ;
227
+ }
228
+
229
+ // else
230
+
231
+ // check if the first token is a valid osc method (starts with '/')
232
+ let osc_method = match tokens. get ( 0 ) {
233
+ Some ( v) => {
234
+ if v. starts_with ( '/' ) {
235
+ v. to_string ( )
236
+ } else {
237
+ format ! ( "/{}" , v)
238
+ }
239
+ } ,
240
+ None => {
241
+ println ! ( "No OSC method provided" ) ;
242
+ continue ;
243
+ }
244
+ } ;
245
+
246
+ // remove the first token
247
+ tokens. remove ( 0 ) ;
248
+
249
+ let mut osc_args: Vec < OscType > = Vec :: new ( ) ;
250
+
251
+ for token in tokens {
252
+ if let Ok ( int) = token. parse :: < i32 > ( ) {
253
+ osc_args. push ( OscType :: Int ( int) ) ;
254
+ } else if let Ok ( float) = token. parse :: < f32 > ( ) {
255
+ osc_args. push ( OscType :: Float ( float) ) ;
256
+ } else {
257
+ osc_args. push ( OscType :: String ( token. to_string ( ) ) ) ;
258
+ }
259
+ }
260
+
261
+ osc_sender. send ( osc_method. to_string ( ) , osc_args. clone ( ) ) ;
262
+
263
+ if verbose {
264
+ print ! ( "Sent OSC message to {} with args {:?}\n " , osc_target_host_address, osc_args) ;
265
+ }
266
+ }
267
+ }
268
+
269
+
270
+
212
271
fn main ( ) {
213
272
let matches = Command :: new ( "mot" )
214
273
. bin_name ( "mot" )
@@ -288,6 +347,16 @@ fn main() {
288
347
. help ( "the host:port to receive OSC data" )
289
348
. value_parser ( is_host_with_port) )
290
349
)
350
+ . subcommand ( Command :: new ( "osc_send" )
351
+ . about ( "Send OSC messages from STDIN. The first token of each line is the OSC method, the rest are the arguments. Only floats, ints and strings are converted to OSC types." )
352
+ . arg ( Arg :: new ( "verbose" )
353
+ . short ( 'v' )
354
+ . help ( "print verbose information" ) )
355
+ . arg ( Arg :: new ( "host:port" )
356
+ . default_value ( "127.0.0.1:1234" )
357
+ . help ( "the host:port to send OSC data to" )
358
+ . value_parser ( is_host_with_port) )
359
+ )
291
360
. subcommand ( Command :: new ( "midi_roundtrip_latency" )
292
361
. about ( "Test MIDI roundtrip latency" )
293
362
. arg ( Arg :: new ( "list" )
@@ -316,10 +385,16 @@ fn main() {
316
385
//let midi_input_index = usize::from_str(sub_matches.value_of("midi_input_index").unwrap()).unwrap();
317
386
if midi_io:: MidiIn :: check_midi_input_port_index ( midi_input_index) {
318
387
MidiEcho :: new ( midi_input_index) . echo_midi ( ) ;
319
- }
388
+ }
320
389
}
321
390
}
322
391
392
+ if let Some ( sub_matches) = matches. subcommand_matches ( "osc_send" ) {
393
+ let osc_target_host_address = sub_matches. get_one :: < String > ( "host:port" ) . unwrap ( ) ;
394
+ let verbose = sub_matches. value_source ( "verbose" ) == Some ( clap:: parser:: ValueSource :: CommandLine ) ;
395
+ osc_send ( osc_target_host_address, verbose) ;
396
+ }
397
+
323
398
if let Some ( sub_matches) = matches. subcommand_matches ( "midi_to_osc" ) {
324
399
if sub_matches. value_source ( "list" ) == Some ( clap:: parser:: ValueSource :: CommandLine ) {
325
400
midi_io:: MidiIn :: list_midi_input_ports ( ) ;
0 commit comments