static PyObject* cAction_crossfade(PyObject* self, PyObject* args) { PyObject *objInSound1, *objInSound2; char* s_mode = NULL; // Hacky - the percentage through the crossfade that we're processing. // Allows for incremental processing of the same crossfade in chunks. long total = -1; long offset = 0; if (!PyArg_ParseTuple(args, "OO|sll", &objInSound1, &objInSound2, &s_mode, &total, &offset)) return NULL; PyArrayObject *inSound1 = get_pyarray(objInSound1); if (inSound1 == NULL) return NULL; PyArrayObject *inSound2 = get_pyarray(objInSound2); if (inSound2 == NULL) { Py_XDECREF(inSound1); return NULL; } float* inSamples1 = (float *)inSound1->data; float* inSamples2 = (float *)inSound2->data; uint numInSamples = inSound1->dimensions[0]; uint numInChannels = inSound1->dimensions[1]; npy_intp dims[DIMENSIONS]; dims[0] = numInSamples; dims[1] = numInChannels; if ( total < 0 ) { total = numInSamples; } // Allocate interlaced memory for output sound object PyArrayObject* outSound = (PyArrayObject *)PyArray_SimpleNew(DIMENSIONS, dims, NPY_FLOAT); // Get the actual array float* outSamples = (float *)outSound->data; // Figure out which crossfade to use. float (*fader)(float, float, long, long) = strcmp(s_mode, "linear") == 0 ? linear : equal_power; for (uint i = 0; i < numInChannels; i++) { for (uint j = 0; j < numInSamples; j++) { uint index = i + j*numInChannels; outSamples[index] = fader(inSamples1[index], inSamples2[index], (j + offset > total ? total : j + offset), total); } } Py_DECREF(inSound1); Py_DECREF(inSound2); return PyArray_Return(outSound); }
static PyObject* cAction_limit(PyObject* self, PyObject* args) { PyObject *objInSound; if (!PyArg_ParseTuple(args, "O", &objInSound)) return NULL; PyArrayObject *inSound = get_pyarray(objInSound); if (inSound == NULL) return NULL; uint nSamples = inSound->dimensions[0]; uint nChannels = inSound->dimensions[1]; // float *inSamples = (Float32 *)NA_OFFSETDATA(inSound); float *inSamples = (float*) PyArray_DATA(inSound); // Limit: for (uint j = 0; j < nChannels; j++) { for (uint i = 0; i < nSamples; i++) { float f = inSamples[nChannels*i + j]; inSamples[nChannels*i + j] = limiter(f); } } // Do we need to make a copy before returning, or can we return the modified original? return PyArray_Return(inSound); }
static PyObject* cAction_fade(PyObject* self, PyObject* args) { PyObject *objInSound; float volume = 1.0f; float from = 0.0f; float to = 1.0f; if (!PyArg_ParseTuple(args, "O|f|f|f", &objInSound, &volume, &from, &to)) return NULL; PyArrayObject *inSound = get_pyarray(objInSound); if (inSound == NULL) return NULL; uint nSamples = inSound->dimensions[0]; uint nChannels = inSound->dimensions[1]; // float *inSamples = (Float32 *)NA_OFFSETDATA(inSound); float *inSamples = (float*) PyArray_DATA(inSound); // Limit: for (uint j = 0; j < nChannels; j++) { for (uint i = 0; i < nSamples; i++) { float frac = ((float)(nSamples - i) / (float) nSamples) * (to - from) + from; float f = inSamples[nChannels * i + j]; inSamples[nChannels * i + j] = limiter(frac * f * volume); } } // Do we need to make a copy before returning, or can we return the modified original? return PyArray_Return(inSound); }
static PyObject* cAction_crossfade(PyObject* self, PyObject* args) { PyObject *objInSound1, *objInSound2; char* s_mode = NULL; if (!PyArg_ParseTuple(args, "OO|s", &objInSound1, &objInSound2, &s_mode)) return NULL; PyArrayObject *inSound1 = get_pyarray(objInSound1); if (inSound1 == NULL) return NULL; PyArrayObject *inSound2 = get_pyarray(objInSound2); if (inSound2 == NULL) { Py_XDECREF(inSound1); return NULL; } float* inSamples1 = (float *)inSound1->data; float* inSamples2 = (float *)inSound2->data; uint numInSamples = inSound1->dimensions[0]; uint numInChannels = inSound1->dimensions[1]; npy_intp dims[DIMENSIONS]; dims[0] = numInSamples; dims[1] = numInChannels; // Allocate interlaced memory for output sound object PyArrayObject* outSound = (PyArrayObject *)PyArray_SimpleNew(DIMENSIONS, dims, NPY_FLOAT); // Get the actual array float* outSamples = (float *)outSound->data; // Figure out which crossfade to use. float (*fader)(float, float, long, long) = strcmp(s_mode, "linear") == 0 ? linear : equal_power; for (uint i = 0; i < numInChannels; i++) { for (uint j = 0; j < numInSamples; j++) { uint index = i + j*numInChannels; outSamples[index] = fader(inSamples1[index], inSamples2[index], j, numInSamples); } } return PyArray_Return(outSound); }