caudiosignal-processingtrigonometryalsa

Getting half the frequency and double the duration from a sine wave generated using C and played using aplay


I am trying to generate a sine wave of 440Hz frequency that lasts for 10 seconds using the following C code:

#include <stdio.h>
#include <math.h>

double sine(double amp, double freq, double time);

int main(int argc, char *argv[])
{
    int sample_rate = 48000;
    double freq = 440;
    double amp = 1;
    double duration = 10;
    double time = 0;
    double val = 0;
    int temp = 0;
    int i = 0;

    FILE *fp = fopen("sine.bin", "wb");
    if (fp == NULL)
    {
        return -1;
    }
    while (i <= sample_rate * duration)
    {
        val = 32767.0 * sine(amp, freq, time);
        temp = (int) val;
        fwrite((const void*) &temp, sizeof(int), 1, fp);
        time = i / (1.0 * sample_rate);
        i++;
    }
}

double sine(double amp, double freq, double time)
{
    return amp * sin(2.0 * M_PI * freq * time);
}

However, I am getting a sine wave of 220Hz that lasts for 20 seconds instead. How can I modify this code to produce a sine wave of 440Hz that lasts for 10 seconds? I have compiled and run this code using:

gcc sound.c  -Wall -Wextra -lm -o sound && ./sound
aplay -r 48000 -f S16_LE sine.bin

Solution

  • When trying to generate a 16-bit sound file, using int means it is 32-bit or 64-bit, so short must be used when working with 16-bit audio

    C Programming/limits.h

    #include <stdio.h>
    #include <math.h>
    
    double sine(double amp, double freq, double time);
    
    int main(int argc, char *argv[])
    {
        int sample_rate = 48000;
        double freq = 220;
        double amp = 1;
        double duration = 10;
        double time = 0;
        double val = 0;
        short temp = 0;
        int i = 0;
    
        FILE *fp = fopen("sine.bin", "wb");
        if (fp == NULL)
        {
            return -1;
        }
        while (i <= sample_rate*duration)
        {
            val = 32767.0*sine(amp, freq, time);
            temp = (short) val;
            fwrite((const void*) &temp,sizeof(short),1,fp);
            time = i/(1.0*sample_rate);
            i++;
        }
    }
    double sine(double amp, double freq, double time)
    {
            return amp*sin(2.0*M_PI*freq*time);
    }