mirror of https://github.com/python/cpython
bpo-1635741: Port audioop extension module to multiphase initialization (PEP 489) (GH-18608)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
a158168a78
commit
41fbf865a3
|
@ -0,0 +1 @@
|
|||
Port audioop extension module to multiphase initialization (:pep:`489`).
|
|
@ -375,15 +375,22 @@ static PyModuleDef audioopmodule;
|
|||
|
||||
typedef struct {
|
||||
PyObject *AudioopError;
|
||||
} _audioopstate;
|
||||
} audioop_state;
|
||||
|
||||
#define _audioopstate(o) ((_audioopstate *)PyModule_GetState(o))
|
||||
static inline audioop_state *
|
||||
get_audioop_state(PyObject *module)
|
||||
{
|
||||
void *state = PyModule_GetState(module);
|
||||
assert(state != NULL);
|
||||
return (audioop_state *)state;
|
||||
}
|
||||
|
||||
static int
|
||||
audioop_check_size(PyObject *module, int size)
|
||||
{
|
||||
if (size < 1 || size > 4) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Size should be 1, 2, 3 or 4");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Size should be 1, 2, 3 or 4");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
@ -396,7 +403,8 @@ audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
|
|||
if (!audioop_check_size(module, size))
|
||||
return 0;
|
||||
if (len % size != 0) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"not a whole number of frames");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -428,7 +436,8 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
|
|||
if (!audioop_check_parameters(module, fragment->len, width))
|
||||
return NULL;
|
||||
if (index < 0 || index >= fragment->len/width) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Index out of range");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Index out of range");
|
||||
return NULL;
|
||||
}
|
||||
val = GETRAWSAMPLE(width, fragment->buf, index*width);
|
||||
|
@ -619,7 +628,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
|
|||
double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
|
||||
|
||||
if (fragment->len & 1 || reference->len & 1) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Strings should be even-sized");
|
||||
return NULL;
|
||||
}
|
||||
cp1 = (const int16_t *)fragment->buf;
|
||||
|
@ -628,7 +638,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
|
|||
len2 = reference->len >> 1;
|
||||
|
||||
if (len1 < len2) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "First sample should be longer");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"First sample should be longer");
|
||||
return NULL;
|
||||
}
|
||||
sum_ri_2 = _sum2(cp2, cp2, len2);
|
||||
|
@ -686,11 +697,13 @@ audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
|
|||
double sum_ri_2, sum_aij_ri, result;
|
||||
|
||||
if (fragment->len & 1 || reference->len & 1) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Strings should be even-sized");
|
||||
return NULL;
|
||||
}
|
||||
if (fragment->len != reference->len) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Samples should be same size");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Samples should be same size");
|
||||
return NULL;
|
||||
}
|
||||
cp1 = (const int16_t *)fragment->buf;
|
||||
|
@ -730,14 +743,16 @@ audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
|
|||
double result, best_result;
|
||||
|
||||
if (fragment->len & 1) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Strings should be even-sized");
|
||||
return NULL;
|
||||
}
|
||||
cp1 = (const int16_t *)fragment->buf;
|
||||
len1 = fragment->len >> 1;
|
||||
|
||||
if (length < 0 || len1 < length) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Input sample should be longer");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Input sample should be longer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -969,7 +984,8 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
|
|||
if (!audioop_check_parameters(module, len, width))
|
||||
return NULL;
|
||||
if (((len / width) & 1) != 0) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"not a whole number of frames");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1064,7 +1080,8 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
|
|||
if (!audioop_check_parameters(module, fragment1->len, width))
|
||||
return NULL;
|
||||
if (fragment1->len != fragment2->len) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "Lengths should be the same");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"Lengths should be the same");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1310,7 +1327,8 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
|
|||
if (!audioop_check_size(module, width))
|
||||
return NULL;
|
||||
if (nchannels < 1) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "# of channels should be >= 1");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"# of channels should be >= 1");
|
||||
return NULL;
|
||||
}
|
||||
if (width > INT_MAX / nchannels) {
|
||||
|
@ -1323,17 +1341,19 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
|
|||
}
|
||||
bytes_per_frame = width * nchannels;
|
||||
if (weightA < 1 || weightB < 0) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError,
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"weightA should be >= 1, weightB should be >= 0");
|
||||
return NULL;
|
||||
}
|
||||
assert(fragment->len >= 0);
|
||||
if (fragment->len % bytes_per_frame != 0) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"not a whole number of frames");
|
||||
return NULL;
|
||||
}
|
||||
if (inrate <= 0 || outrate <= 0) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError, "sampling rate not > 0");
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"sampling rate not > 0");
|
||||
return NULL;
|
||||
}
|
||||
/* divide inrate and outrate by their greatest common divisor */
|
||||
|
@ -1374,7 +1394,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
|
|||
&d, &PyTuple_Type, &samps))
|
||||
goto exit;
|
||||
if (PyTuple_Size(samps) != nchannels) {
|
||||
PyErr_SetString(_audioopstate(module)->AudioopError,
|
||||
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||
"illegal state argument");
|
||||
goto exit;
|
||||
}
|
||||
|
@ -1903,31 +1923,61 @@ static PyMethodDef audioop_methods[] = {
|
|||
};
|
||||
|
||||
static int
|
||||
audioop_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
_audioopstate *state = _audioopstate(m);
|
||||
if (state != NULL)
|
||||
audioop_traverse(PyObject *module, visitproc visit, void *arg)
|
||||
{
|
||||
audioop_state *state = (audioop_state *)PyModule_GetState(module);
|
||||
if (state) {
|
||||
Py_VISIT(state->AudioopError);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
audioop_clear(PyObject *m) {
|
||||
_audioopstate *state = _audioopstate(m);
|
||||
if (state != NULL)
|
||||
audioop_clear(PyObject *module)
|
||||
{
|
||||
audioop_state *state = (audioop_state *)PyModule_GetState(module);
|
||||
if (state) {
|
||||
Py_CLEAR(state->AudioopError);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
audioop_free(void *m) {
|
||||
audioop_clear((PyObject *)m);
|
||||
audioop_free(void *module) {
|
||||
audioop_clear((PyObject *)module);
|
||||
}
|
||||
|
||||
static int
|
||||
audioop_exec(PyObject* module)
|
||||
{
|
||||
audioop_state *state = get_audioop_state(module);
|
||||
|
||||
state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
|
||||
if (state->AudioopError == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_INCREF(state->AudioopError);
|
||||
if (PyModule_AddObject(module, "error", state->AudioopError) < 0) {
|
||||
Py_DECREF(state->AudioopError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyModuleDef_Slot audioop_slots[] = {
|
||||
{Py_mod_exec, audioop_exec},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef audioopmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"audioop",
|
||||
NULL,
|
||||
sizeof(_audioopstate),
|
||||
sizeof(audioop_state),
|
||||
audioop_methods,
|
||||
NULL,
|
||||
audioop_slots,
|
||||
audioop_traverse,
|
||||
audioop_clear,
|
||||
audioop_free
|
||||
|
@ -1936,14 +1986,5 @@ static struct PyModuleDef audioopmodule = {
|
|||
PyMODINIT_FUNC
|
||||
PyInit_audioop(void)
|
||||
{
|
||||
PyObject *m = PyModule_Create(&audioopmodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
PyObject *AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
|
||||
if (AudioopError == NULL)
|
||||
return NULL;
|
||||
Py_INCREF(AudioopError);
|
||||
PyModule_AddObject(m, "error", AudioopError);
|
||||
_audioopstate(m)->AudioopError = AudioopError;
|
||||
return m;
|
||||
return PyModuleDef_Init(&audioopmodule);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue