#
# Split multichannel PCM stream to channel groups
#

#
# Helper macros
#

DefineMacro.SplitPCM_chnpos.If.a {
	Condition {
		Type String
		Empty "${var:__HWChannelPos}"
	}
	False.LibraryConfig.0.SubstiConfig.pcm."${var:__Name}" {
		slave.pcm.chmap [ "${var:__HWChannelPos}" ]
	}
}

DefineMacro.SplitPCM_chn.If.a {
	Condition {
		Type RegexMatch
		Regex "${var:__ChRegex}"
		String "${var:__Channels}"
	}
	True.LibraryConfig.0.SubstiConfig.pcm."${var:__Name}" {
		@args."${eval:$__ChIndex+2}" "CHN${var:__ChIndex}"
		@args { "CHN${var:__ChIndex}".type integer }
		bindings."${var:__ChIndex}" "$CHN${var:__ChIndex}"
	}
}

DefineMacro.SplitPCMDevice_chnpos.If.a {
	Condition {
		Type String
		Empty "${var:__Channel}"
	}
	False.Value {
		"${var:__Direction}Channel${var:__Index}" "${var:__Channel}"
		"${var:__Direction}ChannelPos${var:__Index}" "${var:__ChannelPos}"
	}
}

DefineMacro.SplitPCMDevice_addchn.If.a {
	Condition {
		Type String
		Empty "${var:__Channel}"
	}
	False.Define.__pcmdev "${var:__pcmdev},${var:__Channel}"
}

#
# Macro SplitPCM
#
# Application variable:
#   @SplitPCM - defined, return channel description using UCM values
#
# Arguments:
#   Name - PCM name (alsa-lib)
#   Direction - "Playback" or "Capture"
#   [Format] - sample format like S16_LE or S32_LE
#   Channels - application channels
#   HWChannels - hardware channels
#   HWChannelPos0 - channel position (MONO FR FL etc. - see alsa-lib's strings)
#   [HWChannelPos1] - channel position (MONO FR FL etc. - see alsa-lib's strings)
#

DefineMacro.SplitPCM.If.a {
	Condition {
		Type String
		Empty "${var:@SplitPCM}"
	}
	True {
		If.period_time {
			Condition {
				Type String
				Empty "${var:-SplitPCMPeriodTime}"
			}
			True.Define.__period_time 20000
			False.Define.__period_time "${var:SplitPCMPeriodTime}"
		}
		If.buffer_time {
			Condition {
				Type String
				Empty "${var:-SplitPCMBufferTime}"
			}
			True.Define.__buffer_time 500000
			False.Define.__buffer_time "${var:SplitPCMBufferTime}"
		}
		If.format {
			Condition {
				Type String
				Empty "${var:-__Format}"
			}
			True.Define.__Format S16_LE
		}

		LibraryConfig.pcm.SubstiConfig.pcm."${var:__Name}" {
			@args [ CARD DEV CHN0 ]
			@args {
				CARD.type string
				DEV.type integer
				CHN0.type integer
			}
			ipc_key 6678293
			type dshare
			slave {
				pcm {
					type hw
					card $CARD
					device $DEV
					chmap [ "${var:__HWChannelPos0}" ]
				}
				format "${var:__Format}"
				channels "${evali:$__HWChannels}"
				period_time "${evali:$__period_time}"
				buffer_time "${evali:$__buffer_time}"
			}
			bindings.0 $CHN0
		}

		Macro.pos1.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos1}" }
		Macro.pos2.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos2}" }
		Macro.pos3.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos3}" }
		Macro.pos4.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos4}" }
		Macro.pos5.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos5}" }
		Macro.pos6.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos6}" }
		Macro.pos7.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos7}" }
		Macro.pos8.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos8}" }
		Macro.pos9.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos9}" }
		Macro.pos10.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos10}" }
		Macro.pos11.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos11}" }
		Macro.pos12.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos12}" }
		Macro.pos13.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos13}" }
		Macro.pos14.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos14}" }
		Macro.pos15.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos15}" }
		Macro.pos16.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos16}" }
		Macro.pos17.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos17}" }
		Macro.pos18.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos18}" }
		Macro.pos19.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos19}" }
		Macro.pos20.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos20}" }
		Macro.pos21.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos21}" }
		Macro.pos22.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos22}" }
		Macro.pos23.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos23}" }
		Macro.pos24.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos24}" }
		Macro.pos25.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos25}" }
		Macro.pos26.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos26}" }
		Macro.pos27.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos27}" }
		Macro.pos28.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos28}" }
		Macro.pos29.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos29}" }
		Macro.pos30.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos30}" }
		Macro.pos31.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos31}" }
		Macro.pos32.SplitPCM_chnpos { HWChannelPos="${var:-__HWChannelPos32}" }

		Macro.ch1.SplitPCM_chn { ChIndex=1 ChRegex="^([2-9]|[1-9][0-9])$" }
		Macro.ch2.SplitPCM_chn { ChIndex=2 ChRegex="^([3-9]|[1-9][0-9])$" }
		Macro.ch3.SplitPCM_chn { ChIndex=3 ChRegex="^([4-9]|[1-9][0-9])$" }
		Macro.ch4.SplitPCM_chn { ChIndex=4 ChRegex="^([5-9]|[1-9][0-9])$" }
		Macro.ch5.SplitPCM_chn { ChIndex=5 ChRegex="^([6-9]|[1-9][0-9])$" }
		Macro.ch6.SplitPCM_chn { ChIndex=6 ChRegex="^([7-9]|[1-9][0-9])$" }
		Macro.ch7.SplitPCM_chn { ChIndex=7 ChRegex="^([8-9]|[1-9][0-9])$" }

		If.dir {
			Condition {
				Type String
				String1 "${var:__Direction}"
				String2 "Capture"
			}
			True.LibraryConfig.dir.Config.pcm."${var:__Name}".type dsnoop
		}
	}
}

