|
|
@@ -3,6 +3,12 @@
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
|
|
|
+
|
|
|
+#ifndef RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION
|
|
|
+#define RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION 13
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
static int sample_index = 0;
|
|
|
|
|
|
// From pulsecore/macro.h
|
|
|
@@ -539,6 +545,10 @@ int AudioMgrImpl::audio_get_device_name(char* pstrbuf, size_t ulen, bool binput,
|
|
|
const char stranalogstereo[] = { 0x20,0xe6,0xa8,0xa1,0xe6,0x8b,0x9f,0xe7,0xab,0x8b,0xe4,0xbd,0x93,0xe5,0xa3,0xb0,0 };
|
|
|
//数字立体声
|
|
|
const char strdigitalstereo[] = { 0x20,0xe6,0x95,0xb0,0xe5,0xad,0x97,0xe7,0xab,0x8b,0xe4,0xbd,0x93,0xe5,0xa3,0xb0,0 };
|
|
|
+ //立体声
|
|
|
+ const char strstereo[] = { 0x20,0xe7,0xab,0x8b,0xe4,0xbd,0x93,0xe5,0xa3,0xb0,0 };
|
|
|
+ //多声道
|
|
|
+ const char strmultistereo[] = { 0x20,0xe5,0xa4,0x9a,0xe5,0xa3,0xb0,0xe9,0x81,0x93,0 };
|
|
|
|
|
|
rvc_audio_device_t* audio_device = NULL;
|
|
|
if (binput){
|
|
|
@@ -552,10 +562,10 @@ int AudioMgrImpl::audio_get_device_name(char* pstrbuf, size_t ulen, bool binput,
|
|
|
if (ulen > unamelen){
|
|
|
memcpy(pstrbuf, audio_device->description, ulen);
|
|
|
char* pindex = NULL;
|
|
|
- if (pindex = strstr(pstrbuf, stranalogstereo)){
|
|
|
+ if ((pindex = strstr(pstrbuf, stranalogstereo))||(pindex = strstr(pstrbuf, strdigitalstereo))){
|
|
|
*pindex = 0;
|
|
|
}
|
|
|
- if (pindex = strstr(pstrbuf, strdigitalstereo)) {
|
|
|
+ if ((pindex = strstr(pstrbuf, strstereo)) || (pindex = strstr(pstrbuf, strmultistereo))) {
|
|
|
*pindex = 0;
|
|
|
}
|
|
|
|
|
|
@@ -737,8 +747,6 @@ static void get_latency(pa_stream* s)
|
|
|
|
|
|
//latency = l * (negative?-1:1);
|
|
|
latency = l; /*can only be negative in monitoring streams*/
|
|
|
-
|
|
|
- printf("AUDIO: pulseaudio latency is %0.0f usec \n", (float)latency);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -848,8 +856,6 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- printf("**************%s:%d**************\n", __FUNCTION__, __LINE__);
|
|
|
-
|
|
|
if (audio_ctx->samprate == 0)
|
|
|
{
|
|
|
fprintf(stderr, "AUDIO: (pulse audio) stream_request_cb failed: samprate = 0\n");
|
|
|
@@ -873,7 +879,7 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
|
|
|
return;
|
|
|
}
|
|
|
else {
|
|
|
- printf("%s:%d pa_stream_peek audio length is %d.\n", __FUNCTION__, __LINE__, length);
|
|
|
+ //printf("%s:%d pa_stream_peek audio length is %d.\n", __FUNCTION__, __LINE__, length);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -885,16 +891,13 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
|
|
|
|
|
|
get_latency(s);
|
|
|
|
|
|
- printf("%s:%d\n", __FUNCTION__, __LINE__);
|
|
|
ts = ns_time_monotonic() - (latency * 1000);
|
|
|
|
|
|
- printf("%s:%d ts is %d and last_ts is %d.\n", __FUNCTION__, __LINE__, ts, audio_ctx->last_ts);
|
|
|
if (audio_ctx->last_ts <= 0)
|
|
|
audio_ctx->last_ts = ts;
|
|
|
|
|
|
|
|
|
uint32_t numSamples = (uint32_t)length / sizeof(sample_t);
|
|
|
- printf("%s:%d numSamples is %d.\n", __FUNCTION__, __LINE__, numSamples);
|
|
|
|
|
|
audio_ctx->audio_param.on_audio_callback(inputBuffer, length, audio_ctx->audio_param.user_data);
|
|
|
|
|
|
@@ -917,18 +920,15 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
|
|
|
*/
|
|
|
void* pulse_read_audio(void* data)
|
|
|
{
|
|
|
- //AudioMgrImpl* audio_mgr = (AudioMgrImpl*)data;
|
|
|
- //assert(audio_mgr != NULL);
|
|
|
+ AudioMgrImpl* audio_mgr = (AudioMgrImpl*)data;
|
|
|
+ assert(audio_mgr != NULL);
|
|
|
|
|
|
- rvc_audio_context_t* audio_ctx =(rvc_audio_context_t*)data /*audio_mgr->get_audio_context()*/;
|
|
|
- printf("%s:%d stream_flag = %d, audio context is 0x%0x.\n", __FUNCTION__, __LINE__, audio_ctx->stream_flag, audio_ctx);
|
|
|
+ IAudioMgrCallback* callback = audio_mgr->audio_get_callback();
|
|
|
+ assert(callback != NULL);
|
|
|
+
|
|
|
+ rvc_audio_context_t* audio_ctx = audio_mgr->audio_get_context();
|
|
|
/*assertions*/
|
|
|
assert(audio_ctx != NULL);
|
|
|
- int verbosity = 1;
|
|
|
-
|
|
|
- if (verbosity > 0) {
|
|
|
- printf("AUDIO: (pulseaudio) read thread started stream flag = %d,audio context is 0x%0x.\n", audio_ctx->stream_flag, audio_ctx);
|
|
|
- }
|
|
|
|
|
|
pa_mainloop* pa_ml;
|
|
|
pa_mainloop_api* pa_mlapi;
|
|
|
@@ -946,7 +946,7 @@ void* pulse_read_audio(void* data)
|
|
|
|
|
|
if (pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0)
|
|
|
{
|
|
|
- printf("AUDIO: PULSE - unable to connect to server: pa_context_connect failed\n");
|
|
|
+ callback->debug("AUDIO: PULSE - unable to connect to server: pa_context_connect failed.");
|
|
|
finish(pa_ctx, pa_ml);
|
|
|
return ((void*)-1);
|
|
|
}
|
|
|
@@ -986,7 +986,7 @@ void* pulse_read_audio(void* data)
|
|
|
|
|
|
recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
|
|
|
if (!recordstream)
|
|
|
- fprintf(stderr, "AUDIO: (pulse audio) pa_stream_new failed (chan:%d rate:%d)\n",
|
|
|
+ callback->debug("AUDIO: (pulse audio) pa_stream_new failed (chan:%d rate:%d)",
|
|
|
ss.channels, ss.rate);
|
|
|
|
|
|
/* define the callbacks */
|
|
|
@@ -998,11 +998,14 @@ void* pulse_read_audio(void* data)
|
|
|
bufattr.maxlength = (uint32_t)-1;
|
|
|
bufattr.prebuf = (uint32_t)-1;
|
|
|
bufattr.minreq = (uint32_t)-1;
|
|
|
- printf("audio_ctx->latency = %f\n", audio_ctx->latency);
|
|
|
|
|
|
if (audio_ctx->latency > 0){
|
|
|
bufattr.fragsize = bufattr.tlength = pa_usec_to_bytes((audio_ctx->latency * 1000) * PA_USEC_PER_MSEC, &ss);
|
|
|
- pastream_flag |= PA_STREAM_ADJUST_LATENCY;
|
|
|
+ uint32_t uvsersion = pa_context_get_protocol_version(pa_ctx);
|
|
|
+ if (uvsersion >= RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION) {
|
|
|
+ pastream_flag |= PA_STREAM_ADJUST_LATENCY;
|
|
|
+ }
|
|
|
+ callback->debug("pa protocol version is %d.", uvsersion);
|
|
|
}
|
|
|
else {
|
|
|
bufattr.fragsize = bufattr.tlength = (uint32_t)-1;
|
|
|
@@ -1012,13 +1015,12 @@ void* pulse_read_audio(void* data)
|
|
|
pastream_flag |= PA_STREAM_AUTO_TIMING_UPDATE;
|
|
|
|
|
|
char* dev = audio_ctx->list_input_devices[audio_ctx->device].name;
|
|
|
- if (verbosity > 0)
|
|
|
- printf("AUDIO: (pulseaudio) connecting to device %s\n\t (channels %d rate %d)\n",
|
|
|
+ callback->debug("AUDIO: (pulse audio) connecting to device %s (channels %d rate %d)",
|
|
|
dev, ss.channels, ss.rate);
|
|
|
r = pa_stream_connect_record(recordstream, dev, &bufattr, (pa_stream_flags_t)pastream_flag);
|
|
|
if (r < 0)
|
|
|
{
|
|
|
- fprintf(stderr, "AUDIO: (pulse audio) skip latency adjustment\n");
|
|
|
+ callback->debug("AUDIO: (pulse audio) skip latency adjustment");
|
|
|
/*
|
|
|
* Old pulse audio servers don't like the ADJUST_LATENCY flag,
|
|
|
* so retry without that
|
|
|
@@ -1028,12 +1030,12 @@ void* pulse_read_audio(void* data)
|
|
|
(int32_t)PA_STREAM_AUTO_TIMING_UPDATE));
|
|
|
}
|
|
|
else {
|
|
|
- printf("pa_stream_connect_record success!\n");
|
|
|
+ callback->debug("pa_stream_connect_record success!");
|
|
|
}
|
|
|
|
|
|
if (r < 0)
|
|
|
{
|
|
|
- fprintf(stderr, "AUDIO: (pulse audio) pa_stream_connect_record failed\n");
|
|
|
+ callback->debug("AUDIO: (pulse audio) pa_stream_connect_record failed");
|
|
|
finish(pa_ctx, pa_ml);
|
|
|
return ((void*)-1);
|
|
|
}
|
|
|
@@ -1046,16 +1048,12 @@ void* pulse_read_audio(void* data)
|
|
|
* done. Set it to zero for non-blocking.
|
|
|
*/
|
|
|
|
|
|
- printf("%s:%d stream_flag is %d.\n", __FUNCTION__, __LINE__, audio_ctx->stream_flag);
|
|
|
while (audio_ctx->stream_flag == AUDIO_STRM_ON)
|
|
|
{
|
|
|
pa_mainloop_iterate(pa_ml, 1, NULL);
|
|
|
- printf("%s:%d\n", __FUNCTION__, __LINE__);
|
|
|
}
|
|
|
- printf("%s:%d\n", __FUNCTION__, __LINE__);
|
|
|
|
|
|
- if (verbosity > 0)
|
|
|
- printf("AUDIO: (pulseaudio) stream terminated(%i)\n", audio_ctx->stream_flag);
|
|
|
+ callback->debug("AUDIO: (pulse audio) stream terminated(%i)", audio_ctx->stream_flag);
|
|
|
|
|
|
pa_stream_disconnect(recordstream);
|
|
|
pa_stream_unref(recordstream);
|
|
|
@@ -1063,6 +1061,7 @@ void* pulse_read_audio(void* data)
|
|
|
return ((void*)0);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
int AudioMgrImpl::set_audio_capture_params(audiocap_param_t* param)
|
|
|
{
|
|
|
assert(param != NULL);
|
|
|
@@ -1145,6 +1144,17 @@ void AudioMgrImpl::audio_set_latency(double latency)
|
|
|
m_audio_context->latency = latency;
|
|
|
}
|
|
|
|
|
|
+rvc_audio_context_t* AudioMgrImpl::audio_get_context()
|
|
|
+{
|
|
|
+ return m_audio_context;
|
|
|
+}
|
|
|
+
|
|
|
+IAudioMgrCallback* AudioMgrImpl::audio_get_callback()
|
|
|
+{
|
|
|
+ return m_callback;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int AudioMgrImpl::start_audio_capture()
|
|
|
{
|
|
|
/*assertions*/
|
|
|
@@ -1153,14 +1163,13 @@ int AudioMgrImpl::start_audio_capture()
|
|
|
m_audio_context->stream_flag = AUDIO_STRM_ON;
|
|
|
printf("%s:%d stream_flag = %d, audio context is 0x%0x.\n",__FUNCTION__, __LINE__, m_audio_context->stream_flag, m_audio_context);
|
|
|
/* start audio capture thread */
|
|
|
- if (__THREAD_CREATE(&m_readthread, pulse_read_audio, (void*)m_audio_context)){
|
|
|
- printf("AUDIO: (pulse audio) read thread creation failed\n");
|
|
|
+ if (__THREAD_CREATE(&m_readthread, pulse_read_audio, this)){
|
|
|
+ m_callback->debug("AUDIO: (pulse audio) read thread creation failed");
|
|
|
m_audio_context->stream_flag = AUDIO_STRM_OFF;
|
|
|
return (-1);
|
|
|
}
|
|
|
else {
|
|
|
- printf("AUDIO: (pulse audio) read thread creation success, and thread id is %u.\n", m_readthread);
|
|
|
- printf("%s:%d stream_flag = %d, audio context is 0x%0x.\n", __FUNCTION__, __LINE__, m_audio_context->stream_flag, m_audio_context);
|
|
|
+ m_callback->debug("AUDIO: (pulse audio) read thread creation success, and thread id is %u.", m_readthread);
|
|
|
}
|
|
|
|
|
|
return 0;
|