below code allows me to select and read a WAV file and display some information from that particular file. Output would be something like
What I want to do next in case of 2 channels is write the file into two new files (one for the left and one for the right channel).
In order to do that I will have to rewrite the Chunksize (=Subchunksize/2 + 36), change the number of channels to 1 (instead of 2) and devide the subchunksize by 2. Starting from byte 44, where the actually sound data start in block of two bytes (left and right channel), the even bytes are written to one and the odd bytes two the second new file.
I read the file in binary mode with
char c;
while (f.get(c))
and copy the data which doesn't change with
newFile.put(c)
to the new file.
My question actually is: in which format do I have to pass through for the newly calculated items. In other words what value should I give "c" to be written to the new file.
The layout of a WAV file is specified in a .csv file ("WAV Format_01.csv") and looks like:
0,4,ChunkID,n
4,4,ChunkSize,y
8,4,Format,n
12,4,Subchunk1ID,n
16,4,Subchunk1Size,y
20,2,AudioFormat,y
22,2,NumChannels,y
24,4,SampleRate,y
28,4,ByteRate,y
32,2,BlockAlig,y
34,2,BitsPerSample,y
36,4,Subchunk2ID,n
40,4,Subchunk2Size,y
44,9999,Data,y
Any help is much appreciated
#include <windows.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <conio.h>
#include <bitset>
#include <algorithm>
#include <limits>
#include <iomanip>
#include <limits>
#include <bitset>
#include <vector>
#include <iostream>
#include <complex>
#include <cmath>
#include <iterator>
using namespace std;
string DialogTitle;
int OutLine = 1;
int DiffFound = 0;
int PrintLine = 0;
int SampleCount=0;
int NumberChannels=0;
ifstream WAVFormat("WAV Format_01.csv", ios::in);
void str_replace( string &s, const string &search, const string &replace )
{
for( size_t pos = 0; ; pos += replace.length() )
{
pos = s.find( search, pos );
if( pos == string::npos ) break;
s.erase( pos, search.length() );
s.insert( pos, replace );
}
}
void split(const string& s, char c,
vector<string>& v) {
string::size_type i = 0;
string::size_type j = s.find(c);
while (j != string::npos) {
v.push_back(s.substr(i, j - i));
i = ++j;
j = s.find(c, j);
if (j == string::npos)
v.push_back(s.substr(i, s.length()));
}
}
struct WAFF
{
int bit; //bit number
int bsize; //bit length
string ID; //Header
string toDEC; // description of Header
};
vector<WAFF> FileFormat;
vector<WAFF>::iterator it;
WAFF Contents;
WAFF Contents1;
void read_bits(const char* path_to_file1)
{
int bitC = 0;
ifstream f(path_to_file1, ios::binary);
char c;
string e;
string hexString="";
string hexString1="";
int bitOn=0;
int prefBit=0;
string conHex;
int bitLength=0;
while (f.get(c)) {
if (bitC<44){
for (it = FileFormat.begin(); it < FileFormat.end(); it++) {
Contents1 = *it;
if(Contents1.bit==bitC){
stringstream d;
d<<bitC;
e = d.str();
cout<<e<< ": " ;
bitLength=Contents1.bsize;
bitOn=1;
conHex=Contents1.toDEC;
cout <<Contents1.ID << " ";
prefBit=bitC;
}
}
if(bitOn==1&&bitC-prefBit!=bitLength-1){
if(conHex.compare("n")==0){
hexString=hexString+c;
}else{
stringstream d1;
d1<<flush << setw(2) << setfill('0') << hex << (unsigned int)(unsigned char)(c);
hexString=d1.str()+hexString;
}
}
if(bitOn==1&&bitC-prefBit==bitLength-1){
if(conHex.compare("n")==0){
hexString=hexString+c;
}else{
stringstream d1;
d1<<flush << setw(2) << setfill('0') << hex << (unsigned int)(unsigned char)(c);
hexString=d1.str()+hexString;
const char *val=new const char[hexString.length()+1];
strcpy((char *)val,hexString.c_str());
unsigned long x;
x = strtoul(val, 0, 16);
std::string number;
std::stringstream strstream;
strstream << x;
strstream >> number;
hexString=hexString+" (decimal: "+number+")";
if(prefBit==22){NumberChannels=atoi(number.c_str());}
}
bitOn=0;
prefBit=0;
cout<<hexString<<"\n";
hexString="";
}
bitC++;
}else{
SampleCount++;
}
}
}
string openfilename(char *filter = "All Files (*.*)\0*.*\0", HWND owner = NULL) {
OPENFILENAME ofn;
char fileName[MAX_PATH] = "";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = owner;
ofn.lpstrTitle = DialogTitle.c_str();
ofn.lpstrFilter = filter;
ofn.lpstrFile = fileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = "";
string fileNameStr;
if (GetOpenFileName(&ofn))
fileNameStr = fileName;
return fileNameStr;
}
int main() {
cout << "-------------------------------------------------------------------------\n";
cout << " Reading WAV Format file...\n";
std::string line;
while (std::getline(WAVFormat, line))
{
vector<string> v;
split(line, ',', v);
Contents.bit = atoi(v[0].c_str());
Contents.bsize = atoi(v[1].c_str());
Contents.toDEC = v[3];
Contents.ID= v[2];
FileFormat.push_back(Contents);
}
DialogTitle = "Open File";
string FirstFile = openfilename();
ifstream Finfile(FirstFile.c_str());
cout << "-------------------------------------------------------------------------\n";
cout<<"File format\n\n";
DiffFound = 0;
read_bits(FirstFile.c_str());
stringstream d1;
d1<<SampleCount;
string e1 = d1.str();
cout<<"Number of samples found: "<<e1<<"\n";
cout<<"Number of Channels : "<<NumberChannels<<"\n";
cout << "-------------------------------------------------------------------------\n";
Finfile.close();
getch();
}
Aucun commentaire:
Enregistrer un commentaire