Thread: Mixing wav files using ANSI C

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    6

    Thumbs up Mixing wav files using ANSI C

    I'm a mere novice with any sort of programming and I need someone's help with a programming project.

    I'm looking to write a basic Visual C++ ANSI C program which will mix two audio wav files together. The program should operate in a DOS console and should simply request both the input files, the percentage mix, i.e. 50/50 mix etc, and the output filename.

    The filetype can be a 8 bit mono type.

    I need some help with what to do, some programming structure as to how I do it.

    I would also appreciate the code for how to go through the process cos as I say I have no real programming experience to speak of..........

    I'd be grateful for anyone's assistance in this, please mail back as soon as you can

  2. #2
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398
    need some help with what to do, some programming structure as to how I do it.

    I would also appreciate the code for how to go through the process cos as I say I have no real programming experience to speak of..........
    Hmmm.... This can be fairly easy*, but you will need to know some programming basics first. It's hard to do anything "interesting" without understanding variables & variable types, loops, and branching (if-statements). You will also need to know something about file I/O. And, if you are going to use C or C++, you'll need to understand functions.

    I suggest you start by working-through the C++ Made Easy Tutorial. I also suggest that you get a beginning C+ book. The tutorial is very abbreviated. A beginning book will cover essentially the same topics, but with 350-700 pages of detail and explanation. As you work-through the tutorial, you should be able to see how you can apply what you are learning to your project.

    Most tutorials and books jump right-into the particular language and are rather light on "general programming concepts" or "structure". Unless you are taking a formal class, you will have to pick-up this stuff as you go along, and do a bit of your own research. You could find books on these subjects, but they would probably be more-advanced books aimed at university-level computer science students.

    You can find the WAV file spec at Wotsit.org. I assume you know something about digital audio, and how the "wave" is stored as a series of individual samples. Like most technical specifications, it's fairly complicated and you might not understand it the first time you look at it... You will probably need to do some additional research.

    It will also help to look at some WAV files with a Hex Editor. You will be able to see the file header and the individual sample values. (You will be looking a bytes in hexadecimal format, so you'd have to combine the bytes to see 16-bit samples.) This may not make much sense at first, since most people are not used to working in hex. But, the hex editor will also show the ASCII character for each byte, so you will see the ASCII characters in the header. The hex editor doesn't know which bytes are supposed to represent ASCII characters, but with the spec in-hand, you will know which "characters" are meaningful, and which ones are actually audio data, etc.

    Visual C++ ANSI C program...
    Note that Visual C++ is the name of Microsoft's compiler. C and C++ are programming languages. Visual C++ includes ANSI C++ and a bunch of additional non-standard functions that allow you to write GUI programs etc. ... There is no graphics or sound in ANSI C++. You can write a pure ANSI C++ program to mix two audio files, but you'd need some non-ANSI functions in order to play the audio.


    * I'd consider this an "easy project" if you require the two WAV files to have the same format (Don't try to mix a 16-bit, 44.1kHz stereo file with an 8-bit 12kHz file) and if you only use the program for "regular" uncompressed WAV files. A beginning programming student could handle this "assignment" by the end of the semester, and probably sooner. If you wanted the ability to mix different formats and compressed files, I say that's an intermediate-to-advanced project.
    Last edited by DougDbug; 03-24-2008 at 04:35 PM.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    shouldn't this be added to the FAQ?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    6
    Hi DougDbug,

    Many thanks for your reply, am still having some difficulties with this. Do you have any more suggestions, parts of this just look very complicated. Are you aware of anyone who's tried doing this in the past

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It is not trivial to do this - you obviously will have to do some code to access the sound data. Reading wav files is not terribly difficult, but does require a little bit of work. Then comes the actual mixing process, which in a trivial variant is just an averaging algorithm, but for better result you probably need to use a more complex method.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    If you don't really have C++ experience, this is going to be hard to do in C++...

    For opening and reading/writing sound files, look at libsndfile. The API looks complex but you only need a few of the calls.

    As far as mixing, just make the weighted average of the corresponding signals. If you are mixing 70/30, you would produce output[i] = 0.7 * input1[i] + 0.3 * input2[i]. If that equation looks confusing I wouldn't try to tackle this project.
    Last edited by brewbuck; 04-01-2008 at 09:41 AM.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You just have to add all the samples at any point in time for the duration of the sound and place those in the final mix buffer. Averaging will cause the volumes to all merge on a central overall volume level which is why it's not a good idea.

  8. #8
    Registered User
    Join Date
    Mar 2008
    Posts
    6
    Thanks Guys for your responses,

    Was just wondering if anyone knew of any code to do part of this as I may be able to understand it a bit better if I have some code to look at. Have managed to specify the wav files and have got the program to read them in. Am just looking at how to mix them together....it need only be a 50/50 mix

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Mixing them together should be very easy - just read the raw data for both files, and produce a new WAV file based on the sum of the two [clamping to max and min values of course]

    --
    Mass
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Mar 2008
    Posts
    6
    Thanks matsp,

    Will try and do that, will it be ok to mail you if I need any more help

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by crouchy8 View Post
    Thanks matsp,

    Will try and do that, will it be ok to mail you if I need any more help
    No!

    Just post here, and someone will answer - that's much quicker than sending me a PM to find that I'm sleeping, eating or otherwise occupied elsewhere.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Bubba View Post
    You just have to add all the samples at any point in time for the duration of the sound and place those in the final mix buffer. Averaging will cause the volumes to all merge on a central overall volume level which is why it's not a good idea.
    Adding the samples is just... adding samples. He wants to mix. If you want to adjust volume, that's a separate issue.

    EDIT: Adding the two samples is a specific instance of mixing: 1.0*x+1.0*y. 0.7*x+0.3*y is another instance. There's nothing different here except the coefficients.

  13. #13
    Registered User
    Join Date
    Mar 2008
    Posts
    6
    Hey Guys,

    Am still trying to do this C program, have been making some progress but am still finding some of what are probably the easiest things in C really difficult.......

    Could someone have a little look over my code so far and tell me where I'm going wrong. This is the code I was looking to open a audio file in C, was trying to get it to output the contents of the file but wasn't having much luck......

    Code:
    #include <stdio.h>
    #include <avg_bytes_sec>
    #include <format_length>
    #include <format_tag>
    #include <channels>
    #include <sample_rate>
    #include <block_align>
    #include <bits_per_sample>
    #include <data_size>
    #include <sound_buffer>
    #include <string.h>
    
    public:
    
    char*   myPath;
    int   myChunkSize;
    int  mySubChunkSize;
          short  myFormat;
    short  myChannels;
    int  mySampleRate;
    int   myByteRate;
    short  myBlockAlign;
    short myBitsPerSample;
    
    ~ DING.WAVForIO()
    {
    	delete myPath;
    	myChunkSize = NULL;
    	mySubChunk1Size = NULL;
    	     myFormat = NULL;
        myChannels = NULL;
    	mySampleRate = NULL;
    	myByteRate = NULL;
    	myBlockAlign = NULL;
    	myBitsPerSample = NULL;
    	myDataSize = NULL;
    }
    
    void Load_Wave_File(char *fname) 
    { 
        FILE *fp; 
    
        fp = fopen("DING.WAV","rb"); 
        if (fp) 
        { 
            BYTE id[4], *sound_buffer; //four bytes to hold 'RIFF' 
            DWORD size; //32 bit value to hold file size 
            short format_tag, channels, block_align, bits_per_sample; //our 16 values 
            DWORD format_length, sample_rate, avg_bytes_sec, data_size, i; //our 32 bit values 
    
            fread(id, sizeof(BYTE), 4, fp); //read in first four bytes 
            if (!strcmp(id, "RIFF")) { //we had 'RIFF' let's continue 
                fread(size, sizeof(DWORD), 1, fp); //read in 32bit size value 
                fread(id, sizeof(BYTE), 4, fp); //read in 4 byte string now 
                if (!strcmp(id,"WAVE")) 
                { //this is probably a wave file since it contained "WAVE" 
                    fread(id, sizeof(BYTE), 4, fp); //read in 4 bytes "fmt "; 
                    fread(&format_length, sizeof(DWORD),1,fp); 
                    fread(&format_tag, sizeof(short), 1, fp); //check mmreg.h (i think?) for other 
                                                                  // possible format tags like ADPCM 
                    fread(&channels, sizeof(short),1,fp); //1 mono, 2 stereo 
                    fread(&sample_rate, sizeof(DWORD), 1, fp); //like 44100, 22050, etc... 
                    fread(&avg_bytes_sec, sizeof(short), 1, fp); //probably won't need this 
                    fread(&block_align, sizeof(short), 1, fp); //probably won't need this 
                    fread(&bits_per_sample, sizeof(short), 1, fp); //8 bit or 16 bit file? 
                    fread(id, sizeof(BYTE), 4, fp); //read in 'data' 
                    fread(&data_size, sizeof(DWORD), 1, fp); //how many bytes of sound data we have 
                    sound_buffer = (BYTE *) malloc (sizeof(BYTE) * data_size); //set aside sound buffer space 
                    fread(sound_buffer, sizeof(BYTE), data_size, fp); //read in our whole sound data chunk 
                } 
                else 
                    printf("Error: RIFF file but not a wave file\n"); 
            } 
            else 
                printf("Error: not a RIFF file\n"); 
        } 
    }
    I'm using Visual Studio 2008 to do this as I have recently downloaded programming software

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, first you should be clear on whether you want to program C or C++. Your code consists of a curious mix of elements of both languages, with the C++ parts used incorrectly.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    Registered User
    Join Date
    Mar 2008
    Posts
    6
    Hi,

    Was looking to code it in C, not C++.....

    What do I need to do change it over to C, is it a big change!!

    Can you give me some info

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program Deployment and DLL/OCX Files?
    By dfghjk in forum C++ Programming
    Replies: 5
    Last Post: 06-16-2008, 02:47 AM
  2. accessing all files in a folder.
    By pastitprogram in forum C++ Programming
    Replies: 15
    Last Post: 04-30-2008, 10:56 AM
  3. Wav files and winbase.h
    By ZapoTex in forum C Programming
    Replies: 5
    Last Post: 02-24-2005, 05:17 PM
  4. DLLs <- sound files, and nesting.
    By sean in forum C++ Programming
    Replies: 2
    Last Post: 10-28-2002, 05:13 PM
  5. reinserting htm files into chm help files
    By verb in forum Windows Programming
    Replies: 0
    Last Post: 02-15-2002, 09:35 AM