如何在C语言中发出警报声?

如何在C语言中发出警报声?,c,audio,wav,siren,C,Audio,Wav,Siren,我想发出警报声,频率每0.65秒变化960Hz和770Hz。(在8秒Wav文件中) 但我不知道如何构建我上面写的函数。 我尝试在每个句点使用“for(…=0;…

我想发出警报声,频率每0.65秒变化960Hz和770Hz。(在8秒Wav文件中) 但我不知道如何构建我上面写的函数。 我尝试在每个句点使用“for(…=0;…<0.65;…++)”。 但是y[0]和y[1]是函数,所以我很困惑。 我的最终目标是发出从右到左的警报声

说到这里,我想知道如何使频率每0.65秒改变960Hz和770Hz。 如果你能给我一些建议来实现我的最终目标,我将非常感谢你

由于我的英语不好,如果你很难理解我的问题,请评论我

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream> 

#pragma once 
#define WAVE_FORMAT_UNKNOWN 0X0000; 
#define WAVE_FORMAT_PCM 0X0001;
#define WAVE_FORMAT_MS_ADPCM 0X0002; 
#define WAVE_FORMAT_IEEE_FLOAT 0X0003; 
#define WAVE_FORMAT_ALAW 0X0006; 
#define WAVE_FORMAT_MULAW 0X0007; 
#define WAVE_FORMAT_IMA_ADPCM 0X0011; 
#define WAVE_FORMAT_YAMAHA_ADPCM 0X0016;
#define WAVE_FORMAT_GSM 0X0031; 
#define WAVE_FORMAT_ITU_ADPCM 0X0040; 
#define WAVE_FORMAT_MPEG 0X0050;
#define WAVE_FORMAT_EXTENSIBLE 0XFFFE;


#define DURATION 8 
#define SAMPLE_RATE 48000
#define CHANNEL 2
#define BIT_RATE 16

typedef struct {
    unsigned char ChunkID[4]; // Contains the letters "RIFF" in ASCII form 
    unsigned int ChunkSize; // This is the size of the rest of the chunk following this number 
    unsigned char Format[4]; // Contains the letters "WAVE" in ASCII form 
} RIFF;

typedef struct {
    unsigned char ChunkID[4]; // Contains the letters "fmt " in ASCII form 
    unsigned int ChunkSize; // 16 for PCM. This is the size of the rest of the Subchunk which follows this number. 
    unsigned short AudioFormat; // PCM = 1 
    unsigned short NumChannels; // Mono = 1, Stereo = 2, etc. 
    unsigned int SampleRate; // 8000, 44100, etc. 
    unsigned int AvgByteRate; // SampleRate * NumChannels * BitsPerSample/8 
    unsigned short BlockAlign; // NumChannels * BitsPerSample/8 
    unsigned short BitPerSample; // 8 bits = 8, 16 bits = 16, etc 
} FMT;

typedef struct {
    char ChunkID[4]; // Contains the letters "data" in ASCII form 
    unsigned int ChunkSize; // NumSamples * NumChannels * BitsPerSample/8 
} DATA;

typedef struct {
    RIFF Riff;
    FMT Fmt;
    DATA Data;
} WAVE_HEADER;



int main() {
    FILE* f_out;
    f_out = fopen("D:\\test.wav", "wb");

    WAVE_HEADER header;
    memcpy(header.Riff.ChunkID, "RIFF", 4);
    header.Riff.ChunkSize = DURATION * SAMPLE_RATE * CHANNEL * BIT_RATE / 8 + 36;
    memcpy(header.Riff.Format, "WAVE", 4);

    memcpy(header.Fmt.ChunkID, "fmt ", 4);
    header.Fmt.ChunkSize = 0x10;
    header.Fmt.AudioFormat = WAVE_FORMAT_PCM;
    header.Fmt.NumChannels = CHANNEL;
    header.Fmt.SampleRate = SAMPLE_RATE;
    header.Fmt.AvgByteRate = SAMPLE_RATE * CHANNEL * BIT_RATE / 8;
    header.Fmt.BlockAlign = CHANNEL * BIT_RATE / 8;
    header.Fmt.BitPerSample = BIT_RATE;

    memcpy(header.Data.ChunkID, "data", 4);
    header.Data.ChunkSize = DURATION * SAMPLE_RATE * CHANNEL * BIT_RATE / 8;

    fwrite(&header, sizeof(header), 1, f_out);

    short y[2]; 
    double high_freq = 960;
    double low_freq = 770;
    for (int i = 0; i < SAMPLE_RATE * DURATION; i++) {
        double level_l = (double)i / (SAMPLE_RATE * DURATION);
        double level_r = 1.0 - level_l;

        y[0] = (short)(30000 * sin(2 * 3.141592 * i * high_freq / SAMPLE_RATE) * level_l);
        y[1] = (short)(30000 * sin(2 * 3.141592 * i * low_freq / SAMPLE_RATE) * level_r);
        fwrite(&y[0], sizeof(short), 1, f_out);
        fwrite(&y[1], sizeof(short), 1, f_out);
    }


    fclose(f_out);
    return 0;
}
\define\u CRT\u SECURE\u NO\u警告
#包括
#包括
#布拉格语一次
#定义WAVE_格式_未知0X0000;
#定义波形格式\u PCM 0X0001;
#定义波形格式\u MS\u ADPCM 0X0002;
#定义波形格式IEEE浮点0X0003;
#定义WAVE_格式_ALAW 0X0006;
#定义波形格式公式0X0007;
#定义波形格式\u IMA\u ADPCM 0X0011;
#定义WAVE_格式_YAMAHA_ADPCM 0X0016;
#定义波形格式\u GSM 0X0031;
#定义WAVE\u格式\u ITU\u ADPCM 0X0040;
#定义WAVE_格式\u MPEG 0X0050;
#定义波形格式0XFFFE;
#定义持续时间8
#定义采样率48000
#定义通道2
#定义比特率16
类型定义结构{
unsigned char ChunkID[4];//包含ASCII格式的字母“RIFF”
unsigned int ChunkSize;//这是该数字后面的块的其余部分的大小
无符号字符格式[4];//包含ASCII格式的字母“WAVE”
}裂痕;
类型定义结构{
unsigned char ChunkID[4];//包含ASCII格式的字母“fmt”
unsigned int ChunkSize;//16用于PCM。这是此数字后面的子chunk的其余部分的大小。
无符号短音频格式;//PCM=1
无符号短数字通道;//单声道=1,立体声=2,等等。
无符号整数采样器;//8000、44100等。
unsigned int AvgByteRate;//SampleRate*NumChannels*BitsPerSample/8
无符号短块对齐;//NumChannels*BitsPerSample/8
无符号短位示例;//8位=8,16位=16,等等
}FMT;
类型定义结构{
char ChunkID[4];//包含ASCII格式的字母“data”
unsigned int ChunkSize;//NumSamples*NumChannels*BitsPerSample/8
}数据;
类型定义结构{
裂痕裂痕;
FMT-FMT;
数据;
}波头;
int main(){
文件*f_out;
f_out=fopen(“D:\\test.wav”、“wb”);
波头;
memcpy(header.Riff.ChunkID,“Riff”,4);
header.Riff.ChunkSize=持续时间*采样率*通道*比特率/8+36;
memcpy(header.Riff.Format,“WAVE”,4);
memcpy(header.Fmt.ChunkID,“Fmt”,4);
header.Fmt.ChunkSize=0x10;
header.Fmt.AudioFormat=波形\格式\ PCM;
header.Fmt.NumChannels=通道;
header.Fmt.SampleRate=采样率;
header.Fmt.AvgByteRate=采样率*通道*比特率/8;
header.Fmt.BlockAlign=通道*比特率/8;
header.Fmt.BitPerSample=比特率;
memcpy(header.Data.ChunkID,“数据”,4);
header.Data.ChunkSize=持续时间*采样率*通道*比特率/8;
fwrite(&header,sizeof(header),1,f_out);
短y[2];
双高频=960;
双低频=770;
对于(int i=0;i<采样率*持续时间;i++){
双水平i=(双)i/(采样率*持续时间);
双电平\u r=1.0-电平\u l;
y[0]=(短)(30000*sin(2*3.141592*i*高频/采样率)*电平);
y[1]=(短)(30000*sin(2*3.141592*i*低频/采样率)*电平);
fwrite(&y[0],sizeof(short),1,f_out);
fwrite(&y[1],sizeof(short),1,f_out);
}
fclose(f_out);
返回0;
}

您正在交替采样上输出两个频率中的每一个。即,左声道中一个频率的稳定音调和右声道中另一个频率的稳定音调

我们需要做的是在给定的子持续时间内保持相同的频率,并在它们之间切换。而且,相同的频率被馈入两个通道[尽管音量不同]

这里有一个轻微的重构可以做到这一点。它是注释的

我不确定您使用的级别(例如
level\u l
level\u r
)。我认为如果它们是相同的(即警报器越来越近),听起来会更好,因此我将
level\u r
作为一个选项设置为
level\u l
。但是,我保留了原始的L/R比例不变

编辑:听了以上内容后,当我缩短子持续时间时,警报器听起来更像是一个真正的[欧洲]警报器。我不确定现在还是0.65秒,但听起来更好(对我来说)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//#include <iostream>
#include <string.h>
#include <math.h>

//#pragma once
#define WAVE_FORMAT_UNKNOWN 0X0000;
#define WAVE_FORMAT_PCM 0X0001;
#define WAVE_FORMAT_MS_ADPCM 0X0002;
#define WAVE_FORMAT_IEEE_FLOAT 0X0003;
#define WAVE_FORMAT_ALAW 0X0006;
#define WAVE_FORMAT_MULAW 0X0007;
#define WAVE_FORMAT_IMA_ADPCM 0X0011;
#define WAVE_FORMAT_YAMAHA_ADPCM 0X0016;
#define WAVE_FORMAT_GSM 0X0031;
#define WAVE_FORMAT_ITU_ADPCM 0X0040;
#define WAVE_FORMAT_MPEG 0X0050;
#define WAVE_FORMAT_EXTENSIBLE 0XFFFE;

#define DURATION 8
#define SAMPLE_RATE 48000
#define CHANNEL 2
#define BIT_RATE 16

typedef struct {
    unsigned char ChunkID[4];           // Contains the letters "RIFF" in ASCII form
    unsigned int ChunkSize;             // This is the size of the rest of the chunk following this number
    unsigned char Format[4];            // Contains the letters "WAVE" in ASCII form
} RIFF;

typedef struct {
    unsigned char ChunkID[4];           // Contains the letters "fmt " in ASCII form
    unsigned int ChunkSize;             // 16 for PCM. This is the size of the rest of the Subchunk which follows this number.
    unsigned short AudioFormat;         // PCM = 1
    unsigned short NumChannels;         // Mono = 1, Stereo = 2, etc.
    unsigned int SampleRate;            // 8000, 44100, etc.
    unsigned int AvgByteRate;           // SampleRate * NumChannels * BitsPerSample/8
    unsigned short BlockAlign;          // NumChannels * BitsPerSample/8
    unsigned short BitPerSample;        // 8 bits = 8, 16 bits = 16, etc
} FMT;

typedef struct {
    char ChunkID[4];                    // Contains the letters "data" in ASCII form
    unsigned int ChunkSize;             // NumSamples * NumChannels * BitsPerSample/8
} DATA;

typedef struct {
    RIFF Riff;
    FMT Fmt;
    DATA Data;
} WAVE_HEADER;

int
main()
{
    FILE *f_out;

#if 0
    f_out = fopen("D:\\test.wav", "wb");
#else
    f_out = fopen("test.wav", "wb");
#endif

    WAVE_HEADER header;

    memcpy(header.Riff.ChunkID, "RIFF", 4);
    header.Riff.ChunkSize = DURATION * SAMPLE_RATE * CHANNEL * BIT_RATE / 8 + 36;
    memcpy(header.Riff.Format, "WAVE", 4);

    memcpy(header.Fmt.ChunkID, "fmt ", 4);
    header.Fmt.ChunkSize = 0x10;
    header.Fmt.AudioFormat = WAVE_FORMAT_PCM;
    header.Fmt.NumChannels = CHANNEL;
    header.Fmt.SampleRate = SAMPLE_RATE;
    header.Fmt.AvgByteRate = SAMPLE_RATE * CHANNEL * BIT_RATE / 8;
    header.Fmt.BlockAlign = CHANNEL * BIT_RATE / 8;
    header.Fmt.BitPerSample = BIT_RATE;

    memcpy(header.Data.ChunkID, "data", 4);
    header.Data.ChunkSize = DURATION * SAMPLE_RATE * CHANNEL * BIT_RATE / 8;

    fwrite(&header, sizeof(header), 1, f_out);

    short y[2];
    double high_freq = 960;
    double low_freq = 770;

#if 0
    for (int i = 0; i < SAMPLE_RATE * DURATION; i++) {
        double level_l = (double) i / (SAMPLE_RATE * DURATION);
        double level_r = 1.0 - level_l;

        y[0] = (short) (30000 * sin(2 * 3.141592 * i * high_freq / SAMPLE_RATE) * level_l);
        y[1] = (short) (30000 * sin(2 * 3.141592 * i * low_freq / SAMPLE_RATE) * level_r);
        fwrite(&y[0], sizeof(short), 1, f_out);
        fwrite(&y[1], sizeof(short), 1, f_out);
    }
#endif

#if 1
    // number of samples to flip on
#if 0
    int flipfreq = (SAMPLE_RATE * 65) / 100;
#else
    int flipfreq = (SAMPLE_RATE * 65) / 200;
#endif

    // current frequency to use
    int curtyp = 0;

    for (int i = 0; i < SAMPLE_RATE * DURATION; i++) {
        // after 0.65 seconds, change the frequency
        if ((i % flipfreq) == 0)
            curtyp = ! curtyp;

        // use the frequency for this period
        double cur_freq = curtyp ? high_freq : low_freq;

        double level_l = (double) i / (SAMPLE_RATE * DURATION);
#if 1
        double level_r = 1.0 - level_l;
#else
        double level_r = level_l;
#endif

        y[0] = (short) (30000 * sin(2 * 3.141592 * i * cur_freq / SAMPLE_RATE) * level_l);
        y[1] = (short) (30000 * sin(2 * 3.141592 * i * cur_freq / SAMPLE_RATE) * level_r);
        fwrite(&y[0], sizeof(short), 1, f_out);
        fwrite(&y[1], sizeof(short), 1, f_out);
    }
#endif

    fclose(f_out);
    return 0;
}
\define\u CRT\u SECURE\u NO\u警告
#包括
//#包括
#包括
#包括
//#布拉格语一次
#定义WAVE_格式_未知0X0000;
#定义波形格式\u PCM 0X0001;
#定义波形格式\u MS\u ADPCM 0X0002;
#定义波形格式IEEE浮点0X0003;
#定义WAVE_格式_ALAW 0X0006;
#定义波形格式公式0X0007;
#定义波形格式\u IMA\u ADPCM 0X0011;
#定义WAVE_格式_YAMAHA_ADPCM 0X0016;
#定义波形格式\u GSM 0X0031;
#定义WAVE\u格式\u ITU\u ADPCM 0X0040;
#定义WAVE_格式\u MPEG 0X0050;
#定义波形格式0XFFFE;
#定义持续时间8
#定义采样率48000
#定义通道2
#定义比特率16
类型定义结构{
unsigned char ChunkID[4];//包含ASCII格式的字母“RIFF”
unsigned int ChunkSize;//这是该数字后面的块的其余部分的大小
无符号字符格式[4];//包含ASCII格式的字母“WAVE”
}裂痕;
类型定义结构{
unsigned char ChunkID[4];//包含ASCII格式的字母“fmt”
unsigned int ChunkSize;//16用于PCM。这是此数字后面的子chunk的其余部分的大小。
无符号短音频格式;//PCM=1
无符号短数字通道;//单声道=1,立体声=2,等等。
无符号整数采样器;//8000,4410