123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #include "precompile.h"
- #include "audioengine.h"
- #include "audiolog.h"
- #define DEFAULT_SIZE 1024
- struct audioengine_t
- {
- unsigned int timer_id;
- apr_array_header_t *arr_ctx;
- apr_thread_mutex_t *mtx;
- LARGE_INTEGER start_tick;
- LARGE_INTEGER tick;
- LARGE_INTEGER seq;
- };
- void audiocontext_signal(audiocontext_t *ctx);
- static __inline void GetTick(LARGE_INTEGER *last, LARGE_INTEGER *lt)
- {
- DWORD dwNow = GetTickCount();
- if (last->LowPart > dwNow) {
- lt->LowPart = dwNow;
- lt->HighPart = last->HighPart + 1;
- } else {
- lt->LowPart = dwNow;
- lt->HighPart = last->HighPart;
- }
- }
- static void engine_on_clock(audioengine_t *e)
- {
- e->seq.LowPart++;
- if (e->seq.LowPart == 0)
- e->seq.HighPart++;
- apr_thread_mutex_lock(e->mtx);
- {
- int i;
- for (i = 0; i < e->arr_ctx->nelts; ++i) {
- audiocontext_t *ctx = APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*);
- audiocontext_signal(ctx);
- }
- }
- apr_thread_mutex_unlock(e->mtx);
- }
- static void CALLBACK time_cb(UINT uTimerID,
- UINT uMsg,
- DWORD_PTR dwUser,
- DWORD_PTR dw1,
- DWORD_PTR dw2)
- {
- audioengine_t *e = (audioengine_t*)dwUser;
- LONGLONG diff;
- LONGLONG duration;
- GetTick(&e->tick, &e->tick);
- diff = e->tick.QuadPart - e->start_tick.QuadPart;
- duration = e->seq.QuadPart * FRAME_TIME;
- if (diff > duration + 100) {
- engine_on_clock(e);
- engine_on_clock(e);
- AUDIO_LOG_ERROR("time_cb swift, add one onclock!");
- } else if (diff > duration-100) {
- engine_on_clock(e);
- } else {
- AUDIO_LOG_ERROR("time_cb swift, remove one onclock!");
- }
- }
- apr_status_t audioengine_create(apr_pool_t *pool, audioengine_t **p_engine)
- {
- apr_status_t status;
- audioengine_t *engine;
- engine = apr_palloc(pool, sizeof(audioengine_t));
- memset(engine, 0, sizeof(audioengine_t));
- engine->arr_ctx = apr_array_make(pool, DEFAULT_SIZE, sizeof(audiocontext_t*));
- if (!engine->arr_ctx) {
- return APR_ENOMEM;
- }
- status = apr_thread_mutex_create(&engine->mtx,
- APR_THREAD_MUTEX_NESTED, pool);
- if (status != APR_SUCCESS) {
- return status;
- }
- *p_engine = engine;
- return APR_SUCCESS;
- }
- void audioengine_destroy(audioengine_t *engine)
- {
- if (engine) {
- apr_thread_mutex_destroy(engine->mtx);
- }
- }
- apr_status_t audioengine_start(audioengine_t *e)
- {
- e->start_tick.LowPart = 0;
- e->start_tick.HighPart = 0;
- e->seq.LowPart = 0;
- e->seq.HighPart = 0;
- e->tick.LowPart = 0;
- e->tick.HighPart = 0;
- GetTick(&e->start_tick, &e->start_tick);
- e->timer_id = timeSetEvent(FRAME_TIME, 0, &time_cb, (DWORD_PTR)e,
- TIME_PERIODIC | TIME_CALLBACK_FUNCTION | TIME_KILL_SYNCHRONOUS);
- return e->timer_id ? APR_SUCCESS : apr_get_os_error();
- }
- void audioengine_stop(audioengine_t *e)
- {
- if (e) {
- timeKillEvent(e->timer_id);
- e->timer_id = 0;
- }
- }
- int audioengine_is_started(audioengine_t *e)
- {
- return e->timer_id != 0;
- }
- apr_status_t audioengine_start_context(audioengine_t *e, audiocontext_t *ctx)
- {
- if (!e || !ctx) {
- return APR_BADARG;
- }
- apr_thread_mutex_lock(e->mtx);
- APR_ARRAY_PUSH(e->arr_ctx, audiocontext_t*) = ctx;
- apr_thread_mutex_unlock(e->mtx);
- return APR_SUCCESS;
- }
- void audioengine_stop_context(audioengine_t *e, audiocontext_t *ctx)
- {
- if (e && ctx) {
- int i;
- apr_thread_mutex_lock(e->mtx);
- for (i = 0; i < e->arr_ctx->nelts; ++i) {
- if (ctx == APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*)) {
- if (i < e->arr_ctx->nelts-1) {
- audiocontext_t *tmp = APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*);
- APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*) = APR_ARRAY_IDX(e->arr_ctx, e->arr_ctx->nelts-1, audiocontext_t*);
- APR_ARRAY_IDX(e->arr_ctx, e->arr_ctx->nelts-1, audiocontext_t*) = tmp;
- }
- apr_array_pop(e->arr_ctx);
- break;
- }
- }
- apr_thread_mutex_unlock(e->mtx);
- }
- }
|