Skip to content

Instantly share code, notes, and snippets.

@lxfly2000
Last active September 6, 2017 09:47
Show Gist options
  • Save lxfly2000/55b2193533e837a0ea450836a0de1548 to your computer and use it in GitHub Desktop.
Save lxfly2000/55b2193533e837a0ea450836a0de1548 to your computer and use it in GitHub Desktop.
音频分隔
#include<iostream>
#include<fstream>
#include<string>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
typedef short DataStructure_16BitMono;
struct WaveStructure
{
char strRIFF[4];
int chunkSize;
char strFormat[4];
char strFmt[4];
int subchunk1Size;
short audioFormat;
short numChannels;
int sampleRate;
int byteRate;
short blockAlign;
short bpsample;//Bits per sample
char strData[4];
int subchunk2Size;//Data size
DataStructure_16BitMono *eachSample;//Length is subchunk2Size/sizeof(DataStructure)
};
int WritePCM16BitMonoWaveFile(WaveStructure *wf,const char *fn, short *psample, int length)
{
FILE *pf;
fopen_s(&pf, fn, "wb");
wf->subchunk2Size = sizeof(DataStructure_16BitMono)*length;
wf->chunkSize = wf->subchunk2Size + 36;
fwrite(wf, 44, 1, pf);
fwrite(psample, wf->subchunk2Size, 1, pf);
fclose(pf);
return 0;
}
long long smplength, microslength;
int CalcBeforeSum(const DataStructure_16BitMono*p, int cur, int len)
{
int r = 0;
while (len)
{
r += abs(p[max(0, cur - len)]);
len--;
}
return r;
}
char timestr[13];
int ConvertTime(int smp)
{
return (int)(smp*microslength / smplength);
}
const char *ConvertTimeStr(int smp)
{
int mcs = ConvertTime(smp);
int s = mcs / 1000000;
mcs %= 1000000;
int minute = s / 60;
s %= 60;
sprintf_s(timestr, "%02d:%02d:%06d", minute, s, mcs);
timestr[8] = '\0';
return timestr;
}
int FindSplit(WaveStructure* pwave, const char *fn, int deltasmp, int sm)
{
int cursor = 0;
int accumusmp = 0;
int count = 0;
smplength = pwave->subchunk2Size / sizeof(DataStructure_16BitMono);
microslength = smplength * 1000000 / pwave->sampleRate;
char sfn[_MAX_PATH];
int ca = 0, cb = 0;
for (cursor = 0; cursor < smplength; cursor++)
{
if (pwave->eachSample[cursor] == 0 && accumusmp >= deltasmp&&pwave->eachSample[min(cursor + 1, smplength - 1)] && CalcBeforeSum(pwave->eachSample, cursor, sm) == 0)
{
ca = cb;
cb = cursor;
if (ca != 0)
{
sprintf_s(sfn, "SSG%d_%d.wav", count / 6, count % 6);
WritePCM16BitMonoWaveFile(pwave, sfn, pwave->eachSample + ca, cb - ca);
count++;
}
accumusmp = 0;
}
else accumusmp++;
}
sprintf_s(sfn, "SSG%d_%d.wav", count / 6, count % 6);
WritePCM16BitMonoWaveFile(pwave, sfn, pwave->eachSample + cb, smplength - cb);
return 0;
}
int main(int argc, char *argv[])
{
WaveStructure wf;
std::ifstream f;
std::string path;
if (argc > 1)
f.open(argv[1], std::ios::binary);
else
{
std::cout << "文件名:" << std::endl;
std::cin >> path;
f.open(path, std::ios::binary);
}
if (!f)
{
std::cout << "文件打开失败。" << std::endl;
return -1;
}
f.read((char*)&wf, 44);
if (wf.numChannels == 1 && wf.bpsample == 16)
{
wf.eachSample = reinterpret_cast<DataStructure_16BitMono*>(new char[wf.subchunk2Size]);
f.read((char*)wf.eachSample, wf.subchunk2Size);
int input;
int ds, silencesmp;
bool findatend = true;
do
{
std::cout << "1=查找,0=退出:";
std::cin >> input;
switch (input)
{
case 1:
std::cout << "输入间隔Sample,最少静音Sample:(3000 100)";
std::cin >> ds >> silencesmp;
FindSplit(&wf, path.c_str(), ds, silencesmp);
break;
case 0:default:
break;
}
} while (input);
delete[]wf.eachSample;
}
else
{
std::cout << "不支持的格式:" << wf.numChannels << "通道," << wf.bpsample << "位。" << std::endl;
}
f.close();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment