/* sig2wav.cpp - AAEL .sig format to MIT WFDB-compatible .wav format conversion application Written for: Ann Arbor Electrogram Libraries http://www.electrogram.com Written by: Syed Mohammad Zethus Enterprises, LLC P.O. Box 130677, Ann Arbor, MI 48113 email: syed.mohammad@zethus.com http://www.zethus.com (c)2007 Ann Arbor Electrogram Libraries */ #include #include #include using namespace std; enum { TEXT, BINARY }; void printSizeOf() { cout << "sizeof(char) = " << sizeof(char) << endl; cout << "sizeof(short) = " << sizeof(short) << endl; cout << "sizeof(long) = " << sizeof(long) << endl; cout << "sizeof(int) = " << sizeof(int) << endl; cout << "sizeof(float) = " << sizeof(float) << endl; cout << "sizeof(double) = " << sizeof(double) << endl; }//printSizeOf int out16(ofstream &ofile, short x) { ofile.put(x & 0xff ); ofile.put((x >> 8) & 0xff ); return(2); }//out16 int out32(ofstream &ofile, long x) { ofile.put(x & 0xff ); ofile.put((x >> 8) & 0xff ); ofile.put((x >> 16) & 0xff); ofile.put((x >> 24) & 0xff); return(4); }//out32 int sig2txt(ifstream::pos_type size, char * memblock, string name) { int offset = 326; short chan = memblock[0]; int freq; memcpy(&freq, &memblock[2], 4); cout << "channels: " << chan << "\tfrequency: " << freq << " hz" << endl; ofstream ofile((name + ".txt").c_str(), ios::out); short val; do { for (int i = 0; i < chan; i++) { memcpy(&val, &memblock[offset+(i*2)], 2); ofile << val << "\t"; } ofile << endl; } while ((offset+=(chan*2)) < size); ofile.close(); return size; } //sig2txt int sig2wav(ifstream::pos_type size, char * memblock, string name) { int offset = 326; short chan = memblock[0]; int freq; memcpy(&freq, &memblock[2], 4); cout << "channels: " << chan << "\tfrequency: " << freq << " hz" << endl; ofstream ofile((name + ".wav").c_str(), ios::out|ios::binary); short val; //44byte header (0x00-0x2C) //(0x2C onwards = data) //[Header chunk] ofile.write("RIFF", 4); out32(ofile, ((int)size - 326) + 36); //size of remaining file ofile.write("WAVE", 4); //[Format chunk] ofile.write("fmt ", 4); out32(ofile, 16); //16 (format chunk length in bytes) out16(ofile, 1); //1 (format tag, no compresion) out16(ofile, chan); //number of signals out32(ofile, freq); //sampling frequency in Hz out32(ofile, freq*chan*2); //bytes per second out16(ofile, chan*2); //frame size (chan * 2 bytes/chan) out16(ofile, 12); //bits per sample (actual bits per sample) //[Data chunk] ofile.write("data", 4); out32(ofile, ((int)size - 326)); ofile.write(&memblock[326], (ifstream::pos_type)((int)size-326)); ofile.close(); return size; } //sig2wav void printHelp() { cout << "sig2wav usage:" << endl << endl << " to convert filename.sig to MIT WFDB-compatible WAV format filename.wav:" << endl << " sig2wav filename.sig" << endl << endl << " to convert filename.sig to tab-delimited TXT format filename.txt:" << endl << " sig2wav -t filename.sig" << endl << endl << " to display this help screen:" << endl << " sig2wav -h" << endl << endl << " (c)2007 Ann Arbor Electrogram Libraries http://www.electrogram.com" << endl; }//printHelp string getName(char * argv) { string name = string(argv); return(name.substr(0,name.find_last_of(".",name.size()))); }//getName int main (int argc, char ** argv) { ifstream::pos_type size; char * memblock; int outputMode = BINARY; //default to Binary output string name; if (argc < 2) { printHelp(); return 0; } if (!strcmp(argv[1], "-s") | !strcmp(argv[1], "-S")) { printSizeOf(); return 0; } if (!strcmp(argv[1], "-h") | !strcmp(argv[1], "-H") | !strcmp(argv[1], "-?") | !strcmp(argv[1], "?")) { printHelp(); return 0; } ifstream file; if (!strcmp(argv[1], "-t") | !strcmp(argv[1], "-T")) { outputMode = TEXT; if (argc < 3) { printHelp(); return 0; } file.open(argv[2], ios::in|ios::binary|ios::ate); name = getName(argv[2]); } else { file.open(argv[1], ios::in|ios::binary|ios::ate); name = getName(argv[1]); } cout << "processing file " << ((outputMode == TEXT) ? argv[2] : argv[1]) << endl; if (file.is_open()) { size = file.tellg(); memblock = new char [size]; file.seekg (0, ios::beg); file.read (memblock, size); file.close(); cout << size << " bytes loaded in memory" << endl; cout << ((outputMode == TEXT) ? sig2txt(size, memblock, name) : sig2wav(size, memblock, name)) << " bytes processed" << endl; delete[] memblock; } else cout << "unable to open file" << endl; return 0; }//main