получение iaxclient для отправки аудио/аудио из буфера вместо аудио-устройства
Я пытаюсь написать программу 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:[email protected]/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
Пожалуйста, посмотрите в 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, чтобы получить хороший старт. Тем не менее, исходный код должен долго копировать и вставлять, извините за это.