mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Start work on python wrapper for espeak-ng
This commit is contained in:
parent
18f3a8893a
commit
3dd31eae0b
@ -53,6 +53,15 @@ class pyobject_raii {
|
||||
|
||||
static bool initialize_called = false;
|
||||
|
||||
static PyObject*
|
||||
terminate(PyObject *self, PyObject *args) {
|
||||
if (initialize_called) {
|
||||
espeak_Terminate();
|
||||
initialize_called = false;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
info(PyObject *self, PyObject *args) {
|
||||
const char *path_data;
|
||||
@ -208,7 +217,7 @@ int_as_four_bytes(int32_t value, unsigned char *output) {
|
||||
|
||||
static PyObject*
|
||||
create_recording_wav(PyObject *self, PyObject *args) {
|
||||
int buflength = 1000;
|
||||
int buflength = 0;
|
||||
unsigned int flags = 0;
|
||||
const char *text;
|
||||
Py_ssize_t text_len;
|
||||
@ -225,7 +234,7 @@ create_recording_wav(PyObject *self, PyObject *args) {
|
||||
};
|
||||
int_as_four_bytes(rate, wave_hdr + 24);
|
||||
int_as_four_bytes(rate * 2, wave_hdr + 28);
|
||||
PyObject *ret = PyObject_CallFunction(cbdata.data_callback, "s#", wave_hdr, sizeof(wave_hdr));
|
||||
PyObject *ret = PyObject_CallFunction(cbdata.data_callback, "y#", wave_hdr, sizeof(wave_hdr));
|
||||
if (!ret) return NULL;
|
||||
Py_DECREF(ret);
|
||||
|
||||
@ -241,11 +250,11 @@ create_recording_wav(PyObject *self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// Boilerplate {{{
|
||||
#define M(name, args, doc) { #name, (PyCFunction)name, args, ""}
|
||||
static PyMethodDef methods[] = {
|
||||
M(info, METH_NOARGS, "version and path"),
|
||||
M(terminate, METH_NOARGS, "terminate the library"),
|
||||
M(cancel, METH_NOARGS, "cancel all ongoing speech activity"),
|
||||
M(synchronize, METH_NOARGS, "synchronize all ongoing speech activity"),
|
||||
M(is_playing, METH_NOARGS, "True iff speech is happening"),
|
||||
@ -282,12 +291,7 @@ static PyModuleDef_Slot slots[] = { {Py_mod_exec, (void*)exec_module}, {0, NULL}
|
||||
static struct PyModuleDef module_def = {PyModuleDef_HEAD_INIT};
|
||||
|
||||
static void
|
||||
finalize(void*) {
|
||||
if (initialize_called) {
|
||||
espeak_Terminate();
|
||||
initialize_called = false;
|
||||
}
|
||||
}
|
||||
finalize(void*) { terminate(NULL, NULL); }
|
||||
|
||||
CALIBRE_MODINIT_FUNC PyInit_espeak(void) {
|
||||
module_def.m_name = "espeak";
|
||||
|
39
src/calibre/utils/tts/espeak.py
Normal file
39
src/calibre/utils/tts/espeak.py
Normal file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
def info():
|
||||
from calibre_extensions.espeak import info
|
||||
return info()
|
||||
|
||||
|
||||
def create_recording_wav(text, seekable_file_object_or_path, buflength=0, ssml=False, phonemes=False, endpause=False):
|
||||
import struct
|
||||
|
||||
from calibre_extensions.espeak import (
|
||||
ENDPAUSE, PHONEMES, SSML, create_recording_wav as doit
|
||||
)
|
||||
flags = 0
|
||||
if ssml:
|
||||
flags |= SSML
|
||||
if phonemes:
|
||||
flags |= PHONEMES
|
||||
if endpause:
|
||||
flags |= ENDPAUSE
|
||||
if isinstance(seekable_file_object_or_path, str):
|
||||
seekable_file_object = open(seekable_file_object_or_path, 'w+b')
|
||||
else:
|
||||
seekable_file_object = seekable_file_object_or_path
|
||||
|
||||
w = seekable_file_object.write
|
||||
|
||||
def write(data):
|
||||
w(data)
|
||||
return False
|
||||
|
||||
doit(text, write, buflength, flags)
|
||||
sz = seekable_file_object.tell()
|
||||
seekable_file_object.seek(4)
|
||||
seekable_file_object.write(struct.pack('<I', sz - 8))
|
||||
seekable_file_object.seek(40)
|
||||
seekable_file_object.write(struct.pack('<I', sz - 44))
|
Loading…
x
Reference in New Issue
Block a user