Commit f548a3e4 authored by Tyler Kieft's avatar Tyler Kieft Committed by Miss Skeleton (bot)

bpo-38303: Make audioop extension module PEP-384 compatible (GH-16497)



https://bugs.python.org/issue38303



Automerge-Triggered-By: @encukou
parent dfe726b1
...@@ -847,6 +847,7 @@ Dhiru Kholia ...@@ -847,6 +847,7 @@ Dhiru Kholia
Artem Khramov Artem Khramov
Akshit Khurana Akshit Khurana
Sanyam Khurana Sanyam Khurana
Tyler Kieft
Mads Kiilerich Mads Kiilerich
Jason Killen Jason Killen
Jan Kim Jan Kim
......
Update audioop extension module to use the stable ABI (PEP-384). Patch by Tyler Kieft.
...@@ -371,14 +371,19 @@ static const int stepsizeTable[89] = { ...@@ -371,14 +371,19 @@ static const int stepsizeTable[89] = {
SETINT32((cp), (i), (val)); \ SETINT32((cp), (i), (val)); \
} while(0) } while(0)
static PyModuleDef audioopmodule;
static PyObject *AudioopError; typedef struct {
PyObject *AudioopError;
} _audioopstate;
#define _audioopstate(o) ((_audioopstate *)PyModule_GetState(o))
static int static int
audioop_check_size(int size) audioop_check_size(PyObject *module, int size)
{ {
if (size < 1 || size > 4) { if (size < 1 || size > 4) {
PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4"); PyErr_SetString(_audioopstate(module)->AudioopError, "Size should be 1, 2, 3 or 4");
return 0; return 0;
} }
else else
...@@ -386,12 +391,12 @@ audioop_check_size(int size) ...@@ -386,12 +391,12 @@ audioop_check_size(int size)
} }
static int static int
audioop_check_parameters(Py_ssize_t len, int size) audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
{ {
if (!audioop_check_size(size)) if (!audioop_check_size(module, size))
return 0; return 0;
if (len % size != 0) { if (len % size != 0) {
PyErr_SetString(AudioopError, "not a whole number of frames"); PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
return 0; return 0;
} }
return 1; return 1;
...@@ -420,10 +425,10 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -420,10 +425,10 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
{ {
int val; int val;
if (!audioop_check_parameters(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(AudioopError, "Index out of range"); PyErr_SetString(_audioopstate(module)->AudioopError, "Index out of range");
return NULL; return NULL;
} }
val = GETRAWSAMPLE(width, fragment->buf, index*width); val = GETRAWSAMPLE(width, fragment->buf, index*width);
...@@ -447,7 +452,7 @@ audioop_max_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -447,7 +452,7 @@ audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
Py_ssize_t i; Py_ssize_t i;
unsigned int absval, max = 0; unsigned int absval, max = 0;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
for (i = 0; i < fragment->len; i += width) { for (i = 0; i < fragment->len; i += width) {
int val = GETRAWSAMPLE(width, fragment->buf, i); int val = GETRAWSAMPLE(width, fragment->buf, i);
...@@ -479,7 +484,7 @@ audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -479,7 +484,7 @@ audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width)
a warning */ a warning */
int min = 0x7fffffff, max = -0x7FFFFFFF-1; int min = 0x7fffffff, max = -0x7FFFFFFF-1;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
for (i = 0; i < fragment->len; i += width) { for (i = 0; i < fragment->len; i += width) {
int val = GETRAWSAMPLE(width, fragment->buf, i); int val = GETRAWSAMPLE(width, fragment->buf, i);
...@@ -507,7 +512,7 @@ audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -507,7 +512,7 @@ audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width)
int avg; int avg;
double sum = 0.0; double sum = 0.0;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
for (i = 0; i < fragment->len; i += width) for (i = 0; i < fragment->len; i += width)
sum += GETRAWSAMPLE(width, fragment->buf, i); sum += GETRAWSAMPLE(width, fragment->buf, i);
...@@ -536,7 +541,7 @@ audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -536,7 +541,7 @@ audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
unsigned int res; unsigned int res;
double sum_squares = 0.0; double sum_squares = 0.0;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
for (i = 0; i < fragment->len; i += width) { for (i = 0; i < fragment->len; i += width) {
double val = GETRAWSAMPLE(width, fragment->buf, i); double val = GETRAWSAMPLE(width, fragment->buf, i);
...@@ -614,7 +619,7 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment, ...@@ -614,7 +619,7 @@ 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(AudioopError, "Strings should be even-sized"); PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
return NULL; return NULL;
} }
cp1 = (const int16_t *)fragment->buf; cp1 = (const int16_t *)fragment->buf;
...@@ -623,7 +628,7 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment, ...@@ -623,7 +628,7 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
len2 = reference->len >> 1; len2 = reference->len >> 1;
if (len1 < len2) { if (len1 < len2) {
PyErr_SetString(AudioopError, "First sample should be longer"); PyErr_SetString(_audioopstate(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);
...@@ -681,11 +686,11 @@ audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, ...@@ -681,11 +686,11 @@ 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(AudioopError, "Strings should be even-sized"); PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
return NULL; return NULL;
} }
if (fragment->len != reference->len) { if (fragment->len != reference->len) {
PyErr_SetString(AudioopError, "Samples should be same size"); PyErr_SetString(_audioopstate(module)->AudioopError, "Samples should be same size");
return NULL; return NULL;
} }
cp1 = (const int16_t *)fragment->buf; cp1 = (const int16_t *)fragment->buf;
...@@ -725,14 +730,14 @@ audioop_findmax_impl(PyObject *module, Py_buffer *fragment, ...@@ -725,14 +730,14 @@ 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(AudioopError, "Strings should be even-sized"); PyErr_SetString(_audioopstate(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(AudioopError, "Input sample should be longer"); PyErr_SetString(_audioopstate(module)->AudioopError, "Input sample should be longer");
return NULL; return NULL;
} }
...@@ -777,7 +782,7 @@ audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -777,7 +782,7 @@ audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
unsigned int avg; unsigned int avg;
int diff, prevdiff, nextreme = 0; int diff, prevdiff, nextreme = 0;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
if (fragment->len <= width) if (fragment->len <= width)
return PyLong_FromLong(0); return PyLong_FromLong(0);
...@@ -833,7 +838,7 @@ audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -833,7 +838,7 @@ audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width)
unsigned int max = 0, extremediff; unsigned int max = 0, extremediff;
int diff, prevdiff; int diff, prevdiff;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
if (fragment->len <= width) if (fragment->len <= width)
return PyLong_FromLong(0); return PyLong_FromLong(0);
...@@ -885,7 +890,7 @@ audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -885,7 +890,7 @@ audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width)
int prevval; int prevval;
Py_ssize_t ncross; Py_ssize_t ncross;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
ncross = -1; ncross = -1;
prevval = 17; /* Anything <> 0,1 */ prevval = 17; /* Anything <> 0,1 */
...@@ -918,7 +923,7 @@ audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -918,7 +923,7 @@ audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width,
double maxval, minval; double maxval, minval;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
maxval = (double) maxvals[width]; maxval = (double) maxvals[width];
...@@ -961,10 +966,10 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -961,10 +966,10 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
cp = fragment->buf; cp = fragment->buf;
len = fragment->len; len = fragment->len;
if (!audioop_check_parameters(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(AudioopError, "not a whole number of frames"); PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
return NULL; return NULL;
} }
...@@ -1008,7 +1013,7 @@ audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1008,7 +1013,7 @@ audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width,
double maxval, minval; double maxval, minval;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
maxval = (double) maxvals[width]; maxval = (double) maxvals[width];
...@@ -1056,10 +1061,10 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1, ...@@ -1056,10 +1061,10 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
int minval, maxval, newval; int minval, maxval, newval;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(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(AudioopError, "Lengths should be the same"); PyErr_SetString(_audioopstate(module)->AudioopError, "Lengths should be the same");
return NULL; return NULL;
} }
...@@ -1114,7 +1119,7 @@ audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias) ...@@ -1114,7 +1119,7 @@ audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
unsigned int val = 0, mask; unsigned int val = 0, mask;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
rv = PyBytes_FromStringAndSize(NULL, fragment->len); rv = PyBytes_FromStringAndSize(NULL, fragment->len);
...@@ -1172,7 +1177,7 @@ audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -1172,7 +1177,7 @@ audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
Py_ssize_t i; Py_ssize_t i;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
rv = PyBytes_FromStringAndSize(NULL, fragment->len); rv = PyBytes_FromStringAndSize(NULL, fragment->len);
...@@ -1205,7 +1210,7 @@ audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -1205,7 +1210,7 @@ audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
Py_ssize_t i; Py_ssize_t i;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
rv = PyBytes_FromStringAndSize(NULL, fragment->len); rv = PyBytes_FromStringAndSize(NULL, fragment->len);
...@@ -1241,9 +1246,9 @@ audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1241,9 +1246,9 @@ audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width,
Py_ssize_t i, j; Py_ssize_t i, j;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
if (!audioop_check_size(newwidth)) if (!audioop_check_size(module, newwidth))
return NULL; return NULL;
if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) { if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) {
...@@ -1302,10 +1307,10 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1302,10 +1307,10 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
PyObject *samps, *str, *rv = NULL, *channel; PyObject *samps, *str, *rv = NULL, *channel;
int bytes_per_frame; int bytes_per_frame;
if (!audioop_check_size(width)) if (!audioop_check_size(module, width))
return NULL; return NULL;
if (nchannels < 1) { if (nchannels < 1) {
PyErr_SetString(AudioopError, "# of channels should be >= 1"); PyErr_SetString(_audioopstate(module)->AudioopError, "# of channels should be >= 1");
return NULL; return NULL;
} }
if (width > INT_MAX / nchannels) { if (width > INT_MAX / nchannels) {
...@@ -1318,17 +1323,17 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1318,17 +1323,17 @@ 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(AudioopError, PyErr_SetString(_audioopstate(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(AudioopError, "not a whole number of frames"); PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
return NULL; return NULL;
} }
if (inrate <= 0 || outrate <= 0) { if (inrate <= 0 || outrate <= 0) {
PyErr_SetString(AudioopError, "sampling rate not > 0"); PyErr_SetString(_audioopstate(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 */
...@@ -1369,7 +1374,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1369,7 +1374,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(AudioopError, PyErr_SetString(_audioopstate(module)->AudioopError,
"illegal state argument"); "illegal state argument");
goto exit; goto exit;
} }
...@@ -1491,7 +1496,7 @@ audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -1491,7 +1496,7 @@ audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
Py_ssize_t i; Py_ssize_t i;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
...@@ -1525,7 +1530,7 @@ audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -1525,7 +1530,7 @@ audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
Py_ssize_t i; Py_ssize_t i;
PyObject *rv; PyObject *rv;
if (!audioop_check_size(width)) if (!audioop_check_size(module, width))
return NULL; return NULL;
if (fragment->len > PY_SSIZE_T_MAX/width) { if (fragment->len > PY_SSIZE_T_MAX/width) {
...@@ -1564,7 +1569,7 @@ audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -1564,7 +1569,7 @@ audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
Py_ssize_t i; Py_ssize_t i;
PyObject *rv; PyObject *rv;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
...@@ -1599,7 +1604,7 @@ audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) ...@@ -1599,7 +1604,7 @@ audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
int val; int val;
PyObject *rv; PyObject *rv;
if (!audioop_check_size(width)) if (!audioop_check_size(module, width))
return NULL; return NULL;
if (fragment->len > PY_SSIZE_T_MAX/width) { if (fragment->len > PY_SSIZE_T_MAX/width) {
...@@ -1643,7 +1648,7 @@ audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1643,7 +1648,7 @@ audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width,
PyObject *rv = NULL, *str; PyObject *rv = NULL, *str;
int outputbuffer = 0, bufferstep; int outputbuffer = 0, bufferstep;
if (!audioop_check_parameters(fragment->len, width)) if (!audioop_check_parameters(module, fragment->len, width))
return NULL; return NULL;
/* Decode state, should have (value, step) */ /* Decode state, should have (value, step) */
...@@ -1773,7 +1778,7 @@ audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, ...@@ -1773,7 +1778,7 @@ audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width,
PyObject *rv, *str; PyObject *rv, *str;
int inputbuffer = 0, bufferstep; int inputbuffer = 0, bufferstep;
if (!audioop_check_size(width)) if (!audioop_check_size(module, width))
return NULL; return NULL;
/* Decode state, should have (value, step) */ /* Decode state, should have (value, step) */
...@@ -1897,31 +1902,48 @@ static PyMethodDef audioop_methods[] = { ...@@ -1897,31 +1902,48 @@ static PyMethodDef audioop_methods[] = {
{ 0, 0 } { 0, 0 }
}; };
static int
audioop_traverse(PyObject *m, visitproc visit, void *arg) {
_audioopstate *state = _audioopstate(m);
if (state != NULL)
Py_VISIT(state->AudioopError);
return 0;
}
static int
audioop_clear(PyObject *m) {
_audioopstate *state = _audioopstate(m);
if (state != NULL)
Py_CLEAR(state->AudioopError);
return 0;
}
static void
audioop_free(void *m) {
audioop_clear((PyObject *)m);
}
static struct PyModuleDef audioopmodule = { static struct PyModuleDef audioopmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"audioop", "audioop",
NULL, NULL,
-1, sizeof(_audioopstate),
audioop_methods, audioop_methods,
NULL, NULL,
NULL, audioop_traverse,
NULL, audioop_clear,
NULL audioop_free
}; };
PyMODINIT_FUNC PyMODINIT_FUNC
PyInit_audioop(void) PyInit_audioop(void)
{ {
PyObject *m, *d; PyObject *m = PyModule_Create(&audioopmodule);
m = PyModule_Create(&audioopmodule);
if (m == NULL) if (m == NULL)
return NULL; return NULL;
d = PyModule_GetDict(m); PyObject *AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
if (d == NULL) if (AudioopError == NULL)
return NULL; return NULL;
AudioopError = PyErr_NewException("audioop.error", NULL, NULL); Py_INCREF(AudioopError);
if (AudioopError != NULL) PyModule_AddObject(m, "error", AudioopError);
PyDict_SetItemString(d,"error",AudioopError); _audioopstate(m)->AudioopError = AudioopError;
return m; return m;
} }
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