@@ -401,7 +401,7 @@ private void audioParamCheck(int streamType, int sampleRateInHz,
401401 mChannels = AudioFormat .CHANNEL_OUT_STEREO ;
402402 break ;
403403 default :
404- if ((channelConfig & SUPPORTED_OUT_CHANNELS ) != channelConfig ) {
404+ if (! isMultichannelConfigSupported (channelConfig ) ) {
405405 // input channel configuration features unsupported channels
406406 mChannelCount = 0 ;
407407 mChannels = AudioFormat .CHANNEL_INVALID ;
@@ -438,6 +438,37 @@ private void audioParamCheck(int streamType, int sampleRateInHz,
438438 }
439439 }
440440
441+ /**
442+ * Convenience method to check that the channel configuration (a.k.a channel mask) is supported
443+ * @param channelConfig the mask to validate
444+ * @return false if the AudioTrack can't be used with such a mask
445+ */
446+ private static boolean isMultichannelConfigSupported (int channelConfig ) {
447+ // check for unsupported channels
448+ if ((channelConfig & SUPPORTED_OUT_CHANNELS ) != channelConfig ) {
449+ Log .e (TAG , "Channel configuration features unsupported channels" );
450+ return false ;
451+ }
452+ // check for unsupported multichannel combinations:
453+ // - FL/FR must be present
454+ // - L/R channels must be paired (e.g. no single L channel)
455+ final int frontPair =
456+ AudioFormat .CHANNEL_OUT_FRONT_LEFT | AudioFormat .CHANNEL_OUT_FRONT_RIGHT ;
457+ if ((channelConfig & frontPair ) != frontPair ) {
458+ Log .e (TAG , "Front channels must be present in multichannel configurations" );
459+ return false ;
460+ }
461+ final int backPair =
462+ AudioFormat .CHANNEL_OUT_BACK_LEFT | AudioFormat .CHANNEL_OUT_BACK_RIGHT ;
463+ if ((channelConfig & backPair ) != 0 ) {
464+ if ((channelConfig & backPair ) != backPair ) {
465+ Log .e (TAG , "Rear channels can't be used independently" );
466+ return false ;
467+ }
468+ }
469+ return true ;
470+ }
471+
441472
442473 // Convenience method for the contructor's audio buffer size check.
443474 // preconditions:
0 commit comments