rtc_plugins/rtc_plugins.cpp

130 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// rtc_plugins.cpp
#define IMPLEMENT_NUMPY_API // 标记这是实现文件
#include "util/numpyStub.h"
#include "util/RTCContext.h"
// 提供转换接口
void** get_numpy_api() {
return (void**)RTC_PLUGINS_ARRAY_API;
}
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* srcRoomId, const char* destRoomId, const int16_t destChannelIndex, const uint8_t channelNum) {
bool res = RTCContext::instance().initSend(srcRoomId, destRoomId, destChannelIndex, channelNum);
if (res) {
return 0;
} else {
return -1;
}
}
py::object create_int16_array() {
// 1. 定义数组维度1维长度为 4
npy_intp dims[1] = {4};
// 2. 创建原生 C 数组int16_t 数据)
int16_t data[4] = {1, 2, -3, 4}; // 示例数据
// 3. 通过 NumPy C API 创建 PyObject*
PyObject* py_array = PyArray_SimpleNewFromData(
1, // 维度数
dims, // 各维度大小
NPY_INT16, // 数据类型np.int16
data // 数据指针
);
if (!py_array) {
throw std::runtime_error("Failed to create NumPy array");
}
// 4. 转换为 py::object自动管理引用计数
return py::object(py::handle<>(py_array));
}
int sendCustomAudioData(int16_t destChannelIndex, py::object pD,
int32_t sampleRate, uint64_t channelNum, uint64_t dataLen) {
try {
// 强制转换为 int16 连续数组
PyObject* py_array = PyArray_FROM_OTF(
pD.ptr(),
NPY_INT16,
NPY_ARRAY_IN_ARRAY | NPY_ARRAY_FORCECAST
);
if (!py_array) {
throw std::runtime_error("Failed to convert input to int16 array");
}
// 修复点:使用花括号初始化
py::object arr{py::handle<>(py_array)};
// 检查数据长度
PyArrayObject* npArray = reinterpret_cast<PyArrayObject*>(arr.ptr());
if (PyArray_SIZE(npArray) != static_cast<npy_intp>(dataLen)) {
Py_DECREF(py_array);
throw std::runtime_error("Array length does not match dataLen");
}
// 处理数据...
void* dataPtr = PyArray_DATA(npArray);
int ret = RTCContext::instance().sendCustomAudioData(
destChannelIndex, dataPtr, sampleRate, channelNum, dataLen
);
Py_DECREF(py_array); // 释放临时数组
return ret;
} catch (...) {
PyErr_SetString(PyExc_RuntimeError, "Invalid audio data");
return -1;
}
}
void init_numpy() {
// 直接调用底层函数,绕过宏的问题
if (_import_array() < 0) {
PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
throw std::runtime_error("NumPy initialization failed");
}
std::cout << "NumPy API addr: " << PyArray_API << std::endl;
}
BOOST_PYTHON_MODULE(rtc_plugins) {
try {
init_numpy();
void** numpyApi = (void**)PyArray_API;
if (!numpyApi || !numpyApi[93]) { // 93是PyArray_SimpleNew的偏移量
std::cout << "NumPy API corrupt! Key functions missing." << std::endl;
PyErr_Print();
throw std::runtime_error("Invalid NumPy API state");
} else {
RTCContext::instance().setNumpyApi(numpyApi);
std::cout << "set numpyApi succ:" << numpyApi[93] << std::endl;
}
py::def("init", &init);
py::def("initRecv", &initRecv);
py::def("initSend", &initSend);
py::def("sendCustomAudioData", &sendCustomAudioData);
} catch (...) {
PyErr_SetString(PyExc_RuntimeError, "Module initialization failed");
}
}