I'm experimenting with generating sound programmatically. As I understand the math, I think I'm creating a 5-second long mono-channel sine wave at the frequency of "middle C," but when I play back the audio data, I cannot hear anything.
Let me explain how I'm creating the data, and maybe you can tell what I'm doing wrong.
- I start with a sine wave; I am dividing the time parameter by
2 * pi
so that the function repeats for every one unit; this is to hopefully simplify the math: - To set the pitch of this wave, I multiply the time parameter by
261.63
, so that it will oscillate at the frequency for middle C. - I sample the function 44100 times per second, for 5 seconds.
- For each sample value, I add 1, so that values range from 0 to 2.
- Each sample value is multiplied by 215, giving me a range from 0 to 65536 (16 bits).
- I output, in little-endian format, each 2-byte value in sequence.
When inspecting the raw audio data in a hex editor, it looks correct to me; values start mid-range at 0x8000
, go up to 0xffff
, go back down to 0x0000
, go back up to 0xffff
, etc. It resembles what I'd expect a sine wave to look like, taking up the full dynamic range of 16 bit values.
So given this raw data, I convert it through sox to a WAV file (line breaks added for clarity):
sox
-t raw
-b 16
-r 44100
-e unsigned-integer
--endian little
input.raw
output.wav
The wave file is successfully created and looks valid from what I can tell. Playback works for the file, and visualization during playback shows there's something being output, but I can't hear a thing. I tried playing with the amplitude of the wave to reduce the dynamic range, but that didn't help.
I am extremely new to sound, and am just now learning all the theory behind it. Is the mathematical approach correct for producing a tone? Am I doing something wrong with my data formatting? Am I using sox incorrectly? What could be the problem here?
(I decided to not include all my Haskell code, but if it would help, I can post it here. However, as I stated, the data resembles a sine wave, so I have no idea why there's no sound.)
Edit:
Here's a link to the file.
Edit 2:
I created new samples that are signed 16-bit values, then converted to a WAV with this:
sox
-t raw
-b 16
-r 44100
-e signed-integer
--endian little
input.raw
output.wav
The output from that is this. Unfortunately, it still is inaudible.