[AI应用实例系列1] 基于ChatGpt和DeepSeek 代码生成的对比

[AI应用实例系列1] 基于ChatGpt和DeepSeek 代码生成的对比

一直以来,我一直关注AI代码生成对我们工程应用的帮助。我后面会做一系列的应用实例来对比AI 代码生成对我们帮助。通过我的使用方式,希望能抛砖引玉方式给大家一些交流

本次应用场景:

在音频采集中 不同的波特率直接转换是一个比较麻烦事情,目前有一个应用,我们采集端驱动仅仅只 支持48000 16bit PCM 的双声道,但是输入源是44100 音频输入, 如果不转换会造成音频问题。 基于这个实际的应用场景,我们来开启这次AI 代码生成之旅。

1.工具准备

我们测试环境Windows: 编译工具VS2010
测试音频问题 44100 16bit PCM 的wav文件。
2.首先我分别向ChatGPT 和 DeekSeek 提出下面一个要求

我有一个音频处理的工作 需要用C语言实现 有下面一个工程
1.第一个函数实现从wav文件里读取 44.1K 双声道 16bit 到内存buffer 里
2. 第二个函数 实现 44.1K 音频文件转换48K 音频PCM 文件
3.第三个函数 实现 生产48KPCM 文件保存wav 文件

在DeepSeek 里面会生成如下code

#include 
#include 
#include 
#include 
#include 
#pragma pack(push, 1)
typedef struct {
char riff[4];
uint32_t fileSize;
char wave[4];
char fmt[4];
uint32_t fmtSize;
uint16_t audioFormat;
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
char data[4];
uint32_t dataSize;
} WavHeader;
#pragma pack(pop)
typedef struct {
int16_t* data;
uint32_t sampleCount;
uint16_t numChannels;
uint32_t sampleRate;
} AudioBuffer;
int read_wav(const char* filename, AudioBuffer* buffer) {
FILE* file = fopen(filename, "rb");
if (!file) {
perror("Failed to open file");
return -1;
}
WavHeader header;
if (fread(&header, sizeof(WavHeader), 1, file) != 1) {
fclose(file);
return -1;
}
// 验证头部信息
if (memcmp(header.riff, "RIFF", 4) != 0 ||
memcmp(header.wave, "WAVE", 4) != 0 ||
memcmp(header.fmt, "fmt ", 4) != 0 ||
memcmp(header.data, "data", 4) != 0) {
fclose(file);
return -1;
}
// 检查格式是否符合要求
if (header.audioFormat != 1 || // PCM格式
header.numChannels != 2 ||
header.sampleRate != 44100 ||
header.bitsPerSample != 16) {
fclose(file);
return -1;
}
// 分配内存
buffer->sampleCount = header.dataSize / (header.numChannels * sizeof(int16_t));
buffer->data = (int16_t*)malloc(header.dataSize);
buffer->numChannels = header.numChannels;
buffer->sampleRate = header.sampleRate;
// 读取PCM数据
if (fread(buffer->data, 1, header.dataSize, file) != header.dataSize) {
free(buffer->data);
fclose(file);
return -1;
}
fclose(file);
return 0;
}
int resample_44k_to_48k(const AudioBuffer* input, AudioBuffer* output) {
const double ratio = 48000.0 / 44100.0;
const uint32_t outSamples = (uint32_t)(input->sampleCount * ratio + 0.5);

output->sampleRate = 48000;
output->numChannels = input->numChannels;
output->sampleCount = outSamples;
output->data = (int16_t*)malloc(outSamples * input->numChannels * sizeof(int16_t));

if (!output->data) return -1;
for (uint32_t i = 0; i < outSamples; ++i) {
double pos = i / ratio;
uint32_t index = (uint32_t)pos;
double frac = pos - index;
for (int ch = 0; ch < input->numChannels; ++ch) {
int16_t s0 = input->data[index * input->numChannels + ch];
int16_t s1 = (index + 1 < input->sampleCount) ?
input->data[(index + 1) * input->numChannels + ch] : s0;

// 线性插值
double sample = s0 + (s1 - s0) * frac;
output->data[i * input->numChannels + ch] = (int16_t)sample;
}
}
return 0;
}
int write_wav(const char* filename, const AudioBuffer* buffer) {
WavHeader header = {
.riff = {'R','I','F','F'},
.wave = {'W','A','V','E'},
.fmt = {'f','m','t',' '},
.fmtSize = 16,
.audioFormat = 1,
.numChannels = buffer->numChannels,
.sampleRate = buffer->sampleRate,
.bitsPerSample = 16,
.data = {'d','a','t','a'}
};
header.byteRate = buffer->sampleRate * buffer->numChannels * 2;
header.blockAlign = buffer->numChannels * 2;
header.dataSize = buffer->sampleCount * buffer->numChannels * 2;
header.fileSize = sizeof(WavHeader) - 8 + header.dataSize;
FILE* file = fopen(filename, "wb");
if (!file) return -1;
if (fwrite(&header, sizeof(WavHeader), 1, file) != 1) {
fclose(file);
return -1;
}
if (fwrite(buffer->data, 1, header.dataSize, file) != header.dataSize) {
fclose(file);
return -1;
}
fclose(file);
return 0;
}
int main() {
AudioBuffer input, output;

if (read_wav("input.wav", &input) != 0) {
printf("Error reading input file\n");
return 1;
}
if (resample_44k_to_48k(&input, &output) != 0) {
printf("Resampling failed\n");
free(input.data);
return 1;
}
if (write_wav("output.wav", &output) != 0) {
printf("Error writing output file\n");
}
free(input.data);
free(output.data);
return 0;
}

