Skip to content

Commit a4ff92f

Browse files
committed
ALSA: seq: ump: Transmit RPN/NRPN message at each MSB/LSB data reception
Just like the core UMP conversion helper, we need to deal with the partially-filled RPN/NRPN data in the sequencer UMP converter as well. Link: https://patch.msgid.link/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent a683030 commit a4ff92f

File tree

1 file changed

+44
-30
lines changed

1 file changed

+44
-30
lines changed

sound/core/seq/seq_ump_convert.c

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -790,27 +790,39 @@ static int paf_ev_to_ump_midi2(const struct snd_seq_event *event,
790790
}
791791

792792
/* set up the MIDI2 RPN/NRPN packet data from the parsed info */
793-
static void fill_rpn(struct ump_cvt_to_ump_bank *cc,
794-
union snd_ump_midi2_msg *data,
795-
unsigned char channel)
793+
static int fill_rpn(struct ump_cvt_to_ump_bank *cc,
794+
union snd_ump_midi2_msg *data,
795+
unsigned char channel,
796+
bool flush)
796797
{
798+
if (!(cc->cc_data_lsb_set || cc->cc_data_msb_set))
799+
return 0; // skip
800+
/* when not flushing, wait for complete data set */
801+
if (!flush && (!cc->cc_data_lsb_set || !cc->cc_data_msb_set))
802+
return 0; // skip
803+
797804
if (cc->rpn_set) {
798805
data->rpn.status = UMP_MSG_STATUS_RPN;
799806
data->rpn.bank = cc->cc_rpn_msb;
800807
data->rpn.index = cc->cc_rpn_lsb;
801-
cc->rpn_set = 0;
802-
cc->cc_rpn_msb = cc->cc_rpn_lsb = 0;
803-
} else {
808+
} else if (cc->nrpn_set) {
804809
data->rpn.status = UMP_MSG_STATUS_NRPN;
805810
data->rpn.bank = cc->cc_nrpn_msb;
806811
data->rpn.index = cc->cc_nrpn_lsb;
807-
cc->nrpn_set = 0;
808-
cc->cc_nrpn_msb = cc->cc_nrpn_lsb = 0;
812+
} else {
813+
return 0; // skip
809814
}
815+
810816
data->rpn.data = upscale_14_to_32bit((cc->cc_data_msb << 7) |
811817
cc->cc_data_lsb);
812818
data->rpn.channel = channel;
819+
820+
cc->rpn_set = 0;
821+
cc->nrpn_set = 0;
822+
cc->cc_rpn_msb = cc->cc_rpn_lsb = 0;
813823
cc->cc_data_msb = cc->cc_data_lsb = 0;
824+
cc->cc_data_msb_set = cc->cc_data_lsb_set = 0;
825+
return 1;
814826
}
815827

816828
/* convert CC event to MIDI 2.0 UMP */
@@ -823,28 +835,34 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
823835
unsigned char index = event->data.control.param & 0x7f;
824836
unsigned char val = event->data.control.value & 0x7f;
825837
struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel];
838+
int ret;
826839

827840
/* process special CC's (bank/rpn/nrpn) */
828841
switch (index) {
829842
case UMP_CC_RPN_MSB:
843+
ret = fill_rpn(cc, data, channel, true);
830844
cc->rpn_set = 1;
831845
cc->cc_rpn_msb = val;
832-
return 0; // skip
846+
return ret;
833847
case UMP_CC_RPN_LSB:
848+
ret = fill_rpn(cc, data, channel, true);
834849
cc->rpn_set = 1;
835850
cc->cc_rpn_lsb = val;
836-
return 0; // skip
851+
return ret;
837852
case UMP_CC_NRPN_MSB:
853+
ret = fill_rpn(cc, data, channel, true);
838854
cc->nrpn_set = 1;
839855
cc->cc_nrpn_msb = val;
840-
return 0; // skip
856+
return ret;
841857
case UMP_CC_NRPN_LSB:
858+
ret = fill_rpn(cc, data, channel, true);
842859
cc->nrpn_set = 1;
843860
cc->cc_nrpn_lsb = val;
844-
return 0; // skip
861+
return ret;
845862
case UMP_CC_DATA:
863+
cc->cc_data_msb_set = 1;
846864
cc->cc_data_msb = val;
847-
return 0; // skip
865+
return fill_rpn(cc, data, channel, false);
848866
case UMP_CC_BANK_SELECT:
849867
cc->bank_set = 1;
850868
cc->cc_bank_msb = val;
@@ -854,11 +872,9 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
854872
cc->cc_bank_lsb = val;
855873
return 0; // skip
856874
case UMP_CC_DATA_LSB:
875+
cc->cc_data_lsb_set = 1;
857876
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;
877+
return fill_rpn(cc, data, channel, false);
862878
}
863879

864880
data->cc.status = status;
@@ -926,6 +942,7 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
926942
unsigned char index = event->data.control.param & 0x7f;
927943
struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel];
928944
unsigned char msb, lsb;
945+
int ret;
929946

930947
msb = (event->data.control.value >> 7) & 0x7f;
931948
lsb = event->data.control.value & 0x7f;
@@ -939,28 +956,25 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
939956
cc->cc_bank_lsb = lsb;
940957
return 0; // skip
941958
case UMP_CC_RPN_MSB:
942-
cc->cc_rpn_msb = msb;
943-
fallthrough;
944959
case UMP_CC_RPN_LSB:
945-
cc->rpn_set = 1;
960+
ret = fill_rpn(cc, data, channel, true);
961+
cc->cc_rpn_msb = msb;
946962
cc->cc_rpn_lsb = lsb;
947-
return 0; // skip
963+
cc->rpn_set = 1;
964+
return ret;
948965
case UMP_CC_NRPN_MSB:
949-
cc->cc_nrpn_msb = msb;
950-
fallthrough;
951966
case UMP_CC_NRPN_LSB:
967+
ret = fill_rpn(cc, data, channel, true);
968+
cc->cc_nrpn_msb = msb;
952969
cc->nrpn_set = 1;
953970
cc->cc_nrpn_lsb = lsb;
954-
return 0; // skip
971+
return ret;
955972
case UMP_CC_DATA:
956-
cc->cc_data_msb = msb;
957-
fallthrough;
958973
case UMP_CC_DATA_LSB:
974+
cc->cc_data_msb_set = cc->cc_data_lsb_set = 1;
975+
cc->cc_data_msb = msb;
959976
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;
977+
return fill_rpn(cc, data, channel, false);
964978
}
965979

966980
data->cc.status = UMP_MSG_STATUS_CC;

0 commit comments

Comments
 (0)