mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Code to list espeak voices
This commit is contained in:
parent
99a3d9c756
commit
2d9dd81f46
@ -12,11 +12,74 @@
|
||||
#include <Python.h>
|
||||
#include <espeak-ng/speak_lib.h>
|
||||
|
||||
class pyobject_raii {
|
||||
private:
|
||||
PyObject *handle;
|
||||
pyobject_raii( const pyobject_raii & ) ;
|
||||
pyobject_raii & operator=( const pyobject_raii & ) ;
|
||||
|
||||
public:
|
||||
pyobject_raii() : handle(NULL) {}
|
||||
pyobject_raii(PyObject* h) : handle(h) {}
|
||||
|
||||
~pyobject_raii() { Py_CLEAR(handle); }
|
||||
|
||||
PyObject *ptr() { return handle; }
|
||||
void set_ptr(PyObject *val) { handle = val; }
|
||||
PyObject **address() { return &handle; }
|
||||
explicit operator bool() const { return handle != NULL; }
|
||||
PyObject *detach() { PyObject *ans = handle; handle = NULL; return ans; }
|
||||
};
|
||||
|
||||
static bool initialize_called = false;
|
||||
|
||||
static PyObject*
|
||||
info(PyObject *self, PyObject *args) {
|
||||
const char *path_data;
|
||||
const char *version = espeak_Info(&path_data);
|
||||
return Py_BuildValue("ss", version, path_data);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
list_voices(PyObject *self, PyObject *args, PyObject *kw) {
|
||||
espeak_VOICE q = {0};
|
||||
static const char* kwds[] = {"name", "language", "identifier", "gender", "age", NULL};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "|$sssBB", (char**)kwds, &q.name, &q.languages, &q.identifier, &q.gender, &q.age)) return NULL;
|
||||
const espeak_VOICE **voices;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
voices = espeak_ListVoices(&q);
|
||||
Py_END_ALLOW_THREADS;
|
||||
pyobject_raii ans(PyList_New(0));
|
||||
if (!ans) return NULL;
|
||||
while (*voices) {
|
||||
const espeak_VOICE *x = *voices;
|
||||
pyobject_raii languages(PyList_New(0));
|
||||
if (!languages) return NULL;
|
||||
const char *pos = x->languages;
|
||||
while (pos && *pos) {
|
||||
const char priority = *pos;
|
||||
size_t sz = strlen(++pos);
|
||||
if (!sz) break;
|
||||
pyobject_raii lang(Py_BuildValue("bs", priority, pos));
|
||||
if (!lang) return NULL;
|
||||
if (PyList_Append(languages.ptr(), lang.ptr()) != 0) return NULL;
|
||||
pos += sz + 1;
|
||||
}
|
||||
pyobject_raii entry(Py_BuildValue("{ss ss sO sB sB}",
|
||||
"name", x->name, "identifier", x->identifier, "languages", languages.ptr(),
|
||||
"gender", x->gender, "age", x->age));
|
||||
if (!entry) return NULL;
|
||||
if (PyList_Append(ans.ptr(), entry.ptr()) != 0) return NULL;
|
||||
voices++;
|
||||
}
|
||||
return ans.detach();
|
||||
}
|
||||
|
||||
// Boilerplate {{{
|
||||
#define M(name, args) { #name, (PyCFunction)name, args, ""}
|
||||
#define M(name, args, doc) { #name, (PyCFunction)name, args, ""}
|
||||
static PyMethodDef methods[] = {
|
||||
M(info, METH_VARARGS, "version and path"),
|
||||
M(list_voices, METH_VARARGS | METH_KEYWORDS, "list available voices"),
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
#undef M
|
||||
|
Loading…
x
Reference in New Issue
Block a user