@@ -368,7 +368,7 @@ static int cvt_ump_midi1_to_midi2(struct snd_seq_client *dest,
368
368
struct snd_seq_ump_event ev_cvt ;
369
369
const union snd_ump_midi1_msg * midi1 = (const union snd_ump_midi1_msg * )event -> ump ;
370
370
union snd_ump_midi2_msg * midi2 = (union snd_ump_midi2_msg * )ev_cvt .ump ;
371
- struct snd_seq_ump_midi2_bank * cc ;
371
+ struct ump_cvt_to_ump_bank * cc ;
372
372
373
373
ev_cvt = * event ;
374
374
memset (& ev_cvt .ump , 0 , sizeof (ev_cvt .ump ));
@@ -789,28 +789,45 @@ static int paf_ev_to_ump_midi2(const struct snd_seq_event *event,
789
789
return 1 ;
790
790
}
791
791
792
+ static void reset_rpn (struct ump_cvt_to_ump_bank * cc )
793
+ {
794
+ cc -> rpn_set = 0 ;
795
+ cc -> nrpn_set = 0 ;
796
+ cc -> cc_rpn_msb = cc -> cc_rpn_lsb = 0 ;
797
+ cc -> cc_data_msb = cc -> cc_data_lsb = 0 ;
798
+ cc -> cc_data_msb_set = cc -> cc_data_lsb_set = 0 ;
799
+ }
800
+
792
801
/* set up the MIDI2 RPN/NRPN packet data from the parsed info */
793
- static void fill_rpn (struct snd_seq_ump_midi2_bank * cc ,
794
- union snd_ump_midi2_msg * data ,
795
- unsigned char channel )
802
+ static int fill_rpn (struct ump_cvt_to_ump_bank * cc ,
803
+ union snd_ump_midi2_msg * data ,
804
+ unsigned char channel ,
805
+ bool flush )
796
806
{
807
+ if (!(cc -> cc_data_lsb_set || cc -> cc_data_msb_set ))
808
+ return 0 ; // skip
809
+ /* when not flushing, wait for complete data set */
810
+ if (!flush && (!cc -> cc_data_lsb_set || !cc -> cc_data_msb_set ))
811
+ return 0 ; // skip
812
+
797
813
if (cc -> rpn_set ) {
798
814
data -> rpn .status = UMP_MSG_STATUS_RPN ;
799
815
data -> rpn .bank = cc -> cc_rpn_msb ;
800
816
data -> rpn .index = cc -> cc_rpn_lsb ;
801
- cc -> rpn_set = 0 ;
802
- cc -> cc_rpn_msb = cc -> cc_rpn_lsb = 0 ;
803
- } else {
817
+ } else if (cc -> nrpn_set ) {
804
818
data -> rpn .status = UMP_MSG_STATUS_NRPN ;
805
819
data -> rpn .bank = cc -> cc_nrpn_msb ;
806
820
data -> rpn .index = cc -> cc_nrpn_lsb ;
807
- cc -> nrpn_set = 0 ;
808
- cc -> cc_nrpn_msb = cc -> cc_nrpn_lsb = 0 ;
821
+ } else {
822
+ return 0 ; // skip
809
823
}
824
+
810
825
data -> rpn .data = upscale_14_to_32bit ((cc -> cc_data_msb << 7 ) |
811
826
cc -> cc_data_lsb );
812
827
data -> rpn .channel = channel ;
813
- cc -> cc_data_msb = cc -> cc_data_lsb = 0 ;
828
+
829
+ reset_rpn (cc );
830
+ return 1 ;
814
831
}
815
832
816
833
/* convert CC event to MIDI 2.0 UMP */
@@ -822,29 +839,39 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
822
839
unsigned char channel = event -> data .control .channel & 0x0f ;
823
840
unsigned char index = event -> data .control .param & 0x7f ;
824
841
unsigned char val = event -> data .control .value & 0x7f ;
825
- struct snd_seq_ump_midi2_bank * cc = & dest_port -> midi2_bank [channel ];
842
+ struct ump_cvt_to_ump_bank * cc = & dest_port -> midi2_bank [channel ];
843
+ int ret ;
826
844
827
845
/* process special CC's (bank/rpn/nrpn) */
828
846
switch (index ) {
829
847
case UMP_CC_RPN_MSB :
848
+ ret = fill_rpn (cc , data , channel , true);
830
849
cc -> rpn_set = 1 ;
831
850
cc -> cc_rpn_msb = val ;
832
- return 0 ; // skip
851
+ if (cc -> cc_rpn_msb == 0x7f && cc -> cc_rpn_lsb == 0x7f )
852
+ reset_rpn (cc );
853
+ return ret ;
833
854
case UMP_CC_RPN_LSB :
855
+ ret = fill_rpn (cc , data , channel , true);
834
856
cc -> rpn_set = 1 ;
835
857
cc -> cc_rpn_lsb = val ;
836
- return 0 ; // skip
858
+ if (cc -> cc_rpn_msb == 0x7f && cc -> cc_rpn_lsb == 0x7f )
859
+ reset_rpn (cc );
860
+ return ret ;
837
861
case UMP_CC_NRPN_MSB :
862
+ ret = fill_rpn (cc , data , channel , true);
838
863
cc -> nrpn_set = 1 ;
839
864
cc -> cc_nrpn_msb = val ;
840
- return 0 ; // skip
865
+ return ret ;
841
866
case UMP_CC_NRPN_LSB :
867
+ ret = fill_rpn (cc , data , channel , true);
842
868
cc -> nrpn_set = 1 ;
843
869
cc -> cc_nrpn_lsb = val ;
844
- return 0 ; // skip
870
+ return ret ;
845
871
case UMP_CC_DATA :
872
+ cc -> cc_data_msb_set = 1 ;
846
873
cc -> cc_data_msb = val ;
847
- return 0 ; // skip
874
+ return fill_rpn ( cc , data , channel , false);
848
875
case UMP_CC_BANK_SELECT :
849
876
cc -> bank_set = 1 ;
850
877
cc -> cc_bank_msb = val ;
@@ -854,11 +881,9 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
854
881
cc -> cc_bank_lsb = val ;
855
882
return 0 ; // skip
856
883
case UMP_CC_DATA_LSB :
884
+ cc -> cc_data_lsb_set = 1 ;
857
885
cc -> cc_data_lsb = val ;
858
- if (!(cc -> rpn_set || cc -> nrpn_set ))
859
- return 0 ; // skip
860
- fill_rpn (cc , data , channel );
861
- return 1 ;
886
+ return fill_rpn (cc , data , channel , false);
862
887
}
863
888
864
889
data -> cc .status = status ;
@@ -887,7 +912,7 @@ static int pgm_ev_to_ump_midi2(const struct snd_seq_event *event,
887
912
unsigned char status )
888
913
{
889
914
unsigned char channel = event -> data .control .channel & 0x0f ;
890
- struct snd_seq_ump_midi2_bank * cc = & dest_port -> midi2_bank [channel ];
915
+ struct ump_cvt_to_ump_bank * cc = & dest_port -> midi2_bank [channel ];
891
916
892
917
data -> pg .status = status ;
893
918
data -> pg .channel = channel ;
@@ -924,8 +949,9 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
924
949
{
925
950
unsigned char channel = event -> data .control .channel & 0x0f ;
926
951
unsigned char index = event -> data .control .param & 0x7f ;
927
- struct snd_seq_ump_midi2_bank * cc = & dest_port -> midi2_bank [channel ];
952
+ struct ump_cvt_to_ump_bank * cc = & dest_port -> midi2_bank [channel ];
928
953
unsigned char msb , lsb ;
954
+ int ret ;
929
955
930
956
msb = (event -> data .control .value >> 7 ) & 0x7f ;
931
957
lsb = event -> data .control .value & 0x7f ;
@@ -939,28 +965,27 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
939
965
cc -> cc_bank_lsb = lsb ;
940
966
return 0 ; // skip
941
967
case UMP_CC_RPN_MSB :
942
- cc -> cc_rpn_msb = msb ;
943
- fallthrough ;
944
968
case UMP_CC_RPN_LSB :
945
- cc -> rpn_set = 1 ;
969
+ ret = fill_rpn (cc , data , channel , true);
970
+ cc -> cc_rpn_msb = msb ;
946
971
cc -> cc_rpn_lsb = lsb ;
947
- return 0 ; // skip
972
+ cc -> rpn_set = 1 ;
973
+ if (cc -> cc_rpn_msb == 0x7f && cc -> cc_rpn_lsb == 0x7f )
974
+ reset_rpn (cc );
975
+ return ret ;
948
976
case UMP_CC_NRPN_MSB :
949
- cc -> cc_nrpn_msb = msb ;
950
- fallthrough ;
951
977
case UMP_CC_NRPN_LSB :
978
+ ret = fill_rpn (cc , data , channel , true);
979
+ cc -> cc_nrpn_msb = msb ;
952
980
cc -> nrpn_set = 1 ;
953
981
cc -> cc_nrpn_lsb = lsb ;
954
- return 0 ; // skip
982
+ return ret ;
955
983
case UMP_CC_DATA :
956
- cc -> cc_data_msb = msb ;
957
- fallthrough ;
958
984
case UMP_CC_DATA_LSB :
985
+ cc -> cc_data_msb_set = cc -> cc_data_lsb_set = 1 ;
986
+ cc -> cc_data_msb = msb ;
959
987
cc -> cc_data_lsb = lsb ;
960
- if (!(cc -> rpn_set || cc -> nrpn_set ))
961
- return 0 ; // skip
962
- fill_rpn (cc , data , channel );
963
- return 1 ;
988
+ return fill_rpn (cc , data , channel , false);
964
989
}
965
990
966
991
data -> cc .status = UMP_MSG_STATUS_CC ;
@@ -1192,44 +1217,53 @@ static int cvt_sysex_to_ump(struct snd_seq_client *dest,
1192
1217
{
1193
1218
struct snd_seq_ump_event ev_cvt ;
1194
1219
unsigned char status ;
1195
- u8 buf [6 ], * xbuf ;
1220
+ u8 buf [8 ], * xbuf ;
1196
1221
int offset = 0 ;
1197
1222
int len , err ;
1223
+ bool finished = false;
1198
1224
1199
1225
if (!snd_seq_ev_is_variable (event ))
1200
1226
return 0 ;
1201
1227
1202
1228
setup_ump_event (& ev_cvt , event );
1203
- for (;; ) {
1229
+ while (! finished ) {
1204
1230
len = snd_seq_expand_var_event_at (event , sizeof (buf ), buf , offset );
1205
1231
if (len <= 0 )
1206
1232
break ;
1207
- if (WARN_ON (len > 6 ))
1233
+ if (WARN_ON (len > sizeof ( buf ) ))
1208
1234
break ;
1209
- offset += len ;
1235
+
1210
1236
xbuf = buf ;
1237
+ status = UMP_SYSEX_STATUS_CONTINUE ;
1238
+ /* truncate the sysex start-marker */
1211
1239
if (* xbuf == UMP_MIDI1_MSG_SYSEX_START ) {
1212
1240
status = UMP_SYSEX_STATUS_START ;
1213
- xbuf ++ ;
1214
1241
len -- ;
1215
- if (len > 0 && xbuf [len - 1 ] == UMP_MIDI1_MSG_SYSEX_END ) {
1242
+ offset ++ ;
1243
+ xbuf ++ ;
1244
+ }
1245
+
1246
+ /* if the last of this packet or the 1st byte of the next packet
1247
+ * is the end-marker, finish the transfer with this packet
1248
+ */
1249
+ if (len > 0 && len < 8 &&
1250
+ xbuf [len - 1 ] == UMP_MIDI1_MSG_SYSEX_END ) {
1251
+ if (status == UMP_SYSEX_STATUS_START )
1216
1252
status = UMP_SYSEX_STATUS_SINGLE ;
1217
- len -- ;
1218
- }
1219
- } else {
1220
- if (xbuf [len - 1 ] == UMP_MIDI1_MSG_SYSEX_END ) {
1253
+ else
1221
1254
status = UMP_SYSEX_STATUS_END ;
1222
- len -- ;
1223
- } else {
1224
- status = UMP_SYSEX_STATUS_CONTINUE ;
1225
- }
1255
+ len -- ;
1256
+ finished = true;
1226
1257
}
1258
+
1259
+ len = min (len , 6 );
1227
1260
fill_sysex7_ump (dest_port , ev_cvt .ump , status , xbuf , len );
1228
1261
err = __snd_seq_deliver_single_event (dest , dest_port ,
1229
1262
(struct snd_seq_event * )& ev_cvt ,
1230
1263
atomic , hop );
1231
1264
if (err < 0 )
1232
1265
return err ;
1266
+ offset += len ;
1233
1267
}
1234
1268
return 0 ;
1235
1269
}
0 commit comments