'MSVC - expression must have pointer-to-object type but it has type "float" on generic array?

MSVC on Visual Studio 2019 says "expression must have pointer-to-object type but it has type "float" on generic array" here:

void _stdcall sample::Eff_Render(PWAV32FS SourceBuffer, PWAV32FS DestBuffer, int Length)
{
    float gain = _gain;
    for (int ii = 0; ii < Length; ii++)
    {
        (*DestBuffer)[ii][0] = (*SourceBuffer)[ii][0] * gain;
        (*DestBuffer)[ii][1] = (*SourceBuffer)[ii][1] * gain;
    }
}

the problem seems here:

    (*DestBuffer)[ii][0] = (*SourceBuffer)[ii][0] * gain;
    (*DestBuffer)[ii][1] = (*SourceBuffer)[ii][1] * gain;

Not sure why:

typedef float TWAV32FS[2];
typedef TWAV32FS *PWAV32FS;

Some flag to be disabled? On gcc this kind of "cast" seems auto-manage by the compiler. What's the correct way to manage this? (maybe I'm wrong on gcc and didn't know...)



Solution 1:[1]

Change this:

    (*DestBuffer)[ii][0] = (*SourceBuffer)[ii][0] * gain;
    (*DestBuffer)[ii][1] = (*SourceBuffer)[ii][1] * gain;

To this:

    DestBuffer[ii][0] = (SourceBuffer[ii][0]) * gain;
    DestBuffer[ii][1] = (SourceBuffer[ii][1]) * gain;

Explanation:

(I'm guessing you are doing audio processing of a stereo signal in floating point).

DestBuffer and SourceBuffer are both arrays of samples. Each sample is a pair of floats.

Each sample is referenced like this:

DestBuffer[ii]

Each individual channel on a sample is referenced like this:

DestBuffer[ii][0]
DestBuffer[ii][1]

The error you have with this syntax:

(*DestBuffer)[ii][0]

Is that *DestBuffer is really the same as DestBuffer[0], or the first sample in the array. So (*DestBuffer)[ii] is the same as DestBuffer[0][ii] which is not what you want anyway. But (*DestBuffer)[ii][0] is the same as DestBuffer[0][ii][0] - which triggers the compiler error because that third dimension does not exist.

Having done some audio processing code before - don't forget to clamp the result of your multiplication with gain as appropriate.

Solution 2:[2]

Due to these typedefs

typedef float TWAV32FS[2];
typedef TWAV32FS *PWAV32FS;

the typedef name PWAV32FS is equivalent to float ( * )[2].

So the parameters SourceBuffer and DestBuffer actually are declared like

float ( *SourceBuffer )[2], float ( * DestBuffer )[2]

Thus the for loop should be rewritten like

for (int ii = 0; ii < Length; ii++)
{
    DestBuffer[ii][0] = SourceBuffer[ii][0] * gain;
    DestBuffer[ii][1] = SourceBuffer[ii][1] * gain;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Vlad from Moscow