#include #include #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include #include "./util/RTCContext.h" namespace py = boost::python; int init(const char* selfUserId, const char* selfDisplayName, const char* selfRoomId, boost::python::object callback) { RTCContext::instance().setPyCallback(callback); bool res = RTCContext::instance().init(selfUserId, selfDisplayName, selfRoomId); if (res) { return 0; } else { return -1; } } int initRecv(const char* destRoomId, const char* srcUserId, const int16_t destChannelIndex) { bool res = RTCContext::instance().initRecv(destRoomId, srcUserId, destChannelIndex); if (res) { return 0; } else { return -1; } } int initSend(const char* destRoomId, const int16_t destChannelIndex) { bool res = RTCContext::instance().initSend(destRoomId, destChannelIndex); if (res) { return 0; } else { return -1; } } py::object create_numpy_array() { // 确保已调用 import_array() if (PyArray_API == nullptr) { throw std::runtime_error("NumPy API not initialized"); } // 创建数组 npy_intp dims[1] = {4}; int32_t data[4] = {1, 2, 3, 4}; PyObject* py_array = PyArray_SimpleNewFromData(1, dims, NPY_INT32, data); if (!py_array) { throw std::runtime_error("Failed to create NumPy array"); } return py::object(py::handle<>(py_array)); } int sendCustomAudioData(const int16_t destChannelIndex, py::object pD, int32_t sampleRate, uint64_t channelNum, uint64_t dataLen) { try { py::object pyData = create_numpy_array(); std::cout << "step 1" << std::endl; // 1. 检查输入有效性 if (pyData.ptr() == nullptr) { throw std::runtime_error("Input data is NULL"); } std::cout << "step 2" << std::endl; std::cout << "pyData ptr is:" << pyData.ptr() << std::endl; if (!pyData.ptr() || !Py_IsInitialized() || !PyObject_TypeCheck(pyData.ptr(), &PyBaseObject_Type)) { throw std::runtime_error("Invalid Python object"); } std::cout << "step 2" << std::endl; // 2. 检查是否是 numpy 数组 if (!PyArray_Check(pyData.ptr())) { std::cout << "input is notnumpy" << std::endl; throw std::runtime_error("Input is not a numpy array"); } std::cout << "step 3" << std::endl; // 3. 转换为 PyArrayObject PyArrayObject* npArray = reinterpret_cast(pyData.ptr()); std::cout << "step 4" << std::endl; // 4. 检查数据类型是否为 int16 if (PyArray_TYPE(npArray) != NPY_INT16) { throw std::runtime_error("Array must be of type int16 (np.int16)"); } std::cout << "step 5" << std::endl; // 5. 检查数据是否连续 if (!PyArray_ISCONTIGUOUS(npArray)) { throw std::runtime_error("Array must be contiguous in memory"); } std::cout << "step 6" << std::endl; // 6. 获取数据指针 void* dataPtr = PyArray_DATA(npArray); if (dataPtr == nullptr) { throw std::runtime_error("Invalid data pointer"); } std::cout << "step 7" << std::endl; return RTCContext::instance().sendCustomAudioData(destChannelIndex, dataPtr, sampleRate, channelNum, dataLen); } catch (const std::exception& e) { std::cout << "error:" << e.what() << std::endl; return -1; } } // 修改后的初始化函数 int init_numpy() { if (import_array() < 0) { PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return -1; } return 0; } BOOST_PYTHON_MODULE(rtc_plugins) { if (init_numpy() != 0) return; py::def("init", &init); py::def("initRecv", &initRecv); py::def("initSend", &initSend); py::def("sendCustomAudioData", &sendCustomAudioData); }