@@ -68,20 +68,6 @@ float atoff(const char *s) {
6868 int16_t: atoi \
6969)
7070
71- #define PARSE_VAL_TO_SEP (type ) \
72- int parse_val_to_sep_##type(char *message, type *val, char sep) { \
73- int c = 0; \
74- *val = PARSE_LIST_ATO(*val)(message); \
75- c = strspn(message, PARSE_LIST_STRSPN2(*val)); \
76- if (message[c] == sep) { \
77- return c + 1; \
78- } \
79- return -1; \
80- }
81-
82- PARSE_VAL_TO_SEP (float )
83- PARSE_VAL_TO_SEP (int32_t )
84-
8571#define PARSE_LIST (type ) \
8672 int parse_list_##type(char *message, type *vals, int max_num_vals, type skipped_val) { \
8773 uint16_t c = 0, last_c; \
@@ -118,6 +104,17 @@ PARSE_LIST(int32_t)
118104PARSE_LIST (int16_t )
119105
120106
107+ #define PARSE_VAL (type ) \
108+ int parse_val_##type(char *message, type *val) { \
109+ int c = 0; \
110+ *val = PARSE_LIST_ATO(*val)(message); \
111+ c = strspn(message, PARSE_LIST_STRSPN2(*val)); \
112+ return c; \
113+ }
114+
115+ PARSE_VAL (float )
116+ PARSE_VAL (int32_t )
117+
121118char * copy_with_trim (char * dest , size_t dest_len , const char * src , size_t src_len ) {
122119 // Copy a string while trimming leading and trailing spaces.
123120 const char * s = src ;
@@ -310,18 +307,17 @@ extern const mp_obj_fun_builtin_var_t tulip_pcm_load_file_obj;
310307#endif
311308
312309int parse_midi_cc_payload (char * message , int32_t * p_cc_code , int32_t * p_is_log , float * p_min_val , float * p_max_val , float * p_offset_val ) {
313- int c ;
314310 char * m = message ;
315- if (( c = parse_val_to_sep_int32_t (m , p_cc_code , ',' )) < 0 ) return -1 ;
316- m += c ;
317- if (( c = parse_val_to_sep_int32_t (m , p_is_log , ',' )) < 0 ) return -1 ;
318- m += c ;
319- if (( c = parse_val_to_sep_float (m , p_min_val , ',' )) < 0 ) return -1 ;
320- m += c ;
321- if (( c = parse_val_to_sep_float (m , p_max_val , ',' )) < 0 ) return -1 ;
322- m += c ;
323- if (( c = parse_val_to_sep_float (m , p_offset_val , ',' )) < 0 ) return -1 ;
324- m += c ;
311+ m += parse_val_int32_t (m , p_cc_code ) ;
312+ if ( m [ 0 ] != ',' ) goto end ; else ++ m ;
313+ m += parse_val_int32_t (m , p_is_log ) ;
314+ if ( m [ 0 ] != ',' ) goto end ; else ++ m ;
315+ m += parse_val_float (m , p_min_val ) ;
316+ if ( m [ 0 ] != ',' ) goto end ; else ++ m ;
317+ m += parse_val_float (m , p_max_val ) ;
318+ if ( m [ 0 ] != ',' ) goto end ; else ++ m ;
319+ m += parse_val_float (m , p_offset_val ) ;
320+ end :
325321 return m - message ;
326322}
327323
@@ -345,20 +341,24 @@ int amy_parse_synth_layer_message(char *message, amy_event *e) {
345341 else if (cmd == 'c' ) {
346342 // MIDI CC mapping ic<C>,<L>,<N>,<X>,<O>,<CODE>, see https://github.com/shorepine/amy/issues/524
347343 // ic255 clears all MIDI CC mappings for this synth (short form, no extra fields needed).
348- if ( atoi ( message ) == 255 ) {
349- midi_clear_channel_mappings ( e -> synth ) ;
350- skip_chars = strlen ( message ) + 1 ;
351- } else {
352- int32_t cc_code , is_log ;
353- float min_val , max_val , offset_val ;
354- skip_chars = parse_midi_cc_payload ( message , & cc_code , & is_log , & min_val , & max_val , & offset_val );
355- if ( skip_chars < 0 ) {
344+ int32_t cc_code , is_log ;
345+ float min_val , max_val , offset_val ;
346+ AMY_UNSET ( cc_code ) ;
347+ AMY_UNSET ( is_log );
348+ skip_chars = parse_midi_cc_payload ( message , & cc_code , & is_log , & min_val , & max_val , & offset_val ) ;
349+ if ( * ( message + skip_chars ) != ',' ) {
350+ if ( AMY_IS_UNSET ( cc_code ) || AMY_IS_SET ( is_log )) {
351+ // Either parsing bailed without even a CC code, or it got past the is_log, meaning it wasn't a bare ic<NUM> command.
356352 fprintf (stderr , "synth_layer: midi cc payload didn't parse for %s.\n" , message - 1 );
357- return 1 ; // skip over the 'c'.
353+ return skip_chars ; // maybe the rest will parse?
358354 }
359- midi_store_control_code (e -> synth , cc_code , is_log , min_val , max_val , offset_val , message + skip_chars );
360- skip_chars = strlen (message ) + 1 ;
355+ // Else we got an incomplete message with a valid CC code - clear it
356+ midi_clear_control_code (e -> synth , cc_code ); // (handles 255 as special case).
357+ return skip_chars ;
361358 }
359+ ++ skip_chars ; // step over the "," before the wire string template.
360+ midi_store_control_code (e -> synth , cc_code , is_log , min_val , max_val , offset_val , message + skip_chars );
361+ skip_chars = strlen (message ) + 1 ;
362362 }
363363 else fprintf (stderr , "Unrecognized synth-level command '%s'\n" , message - 1 );
364364 return skip_chars ;
0 commit comments