让 iaxClient 将音频发送到缓冲区而不是音频设备/从缓冲区获取音频

getting iaxclient to send audio to/get audio from buffer instead of audio-device

本文关键字:音频 缓冲区 获取 iaxClient      更新时间:2023-10-16

我正在尝试编写一个连接到Asterisk服务器的C++程序(如果有人知道更好的(IAX/SIP(替代方案,python也会很好(。

连接后,它应该侦听音频并进行处理。它还应该发回音频。我为此使用 https://sourceforge.net/projects/iaxclient/(请注意,有几个版本(测试版、常规版本、svn 版本(的行为都不同(。

现在,如果我正确理解了库的代码,那么它就可以调用带有事件的回调函数。其中一个事件是IAXC_EVENT_AUDIO。在那个IAXC_EVENT_AUDIO的结构中有一个方向;传入的传出。这就是我迷茫的地方:对于某些版本的iaxclient,我只收到IAXC_SOURCE_REMOTE消息,有些则两者兼而有之。如果我切换到测试模式(应该只禁用音频设备(,我通常什么也没收到。当我同时收到IAXC_SOURCE_LOCAL和IAXC_SOURCE_REMOTE时,我尝试将这些事件的缓冲区设置为随机数据,但这根本没有到达另一端(我将其设置为 RAW 模式(。

作为任何人,有什么建议如何解决这个问题?

我的测试代码是:

#include <iaxclient.h>
#include <unistd.h>
int iaxc_event_callback(iaxc_event e)
{
if (e.type == IAXC_EVENT_TEXT) {
printf("textn");
}
else if (e.type == IAXC_EVENT_LEVELS) {
printf("leveln");
}
else if (e.type == IAXC_EVENT_STATE) {
struct iaxc_ev_call_state *st = iaxc_get_event_state(&e);
printf("tcallno %d state %d format %d remote %s(%s)n", st->callNo, st->state, st->format,st->remote, st->remote_name);
iaxc_key_radio(st->callNo);
}
else if (e.type == IAXC_EVENT_NETSTAT) {
printf("tcallno %d rtt %dn", e.ev.netstats.callNo, e.ev.netstats.rtt);
}
else if (e.type == IAXC_EVENT_AUDIO) {
printf("t AUDIO!!!! %d %u %dn", e.ev.audio.source, e.ev.audio.ts, e.ev.audio.size);
for(int i=0; i<e.ev.audio.size; i++)
printf("%02x ", e.ev.audio.data[i]);
printf("n");
}
else {
printf("type: %dn", e.type);
}
return 1;
}
int main(int argc, char *argv[])
{
iaxc_set_test_mode(1);
printf("init %dn", iaxc_initialize(1));
iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX);
iaxc_set_event_callback(iaxc_event_callback);
printf("get audio pref %dn", iaxc_get_audio_prefs());
//printf("set audio pref %dn", iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED));
printf("set audio pref %dn", iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_REMOTE_RAW | IAXC_AUDIO_PREF_RECV_LOCAL_RAW));
printf("get audio pref %dn", iaxc_get_audio_prefs());
printf("start thread %dn", iaxc_start_processing_thread());
int id = -1;
printf("register %dn", id = iaxc_register("6003", "1923", "192.168.64.1"));
int callNo = -1;
printf("call %dn", callNo = iaxc_call("6003:1923@192.168.64.1/6001"));
printf("unquelch: %dn", iaxc_unquelch(callNo));
pause();
printf("finishn");
printf("%dn", iaxc_unregister(id));
printf("%dn", iaxc_stop_processing_thread());
iaxc_shutdown();
return 0;
}

请在 iaxclient_lib.c 中也看看逻辑是如何工作的。要挂接或替换输入/输出,您可以在memcpy(e.ev.audio.data,data,size(更改功能iaxci_do_audio_callback;设置缓冲区的位置。另请查看service_audio,了解如何替换发送到远程位置的缓冲区/流(例如want_send_audio和want_local_audio(。您还可以在端口音频中创建虚拟输入/输出设备,iaxclient 将该设备用于使用缓冲区处理音频。

有关更具体的示例,请查看simplecall源代码中的main方法以获得良好的开端。但是,源代码是渴望复制和粘贴,对此感到抱歉。