While netem doesn't allow you to set a time varying latency directly, tc responds quickly to changes (in the order of 100ms or lower).
Knowing this, you can just write a program to change the latency in a way which tracks the function you want.
For example, incrementing the latency every second using bash:
# Virtual ethernet for testing
sudo ip netns add net1
sudo ip netns add net2
sudo ip link add name veth netns net1 type veth peer name veth netns net2
sudo ip netns exec net1 ip addr add 10.0.0.1/24 dev veth
sudo ip netns exec net2 ip addr add 10.0.0.2/24 dev veth
sudo ip netns exec net1 ip link set dev veth up
sudo ip netns exec net2 ip link set dev veth up
# Latency measurement
(sudo ip netns exec net1 ping -c 40 -i 0.1 10.0.0.2 | awk -F'=' '/time=/{print "{\"latency_ms\": " substr($4, 1, length($4)-3) "}"}' | jq -s . > changing_latency.json) &
# Increment latency every second
seq 1 4 | while read -r i; do
if [ "$i" = "1" ]; then
(sudo ip netns exec net1 tc qdisc add dev veth root netem delay ${i}ms) &
else
(sudo ip netns exec net1 tc qdisc change dev veth root netem delay ${i}ms) &
fi
sleep 1
done
sudo ip netns exec net1 tc qdisc del dev veth root
Resulting in the following measured latency:

I have tested this on multiple machines with different specs and the timing behavior seems to be the same across all of them.