Outputing hex data to file to mimick original Hex input.

I am trying to do a relatively simple task (I say simple....) of reading in a .WAV audio file, and extracting the useful information and the audio samples...

I plan on using hardware to play the audio samples back to reproduce the file audio.

Here is where I am at currently::

I have read the .WAV file header into a struct,
I have converted the relevant char arrays into strings to allow for simple if(string == "Blah") statements
I have done relevant testing of the various bits of data to make sure the file is a compatible uncompressed file

What I'm kind of struggling with is the outputting of the data into a file were the format is identical to the input file (minus superfluous data I don't need)

Here is elements of my code (The // at the moment are basic references to the source where any info was found -- I'm not trying to pass of any code that isn't mine as mine /> )

looking at this you can see some of the elements... the first four bytes 0x52494646 translate to ACSII as 'RIFF'

however, when the header is read into the struct, C (or the compiler...) obviously converts them to more sensible 'numbers' and characters.... for instance If I were to insert the below code I would see the resulting output::

so it stands to reason, that when I output the file, and then open up in a hex editor I see the following::

34 34 31 30 30 38 31 30 30 30

(This is just the sample frequency, the bit depth of each sample, and the number of samples)

instead of outputting the hex value for 8, it has outputted hex value for the ASCII character 8 (38) and so on and so forth...

If I change the output lines to ::

out_file << hex << num_samples;

The output in the hex editor is hex values for the ASCII characters '38E' which is the Hex number I want stored (1000)

Are you still with me?? Sorry about this!!

TL;DR Basically, my question boils down to, how do I in C++ output a data file, that when opened in a hex editor looks like this (for my example of 44100 sampling frequency, 8 bit sample depth, and 1000 samples)::

44 AC 00 00 08 00 E8 03

(Now I know this is in Little Endian form, but at this moment I want it to stay that way, If I need it in big Endian form its just a case of manipulating the data BEFORE writing it to the file, so I can work on that)

It would be akin to a hex dump I suppose.....

Any and all help is greatly appreciated!

Once I've cracked this the next step would be to read in that actual sample data, if needed strip any 'extra' audio channels out so that you are left with a mono data file, which contains only the following elements:: Sample Frequency, bit depth, number of sample, data.... that way, I can use the first word to configure any hardware, then just pump out the sample data.... but that will be my next challenge.... and no doubt, another question!!

When you write numbers using formatted output you get the ASCII representation, not the hex you seem to want. You should be using the read/write method functions instead.

Jim

Jim, ahhhhhhhhh..... I must admit, this is the first time I've ever dealt with binary files. And I've never used .read or .write before......

It took me some time to combine the reference materials I had to cobble this code together!!

Also, is cstdint.h a standard header? I always get confused with what is amd isn't! !

I will implement the .write function as soon as I can, if I get stuck I might need help!!

Slighty thinking about the next issue..... I'm not sure how best to tackle the actual data itself.... as you won't know the .wav file size until runtime I would assume vectors would be best, can I use .read to read in bytes to a buffer then push them into the vector? But really if (more likely when!) I get stuck thats another topic!

As for the file closing, I realised after posting that I hadn't done that, and that you may pick up on it, but as it's not related to the question I would have hoped that it wouldn't have stopped people from helping me.

Re: Outputing hex data to file to mimick original Hex input.

Also, is cstdint.h a standard header? I always get confused with what is amd isn't! !

No, you'd add the c to the front of the C standard header and leave off any extension. For example <cstdio>

Quote

I will implement the .write function as soon as I can, if I get stuck I might need help!!

What? Remember the C++ streams already have a read() and write() method function.

Quote

As for the file closing, I realised after posting that I hadn't done that, and that you may pick up on it, but as it's not related to the question I would have hoped that it wouldn't have stopped people from helping me.

Quite often it is not necessary to close C++ file streams because they will close themselves when the go out of scope. The only time you really need to worry about closing the stream is when you try to re-use the stream.

You stated that this was a possible problem and people told you not to defer fixing possible problems, that doesn't mean that it will stop them from helping. Unless you seem to be ignoring the help being given.

Quote

Slighty thinking about the next issue..... I'm not sure how best to tackle the actual data itself.... as you won't know the .wav file size until runtime I would assume vectors would be best, can I use .read to read in bytes to a buffer then push them into the vector?

Remember that you are writing fixed amounts of data to and from your files. So you can read this fixed number of bytes from file one and then write these same bytes to the file. There is no real need to read and write the complete file at one time.

Re: Outputing hex data to file to mimick original Hex input.

Posted 22 December 2013 - 08:54 PM

Hi jim,

Cheers for the reponse,

About .write I should been clearer, tomorrow afternoon, I will spend time fully getting to grips with the fstream.write function.

As for the data, my only tbought was that I am developing the hardware to play back the adulterated .wav files and it will only be mono, there is no need for stero, and adds layers of unnecessary complexity etc... if the provided audio file is stero (or for that matter any other number other than 1) I will need to read in the data, then only write out every other piece, or every 3rd piece
.. but then again, a small input buffer (array of fixed size in bytes) could read in a sample, then only write specific elements of that array to the output.

Only thing I need to consider with higher bit depths is that >16 bit wav files store the samples in 2's complement I need to think about hardware issues then!

Re: Outputing hex data to file to mimick original Hex input.

Posted 23 December 2013 - 04:47 PM

Skydiver, on 23 December 2013 - 12:32 PM, said:

Additionally, in a C++ program, you should not be using exit(). The prevents the destructors for classes from running.

I've wondered about this for a long time. Why should we care? Unless there's data that we want to be sure is saved before exiting a program it seems like calling the destructors is just extra work since all of the memory used by the app will be freed by the OS regardless. I always wonder about this when an app takes too long (long enough for me to notice) to quit and I know I didn't intend to save anything. Maybe it's a problem with Windows memory management? Will it not free memory properly when and app terminates?

Re: Outputing hex data to file to mimick original Hex input.

Posted 23 December 2013 - 08:39 PM

It's not just heap memory resources that a class can hold. It can also hold file handles, file locks, database connections, mutexes, semaphores, share memory, etc. Basically things that are not automatically cleaned up when a process terminates.

Normally the slow shutdown issue you are seeing is because Windows is still trying to send messages to a program whose message pump is not running anymore, or whose window procedure now points to memory that has been deallocated or unloaded. For the dead message pump case, Windows will sit for a while before it detects that a program is not responding (because it is not pumping messages anymore). For the deallocated or unloaded windows procedure, typically an exception is thrown, and Windows will try to walk up the exception stack to see if somebody can handle it, and if nobody can handle it, it looks to see if this crash is common. To see if it is common, it needs to package up the call stack as well as a memory dump and try to send it back to MSFT's Watson crash database.