[英]pjsip capture and play pcm data
I have some embedded Devices that have no audio device by default.我有一些默认情况下没有音频设备的嵌入式设备。 They communicate with each other via a FPGA.它们通过 FPGA 相互通信。 So my question is, how do I capture/play back audio from pjsip in pcm in order to send/receive it with the FPGA?所以我的问题是,如何从 pcm 中的 pjsip 捕获/播放音频,以便使用 FPGA 发送/接收它?
I know that there is pjmedia_mem_player_create() and pjmedia_mem_capture_create() but I can't seem to find any good info towards using these functions.我知道有pjmedia_mem_player_create()和pjmedia_mem_capture_create()但我似乎找不到任何关于使用这些函数的好信息。
I tried the following piece of code, but an assertion failed cause one of the function's parameter is "empty".我尝试了下面的一段代码,但断言失败,因为函数的参数之一是“空”。
Error:错误:
pjmedia_mem_capture_create: Assertion `pool && buffer && size && clock_rate && channel_count && samples_per_frame && bits_per_sample && p_port' failed. pjmedia_mem_capture_create:断言`pool && buffer && size && clock_rate && channel_count && samples_per_frame && bits_per_sample && p_port'失败。
Note : I'm mainly using pjsua2 for everything else like registrations, transports etc. Also the default audio is set to null with ep.audDevManager().setNullDev();注意:我主要将 pjsua2 用于其他所有内容,例如注册、传输等。此外,使用ep.audDevManager().setNullDev();将默认音频设置为 null ; as without this, making/receiving a call would simply fail?!如果没有这个,拨打/接听电话就会失败?!
void MyCall::onCallMediaState(OnCallMediaStateParam &prm){
CallInfo ci = getInfo();
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
pj_pool_t *pool = pj_pool_create(&cp.factory, "POOLNAME", 2000, 2000, NULL);
void *buffer;
pjmedia_port *prt;
#define CLOCK_RATE 8000
#define CHANELS 1
#define SAMPLES_PER_FRAME 480
#define BITS_PER_SAMPLE 16
pjmedia_mem_capture_create( pool, //Pool
buffer, //Buffer
2000, //Buffer Size
CLOCK_RATE,
CHANELS,
SAMPLES_PER_FRAME,
BITS_PER_SAMPLE,
0, //Options
&prt); //The return port}
UPDATE更新
The assertion failed cause the buffer variable doesn't have any memory allocated to it.断言失败导致缓冲区变量没有分配任何内存。 Allocate with twice the amount of samples per frame to have sufficient memory.每帧分配两倍的样本量以获得足够的内存。
buffer = pj_pool_zalloc(pool, 960);
Also a callback needs to be registered with pjmedia_mem_capture_set_eof_cb2()
(The two at the end is necessary for PJSIP 2.10 or later) Apparently from there the buffer can be used.还需要使用pjmedia_mem_capture_set_eof_cb2()
注册回调pjmedia_mem_capture_set_eof_cb2()
PJSIP 2.10 或更高版本需要末尾的两个)显然可以使用缓冲区。 Just that my implementation atm doesn't execute the callback.只是我的实现 atm 不执行回调。
Looks like I found the solution, I have modified your code and wrote a simple code in C with pjsua API to dump every frame to file.看起来我找到了解决方案,我修改了您的代码并使用 pjsua API 在 C 中编写了一个简单的代码,以将每一帧转储到文件中。 Sorry for mess, I'm not proficient in C:对不起,我不精通C:
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
pjsua_conf_port_info cpi;
pjsua_conf_get_port_info(ci.conf_slot, &cpi);
pj_pool_t *pool = pjsua_pool_create("POOLNAME", 2000, 2000);
pjmedia_port *prt;
uint buf_size = cpi.bits_per_sample*cpi.samples_per_frame/8;
void *buffer = pj_pool_zalloc(pool, buf_size);
pjsua_conf_port_id port_id;
pjmedia_mem_capture_create( pool,
buffer,
buf_size,
cpi.clock_rate,
cpi.channel_count,
cpi.samples_per_frame,
cpi.bits_per_sample,
0,
&prt);
pjmedia_mem_capture_set_eof_cb(prt, buffer, dump_incoming_frames);
pjsua_conf_add_port(pool, prt, &port_id);
pjsua_conf_connect(ci.conf_slot, port_id); //connect port with conference
///////dumping frames///
static pj_status_t dump_incoming_frames(pjmedia_port * port, void * usr_data){
pj_size_t buf_size = pjmedia_mem_capture_get_size(port);
char * data = usr_data;
...
fwrite(data,sizeof(data[0]),buf_size,fptr);
...
}
Documenation says pjmedia_mem_capture_set_eof_cb
is deprecated but I couldn't make work pjmedia_mem_capture_set_eof_cb2
, buf_size
is 0 for every call of dump_incoming_frames
so just left with deprecated function. Documenation说pjmedia_mem_capture_set_eof_cb
已被弃用,但我不能让工作pjmedia_mem_capture_set_eof_cb2
, buf_size
是0的每一个电话dump_incoming_frames
所以只留下了不推荐使用的功能。 I also succeed the same result with creating custom port .我也通过创建自定义端口获得了相同的结果。
I hope you can modify it easily to your C++/pjsua2 code我希望您可以轻松地将其修改为您的 C++/pjsua2 代码
UPD: I have modified the PJSIP and packed audio in-out streaming into proper PJSUA2/Media classes so it can be called from Python. UPD:我已经修改了 PJSIP 并将音频输入输出流打包到适当的 PJSUA2/Media 类中,以便可以从 Python 调用它。 Full code is here .完整代码在这里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.