////////////////////AtoWav.cpp/////////////// ///Converte un flusso di float ASCII in Formato Windows WAV ///By Fischetti P ////////////////////AtoWav.cpp////////////////////////// /////////ASCII to Windows Wav Converter///////////////// #include #include #include #include #include #include #include #include #include #include #include using namespace std; #include int mNChans=1; int mBitsXSample = 8; float mSRate=16384; #define sign(x) ((x > 0) - (x < 0)) typedef double SampleType; #if _MSC_VER <= 1200 typedef unsigned short UINT16; typedef unsigned int UINT32; #endif int verbose=0; void Help(const char *ProgName) { cerr << ProgName; cerr << " - "; cerr << "Convert ASCII Stream to Windows WAV File"< out.wav" << endl; cerr << endl << "Warn: If nChannels=2 and -2ChannelFile is missing stream input must be overlapped" << endl; } struct WaveHeader { char RIFF[4]; UINT32 DataLength; char WAVE[4]; char fmt_[4]; UINT32 SubBlockLength; UINT16 formatTag; UINT16 Channels; UINT32 SampFreq; UINT32 BytesPerSec; UINT16 BytesPerSamp; UINT16 BitsPerSamp; char data[4]; UINT32 WaveSize; }; bool FlushWAVEHeader(ostream &outfile, const unsigned long DataSize) { long flen; long fpos; long DataLength = DataSize + sizeof(WaveHeader) - 8; fpos = outfile.tellp(); flen = fpos - 1; outfile.seekp(4); outfile.write((const char *)&DataLength,sizeof(DataLength)); outfile.seekp(40); outfile.write((const char *)&DataSize,sizeof(DataSize)); return true; } short Encode16Bit(SampleType x) { x=(fabs(x)<=1)? x : sign(x); if(verbose){ cerr << dec << x; cerr <<"\t0x" << setfill('0') << setw(4) << hex << (short)((float)x * (1. * SHRT_MAX)) << endl; } return (short)((float)x * (1. * SHRT_MAX)); } char Encode8Bit(SampleType x) { x=(fabs(x)<=1)? x : sign(x); char b = (char)(x * CHAR_MAX); b += 128; if(verbose){ cerr << dec << x; cerr <<"\t0x" << setfill('0') << setw(2) << hex << (short(b) & 0x00FF) << endl; } return b; } SampleType Decode16Bit(const short &s) { double y=s; y /= SHRT_MAX; return y; } SampleType Decode8Bit(const char &b) { double y=(b & 0x00FF - 0x80);; y /= CHAR_MAX; return y; } void createWAVHeader(WaveHeader &header,int NSamples,float SampleFrequency,int BitsPerSample,int nChans) { UINT32 frequency = static_cast(SampleFrequency); if (nChans != 1 && nChans != 2) nChans =1; UINT16 channels = nChans; UINT16 bitsPerSample = BitsPerSample; UINT16 bytesPerSample = BitsPerSample/8; if (bitsPerSample > 16) bitsPerSample = 16; UINT32 bytesPerSec = frequency * channels * bytesPerSample; UINT32 waveSize = NSamples * channels * bytesPerSample ;// .getSamplesCount() strncpy(header.RIFF, "RIFF", 4); header.DataLength = waveSize + sizeof(WaveHeader) - 8; strncpy(header.WAVE, "WAVE", 4); strncpy(header.fmt_, "fmt ", 4); header.SubBlockLength = 16; header.formatTag = WAVE_FORMAT_PCM;//1 header.Channels = channels; header.SampFreq = frequency; header.BytesPerSec = bytesPerSec; header.BytesPerSamp = header.Channels * bytesPerSample ; header.BitsPerSamp = bitsPerSample; strncpy(header.data, "data", 4); header.WaveSize = waveSize; } void WriteWAVHeader(ostream &out,WaveHeader &header) { out.write((const char*)(&header), sizeof(WaveHeader)); } bool GetSample(istream &ifs, SampleType &x) { if (ifs.rdstate() & ios::eofbit) return false; if(ifs >> x) return true; else return false; } bool WriteSample(ostream &out,const SampleType &x,const int &BytesXSample) { short s=0; char b=0; if (2 == BytesXSample) { s = Encode16Bit(x); out.write((const char *)&s,sizeof(s)); } else { b = Encode8Bit(x); out.write((const char *)&b,sizeof(b)); } if (isatty(fileno(stdout))) out << endl; return true; } int main(int argc, char *argv[]) { char **pargv = argv; char *sChannel1 = NULL; char *sChannel2 = NULL; ifstream fs2; int BytesXSample=0; try{ while (*pargv != NULL) { if (strncmp(*pargv,"/?",2)==0 || strncmp(*pargv,"-?",2)==0) { Help(argv[0]); return 1; } if (strncmp(*pargv,"-c",2)==0) { mNChans=atoi((*pargv+2)); }; if (strncmp(*pargv,"-R",2)==0) { mSRate=(float)atof((*pargv+2)); }; if (strncmp(*pargv,"-b",2)==0) { mBitsXSample=atoi(*pargv +2); }; if (strncmp(*pargv,"-1",2)==0) { sChannel1=(*pargv+2); }; if (strncmp(*pargv,"-2",2)==0) { sChannel2=(*pargv+2); }; if (strncmp(*pargv,"-v",2)==0) { verbose=1; }; pargv++; }; if (2== mNChans && sChannel2) { fs2.open(sChannel2,ios::in); if (!fs2) throw "Error Opening File2" ; } SampleType x=0; short s=0; char b = 0; unsigned long NSamples=0; WaveHeader wh; BytesXSample=mBitsXSample/8; if (!isatty(fileno(stdout))) { setmode (fileno (stdout), O_BINARY); createWAVHeader(wh, 0*mNChans, mSRate, mBitsXSample,mNChans);// mNChans WriteWAVHeader(cout,wh); } else throw "Missing Out File" ; NSamples=0; if (1 == wh.Channels) { while( GetSample(cin,x)) { if(!cin.eof() && WriteSample(cout,x,BytesXSample)) NSamples++; } } else { int NSamples1=0,NSamples2=0; if(NULL != sChannel2) { while(!(cin.eof() && fs2.eof())) { if(!cin.eof()) GetSample(cin,x); else x=0; if(WriteSample(cout,x,BytesXSample)) NSamples1++; if (!fs2.eof()) GetSample(fs2,x); else x=0; if(WriteSample(cout,x,BytesXSample)) NSamples2++; } } else { while( GetSample(cin,x)) { if(!cin.eof()){ if(WriteSample(cout,x,BytesXSample)) NSamples1++;} } } NSamples = max(NSamples1,NSamples2); } //NSamples /=mNChans; if (!isatty(fileno(stdout))) FlushWAVEHeader(cout,NSamples * mNChans * (BytesXSample)); if (fs2.is_open()) fs2.close(); } catch(const char * str ) { cerr << str << endl; return -1; } return 0; }