mmioRead and 24 bit data

So my first question is when using mmioRead() to read a PCM WAV file that was written as 24 bit it tells me that my Bit Depth is 32, is this because there are no 24 bit data types and the only data type large enough to accept the information is a 32 bit type (int)?

So this is where the fun begins. My Wav is PCM 24 bit, so I want to read 3 bytes at a time, so instead of this:

mmioRead(handle, (HPSTR)&readBuffers[i][j], sizeof(int));

I want this:

mmioRead(handle, (HPSTR)&readBuffers[i][j], 3);

I'm wondering what the best approach would be:
1. Create a 24 bit integer data type or
2. Read the 3 bytes of data and somehow use bit shifting to get it to fit into a 32 bit type (int).

In both cases I'm not quite sure where to start. The simplest approach appears to my novice eyes to be bit shift.

If anyone can offer some guidance it would be greatly appreciated.

Chris
CORRECTION

I just got home and made sure that I was using a file that had the correct bit depth and it reported the bit depth correctly.
it tells me that my Bit Depth is 32

What is it that's telling you this? Tell us more about this and your readBuffers array.

I'm a little embarrassed, because I work with audio quite a lot, but I've never really had to tackle 24-bit audio. So there's a chance that I'm completely wrong.

You could possibly use a bitfield:

1
2
3
struct int24{
    unsigned int data : 24;
};

Just make sure to disable any sort of byte padding.

I would think that it's easier to simply treat everything as 32-bit, and then do the conversion to 24-bit when you need to do some sort of input/output/playback.
You typically find 24 bit audio in studio environments during the record process. It allows for a lower noise floor and more headroom. Once the mixing process is done the audio is dithered down to 16 bit for CD audio.

So I took some time off from C++ and worked a lot with UnrealScript which unfortunately has caused me to forget certain aspects of C++.

Looking at the code snippet you provided and the part the confuses me is the colon ":" in the declaration

unsigned int data : 24;

What is this telling us?
unsigned int data : 24;

What is this telling us?


It's the syntax for creating a so called "bitfield". If a member of a struct or class needs to occupy less storage than an integral type, you can explicitly set the size in bits using this syntax.
In the example above, the member "data" occupies 24 bits.

MSDN has more info and pretty pictures:

http://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx

edit* whoopsie
Last edited on
That syntax is only supported by Microsoft compiler.
Thank you for the explanation. Correct me if I'm wrong, just want to make sure I'm understanding this.

unsigned int data : 24;

Is this saying that this member is an unsigned int, but we're only going to occupy 24 bits of the 32 bits this data type provides?
That is correct - to my understanding. However, there are some things to be aware of. Take a look at this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

struct BitStruct {
	signed s : 1;
	unsigned u : 1;
};

int main(int argc, char* argv[]) {

	BitStruct foo;

	foo.s = 1;
	foo.u = 1;

	std::cout << "signed:\t\t" << foo.s << std::endl;
	std::cout << "unsigned:\t" << foo.u << std::endl;
	std::cin.get();
	return 0;
}


If you run this example, you'll notice that "-1" gets printed for the signed variable. This is so, because - as you probably know, for signed variables, the most significant bit determines the sign. Therefore, while the signed variable will be stored in binary as "1", it will be interpreted as "-1".
Last edited on
Topic archived. No new replies allowed.