我们用ChatGpt 生产代码如下

#include 
#include 
#include 
#include <sys/types.h>
// 定义 WAV 文件头结构体
typedef struct {
char chunk_id[4];
int chunk_size;
char format[4];
char subchunk1_id[4];
int subchunk1_size;
short audio_format;
short num_channels;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
char subchunk2_id[4];
int subchunk2_size;
} WavHeader;
// 第一个函数:从 WAV 文件读取 44.1K 双声道 16bit 到内存 buffer
void read_wav_file(const char *filename, short **buffer, int *buffer_size) {
int fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("Failed to open file");
return;
}
WavHeader header;
read(fd, &header, sizeof(WavHeader));
if (header.sample_rate!= 44100 || header.num_channels!= 2 || header.bits_per_sample!= 16) {
close(fd);
perror("Invalid WAV file format");
return;
}
*buffer_size = header.subchunk2_size / sizeof(short);
*buffer = (short *)sbrk(*buffer_size * sizeof(short));
read(fd, *buffer, header.subchunk2_size);
close(fd);
}
// 第二个函数:44.1K 音频文件转换为 48K 音频 PCM 文件
void resample_44100_to_48000(short *input_buffer, int input_size, short **output_buffer, int *output_size) {
double ratio = 48000.0 / 44100.0;
*output_size = (int)(input_size * ratio);
*output_buffer = (short *)sbrk(*output_size * sizeof(short));
for (int i = 0; i < *output_size; i++) {
double input_index = i / ratio;
int index_floor = (int)input_index;
int index_ceil = (index_floor + 1 < input_size)? index_floor + 1 : index_floor;
double fraction = input_index - index_floor;
*(*output_buffer + i) = (short)((1 - fraction) * input_buffer[index_floor] + fraction * input_buffer[index_ceil]);
}
}
// 第三个函数:生成 48K PCM 文件并保存为 WAV 文件
void save_pcm_to_wav(const char *filename, short *pcm_buffer, int pcm_size) {
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("Failed to open file");
return;
}
WavHeader header;
header.chunk_id[0] = 'R';
header.chunk_id[1] = 'I';
header.chunk_id[2] = 'F';
header.chunk_id[3] = 'F';
header.chunk_size = 36 + pcm_size * sizeof(short);
header.format[0] = 'W';
header.format[1] = 'A';
header.format[2] = 'V';
header.format[3] = 'E';
header.subchunk1_id[0] = 'f';
header.subchunk1_id[1] = 'm';
header.subchunk1_id[2] = 't';
header.subchunk1_id[3] = ' ';
header.subchunk1_size = 16;
header.audio_format = 1;
header.num_channels = 2;
header.sample_rate = 48000;
header.byte_rate = 48000 * 2 * 2;
header.block_align = 2 * 2;
header.bits_per_sample = 16;
header.subchunk2_id[0] = 'd';
header.subchunk2_id[1] = 'a';
header.subchunk2_id[2] = 't';
header.subchunk2_id[3] = 'a';
header.subchunk2_size = pcm_size * sizeof(short);
write(fd, &header, sizeof(WavHeader));
write(fd, pcm_buffer, pcm_size * sizeof(short));
close(fd);
}
int main() {
short *input_buffer;
int input_size;
read_wav_file("input.wav", &input_buffer, &input_size);
short *output_buffer;
int output_size;
resample_44100_to_48000(input_buffer, input_size, &output_buffer, &output_size);
save_pcm_to_wav("output.wav", output_buffer, output_size);
return 0;
}

