Получение iaxclient для отправки аудио в / получить аудио из буфера вместо аудио-устройства - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь написать программу на C ++ (хотя python вполне подойдет, если кто-то знает лучшую (IAX / SIP) альтернативу), которая подключается к серверу Asterisk.

После подключения он должен прослушать аудио и обработать его. Также следует отправить аудио обратно. Для этого я использую 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("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;
}

1 Ответ

0 голосов
/ 11 сентября 2018

Пожалуйста, посмотрите в iaxclient_lib.c и посмотрите, как работает логика. Чтобы перехватить или заменить ввод / вывод, вы можете изменить функцию iaxci_do_audio_callback в memcpy (e.ev.audio.data, data, size); там, где установлен буфер. Также взгляните на service_audio , чтобы понять, как вы можете заменить буфер / поток, отправленный в удаленное местоположение (например, want_send_audio и want_local_audio). Вы также можете создавать виртуальные устройства ввода / вывода в portaudio, которые iaxclient использует для обработки аудио, используя вместо этого буферы.

Для более конкретного примера, пожалуйста, посмотрите на основной метод в simplecall source , чтобы получить хорошее начало. Однако исходный код слишком длинный для копирования и вставки, извините за это.

...