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 {
|
typedef struct {
|
||||||
PyObject *AudioopError;
|
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
|
static int
|
||||||
audioop_check_size(PyObject *module, int size)
|
audioop_check_size(PyObject *module, int size)
|
||||||
{
|
{
|
||||||
if (size < 1 || size > 4) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -396,7 +403,8 @@ audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
|
||||||
if (!audioop_check_size(module, size))
|
if (!audioop_check_size(module, size))
|
||||||
return 0;
|
return 0;
|
||||||
if (len % size != 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 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -428,7 +436,8 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
|
||||||
if (!audioop_check_parameters(module, fragment->len, width))
|
if (!audioop_check_parameters(module, fragment->len, width))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (index < 0 || index >= fragment->len/width) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
val = GETRAWSAMPLE(width, fragment->buf, index*width);
|
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;
|
double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
|
||||||
|
|
||||||
if (fragment->len & 1 || reference->len & 1) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
cp1 = (const int16_t *)fragment->buf;
|
cp1 = (const int16_t *)fragment->buf;
|
||||||
|
@ -628,7 +638,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
|
||||||
len2 = reference->len >> 1;
|
len2 = reference->len >> 1;
|
||||||
|
|
||||||
if (len1 < len2) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
sum_ri_2 = _sum2(cp2, cp2, len2);
|
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;
|
double sum_ri_2, sum_aij_ri, result;
|
||||||
|
|
||||||
if (fragment->len & 1 || reference->len & 1) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (fragment->len != reference->len) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
cp1 = (const int16_t *)fragment->buf;
|
cp1 = (const int16_t *)fragment->buf;
|
||||||
|
@ -730,14 +743,16 @@ audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
|
||||||
double result, best_result;
|
double result, best_result;
|
||||||
|
|
||||||
if (fragment->len & 1) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
cp1 = (const int16_t *)fragment->buf;
|
cp1 = (const int16_t *)fragment->buf;
|
||||||
len1 = fragment->len >> 1;
|
len1 = fragment->len >> 1;
|
||||||
|
|
||||||
if (length < 0 || len1 < length) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,7 +984,8 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
|
||||||
if (!audioop_check_parameters(module, len, width))
|
if (!audioop_check_parameters(module, len, width))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (((len / width) & 1) != 0) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,7 +1080,8 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
|
||||||
if (!audioop_check_parameters(module, fragment1->len, width))
|
if (!audioop_check_parameters(module, fragment1->len, width))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (fragment1->len != fragment2->len) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1310,7 +1327,8 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
|
||||||
if (!audioop_check_size(module, width))
|
if (!audioop_check_size(module, width))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (nchannels < 1) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (width > INT_MAX / nchannels) {
|
if (width > INT_MAX / nchannels) {
|
||||||
|
@ -1323,17 +1341,19 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
|
||||||
}
|
}
|
||||||
bytes_per_frame = width * nchannels;
|
bytes_per_frame = width * nchannels;
|
||||||
if (weightA < 1 || weightB < 0) {
|
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");
|
"weightA should be >= 1, weightB should be >= 0");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
assert(fragment->len >= 0);
|
assert(fragment->len >= 0);
|
||||||
if (fragment->len % bytes_per_frame != 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (inrate <= 0 || outrate <= 0) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* divide inrate and outrate by their greatest common divisor */
|
/* 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))
|
&d, &PyTuple_Type, &samps))
|
||||||
goto exit;
|
goto exit;
|
||||||
if (PyTuple_Size(samps) != nchannels) {
|
if (PyTuple_Size(samps) != nchannels) {
|
||||||
PyErr_SetString(_audioopstate(module)->AudioopError,
|
PyErr_SetString(get_audioop_state(module)->AudioopError,
|
||||||
"illegal state argument");
|
"illegal state argument");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -1903,31 +1923,61 @@ static PyMethodDef audioop_methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
audioop_traverse(PyObject *m, visitproc visit, void *arg) {
|
audioop_traverse(PyObject *module, visitproc visit, void *arg)
|
||||||
_audioopstate *state = _audioopstate(m);
|
{
|
||||||
if (state != NULL)
|
audioop_state *state = (audioop_state *)PyModule_GetState(module);
|
||||||
|
if (state) {
|
||||||
Py_VISIT(state->AudioopError);
|
Py_VISIT(state->AudioopError);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
audioop_clear(PyObject *m) {
|
audioop_clear(PyObject *module)
|
||||||
_audioopstate *state = _audioopstate(m);
|
{
|
||||||
if (state != NULL)
|
audioop_state *state = (audioop_state *)PyModule_GetState(module);
|
||||||
|
if (state) {
|
||||||
Py_CLEAR(state->AudioopError);
|
Py_CLEAR(state->AudioopError);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
audioop_free(void *m) {
|
audioop_free(void *module) {
|
||||||
audioop_clear((PyObject *)m);
|
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 = {
|
static struct PyModuleDef audioopmodule = {
|
||||||
PyModuleDef_HEAD_INIT,
|
PyModuleDef_HEAD_INIT,
|
||||||
"audioop",
|
"audioop",
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(_audioopstate),
|
sizeof(audioop_state),
|
||||||
audioop_methods,
|
audioop_methods,
|
||||||
NULL,
|
audioop_slots,
|
||||||
audioop_traverse,
|
audioop_traverse,
|
||||||
audioop_clear,
|
audioop_clear,
|
||||||
audioop_free
|
audioop_free
|
||||||
|
@ -1936,14 +1986,5 @@ static struct PyModuleDef audioopmodule = {
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit_audioop(void)
|
PyInit_audioop(void)
|
||||||
{
|
{
|
||||||
PyObject *m = PyModule_Create(&audioopmodule);
|
return PyModuleDef_Init(&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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue