Commit 110a938b authored by Manuel Günther's avatar Manuel Günther
Browse files

Started porting documentation to bob::extension Documentation (see #2)

parent 211cb9ff
......@@ -16,7 +16,7 @@
#include <map>
#include "file.h"
#include "cpp/writer.h"
#include "main.h"
static PyMethodDef module_methods[] = {
{0} /* Sentinel */
......@@ -35,33 +35,28 @@ static PyModuleDef module_definition = {
};
#endif
extern PyTypeObject PyBobIoAudioReader_Type;
extern PyTypeObject PyBobIoAudioWriter_Type;
static PyObject* create_module (void) {
PyBobIoAudioReader_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyBobIoAudioReader_Type) < 0) return 0;
PyBobIoAudioWriter_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyBobIoAudioWriter_Type) < 0) return 0;
# if PY_VERSION_HEX >= 0x03000000
PyObject* m = PyModule_Create(&module_definition);
auto m_ = make_xsafe(m);
PyObject* module = PyModule_Create(&module_definition);
auto module_ = make_xsafe(module);
const char* ret = "O";
# else
PyObject* m = Py_InitModule3(BOB_EXT_MODULE_NAME, module_methods, module_docstr);
PyObject* module = Py_InitModule3(BOB_EXT_MODULE_NAME, module_methods, module_docstr);
const char* ret = "N";
# endif
if (!m) return 0;
if (!module) return 0;
/* register the types to python */
Py_INCREF(&PyBobIoAudioReader_Type);
if (PyModule_AddObject(m, "reader", (PyObject *)&PyBobIoAudioReader_Type) < 0) return 0;
if (!init_BobIoAudioReader(module)) return 0;
Py_INCREF(&PyBobIoAudioWriter_Type);
if (PyModule_AddObject(m, "writer", (PyObject *)&PyBobIoAudioWriter_Type) < 0) return 0;
if (PyModule_AddObject(module, "writer", (PyObject *)&PyBobIoAudioWriter_Type) < 0) return 0;
/* imports dependencies */
if (import_bob_blitz() < 0) return 0;
......@@ -77,7 +72,7 @@ static PyObject* create_module (void) {
}
}
return Py_BuildValue(ret, m);
return Py_BuildValue(ret, module);
}
PyMODINIT_FUNC BOB_EXT_ENTRY_NAME (void) {
......
/**
* @author Manuel Guenther <siebenkopf@googlemail.com>
* @date Wed Mar 2 18:35:11 MST 2016
*
* @brief Header file for bindings to bob::io::audio
*/
#ifndef BOB_IP_BASE_MAIN_H
#define BOB_IP_BASE_MAIN_H
#include <bob.blitz/cppapi.h>
#include <bob.blitz/cleanup.h>
#include <bob.core/api.h>
#include <bob.io.base/api.h>
#include <bob.extension/documentation.h>
#include "cpp/utils.h"
#include "cpp/reader.h"
#include "cpp/writer.h"
// Reader
typedef struct {
PyObject_HEAD
boost::shared_ptr<bob::io::audio::Reader> v;
} PyBobIoAudioReaderObject;
extern PyTypeObject PyBobIoAudioReader_Type;
bool init_BobIoAudioReader(PyObject* module);
int PyBobIoAudioReader_Check(PyObject* o);
#endif // BOB_IP_BASE_MAIN_H
......@@ -14,239 +14,209 @@
#include <bob.io.base/api.h>
#include <stdexcept>
#include "cpp/utils.h"
#include "cpp/reader.h"
#define AUDIOREADER_NAME "reader"
PyDoc_STRVAR(s_audioreader_str, BOB_EXT_MODULE_PREFIX "." AUDIOREADER_NAME);
PyDoc_STRVAR(s_audioreader_doc,
"reader(filename) -> new reader\n\
\n\
Use this object to read samples from audio files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to read data from\n\
\n\
Audio reader objects can read data from audio files. The current\n\
implementation uses `SoX <http://sox.sourceforge.net/>`_ which is\n\
a stable freely available audio encoding and decoding library,\n\
designed specifically for these tasks. You can read an entire\n\
audio in memory by using the :py:meth:`bob.io.audio.reader.load`\n\
method.\n\
\n\
");
typedef struct {
PyObject_HEAD
boost::shared_ptr<bob::io::audio::Reader> v;
} PyBobIoAudioReaderObject;
extern PyTypeObject PyBobIoAudioReader_Type;
/* How to create a new PyBobIoAudioReaderObject */
static PyObject* PyBobIoAudioReader_New(PyTypeObject* type, PyObject*, PyObject*) {
/* Allocates the python object itself */
PyBobIoAudioReaderObject* self = (PyBobIoAudioReaderObject*)type->tp_alloc(type, 0);
self->v.reset();
return reinterpret_cast<PyObject*>(self);
}
static void PyBobIoAudioReader_Delete (PyBobIoAudioReaderObject* o) {
o->v.reset();
Py_TYPE(o)->tp_free((PyObject*)o);
}
#include "main.h"
static auto s_reader = bob::extension::ClassDoc(
"reader",
"Use this object to read samples from audio files"
)
.add_constructor(
bob::extension::FunctionDoc(
"reader",
"Opens an audio file for reading",
"Audio reader objects can read data from audio files. "
"The current implementation uses `SoX <http://sox.sourceforge.net/>`_ , which is a stable freely available audio encoding and decoding library, designed specifically for these tasks. "
"You can read an entire audio in memory by using the :py:meth:`load` method.",
true
)
.add_prototype("filename", "")
.add_parameter("filename", "str", "The file path to the file you want to read data from")
);
/* The __init__(self) method */
static int PyBobIoAudioReader_Init(PyBobIoAudioReaderObject* self,
PyObject *args, PyObject* kwds) {
BOB_TRY
/* Parses input arguments in a single shot */
static const char* const_kwlist[] = {"filename", 0};
static char** kwlist = const_cast<char**>(const_kwlist);
char** kwlist = s_reader.kwlist();
PyObject* filename = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist,
&PyBobIo_FilenameConverter, &filename)) return -1;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, &PyBobIo_FilenameConverter, &filename)) return -1;
auto filename_ = make_safe(filename);
#if PY_VERSION_HEX >= 0x03000000
const char* c_filename = PyBytes_AS_STRING(filename);
#else
const char* c_filename = PyString_AS_STRING(filename);
#endif
try {
self->v.reset(new bob::io::audio::Reader(c_filename));
}
catch (std::exception& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
return -1;
}
catch (...) {
PyErr_Format(PyExc_RuntimeError, "cannot open audio file `%s' for reading: unknown exception caught", c_filename);
return -1;
}
self->v.reset(new bob::io::audio::Reader(c_filename));
return 0; ///< SUCCESS
BOB_CATCH_MEMBER("constructor", -1)
}
static void PyBobIoAudioReader_Delete (PyBobIoAudioReaderObject* o) {
o->v.reset();
Py_TYPE(o)->tp_free((PyObject*)o);
}
static auto s_filename = bob::extension::VariableDoc(
"filename",
"str",
"The full path to the file that will be decoded by this object"
);
PyObject* PyBobIoAudioReader_Filename(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("s", self->v->filename());
}
PyDoc_STRVAR(s_filename_str, "filename");
PyDoc_STRVAR(s_filename_doc,
"[str] The full path to the file that will be decoded by this object");
static auto s_rate = bob::extension::VariableDoc(
"rate",
"float",
"The sampling rate of the audio stream"
);
PyObject* PyBobIoAudioReader_Rate(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("d", self->v->rate());
}
PyDoc_STRVAR(s_rate_str, "rate");
PyDoc_STRVAR(s_rate_doc,
"[float] The sampling rate of the audio stream");
static auto s_number_of_channels = bob::extension::VariableDoc(
"number_of_channels",
"int",
"The number of channels on the audio stream"
);
PyObject* PyBobIoAudioReader_NumberOfChannels(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("n", self->v->numberOfChannels());
}
PyDoc_STRVAR(s_number_of_channels_str, "number_of_channels");
PyDoc_STRVAR(s_number_of_channels_doc,
"[int] The number of channels on the audio stream");
static auto s_bits_per_sample = bob::extension::VariableDoc(
"bits_per_sample",
"int",
"The number of bits per sample in this audio stream"
);
PyObject* PyBobIoAudioReader_BitsPerSample(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("n", self->v->bitsPerSample());
}
PyDoc_STRVAR(s_bits_per_sample_str, "bits_per_sample");
PyDoc_STRVAR(s_bits_per_sample_doc,
"[int] The number of bits per sample in this audio stream");
static auto s_number_of_samples = bob::extension::VariableDoc(
"number_of_samples",
"int",
"The number of samples in this audio stream"
);
PyObject* PyBobIoAudioReader_NumberOfSamples(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("n", self->v->numberOfSamples());
}
PyDoc_STRVAR(s_number_of_samples_str, "number_of_samples");
PyDoc_STRVAR(s_number_of_samples_doc,
"[int] The number of samples in this audio stream");
static auto s_duration = bob::extension::VariableDoc(
"duration",
"float",
"Total duration of this audio file in seconds"
);
PyObject* PyBobIoAudioReader_Duration(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("d", self->v->duration());
}
PyDoc_STRVAR(s_duration_str, "duration");
PyDoc_STRVAR(s_duration_doc,
"[float] Total duration of this audio file in seconds");
static auto s_compression_factor = bob::extension::VariableDoc(
"compression_factor",
"float",
"Compression factor on the audio stream"
);
PyObject* PyBobIoAudioReader_CompressionFactor(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("d", self->v->compressionFactor());
}
PyDoc_STRVAR(s_compression_factor_str, "compressionfactor");
PyDoc_STRVAR(s_compression_factor_doc,
"[float] Compression factor on the audio stream");
static auto s_encoding = bob::extension::VariableDoc(
"encoding",
"str",
"Name of the encoding in which this audio file was recorded in"
);
PyObject* PyBobIoAudioReader_EncodingName(PyBobIoAudioReaderObject* self) {
return Py_BuildValue("s", bob::io::audio::encoding2string(self->v->encoding()));
}
PyDoc_STRVAR(s_encoding_name_str, "encoding");
PyDoc_STRVAR(s_encoding_name_doc,
"[str] Name of the encoding in which this audio file was recorded in");
static auto s_type = bob::extension::VariableDoc(
"type",
"tuple",
"Typing information to load all of the file at once"
);
PyObject* PyBobIoAudioReader_TypeInfo(PyBobIoAudioReaderObject* self) {
return PyBobIo_TypeInfoAsTuple(self->v->type());
}
PyDoc_STRVAR(s_type_str, "type");
PyDoc_STRVAR(s_type_doc,
"[tuple] Typing information to load all of the file at once");
static PyGetSetDef PyBobIoAudioReader_getseters[] = {
{
s_filename_str,
s_filename.name(),
(getter)PyBobIoAudioReader_Filename,
0,
s_filename_doc,
s_filename.doc(),
0,
},
{
s_rate_str,
s_rate.name(),
(getter)PyBobIoAudioReader_Rate,
0,
s_rate_doc,
s_rate.doc(),
0,
},
{
s_number_of_channels_str,
s_number_of_channels.name(),
(getter)PyBobIoAudioReader_NumberOfChannels,
0,
s_number_of_channels_doc,
s_number_of_channels.doc(),
0,
},
{
s_bits_per_sample_str,
s_bits_per_sample.name(),
(getter)PyBobIoAudioReader_BitsPerSample,
0,
s_bits_per_sample_doc,
s_bits_per_sample.doc(),
0,
},
{
s_number_of_samples_str,
s_number_of_samples.name(),
(getter)PyBobIoAudioReader_NumberOfSamples,
0,
s_number_of_samples_doc,
s_number_of_samples.doc(),
0,
},
{
s_duration_str,
s_duration.name(),
(getter)PyBobIoAudioReader_Duration,
0,
s_duration_doc,
s_duration.doc(),
0,
},
{
s_encoding_name_str,
s_encoding.name(),
(getter)PyBobIoAudioReader_EncodingName,
0,
s_encoding_name_doc,
s_encoding.doc(),
0,
},
{
s_compression_factor_str,
s_compression_factor.name(),
(getter)PyBobIoAudioReader_CompressionFactor,
0,
s_compression_factor_doc,
s_compression_factor.doc(),
0,
},
{
s_type_str,
s_type.name(),
(getter)PyBobIoAudioReader_TypeInfo,
0,
s_type_doc,
s_type.doc(),
0,
},
{0} /* Sentinel */
};
static PyObject* PyBobIoAudioReader_Repr(PyBobIoAudioReaderObject* self) {
return
# if PY_VERSION_HEX >= 0x03000000
PyUnicode_FromFormat
# else
PyString_FromFormat
# endif
("%s(filename='%s')", Py_TYPE(self)->tp_name, self->v->filename());
return PyString_FromFormat("%s(filename='%s')", Py_TYPE(self)->tp_name, self->v->filename());
}
/**
......@@ -260,11 +230,18 @@ static void Check_Interrupt() {
}
}
static PyObject* PyBobIoAudioReader_Load(PyBobIoAudioReaderObject* self, PyObject *args, PyObject* kwds) {
/* Parses input arguments in a single shot */
static const char* const_kwlist[] = {0};
static char** kwlist = const_cast<char**>(const_kwlist);
static auto s_load = bob::extension::FunctionDoc(
"load",
"Loads all of the audio stream in a :py:class:`numpy.ndarray`",
"The data is organized in this way: ``(channels, data)``. "
)
.add_prototype("","data")
.add_return("data", ":py:class:`numpy.ndarray`", "The data read from this file")
;
static PyObject* PyBobIoAudioReader_Load(PyBobIoAudioReaderObject* self, PyObject *args, PyObject* kwds) {
BOB_TRY
char** kwlist = s_load.kwlist();
PyObject* raise = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist, &raise)) return 0;
......@@ -283,18 +260,8 @@ static PyObject* PyBobIoAudioReader_Load(PyBobIoAudioReaderObject* self, PyObjec
Py_ssize_t samples_read = 0;
try {
bobskin skin((PyArrayObject*)retval, info.dtype);
samples_read = self->v->load(skin, &Check_Interrupt);
}
catch (std::exception& e) {
if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
return 0;
}
catch (...) {
if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading audio from file `%s'", self->v->filename());
return 0;
}
bobskin skin((PyArrayObject*)retval, info.dtype);
samples_read = self->v->load(skin, &Check_Interrupt);
if (samples_read != shape[1]) {
//resize
......@@ -305,27 +272,16 @@ static PyObject* PyBobIoAudioReader_Load(PyBobIoAudioReaderObject* self, PyObjec
PyArray_Resize((PyArrayObject*)retval, &newshape, 1, NPY_ANYORDER);
}
Py_INCREF(retval);
return retval;
return Py_BuildValue("O", retval);
BOB_CATCH_MEMBER("load", 0)
}
PyDoc_STRVAR(s_load_str, "load");
PyDoc_STRVAR(s_load_doc,
"x.load() -> numpy.ndarray\n\
\n\
Loads all of the audio stream in a numpy ndarray organized\n\
in this way: (channels, data). I'll dynamically allocate the\n\
output array and return it to you.\n\
\n\
");
static PyMethodDef PyBobIoAudioReader_Methods[] = {
{
s_load_str,
s_load.name(),
(PyCFunction)PyBobIoAudioReader_Load,
METH_VARARGS|METH_KEYWORDS,
s_load_doc,
s_load.doc(),
},
{0} /* Sentinel */
};
......@@ -341,42 +297,34 @@ static PyMappingMethods PyBobIoAudioReader_Mapping = {
};
PyTypeObject PyBobIoAudioReader_Type = {
PyVarObject_HEAD_INIT(0, 0)
s_audioreader_str, /*tp_name*/
sizeof(PyBobIoAudioReaderObject), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)PyBobIoAudioReader_Delete, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)PyBobIoAudioReader_Repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
&PyBobIoAudioReader_Mapping, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
(reprfunc)PyBobIoAudioReader_Repr, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
s_audioreader_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
PyBobIoAudioReader_Methods, /* tp_methods */
0, /* tp_members */
PyBobIoAudioReader_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)PyBobIoAudioReader_Init, /* tp_init */
0, /* tp_alloc */
PyBobIoAudioReader_New, /* tp_new */
PyVarObject_HEAD_INIT(0, 0)
0
};
bool init_BobIoAudioReader(PyObject* module){
// initialize the File
PyBobIoAudioReader_Type.tp_name = s_reader.name();
PyBobIoAudioReader_Type.tp_basicsize = sizeof(PyBobIoAudioReaderObject);
PyBobIoAudioReader_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
PyBobIoAudioReader_Type.tp_doc = s_reader.doc();
// set the functions
PyBobIoAudioReader_Type.tp_new = PyType_GenericNew;
PyBobIoAudioReader_Type.tp_init = reinterpret_cast<initproc>(PyBobIoAudioReader_Init);
PyBobIoAudioReader_Type.tp_dealloc = reinterpret_cast<destructor>(PyBobIoAudioReader_Delete);
PyBobIoAudioReader_Type.tp_methods = PyBobIoAudioReader_Methods;
PyBobIoAudioReader_Type.tp_getset = PyBobIoAudioReader_getseters;
PyBobIoAudioReader_Type.tp_str = reinterpret_cast<reprfunc>(PyBobIoAudioReader_Repr);
PyBobIoAudioReader_Type.tp_repr = reinterpret_cast<reprfunc>(PyBobIoAudioReader_Repr);
PyBobIoAudioReader_Type.tp_as_mapping = &PyBobIoAudioReader_Mapping;
// check that everything is fine
if (PyType_Ready(&PyBobIoAudioReader_Type) < 0) return false;
// add the type to the module
Py_INCREF(&PyBobIoAudioReader_Type);
return PyModule_AddObject(module, "reader", (PyObject*)&PyBobIoAudioReader_Type) >= 0;
}
2.0.1a0
\ No newline at end of file
2.0.1b1
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment