wav文件生成器

 * @FilePath: /Programs/TST/test.cpp
 * @Author: Infter
 * @Date: 2025-06-14 10:32:23
 * @LastEditTime: 2025-09-10 16:50:32
 */
 #include <bits/stdc++.h>

// WAV 文件头结构
struct WavHeader {
    char riff[4] = {'R', 'I', 'F', 'F'};
    uint32_t chunkSize;
    char wave[4] = {'W', 'A', 'V', 'E'};
    char fmt[4] = {'f', 'm', 't', ' '};
    uint32_t fmtChunkSize = 16;
    uint16_t audioFormat = 1; // PCM
    uint16_t numChannels;
    uint32_t sampleRate;
    uint32_t byteRate;
    uint16_t blockAlign;
    uint16_t bitsPerSample;
    char data[4] = {'d', 'a', 't', 'a'};
    uint32_t dataChunkSize;
};

void makeWave(std::vector<int16_t>& samples, double frequency, double duration, 
                     uint32_t sampleRate, double amplitude, double (*f)(int, double), double (*g)(int, double)) {
    int numSamples = static_cast<int>(duration * sampleRate);
    samples.reserve(samples.size() + numSamples);
    
    for (int i = 0; i < numSamples; i++) {
        double sample = amplitude * f(frequency, frequency * i / sampleRate);
        samples.push_back(int16_t(sample * 32767));
        sample = amplitude * g(frequency, frequency * i / sampleRate);
        samples.push_back(int16_t(sample * 32767));
    }
}

// 写入 WAV 文件
bool writeWavFile(const std::string& filename, const std::vector<int16_t>& samples, 
                 uint32_t sampleRate, uint16_t numChannels = 2) {
    std::ofstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "无法打开文件: " << filename << std::endl;
        return false;
    }
    
    WavHeader header;
    header.numChannels = numChannels;
    header.sampleRate = sampleRate;
    header.bitsPerSample = 16;
    header.byteRate = sampleRate * numChannels * header.bitsPerSample / 8;
    header.blockAlign = numChannels * header.bitsPerSample / 8;
    header.dataChunkSize = samples.size() * sizeof(int16_t);
    header.chunkSize = 36 + header.dataChunkSize;
    
    // 写入文件头
    file.write(reinterpret_cast<const char*>(&header), sizeof(header));
    
    // 写入音频数据
    file.write(reinterpret_cast<const char*>(samples.data()), 
               samples.size() * sizeof(int16_t));
    
    file.close();
    return true;
}

const uint32_t sampleRate = 44100; // 44.1 kHz
const double PI = acos(-1);
std::mt19937 rng(114514);
double cur;
double f(int fre, double a) { // 左声道
    int tt = int(a);
    double t = tt;
    a = a - t;
    if (tt & 1)
        t = double(tt % fre) / fre;
    else t = 1 - double(tt % fre) / fre;
    return sin((t + 0.5) * a * 2 * PI) * 0.2 + cos((1.5 - t) * a * 2 * PI) * 0.8;
}

double g(int fre, double a) { // 右声道
    int tt = int(a);
    double t = tt;
    a = a - t;
    if (tt & 1)
        t = double(tt % fre) / fre;
    else t = 1 - double(tt % fre) / fre;
    return sin((t + 0.5) * a * 2 * PI) * 0.8 + cos((1.5 - t) * a * 2 * PI) * 0.2;
}

int main() {
    
    std::vector<int16_t> samples;
    
    makeWave(samples, 330, 8, sampleRate, 0.8, f, g);
    
    if (writeWavFile("test.wav", samples, sampleRate)) {
        std::cout << "Done." << std::endl;
    }
    
    return 0;
}
posted @ 2025-09-10 16:56  Infter  阅读(35)  评论(2)    收藏  举报