Let's take a unit vector \$\vec u\$ in the direction we want to travel, and a vector perpendicular to it, \$\vec v\$:
$$\vec u = \begin{bmatrix}cos \Theta\\sin \Theta\end{bmatrix}, \vec v = \begin{bmatrix}-sin\Theta\\cos \Theta\end{bmatrix}$$
Then we can define a point on a sinusoidal curve through starting point \$\vec p_0\$, travelling in the direction \$\vec u\$, with a given speed, frequency, and amplitude, after time \$t\$ as:
$$\vec p(t) = \vec p_0 + \vec u \cdot speed \cdot t + \vec v \cdot amplitude \cdot sin(frequency \cdot t)$$
Taking the derivative, we get:
$$\frac{\delta \vec p(t)}{\delta t} = \vec u \cdot speed + \vec v \cdot amplitude \cdot cos(frequency \cdot t) \cdot frequency$$
So, we can rewrite your velocity expressions as...
c = (float)(Math.cos(Math.toRadians(dir)));
s = (float)(Math.sin(Math.toRadians(dir)));
wobble = amplitude * (float)Math.cos(frequency * t) * frequency;
velX = c * speed - s * wobble;
velY = s * speed + c * wobble;
Note that steering the object purely by velocity, you can accumulate rounding and integration errors. While the path will have the overall shape, it may stray from the parametric equation \$\vec p(t)\$ above. To fix this, you could instead compute your next position directly from the parametric equation, then compute a velocity to reach it.
velY = (float)(Math.sin(Math.toRadians(dir) + dT)) * speed;
, where dT is the elapsed time - probably milliseconds - since the last update. This will oscillate on the Y axis. \$\endgroup\$