technical documentation - diglet48/restim GitHub Wiki
This page will explain how Restim generates frequency locked multi-phase signals. The target audience is software developers who want to reproduce Restim signals in their own applications.
The main idea is that generating N-phase signals is equivalent with projecting N points on the complex plane with these constraints:
$$\begin{align}
p_1, p_2, ... p_n &= \text{points on complex plane} \
\text{electrode}\ n \ \text{amplitude} &= |p_n| \
p_1 + p_2 + ... p_n &= 0
\end{align}$$
We can then sweep across the complex plane with the desired carrier frequency to generate the electrode signals, which can then be converted to audio channel signal.
More formalized:
$$\left[\begin{matrix} \text{left audio channel}\ \text{right audio channel}\ 0 \end{matrix}\right] = T_{P2C} * \text{project-on-complex-plane()} * \text{carrier\_signal} $$
Where $T_{P2C}$ is the potential to channel matrix described here and the carrier signal is
$$\text{carrier\_signal} = \left[\begin{matrix} \cos(t * \pi * 2 * \text{frequency})\ \sin(t * \pi * 2 * \text{frequency})\end{matrix}\right] $$
The projection on the complex plane is the complicated part.
For four or more phases, we use an iterative approach. An exact solution exists for threephase which is described below.
$$\begin{align}
\alpha, \beta &= \text{user input} \
\theta &= \text{atan}(\beta, \alpha) \
r &= \text{norm}(\alpha, \beta) \
\text{base} &=
\left[\begin{matrix}
\cos(0) & \sin(0) \
\cos(120) & \sin(120) \
\cos(-120) & \sin(-120) \
\end{matrix}\right] \
\text{offset} &=
\left[\begin{matrix}
\cos(\theta) & \sin(\theta) \
\cos(\theta - 120) & \sin(\theta - 120) \
\cos(\theta + 120) & \sin(\theta + 120) \
\end{matrix}\right] \
\text{projection on complex plane} &= \text{base} * (1 - \frac{r}{2}) + \text{offset} * \frac{r}{2}
\end{align}
$$
A more efficient solution exists in this form:
$$\text{projection on complex plane} = \ \left[\begin{matrix} 1 & 0 \ {-} \frac{1}{2} & \frac{\sqrt{3}}{2} \ {-} \frac{1}{2} & - \frac{\sqrt{3}}{2} \end{matrix}\right] * \left[\begin{matrix} 2 - r + \alpha & \beta \ \beta & 2 - r - \alpha \end{matrix}\right] * \frac{1}{2} $$
For maximum efficiency, pre-multiply the constant matrix with the potential-to-channel matrix.