Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //mix 2 wav file
- //http://www.youtube.com/user/thecplusplusguy
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <cstring>
- bool isBigEndian()
- {
- int a=1;
- return !((char*)&a)[0];
- }
- int convertToInt(char* buffer,int len,bool n=false)
- {
- int a=0;
- bool neg; //we have to manually handle the negative sign in this case
- if(!isBigEndian())
- {
- neg=(buffer[len-1] & 128) ? 1 : 0;
- for(int i=0;i<len;i++)
- ((char*)&a)[i]=buffer[i];
- }else{
- neg=(buffer[0] & 128) ? 1 : 0;
- for(int i=0;i<len;i++)
- ((char*)&a)[sizeof(int)-1-i]=buffer[i];
- }
- if(!n)
- return a;
- else
- return a-(neg ? 65536 : 0);
- }
- //convert an integer to a char array
- void convertToChar(char* buffer,int data,int len)
- {
- for(int i=0;i<len;i++)
- buffer[i]=0;
- if(isBigEndian())
- {
- for(int i=0;i<len;i++)
- buffer[sizeof(int)-1-i]=((char*)&data)[i];
- }else{
- for(int i=0;i<len;i++)
- buffer[i]=((char*)&data)[i];
- }
- }
- //loads the wave file like in the tutorial
- char* loadWav(const char* filename,int& ochannels,int& osampleRate,int& osamplesPerSecond,int& osize)
- {
- std::ifstream in(filename,std::ios::binary);
- char tmpBuffer[4];
- in.read(tmpBuffer,4);
- if(strncmp(tmpBuffer,"RIFF",4)!=0)
- {
- std::cout << "This is not a valid WAV file (1) " << tmpBuffer[0] << tmpBuffer[1] << tmpBuffer[2] << tmpBuffer[3] << tmpBuffer[4] << '\n';
- return 0;
- }
- in.read(tmpBuffer,4);
- int sizeInBytes=convertToInt(tmpBuffer,4);
- in.read(tmpBuffer,4);
- if(strncmp(tmpBuffer,"WAVE",4)!=0)
- {
- std::cout << "This is not a valid WAV file (2) " << tmpBuffer[0] << tmpBuffer[1] << tmpBuffer[2] << tmpBuffer[3] << tmpBuffer[4] << '\n';
- return 0;
- }
- in.read(tmpBuffer,4);
- if(strncmp(tmpBuffer,"fmt ",4)!=0)
- {
- std::cout << "This is not a valid WAV file (3) " << tmpBuffer[0] << tmpBuffer[1] << tmpBuffer[2] << tmpBuffer[3] << tmpBuffer[4] << '\n';
- return 0;
- }
- in.read(tmpBuffer,4);
- int fmtSize=convertToInt(tmpBuffer,4);
- if(fmtSize!=16)
- {
- std::cout << "Sorry only PCM (not compressed WAV)" << fmtSize << '\n';
- return 0;
- }
- in.read(tmpBuffer,2);
- int PCM=convertToInt(tmpBuffer,2);
- if(PCM!=1)
- {
- std::cout << "Sorry only PCM (not compressed WAV)\n";
- return 0;
- }
- in.read(tmpBuffer,2);
- int channels=convertToInt(tmpBuffer,2);
- in.read(tmpBuffer,4);
- int samples=convertToInt(tmpBuffer,4);
- in.read(tmpBuffer,4);
- int byteRate=convertToInt(tmpBuffer,4);
- in.read(tmpBuffer,2);
- int blockAlign=convertToInt(tmpBuffer,2);
- in.read(tmpBuffer,2);
- int bitsPerSample=convertToInt(tmpBuffer,2);
- in.read(tmpBuffer,4);
- if(strncmp(tmpBuffer,"data",4)!=0)
- {
- std::cout << "This is not a valid WAV file (4) " << tmpBuffer[0] << tmpBuffer[1] << tmpBuffer[2] << tmpBuffer[3] << tmpBuffer[4] << '\n';
- return 0;
- }
- in.read(tmpBuffer,4);
- int dataSize=convertToInt(tmpBuffer,4);
- if(dataSize<=0)
- {
- std::cout << "This is not a valid WAV file (4) " << dataSize << '\n';
- return 0;
- }
- char* data=new char[dataSize];
- in.read(data,dataSize);
- ochannels=channels;
- osampleRate=bitsPerSample;
- osamplesPerSecond=samples;
- osize=dataSize;
- return data;
- }
- //writes out the file
- void writeWAV(const char* filename,char* data,int datasize,const char* original)
- {
- std::ifstream in(original,std::ios::binary);
- std::ofstream out(filename,std::ios::binary);
- char header[44]; //no conversation, use the same header as the original file (of course, you might want to change that)
- in.read(header,44);
- out.write(header,44);
- out.write(data,datasize);
- out.close();
- in.close();
- }
- int main()
- {
- int ch1,bps1,sps1,size1;
- int ch2,bps2,sps2,size2;
- char* buf1=loadWav("first.wav",ch1,bps1,sps1,size1);
- char* buf2=loadWav("second.wav",ch2,bps2,sps2,size2);
- char* mixed=NULL; //mixed, final result
- if(ch1!=ch2 || ch1>=2 || bps1!=bps2 || sps1!=sps2)
- {
- std::cout << "Sorry, in this demonstration the channels, bitpersample samplespersecond have to be equal, and no stereo" << std::endl;
- }else{
- int bytePerSample=bps1/8;
- char buf[2];
- if(size2>size1)
- {
- //swap buffers
- char* tmp=buf1;
- buf1=buf2;
- buf2=tmp;
- //swap size
- int itmp=size1;
- size1=size2;
- size2=itmp;
- }
- mixed=new char[size1];
- for(int i=0;i<size2;i+=bytePerSample) //either go byte-by-byte, or 2-byte at a loop (depent, if it's 8 bit or 16 bit per sample)
- {
- int sample1,sample2;
- sample1=convertToInt(buf1+i,bytePerSample,true);
- sample2=convertToInt(buf2+i,bytePerSample,true);
- int result=(sample1+sample2)/2; //get the avarage of two
- if(bytePerSample==1 && result>255) //2^8 - 1
- result=255;
- if(bytePerSample==2 && result>65536) //2^16 - 1
- result=65536;
- convertToChar(buf,result,bytePerSample);
- for(int j=0;j<bytePerSample;j++)
- {
- mixed[i+j]=buf[j];
- }
- }
- for(int i=size2;i<size1;i++) //copy the rest of the data (if there is)
- mixed[i]=buf1[i];
- writeWAV("mixed.wav",mixed,size1,"first.wav");
- std::cout << "mixed.wav created" << std::endl;
- }
- delete[] mixed;
- delete[] buf1;
- delete[] buf2;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement