You are getting a distorted sound because the default settings for the old /dev/dsp* devices are 8 bit, 8 kHz sample rate, mono. To change this one must use ioctl() calls but of course if you use the '>' shell redirect doesn't happen.
So what happens if you pipe in a 16 bit wav? The device will read in one byte at a time, but its input contains 2 bytes per sample. The 16 bits are spread over 2 bytes, one for the upper 8 bits and one for the lower 8 bits.
Example: a sine wave in 8 bits may produce the following sequence of values:
0 64 110 127 110 63 0 -64 -110 -127 -110 -63 0
This is one full cycle; the values go up and down smoothly.
The same sine in 16 bits has the following values:
0 16384 28377 32767 28377 16383 0 -16384 -28377 -32767 -28377 -16383 0
Again, going up and down smoothly. But what happens if we split the 16 bits into 2 8 bit quantities?
0 0 0 64 -39 111 -1 128 -39 111 -1 64 0 0 0 -64 39 -111 1 -128 39 -111 1 -64 0 0
Suddenly it becomes a chaotic sequence of values, and that is what you are hearing: noise.
So how do you fix this? You can try to convert the sample with sox, but of course that will severely downgrade the quality (I mean, 8 bits at 8 kHz is telephone quality...). So the best way, as you already discovered, is using aplay; it will set the device to the proper settings. If you want to play something from your own program, you must set the proper bit size, sample rate, number of channels etc. etc. using ioctl() calls. Search for 'oss ioctl'.
/dev/dspis OSS and deprecated. It should still work if it's present, though. One thing you could try is a signal generator. Try looking for thesiggenpackage. This will help you figure out what kind of "glitches" we're dealing with. Btw, what is your operating system? Raspbian? – appas Jun 17 '15 at 00:21