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.

  1. 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:
  2. 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.
  3. I sample the function 44100 times per second, for 5 seconds.
  4. For each sample value, I add 1, so that values range from 0 to 2.
  5. Each sample value is multiplied by 215, giving me a range from 0 to 65536 (16 bits).
  6. 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):

  -t raw
  -b 16
  -r 44100
  -e unsigned-integer
  --endian little

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.)


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:

  -t raw
  -b 16
  -r 44100
  -e signed-integer
  --endian little

The output from that is this. Unfortunately, it still is inaudible.

  • I think it would help if you posted your code, especially if it's something nice as Haskell! – The most likely reason why you don't hear anything seems that you're generating infrasound for some reason. – leftaroundabout Jul 29 '14 at 9:32
  • 2
    This question is perhaps better suited for a programming q&a site, have you tried that? – Arnoud Traa Jul 29 '14 at 11:00
  • @ArnoudTraa: I disagree, it's not about "why does my program not produce the signal I want" but about "why is this signal which my program yields not audible", which has nothing do to with programming so SoundDesign is definitely a better location than a StackOverflow. I just asked the OP to post the code so the problem is reproducible, but he might as well post the audio file. – leftaroundabout Jul 29 '14 at 11:06
  • Hi leftaroundabout, I agree with the distinction between the two issues, that's why i wrote perhaps. I don't want to say programming sounds with SOX i not sound design, but then again, i think there should be better places to discuss this topic. That would help keep this site in focus (sound design). But I must admit that this might also be a sound design topic... it's a grey area. – Arnoud Traa Jul 29 '14 at 12:40
  • I have created a Meta Post to discuss if this kind of question is on topic. Personally, my vote would be with ArnoudTraa that this is a programming question. If it is actually producing a sine wave and proper audio file, it should be audible, the fact it is not means there is a bug in the program, which means this is debugging. I don't see how debugging is sound design or even audio production. – AJ Henderson Jul 29 '14 at 14:21

Your sine has come out a couple of octaves too low, for some reason. Indeed it's infrasound, 6.6 Hz to be precise, which rather explains why you don't hear anything.

A couple of ways you could have found this out:

  • Actually the sound is still "audible": over a decent subwoofer, you'll hear (or rather feel) a throbbing similar to a ship engine, and things in your room might start to clatter in an audible way.
  • Pretty much any audio player nowadays has some kind of primitive spectrum view. With your file, it'll show quite some signal in the low-frequency end, but nothing elsewhere: Audacious spectrum view
  • Any audio editor / DAW shows the waveform. Audacity will do: Waveform in audacity Here you can immediately see that there's a perfectly correctly scaled signal, amplitude-wise, but with just a few cycles per second: certainly not 261. In fact you can easily count them by hand, though there's also tools to do this for you.
  • If I was you, I had just toyed around with the program's parameter's a bit: asking it for a frequency of 5 kHz would have given a well-audible 127 Hz, roughly B1. That would have pointed to the problem a bit more clearly.

So what is the problem, now? Well, we can reverse-engineer those 6.6 Hz. You've used the numbers 261.63, 2π, 5 and 44100. The last one is so big it's unlikely to play a role, but guess-combining the other ones reveals what's going on:

GHCi, version 7.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Prelude> 2 * pi
Prelude> 261.63 / 5
Prelude> 261.63 / (5 * 2 * pi)
Prelude> 261.63 / (2 * pi)
Prelude> 261.63 / (2 * pi * 6.6)
Prelude> 261.63 / (2 * pi)^2

Bingo. So you need to multiply the frequency twice by 2π. Why is this? Well actually it would have been clear even from properly reading the question:

I am dividing the time parameter by 2 * pi

This is of course wrong. The 2π are the period length of a RAD sine, so you need to multiply the time by it, not divide. Dividing instead of multiplying leaves you with a factor of (2π)2 short, which is the reason for your wrong frequency.

  • You are simply amazing. I will try the fix! – Jacob Jul 30 '14 at 15:43
  • Yes, that worked perfectly. – Jacob Jul 30 '14 at 15:44

Your Answer

