home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / wavmix11.zip / wavmix.cpp < prev    next >
C/C++ Source or Header  |  1999-01-03  |  9KB  |  297 lines

  1. //
  2. // wavmx100.exe Audio mixer, requires MMPM/2
  3.  
  4. //
  5. // Things to add:  check to see if target drive has enough space?
  6.  
  7. #include <os2.h>
  8. #include <stdlib.h>
  9. #include <iostream.h>
  10. #define INCL_OS2MM
  11. #include <os2me.h>
  12. #include <assert.h>
  13.  
  14. #define COPYSIZE 4096*1024
  15.  
  16.  
  17. int copyaudio(HMMIO hmmiofrom, HMMIO hmmioto, LONG Bytes)
  18. {
  19.     // method allocates a buffer and does a standard copy from from to to
  20.  
  21.    PCHAR pAudio = NULL;
  22.    DosAllocMem((void **) &pAudio,COPYSIZE,PAG_WRITE | PAG_COMMIT);
  23.    assert(pAudio!=NULL);
  24.  
  25.    long BytesRead,BytesWritten;
  26.    long bytes_to_copy = Bytes;
  27.    do
  28.    {
  29.        if (bytes_to_copy > COPYSIZE)
  30.        {
  31.            //
  32.            // now read the FIRST file
  33.            BytesRead = mmioRead(hmmiofrom,(PCHAR)pAudio,COPYSIZE);
  34.            bytes_to_copy -= BytesRead;
  35.        }
  36.        else
  37.        {
  38.            BytesRead = mmioRead(hmmiofrom,(PCHAR)pAudio,bytes_to_copy);
  39.            bytes_to_copy -= BytesRead;
  40.        }
  41.        cout << "            Read " << BytesRead << " from source file, " << bytes_to_copy << " left " << endl;
  42.        
  43.        //
  44.        // write the new file
  45.        BytesWritten = mmioWrite(hmmioto,(PCHAR)pAudio,BytesRead);
  46.        assert(BytesRead==BytesWritten);
  47.    }
  48.    while(bytes_to_copy!=0);
  49.    DosFreeMem(pAudio);
  50.    return 0;
  51. }
  52.        
  53.  
  54. int main(int argc, char *argv[])
  55. {
  56.  
  57.     //
  58.     // initial seconds count, set to zero.
  59.     
  60.     int seconds = 0;
  61.  
  62.     //
  63.     // Here we say who we are...
  64.     cout << "WavMix Version 1.1 built " << __DATE__ << "  " << __TIME__ << endl;
  65.     cout << "Application mixes 44.1khz stereo wav files only." << endl;
  66.     cout << endl;
  67.  
  68.     if (argc < 5)
  69.     {
  70.         //
  71.         //
  72.         cout << endl;
  73.         cout << "     Usage:" << endl;
  74.         cout << "     Provide two source filenames, a target file name, the number of seconds" << endl;
  75.         cout << "     you wish to mix, optional flag to just produce a sample mix, " << endl;
  76.         cout << "     This program REQUIRES MMPM/2 to be installed." << endl;
  77.         cout << endl;
  78.         cout << " This application mixes 44.1khz stereo wav files only.  It will mix two" << endl;
  79.         cout << " source wav files and create a target wav file.  You set the amount of " << endl;
  80.         cout << " overlap in seconds.  WavMix will mix using the seconds of overlap.  A " << endl;
  81.         cout << " preview mode is provided.  Since wave files of this type are extremely " << endl;
  82.         cout << " large, it will produce  a target wav file of just the overlap so you " << endl;
  83.         cout << " may preview your mixdowns" << endl;
  84.         cout << endl;
  85.         cout << endl;
  86.         cout << " Sample command line" << endl;
  87.         cout << " [r:\\audio\\mixdown] wavmix track01.wav track02.wav output.wav 5 " << endl;
  88.         cout << "      Above line mixes track01.wav and track02.wav using 5 seconds " << endl;
  89.         cout << "      of overlap creating output.wav" << endl;
  90.         cout << endl;
  91.         cout << " [r:\\audio\\mixdown] wavmix track01.wav track02.wav output.wav 5 S" << endl;
  92.         cout << "      Above line mixes 5 seconds of audio from the end of track01.wav and the" << endl;
  93.         cout << "      start of track02.wav creating output.wav" << endl;
  94.         
  95.         cout << endl;
  96.         cout << endl;
  97.         cout << "     Support questions or comments to terryfry@toward.com" << endl;
  98.             
  99.             
  100.         cout << "Provide filename1 filename2 destinationfile secondtomix (Longcut)" << endl;
  101.         return 1;
  102.     }
  103.  
  104.     //
  105.     // set the type of mix we are going to do.  if this is true, we do a full mix, if its
  106.     // false, we only will do a "sample" of the mix part.
  107.    short longcut = TRUE;
  108.  
  109.    if (argc > 5)
  110.    {
  111.        if (strcmp(argv[5],"S")==0)
  112.        {
  113.            cout << "Output file will only be the overlap." << endl;
  114.            longcut = FALSE;
  115.        }
  116.    }
  117.        
  118.    
  119.    seconds= atoi(argv[4]);
  120.  
  121.    if (seconds == 0)
  122.    {
  123.        cout << " ERROR:  You cannot set seconds-to-mix to 0. " << endl;
  124.        return 5;
  125.    }
  126.  
  127.   
  128.    MMAUDIOHEADER mmAudioHeader,mmAudioHeader2;
  129.     
  130.     //
  131.     // open file1
  132.    HMMIO hmmio = mmioOpen(argv[1],NULL,MMIO_READ | MMIO_ALLOCBUF);
  133.    if (hmmio==0)
  134.    {
  135.        cout << "Failed to open file " << argv[1] << endl;
  136.        return 1;
  137.    }
  138.  
  139.    long BytesRead;
  140.    int rc = mmioGetHeader(hmmio,(PVOID)&mmAudioHeader,sizeof(MMAUDIOHEADER),&BytesRead,NULL,NULL);
  141.    if (rc)
  142.    {
  143.        cout << "Error on mmioGetHeader for file " << argv[1] <<  endl;
  144.    }
  145.  
  146.    //
  147.    // now open the second file
  148.  
  149.    HMMIO hmmio2 = mmioOpen(argv[2],NULL,MMIO_READ | MMIO_ALLOCBUF);
  150.    if (hmmio2==0)
  151.    {
  152.        cout << "ERROR: Failed to open file " << argv[2] << endl;
  153.        return 2;
  154.    }
  155.    
  156.    rc = mmioGetHeader(hmmio2,(PVOID)&mmAudioHeader2,sizeof(MMAUDIOHEADER),&BytesRead,NULL,NULL);
  157.    if (rc)
  158.    {
  159.        cout << "ERROR on mmioGetHeader 2 " << endl;
  160.        return 3;
  161.    }
  162.    
  163.    //
  164.    // now we are going to create another wave file
  165.  
  166.    MMIOINFO mmioinfo;
  167.  
  168.    memset(&mmioinfo,'\0',sizeof(mmioinfo));
  169.  
  170.    mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER+MMIO_TRANSLATEDATA;
  171.    mmioinfo.aulInfo[3] = MMIO_MEDIATYPE_AUDIO;
  172.    mmioinfo.fccIOProc = mmioFOURCC('W','A','V','E');
  173.    HMMIO hmmioTo = mmioOpen(argv[3],&mmioinfo,MMIO_CREATE+MMIO_WRITE);
  174.  
  175.    if (!hmmioTo)
  176.    {
  177.        cout << "ERROR : Could not create file." << argv[3] <<  endl;
  178.        return 1;
  179.    }
  180.  
  181.  
  182.    // here we calculate the OFFSET from the back of the file for the 5 second overlay
  183.    long audiosize = 176400 * seconds; // seconds of audio
  184.    long filesize1 = mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes;
  185.    long filesize2 = mmAudioHeader2.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes;
  186.    if (audiosize > filesize1)
  187.    {
  188.        cout << "ERROR, you cannot have a mix area that is larger than your source audio file. " << endl;
  189.        return 1;
  190.    }
  191.  
  192.    if (longcut != TRUE)
  193.    {
  194.        //
  195.        // install the new file size in the buffer
  196.        mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes = audiosize;
  197.        cout << "Total resulting file size is: " << audiosize << endl;
  198.    }
  199.  
  200.    if (longcut == TRUE)
  201.    {
  202.        //
  203.        // install the new file size in the buffer
  204.        mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes = filesize1 + filesize2;
  205.        cout << "Total resulting file size is: " << (filesize1 + filesize2) << endl;
  206.    }
  207.   
  208.   
  209.    //
  210.    // here we calculate the seekto, not necessary really with longcut
  211.    long seekto = filesize1 - audiosize;
  212.  
  213.    cout << "Attempting to mix " << seconds << " seconds " << endl;
  214.  
  215.    //
  216.    // first we copy the begining of file 1 to destfile
  217.    if (longcut==TRUE)
  218.    {
  219.        cout << "Copying " << seekto << " bytes" << endl;
  220.        copyaudio(hmmio,hmmioTo,seekto);
  221.    }
  222.    
  223.    
  224.    //
  225.    // now seek to the new location in file 1
  226.    LONG newPos = mmioSeek(hmmio,seekto,0);
  227.    assert(newPos == seekto);
  228.  
  229.    //
  230.    // allocate a buffer
  231.    PSHORT pAudio = NULL;
  232.    DosAllocMem((void **) &pAudio,audiosize,PAG_WRITE | PAG_COMMIT);
  233.  
  234.    //
  235.    // now read the FIRST file
  236.    BytesRead = mmioRead(hmmio,(PCHAR)pAudio,audiosize);
  237.    assert(BytesRead == audiosize);
  238.  
  239.    //
  240.    // now allocate the second buffer
  241.  
  242.    PSHORT pAudio2 = NULL;
  243.    DosAllocMem((void **) &pAudio2,audiosize,PAG_WRITE | PAG_COMMIT);
  244.  
  245.    //
  246.    // and read that in
  247.    BytesRead = mmioRead(hmmio2,(PCHAR)pAudio2,audiosize);
  248.    assert(BytesRead == audiosize);
  249.  
  250.    //
  251.    // now ADD them together?
  252.    long shortsize = audiosize/2;
  253.    for (unsigned long index = 0; index < shortsize ; index++)
  254.    {
  255.        short part1 = *(pAudio+index);
  256.        short part2 = *(pAudio2+index);
  257.        short result = part1 + part2;
  258.        *(pAudio+index) = result;
  259.            //       *(pAudio+index) = *(pAudio2+index) + *(pAudio+index);
  260.    }
  261.  
  262.  
  263.    //
  264.    // build the header
  265.    rc = mmioSetHeader(hmmioTo,&mmAudioHeader,sizeof(MMAUDIOHEADER),&BytesRead,0,0);
  266.    if (rc)
  267.    {
  268.        cout << "Error in mmioSetHeader" << endl;
  269.        return 1;
  270.    }
  271.  
  272.    //
  273.    // write the new file
  274.    rc = mmioWrite(hmmioTo,(PCHAR)pAudio,audiosize);
  275.    if (rc < 0)
  276.    {
  277.        cout << "ERROR during a write" << endl;
  278.    }
  279.  
  280.    //
  281.    // now, copy the rest of file 2
  282.    if (longcut == TRUE)
  283.    {
  284.        cout << "Copying " << filesize2 - audiosize << " bytes" << endl;
  285.        copyaudio(hmmio2,hmmioTo,filesize2 - audiosize);
  286.    }
  287.    DosFreeMem(pAudio);
  288.    DosFreeMem(pAudio2);
  289.    mmioClose(hmmio,0);
  290.    mmioClose(hmmio2,0);
  291.    mmioClose(hmmioTo,0);
  292.  
  293.    cout << "Finished, output file created" << endl;
  294.     
  295.     
  296. }
  297.