#
# Macro SplitPCMDevice
#
# Application variable:
#   @SplitPCM - defined, return channel description using UCM values
#
# Arguments:
#   Name - PCM name (alsa-lib)
#   Direction - "Playback" or "Capture"
#   Device - hardware PCM device number (optional - default 0)
#   Channels - count of application channels
#   HWChannels - total channels (in hardware)
#   Channel0 - channel index in stream for the destination channel 0
#   [Channel1] - channel index in stream for the destination channel 1 (optional)
#   ChannelPos0 - channel position (MONO FR FL etc. - see alsa-lib's strings
#   [ChannelPos1] - channel position (MONO FR FL etc. - see alsa-lib's strings)
#

DefineMacro.SplitPCMDevice {
	If.a {
		Condition {
			Type String
			Empty "${var:-__Device}"
		}
		True.Define.__Device "0"
	}
	If.b {
		Condition {
			Type String
			Empty "${var:@SplitPCM}"
		}
		False {
			Value {
				"${var:__Direction}Channels" "${var:__HWChannels}"
				"${var:__Direction}PCM" "hw:${CardId},${var:__Device}"
				"${var:__Direction}Channel0" "${var:__Channel0}"
				"${var:__Direction}ChannelPos0" "${var:__ChannelPos0}"
			}

			Macro.chn1.SplitPCMDevice_chnpos { Index=1 Channel="${var:-__Channel1}" ChannelPos="${var:-__ChannelPos1}" }
			Macro.chn2.SplitPCMDevice_chnpos { Index=2 Channel="${var:-__Channel2}" ChannelPos="${var:-__ChannelPos2}" }
			Macro.chn3.SplitPCMDevice_chnpos { Index=3 Channel="${var:-__Channel3}" ChannelPos="${var:-__ChannelPos3}" }
			Macro.chn4.SplitPCMDevice_chnpos { Index=4 Channel="${var:-__Channel4}" ChannelPos="${var:-__ChannelPos4}" }
			Macro.chn5.SplitPCMDevice_chnpos { Index=5 Channel="${var:-__Channel5}" ChannelPos="${var:-__ChannelPos5}" }
			Macro.chn6.SplitPCMDevice_chnpos { Index=6 Channel="${var:-__Channel6}" ChannelPos="${var:-__ChannelPos6}" }
			Macro.chn7.SplitPCMDevice_chnpos { Index=7 Channel="${var:-__Channel7}" ChannelPos="${var:-__ChannelPos7}" }
		}
		True {
			Define.__pcmdev "${var:__Name}:${CardId},${var:__Device},${var:__Channel0}"
			Macro.ch1.SplitPCMDevice_addchn { Channel="${var:-__Channel1}" }
			Macro.ch2.SplitPCMDevice_addchn { Channel="${var:-__Channel2}" }
			Macro.ch3.SplitPCMDevice_addchn { Channel="${var:-__Channel3}" }
			Macro.ch4.SplitPCMDevice_addchn { Channel="${var:-__Channel4}" }
			Macro.ch5.SplitPCMDevice_addchn { Channel="${var:-__Channel5}" }
			Macro.ch6.SplitPCMDevice_addchn { Channel="${var:-__Channel6}" }
			Macro.ch7.SplitPCMDevice_addchn { Channel="${var:-__Channel7}" }
			Value {
				"${var:__Direction}Channels" "${var:__Channels}"
				"${var:__Direction}PCM" "${var:__pcmdev}"
			}
		}
	}
}
