Software for simulating NMR spectra
There is still the old WINDNMR programme developed by Hans Reich: https://www.chem.wisc.edu/areas/reich/plt/windnmr.htm which apparently should still work on modern versions of Windows.

It is not quite as sophisticated as Spinach, but if all you want is a 1D spectrum with various multiplets, then it is probably good enough.

If you have the computational resources, then there is software developed by Stefan Grimme's group https://xtb-docs.readthedocs.io/en/latest/enso_doc/enso.html, but you can't specify shifts manually, you need to generate them via a quantum chemical calculation using ORCA. Technically, all of these are free to use, but obviously it is not always practical. But in any case, if you are interested, the relevant publication is Angew. Chem. Int. Ed. 2017, 56 (46), 14763–14769. It should be possible now to run all the steps using just one ORCA input file; I suggest looking in the ORCA manual for more information.



For what it's worth, if you have the programming knowledge required, it's easy enough to write a (e.g.) Python script that is capable of simulating two- or three-spin (maybe four-spin) systems. At the end of the day, an NMR experiment is "just" a bunch of unitary operators acting on density matrices, i.e. lots and lots of matrix multiplication. For example, you could take a look at some of my MATLAB code here which simulates the first FID of a sensitivity-enhanced HSQC experiment. It is fairly trivial to port this to Python, since numpy provides you with pretty much every function you might need.

[Disclaimer: the code will not necessarily stay there forever.]

The only problem is that this scales exponentially with the number of spins, so unless you do some serious optimisation of the code (like that done in Spinach), it becomes intractable very quickly. But if your molecule can be "decomposed" into several spin systems which are small, then the overall spectrum is just the sum of the spectrum of each spin system, so you might be able to get away with simpler code. I've never thought about how you might do that, although my guess is that you would want to construct a Hamiltonian matrix, then pass it to a function which would call itself recursively if the matrix can be written in block-diagonal form.