Thread: File format converter, wav to aiff.

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485

    File format converter, wav to aiff.

    Ok, I´m comming back to the issue of making a wav to aiff converter. I was arguing with myself a bit if I should start a new thread or continue hmm.

    I´m thinking about what would be the best way of doing this. A normal wave header (old one not bwf) is 44 bytes and little endian. The shortest possible aiff header without any meta data is 54 bytes and that is what I´m going for here. And aiff is big endian. So, I have the basic aiff header set up in three structs, FORM, COMM and SSND. I need to get data from the wave header about file size, bitdepth and so forth and in some cases perform some calculations on it and then assign the value to the variables in my structs.

    Now if I write back the aiff header to the old file I will overwrite the data by 10 bytes and the data will still be little endian.

    So what´s the best way of doing this? I´we been thinking of reading in the complete wav file into an array, perform an endian conversion on the complete array, copy data to my aiff structs, then write my aiff header to the file, and finaly the sound data itself from the array.

    This is just my own ideas on this, drawn from my limited experience in C haha. So do anyone here have any input on the basic steps involved in this process?

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Why are you making this so insanely complicated? Why do you want to rewrite the file in place? I don't know of a single conversion utility (sound, video, image or otherwise) that does that. And I wouldn't use such a tool -- if it crashes, I've lost my original file.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Brewbuck, if it´s complicated it´s because I´m new to this. What would be a better way of doing this in your oppinion? And at some point I would have to rewrite over the old file or end up with two files right?

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Subsonics View Post
    Brewbuck, if it´s complicated it´s because I´m new to this. What would be a better way of doing this in your oppinion? And at some point I would have to rewrite over the old file or end up with two files right?
    I don't think it's that complicated. It sounds like you're on the right track by reading the WAV header into a structure then writing that out as an AIFF header. I just wouldn't suggest complicating it by trying to do everything in place. Just use a temporary file. If you insist on overwriting the original, then do this after the conversion by deleting it then renaming the temporary file.

    In any case, rewriting directly in place is not only more complicated, it's dangerous because a bug in your program can trash the input file, and that will probably anger the user If you are replacing the original, at least provide a way to turn this feature off in case the user is paranoid. Then you can always say "I warned you..."

    Reading the entire WAV into memory isn't the best plan either, since that means the size of file you can convert is limited by available RAM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by brewbuck View Post
    I don't think it's that complicated. It sounds like you're on the right track by reading the WAV header into a structure then writing that out as an AIFF header. I just wouldn't suggest complicating it by trying to do everything in place. Just use a temporary file. If you insist on overwriting the original, then do this after the conversion by deleting it then renaming the temporary file.

    In any case, rewriting directly in place is not only more complicated, it's dangerous because a bug in your program can trash the input file, and that will probably anger the user If you are replacing the original, at least provide a way to turn this feature off in case the user is paranoid. Then you can always say "I warned you..."
    Yes, point taken. Using a temp file seems like a better way of doing this. I think it´s safe to say that it will save me from some headache while testing my code as well.

    Quote Originally Posted by brewbuck View Post
    Reading the entire WAV into memory isn't the best plan either, since that means the size of file you can convert is limited by available RAM.
    So I guess doing it in portions, performing any necessary conversion then writing to the temp file is the way to do it.

    Cheers.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Subsonics View Post
    Yes, point taken. Using a temp file seems like a better way of doing this. I think it´s safe to say that it will save me from some headache while testing my code as well.
    Yep!

    So I guess doing it in portions, performing any necessary conversion then writing to the temp file is the way to do it.
    Maybe 1MB at a time... Anything is reasonable, just not "potentially infinite." I've seen some extremely large WAV files.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Thanks Brewbuck.

    Getting into more details. What whould be the best way of getting the data from the file into the specific struct members that are not constants? For now I have set up a for loop that fgetc´s the first 44 bytes and assigns them into a char array. I then memcpy from the array into the appropriate struct members. The memcpy have the side effect of changing the endianess as well which is welcomed in this case.

    Is there a more effective way of doing this? I have tried to make an array of just the struct members I want to write to but got an error message, is that at all possible? It would be nice if I could some how get the data from the file into the struct using a loop or something.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Subsonics View Post
    Getting into more details. What whould be the best way of getting the data from the file into the specific struct members that are not constants? For now I have set up a for loop that fgetc´s the first 44 bytes and assigns them into a char array. I then memcpy from the array into the appropriate struct members. The memcpy have the side effect of changing the endianess as well which is welcomed in this case.

    Is there a more effective way of doing this? I have tried to make an array of just the struct members I want to write to but got an error message, is that at all possible? It would be nice if I could some how get the data from the file into the struct using a loop or something.
    memcpy() shouldn't change endianness. Can you give more details and/or code?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Here is the first part where I read 44 bytes into the array fileName (re-used BTW, as I use it for file name as well). (This code is losely based on Noir´s code in the sticky about development process BTW.)


    Code:
    	// collect data from fileheader in file: fileName.
    	FILE *fp = fopen( fileName, "r" ); 
    
    	if ( fp ) {
    		for(i = 0; i < 44; i++) {
    			fileName[i] = fgetc( fp ); 
    	    }
    	    fclose( fp );
    	} else {
    		perror( "error opening the file" );
    	}
    Here is the part where I memcpy from the array. (it´s just the first struct of three but it should do to demonstrate what happens):
    Code:
    	// Add data to FORM chunk
    	FormAIFFChunk form = {"FORM", 0, "AIFF"};
    	memcpy(&form.ckDataSize, &fileName[4], 4);	
    	printf("%s%d%s", form.ckID, form.ckDataSize, form.formType);

    OT:

    I managed to collect all struct members that I plan to write to (6 in total) in an array BTW, so I might try to somehow automate the assigning from the file in a for loop instead of using the array and memcpy later on.
    Last edited by Subsonics; 01-09-2009 at 12:36 AM.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    There's no endian reversing going on there -- what proof do you have that it's happening? Also, what's your platform?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    What I did was trying the program on a wav file and passed stdout to a new file. I then opened both the the original wav and the file the program gave me into an hexeditor. I set the hexeditor to display the wav as little endian and compared the filesize (that is byte 4-8) and my file. The output from the program is a string and I changed %d to %x to get a hexnumber. The wave displays: 6409 | 6800 | and the string in my file displays: 680964.

    I´m using a mac BTW, but it´s an intel one.
    Last edited by Subsonics; 01-09-2009 at 01:54 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 10:39 PM
  2. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  3. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  4. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM