/*
* Python type encapsulating all the different workspaces and wavetables.
*/
typedef struct {
PyObject_HEAD
union pygsl_transform_space_t space;
enum pygsl_transform_space_type type;
} PyGSL_transform_space;
static void
PyGSL_transform_space_dealloc(PyGSL_transform_space * self);
static PyObject*
PyGSL_transform_space_getattr(PyGSL_transform_space * self, char * name);
#define PyGSL_transform_space_check(op) ((op)->ob_type == &PyGSL_transform_space_pytype)
#define PyGSL_complex_fft_work_space_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == COMPLEX_WORKSPACE)
#define PyGSL_complex_fft_wave_table_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == COMPLEX_WAVETABLE)
#define PyGSL_halfcomplex_fft_wave_table_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == HALFCOMPLEX_WAVETABLE)
#define PyGSL_real_fft_work_space_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == REAL_WORKSPACE)
#define PyGSL_real_fft_wave_table_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == REAL_WAVETABLE)
#define PyGSL_complex_fft_work_space_float_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == COMPLEX_WORKSPACE_FLOAT)
#define PyGSL_complex_fft_wave_table_float_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == COMPLEX_WAVETABLE_FLOAT)
#define PyGSL_halfcomplex_fft_wave_table_float_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == HALFCOMPLEX_WAVETABLE_FLOAT)
#define PyGSL_real_fft_work_space_float_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == REAL_WORKSPACE_FLOAT)
#define PyGSL_real_fft_wave_table_float_check(op) \
(PyGSL_transform_space_check(op) && ((PyGSL_transform_space *)op)->type == REAL_WAVETABLE_FLOAT)
PyTypeObject PyGSL_transform_space_pytype = {
PyObject_HEAD_INIT(NULL) /* fix up the type slot in init */
0, /* ob_size */
"PyGSL_transform_space", /* tp_name */
sizeof(PyGSL_transform_space), /* tp_basicsize */
0, /* tp_itemsize */
/* standard methods */
(destructor) PyGSL_transform_space_dealloc, /* tp_dealloc ref-count==0 */
(printfunc) 0, /* tp_print "print x" */
(getattrfunc) PyGSL_transform_space_getattr, /* tp_getattr "x.attr" */
(setattrfunc) 0, /* tp_setattr "x.attr=v" */
(cmpfunc) 0, /* tp_compare "x > y" */
(reprfunc) 0, /* tp_repr `x`, print x */
/* type categories */
0, /* tp_as_number +,-,*,/,%,&,>>,pow...*/
0, /* tp_as_sequence +,[i],[i:j],len, ...*/
0, /* tp_as_mapping [key], len, ...*/
/* more methods */
(hashfunc) 0, /* tp_hash "dict[x]" */
(ternaryfunc) 0, /* tp_call "x()" */
(reprfunc) 0, /* tp_str "str(x)" */
(getattrofunc) 0, /* tp_getattro */
(setattrofunc) 0, /* tp_setattro */
0, /* tp_as_buffer */
0L, /* tp_flags */
(char *) PyGSL_transform_space_type_doc /* tp_doc */
};
/*
* Get the size of the work space. Also used in C code. Thus split up
* and a separate function, returning a PyInt.
*/
static int
PyGSL_transform_space_get_n(PyGSL_transform_space *self)
{
int n=0;
FUNC_MESS_BEGIN();
assert(PyGSL_transform_space_check(self));
assert(self->space.v);
switch(self->type) {
case COMPLEX_WORKSPACE: n = self->space.cws ->n; break;
case REAL_WORKSPACE: n = self->space.rws ->n; break;
case COMPLEX_WAVETABLE: n = self->space.cwt ->n; break;
case REAL_WAVETABLE: n = self->space.rwt ->n; break;
case HALFCOMPLEX_WAVETABLE: n = self->space.hcwt->n; break;
case COMPLEX_WORKSPACE_FLOAT: n = self->space.cwsf ->n; break;
case REAL_WORKSPACE_FLOAT: n = self->space.rwsf ->n; break;
case COMPLEX_WAVETABLE_FLOAT: n = self->space.cwtf ->n; break;
case REAL_WAVETABLE_FLOAT: n = self->space.rwtf ->n; break;
case HALFCOMPLEX_WAVETABLE_FLOAT: n = self->space.hcwtf->n; break;
case WAVELET_WORKSPACE: n = self->space.wws->n; break;
default:
gsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY);
return -1;
}
FUNC_MESS_END();
return n;
}
static PyObject *
PyGSL_transform_space_get_n_py(PyGSL_transform_space *self)
{
return PyInt_FromLong((long) PyGSL_transform_space_get_n(self));
}
/*
* Get the factors of FFT wavetables....
*/
static PyObject *
PyGSL_transform_space_get_factors(PyGSL_transform_space *self, PyGSL_transform_space *args)
{
int nf, i;
long *data=NULL;
size_t *cp_data=NULL;
PyArrayObject * a_array = NULL;
FUNC_MESS_BEGIN();
assert(PyGSL_transform_space_check(self));
assert(self->space.v);
DEBUG_MESS(2, "Type = %d", self->type);
switch(self->type){
case COMPLEX_WAVETABLE: nf = self->space.cwt ->nf; cp_data = self->space.cwt ->factor; break;
case REAL_WAVETABLE: nf = self->space.rwt ->nf; cp_data = self->space.rwt ->factor; break;
case HALFCOMPLEX_WAVETABLE: nf = self->space.hcwt->nf; cp_data = self->space.hcwt->factor; break;
case COMPLEX_WAVETABLE_FLOAT: nf = self->space.cwtf ->nf; cp_data = self->space.cwtf ->factor; break;
case REAL_WAVETABLE_FLOAT: nf = self->space.rwtf ->nf; cp_data = self->space.rwtf ->factor; break;
case HALFCOMPLEX_WAVETABLE_FLOAT: nf = self->space.hcwtf->nf; cp_data = self->space.hcwtf->factor; break;
default: gsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY); return NULL; break;
}
a_array = (PyArrayObject *) PyGSL_New_Array(1, &nf, PyArray_LONG);
if(a_array == NULL)
return NULL;
data = (long *) a_array->data;
for(i=0; i<nf; i++){
data[i] = (long) cp_data[i];
}
FUNC_MESS_END();
return (PyObject *) a_array;
}
static const char PyGSL_transform_space_get_factors_doc[] = " Get the factors ...";
static const char PyGSL_transform_space_get_type_doc[] = " Get the type of this space";
/* Allows the user to find out what is encapsulated over the method get_type */
static PyObject *
PyGSL_transform_space_get_type(PyGSL_transform_space *self, PyObject *notused)
{
char *p = NULL;
FUNC_MESS_BEGIN();
assert(PyGSL_transform_space_check(self));
switch(self->type){
case COMPLEX_WORKSPACE: p = "COMPLEX_WORKSPACE"; break;
case REAL_WORKSPACE: p = "REAL_WORKSPACE"; break;
case COMPLEX_WAVETABLE: p = "COMPLEX_WAVETABLE"; break;
case REAL_WAVETABLE: p = "REAL_WAVETABLE"; break;
case HALFCOMPLEX_WAVETABLE: p = "HALFCOMPLEX_WAVETABLE"; break;
case COMPLEX_WORKSPACE_FLOAT: p = "COMPLEX_WORKSPACE_FLOAT"; break;
case REAL_WORKSPACE_FLOAT: p = "REAL_WORKSPACE_FLOAT"; break;
case COMPLEX_WAVETABLE_FLOAT: p = "COMPLEX_WAVETABLE_FLOAT"; break;
case REAL_WAVETABLE_FLOAT: p = "REAL_WAVETABLE_FLOAT"; break;
case HALFCOMPLEX_WAVETABLE_FLOAT: p = "HALFCOMPLEX_WAVETABLE_FLOAT"; break;
case WAVELET_WORKSPACE: p = "WAVELET_WORKSPACE"; break;
default: gsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY); return NULL;
}
FUNC_MESS_END();
return PyString_FromString(p);
}
static const char get_type[] = "get_type";
static const char get_n[] = "get_n";
static PyMethodDef PyGSL_transform_wavetable_methods[] = {
{"get_factors", (PyCFunction)PyGSL_transform_space_get_factors, METH_NOARGS, (char *)PyGSL_transform_space_get_factors_doc},
{(char *)get_type, (PyCFunction)PyGSL_transform_space_get_type, METH_NOARGS, (char *)PyGSL_transform_space_get_type_doc},
{(char *)get_n, (PyCFunction)PyGSL_transform_space_get_n_py, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL} /* sentinel */
};
static PyMethodDef PyGSL_transform_space_methods[] = {
{(char *)get_type, (PyCFunction)PyGSL_transform_space_get_type, METH_NOARGS, (char *)PyGSL_transform_space_get_type_doc},
{(char *)get_n, (PyCFunction)PyGSL_transform_space_get_n_py, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL} /* sentinel */
};
static PyObject*
PyGSL_transform_space_getattr(PyGSL_transform_space *self, char *name)
{
PyObject *tmp = NULL;
FUNC_MESS_BEGIN();
assert(PyGSL_transform_space_check(self));
switch(self->type){
case COMPLEX_WORKSPACE:
case REAL_WORKSPACE:
case COMPLEX_WORKSPACE_FLOAT:
case REAL_WORKSPACE_FLOAT:
tmp = Py_FindMethod(PyGSL_transform_space_methods, (PyObject *) self, name);
default:
tmp = Py_FindMethod(PyGSL_transform_wavetable_methods, (PyObject *) self, name);
}
FUNC_MESS_END();
return tmp;
}
static void
PyGSL_transform_space_dealloc(PyGSL_transform_space * self)
{
FUNC_MESS_BEGIN();
assert(PyGSL_transform_space_check(self));
assert(self->space.v);
switch(self->type){
case COMPLEX_WORKSPACE: gsl_fft_complex_workspace_free(self->space.cws); break;
case COMPLEX_WAVETABLE: gsl_fft_complex_wavetable_free(self->space.cwt); break;
case REAL_WORKSPACE: gsl_fft_real_workspace_free(self->space.rws); break;
case REAL_WAVETABLE: gsl_fft_real_wavetable_free(self->space.rwt); break;
case HALFCOMPLEX_WAVETABLE: gsl_fft_halfcomplex_wavetable_free(self->space.hcwt); break;
case COMPLEX_WORKSPACE_FLOAT: gsl_fft_complex_workspace_float_free(self->space.cwsf); break;
case COMPLEX_WAVETABLE_FLOAT: gsl_fft_complex_wavetable_float_free(self->space.cwtf); break;
case REAL_WORKSPACE_FLOAT: gsl_fft_real_workspace_float_free(self->space.rwsf); break;
case REAL_WAVETABLE_FLOAT: gsl_fft_real_wavetable_float_free(self->space.rwtf); break;
case HALFCOMPLEX_WAVETABLE_FLOAT: gsl_fft_halfcomplex_wavetable_float_free(self->space.hcwtf); break;
case WAVELET_WORKSPACE : gsl_wavelet_workspace_free(self->space.wws); break;
default: gsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY); break;
}
self->space.v = NULL;
FUNC_MESS_END();
}
static PyObject*
PyGSL_transform_space_init(PyObject *self, PyObject *args, const enum pygsl_transform_space_type type)
{
PyGSL_transform_space *o=NULL;
size_t n;
FUNC_MESS_BEGIN();
o = (PyGSL_transform_space *) PyObject_NEW(PyGSL_transform_space, &PyGSL_transform_space_pytype);
if(o == NULL){
return NULL;
}
if (0==PyArg_ParseTuple(args,"l", &n))
return NULL;
if (n<=0) {
gsl_error("dimension must be >0", filename, __LINE__, GSL_EINVAL);
return NULL;
}
o->type = type;
switch(type){
case COMPLEX_WORKSPACE: o->space.cws = gsl_fft_complex_workspace_alloc(n); break;
case COMPLEX_WAVETABLE: o->space.cwt = gsl_fft_complex_wavetable_alloc(n); break;
case REAL_WORKSPACE: o->space.rws = gsl_fft_real_workspace_alloc(n); break;
case REAL_WAVETABLE: o->space.rwt = gsl_fft_real_wavetable_alloc(n); break;
case HALFCOMPLEX_WAVETABLE: o->space.hcwt = gsl_fft_halfcomplex_wavetable_alloc(n); break;
case COMPLEX_WORKSPACE_FLOAT: o->space.cwsf = gsl_fft_complex_workspace_float_alloc(n); break;
case COMPLEX_WAVETABLE_FLOAT: o->space.cwtf = gsl_fft_complex_wavetable_float_alloc(n); break;
case REAL_WORKSPACE_FLOAT: o->space.rwsf = gsl_fft_real_workspace_float_alloc(n); break;
case REAL_WAVETABLE_FLOAT: o->space.rwtf = gsl_fft_real_wavetable_float_alloc(n); break;
case HALFCOMPLEX_WAVETABLE_FLOAT: o->space.hcwtf = gsl_fft_halfcomplex_wavetable_float_alloc(n); break;
case WAVELET_WORKSPACE : o->space.wws = gsl_wavelet_workspace_alloc(n); break;
default: gsl_error("Got unknown switch", filename, __LINE__, GSL_ESANITY); return NULL; break;
}
assert(o->space.v);
FUNC_MESS_END();
return (PyObject *) o;
}
#define PyGSL_SPACE_ALLOC(TYPE) \
static PyObject * \
PyGSL_transform_space_init_ ## TYPE (PyObject *self, PyObject *args)\
{ \
return PyGSL_transform_space_init(self, args, TYPE); \
}
PyGSL_SPACE_ALLOC(COMPLEX_WORKSPACE)
PyGSL_SPACE_ALLOC(COMPLEX_WAVETABLE)
PyGSL_SPACE_ALLOC(REAL_WORKSPACE)
PyGSL_SPACE_ALLOC(REAL_WAVETABLE)
PyGSL_SPACE_ALLOC(HALFCOMPLEX_WAVETABLE)
PyGSL_SPACE_ALLOC(COMPLEX_WORKSPACE_FLOAT)
PyGSL_SPACE_ALLOC(COMPLEX_WAVETABLE_FLOAT)
PyGSL_SPACE_ALLOC(REAL_WORKSPACE_FLOAT)
PyGSL_SPACE_ALLOC(REAL_WAVETABLE_FLOAT)
PyGSL_SPACE_ALLOC(HALFCOMPLEX_WAVETABLE_FLOAT)
PyGSL_SPACE_ALLOC(WAVELET_WORKSPACE)
syntax highlighted by Code2HTML, v. 0.9.1