Created
April 27, 2017 04:23
-
-
Save lxfly2000/82e5094f5baad9c4210aebff3b08e651 to your computer and use it in GitHub Desktop.
Find loop points in a wave file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<fstream> | |
#include<string> | |
struct DataStructure_16BitStereo | |
{ | |
short var_left, var_right; | |
}; | |
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_16BitStereo *eachSample;//Length is subchunk2Size/sizeof(Struct) | |
}; | |
int FindLoop(DataStructure_16BitStereo* pdata, int a, int b, int rsearch, int psearch, int rsum, int psum, bool atend) | |
{ | |
int minpos = 0; | |
int64_t minsquaresum = 0x7FFFFFFFFFFFFFFF, cur_sum; | |
int64_t tempa; | |
if (atend) | |
{ | |
std::cout << "位置\t双通道方差累计" << std::endl; | |
for (int j = -rsearch; j < rsearch; j += psearch) | |
{ | |
cur_sum = 0; | |
for (int i = -rsum; i < rsum; i += psum) | |
{ | |
tempa = (pdata[a + i].var_left - pdata[b + j + i].var_left); | |
cur_sum += tempa*tempa; | |
tempa = (pdata[a + i].var_right - pdata[b + j + i].var_right); | |
cur_sum += tempa*tempa; | |
} | |
if (cur_sum < minsquaresum) | |
{ | |
minsquaresum = cur_sum; | |
minpos = b + j; | |
} | |
std::cout << b + j << "\t" << cur_sum << std::endl; | |
} | |
std::cout << "查找[" << b - rsearch << "," << b + rsearch << "]完毕,符合条件的位置:" << minpos << | |
", 方差累计:" << minsquaresum << std::endl; | |
} | |
else | |
std::cout << "未实现。" << std::endl; | |
return minpos; | |
} | |
int main(int argc,char *argv[]) | |
{ | |
WaveStructure wf; | |
std::ifstream f; | |
if (argc > 1) | |
f.open(argv[1], std::ios::binary); | |
else | |
{ | |
std::string path; | |
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 == 2 && wf.bpsample == 16) | |
{ | |
wf.eachSample = reinterpret_cast<DataStructure_16BitStereo*>(new char[wf.subchunk2Size]); | |
f.read((char*)wf.eachSample, wf.subchunk2Size); | |
int input; | |
int loopa, loopb; | |
int radiussearch = 230, precisesearch = 1, rsum = 250, precsum = 10; | |
bool findatend = true; | |
do | |
{ | |
std::cout << "1=查找,2=定头,3=定尾,4=搜索半径(" << radiussearch << "),5=搜索精度(" << precisesearch << "),6=计算范围(" << rsum << "),7=计算精度(" << precsum << "),0=退出:"; | |
std::cin >> input; | |
switch (input) | |
{ | |
case 1: | |
std::cout << "输入起止Sample:"; | |
std::cin >> loopa >> loopb; | |
FindLoop(wf.eachSample, loopa, loopb, radiussearch, precisesearch, rsum, precsum, findatend); | |
break; | |
case 2:findatend = true; break; | |
case 3:findatend = false; break; | |
case 4:std::cin >> radiussearch; break; | |
case 5:std::cin >> precisesearch; break; | |
case 6:std::cin >> rsum; break; | |
case 7:std::cin >> precsum; 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