Reputation: 1804
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:
long
in range [min, max]
unsigned long
in range [0, max]
float
in range [min, max]
float
in range [-1, 1]
?(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 long
s) 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
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 float
s 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
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