JNI double arrays problems

117 views
Skip to first unread message

hana amiri

unread,
Mar 4, 2015, 10:36:36 AM3/4/15
to andro...@googlegroups.com
I am new to NDK. Lately, i ve been trying to use a C library to perform convolution on two double arrays extracted from wav files.

I made some changes to the code, so that one native function (convolution) will call several other usual C functions (fft, ifft,..).

I don't know what the problem is, i get this error


invalid use of void expression

Here's the code:



#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include <android/log.h>
// Private function prototypes
#define SIZE_MAX ((size_t)-1)



int  transform(double real[], double imag[], size_t n) {
   
if (n == 0)
       
return 1;

   
else  // More complicated algorithm for arbitrary sizes
   
{
       
return transform_bluestein(real, imag, n);
        __android_log_print
(ANDROID_LOG_VERBOSE, "log", "inside transform ", 1);
   
}
}


int inverse_transform(double real[], double imag[], size_t n) {
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "inside ifft ", 1);
   
return transform(imag, real, n);
}



int transform_bluestein(double real[], double imag[], size_t n) {
   
// Variables
   
int status = 0;
   
double *cos_table, *sin_table;
   
double *areal, *aimag;
   
double *breal, *bimag;
   
double *creal, *cimag;
    size_t m
;
    size_t size_n
, size_m;
    size_t i
;

    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "start bluestein ", 1);
   
// Find a power-of-2 convolution length m such that m >= n * 2 + 1
   
{
        size_t target
;
       
if (n > (SIZE_MAX - 1) / 2)
       
{
            __android_log_print
(ANDROID_LOG_VERBOSE, "log", "return zero ", 1);
           
return 0;
       
}
        target
= n * 2 + 1;
       
for (m = 1; m < target; m *= 2) {
           
if (SIZE_MAX / 2 < m)
           
{
                __android_log_print
(ANDROID_LOG_VERBOSE, "log", "return 0", 1);
               
return 0;
           
}
       
}
   
}

   
// Allocate memory
   
if (SIZE_MAX / sizeof(double) < n || SIZE_MAX / sizeof(double) < m)
       
return 0;
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "allocate ", 1);
    size_n
= n * sizeof(double);
    size_m
= m * sizeof(double);
    cos_table
= malloc(size_n);
    sin_table
= malloc(size_n);
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "inside allocate ", 1);
    areal
= calloc(m, sizeof(double));
    aimag
= calloc(m, sizeof(double));
    breal
= calloc(m, sizeof(double));
    bimag
= calloc(m, sizeof(double));
    creal
= malloc(size_m);
    cimag
= malloc(size_m);
   
if (cos_table == NULL || sin_table == NULL
           
|| areal == NULL || aimag == NULL
           
|| breal == NULL || bimag == NULL
           
|| creal == NULL || cimag == NULL)
       
goto cleanup;
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "finished allocation", 1);

   
// Trignometric tables

   
for (i = 0; i < n; i++) {
       
double temp = M_PI * (size_t)((unsigned long long)i * i % ((unsigned long long)n * 2)) / n;
       
// Less accurate version if long long is unavailable: double temp = M_PI * i * i / n;
        cos_table
[i] = cos(temp);
        sin_table
[i] = sin(temp);
       
//        __android_log_print(ANDROID_LOG_VERBOSE, "log", "inside for %d ", i);
   
}

   
// Temporary vectors and preprocessing
   
for (i = 0; i < n; i++) {
        areal
[i] =  real[i] * cos_table[i] + imag[i] * sin_table[i];
        aimag
[i] = -real[i] * sin_table[i] + imag[i] * cos_table[i];
       
//        __android_log_print(ANDROID_LOG_VERBOSE, "log", "inside for %d ", i);

   
}
    breal
[0] = cos_table[0];
    bimag
[0] = sin_table[0];
   
for (i = 1; i < n; i++) {
        breal
[i] = breal[m - i] = cos_table[i];
        bimag
[i] = bimag[m - i] = sin_table[i];
       
//        __android_log_print(ANDROID_LOG_VERBOSE, "log", "inside for %d ", i);

   
}
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "before postprocessing ", i);

   
//    // Convolution
   
//    if (!Java_com_example_convolution_MainActivity_convolution(env, obj, areal, aimag, breal, bimag, creal, cimag, m))
   
//        goto cleanup;

   
// Postprocessing
   
for (i = 0; i < n; i++) {
        real
[i] =  creal[i] * cos_table[i] + cimag[i] * sin_table[i];//------------------- (problem starts here)
        imag
[i] = -creal[i] * sin_table[i] + cimag[i] * cos_table[i];
       
//    __android_log_print(ANDROID_LOG_VERBOSE, "log", "inside for %d ", i);
   
}
    status
= 1;

   
// Deallocation
    cleanup
:
    free
(cimag);
    free
(creal);
    free
