summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorHai Shi <shihai1992@gmail.com>2020-03-11 16:49:11 (GMT)
committerGitHub <noreply@github.com>2020-03-11 16:49:11 (GMT)
commit41fbf865a35d4fb64f047f98dc24690cb0c170fd (patch)
treeaa39c46541a4f0793e2edadfcd15fbffc7bca856 /Modules
parenta158168a787e82c4b7b18f6833153188e93627a5 (diff)
downloadcpython-41fbf865a35d4fb64f047f98dc24690cb0c170fd.zip
cpython-41fbf865a35d4fb64f047f98dc24690cb0c170fd.tar.gz
cpython-41fbf865a35d4fb64f047f98dc24690cb0c170fd.tar.bz2
bpo-1635741: Port audioop extension module to multiphase initialization (PEP 489) (GH-18608)
Co-authored-by: Victor Stinner <vstinner@python.org>
Diffstat (limited to 'Modules')
-rw-r--r--Modules/audioop.c117
1 files changed, 79 insertions, 38 deletions
diff --git a/Modules/audioop.c b/Modules/audioop.c
index 7726c88..467bd63 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -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);
}