网上有很多相关资料,但是90%都无法运行,原因应该是时代发展太快了,很多东西都不行
下代码是VS2019的可以运行的
// read_wave_2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
int load_wave_file( )
{
//第零步:从硬盘读取文件
FILE* fp;
fp = fopen("e:\\test3.wav", "rb");
if (!fp)
{
return -1;
}
//第一步:对RIFF区块的读取
char RIFF_id[5]; // 5个字节存储空间存储'RIFF'和'\0',这个是为方便利用strcmp
fread(RIFF_id, sizeof(char), 4, fp); // 读取'RIFF'
RIFF_id[4] = '\0';
if (strcmp(RIFF_id, "RIFF"))//零 这两个字符串相等。
{
return -1;
}
//
unsigned long RIFF_size; // 存储文件大小
fread(&RIFF_size, sizeof(unsigned long), 1, fp); // 读取文件大小
//
char RIFF_Type[5]; // 5个字节存储空间存储'RIFF'和'\0',这个是为方便利用strcmp
fread(RIFF_Type, sizeof(char), 4, fp); // 读取'RIFF'
RIFF_Type[4] = '\0';
if (strcmp(RIFF_Type, "WAVE"))
{
return -1;
}
//第二步:FORMAT区块
short format_Audio, Format_channels, format_block_align, format_bits_per_sample; // 16位数据
unsigned long format_length, format_sample_rate, format_bytes_sec ; // 32位数据
char FORMAT_id[5];
fread(FORMAT_id, sizeof(char), 4, fp); // 读取4字节 "fmt ";
FORMAT_id[4] = '\0';
fread(&format_length, sizeof(unsigned long), 1, fp);//Size表示该区块数据的长度(不包含ID和Size的长度)
fread(&format_Audio, sizeof(short), 1, fp); // 读取文件tag 音频格式
fread(&Format_channels, sizeof(short), 1, fp); // 读取通道数目
fread(&format_sample_rate, sizeof(unsigned long), 1, fp); // 读取采样率大小
fread(&format_bytes_sec, sizeof(unsigned long), 1, fp); // 每秒数据字节数= SampleRate * NumChannels * BitsPerSample / 8
fread(&format_block_align, sizeof(short), 1, fp); //每个采样所需的字节数 = NumChannels * BitsPerSample / 8
fread(&format_bits_per_sample, sizeof(short), 1, fp); // 每个采样存储的bit数,8:8bit,16:16bit,32:32bit
//第三步: DATA区块
char DATA_id[5];
fread(DATA_id, sizeof(char), 4, fp); // 读入'data'
DATA_id[4] = '\0';
if (strcmp(DATA_id, "data"))
{
return -1;
}
//
unsigned long gsz_data_size;//
fread(&gsz_data_size, sizeof(unsigned long), 1, fp); // 读取数据大小
//
char* gsz_data_data = new char[gsz_data_size];// 读取数据
fread(gsz_data_data, sizeof(char), gsz_data_size, fp);
gsz_data_data[gsz_data_size] = '\0';
//如果16位双通道,那么数据应该是L低字节,L高字节,R低字节,R高字节,
}
int main()
{
int a= load_wave_file( );
std::cout << "Hello World!\n";
}
*************
更新要给
// read_write_wave.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string.h>
using namespace std;
//声明一个函数:将wave文件从硬盘读取,并拆解
string read_wave_file();
//声明一个函数:将数据以WAVE格式写入硬盘
string write_wave_file();
//
char* m_gsz_data_data;
unsigned long m_gsz_data_size;//
int main()
{
string gsz_rerurn =read_wave_file();
std::cout<<"函数:read_wave_file的返回值----" << gsz_rerurn << "\n" << std::endl;
std::cout << "Hello World!\n";
}
//将wave文件从硬盘读取,并拆解
string read_wave_file()
{
//第零步:从硬盘读取文件
FILE* fp;
fp = fopen("e:\\test3.wav", "rb");
if (!fp)
{
return "error_fopen";
}
else
{
std::cout << "成功从硬盘找到并打开 wav文件\n";
}
//第一步:对RIFF区块的读取
char RIFF_id[5]; // 5个字节存储空间存储'RIFF'和'\0',这个是为方便利用strcmp
fread(RIFF_id, sizeof(char), 4, fp); // 读取'RIFF'
RIFF_id[4] = '\0';
if (strcmp(RIFF_id, "RIFF"))//零 这两个字符串相等。
{
return "error_RIFF_id";
}
//
unsigned long RIFF_size; // 存储文件大小
fread(&RIFF_size, sizeof(unsigned long), 1, fp); // 读取文件大小
//
char RIFF_Type[5]; // 5个字节存储空间存储'RIFF'和'\0',这个是为方便利用strcmp
fread(RIFF_Type, sizeof(char), 4, fp); // 读取'RIFF'
RIFF_Type[4] = '\0';
if (strcmp(RIFF_Type, "WAVE"))
{
return "error_WAVE";
}
//第二步:FORMAT区块
short format_Audio, Format_channels, format_block_align, format_bits_per_sample; // 16位数据
unsigned long format_length, format_sample_rate, format_bytes_sec; // 32位数据
char FORMAT_id[5];
fread(FORMAT_id, sizeof(char), 4, fp); // 读取4字节 "fmt ";
FORMAT_id[4] = '\0';
fread(&format_length, sizeof(unsigned long), 1, fp);//Size表示该区块数据的长度(不包含ID和Size的长度)
//若Format Chunk的size大小为18,则该模块的最后两个字节为附加信息
std::cout << "函数:read_wave_file--format_length----" << format_length << "\n" << std::endl;
if (18 == format_length)
{
std::cout << "函数:read_wave_file--该WAVE文件里面有附加信息块----" << "\n" << std::endl;
std::cout << "本程序,不支持 对附加信息读取!!!" << "\n" << std::endl;
}
else
{
std::cout << "函数:read_wave_file--该WAVE文件里面没有附加信息块----" << "\n" << std::endl;
}
//PCM信号采样 = 1
fread(&format_Audio, sizeof(short), 1, fp); // 读取文件tag 音频格式
std::cout << "函数:read_wave_file--音频格式----" << format_Audio << "\n" << std::endl;
fread(&Format_channels, sizeof(short), 1, fp); // 读取通道数目
std::cout << "函数:read_wave_file--通道数目----" << Format_channels << "\n" << std::endl;
fread(&format_sample_rate, sizeof(unsigned long), 1, fp); // 读取采样率大小
std::cout << "函数:read_wave_file--采样率大小----" << format_sample_rate << "\n" << std::endl;
fread(&format_bytes_sec, sizeof(unsigned long), 1, fp); // 每秒数据字节数= SampleRate * NumChannels * BitsPerSample / 8
std::cout << "函数:read_wave_file--每秒数据字节数----" << format_bytes_sec << "\n" << std::endl;
fread(&format_block_align, sizeof(short), 1, fp); //每个采样所需的字节数 = NumChannels * BitsPerSample / 8
std::cout << "函数:read_wave_file--每个采样所需的字节数----" << format_block_align << "\n" << std::endl;
fread(&format_bits_per_sample, sizeof(short), 1, fp); // 每个采样存储的bit数,8:8bit,16:16bit,32:32bit
std::cout << "函数:read_wave_file--每个采样存储的bit数----" << format_bits_per_sample << "\n" << std::endl;
//第三步: DATA区块
char DATA_id[5];
fread(DATA_id, sizeof(char), 4, fp); // 读入'data'
DATA_id[4] = '\0';
if (strcmp(DATA_id, "data"))
{
return "error_data";
}
//
unsigned long gsz_data_size;//
fread(&gsz_data_size, sizeof(unsigned long), 1, fp); // 读取数据大小
std::cout << "函数:read_wave_file--数据大小----" << gsz_data_size << "\n" << std::endl;
m_gsz_data_size = gsz_data_size;
//
char* gsz_data_data = new char[gsz_data_size];// 读取数据
m_gsz_data_data = gsz_data_data;
fread(gsz_data_data, sizeof(char), gsz_data_size, fp);
gsz_data_data[gsz_data_size] = '\0';
/*for (int i = 0; i < gsz_data_size; i++)
{
std::cout << "--数据内容----" <<i<<"--" << gsz_data_data[0] << "\n" << std::endl;
}*/
//如果16位双通道,那么数据应该是L低字节,L高字节,R低字节,R高字节,
return "read_wave_file_OK";
}
//将数据以WAVE格式写入硬盘
string write_wave_file()
{
return "write_wave_file_OK";
}
需要说明的是:
1)需要在
添加: _CRT_SECURE_NO_WARNINGS
2)程序是C++ WIN32控制器台程序
3)需要参考(音频-WAV数据格式_wenluderen的专栏-CSDN博客)
这个博文,用于学习PCM数据的存放格式