diff options
Diffstat (limited to 'source/blender/python/api2_2x/Sound.c')
-rw-r--r-- | source/blender/python/api2_2x/Sound.c | 522 |
1 files changed, 522 insertions, 0 deletions
diff --git a/source/blender/python/api2_2x/Sound.c b/source/blender/python/api2_2x/Sound.c new file mode 100644 index 00000000000..338f940eb6b --- /dev/null +++ b/source/blender/python/api2_2x/Sound.c @@ -0,0 +1,522 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Chris Keith + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include <BKE_main.h> +#include <BKE_global.h> +#include <BKE_library.h> +#include <BKE_sound.h> +#include <BLI_blenlib.h> +#include <BIF_editsound.h> +#include <BIF_space.h> /* allqueue() */ + +#include "mydevice.h" /* redraw defines */ + +#include "gen_utils.h" + +#include "Sound.h" + +/*****************************************************************************/ +/* Python BPy_Sound defaults: */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Python API function prototypes for the Sound module. */ +/*****************************************************************************/ +static PyObject *M_Sound_New (PyObject *self, PyObject *args, + PyObject *keywords); +static PyObject *M_Sound_Get (PyObject *self, PyObject *args); +static PyObject *M_Sound_Load (PyObject *self, PyObject *args); + +/************************************************************************/ +/* The following string definitions are used for documentation strings. */ +/* In Python these will be written to the console when doing a */ +/* Blender.Sound.__doc__ */ +/************************************************************************/ +static char M_Sound_doc[] = +"The Blender Sound module\n\n"; + +static char M_Sound_New_doc[] = +"() - return a new Sound object -- unimplemented"; + +static char M_Sound_Get_doc[] = +"(name) - return the sound with the name 'name', \ +returns None if not found.\n If 'name' is not specified, \ +it returns a list of all sounds in the\ncurrent scene."; + +static char M_Sound_Load_doc[] = +"(filename, redraw = 0) - return sound from file filename as Sound Object,\n\ +returns None if not found."; + +/*****************************************************************************/ +/* Python method structure definition for Blender.Sound module: */ +/*****************************************************************************/ +struct PyMethodDef M_Sound_methods[] = { + {"New",(PyCFunction)M_Sound_New, METH_VARARGS|METH_KEYWORDS, + M_Sound_New_doc}, + {"Get", M_Sound_Get, METH_VARARGS, M_Sound_Get_doc}, + {"get", M_Sound_Get, METH_VARARGS, M_Sound_Get_doc}, + {"Load", M_Sound_Load, METH_VARARGS, M_Sound_Load_doc}, + {NULL, NULL, 0, NULL} +}; + +/*****************************************************************************/ +/* Python Sound_Type callback function prototypes: */ +/*****************************************************************************/ +static void Sound_dealloc (BPy_Sound *self); +static int Sound_setAttr (BPy_Sound *self, char *name, PyObject *v); +static int Sound_compare (BPy_Sound *a, BPy_Sound *b); +static PyObject *Sound_getAttr (BPy_Sound *self, char *name); +static PyObject *Sound_repr (BPy_Sound *self); + +#define SOUND_FLOAT_METHODS(funcname, varname) \ +static PyObject *Sound_get ## funcname(BPy_Sound *self) { \ + char e[256]; \ + PyObject *attr = PyFloat_FromDouble(self->sound->varname); \ + if (attr) return attr; \ + sprintf(e, "couldn't get Sound.%s attribute", #varname); \ + return EXPP_ReturnPyObjError (PyExc_RuntimeError, e); \ +} \ +static PyObject *Sound_set ## funcname(BPy_Sound *self, PyObject *args) { \ + float f = 0; \ + if (!PyArg_ParseTuple(args, "f", &f)) \ + return (EXPP_ReturnPyObjError (PyExc_TypeError, \ + "expected float argument")); \ + self->sound->varname = f; \ + Py_INCREF(Py_None); \ + return Py_None; \ +} + +#define SOUND_FLOAT_METHOD_FUNCS(varname) \ +{"get"#varname, (PyCFunction)Sound_get ## varname, METH_NOARGS, \ +"() - Return Sound object "#varname}, \ +{"set"#varname, (PyCFunction)Sound_set ## varname, METH_VARARGS, \ +"(float) - Change Sound object "#varname}, + + +/*****************************************************************************/ +/* Python BPy_Sound methods declarations: */ +/*****************************************************************************/ +static PyObject *Sound_getName(BPy_Sound *self); +static PyObject *Sound_getFilename(BPy_Sound *self); +static PyObject *Sound_play(BPy_Sound *self); +static PyObject *Sound_makeActive(BPy_Sound *self); +SOUND_FLOAT_METHODS(Volume, volume) +SOUND_FLOAT_METHODS(Panning, panning) +SOUND_FLOAT_METHODS(Attenuation, attenuation) +SOUND_FLOAT_METHODS(Pitch, pitch) +SOUND_FLOAT_METHODS(MinGain, min_gain) +SOUND_FLOAT_METHODS(MaxGain, max_gain) +SOUND_FLOAT_METHODS(Distance, distance) + +/*****************************************************************************/ +/* Python BPy_Sound methods table: */ +/*****************************************************************************/ +static PyMethodDef BPy_Sound_methods[] = { + /* name, method, flags, doc */ + {"getName", (PyCFunction)Sound_getName, METH_NOARGS, + "() - Return Sound object name"}, + {"getFilename", (PyCFunction)Sound_getFilename, METH_NOARGS, + "() - Return Sound object filename"}, + {"play", (PyCFunction)Sound_play, METH_NOARGS, + "() - play this sound"}, + {"makeActive", (PyCFunction)Sound_makeActive, METH_NOARGS, + "() - make this the active sound in the sound buttons win (also redraws)"}, + SOUND_FLOAT_METHOD_FUNCS(Volume) + SOUND_FLOAT_METHOD_FUNCS(Panning) + SOUND_FLOAT_METHOD_FUNCS(Attenuation) + SOUND_FLOAT_METHOD_FUNCS(Pitch) + SOUND_FLOAT_METHOD_FUNCS(MinGain) + SOUND_FLOAT_METHOD_FUNCS(MaxGain) + SOUND_FLOAT_METHOD_FUNCS(Distance) + {NULL, NULL, 0, NULL} +}; + +/*****************************************************************************/ +/* Python Sound_Type structure definition: */ +/*****************************************************************************/ +PyTypeObject Sound_Type = +{ + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "Blender Sound", /* tp_name */ + sizeof (BPy_Sound), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)Sound_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc)Sound_getAttr, /* tp_getattr */ + (setattrfunc)Sound_setAttr, /* tp_setattr */ + (cmpfunc)Sound_compare, /* tp_compare */ + (reprfunc)Sound_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_as_hash */ + 0,0,0,0,0,0, + 0, /* tp_doc */ + 0,0,0,0,0,0, + BPy_Sound_methods, /* tp_methods */ + 0, /* tp_members */ +}; + +/*****************************************************************************/ +/* Function: M_Sound_New */ +/* Python equivalent: Blender.Sound.New */ +/*****************************************************************************/ +static PyObject *M_Sound_New(PyObject *self, PyObject *args, PyObject *keywords) +{ + printf ("In Sound_New() - unimplemented in 2.34\n"); + + Py_INCREF(Py_None); + return Py_None; +} + +/* NOTE: these were copied and modified from image.h. To Be Done TBD: + * macro-ize them, or C++ templates eventually? + */ +/********************************************************************************/ +/* Function: M_Sound_Get */ +/* Python equivalent: Blender.Sound.Get */ +/* Description: Receives a string and returns the Sound object */ +/* whose name matches the string. If no argument is */ +/* passed in, a list of all Sound names in the */ +/* current scene is returned. */ +/*********************************************************************************/ +static PyObject *M_Sound_Get(PyObject *self, PyObject *args) +{ + char *name = NULL; + bSound *snd_iter; + + if (!PyArg_ParseTuple(args, "|s", &name)) + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument (or nothing)")); + + snd_iter = G.main->sound.first; + + if (name) { /* (name) - Search Sound by name */ + + BPy_Sound *wanted_Sound = NULL; + + while ((snd_iter) && (wanted_Sound == NULL)) { + if (strcmp (name, snd_iter->id.name+2) == 0) { + wanted_Sound = (BPy_Sound *)PyObject_NEW(BPy_Sound, &Sound_Type); + if (wanted_Sound) { + wanted_Sound->sound = snd_iter; + break; + } + } + snd_iter = snd_iter->id.next; + } + + if (wanted_Sound == NULL) { /* Requested Sound doesn't exist */ + char error_msg[64]; + PyOS_snprintf(error_msg, sizeof(error_msg), + "Sound \"%s\" not found", name); + return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); + } + + return (PyObject *)wanted_Sound; + } + + else { /* () - return a list of all Sounds in the scene */ + int index = 0; + PyObject *snd_list, *pyobj; + + snd_list = PyList_New (BLI_countlist (&(G.main->sound))); + + if (snd_list == NULL) + return (EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create PyList")); + + while (snd_iter) { + pyobj = Sound_CreatePyObject (snd_iter); + + if (!pyobj) + return (EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create PyObject")); + + PyList_SET_ITEM (snd_list, index, pyobj); + + snd_iter = snd_iter->id.next; + index++; + } + + return (snd_list); + } +} + +/*****************************************************************************/ +/* Function: M_Sound_Load */ +/* Python equivalent: Blender.Sound.Load */ +/* Description: Receives a string and returns the Sound object */ +/* whose filename matches the string. */ +/*****************************************************************************/ +static PyObject *M_Sound_Load(PyObject *self, PyObject *args) +{ + char *fname; + bSound *snd_ptr; + BPy_Sound *snd; + + if (!PyArg_ParseTuple(args, "s", &fname)) + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument")); + + snd = (BPy_Sound *)PyObject_NEW(BPy_Sound, &Sound_Type); + + if (!snd) + return (EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create PyObject Sound_Type")); + + snd_ptr = sound_new_sound(fname); + + if (snd_ptr) { + if (G.ssound) { + G.ssound->sound= snd_ptr; + } + } + + if (!snd_ptr) + return (EXPP_ReturnPyObjError (PyExc_IOError, + "not a valid sound sample")); + + snd->sound = snd_ptr; + + return (PyObject *)snd; +} + +/*****************************************************************************/ +/* Function: Sound_Init */ +/*****************************************************************************/ +PyObject *Sound_Init (void) +{ + PyObject *submodule; + + Sound_Type.ob_type = &PyType_Type; + + submodule = Py_InitModule3("Blender.Sound", M_Sound_methods, M_Sound_doc); + + return (submodule); +} + +/************************/ +/*** The Sound PyType ***/ +/************************/ + +/*****************************************************************************/ +/* Function: Sound_dealloc */ +/* Description: This is a callback function for the BPy_Sound type. It is */ +/* the destructor function. */ +/*****************************************************************************/ +static void Sound_dealloc (BPy_Sound *self) +{ + PyObject_DEL (self); +} + +/*****************************************************************************/ +/* Function: Sound_CreatePyObject */ +/* Description: This function will create a new BPy_Sound from an existing */ +/* Blender Sound structure. */ +/*****************************************************************************/ +PyObject *Sound_CreatePyObject (bSound *snd) +{ + BPy_Sound *py_snd; + + py_snd = (BPy_Sound *)PyObject_NEW (BPy_Sound, &Sound_Type); + + if (!py_snd) + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create BPy_Sound object"); + + py_snd->sound = snd; + + return (PyObject *)py_snd; +} + +/*****************************************************************************/ +/* Function: Sound_CheckPyObject */ +/* Description: This function returns true when the given PyObject is of the */ +/* type Sound. Otherwise it will return false. */ +/*****************************************************************************/ +int Sound_CheckPyObject (PyObject *pyobj) +{ + return (pyobj->ob_type == &Sound_Type); +} + +/*****************************************************************************/ +/* Function: Sound_FromPyObject */ +/* Description: Returns the Blender Sound associated with this object */ +/*****************************************************************************/ +bSound *Sound_FromPyObject (PyObject *pyobj) +{ + return ((BPy_Sound *)pyobj)->sound; +} + +/*****************************************************************************/ +/* Python BPy_Sound methods: */ +/*****************************************************************************/ +static PyObject *Sound_getName(BPy_Sound *self) +{ + PyObject *attr = PyString_FromString(self->sound->id.name+2); + + if (attr) return attr; + + return (EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't get Sound.name attribute")); +} + +static PyObject *Sound_getFilename(BPy_Sound *self) +{ + PyObject *attr = PyString_FromString(self->sound->name); + + if (attr) return attr; + + return (EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't get Sound.filename attribute")); +} + +static PyObject *Sound_play(BPy_Sound *self) +{ + sound_play_sound(self->sound); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *Sound_makeActive(BPy_Sound *self) +{ + bSound *snd_ptr = self->sound; + + if (snd_ptr) { + if (G.ssound) { + G.ssound->sound = snd_ptr; + } + } + + allqueue(REDRAWSOUND, 0); + allqueue(REDRAWBUTSLOGIC, 0); + + Py_INCREF (Py_None); + return Py_None; +} + +/*****************************************************************************/ +/* Function: Sound_getAttr */ +/* Description: This is a callback function for the BPy_Sound type. It is */ +/* the function that accesses BPy_Sound member variables and */ +/* methods. */ +/*****************************************************************************/ +static PyObject *Sound_getAttr (BPy_Sound *self, char *name) +{ + PyObject *attr = Py_None; + + if (strcmp(name, "name") == 0) + attr = PyString_FromString(self->sound->id.name+2); + else if (strcmp(name, "filename") == 0) + attr = PyString_FromString(self->sound->name); + + else if (strcmp(name, "__members__") == 0) + attr = Py_BuildValue("[s,s]", + "name", "filename"); + + if (!attr) + return (EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create PyObject")); + + if (attr != Py_None) return attr; /* attribute found, return its value */ + + /* not an attribute, search the methods table */ + return Py_FindMethod(BPy_Sound_methods, (PyObject *)self, name); +} + +/*****************************************************************************/ +/* Function: Sound_setAttr */ +/* Description: This is a callback function for the BPy_Sound type. It is the*/ +/* function that changes Sound object members values. If this */ +/* data is linked to a Blender Sound, it also gets updated. */ +/*****************************************************************************/ +static int Sound_setAttr (BPy_Sound *self, char *name, PyObject *value) +{ + PyObject *valtuple; + PyObject *error = NULL; + +/* We're playing a trick on the Python API users here. Even if they use + * Sound.member = val instead of Sound.setMember(value), we end up using the + * function anyway, since it already has error checking, clamps to the right + * interval and updates the Blender Sound structure when necessary. */ + + valtuple = Py_BuildValue("(O)", value); /*the set* functions expect a tuple*/ + + if (!valtuple) + return EXPP_ReturnIntError(PyExc_MemoryError, + "SoundSetAttr: couldn't create PyTuple"); + +/* if (strcmp (name, "name") == 0) + error = Sound_setName (self, valtuple); + else */ { + /* Error: no such member in the Sound object structure */ + Py_DECREF(value); + Py_DECREF(valtuple); + return (EXPP_ReturnIntError (PyExc_KeyError, + "attribute not found or immutable")); + } + + Py_DECREF(valtuple); + + if (error != Py_None) return -1; + + Py_DECREF(Py_None); /* incref'ed by the called set* function */ + return 0; /* normal exit */ +} + +/*****************************************************************************/ +/* Function: Sound_compare */ +/* Description: This is a callback function for the BPy_Sound type. It */ +/* compares two Sound_Type objects. Only the "==" and "!=" */ +/* comparisons are meaninful. Returns 0 for equality and -1 if */ +/* they don't point to the same Blender Sound struct. */ +/* In Python it becomes 1 if they are equal, 0 otherwise. */ +/*****************************************************************************/ +static int Sound_compare (BPy_Sound *a, BPy_Sound *b) +{ + bSound *pa = a->sound, *pb = b->sound; + return (pa == pb) ? 0:-1; +} + +/*****************************************************************************/ +/* Function: Sound_repr */ +/* Description: This is a callback function for the BPy_Sound type. It */ +/* builds a meaninful string to represent Sound objects. */ +/*****************************************************************************/ +static PyObject *Sound_repr (BPy_Sound *self) +{ + return PyString_FromFormat("[Sound \"%s\"]", self->sound->id.name+2); +} |