egst
egst

Reputation: 1804

WASAPI shared mode: What amplitude does the audio engine expect?

I previously messed up with this question. I made it sound as though I'm asking about my particular implementation, but my question is actually about the general topic. I am pretty confident, that my implementation is OK. So I am rewriting this question:

WASAPI gives me information about the audio format that the audio engine accepts in shared mode. I know the expected bit depth of the samples I provide to the buffer. What I don't know, is the expected representation of the signal amplitude in the samples. For example, if the audio engine expects 32 bit samples, does it mean, that I should represent a sine wave amplitude as:

(max = std::numeric_limits<type>::max() and min = ...::min() in C++)

So far I've been experimenting with this with different values by trial and error method. It seems, that only when my samples contain numbers max/2 or -min/2 (as a long) alternating (along with other numbers), it produces a sound. Even numbers close to these (+- a few integers) produce the same results. When these two numbers (or numbers close to them) are not present in the samples, the result is silence no matter what I do.

It may be irrelevant, but I noticed, that these numbers' (max/2 and min/2) bit representation (as longs) is identical to IEEE float bit representation of 2.0 and -2.0. It still makes no sense to me, why it works like that.

Upvotes: 2

Views: 665

Answers (2)

egst
egst

Reputation: 1804

After a deeper look into the WAVEFORMATEXTENSIBLE structure I found out, that the information I needed might be stored in the SubFormat property. In my case, it was KSDATAFORMAT_SUBTYPE_IEEE_FLOAT. So the audio engine was expecting 32 bit floats in a range of [-1, +1]. For some reason my previous test with float values was unsuccessful, so I kept on trying with integers. Now a simple sine function in the [-1, +1] range provides a correct result. There are some glitches in the sound, but this may be related to some timing issues, when waiting for the buffer.

Upvotes: 1

jaket
jaket

Reputation: 9341

The typical representation is float -1 to 1 scaled to a fixed point representation. For 32-bit signed you'd ideally like 1 to map to 0x7fffffff and -1 to map to 0x8000000. However, you need to keep in mind that there is asymmetry around 0 such that there is one more negative value than there are positive values. In other words, you shouldn't use 0x80000000 otherwise you'll risk overflow on the positive side.

int xfixed = (int)(xfloat * 0x7fffffff);

More explicitly:

int xfixed = (int)(xfloat * ((1<<(32-1)) - 1));

Upvotes: 2

Related Questions