如何在 C 中制作立体声波?

How can I make stereo wave sound in C?

虽然我想在C中制作立体声波形,但我可以找到单声道代码,这里是

#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 freq = 1000; 
    for (int i = 0; i < SAMPLE_RATE * DURATION * CHANNEL * BIT_RATE / 8; i++) {
        y[0] = (short)30000 * sin(2 * 3.141592 * i * freq / SAMPLE_RATE); 
        fwrite(&y[0], sizeof(short), 1, f_out);
        }


    fclose(f_out); 
        return 0; 
}

但我想将其更改为立体声(频道 2)。 具体来说,我希望我可以控制左声音功能和右声音功能(例如Left_sound[0] = ~~; right_sound[0] = ~~) 我的最终目标是让警笛向我靠近并远离我。 如何添加左右声道的功能??

重点是16位立体声数据在数据块中打包如下:

+-----------------+-----------------+-----------------+-----------------+
|    Left ch      |    Left ch      |    Right ch     |    Right ch     |
| low-order byte  | high-order byte | low-order byte  | high-order byte |
+-----------------+-----------------+-----------------+-----------------+

那么与您的代码的区别将是:

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

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

声音从左侧开始,靠近中心,然后通过 远离右边。
请注意您的代码中索引 i 的范围不正确,因为 i 的单位是样本,而不是字节。