Thread: Read and edit .wav file

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    163

    Read and edit .wav file

    I have a program that manipulates .wav file to be 8bit 8000hz mono. After that I need to strip the headers and do various stuff to the samples.
    I'm having trouble with stripping the .wav headers, though. I thought it would just read the file in character by character then resave without the header bytes. Unfortunately the code doesn't do what I expected. I've been working on this for a while, so I'm probably just missing something stupidly simple, but some help would be great.

    Given a .wav file:
    Code:
    RIFF˜WAVEfmt @@data”ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÅÇÇÇÇÉÉÉÑÑÑÑÑÉÇÄ}{zyxwwwxyz{{||}~ÄÅÇÇÑÖÖÖÖÑÑÑÉÇÇÅÄÄÄÄÅÇÇÑÖÜÜáááààààáÜÑÉÇÅ}|{yxwwwwxz{|~ÄÅÇÉÑÑÖÖÖÖÖÜÜÜÜÖÑÇÅÄ~~~}|{zyyxwvuttsrrrrssttuvwxyz}ÅÑáâåéèëëëëëëëêèééééééçåäâàÜÖÑÇÅÄ~}|{yyxwvuutttuvxyz|}ÅÇÉÑÖÖÜÜÖÑÑÑÉÉÅÄ~|{yxwvvuuuvvwwxyz{{zzzz{{|~ÄÅÅÇÇÉÑÜáâäåçéèéééçåãäâââââääãääâàáÜÖÖÑÉÇÅÄ~|{yxwvvuuuuvvwwwxyyzz{{{{{{{||}}~~}||{{{zzyyzz{{|}}}}||{{{|}~ÄÇÉÉÉÑÑÖÖÜàäåéèêëííëêèéçåãääääããããäâàáÜÖÑÉÇÅ~|zyxwvutttssssttuvvwxxyyzyyyz|}~}}{xvsqonnoqsuwy{}ÄÇÉÑÜáááÜÜÜÜÜÖÑÑÖÜÜáàäçëìïóôöõõöóìêåàÖÇ~}~~ÄÉÜàãéèêêêêééçãàÖÅ|yvsqolheca_]ZYWVVVWWXY[^aflszÇâêïöúûü††üûûûûùõôñîêçäáÑÅ|zxwutsrrsuwz~ÇÜâçêìïñïîìëéäáÉÄ}~
    into this code:
    Code:
    void kedit(char *file)
    {
        int MAX_SAMPLE = 1000000;
        int slen;
        int i;
        char sample[MAX_SAMPLE];
        char nsample[MAX_SAMPLE];
        char tempfile[175];
        FILE *wav;
        FILE *outwav;
        
        
        snprintf(tempfile, 175, "temp%s", file);
        wav = fopen(tempfile, "r");
        outwav = fopen(file, "w");
        
        
        slen = 0;    
        while( (sample[slen] = getc(wav)) != EOF)
        {
            slen++;
            printf("sample%d: %s\n", slen, sample);
        }
        
        fclose(wav);
        for(i = 12; i < slen; i++)
        {
            nsample[i-12] = sample[i];
            
            printf("nsample: %s", nsample);
            printf(" sample: %s\n", sample);
        }
        fprintf(outwav, nsample);
        
        fclose(outwav);
        
        return;
    }
    I get this output:
    Code:
    sample1: R
    sample2: RI
    sample3: RIF
    sample4: RIFF
    sample5: RIFF?
    sample6: RIFF?
    sample7: RIFF?
    sample8: RIFF?
    sample9: RIFF?
    sample10: RIFF?
    ~~~~~~all the way to: sample767
    nsample: f sample: RIFF?
    nsample: fm sample: RIFF?
    nsample: fmt sample: RIFF?
    nsample: fmt  sample: RIFF?
    nsample: fmt  sample: RIFF?
    nsample: fmt  sample: RIFF?
    nsample: fmt  sample: RIFF?
    ~~~~~~Repeats to 767...
    The output should be the .wav file minus the first 12 bytes. What am I doing wrong?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You probably don't want to use fprintf() to write binary data to a file. It will stop as soon as a byte is zero - because it treats zero as end of string.

    Use fwrite() instead.

    You may want to consider fread() for the input as well.

    The input loop:
    Code:
       while( (sample[slen] = getc(wav)) != EOF)
        {
            slen++;
            printf("sample%d: %s\n", slen, sample);
        }
    will indicate EOF when you read a 0xFF byte, since your sample[] is a signed char, and 0xff as a signed char is -1, which is also the value of EOF. Something like this may work:
    Code:
       int ch;
       while( (ch = getc(wav)) != EOF)
        {
            sample[slen++]  = ch;
            printf("sample%d: %s\n", slen, sample);
        }
    --
    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.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You'll need "rb" and "wb" for the file open modes.

    > (sample[slen] = getc(wav)) != EOF
    You also need to read into an int variable in order to compare with EOF, and then (only if not EOF) cast it back down to a char in the assignment.

    > char sample[MAX_SAMPLE];
    > char nsample[MAX_SAMPLE];
    2MB on the stack?
    So what happens when the file is bigger than this?
    Use a fixed sized block and process as you go. There is seldom any need to store the whole file in memory at once.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Aug 2006
    Posts
    163
    Quote Originally Posted by Salem View Post
    > char sample[MAX_SAMPLE];
    > char nsample[MAX_SAMPLE];
    2MB on the stack?
    So what happens when the file is bigger than this?
    Use a fixed sized block and process as you go. There is seldom any need to store the whole file in memory at once.
    Thanks for the quick replies guys.
    Files shouldn't be any larger than 50kb or so, as they're being sent to a satellite(in space!). I'm leaving my work building soon and heading home where I'll start implementing your suggestions, and let you know how it works out. cprogramming.com will get recognition in many documents I hand off to the bosses

    -student project type thing, so it's 50% learning, 50% profit for the upper guys(not me)

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    163
    Sorry for double post, but I got it working, and doing what I need it to do. Thanks for all the help guys!

    Code:
    void kedit(char *file)
    {
        int slen;
        int i;
        int result;
        int NUM_SKIP = 40;
        char *sample;
        char tempfile[175];
        FILE *wav;
        FILE *outwav;
        
        
        snprintf(tempfile, 175, "temp&#37;s", file);
        wav = fopen(tempfile, "rb");
        outwav = fopen(file, "wb");
        
        fseek(wav, 0, SEEK_END);
        slen = ftell(wav);
        rewind(wav);
        
        sample = (char*) malloc (sizeof(char)*slen);
        if(sample == NULL)
        {
            fputs("Memory error", stderr);
            exit(1);
        }
        
        result = fread(sample, 1, slen, wav);
        if(result != slen)
        {
            fputs("Read error",stderr);
            exit(2);
        }
        
        fclose(wav);
        char nsample[slen-NUM_SKIP];
        for(i = slen-1; i >NUM_SKIP; i--)
        {
            nsample[i-NUM_SKIP] = sample[i];
            //Some other stuff happens in here too, but it's irrelevant to gettting this all to work.
            printf("nsample: %c", nsample[i]);
            printf(" sample: %c\n", sample[i]);
        }
    
        fwrite(nsample, 1, slen-NUM_SKIP, outwav);
        fclose(outwav);
        
        return;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. edit txt file help
    By pczafer in forum C++ Programming
    Replies: 4
    Last Post: 04-20-2009, 07:49 AM
  2. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  3. Searching Binary Files for a Pattern
    By CaptainMorgan in forum C Programming
    Replies: 16
    Last Post: 06-17-2007, 06:04 PM
  4. Read file into edit box?
    By dcboy in forum Windows Programming
    Replies: 1
    Last Post: 04-17-2006, 11:39 AM
  5. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM