Skip to content

Instantly share code, notes, and snippets.

@awesie
Created January 25, 2020 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awesie/7c6f43c3117ea82cbd832551ee384100 to your computer and use it in GitHub Desktop.
Save awesie/7c6f43c3117ea82cbd832551ee384100 to your computer and use it in GitHub Desktop.
Test for faad_imdct issue
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned short uint16_t;
float constdata[1024];
inline static void ComplexMult(float *y1, float *y2, float x1, float x2, float c1, float c2)
{
*y1 = (x1 * c1) + (x2 * c2);
*y2 = (x2 * c1) - (x1 * c2);
}
// incorrect behavior on -O3
// (implicit cast of N2 to int causes vectorization to produce wrong results)
void __attribute__((noinline)) imdct(unsigned int N, float *xin, float *xout)
{
float Z1[1024];
uint16_t N2 = N >> 1;
uint16_t N4 = N >> 2;
for (uint16_t k = 0; k < N4; k++)
ComplexMult(&Z1[k * 2 + 1], &Z1[k * 2 + 0], xin[k * 2], xin[N2 - 1 - k * 2], constdata[k * 2 + 0], constdata[k * 2 + 1]);
for (uint16_t k = 0; k < N4; k++)
ComplexMult(&xout[k * 2], &xout[k * 2 + 1], Z1[k * 2 + 1], Z1[k * 2 + 0], constdata[k * 2 + 0], constdata[k * 2 + 1]);
}
// correct behavior on -O3
void __attribute__((noinline)) imdct2(unsigned int N, float *xin, float *xout)
{
float Z1[1024];
uint16_t N2 = N >> 1;
uint16_t N4 = N >> 2;
for (uint16_t k = 0; k < N4; k++)
ComplexMult(&Z1[k * 2 + 1], &Z1[k * 2 + 0], xin[k * 2], xin[(unsigned int)N2 - 1 - k * 2], constdata[k * 2 + 0], constdata[k * 2 + 1]);
for (uint16_t k = 0; k < N4; k++)
ComplexMult(&xout[k * 2], &xout[k * 2 + 1], Z1[k * 2 + 1], Z1[k * 2 + 0], constdata[k * 2 + 0], constdata[k * 2 + 1]);
}
// test bed to compare results of the two functions
int main(int argc, char *argv[])
{
float xin[1024], xout[1024], xout2[1024];
for (unsigned int i = 0; i < 1024; i++)
{
constdata[i] = 1;
xin[i] = 1;
}
memset(xout, 0, sizeof(xout));
imdct(2048, xin, xout);
for (unsigned int i = 0; i < 1024; i++)
{
constdata[i] = 1;
xin[i] = 1;
}
memset(xout2, 0, sizeof(xout2));
imdct2(2048, xin, xout2);
if (memcmp(xout, xout2, sizeof(xout)) == 0)
{
printf("pass\n");
}
else
{
printf("fail\n");
for (unsigned int i = 0; i < 16; i++)
printf("%f = %f\n", xout[i], xout2[i]);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment