示例#1
0
OfdmGenerator::~OfdmGenerator()
{
    PDEBUG("OfdmGenerator::~OfdmGenerator() @ %p\n", this);

#if USE_FFTW
    if (myFftIn) {
         fftwf_free(myFftIn);
    }

    if (myFftOut) {
         fftwf_free(myFftOut);
    }

    if (myFftPlan) {
        fftwf_destroy_plan(myFftPlan);
    }

#else
    if (myFftPlan != NULL) {
        kiss_fft_free(myFftPlan);
    }

    if (myFftBuffer != NULL) {
        free(myFftBuffer);
    }

    kiss_fft_cleanup();
#endif
}
示例#2
0
DP_FN_POSTAMBLE


DP_FN_PREAMBLE(cfft,deinit) {
 if (s->buffs_allocd) {
  free(s->ibuff);
  free(s->obuff);
  kiss_fft_cleanup();
 }
}
示例#3
0
文件: dsp.c 项目: 1nfused/RedPitaya
int rp_spectr_fft_clean()
{
    kiss_fft_cleanup();
    if(rp_kiss_fft_out1) {
        free(rp_kiss_fft_out1);
        rp_kiss_fft_out1 = NULL;
    }
    if(rp_kiss_fft_out2) {
        free(rp_kiss_fft_out2);
        rp_kiss_fft_out2 = NULL;
    }
    if(rp_kiss_fft_cfg) {
        free(rp_kiss_fft_cfg);
        rp_kiss_fft_cfg = NULL;
    }
    return 0;
}
示例#4
0
Tracter::Fourier::~Fourier()
{
    if (!mFourierData)
        return;

    assert(FourierKiss::sInstanceCount > 0);
    FourierData& m = *mFourierData;

    if (m.Config)
        free(m.Config);
    if (m.MyIData && m.IData)
        free(m.IData);
    if (m.MyOData && m.OData)
        free(m.OData);
    if (m.TmpData)
        free(m.TmpData);
    delete mFourierData;

    if (--FourierKiss::sInstanceCount == 0)
        kiss_fft_cleanup();
}
示例#5
0
void
fft_filt_c::make_unready() {
 if (fft_ready) {
  if (is_complex) {
   delete input_buf_c;
   delete output_buf_c;
   delete last_output_buf_c;
  } else {
   delete input_buf_r;
   delete output_buf_r;
   delete last_output_buf_r;
  }
  if (filter_is_ready) {
   delete filt_buf;
   filter_is_ready = false;
  }
  delete fdom_buf;
  delete fdom_conv_buf;
  kiss_fft_cleanup();
  fft_ready= false;
 }

}
int main(int argc, char ** argv)
{
    int k;
    int nfft[32];
    int ndims = 1;
    int isinverse = 0;
    int numffts = 1000, i;
    kiss_fft_cpx * buf;
    kiss_fft_cpx * bufout;
    int real = 0;

    nfft[0] = 1024;// default

    while (1) {
        int c = getopt(argc, argv, "n:ix:r");
        if (c == -1)
            break;
        switch (c) {
        case 'r':
            real = 1;
            break;
        case 'n':
            ndims = getdims(nfft, optarg);
            if (nfft[0] != kiss_fft_next_fast_size(nfft[0])) {
                int ng = kiss_fft_next_fast_size(nfft[0]);
                fprintf(stderr, "warning: %d might be a better choice for speed than %d\n", ng, nfft[0]);
            }
            break;
        case 'x':
            numffts = atoi(optarg);
            break;
        case 'i':
            isinverse = 1;
            break;
        }
    }
    int nbytes = sizeof(kiss_fft_cpx);
    for (k = 0; k < ndims; ++k)
        nbytes *= nfft[k];

#ifdef USE_SIMD
    numffts /= 4;
    fprintf(stderr, "since SIMD implementation does 4 ffts at a time, numffts is being reduced to %d\n", numffts);
#endif

    buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes);
    bufout = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes);
    memset(buf, 0, nbytes);

    pstats_init();

    if (ndims == 1) {
        if (real) {
            kiss_fftr_cfg st = kiss_fftr_alloc(nfft[0] , isinverse , 0, 0);
            if (isinverse)
                for (i = 0; i < numffts; ++i)
                    kiss_fftri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout);
            else
                for (i = 0; i < numffts; ++i)
                    kiss_fftr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout);
            free(st);
        } else {
            kiss_fft_cfg st = kiss_fft_alloc(nfft[0] , isinverse , 0, 0);
            for (i = 0; i < numffts; ++i)
                kiss_fft(st , buf, bufout);
            free(st);
        }
    } else {
        if (real) {
            kiss_fftndr_cfg st = kiss_fftndr_alloc(nfft, ndims , isinverse , 0, 0);
            if (isinverse)
                for (i = 0; i < numffts; ++i)
                    kiss_fftndri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout);
            else
                for (i = 0; i < numffts; ++i)
                    kiss_fftndr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout);
            free(st);
        } else {
            kiss_fftnd_cfg st = kiss_fftnd_alloc(nfft, ndims, isinverse , 0, 0);
            for (i = 0; i < numffts; ++i)
                kiss_fftnd(st , buf, bufout);
            free(st);
        }
    }

    free(buf); free(bufout);

    fprintf(stderr, "KISS\tnfft=");
    for (k = 0; k < ndims; ++k)
        fprintf(stderr, "%d,", nfft[k]);
    fprintf(stderr, "\tnumffts=%d\n" , numffts);
    pstats_report();

    kiss_fft_cleanup();

    return 0;
}
示例#7
0
/* real-to-complex transform in 1 dimension */
int tcl_rfft_1d(ClientData nodata, Tcl_Interp *interp,
                int objc, Tcl_Obj *const objv[]) 
{
    Tcl_Obj *result, **tdata;
    
    const char *name;
    kiss_fft_scalar *timed;
    kiss_fft_cpx    *freqd;
    kiss_fftr_cfg    work;
    
    int dir, ndat, k;

    /* thread safety */
    Tcl_MutexLock(&myFftMutex);

    /* set defaults: */
    dir   = FFT_FORWARD;
    ndat  = -1;
    
    /* Parse arguments:
     *
     * usage: r2cfft_1d <data>
     *    or: c2rfft_1d <data>
     * 
     * r2cfftf_1d : is the 1d real-to-complex forward transform.
     * c2rfftb_1d : is the 1d complex-to-real backward transform.
     * <data>     : list containing data to be transformed. this can either a real 
     *              or a list with two reals interpreted as complex.
     */

    name = Tcl_GetString(objv[0]);
    if (strcmp(name,"r2cfft_1d") == 0) {
        dir = FFT_FORWARD;
    } else if (strcmp(name,"c2rfft_1d") == 0) {
        dir = FFT_BACKWARD;
    } else {
        Tcl_AppendResult(interp, name, ": unknown fft command.", NULL);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "<data>");
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    
    /* get handle on data */
    Tcl_IncrRefCount(objv[1]);
    if (Tcl_ListObjGetElements(interp, objv[1], &ndat, &tdata) != TCL_OK) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if (ndat < 0) {             /* this should not happen, but... */
        Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    /* no effect for zero or one element */
    if ((ndat == 0) || (ndat == 1)) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_SetObjResult(interp, objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_OK;
    }

    /* we need an even number of data points for the forward transform */
    if (ndat & 1) {
        if (dir == FFT_FORWARD) {
            Tcl_AppendResult(interp, name, " needs an even number of data points.", NULL);
            Tcl_DecrRefCount(objv[1]);
            Tcl_MutexUnlock(&myFftMutex);
            return TCL_ERROR;
        }
    }

    check_thread_count(interp,"fftcmds");

    /* size of data arrays for backward transform */
    if (dir == FFT_BACKWARD) ndat = (ndat-1)*2;
    
    /* get dynamic storage for passing data to the lowlevel code. */
    timed = (void *)Tcl_Alloc(ndat*sizeof(kiss_fft_scalar));
    freqd = (void *)Tcl_Alloc((ndat/2+1)*sizeof(kiss_fft_cpx));
    work  = kiss_fftr_alloc(ndat, dir, NULL, NULL);
    
    /* parse/copy data list */
    if (dir == FFT_FORWARD) {
        for (k=0; k<ndat; ++k) {
            if (Tcl_GetDoubleFromObj(interp, tdata[k], timed + k) != TCL_OK) {
                Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
                Tcl_DecrRefCount(objv[1]);
                Tcl_MutexUnlock(&myFftMutex);
                return TCL_ERROR;
            }
        }
    } else {
        for (k=0; k<(ndat/2)+1; ++k) {
            if (read_list_cpx(interp, tdata[k], freqd + k) != TCL_OK) {
                Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
                Tcl_DecrRefCount(objv[1]);
                Tcl_MutexUnlock(&myFftMutex);
                return TCL_ERROR;
            }
        }
    }
    Tcl_DecrRefCount(objv[1]);
    
    /* finally run the transform */
    if (dir == FFT_FORWARD) {
        kiss_fftr(work, timed, freqd);
    } else {
        kiss_fftri(work, freqd, timed);
    }

    /* prepare results */
    result = Tcl_NewListObj(0, NULL);
    if (dir == FFT_FORWARD) {
        for (k=0; k<(ndat/2)+1; ++k) {
            make_list_cpx(interp, result, freqd + k);
        }
    } else {
        for (k=0; k<ndat; ++k) {
            Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(timed[k]));
        }
    }
    Tcl_SetObjResult(interp, result);

    /* free intermediate storage */
    Tcl_Free((char *)timed);
    Tcl_Free((char *)freqd);
    kiss_fft_free(work);
    kiss_fft_cleanup();

    Tcl_MutexUnlock(&myFftMutex);
    return TCL_OK;
}
示例#8
0
/* generic complex <N>d-transform. */
int tcl_cfft_nd(ClientData nodata, Tcl_Interp *interp,
                int objc, Tcl_Obj *const objv[]) 
{
    Tcl_Obj *result, **tdata[FFT_MAX_DIM];
    
    const char *name;
    kiss_fft_cpx *input;
    kiss_fft_cpx *output;
    kiss_fftnd_cfg work;
    
    int dir, ndim, alldim, ndat[FFT_MAX_DIM];
    int i;

    Tcl_MutexLock(&myFftMutex);

    /* set defaults: */
    dir   = FFT_FORWARD;
    ndim  = -1;
        
    /* Parse arguments:
     *
     * usage: cfftf_nd <data>
     *    or: cfftb_nd <data>
     * 
     * cfftf_nd   : is the Nd complex forward transform.
     * cfftb_nd   : is the Nd complex backward transform.
     * <data>     : list containing data to be transformed. this can either a real 
     *              or a list with two reals interpreted as complex.
     */

    name = Tcl_GetString(objv[0]);
    if (strcmp(name,"cfftf_2d") == 0) {
        dir = FFT_FORWARD;
        ndim = 2;
    } else if (strcmp(name,"cfftb_2d") == 0) {
        dir = FFT_BACKWARD;
        ndim = 2;
    } else if (strcmp(name,"cfftf_3d") == 0) {
        dir = FFT_FORWARD;
        ndim = 3;
    } else if (strcmp(name,"cfftb_3d") == 0) {
        dir = FFT_BACKWARD;
        ndim = 3;
    } else if (strcmp(name,"cfftf_4d") == 0) {
        dir = FFT_FORWARD;
        ndim = 4;
    } else if (strcmp(name,"cfftb_4d") == 0) {
        dir = FFT_BACKWARD;
        ndim = 4;
    } else {
        Tcl_AppendResult(interp, name, ": unknown fft command.", NULL);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "<data>");
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    
    /* mark data as busy and check */
    Tcl_IncrRefCount(objv[1]);
    if (Tcl_ListObjGetElements(interp, objv[1], &(ndat[0]), &(tdata[0])) != TCL_OK) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if ((ndat[0] < 0) || (ndim > FFT_MAX_DIM)) { /* this should not happen, but... */
        Tcl_AppendResult(interp, name, ": illegal or unsupported data array.", NULL);
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if (ndat[0] == 0) {         /* no effect for empty array */
        Tcl_DecrRefCount(objv[1]);
        Tcl_SetObjResult(interp, objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_OK;
    }

    check_thread_count(interp,"fftcmds");

    /* determine size of each dimension for storage size and parsing/checking. */
    alldim=ndat[0];
    for (i=1; i<ndim; ++i) { 
        if (Tcl_ListObjGetElements(interp, tdata[i-1][0], &(ndat[i]), &(tdata[i])) != TCL_OK) {
            Tcl_DecrRefCount(objv[1]);
            Tcl_MutexUnlock(&myFftMutex);
            return TCL_ERROR;
        }
        alldim *= ndat[i];
    }
    input  = (void *)Tcl_Alloc(alldim*sizeof(kiss_fft_cpx));
    output = (void *)Tcl_Alloc(alldim*sizeof(kiss_fft_cpx));
    work   = kiss_fftnd_alloc(ndat, ndim, dir, NULL, NULL);

    /* parse/copy data list through recursive function and release original data. */
    alldim=0;
    for (i=0; i<ndat[0]; ++i) {
        if (read_list_list(interp, tdata[0][i], 1, ndim, ndat, input, &alldim) != TCL_OK) {
            Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
            Tcl_DecrRefCount(objv[1]);
            Tcl_MutexUnlock(&myFftMutex);
            return TCL_ERROR;
        }
    }
    Tcl_DecrRefCount(objv[1]);
    
    /* finally run the transform */
    kiss_fftnd(work, input, output);
    
    /* build result list(s) recursively */
    result = Tcl_NewListObj(0, NULL);
    alldim = 0;
    for (i=0; i<ndat[0]; ++i) {
        make_list_list(interp, result, 1, ndim, ndat, output, &alldim);
    }
    Tcl_SetObjResult(interp, result);

    /* free intermediate storage */
    Tcl_Free((char *)input);
    Tcl_Free((char *)output);
    kiss_fft_free(work);
    kiss_fft_cleanup();

    Tcl_MutexUnlock(&myFftMutex);
    return TCL_OK;
}
示例#9
0
/* generic complex 1d-transform. */
int tcl_cfft_1d(ClientData nodata, Tcl_Interp *interp,
                int objc, Tcl_Obj *const objv[]) 
{
    Tcl_Obj *result, **tdata;
    
    const char *name;
    kiss_fft_cpx *input;
    kiss_fft_cpx *output;
    kiss_fft_cfg work;
    
    int dir, ndat, k;

    /* thread safety */
    Tcl_MutexLock(&myFftMutex);

    /* set defaults: */
    dir   = FFT_FORWARD;
    ndat  = -1;
    
    /* Parse arguments:
     *
     * usage: cfftf_1d <data>
     *    or: cfftb_1d <data>
     * 
     * cfftf_1d   : is the 1d complex forward transform.
     * cfftb_1d   : is the 1d complex backward transform.
     * <data>     : list containing data to be transformed. this can either a real 
     *              or a list with two reals interpreted as complex.
     */

    name = Tcl_GetString(objv[0]);
    if (strcmp(name,"cfftf_1d") == 0) {
        dir = FFT_FORWARD;
    } else if (strcmp(name,"cfftb_1d") == 0) {
        dir = FFT_BACKWARD;
    } else {
        Tcl_AppendResult(interp, name, ": unknown fft command.", NULL);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "<data>");
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    
    /* get handle on data  and check */
    Tcl_IncrRefCount(objv[1]);
    if (Tcl_ListObjGetElements(interp, objv[1], &ndat, &tdata) != TCL_OK) {
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if (ndat < 0) { /* this should not happen, but... */
        Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
        Tcl_DecrRefCount(objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_ERROR;
    }
    if ((ndat == 0) || (ndat == 1)) { /* no effect for zero or one element */
        Tcl_DecrRefCount(objv[1]);
        Tcl_SetObjResult(interp, objv[1]);
        Tcl_MutexUnlock(&myFftMutex);
        return TCL_OK;
    }
    
    check_thread_count(interp,"fftcmds");

    /* get dynamic storage for passing data to the lowlevel code. */
    input  = (void *)Tcl_Alloc(ndat*sizeof(kiss_fft_cpx));
    output = (void *)Tcl_Alloc(ndat*sizeof(kiss_fft_cpx));
    work   = kiss_fft_alloc(ndat, dir, NULL, NULL);
    
    /* parse/copy data list */
    for (k=0; k<ndat; ++k) {
        if (read_list_cpx(interp, tdata[k], input + k) != TCL_OK) {
            Tcl_AppendResult(interp, name, ": illegal data array.", NULL);
            Tcl_DecrRefCount(objv[1]);
            Tcl_MutexUnlock(&myFftMutex);
            return TCL_ERROR;
        }
    }
    Tcl_DecrRefCount(objv[1]);
    
    /* finally run the transform */
    kiss_fft(work, input, output);

    /* prepare results */
    result = Tcl_NewListObj(0, NULL);
    for (k=0; k<ndat; ++k) {
        make_list_cpx(interp, result, output + k);
    }
    Tcl_SetObjResult(interp, result);

    /* free intermediate storage */
    Tcl_Free((char *)input);
    Tcl_Free((char *)output);
    kiss_fft_free(work);
    kiss_fft_cleanup();
    
    Tcl_MutexUnlock(&myFftMutex);
    return TCL_OK;
}
示例#10
0
void FormSetup::ApplyB()
{
	isON = ui.isONB->isChecked();
	if ( !isON )
		ui.enabledB->setChecked( false );
	Enabled = ui.enabledB->isChecked();
	okno = ui.oknoB->isChecked();

	if ( isON && !Vis )
	{
		Vis = new MyVis;
		Vis->setMinimumSize(10,10);
		if ( VisW < 1 )
			VisW = 400;
		if ( VisH < 1 )
			VisH = 300;
		if ( VisX < 0 )
			VisX = qdw.width()/2 - Vis->width()/2;
		if ( VisY < 0 )
			VisY = qdw.height()/2 - Vis->height()/2;
		Vis->setGeometry(VisX,VisY,VisW,VisH);
		Vis->connect( &timRef, SIGNAL(timeout()), Vis, SLOT( updateGL() ) );
		Vis->connect( &cursorTim, SIGNAL(timeout()), Vis, SLOT( cursorTimDo() ) );
	}

	fftP = ui.paskiB->isChecked();
	fftL = ui.linieB->isChecked();
	fftsize = ui.fftsizeB->value();
	scale = ui.scaleB->value();
	fullScope = ui.fullScopeB->isChecked();
	przesun = ui.pB->value();
	lpaski = ui.lpaskiB->value();
	fftK = ui.kreskiB->isChecked();

	if ( !IsPowerOfTwo(fftsize) )
	{
		fftsize = fftDef;
		ui.fftsizeB->setValue( fftsize );
	}

	if ( !fullScope )
		fftsize2 = fftsize/2;
	else
		fftsize2 = fftsize;

	if ( lpaski > fftsize2 )
	{
		lpaski = fftsize2;
		ui.lpaskiB->setValue( lpaski );
	}

	kiss_fft_cleanup();
	delete[] f;
	delete[] f2;
	delete[] F;
	f = NULL;
	f2 = NULL;
	F = NULL;
	if ( cfg )
		free( cfg );
	if ( out )
		free( out );
	delete[] spec;
	cfg = NULL;
	out = NULL;
	spec = NULL;

	if ( Enabled )
	{
		f  = new float [lpaski];
		f2 = new float [lpaski];
		F  = new int [lpaski];
		memset( f, 0, sizeof( float ) * lpaski );
		memset( f2, 0, sizeof( float ) * lpaski );
		memset( F, 0, sizeof( int ) * lpaski );

		cfg = kiss_fft_alloc( fftsize, false, 0, 0 );
		out = ( kiss_fft_cpx * )malloc( sizeof( kiss_fft_cpx ) * fftsize );
		spec = new float [fftsize];
	}

	if ( przesun > fftsize2 - lpaski )
	{
		przesun = fftsize2 - lpaski;
		ui.pB->setValue( przesun );
	}

	timRefValue = ui.refB->value();

	if ( Enabled && isOpen )
	{
		if ( Vis && !Vis->isVisible() )
		{
			okienkoParent = NULL;
			if ( Vis->x() <= 0 && Vis->y() <= 0 )
				Vis->setGeometry(VisX,VisY,VisW,VisH);
			Vis->setParent(NULL);
			okienko = false;
			if ( !dockEnable )
				Vis->show();
		}
	}
	else if ( Vis && Vis->isVisible() )
	{
		if ( Vis->isFullScreen() )
			Vis->showNormal();
		Vis->setParent(NULL);
		Vis->close();
	}

	if ( Vis )
	{
		if ( Vis->isVisible() && okienko && !okno )
			Vis->odlacz();
		else
		{
			if ( okienko )
				Vis->removeAction(fsAct);
			else if ( !okienko )
				Vis->addAction(fsAct);
		}
	}

	Save.zapiszopcje();

	if ( !isON && Vis )
	{
		delete Vis;
		Vis = NULL;
	}

	if ( !Enabled )
		timRef.stop();
}
示例#11
0
	__declspec(dllexport) void KISS_Cleanup()
	{
		kiss_fft_cleanup();
	}
示例#12
0
void FormSetup::ApplyB()
{
	isON = fs.ui.isONB->isChecked();
	if ( !isON )
		ui.enabledB->setChecked( false );
	Enabled = ui.enabledB->isChecked();
	okno = ui.oknoB->isChecked();

	if ( isON && !Vis )
	{
		Vis = new MyVis;
		Vis->setMinimumSize(10,10);
		if ( VisW < 1 )
			VisW = 400;
		if ( VisH < 1 )
			VisH = 300;
		if (VisX < 0 )
			VisX = qdw.width()/2 - Vis->width()/2;
		if (VisY < 0 )
			VisY = qdw.height()/2 - Vis->height()/2;
		Vis->setGeometry(VisX,VisY,VisW,VisH);
		Vis->connect( &timRef, SIGNAL(timeout()), Vis, SLOT( updateGL() ) );
		Vis->connect( &cursorTim, SIGNAL(timeout()), Vis, SLOT( cursorTimDo() ) );
	}

	timRefValue = fs.ui.refB->value();

	timRef.stop();
	if ( Enabled )
	{
		if ( !cfg )
			cfg = kiss_fft_alloc( 512, false, 0, 0 );
		timRef.start( timRefValue );
	}
	else
	{
		kiss_fft_cleanup();
		if ( cfg )
		{
			free( cfg );
			cfg = NULL;
		}
	}

	if ( Enabled && isOpen )
	{
		if ( Vis && !Vis->isVisible() )
		{
			okienkoParent = NULL;
			if ( Vis->x() <= 0 && Vis->y() <= 0 )
				Vis->setGeometry(VisX,VisY,VisW,VisH);
			Vis->setParent(NULL);
			okienko = false;
			if ( !dockEnable )
				Vis->show();
		}
	}
	else
	{
		if ( Vis && Vis->isVisible() )
		{
			if ( Vis->isFullScreen() )
				Vis->showNormal();
			Vis->setParent(NULL);
			Vis->close();
		}
	}

	if ( Vis )
	{
		if ( Vis->isVisible() && okienko && !okno )
			Vis->odlacz();
		else
		{
			if ( okienko )
				Vis->removeAction(fsAct);
			else if ( !okienko )
				Vis->addAction(fsAct);
		}
	}

	Save.zapiszopcje();

	if ( !isON && Vis )
	{
		delete Vis;
		Vis = NULL;
	}
}