两个AI 生成Code 大体看起来 差不多, 打开wav 和保存wav框架差不多 这里生成的 wav 头文件同时有错误.(当红色标注地方 )

Deepseek 生成 Code

typedef struct {
char riff[4];
uint32_t fileSize;
char wave[4];
char fmt[4];
uint32_t fmtSize;
uint16_t audioFormat;
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
char data[4];
uint32_t dataSize;
} WavHeader;

ChatGPT 生成

typedef struct {
char chunk_id[4];
int chunk_size;
char format[4];
char subchunk1_id[4];
int subchunk1_size;
short audio_format;
short num_channels;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
char subchunk2_id[4];
int subchunk2_size;
} WavHeader;

正常修正的code

typedef struct {
char riff[4];
uint32_t fileSize;
char wave[4];
char fmt[4];
uint32_t fmtSize;
uint16_t audioFormat;
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
uint16_t cbSize;
char data[4];
uint32_t dataSize;
} WavHeader;

接下来我们来看 打开wav 函数 我们发现 DeepSeek 可以正常编译 但是 ChatGPT 生成Code 无法正常编译 因为内存分配函数 ChatGPT 用的函数

*buffer = (short *)sbrk(*buffer_size * sizeof(short));

而DeepSeeek 使用的函数

buffer->data = (int16_t*)malloc(header.dataSize);

可以编译通过。

我们看一下保存Wav 函数 :其中Wav 文件头文件的变量初始化代码。

测试发现VS2010 编译器 DeepSeek 初始化方式不支持。两个大体生成没有问题。这里需修正 .fmtSize = 16+2;(文件头有问题要支持24位头需要多一个Short)

DeepSeek 生成code

WavHeader header = {
.riff = {'R','I','F','F'},
.wave = {'W','A','V','E'},
.fmt = {'f','m','t',' '},
.fmtSize = 16,
.audioFormat = 1,
.numChannels = buffer->numChannels,
.sampleRate = buffer->sampleRate,
.bitsPerSample = 16,
.data = {'d','a','t','a'}
};
header.byteRate = buffer->sampleRate * buffer->numChannels * 2;
header.blockAlign = buffer->numChannels * 2;
header.dataSize = buffer->sampleCount * buffer->numChannels * 2;
header.fileSize = sizeof(WavHeader) - 8 + header.dataSize;

ChatGPT 生成Code

WavHeader header;
header.chunk_id[0] = 'R';
header.chunk_id[1] = 'I';
header.chunk_id[2] = 'F';
header.chunk_id[3] = 'F';
header.chunk_size = 36 + pcm_size * sizeof(short);
header.format[0] = 'W';
header.format[1] = 'A';
header.format[2] = 'V';
header.format[3] = 'E';
header.subchunk1_id[0] = 'f';
header.subchunk1_id[1] = 'm';
header.subchunk1_id[2] = 't';
header.subchunk1_id[3] = ' ';
header.subchunk1_size = 16;
header.audio_format = 1;
header.num_channels = 2;
header.sample_rate = 48000;
header.byte_rate = 48000 * 2 * 2;
header.block_align = 2 * 2;
header.bits_per_sample = 16;
header.subchunk2_id[0] = 'd';
header.subchunk2_id[1] = 'a';
header.subchunk2_id[2] = 't';
header.subchunk2_id[3] = 'a';
header.subchunk2_size = pcm_size * sizeof(short);

基本上两者生成测试和生成测试文件代码可以看出 两者差不多 修改一下可以接受。

下面我们重点来测试两个AI 生成 我们主功能的 这才是我们今天对比的重点。

我们测试样板 44100HZ 的正弦波wav文件通过本测试程序 我们在对生成的文件进行FFT 波形对比 看看两个生成Code 质量如何:

我们测试Deepseek,ChatGPT 对比图如下

输入的wave 文件

DeepSeek 处理后的文件

ChatGPT 生产的文件

对比的结果不言而喻。

如果需要完整的测试Code可以私信给我。