fixes compilation problems related to sip4 (Python/C++ binding generator).

The version included is 4.1.1. If you generate some files using a new version 
of sip4, update or remove sip.h in the apps/py_sems/sip directory.


git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@231 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Raphael Coeffic 20 years ago
parent 5dbbe0e7ab
commit 2fc65e1012

@ -1,598 +0,0 @@
/*
* $Id: Ivr.cpp,v 1.26.2.1 2005/09/02 13:47:46 rco Exp $
* Copyright (C) 2002-2003 Fhg Fokus
*
* This file is part of sems, a free SIP media server.
*
* 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
*
* 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
*/
//#include "IvrDialogBase.h"
//#include "IvrSipDialog.h"
#include "IvrAudio.h"
#include "Ivr.h"
#include "AmConfigReader.h"
#include "AmConfig.h"
#include "log.h"
#include "AmApi.h"
#include "AmUtils.h"
#include "AmSessionScheduler.h"
//#include "AmSessionTimer.h"
#include "AmPlugIn.h"
#include "sip/sipAPIpy_ivr.h"
#include "sip/sippy_ivrIvrDialog.h"
#include <unistd.h>
#include <pthread.h>
#include <regex.h>
#include <dirent.h>
#include <set>
using std::set;
#define PYFILE_REGEX "(.+)\\.(py|pyc|pyo)$"
EXPORT_SESSION_FACTORY(IvrFactory,MOD_NAME);
PyMODINIT_FUNC initpy_ivr();
struct PythonGIL
{
PyGILState_STATE gst;
PythonGIL() { gst = PyGILState_Ensure(); }
~PythonGIL(){ PyGILState_Release(gst); }
};
// This must be the first declaration of every
// function using Python C-API.
// But this is not necessary in function which
// will get called from Python
#define PYLOCK PythonGIL _py_gil
extern "C" {
static PyObject* ivr_log(PyObject*, PyObject* args)
{
int level;
char *msg;
if(!PyArg_ParseTuple(args,"is",&level,&msg))
return NULL;
if((level)<=log_level) {
//if(level == L_ERR)
//assert(0);
if(log_stderr)
log_print( level, msg );
else {
switch(level){
case L_ERR:
syslog(LOG_ERR | L_FAC, "Error: %s", msg);
break;
case L_WARN:
syslog(LOG_WARNING | L_FAC, "Warning: %s", msg);
break;
case L_INFO:
syslog(LOG_INFO | L_FAC, "Info: %s", msg);
break;
case L_DBG:
syslog(LOG_DEBUG | L_FAC, "Debug: %s", msg);
break;
}
}
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* ivr_getHeader(PyObject*, PyObject* args)
{
char* headers;
char* header_name;
if(!PyArg_ParseTuple(args,"ss",&headers,&header_name))
return NULL;
string res = getHeader(headers,header_name);
return PyString_FromString(res.c_str());
}
static PyMethodDef ivr_methods[] = {
{"log", (PyCFunction)ivr_log, METH_VARARGS,"Log a message using Sems' logging system"},
{"getHeader", (PyCFunction)ivr_getHeader, METH_VARARGS,"Python getHeader wrapper"},
{NULL} /* Sentinel */
};
}
IvrFactory::IvrFactory(const string& _app_name)
: AmSessionFactory(_app_name),
user_timer_fact(NULL)
{
}
void IvrFactory::setScriptPath(const string& path)
{
string python_path = script_path = path;
if(python_path.length()){
python_path = AmConfig::PlugInPath + ":" + python_path;
}
else
python_path = AmConfig::PlugInPath;
char* old_path=0;
if((old_path = getenv("PYTHONPATH")) != 0)
if(strlen(old_path))
python_path += ":" + string(old_path);
DBG("setting PYTHONPATH to: '%s'\n",python_path.c_str());
setenv("PYTHONPATH",python_path.c_str(),1);
}
void IvrFactory::import_object(PyObject* m, char* name, PyTypeObject* type)
{
if (PyType_Ready(type) < 0){
ERROR("PyType_Ready failed !\n");
return;
}
Py_INCREF(type);
PyModule_AddObject(m, name, (PyObject *)type);
}
void IvrFactory::import_ivr_builtins()
{
// ivr module - start
PyImport_AddModule("ivr");
ivr_module = Py_InitModule("ivr",ivr_methods);
// IvrSipDialog (= AmSipDialog)
//import_object(ivr_module, "IvrSipDialog", &IvrSipDialogType);
// IvrDialogBase
//import_object(ivr_module,"IvrDialogBase",&IvrDialogBaseType);
// IvrAudioFile
import_object(ivr_module,"IvrAudioFile",&IvrAudioFileType);
PyModule_AddIntConstant(ivr_module, "AUDIO_READ",AUDIO_READ);
PyModule_AddIntConstant(ivr_module, "AUDIO_WRITE",AUDIO_WRITE);
// ivr module - end
// add log level for the log module
PyModule_AddIntConstant(ivr_module, "SEMS_LOG_LEVEL",log_level);
import_module("log");
initpy_ivr();
}
void IvrFactory::import_module(const char* modname)
{
PyObject* py_mod_name = PyString_FromString(modname);
PyObject* py_mod = PyImport_Import(py_mod_name);
Py_DECREF(py_mod_name);
if(!py_mod){
PyErr_Print();
ERROR("IvrFactory: could not find python module '%s'.\n",modname);
ERROR("IvrFactory: please check your installation.\n");
return;
}
}
void IvrFactory::init_python_interpreter()
{
Py_Initialize();
PyEval_InitThreads();
import_ivr_builtins();
PyEval_ReleaseLock();
}
IvrDialog* IvrFactory::newDlg(const string& name)
{
PYLOCK;
map<string,IvrScriptDesc>::iterator mod_it = mod_reg.find(name);
if(mod_it == mod_reg.end()){
ERROR("Unknown script name '%s'\n", name.c_str());
throw AmSession::Exception(500,"Unknown Application");
}
IvrScriptDesc& mod_desc = mod_it->second;
AmDynInvoke* user_timer = user_timer_fact->getInstance();
if(!user_timer){
ERROR("could not get a user timer reference\n");
throw AmSession::Exception(500,"could not get a user timer reference");
}
PyObject* dlg_inst = PyObject_Call(mod_desc.dlg_class,PyTuple_New(0),NULL);
if(!dlg_inst){
PyErr_Print();
ERROR("IvrFactory: while loading \"%s\": could not create instance\n",
name.c_str());
throw AmSession::Exception(500,"Internal error in IVR plug-in.");
return NULL;
}
int err=0;
IvrDialog* dlg = (IvrDialog*)sipForceConvertTo_IvrDialog(dlg_inst,&err);
if(!dlg || err){
PyErr_Print();
ERROR("IvrFactory: while loading \"%s\": could not retrieve IvrDialog ptr.\n",
name.c_str());
throw AmSession::Exception(500,"Internal error in IVR plug-in.");
Py_DECREF(dlg_inst);
return NULL;
}
// take the ownership over dlg
sipTransfer(dlg_inst,1);
return dlg;
}
bool IvrFactory::loadScript(const string& path)
{
PYLOCK;
PyObject *modName,*mod,*dict, *dlg_class, *config=NULL;
modName = PyString_FromString(path.c_str());
mod = PyImport_Import(modName);
AmConfigReader cfg;
string cfg_file = add2path(AmConfig::ModConfigPath,1,(path + ".conf").c_str());
Py_DECREF(modName);
if(!mod){
PyErr_Print();
WARN("IvrFactory: Failed to load \"%s\"\n", path.c_str());
dict = PyImport_GetModuleDict();
Py_INCREF(dict);
PyDict_DelItemString(dict,path.c_str());
Py_DECREF(dict);
return false;
}
dict = PyModule_GetDict(mod);
dlg_class = PyDict_GetItemString(dict, "IvrScript");
if(!dlg_class){
PyErr_Print();
WARN("IvrFactory: class IvrDialog not found in \"%s\"\n", path.c_str());
goto error1;
}
Py_INCREF(dlg_class);
if(!PyObject_IsSubclass(dlg_class,(PyObject *)sipClass_IvrDialog)){
WARN("IvrFactory: in \"%s\": IvrScript is not a "
"subtype of IvrDialog\n", path.c_str());
goto error2;
}
if(cfg.loadFile(cfg_file)){
ERROR("could not load config file at %s\n",cfg_file.c_str());
goto error2;
}
config = PyDict_New();
if(!config){
ERROR("could not allocate new dict for config\n");
goto error2;
}
for(map<string,string>::const_iterator it = cfg.begin();
it != cfg.end(); it++){
PyDict_SetItem(config,
PyString_FromString(it->first.c_str()),
PyString_FromString(it->second.c_str()));
}
PyObject_SetAttrString(mod,"config",config);
mod_reg.insert(make_pair(path,
IvrScriptDesc(mod,dlg_class)));
return true;
error2:
Py_DECREF(dlg_class);
error1:
Py_DECREF(mod);
return false;
}
/**
* Loads python script path and default script file from configuration file
*/
int IvrFactory::onLoad()
{
user_timer_fact = AmPlugIn::instance()->getFactory4Di("user_timer");
if(!user_timer_fact){
ERROR("could not load user_timer from session_timer plug-in\n");
return -1;
}
AmConfigReader cfg;
if(cfg.loadFile(add2path(AmConfig::ModConfigPath,1,MOD_NAME ".conf")))
return -1;
// get application specific global parameters
configureModule(cfg);
setScriptPath(cfg.getParameter("script_path"));
init_python_interpreter();
DBG("** IVR compile time configuration:\n");
DBG("** built with PYTHON support.\n");
#ifdef IVR_WITH_TTS
DBG("** Text-To-Speech enabled\n");
#else
DBG("** Text-To-Speech disabled\n");
#endif
DBG("** IVR run time configuration:\n");
DBG("** script path: \'%s\'\n", script_path.c_str());
regex_t reg;
if(regcomp(&reg,PYFILE_REGEX,REG_EXTENDED)){
ERROR("while compiling regular expression\n");
return -1;
}
DIR* dir = opendir(script_path.c_str());
if(!dir){
regfree(&reg);
ERROR("Ivr: script pre-loader (%s): %s\n",
script_path.c_str(),strerror(errno));
return -1;
}
DBG("directory '%s' opened\n",script_path.c_str());
set<string> unique_entries;
regmatch_t pmatch[2];
struct dirent* entry=0;
while((entry = readdir(dir)) != NULL){
if(!regexec(&reg,entry->d_name,2,pmatch,0)){
string name(entry->d_name + pmatch[1].rm_so,
pmatch[1].rm_eo - pmatch[1].rm_so);
unique_entries.insert(name);
}
}
closedir(dir);
regfree(&reg);
AmPlugIn* plugin = AmPlugIn::instance();
for(set<string>::iterator it = unique_entries.begin();
it != unique_entries.end(); it++) {
if(loadScript(*it)){
bool res = plugin->registerFactory4App(*it,this);
if(res)
INFO("Application script registered: %s.\n",
it->c_str());
}
}
return 0; // don't stop sems from starting up
}
/**
* Load a script using user name from URI.
* Note: there is no default script.
*/
AmSession* IvrFactory::onInvite(const AmSipRequest& req)
{
if(req.cmd != MOD_NAME)
return newDlg(req.cmd);
else
return newDlg(req.user);
}
IvrDialog::IvrDialog()
: py_mod(NULL),
py_dlg(NULL),
playlist(this),
user_timer(NULL)
{
sip_relay_only = false;
}
IvrDialog::IvrDialog(AmDynInvoke* user_timer)
: py_mod(NULL),
py_dlg(NULL),
playlist(this),
user_timer(user_timer)
{
sip_relay_only = false;
}
IvrDialog::~IvrDialog()
{
DBG("IvrDialog::~IvrDialog()\n");
PYLOCK;
Py_XDECREF(py_mod);
Py_XDECREF(py_dlg);
}
void IvrDialog::setPyPtrs(PyObject *mod, PyObject *dlg)
{
assert(py_mod = mod);
assert(py_dlg = dlg);
Py_INCREF(py_mod);
Py_INCREF(py_dlg);
}
static PyObject *
type_error(const char *msg)
{
PyErr_SetString(PyExc_TypeError, msg);
return NULL;
}
static PyObject *
null_error(void)
{
if (!PyErr_Occurred())
PyErr_SetString(PyExc_SystemError,
"null argument to internal routine");
return NULL;
}
PyObject *
PyObject_VaCallMethod(PyObject *o, char *name, char *format, va_list va)
{
PyObject *args, *func = 0, *retval;
if (o == NULL || name == NULL)
return null_error();
func = PyObject_GetAttrString(o, name);
if (func == NULL) {
PyErr_SetString(PyExc_AttributeError, name);
return 0;
}
if (!PyCallable_Check(func))
return type_error("call of non-callable attribute");
if (format && *format) {
args = Py_VaBuildValue(format, va);
}
else
args = PyTuple_New(0);
if (!args)
return NULL;
if (!PyTuple_Check(args)) {
PyObject *a;
a = PyTuple_New(1);
if (a == NULL)
return NULL;
if (PyTuple_SetItem(a, 0, args) < 0)
return NULL;
args = a;
}
retval = PyObject_Call(func, args, NULL);
Py_DECREF(args);
Py_DECREF(func);
return retval;
}
bool IvrDialog::callPyEventHandler(char* name, char* fmt, ...)
{
bool ret=false;
va_list va;
PYLOCK;
va_start(va, fmt);
PyObject* o = PyObject_VaCallMethod(py_dlg,name,fmt,va);
va_end(va);
if(!o) {
if(PyErr_ExceptionMatches(PyExc_AttributeError)){
DBG("method %s is not implemented, trying default one\n",name);
return true;
}
PyErr_Print();
}
else {
if(o && PyBool_Check(o) && (o == Py_True)) {
ret = true;
}
Py_DECREF(o);
}
return ret;
}
void IvrDialog::onSessionStart(const AmSipRequest& req)
{
DBG("IvrDialog::onSessionStart\n");
setInOut(&playlist,&playlist);
AmB2BCallerSession::onSessionStart(req);
}
void IvrDialog::process(AmEvent* event)
{
DBG("IvrDialog::process\n");
AmAudioEvent* audio_event = dynamic_cast<AmAudioEvent*>(event);
if(audio_event && audio_event->event_id == AmAudioEvent::noAudio){
callPyEventHandler("onEmptyQueue", NULL);
event->processed = true;
}
AmPluginEvent* plugin_event = dynamic_cast<AmPluginEvent*>(event);
if(plugin_event && plugin_event->name == "timer_timeout") {
callPyEventHandler("onTimer", "i", plugin_event->data.get(0).asInt());
event->processed = true;
}
if (!event->processed)
AmB2BCallerSession::process(event);
return;
}

@ -1,128 +0,0 @@
/*
* $Id: Ivr.h,v 1.15.2.1 2005/09/02 13:47:46 rco Exp $
* Copyright (C) 2002-2003 Fhg Fokus
*
* This file is part of sems, a free SIP media server.
*
* 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
*
* 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
*/
#ifndef _IVR_H_
#define _IVR_H_
#define MOD_NAME "ivr"
#include <Python.h>
#include "AmB2BSession.h"
#include "AmPlaylist.h"
#ifdef IVR_WITH_TTS
#include "flite.h"
#endif
#include <string>
#include <map>
using std::string;
using std::map;
class IvrDialog;
struct IvrScriptDesc
{
PyObject* mod;
PyObject* dlg_class;
IvrScriptDesc()
: mod(0),
dlg_class(0)
{}
IvrScriptDesc(const IvrScriptDesc& d)
: mod(d.mod),
dlg_class(d.dlg_class)
{}
IvrScriptDesc(PyObject* mod,
PyObject* dlg_class)
: mod(mod),
dlg_class(dlg_class)
{}
};
class IvrFactory: public AmSessionFactory
{
PyObject* ivr_module;
string script_path;
string default_script;
map<string,IvrScriptDesc> mod_reg;
AmDynInvokeFactory* user_timer_fact;
void init_python_interpreter();
void import_ivr_builtins();
void import_module(const char* modname);
void import_object(PyObject* m,
char* name,
PyTypeObject* type);
/** @return true if everything ok */
bool loadScript(const string& path);
void setScriptPath(const string& path);
bool checkCfg();
IvrDialog* newDlg(const string& name);
public:
IvrFactory(const string& _app_name);
int onLoad();
AmSession* onInvite(const AmSipRequest& req);
};
class IvrDialog : public AmB2BCallerSession
{
PyObject *py_mod;
PyObject *py_dlg;
bool callPyEventHandler(char* name, char* fmt, ...);
void process(AmEvent* event);
public:
AmDynInvoke* user_timer;
AmPlaylist playlist;
IvrDialog();
IvrDialog(AmDynInvoke* user_timer);
~IvrDialog();
// must be called before everything else.
void setPyPtrs(PyObject *mod, PyObject *dlg);
void onSessionStart(const AmSipRequest& req);
/* void onBye(const AmSipRequest& req); */
/* void onDtmf(int event, int duration_msec); */
/* void onOtherBye(const AmSipRequest& req); */
/* void onOtherReply(const AmSipReply& r); */
};
#endif

@ -1,321 +0,0 @@
#include "IvrAudio.h"
#include "AmAudio.h"
#include "AmSession.h"
#include "log.h"
#ifdef IVR_WITH_TTS
#define TTS_CACHE_PATH "/tmp/"
extern "C" cst_voice *register_cmu_us_kal();
#endif //ivr_with_tts
static PyObject* IvrAudioFile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
DBG("---------- IvrAudioFile_alloc -----------\n");
IvrAudioFile *self;
self = (IvrAudioFile *)type->tp_alloc(type, 0);
if (self != NULL) {
self->af = new AmAudioFile();
if(!self->af){
Py_DECREF(self);
return NULL;
}
#ifdef IVR_WITH_TTS
flite_init();
self->tts_voice = register_cmu_us_kal();
self->filename = new string();
#endif
}
return (PyObject *)self;
}
static void IvrAudioFile_dealloc(IvrAudioFile* self)
{
DBG("---------- IvrAudioFile_dealloc -----------\n");
delete self->af;
self->af = NULL;
#ifdef IVR_WITH_TTS
if(self->del_file && !self->filename->empty())
unlink(self->filename->c_str());
delete self->filename;
#endif
self->ob_type->tp_free((PyObject*)self);
}
static PyObject* IvrAudioFile_open(IvrAudioFile* self, PyObject* args)
{
int ivr_open_mode;
char* filename;
bool is_tmp;
PyObject* py_is_tmp = NULL;
AmAudioFile::OpenMode open_mode;
if(!PyArg_ParseTuple(args,"si|O",&filename,&ivr_open_mode,&py_is_tmp))
return NULL;
switch(ivr_open_mode){
case AUDIO_READ:
open_mode = AmAudioFile::Read;
break;
case AUDIO_WRITE:
open_mode = AmAudioFile::Write;
break;
default:
PyErr_SetString(PyExc_TypeError,"Unknown open mode");
return NULL;
break;
}
if((py_is_tmp == NULL) || (py_is_tmp == Py_False))
is_tmp = false;
else if(py_is_tmp == Py_True)
is_tmp = true;
else {
PyErr_SetString(PyExc_TypeError,"third parameter should be of type PyBool");
return NULL;
}
if(self->af->open(filename,open_mode,is_tmp)){
PyErr_SetString(PyExc_IOError,"Could not open file");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* IvrAudioFile_fpopen(IvrAudioFile* self, PyObject* args)
{
int ivr_open_mode;
char* filename;
PyObject* py_file = NULL;
AmAudioFile::OpenMode open_mode;
if(!PyArg_ParseTuple(args,"siO",&filename,&ivr_open_mode,&py_file))
return NULL;
switch(ivr_open_mode){
case AUDIO_READ:
open_mode = AmAudioFile::Read;
break;
case AUDIO_WRITE:
open_mode = AmAudioFile::Write;
break;
default:
PyErr_SetString(PyExc_TypeError,"Unknown open mode");
return NULL;
break;
}
FILE* fp = PyFile_AsFile(py_file);
if(!fp){
PyErr_SetString(PyExc_IOError,"Could not get FILE pointer");
return NULL;
}
if(self->af->fpopen(filename,open_mode,fp)){
PyErr_SetString(PyExc_IOError,"Could not open file");
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* IvrAudioFile_rewind(IvrAudioFile* self, PyObject* args)
{
self->af->rewind();
Py_INCREF(Py_None);
return Py_None;
}
#ifdef IVR_WITH_TTS
static PyObject* IvrAudioFile_tts(PyObject* cls, PyObject* args)
{
char* text;
if(!PyArg_ParseTuple(args,"s",&text))
return NULL;
PyObject* constr_args = Py_BuildValue("(O)",Py_None);
PyObject* tts_file = PyObject_CallObject(cls,constr_args);
Py_DECREF(constr_args);
if(tts_file == NULL){
PyErr_Print();
PyErr_SetString(PyExc_RuntimeError,"could not create new IvrAudioFile object");
return NULL;
}
IvrAudioFile* self = (IvrAudioFile*)tts_file;
*self->filename = string(TTS_CACHE_PATH) + AmSession::getNewId() + string(".wav");
self->del_file = true;
flite_text_to_speech(text,self->tts_voice,self->filename->c_str());
if(self->af->open(self->filename->c_str(),AmAudioFile::Read)){
Py_DECREF(tts_file);
PyErr_SetString(PyExc_IOError,"could not open TTS file");
return NULL;
}
return tts_file;
}
#endif
static PyObject* IvrAudioFile_close(IvrAudioFile* self, PyObject*)
{
self->af->close();
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* IvrAudioFile_getDataSize(IvrAudioFile* self, PyObject*)
{
return PyInt_FromLong(self->af->getDataSize());
}
static PyObject* IvrAudioFile_setRecordTime(IvrAudioFile* self, PyObject* args)
{
int rec_time;
if(!PyArg_ParseTuple(args,"i",&rec_time))
return NULL;
self->af->setRecordTime(rec_time);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* IvrAudioFile_exportRaw(IvrAudioFile* self, PyObject*)
{
if(self->af->getMode() == AmAudioFile::Write)
self->af->on_close();
self->af->rewind();
return PyFile_FromFile(self->af->getfp(),"","rwb",NULL);
}
static PyMethodDef IvrAudioFile_methods[] = {
{"open", (PyCFunction)IvrAudioFile_open, METH_VARARGS,
"open the audio file"
},
{"fpopen", (PyCFunction)IvrAudioFile_fpopen, METH_VARARGS,
"open the audio file"
},
{"close", (PyCFunction)IvrAudioFile_close, METH_NOARGS,
"close the audio file"
},
{"rewind", (PyCFunction)IvrAudioFile_rewind, METH_NOARGS,
"rewind the audio file"
},
{"getDataSize", (PyCFunction)IvrAudioFile_getDataSize, METH_NOARGS,
"returns the recorded data size"
},
{"setRecordTime", (PyCFunction)IvrAudioFile_setRecordTime, METH_VARARGS,
"set the maximum record time in millisecond"
},
{"exportRaw", (PyCFunction)IvrAudioFile_exportRaw, METH_NOARGS,
"creates a new Python file with the actual file"
" and eventually flushes headers (audio->on_stop)"
},
#ifdef IVR_WITH_TTS
{"tts", (PyCFunction)IvrAudioFile_tts, METH_CLASS | METH_VARARGS,
"text to speech"
},
#endif
{NULL} /* Sentinel */
};
static PyObject* IvrAudioFile_getloop(IvrAudioFile* self, void*)
{
PyObject* loop = self->af->loop.get() ? Py_True : Py_False;
Py_INCREF(loop);
return loop;
}
static int IvrAudioFile_setloop(IvrAudioFile* self, PyObject* value, void*)
{
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
return -1;
}
if(value == Py_True)
self->af->loop.set(true);
else if(value == Py_False)
self->af->loop.set(false);
else {
PyErr_SetString(PyExc_TypeError,
"The first attribute value must be a boolean");
return -1;
}
return 0;
}
static PyGetSetDef IvrAudioFile_getseters[] = {
{"loop",
(getter)IvrAudioFile_getloop, (setter)IvrAudioFile_setloop,
"repeat mode",
NULL},
{NULL} /* Sentinel */
};
PyTypeObject IvrAudioFileType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"ivr.IvrAudioFile", /*tp_name*/
sizeof(IvrAudioFile), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)IvrAudioFile_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"An audio file", /*tp_doc*/
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
IvrAudioFile_methods, /* tp_methods */
0, /* tp_members */
IvrAudioFile_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
IvrAudioFile_new, /* tp_new */
};

@ -1,33 +0,0 @@
#ifndef IvrAudio_h
#define IvrAudio_h
// Python stuff
#include <Python.h>
#include "structmember.h"
#include "AmAudio.h"
#define AUDIO_READ 1
#define AUDIO_WRITE 2
#ifdef IVR_WITH_TTS
#include "flite.h"
#endif
// Data definition
typedef struct {
PyObject_HEAD
AmAudioFile* af;
#ifdef IVR_WITH_TTS
cst_voice* tts_voice;
string* filename;
bool del_file;
#endif
} IvrAudioFile;
extern PyTypeObject IvrAudioFileType;
#endif

@ -3,7 +3,7 @@ plug_in_name = py_sems
COREPATH ?=../../core
SCRIPT = Python
TTS = y
TTS ?= y
#
# Python specific
@ -25,7 +25,7 @@ PYTHON_LIBDIR = $(PYTHON_PREFIX)/lib/python$(PY_VER)
# put used Python modules from lib-dynload here, e.g. time, mysql, _cvs.so etc.
PYTHON_DYNLOAD_MODULES = $(wildcard $(PYTHON_LIBDIR)/lib-dynload/*.so) \
$(wildcard $(PYTHON_LIBDIR)/site-packages/*.so)
PYTHON_module_cflags = -I$(PYTHON_DIR)
PYTHON_module_cflags = -I$(PYTHON_DIR) -Isip/
PYTHON_module_ldflags = -Xlinker --export-dynamic \
-L$(PYTHON_LIBDIR)/config \
-lpython$(PY_VER) $(wildcard sip/*.o)

@ -27,7 +27,6 @@
#include "log.h"
#include "AmApi.h"
#include "AmUtils.h"
#include "AmMediaProcessor.h"
#include "AmPlugIn.h"
#include "sip/sipAPIpy_sems_lib.h"

@ -0,0 +1,560 @@
/*
* The SIP module interface.
*
* Copyright (c) 2004
* Riverbank Computing Limited <info@riverbankcomputing.co.uk>
*
* This file is part of SIP.
*
* This copy of SIP is licensed for use under the terms of the SIP License
* Agreement. See the file LICENSE for more details.
*
* SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _SIP_H
#define _SIP_H
#include <Python.h>
/*
* There is a mis-feature somewhere with the Borland compiler. This works
* around it.
*/
#if defined(__BORLANDC__)
#include <rpc.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Sanity check on the Python version. */
#if PY_VERSION_HEX < 0x02030000
#error "This version of SIP requires Python v2.3 or later"
#endif
/*
* Define the SIP version number.
*/
#define SIP_VERSION 0x040101
#define SIP_VERSION_STR "4.1.1"
#define SIP_BUILD "255"
/*
* Define the current API version number. SIP must handle modules with the
* same major number and with the same or earlier minor number. Whenever data
* structure elements are added they must be appended and the minor number
* incremented. Whenever data structure elements are removed or the order
* changed then the major number must be incremented and the minor number set
* to 0.
*
* History:
*
* 0.2 Added the 'H' format character to sip_api_parse_args().
*
* 0.1 Added sip_api_add_class_instance().
* Added the 't' format character to sip_api_parse_args().
* Deprecated the 'J' and 'K' format characters to sip_api_parse_result().
*
* 0.0 Original version.
*/
#define SIP_API_MAJOR_NR 0
#define SIP_API_MINOR_NR 2
/* Some compatibility stuff to help with handwritten code for SIP v3. */
#if !defined(ANY)
#define ANY void
#endif
/*
* The mask that can be passed to sipTrace().
*/
#define SIP_TRACE_CATCHERS 0x0001
#define SIP_TRACE_CTORS 0x0002
#define SIP_TRACE_DTORS 0x0004
#define SIP_TRACE_INITS 0x0008
#define SIP_TRACE_DEALLOCS 0x0010
#define SIP_TRACE_METHODS 0x0020
/*
* Hide some thread dependent stuff.
*/
#ifdef WITH_THREAD
typedef PyGILState_STATE sip_gilstate_t;
#define SIP_RELEASE_GIL(gs) PyGILState_Release(gs);
#define SIP_BLOCK_THREADS {PyGILState_STATE sipGIL = PyGILState_Ensure();
#define SIP_UNBLOCK_THREADS PyGILState_Release(sipGIL);}
#else
typedef int sip_gilstate_t;
#define SIP_RELEASE_GIL(gs)
#define SIP_BLOCK_THREADS
#define SIP_UNBLOCK_THREADS
#endif
/*
* The metatype for a wrapper type.
*/
typedef struct _sipWrapperType {
PyHeapTypeObject super; /* The super-metatype. */
struct _sipTypeDef *type; /* The additional type information. */
} sipWrapperType;
/*
* A C/C++ object wrapped as a Python object.
*/
typedef struct _sipWrapper {
PyObject_HEAD
union {
void *cppPtr; /* C/C++ object pointer. */
void *(*afPtr)(); /* Access function. */
} u;
int flags; /* Object flags. */
PyObject *dict; /* The instance dictionary. */
struct _sipPySig *pySigList; /* Python signal list (complex). */
struct _sipWrapper *next; /* Next object at this address. */
} sipWrapper;
/*
* Some convenient function pointers.
*/
typedef void *(*sipInitFunc)(sipWrapper *,PyObject *,int *);
typedef void (*sipDeallocFunc)(sipWrapper *);
typedef void *(*sipCastFunc)(void *,sipWrapperType *);
typedef sipWrapperType *(*sipSubClassConvertFunc)(void *);
typedef void *(*sipForceConvertToFunc)(PyObject *,int *);
typedef int (*sipConvertToFunc)(PyObject *,void **,int *);
typedef PyObject *(*sipConvertFromFunc)(void *);
typedef struct _sipProxy *(*sipProxyFunc)(void);
typedef int (*sipVirtHandlerFunc)(void *,PyObject *,...);
typedef int (*sipEmitFunc)(sipWrapper *,PyObject *);
/*
* The information describing an enum value instance to be added to a
* dictionary.
*/
typedef struct _sipEnumValueInstanceDef {
char *evi_name; /* The enum value name. */
int evi_val; /* The enum value value. */
} sipEnumValueInstanceDef;
/*
* The information describing static instances.
*/
typedef struct _sipInstancesDef {
struct _sipClassInstanceDef *id_class; /* The classes. */
struct _sipVoidPtrInstanceDef *id_voidp; /* The void *. */
struct _sipCharInstanceDef *id_char; /* The chars. */
struct _sipStringInstanceDef *id_string; /* The strings. */
struct _sipLongInstanceDef *id_long; /* The longs. */
struct _sipDoubleInstanceDef *id_double; /* The doubles. */
} sipInstancesDef;
/*
* The information describing a super-class.
*/
typedef struct _sipSuperClassDef {
unsigned sc_class:16; /* The class number. */
unsigned sc_module:8; /* The module number (255 for this one). */
unsigned sc_last:1; /* The last in the list. */
} sipSuperClassDef;
/*
* The information describing a sub-class convertor.
*/
typedef struct _sipSubClassConvertorDef {
sipSubClassConvertFunc scc_convertor; /* The convertor. */
sipSuperClassDef scc_base; /* The encoded base type. */
sipWrapperType *scc_basetype; /* The base type. */
} sipSubClassConvertorDef;
/*
* The different Python slot types.
*/
typedef enum {
str_slot, /* __str__ */
int_slot, /* __int__ */
len_slot, /* __len__ */
contains_slot, /* __contains__ */
add_slot, /* __add__ for number */
concat_slot, /* __add__ for sequence types */
sub_slot, /* __sub__ */
mul_slot, /* __mul__ for number types */
repeat_slot, /* __mul__ for sequence types */
div_slot, /* __div__ */
mod_slot, /* __mod__ */
and_slot, /* __and__ */
or_slot, /* __or__ */
xor_slot, /* __xor__ */
lshift_slot, /* __lshift__ */
rshift_slot, /* __rshift__ */
iadd_slot, /* __iadd__ for number types */
iconcat_slot, /* __iadd__ for sequence types */
isub_slot, /* __isub__ */
imul_slot, /* __imul__ for number types */
irepeat_slot, /* __imul__ for sequence types */
idiv_slot, /* __idiv__ */
imod_slot, /* __imod__ */
iand_slot, /* __iand__ */
ior_slot, /* __ior__ */
ixor_slot, /* __ixor__ */
ilshift_slot, /* __ilshift__ */
irshift_slot, /* __irshift__ */
invert_slot, /* __invert__ */
call_slot, /* __call__ */
getitem_slot, /* __getitem__ */
setitem_slot, /* __setitem__ */
delitem_slot, /* __delitem__ */
lt_slot, /* __lt__ */
le_slot, /* __le__ */
eq_slot, /* __eq__ */
ne_slot, /* __ne__ */
gt_slot, /* __gt__ */
ge_slot, /* __ge__ */
cmp_slot, /* __cmp__ */
nonzero_slot, /* __nonzero__ */
neg_slot, /* __neg__ */
repr_slot /* __repr__ */
} sipPySlotType;
/*
* The information describing a Python slot function.
*/
typedef struct _sipPySlotDef {
void *psd_func; /* The function. */
sipPySlotType psd_type; /* The type. */
} sipPySlotDef;
/*
* The information describing a type.
*/
typedef struct _sipTypeDef {
struct _sipExportedModuleDef *td_module; /* The module. */
char *td_name; /* The name of the type. */
int td_scope; /* The nr. of the scoping type. */
sipSuperClassDef *td_supers; /* The super-types. */
sipPySlotDef *td_pyslots; /* The table of Python slots. */
int td_nrmethods; /* The number of lazy methods. */
PyMethodDef *td_methods; /* The table of lazy methods. */
int td_nrenums; /* The number of lazy enums. */
sipEnumValueInstanceDef *td_enums; /* The table of lazy enums. */
PyMethodDef *td_variables; /* The variable table. */
sipInitFunc td_init; /* The initialisation function. */
sipDeallocFunc td_dealloc; /* The deallocation function. */
sipCastFunc td_cast; /* The cast function, 0 if a C struct. */
sipForceConvertToFunc td_fcto; /* The force convert to function, 0 if a C++ namespace. */
sipConvertToFunc td_cto; /* The convert to function. */
sipProxyFunc td_proxy; /* The create proxy function. */
struct _sipQtSignal *td_emit; /* Emit table for Qt signals. */
sipInstancesDef td_instances; /* The static instances. */
} sipTypeDef;
/*
* The information describing a mapped class.
*/
typedef struct _sipMappedTypeDef {
sipForceConvertToFunc mt_fcto; /* The force convert to function. */
sipConvertToFunc mt_cto; /* The convert to function. */
sipConvertFromFunc mt_cfrom; /* The convert from function. */
} sipMappedTypeDef;
/*
* The information describing an imported module.
*/
typedef struct _sipImportedModuleDef {
char *im_name; /* The module name. */
int im_version; /* The required version. */
struct _sipExportedModuleDef *im_module; /* The imported module. */
} sipImportedModuleDef;
/*
* The main client module structure.
*/
typedef struct _sipExportedModuleDef {
struct _sipExportedModuleDef *em_next; /* The next in the list. */
char *em_name; /* The module name. */
int em_version; /* The module version. */
sipImportedModuleDef *em_imports; /* The imported modules. */
int em_qobject_class; /* The index of the QObject class. */
struct _sipWrapperType **em_types; /* The table of types. */
sipMappedTypeDef **em_mappedtypes; /* The table of mapped types. */
sipVirtHandlerFunc *em_virthandlers; /* The table of virtual handlers. */
sipSubClassConvertorDef *em_convertors; /* The sub-class convertors. */
sipInstancesDef em_instances; /* The static instances. */
struct _sipLicenseDef *em_license; /* The license. */
} sipExportedModuleDef;
/*
* The information describing a license to be added to a dictionary.
*/
typedef struct _sipLicenseDef {
char *lc_type; /* The type of license. */
char *lc_licensee; /* The licensee. */
char *lc_timestamp; /* The timestamp. */
char *lc_signature; /* The signature. */
} sipLicenseDef;
/*
* The information describing a void pointer instance to be added to a
* dictionary.
*/
typedef struct _sipVoidPtrInstanceDef {
char *vi_name; /* The void pointer name. */
void *vi_val; /* The void pointer value. */
} sipVoidPtrInstanceDef;
/*
* The information describing a char instance to be added to a dictionary.
*/
typedef struct _sipCharInstanceDef {
char *ci_name; /* The char name. */
char ci_val; /* The char value. */
} sipCharInstanceDef;
/*
* The information describing a string instance to be added to a dictionary.
*/
typedef struct _sipStringInstanceDef {
char *si_name; /* The string name. */
char *si_val; /* The string value. */
} sipStringInstanceDef;
/*
* The information describing a long instance to be added to a dictionary.
*/
typedef struct _sipLongInstanceDef {
char *li_name; /* The long name. */
long li_val; /* The long value. */
} sipLongInstanceDef;
/*
* The information describing a double instance to be added to a dictionary.
*/
typedef struct _sipDoubleInstanceDef {
char *di_name; /* The double name. */
double di_val; /* The double value. */
} sipDoubleInstanceDef;
/*
* The information describing a class instance to be added to a dictionary.
*/
typedef struct _sipClassInstanceDef {
char *ci_name; /* The class name. */
void *ci_ptr; /* The actual instance. */
struct _sipWrapperType **ci_type; /* A pointer to the Python type. */
int ci_flags; /* The wrapping flags. */
} sipClassInstanceDef;
/*
* Define a mapping between a wrapped type identified by a string and the
* corresponding Python type.
*/
typedef struct _sipStringTypeClassMap {
char *typeString; /* The type as a string. */
struct _sipWrapperType **pyType; /* A pointer to the Python type. */
} sipStringTypeClassMap;
/*
* Define a mapping between a wrapped type identified by an integer and the
* corresponding Python type.
*/
typedef struct _sipIntTypeClassMap {
int typeInt; /* The type as an integer. */
struct _sipWrapperType **pyType; /* A pointer to the Python type. */
} sipIntTypeClassMap;
/*
* A Python method's component parts. This allows us to re-create the method
* without changing the reference counts of the components.
*/
typedef struct _sipPyMethod {
PyObject *mfunc; /* The function. */
PyObject *mself; /* Self if it is a bound method. */
PyObject *mclass; /* The class. */
} sipPyMethod;
/*
* Cache a reference to a Python member function.
*/
typedef struct _sipMethodCache {
int mcflags; /* Method cache flags. */
sipPyMethod pyMethod; /* The method. */
} sipMethodCache;
/*
* A slot (in the Qt, rather than Python, sense).
*/
typedef struct _sipSlot {
char *name; /* Name if a Qt or Python signal. */
PyObject *pyobj; /* Signal or Qt slot object. */
sipPyMethod meth; /* Python slot method, pyobj is NULL. */
PyObject *weakSlot; /* A weak reference to the slot. */
} sipSlot;
/*
* A proxy slot.
*/
typedef struct _sipProxy {
void *qproxy; /* The proxy QObject. */
const char **slotTable; /* The table of slots. */
sipSlot realSlot; /* The Python slot. */
struct _sipWrapper *txSelf; /* The transmitter. */
char *txSig; /* The transmitting signal. */
const char *rxSlot; /* The receiving slot. */
struct _sipProxy *next; /* Next in list. */
struct _sipProxy *prev; /* Previous in list. */
} sipProxy;
/*
* A receiver of a Python signal.
*/
typedef struct _sipPySigRx {
sipSlot rx; /* The receiver. */
struct _sipPySigRx *next; /* Next in the list. */
} sipPySigRx;
/*
* A Python signal.
*/
typedef struct _sipPySig {
char *name; /* The name of the signal. */
sipPySigRx *rxlist; /* The list of receivers. */
struct _sipPySig *next; /* Next in the list. */
} sipPySig;
/*
* Maps the name of a Qt signal to a wrapper function to emit it.
*/
typedef struct _sipQtSignal {
char *st_name; /* The signal name. */
sipEmitFunc st_emitfunc; /* The emitter function. */
} sipQtSignal;
/*
* The API exported by the SIP module, ie. pointers to all the data and
* functions that can be used by generated code.
*/
typedef struct _sipAPIDef {
/*
* The following are part of the public API.
*/
void (*api_bad_catcher_result)(PyObject *method);
void (*api_bad_length_for_slice)(int seqlen,int slicelen);
PyObject *(*api_build_result)(int *isErr,char *fmt,...);
PyObject *(*api_call_method)(int *isErr,PyObject *method,char *fmt,...);
PyObject *(*api_class_name)(PyObject *self);
PyObject *(*api_connect_rx)(PyObject *txObj,const char *sig,PyObject *rxObj,const char *slot);
int (*api_convert_from_sequence_index)(int idx,int len);
void *(*api_convert_to_cpp)(PyObject *sipSelf,sipWrapperType *type,int *iserrp);
PyObject *(*api_disconnect_rx)(PyObject *txObj,const char *sig,PyObject *rxObj,const char *slot);
int (*api_emit_signal)(PyObject *self,const char *sig,PyObject *sigargs);
void (*api_free)(void *mem);
void *(*api_get_sender)(void);
PyObject *(*api_get_wrapper)(void *cppPtr,sipWrapperType *type);
void *(*api_malloc)(size_t nbytes);
sipWrapperType *(*api_map_int_to_class)(int typeInt,const sipIntTypeClassMap *map,int maplen);
sipWrapperType *(*api_map_string_to_class)(const char *typeString,const sipStringTypeClassMap *map,int maplen);
int (*api_parse_result)(int *isErr,PyObject *method,PyObject *res,char *fmt,...);
void (*api_trace)(unsigned mask,const char *fmt,...);
void (*api_transfer)(PyObject *self,int toCpp);
/*
* The following are not part of the public API.
*/
int (*api_export_module)(sipExportedModuleDef *client,unsigned api_major,unsigned api_minor,PyObject *mod_dict);
int (*api_add_enum_instances)(PyObject *dict,sipEnumValueInstanceDef *evi);
int (*api_parse_args)(int *argsParsedp,PyObject *sipArgs,char *fmt,...);
void (*api_common_ctor)(sipMethodCache *cache,int nrmeths);
void (*api_common_dtor)(sipWrapper *sipSelf);
PyObject *(*api_convert_from_void_ptr)(void *val);
void *(*api_convert_to_void_ptr)(PyObject *obj);
void (*api_no_ctor)(int argsParsed,char *classname);
void (*api_no_function)(int argsParsed,char *func);
void (*api_no_method)(int argsParsed,char *classname,char *method);
void (*api_bad_class)(const char *classname);
void (*api_bad_set_type)(const char *classname,const char *var);
void *(*api_get_cpp_ptr)(sipWrapper *w,sipWrapperType *type);
void *(*api_get_complex_cpp_ptr)(sipWrapper *w);
PyObject *(*api_is_py_method)(sip_gilstate_t *gil,sipMethodCache *pymc,sipWrapper *sipSelf,char *cname,char *mname);
PyObject *(*api_map_cpp_to_self)(void *cppPtr,sipWrapperType *type);
PyObject *(*api_map_cpp_to_self_sub_class)(void *cppPtr,sipWrapperType *type);
PyObject *(*api_new_cpp_to_self)(void *cppPtr,sipWrapperType *type,int initflags);
PyObject *(*api_new_cpp_to_self_sub_class)(void *cppPtr,sipWrapperType *type,int initflags);
void (*api_call_hook)(char *hookname);
void (*api_start_thread)(void);
void (*api_end_thread)(void);
void (*api_emit_to_slot)(void *sender,sipSlot *slot,char *fmt,...);
void (*api_raise_unknown_exception)(void);
void (*api_raise_class_exception)(sipWrapperType *type,void *ptr);
void (*api_raise_sub_class_exception)(sipWrapperType *type,void *ptr);
int (*api_add_class_instance)(PyObject *dict,char *name,void *cppPtr,sipWrapperType *wt);
} sipAPIDef;
/*
* Useful macros, not part of the public API.
*/
#define SIP_PY_OWNED 0x01 /* Owned by Python. */
#define SIP_SIMPLE 0x02 /* If the instance is simple. */
#define SIP_INDIRECT 0x04 /* If there is a level of indirection. */
#define SIP_ACCFUNC 0x08 /* If there is an access function. */
#define SIP_XTRA_REF 0x10 /* If C++ has an extra reference. */
#define SIP_NOT_IN_MAP 0x20 /* If Python object not in the map. */
#define sipIsPyOwned(w) ((w) -> flags & SIP_PY_OWNED)
#define sipSetPyOwned(w) ((w) -> flags |= SIP_PY_OWNED)
#define sipResetPyOwned(w) ((w) -> flags &= ~SIP_PY_OWNED)
#define sipIsSimple(w) ((w) -> flags & SIP_SIMPLE)
#define sipIsIndirect(w) ((w) -> flags & SIP_INDIRECT)
#define sipIsAccessFunc(w) ((w) -> flags & SIP_ACCFUNC)
#define sipIsExtraRef(w) ((w) -> flags & SIP_XTRA_REF)
#define sipSetIsExtraRef(w) ((w) -> flags |= SIP_XTRA_REF)
#define sipResetIsExtraRef(w) ((w) -> flags &= ~SIP_XTRA_REF)
#define sipNotInMap(w) ((w) -> flags & SIP_NOT_IN_MAP)
#ifdef __cplusplus
}
#endif
#endif
Loading…
Cancel
Save