(bimag);
    free
(breal);
    free
(aimag);
    free
(areal);
    free
(sin_table);
    free
(cos_table);
   
return status;
}




JNIEXPORT jint JNICALL
Java_com_example_convolution_MainActivity_convolution (JNIEnv *env, jobject obj, jdoubleArray xreal, jdoubleArray ximag, jdoubleArray yreal, jdoubleArray yimag, jdoubleArray outreal, jdoubleArray outimag, jsize n)
{
    jint status
= 0;
    jsize size
;
    jsize i
;
    jdouble
*xr, *xi, *yr, *yi;
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "start of convolution ", 1);

   
if (SIZE_MAX / sizeof(jdouble) < n)
       
return 0;

    size
= n * sizeof(jdouble);

    xr
= (*env)->GetDoubleArrayElements(env, xreal, 0);

    xi
= (*env)->GetDoubleArrayElements(env, ximag, 0);

    yr
= (*env)->GetDoubleArrayElements(env, yreal, 0);

    yi
= (*env)->GetDoubleArrayElements(env, yimag, 0);

    outr
= (*env)->GetDoubleArrayElements(env, outreal, 0);

    outim
= (*env)->GetDoubleArrayElements(env, outim, 0);

   
if (xr == NULL || xi == NULL || yr == NULL || yi == NULL)
   
{
       
goto cleanup;
        __android_log_print
(ANDROID_LOG_VERBOSE, "log",  "one of the arrays is null ", 1);

   
}
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "after allocation ", 1);

    transform
(xr,xi,n);
    transform
(yr,yi,n);

   
if (!transform(xr, xi, n))
   
{
       
goto cleanup;
        __android_log_print
(ANDROID_LOG_VERBOSE, "log", "transform(xr,xi,n) not performed ", 1);

   
}

   
if (!transform(yr, yi, n))
   
{
       
goto cleanup;
        __android_log_print
(ANDROID_LOG_VERBOSE, "log", "transform(yr,yi,n) not performed ", 1);
   
}
    __android_log_print
(ANDROID_LOG_VERBOSE, "log", "after fft ", 1);//------------------------not showing

   
for (i = 0; i < n; i++) {

        jdouble temp
= xr[i] * yr[i] - xi[i] * yi[i];
        xi
[i] = xi[i] * yr[i] + xr[i] * yi[i];
        xr
[i] = temp;
       
//__android_log_print(ANDROID_LOG_VERBOSE, "log", "inside for convolution", 1);//---------------------not showing

   
}
    inverse_transform
(xr,xi,n);

   
if (!inverse_transform(xr, xi, n))
   
{
       
goto cleanup;
        __android_log_print
(ANDROID_LOG_VERBOSE, "log", "inverse_transform(xr,xi,n) not performed ", 1);
   
}

       
for (i = 0; i < n; i++) {  // Scaling (because this FFT implementation omits it)
            outr
[i] = xr[i] / n;
            outim
[i] = xi[i] / n;
       
}
       
    status
= 1;

    cleanup
:

   
//free(yi);
   
(*env)->ReleaseDoubleArrayElements(env, yimag, yi, 0);

   
//free(yr);
   
(*env)->ReleaseDoubleArrayElements(env, yreal, yr, 0);

   
//free(xi);
   
(*env)->ReleaseDoubleArrayElements(env, ximag, xi, 0);

   
//free(xr);
   
(*env)->ReleaseDoubleArrayElements(env, xreal, xr, 0);

   
return status;
}



Can anyone help me ?


RagsSuper!

unread,
Mar 4, 2015, 6:35:44 PM3/4/15
to andro...@googlegroups.com
Hi Hana,

Some of the instances where this error can occur is,

a. Use sizeof(void) or sizeof(void *).
b. Prototype a function as void and assign it to a variable of type int, float etc.

I don't see above in your code. But, can you provide details of which line in the code you are seeing this error?
Also, I hope you have run Javah on the class file and included the Java_com_example_convolution_MainActivity_convolution.h file in the 'C' code?
...

hana amiri

unread,
Mar 26, 2015, 11:44:29 AM3/26/15
to andro...@googlegroups.com
The error is shown here:


outr[i] = xr[i] / n;
outim
[i] = xi[i] / n;

I dont have a returning void function.

RagsSuper!

unread,
Mar 26, 2015, 1:33:56 PM3/26/15
to andro...@googlegroups.com
Hi Hana,

Couple of things.

1. I don't see outr and outim variables declared. Am I missing anything? I think they should be declared as jdouble.

2. In the below code,

    outr = (*env)->GetDoubleArrayElements(env, outreal, 0);

    outim
= (*env)->GetDoubleArrayElements(env, outim, 0);


I think outimag should be passed instead of outim in the second statement. Hope this helps.

Thanks and Regards,
Raghunand.
Reply all
Reply to author
Forward
0 new messages