|
@@ -7,9 +7,12 @@
|
|
|
#include "audioframework.h"
|
|
|
#include "libaudioqueue.h"
|
|
|
#include "rvc_media_common.h"
|
|
|
-#include <string.h>
|
|
|
+#include <string>
|
|
|
#include "iaudionsinterface.h"
|
|
|
|
|
|
+#include <map>
|
|
|
+#include "CommEntityUtil.hpp"
|
|
|
+
|
|
|
#ifdef RVC_OS_WIN
|
|
|
#include <portaudio.h>
|
|
|
#endif
|
|
@@ -191,38 +194,6 @@ static int rvc_audio_playing_data(void* pdata, size_t ulen, void* user_data)
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
-//static int rx_audio_callback(char *frame,void*userdata)
|
|
|
-//{
|
|
|
-// audio_session_t*session = (audio_session_t*)userdata;
|
|
|
-// int used = 0;
|
|
|
-//
|
|
|
-// if (DOUBLERECORD_CALLTYPE != session->phonemedia_conf.eCalltype)
|
|
|
-// {
|
|
|
-// if (frame)
|
|
|
-// {
|
|
|
-// audio_frame frm;
|
|
|
-// frm.bitspersample = 16;
|
|
|
-// frm.format = 1;
|
|
|
-// frm.data = frame;
|
|
|
-// frm.framesize = 160; //注意此参数可能不准确,网络传输的包大小可能是不定长的,取音频数据时慎用此参数
|
|
|
-// //写入实际的单个包大小
|
|
|
-// //frm.framesize = strlen(frame); //不能使用此方法,网络传输的包大小可能是不定长的
|
|
|
-// frm.nchannels = 1;
|
|
|
-// frm.samplespersec = 8000;
|
|
|
-// #ifdef RVC_OS_LINUX
|
|
|
-// frm.iseriesnumber = g_nAudioRecvNum;
|
|
|
-// #endif
|
|
|
-// if (!session->remoteaudioqueue->InsertAudio(&frm))
|
|
|
-// {
|
|
|
-// DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InsertAudio failed! frameCount:%d", frm.framesize);
|
|
|
-// used = -1;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return used;
|
|
|
-//}
|
|
|
-
|
|
|
static void send_hook_callback(const char *buf, int size, void *arg)
|
|
|
{
|
|
|
g_nAudioSendNum++;
|
|
@@ -237,65 +208,6 @@ static void recv_hook_callback(const char *buf, int size, void *arg)
|
|
|
LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_STREAM_RECEIVED, CSimpleStringA::Format("received first audio packet, and packet size is %d.", size).GetData());
|
|
|
psession->baudiorecved = true;
|
|
|
}
|
|
|
-
|
|
|
-//#ifdef RVC_OS_WIN
|
|
|
-// if (0 == psession->phonemedia_conf.dev_type && DOUBLERECORD_CALLTYPE == psession->phonemedia_conf.eCalltype){
|
|
|
-// if (false == psession->brtpinsertqueue){
|
|
|
-// DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("rtp stream insert to audio queue flag is set to true.");
|
|
|
-// }
|
|
|
-// psession->brtpinsertqueue = true;
|
|
|
-// }
|
|
|
-// g_nAudioRecvNum++;
|
|
|
-//
|
|
|
-// if (true == phonemedia_rtp_record(psession)){
|
|
|
-// char strbuffer[RVC_MAX_BUFFER_LEN]={0};
|
|
|
-// int outsize = RVC_MAX_BUFFER_LEN;
|
|
|
-// switch(hdr->pt)
|
|
|
-// {
|
|
|
-// case RTP_PT_PCMA:
|
|
|
-// audiocodec_pcma_decode(buf+sizeof(rtp_hdr), size-sizeof(rtp_hdr), strbuffer, &outsize);
|
|
|
-// break;
|
|
|
-// case RTP_PT_PCMU:
|
|
|
-// audiocodec_pcmu_decode(buf+sizeof(rtp_hdr), size-sizeof(rtp_hdr), strbuffer, &outsize);
|
|
|
-// break;
|
|
|
-// case RTP_PT_G729:
|
|
|
-// audiocodec_g729a_decode(buf+sizeof(rtp_hdr), size-sizeof(rtp_hdr), strbuffer, &outsize);
|
|
|
-// break;
|
|
|
-// default:
|
|
|
-// DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audiocodec_decode not support audio pt(%d).", hdr->pt);
|
|
|
-// break;
|
|
|
-// }
|
|
|
-//
|
|
|
-// if (psession && psession->remoteaudioqueue){
|
|
|
-// int iCount = (outsize+iLastLeft)/RVC_AUDIO_FRAME_LEN;
|
|
|
-// memcpy(straudiodata+iLastLeft, strbuffer, iCount*RVC_AUDIO_FRAME_LEN-iLastLeft);
|
|
|
-// for(int i = 0; i < iCount; i++)
|
|
|
-// {
|
|
|
-// audio_frame frm;
|
|
|
-// char straudio[RVC_AUDIO_FRAME_LEN]={0};
|
|
|
-// memcpy(straudio, straudiodata+i*RVC_AUDIO_FRAME_LEN, RVC_AUDIO_FRAME_LEN);
|
|
|
-// frm.bitspersample = 16;
|
|
|
-// frm.format = 1;
|
|
|
-// frm.data = straudio;
|
|
|
-// frm.framesize = RVC_AUDIO_FRAME_LEN; //注意此参数可能不准确,网络传输的包大小可能是不定长的,取音频数据时慎用此参数
|
|
|
-// frm.nchannels = 1;
|
|
|
-// frm.samplespersec = 8000;
|
|
|
-// if (!psession->remoteaudioqueue->InsertAudio(&frm))
|
|
|
-// {
|
|
|
-// DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InsertAudio failed! frameCount:%d", frm.framesize);
|
|
|
-// }
|
|
|
-// }
|
|
|
-// memset(straudiodata, 0, RVC_MAX_BUFFER_LEN); //清空缓存
|
|
|
-// iLastLeft = (outsize + iLastLeft) % RVC_AUDIO_FRAME_LEN; //上次剩余不足RVC_AUDIO_FRAME_LEN的buffer
|
|
|
-// if ((0 != iLastLeft) && (iCount*RVC_AUDIO_FRAME_LEN < outsize)){
|
|
|
-// memcpy(straudiodata, strbuffer+iCount*RVC_AUDIO_FRAME_LEN, iLastLeft); //暂存上一次的未入队列的音频数据
|
|
|
-// }
|
|
|
-// }
|
|
|
-// else{
|
|
|
-// DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pseesion->remoteaudioqueue is null.");
|
|
|
-// }
|
|
|
-// }
|
|
|
-//#endif
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1008,6 +920,8 @@ int audio_lib_init()
|
|
|
CSimpleStringA strJsonOutData = CSimpleStringA::Format("audio out devices [{%s}]", strJsonOut.GetData());
|
|
|
LogWarn(Severity_Low, Error_Debug, LOG_EVT_SIPPHONE_GET_AUDIO_OUT_INFOS, strJsonOutData.GetData());
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
#endif
|
|
|
audio_log_set_func(&__audio_log_func);
|
|
|
}
|
|
@@ -1022,22 +936,29 @@ void audio_lib_deinit()
|
|
|
|
|
|
|
|
|
#ifdef RVC_OS_WIN
|
|
|
-
|
|
|
int audio_get_dev_count(int *in_cnt, int *out_cnt)
|
|
|
{
|
|
|
int icnt = 0, ocnt = 0;
|
|
|
int cnt = Pa_GetDeviceCount();
|
|
|
for (int i = 0; i < cnt; ++i) {
|
|
|
const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
|
|
|
- if (info->maxInputChannels)
|
|
|
- icnt ++;
|
|
|
- if (info->maxOutputChannels)
|
|
|
- ocnt ++;
|
|
|
+ if (info->maxInputChannels) {
|
|
|
+ icnt++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info->maxOutputChannels) {
|
|
|
+ ocnt++;
|
|
|
+ }
|
|
|
}
|
|
|
- if (in_cnt)
|
|
|
+
|
|
|
+ if (in_cnt) {
|
|
|
*in_cnt = icnt;
|
|
|
- if (out_cnt)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (out_cnt) {
|
|
|
*out_cnt = ocnt;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1069,6 +990,54 @@ CSimpleStringA audio_get_dev_name(bool in_direction, int idx)
|
|
|
return CSimpleStringA();
|
|
|
}
|
|
|
|
|
|
+CSimpleStringA audio_get_dev_infos(bool in_direction)
|
|
|
+{
|
|
|
+ int cnt = Pa_GetDeviceCount();
|
|
|
+
|
|
|
+ CSimpleStringA strAudioJson("");
|
|
|
+ for (int i = 0; i < cnt; ++i) {
|
|
|
+ const PaDeviceInfo* pinfo = Pa_GetDeviceInfo(i);
|
|
|
+ std::map<std::string, std::string> msgInfo;
|
|
|
+ if (in_direction) {
|
|
|
+ if (pinfo->maxInputChannels > 0) {
|
|
|
+ msgInfo["name"] = pinfo->name;
|
|
|
+ msgInfo["samprate"] = CSimpleStringA::Format("%d", (int)pinfo->defaultSampleRate).GetData();
|
|
|
+ msgInfo["channels"] = CSimpleStringA::Format("%d", pinfo->maxInputChannels).GetData();
|
|
|
+ msgInfo["low_latency"] = CSimpleStringA::Format("%.2f", pinfo->defaultLowInputLatency).GetData();
|
|
|
+ msgInfo["high_latency"] = CSimpleStringA::Format("%.2f", pinfo->defaultHighInputLatency).GetData();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (pinfo->maxOutputChannels > 0) {
|
|
|
+ msgInfo["name"] = pinfo->name;
|
|
|
+ msgInfo["samprate"] = CSimpleStringA::Format("%d", (int)pinfo->defaultSampleRate).GetData();
|
|
|
+ msgInfo["channels"] = CSimpleStringA::Format("%d", pinfo->maxOutputChannels).GetData();
|
|
|
+ msgInfo["low_latency"] = CSimpleStringA::Format("%.2f", pinfo->defaultLowOutputLatency).GetData();
|
|
|
+ msgInfo["high_latency"] = CSimpleStringA::Format("%.2f", pinfo->defaultHighOutputLatency).GetData();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ std::pair<bool, std::string> strResult;
|
|
|
+ strResult = generateJsonStr(msgInfo);
|
|
|
+ if (strResult.first) {
|
|
|
+ strAudioJson += strResult.second.c_str();
|
|
|
+ strAudioJson += ",";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (strAudioJson.GetLength() > 0) {
|
|
|
+ strAudioJson[strAudioJson.GetLength() - 1] = '\0';
|
|
|
+ }
|
|
|
+
|
|
|
+ return strAudioJson;
|
|
|
+}
|
|
|
+
|
|
|
int capture_get_audio_device_id(bool in_direction, const char *dev_name)
|
|
|
{
|
|
|
if (NULL == dev_name || 0 == strlen(dev_name)) {
|