Weird glitch when creating sine audio signal

305 views Asked by At

I had a look at the wave format today and created a little wave generator. I create a sine sound like this:

 public static Wave GetSine(double length, double hz)
    {
        int bitRate = 44100;
        int l = (int)(bitRate * length);
        double f = 1.0 / bitRate;
        Int16[] data = new Int16[l];
        for (int i = 0; i < l; i++)
        {
            data[i] = (Int16)(Math.Sin(hz * i * f * Math.PI * 2) * Int16.MaxValue);
        }
        return new Wave(false, Wave.MakeInt16WaveData(data));
    }

MakeInt16WaveData looks like this:

public static byte[] MakeInt16WaveData(Int16[] ints)
    {
        int s = sizeof(Int16);
        byte[] buf = new byte[s * ints.Length];
        for(int i = 0; i < ints.Length; i++)
        {
            Buffer.BlockCopy(BitConverter.GetBytes(ints[i]), 0, buf, i * s, s);
        }
        return buf;
    }

This works as expected! Now I wanted to swoop from one frequency to another like this:

public static Wave GetSineSwoop(double length, double hzStart, double hzEnd)
    {
        int bitRate = 44100;
        int l = (int)(bitRate * length);
        double f = 1.0 / bitRate;
        Int16[] data = new Int16[l];
        double hz;
        double hzDelta = hzEnd - hzStart;
        for (int i = 0; i < l; i++)
        {
            hz = hzStart + ((double)i / l) * hzDelta * 0.5; // why *0.5 ?
            data[i] = (Int16)(Math.Sin(hz * i * f * Math.PI * 2) * Int16.MaxValue);
        }
        return new Wave(false, Wave.MakeInt16WaveData(data));
    }

Now, when I swooped from 200 to 100 Hz, the sound played from 200 to 0 hertz. For some reason I had to multiply the delta by 0.5 to get the correct output. What might be the issue here ? Is this an audio thing or is there a bug in my code ?

Thanks

Edit by TaW: I take the liberty to add screenshots of the data in a chart which illustrate the problem, the first is with the 0.5 factor, the 2nd with 1.0 and the 3rd & 4th with 2.0 and 5.0:

enter image description here enter image description here enter image description here enter image description here

Edit: here is an example, a swoop from 200 to 100 hz: Debug values: Debug values Wave clearly does not end at 100 hz The resulting sine wave clearly does not end at 100 hz

1

There are 1 answers

0
TaW On BEST ANSWER

Digging out my rusty math I think it may be because:

Going in L steps from frequency F1 to F2 you have a frequency of

Fi = F1 + i * ( F2 - F1 ) / L

or with

( F2 - F1 ) / L = S

Fi = F1 + i * S

Now to find out how far we have progressed we need the integral over i, which would be

I(Fi) = i * F1 + 1/2 * i ^ 2 * S

Which give or take resembles the term inside your formula for the sine.

Note that you can gain efficiency by moving the constant part (S/2) out of the loop..