Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Significantly optimized the sound latency performance #3

Merged
merged 1 commit into from
Sep 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 90 additions & 18 deletions OpenParsec/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
#define BUFFER_SIZE 4096
#define SILENT_SIZE 4096
#define FAKE_SIZE 0
#define ALLOW_DELAY 8
#define LOWEST_NUM_BUFFER 3
bool isMuted = false;
bool isStart = false;
int lastbuf = 0;

unsigned int silence_inqueue = 0;
unsigned int silence_outqueue = 0;

AudioQueueBufferRef silence_buf;
typedef struct RecycleChain {
Expand All @@ -28,6 +34,7 @@ struct audio {
AudioQueueRef q;
AudioQueueBufferRef audio_buf[NUM_AUDIO_BUF];
char *mem[NUM_AUDIO_BUF * 2];
int loc[NUM_AUDIO_BUF];
RecycleChainMgr rcm;
int32_t fail_num;
int32_t in_use;
Expand All @@ -36,7 +43,9 @@ struct audio {
static void audio_queue_callback(void *opaque, AudioQueueRef queue, AudioQueueBufferRef buffer)
{
struct audio *ctx = (struct audio *) opaque;

int deltaBuf = 0;
//int silence_use_count = (int)(silence_buf->mUserData);

if (ctx == NULL)
return;

Expand All @@ -45,26 +54,85 @@ static void audio_queue_callback(void *opaque, AudioQueueRef queue, AudioQueueBu
ctx->in_use -= buffer->mAudioDataByteSize;
}

if(buffer != silence_buf) buffer->mAudioDataByteSize = FAKE_SIZE;
RecycleChain *tmp = ctx->rcm.last_to_queue->next;
if ( /*(*tmp->curt)->mAudioDataByteSize != FAKE_SIZE &&*/ tmp != ctx->rcm.first)
if(buffer != silence_buf)
{
//while(ctx->rcm.last_to_queue->next != ctx->rcm.first)
//{
AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
//}
buffer->mAudioDataByteSize = FAKE_SIZE;
lastbuf = *((int *)(buffer->mUserData));
}
else //if ((*ctx->rcm.last_use)->mAudioDataByteSize == FAKE_SIZE)
else
{
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
/*AudioQueueStop(ctx->q, true);
isStart = false;
ctx->in_use = 0;*/
//silence_use_count = 0;
//silence_buf->mUserData = (void *)(0);
++silence_outqueue;
}

if (isMuted) return;

deltaBuf = *((int *)((*ctx->rcm.first->curt)->mUserData));
deltaBuf = deltaBuf - lastbuf - 1;
if (deltaBuf < 0) deltaBuf += NUM_AUDIO_BUF;

while(ctx->rcm.last_to_queue->next != ctx->rcm.first)
{
AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
}

if (deltaBuf + silence_inqueue < LOWEST_NUM_BUFFER + silence_outqueue)
{
int numAddBuffer = ((silence_inqueue >= silence_outqueue) ? (LOWEST_NUM_BUFFER - deltaBuf - (int)(silence_inqueue-silence_outqueue)) : (LOWEST_NUM_BUFFER - deltaBuf - (int)((unsigned int)(0xFFFFFFFF)-silence_outqueue + silence_inqueue + 1)));
if (numAddBuffer > LOWEST_NUM_BUFFER)
{
numAddBuffer = LOWEST_NUM_BUFFER - deltaBuf;
}
else
{
silence_inqueue = silence_outqueue = 0;
}
for (int i=0; i<numAddBuffer; ++i)
{
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
}
if (numAddBuffer > 0) silence_inqueue += numAddBuffer;
}

//RecycleChain *tmp = ctx->rcm.last_to_queue->next;
//if ( /*(*tmp->curt)->mAudioDataByteSize != FAKE_SIZE &&*/ tmp != ctx->rcm.first)
//if (deltaBuf > ALLOW_DELAY)
//{
// //while(ctx->rcm.last_to_queue->next != ctx->rcm.first)
// for (int i = 0; i < deltaBuf - ALLOW_DELAY + 1; ++i)
// {
// AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
// ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
// }
//}
//else
//{
// int silence_use_count = (int)(silence_buf->mUserData);
// if ( deltaBuf > 0 )
// {
// AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
// ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
// }
// else if (silence_use_count == 0)
// {
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// //int tmp = (int)(silence_buf->mUserData);
// //++tmp;
// silence_buf->mUserData = (void *)(1);
// }
//}
//else //if ((*ctx->rcm.last_use)->mAudioDataByteSize == FAKE_SIZE)
//{
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// /*AudioQueueStop(ctx->q, true);
// isStart = false;
// ctx->in_use = 0;*/
//}

/*if(ctx->rcm.last_to_queue->curt == &buffer && ctx->rcm.last_to_queue->next == ctx->rcm.first) // && (*ctx->rcm.first->curt)->mAudioDataByteSize == FAKE_SIZE)
{
AudioQueueStop(ctx->q, true);
Expand Down Expand Up @@ -107,7 +175,8 @@ void audio_init(struct audio **ctx_out)
for (int32_t x = 0; x < NUM_AUDIO_BUF; x++) {
AudioQueueAllocateBuffer(ctx->q, BUFFER_SIZE, &ctx->audio_buf[x]);
ctx->audio_buf[x]->mAudioDataByteSize = FAKE_SIZE;

ctx->loc[x] = x;
ctx->audio_buf[x]->mUserData = (void *)(&ctx->loc[x]);
rcTraverse->curt = &ctx->audio_buf[x];
if( x != NUM_AUDIO_BUF - 1)
{
Expand All @@ -119,16 +188,17 @@ void audio_init(struct audio **ctx_out)
//ctx->rcm.first = rcTraverse;
rcTraverse->next = ctx->rcm.rc;
}

}
isStart = false;
ctx->fail_num = 0;
ctx->in_use = 0;

silence_inqueue = silence_outqueue = 0;
char silence[SILENT_SIZE] = {0};
AudioQueueAllocateBuffer(ctx->q, SILENT_SIZE, &silence_buf);
memcpy(silence_buf->mAudioData, &silence[0], SILENT_SIZE);
silence_buf->mAudioDataByteSize = SILENT_SIZE;
silence_buf->mUserData = NULL;
}

void audio_destroy(struct audio **ctx_out)
Expand All @@ -151,6 +221,7 @@ void audio_destroy(struct audio **ctx_out)
*ctx_out = NULL;
isStart = false;
AudioQueueFreeBuffer(ctx->q, silence_buf);
silence_inqueue = silence_outqueue = 0;
}

void audio_clear(struct audio **ctx_out)
Expand Down Expand Up @@ -181,6 +252,7 @@ void audio_clear(struct audio **ctx_out)
isStart = false;
ctx->in_use = 0;
ctx->fail_num = 0;
silence_inqueue = silence_outqueue = 0;
}

void audio_cb(const int16_t *pcm, uint32_t frames, void *opaque)
Expand Down
Loading