libsndfile的windows编译请参考官方文档<Using Vcpkg package manager>章节:libsndfile: A C library for reading and writing sound files containing sampled audio data. 音频文件基本处理操作库
windows 使用libsndfile库读取和保存音频文件(格式转换)
#include <sndfile.hh>
#pragma comment(lib, "sndfile.lib")
#pragma comment(lib, "vorbisenc.lib")
#pragma comment(lib, "vorbis.lib")
#pragma comment(lib, "FLAC.lib")
#pragma comment(lib, "ogg.lib")
#pragma comment(lib, "opus.lib")
#pragma comment(lib, "mpg123.lib")
#pragma comment(lib, "libmp3lame-static.lib")
#pragma comment(lib, "libmpghip-static.lib")
#pragma comment(lib, "shlwapi.lib")
//#pragma comment(lib, "advapi32.blib")
#include <fstream>
#include <iostream>
#include <vector>
int main()
{
SndfileHandle sndfile("biden-48k.ogg");
// 创建重采样对象
int sr = sndfile.samplerate();
int64_t framecount = sndfile.frames();
SndfileHandle dstsndfile("biden-16k.mp3", SFM_WRITE,
SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III, 1, 48000);
std::cout << "dst snd file:" << dstsndfile.strError() << std::endl;
std::fstream ofs_mp3("biden-48k.mp3", std::ios::binary);
SF_VIRTUAL_IO vir{
[](void* user_data) -> sf_count_t {
std::fstream* ifs = ((std::fstream*)user_data);
ifs->seekp(0, std::ios::end);
auto size = ifs->tellp();
ifs->seekp(0, std::ios::cur);
return size;
},
[](sf_count_t offset, int whence, void* user_data) -> sf_count_t {
std::fstream* ifs = ((std::fstream*)user_data);
ifs->seekg(offset, whence);
ifs->seekp(offset, whence);
return 0;
},
[](void* ptr, sf_count_t count, void* user_data) -> sf_count_t {
std::fstream* ifs = ((std::fstream*)user_data);
ifs->read((char*)ptr, count);
return ifs->gcount();
},
[](const void* ptr, sf_count_t count, void* user_data) ->sf_count_t {
((std::fstream*)user_data)->write((const char*)ptr, count);
return count;
},
[](void* user_data) -> sf_count_t {
return ((std::fstream*)user_data)->tellp();
} };
SndfileHandle dstsndfile1(vir, &ofs_mp3, SFM_WRITE,
SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III, 1, 48000);
std::cout << "dst snd file:" << dstsndfile.strError() << std::endl;
std::ofstream ofs("biden-48k.pcm", std::ios::binary);
int blocksize = sr / 100 * 2;
std::vector<int16_t> data(blocksize);
while (framecount - blocksize >= 0) {
sndfile.read(data.data(), data.size());
framecount -= blocksize;
// 重采样
ofs.write((const char*)data.data(), data.size() * sizeof(int16_t));
int ret = dstsndfile.writef(data.data(), data.size());
if (ret <= 0) {
std::cout << "write error: " << dstsndfile.strError() << std::endl;
}
dstsndfile1.write(data.data(), data.size());
}
return 0;
}