草庐IT

c++ - 让 iaxclient 向缓冲区发送音频/从缓冲区而不是音频设备获取音频

coder 2023-06-01 原文

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

连接后,它应该监听音频并进行处理。它还应该发回音频。我正在使用 https://sourceforge.net/projects/iaxclient/为此(请注意,有几个版本(beta、常规版本、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("text\n");
    }
    else if (e.type == IAXC_EVENT_LEVELS) {
        printf("level\n");
    }
    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 %d\n", e.ev.netstats.callNo, e.ev.netstats.rtt);
    }
    else if (e.type == IAXC_EVENT_AUDIO) {
        printf("\t AUDIO!!!! %d %u %d\n", 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: %d\n", e.type);
    }

    return 1;
}

int main(int argc, char *argv[])
{
    iaxc_set_test_mode(1);
    printf("init %d\n", iaxc_initialize(1));

    iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX);

    iaxc_set_event_callback(iaxc_event_callback);
    printf("get audio pref %d\n", iaxc_get_audio_prefs());
    //printf("set audio pref %d\n", iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED));
    printf("set audio pref %d\n", iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_REMOTE_RAW | IAXC_AUDIO_PREF_RECV_LOCAL_RAW));
    printf("get audio pref %d\n", iaxc_get_audio_prefs());

    printf("start thread %d\n", iaxc_start_processing_thread());

    int id = -1;
    printf("register %d\n", id = iaxc_register("6003", "1923", "192.168.64.1"));

    int callNo = -1;
    printf("call %d\n", callNo = iaxc_call("6003:1923@192.168.64.1/6001"));

    printf("unquelch: %d\n", iaxc_unquelch(callNo));

    pause();

    printf("finish\n");
    printf("%d\n", iaxc_unregister(id));
    printf("%d\n", iaxc_stop_processing_thread());
    iaxc_shutdown();

    return 0;
}

最佳答案

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

更具体的例子请看 simplecall source 中的 main 方法。获得一个良好的开端。但是,源代码太长了,需要复制和粘贴,对此感到抱歉。

关于c++ - 让 iaxclient 向缓冲区发送音频/从缓冲区而不是音频设备获取音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52131418/

有关c++ - 让 iaxclient 向缓冲区发送音频/从缓冲区而不是音频设备获取音频的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  4. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  9. ruby-on-rails - 只有当不是 nil 时才执行映射? - 2

    如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