uint64_t pa_smoother_translate(pa_smoother *s, uint64_t x, uint64_t y_delay) { uint64_t ney; double nde; pa_assert(s); /* Fix up x value */ if (s->paused) x = s->pause_time; x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0; estimate(s, x, &ney, &nde); /* Play safe and take the larger gradient, so that we wakeup * earlier when this is used for sleeping */ if (s->dp > nde) nde = s->dp; #ifdef DEBUG_DATA pa_log_debug("translate(%llu) = %llu (%0.2f)", (unsigned long long) y_delay, (unsigned long long) ((double) y_delay / nde), nde); #endif return (uint64_t) llrint((double) y_delay / nde); }
static void pa_mix_s32ne_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, int32_t *data, unsigned length) { unsigned channel = 0; length /= sizeof(int32_t); for (; length > 0; length--, data++) { int64_t sum = 0; unsigned i; for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t cv = m->linear[channel].i; int64_t v; if (PA_LIKELY(cv > 0)) { v = *((int32_t*) m->ptr); v = (v * cv) >> 16; sum += v; } m->ptr = (uint8_t*) m->ptr + sizeof(int32_t); } sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL); *data = (int32_t) sum; if (PA_UNLIKELY(++channel >= channels)) channel = 0; }
uint64_t pa_smoother_get(pa_smoother *s, uint64_t x) { uint64_t y; pa_assert(s); /* Fix up x value */ if (s->paused) x = s->pause_time; x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0; if (s->monotonic) if (x <= s->last_x) x = s->last_x; estimate(s, x, &y, NULL); if (s->monotonic) { /* Make sure the querier doesn't jump forth and back. */ s->last_x = x; if (y < s->last_y) y = s->last_y; else s->last_y = y; } #ifdef DEBUG_DATA pa_log_debug("%p, get(%llu | %llu) = %llu", s, (unsigned long long) (x + s->time_offset), (unsigned long long) x, (unsigned long long) y); #endif return y; }
static void pa_mix_s16re_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, int16_t *data, unsigned length) { unsigned channel = 0; length /= sizeof(int16_t); for (; length > 0; length--, data++) { int32_t sum = 0; unsigned i; for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t cv = m->linear[channel].i; if (PA_LIKELY(cv > 0)) sum += pa_mult_s16_volume(PA_INT16_SWAP(*((int16_t*) m->ptr)), cv); m->ptr = (uint8_t*) m->ptr + sizeof(int16_t); } sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); *data = PA_INT16_SWAP((int16_t) sum); if (PA_UNLIKELY(++channel >= channels)) channel = 0; } }
static void fix_current_write(pa_memblockq *bq) { pa_assert(bq); if (PA_UNLIKELY(!bq->blocks)) { bq->current_write = NULL; return; } if (PA_UNLIKELY(!bq->current_write)) bq->current_write = bq->blocks_tail; /* Scan right */ while (PA_UNLIKELY(bq->current_write->index + (int64_t) bq->current_write->chunk.length <= bq->write_index)) if (bq->current_write->next) bq->current_write = bq->current_write->next; else break; /* Scan left */ while (PA_LIKELY(bq->current_write != NULL) && PA_UNLIKELY(bq->current_write->index > bq->write_index)) bq->current_write = bq->current_write->prev; /* At this point current_write will either point at or right of the next block to write data to. It may be NULL in case everything in the queue is still to be played */ }
static void fix_current_read(pa_memblockq *bq) { pa_assert(bq); if (PA_UNLIKELY(!bq->blocks)) { bq->current_read = NULL; return; } if (PA_UNLIKELY(!bq->current_read)) bq->current_read = bq->blocks; /* Scan left */ while (PA_UNLIKELY(bq->current_read->index > bq->read_index)) if (bq->current_read->prev) bq->current_read = bq->current_read->prev; else break; /* Scan right */ while (PA_LIKELY(bq->current_read != NULL) && PA_UNLIKELY(bq->current_read->index + (int64_t) bq->current_read->chunk.length <= bq->read_index)) bq->current_read = bq->current_read->next; /* At this point current_read will either point at or left of the next block to play. It may be NULL in case everything in the queue was already played */ }
void pa_smoother_put(pa_smoother *s, uint64_t x, uint64_t y) { uint64_t ney; double nde; bool is_new; pa_assert(s); /* Fix up x value */ if (s->paused) x = s->pause_time; x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0; is_new = x >= s->ex; if (is_new) { /* First, we calculate the position we'd estimate for x, so that * we can adjust our position smoothly from this one */ estimate(s, x, &ney, &nde); s->ex = x; s->ey = ney; s->de = nde; s->ry = y; } /* Then, we add the new measurement to our history */ add_to_history(s, x, y); /* And determine the average gradient of the history */ s->dp = avg_gradient(s, x); /* And calculate when we want to be on track again */ if (s->smoothing) { s->px = s->ex + s->adjust_time; s->py = s->ry + (uint64_t) llrint(s->dp * (double) s->adjust_time); } else { s->px = s->ex; s->py = s->ry; } s->abc_valid = false; #ifdef DEBUG_DATA pa_log_debug("%p, put(%llu | %llu) = %llu", s, (unsigned long long) (x + s->time_offset), (unsigned long long) x, (unsigned long long) y); #endif }
void pa_log_levelv_meta( pa_log_level_t level, const char*file, int line, const char *func, const char *format, va_list ap) { char *t, *n; int saved_errno = errno; char *bt = NULL; pa_log_target_t _target; pa_log_level_t _maximum_level; unsigned _show_backtrace; pa_log_flags_t _flags; /* We don't use dynamic memory allocation here to minimize the hit * in RT threads */ char text[16*1024], location[128], timestamp[32]; pa_assert(level < PA_LOG_LEVEL_MAX); pa_assert(format); PA_ONCE_BEGIN { init_defaults(); } PA_ONCE_END; _target = target_override_set ? target_override : target; _maximum_level = PA_MAX(maximum_level, maximum_level_override); _show_backtrace = PA_MAX(show_backtrace, show_backtrace_override); _flags = flags | flags_override; if (PA_LIKELY(level > _maximum_level)) { errno = saved_errno; return; } pa_vsnprintf(text, sizeof(text), format, ap); if ((_flags & PA_LOG_PRINT_META) && file && line > 0 && func) pa_snprintf(location, sizeof(location), "[%s:%i %s()] ", file, line, func); else if ((_flags & (PA_LOG_PRINT_META|PA_LOG_PRINT_FILE)) && file) pa_snprintf(location, sizeof(location), "%s: ", pa_path_get_filename(file)); else location[0] = 0; if (_flags & PA_LOG_PRINT_TIME) { static pa_usec_t start, last; pa_usec_t u, a, r; u = pa_rtclock_now(); PA_ONCE_BEGIN { start = u; last = u; } PA_ONCE_END; r = u - last; a = u - start; /* This is not thread safe, but this is a debugging tool only * anyway. */ last = u; pa_snprintf(timestamp, sizeof(timestamp), "(%4llu.%03llu|%4llu.%03llu) ", (unsigned long long) (a / PA_USEC_PER_SEC), (unsigned long long) (((a / PA_USEC_PER_MSEC)) % 1000), (unsigned long long) (r / PA_USEC_PER_SEC), (unsigned long long) (((r / PA_USEC_PER_MSEC)) % 1000)); } else