mrp_attr_t *mrp_attribute_get_value(uint32_t idx, mrp_attr_t *value, uint32_t nattr, mrp_attr_def_t *defs, mrp_attr_value_t *attrs) { mrp_attr_t *vdst; mrp_attr_def_t *adef; MRP_ASSERT(!nattr || (nattr > 0 && defs && attrs), "invalid argument"); MRP_ASSERT(idx < nattr, "invalid argument"); if ((vdst = value) || (vdst = mrp_alloc(sizeof(mrp_attr_t)))) { adef = defs + idx; if (!(adef->access & MRP_RESOURCE_READ)) memset(vdst, 0, sizeof(mrp_attr_t)); else { vdst->name = adef->name; vdst->type = adef->type; vdst->value = attrs[idx]; } } return vdst; }
int16_t *filter_buffer_dup(context_t *ctx, int32_t start, int32_t end, size_t *ret_length) { filter_buf_t *filtbuf; int16_t *dup; size_t len; if (!ctx || !(filtbuf = ctx->filtbuf)) return NULL; if (start < 0 || end < 0 || start >= end || start >= filtbuf->len) return NULL; len = (end - start) * sizeof(int16_t); if (!(dup = mrp_alloc(len))) len = 0; else memcpy(dup, filtbuf->buf + start, len); if (ret_length) *ret_length = len / sizeof(int16_t); return dup; }
void filter_buffer_initialize(context_t *ctx, int32_t bufsiz, int32_t highwater_mark, int32_t silen) { options_t *opts; filter_buf_t *filtbuf; uint32_t rate; int32_t frlen; int32_t hwm; size_t silence; if (!ctx || !(opts = ctx->opts) || !(filtbuf = ctx->filtbuf)) return; rate = opts->rate; frlen = filtbuf->frlen; bufsiz = (bufsiz + (frlen - 1)) / frlen * frlen; hwm = (highwater_mark + (frlen - 1)) / frlen * frlen; silence = INJECTED_SILENCE * frlen; filtbuf->buf = mrp_alloc((bufsiz + silence) * sizeof(int16_t)); filtbuf->max = bufsiz; filtbuf->hwm = hwm; filtbuf->silen = silen; if (ctx->verbose) { mrp_debug("frame length %d samples", filtbuf->frlen); mrp_debug("filter buffer size %u samples (%.3lf sec); " "high-water mark %u samples (%.3lf sec)", filtbuf->max, (double)filtbuf->max / (double)rate, filtbuf->hwm, (double)filtbuf->hwm / (double)rate); mrp_debug("silence detection window %d samples (%.3lf sec)", filtbuf->silen, (double)filtbuf->silen / (double)rate); } }
void mrp_resource_owner_update_zone(uint32_t zoneid, mrp_resource_set_t *reqset, uint32_t reqid) { typedef struct { uint32_t replyid; mrp_resource_set_t *rset; bool move; } event_t; mrp_resource_owner_t oldowners[MRP_RESOURCE_MAX]; mrp_resource_owner_t backup[MRP_RESOURCE_MAX]; mrp_zone_t *zone; mrp_application_class_t *class; mrp_resource_set_t *rset; mrp_resource_t *res; mrp_resource_def_t *rdef; mrp_resource_mgr_ftbl_t *ftbl; mrp_resource_owner_t *owner, *old, *owners; mrp_resource_mask_t mask; mrp_resource_mask_t mandatory; mrp_resource_mask_t grant; mrp_resource_mask_t advice; void *clc, *rsc, *rc; uint32_t rid; uint32_t rcnt; bool force_release; bool changed; bool move; mrp_resource_event_t notify; uint32_t replyid; uint32_t nevent, maxev; event_t *events, *ev, *lastev; MRP_ASSERT(zoneid < MRP_ZONE_MAX, "invalid argument"); zone = mrp_zone_find_by_id(zoneid); MRP_ASSERT(zone, "zone is not defined"); if (!(maxev = mrp_get_resource_set_count())) return; nevent = 0; events = mrp_alloc(sizeof(event_t) * maxev); MRP_ASSERT(events, "Memory alloc failure. Can't update zone"); reset_owners(zoneid, oldowners); manager_start_transaction(zone); rcnt = mrp_resource_definition_count(); clc = NULL; while ((class = mrp_application_class_iterate_classes(&clc))) { rsc = NULL; while ((rset=mrp_application_class_iterate_rsets(class,zoneid,&rsc))) { force_release = false; mandatory = rset->resource.mask.mandatory; grant = 0; advice = 0; rc = NULL; switch (rset->state) { case mrp_resource_acquire: while ((res = mrp_resource_set_iterate_resources(rset, &rc))) { rdef = res->def; rid = rdef->id; owner = get_owner(zoneid, rid); backup[rid] = *owner; if (grant_ownership(owner, zone, class, rset, res)) grant |= ((mrp_resource_mask_t)1 << rid); else { if (owner->rset != rset) force_release |= owner->modal; } } owners = get_owner(zoneid, 0); if ((grant & mandatory) == mandatory && mrp_resource_lua_veto(zone, rset, owners, grant, reqset)) { advice = grant; } else { /* rollback, ie. restore the backed up state */ rc = NULL; while ((res=mrp_resource_set_iterate_resources(rset,&rc))){ rdef = res->def; rid = rdef->id; mask = (mrp_resource_mask_t)1 << rid; owner = get_owner(zoneid, rid); *owner = backup[rid]; if ((grant & mask)) { if ((ftbl = rdef->manager.ftbl) && ftbl->free) ftbl->free(zone, res, rdef->manager.userdata); } if (advice_ownership(owner, zone, class, rset, res)) advice |= mask; } grant = 0; if ((advice & mandatory) != mandatory) advice = 0; mrp_resource_lua_set_owners(zone, owners); } break; case mrp_resource_release: while ((res = mrp_resource_set_iterate_resources(rset, &rc))) { rdef = res->def; rid = rdef->id; owner = get_owner(zoneid, rid); if (advice_ownership(owner, zone, class, rset, res)) advice |= ((mrp_resource_mask_t)1 << rid); } if ((advice & mandatory) != mandatory) advice = 0; break; default: break; } changed = false; move = false; notify = 0; replyid = (reqset == rset && reqid == rset->request.id) ? reqid:0; if (force_release) { move = (rset->state != mrp_resource_release); notify = move ? MRP_RESOURCE_EVENT_RELEASE : 0; changed = move || rset->resource.mask.grant; rset->state = mrp_resource_release; rset->resource.mask.grant = 0; } else { if (grant == rset->resource.mask.grant) { if (rset->state == mrp_resource_acquire && !grant && rset->dont_wait.current) { rset->state = mrp_resource_release; rset->dont_wait.current = rset->dont_wait.client; notify = MRP_RESOURCE_EVENT_RELEASE; move = true; } } else { rset->resource.mask.grant = grant; changed = true; if (rset->state != mrp_resource_release && !grant && rset->auto_release.current) { rset->state = mrp_resource_release; rset->auto_release.current = rset->auto_release.client; notify = MRP_RESOURCE_EVENT_RELEASE; move = true; } } } if (notify) { mrp_resource_set_notify(rset, notify); } if (advice != rset->resource.mask.advice) { rset->resource.mask.advice = advice; changed = true; } if (replyid || changed) { ev = events + nevent++; ev->replyid = replyid; ev->rset = rset; ev->move = move; } } /* while rset */ } /* while class */