Пример #1
0
static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
	bool do_draw = false;
	int exit_code = OPERATOR_RUNNING_MODAL;
	RulerInfo *ruler_info = op->customdata;
	ScrArea *sa = ruler_info->sa;
	ARegion *ar = ruler_info->ar;
	RegionView3D *rv3d = ar->regiondata;

	/* its possible to change  spaces while running the operator [#34894] */
	if (UNLIKELY(ar != CTX_wm_region(C))) {
		exit_code = OPERATOR_FINISHED;
		goto exit;
	}

	switch (event->type) {
		case LEFTMOUSE:
			if (event->val == KM_RELEASE) {
				if (ruler_info->state == RULER_STATE_DRAG) {
					/* rubber-band angle removal */
					RulerItem *ruler_item = ruler_item_active_get(ruler_info);
					if (ruler_item && (ruler_item->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) {
						if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
							ruler_item->flag &= ~RULERITEM_USE_ANGLE;
							do_draw = true;
						}
					}
					if (ruler_info->snap_flag & RULER_SNAP_OK) {
						ruler_info->snap_flag &= ~RULER_SNAP_OK;
						do_draw = true;
					}
					ruler_info->state = RULER_STATE_NORMAL;
				}
			}
			else {
				if (ruler_info->state == RULER_STATE_NORMAL) {

					if (event->ctrl ||
					    /* weak - but user friendly */
					    (ruler_info->items.first == NULL))
					{
						View3D *v3d = CTX_wm_view3d(C);
						const bool use_depth = (v3d->drawtype >= OB_SOLID);

						/* Create new line */
						RulerItem *ruler_item_prev = ruler_item_active_get(ruler_info);
						RulerItem *ruler_item;
						/* check if we want to drag an existing point or add a new one */
						ruler_info->state = RULER_STATE_DRAG;

						ruler_item = ruler_item_add(ruler_info);
						ruler_item_active_set(ruler_info, ruler_item);

						if (use_depth) {
							/* snap the first point added, not essential but handy */
							ruler_item->co_index = 0;
							view3d_ruler_item_mousemove(C, ruler_info, event->mval, false, true);
							copy_v3_v3(ruler_info->drag_start_co, ruler_item->co[ruler_item->co_index]);
						}
						else {
							/* initial depth either previous ruler, view offset */
							if (ruler_item_prev) {
								copy_v3_v3(ruler_info->drag_start_co, ruler_item_prev->co[ruler_item_prev->co_index]);
							}
							else {
								negate_v3_v3(ruler_info->drag_start_co, rv3d->ofs);
							}

							copy_v3_v3(ruler_item->co[0], ruler_info->drag_start_co);
							view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
						}

						copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
						ruler_item->co_index = 2;

						do_draw = true;
					}
					else {
						float mval_fl[2] = {UNPACK2(event->mval)};
						RulerItem *ruler_item_pick;
						int co_index;

						/* select and drag */
						if (view3d_ruler_pick(ruler_info, mval_fl, &ruler_item_pick, &co_index)) {
							if (co_index == -1) {
								if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
									/* Add Center Point */
									ruler_item_active_set(ruler_info, ruler_item_pick);
									ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
									ruler_item_pick->co_index = 1;
									ruler_info->state = RULER_STATE_DRAG;

									/* find the factor */
									{
										float co_ss[2][2];
										float fac;

										ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP);
										ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP);

										fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]);
										CLAMP(fac, 0.0f, 1.0f);

										interp_v3_v3v3(ruler_item_pick->co[1],
										               ruler_item_pick->co[0],
										               ruler_item_pick->co[2], fac);
									}

									/* update the new location */
									view3d_ruler_item_mousemove(C, ruler_info, event->mval,
									                            event->shift != 0, event->ctrl != 0);
									do_draw = true;
								}
							}
							else {
								ruler_item_active_set(ruler_info, ruler_item_pick);
								ruler_item_pick->co_index = co_index;
								ruler_info->state = RULER_STATE_DRAG;

								/* store the initial depth */
								copy_v3_v3(ruler_info->drag_start_co, ruler_item_pick->co[ruler_item_pick->co_index]);

								do_draw = true;
							}
						}
						else {
							exit_code = OPERATOR_PASS_THROUGH;
						}

					}
				}
			}
			break;
		case CKEY:
		{
			if (event->ctrl) {
				RulerItem *ruler_item = ruler_item_active_get(ruler_info);
				if (ruler_item) {
					const int prec = 8;
					char numstr[256];
					Scene *scene = CTX_data_scene(C);
					UnitSettings *unit = &scene->unit;

					ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
					WM_clipboard_text_set((void *) numstr, false);
				}
			}
			break;
		}
		case RIGHTCTRLKEY:
		case LEFTCTRLKEY:
		{
			WM_event_add_mousemove(C);
			break;
		}
		case MOUSEMOVE:
		{
			if (ruler_info->state == RULER_STATE_DRAG) {
				if (view3d_ruler_item_mousemove(C, ruler_info, event->mval,
				                                event->shift != 0, event->ctrl != 0))
				{
					do_draw = true;
				}
			}
			break;
		}
		case ESCKEY:
		{
			do_draw = true;
			exit_code = OPERATOR_CANCELLED;
			break;
		}
		case RETKEY:
		{
			view3d_ruler_to_gpencil(C, ruler_info);
			do_draw = true;
			exit_code = OPERATOR_FINISHED;
			break;
		}
		case DELKEY:
		{
			if (event->val == KM_PRESS) {
				if (ruler_info->state == RULER_STATE_NORMAL) {
					RulerItem *ruler_item = ruler_item_active_get(ruler_info);
					if (ruler_item) {
						RulerItem *ruler_item_other = ruler_item->prev ? ruler_item->prev : ruler_item->next;
						ruler_item_remove(ruler_info, ruler_item);
						ruler_item_active_set(ruler_info, ruler_item_other);
						do_draw = true;
					}
				}
			}
			break;
		}
		default:
			exit_code = OPERATOR_PASS_THROUGH;
			break;

	}

	if (do_draw) {
		view3d_ruler_header_update(sa);

		/* all 3d views draw rulers */
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
	}

exit:
	if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
		WM_cursor_modal_restore(ruler_info->win);

		view3d_ruler_end(C, ruler_info);
		view3d_ruler_free(ruler_info);
		op->customdata = NULL;

		ED_area_headerprint(sa, NULL);
	}

	return exit_code;
}
Пример #2
0
MINLINE float sqrt3f(float f)
{
	if      (UNLIKELY(f == 0.0f)) return 0.0f;
	else if (UNLIKELY(f <  0.0f)) return -(float)(exp(log(-f) / 3.0));
	else                          return  (float)(exp(log( f) / 3.0));
}
Пример #3
0
MINLINE float saacos(float fac)
{
	if      (UNLIKELY(fac <= -1.0f)) return (float)M_PI;
	else if (UNLIKELY(fac >=  1.0f)) return 0.0f;
	else                             return acosf(fac);
}
Пример #4
0
int bowed(CSOUND *csound, BOWED *p)
{
    MYFLT       *ar = p->ar;
    uint32_t offset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT       amp = (*p->amp)*AMP_RSCALE; /* Normalise */
    MYFLT       maxVel;
    int         freq_changed = 0;

    if (amp != p->lastamp) {
      p->maxVelocity = FL(0.03) + (FL(0.2) * amp);
      p->lastamp = amp;
    }
    maxVel = p->maxVelocity;
    if (p->lastpress != *p->bowPress)
      p->bowTabl.slope = p->lastpress = *p->bowPress;

                                /* Set Frequency if changed */
    if (p->lastfreq != *p->frequency) {
      /* delay - approx. filter delay */
      if (p->limit<=*p->frequency)
        p->lastfreq = *p->frequency;
      else {
        p->lastfreq = p->limit;
        csound->Warning(csound, Str("frequency too low, set to minimum"));
      }
      p->baseDelay = CS_ESR / p->lastfreq - FL(4.0);
      freq_changed = 1;
    }
    if (p->lastbeta != *p->betaRatio ||
        freq_changed) {         /* Reset delays if changed */
      p->lastbeta = *p->betaRatio;
      DLineL_setDelay(&p->bridgeDelay, /* bow to bridge length */
                      p->baseDelay * p->lastbeta);
      DLineL_setDelay(&p->neckDelay, /* bow to nut (finger) length */
                      p->baseDelay *(FL(1.0) - p->lastbeta));
    }
    p->v_rate = *p->vibFreq * p->vibr->flen * csound->onedsr;
    if (p->kloop>0 && p->h.insdshead->relesing) p->kloop=1;
    if ((--p->kloop) == 0) {
      ADSR_setDecayRate(csound, &p->adsr, (FL(1.0) - p->adsr.value) * FL(0.005));
      p->adsr.target = FL(0.0);
      p->adsr.rate = p->adsr.releaseRate;
      p->adsr.state = RELEASE;
    }

    if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
    }
    for (n=offset;n<nsmps;n++) {
      MYFLT     bowVelocity;
      MYFLT     bridgeRefl=FL(0.0), nutRefl=FL(0.0);
      MYFLT     newVel=FL(0.0), velDiff=FL(0.0), stringVel=FL(0.0);
      MYFLT     lastOutput;

      bowVelocity = maxVel * ADSR_tick(&p->adsr);

      /* Bridge Reflection      */
      bridgeRefl = - OnePole_tick(&p->reflFilt, p->bridgeDelay.lastOutput);
      nutRefl = - p->neckDelay.lastOutput;       /* Nut Reflection  */
      stringVel = bridgeRefl + nutRefl;          /* Sum is String Velocity */
      velDiff = bowVelocity - stringVel;         /* Differential Velocity  */
                                                 /* Non-Lin Bow Function   */
      newVel = velDiff * BowTabl_lookup(csound, &p->bowTabl, velDiff);
      DLineL_tick(&p->neckDelay, bridgeRefl + newVel);  /* Do string       */
      DLineL_tick(&p->bridgeDelay, nutRefl + newVel);   /*   propagations  */

      if (*p->vibAmt > FL(0.0)) {
        int32    temp;
        MYFLT   temp_time, alpha;
                                /* Tick on vibrato table */
        p->v_time += p->v_rate;              /*  Update current time    */
        while (p->v_time >= p->vibr->flen)   /*  Check for end of sound */
          p->v_time -= p->vibr->flen;        /*  loop back to beginning */
        while (p->v_time < FL(0.0))          /*  Check for end of sound */
          p->v_time += p->vibr->flen;        /*  loop back to beginning */

        temp_time = p->v_time;

#ifdef phase_offset
        if (p->v_phaseOffset != FL(0.0)) {
          temp_time += p->v_phaseOffset;     /*  Add phase offset       */
          while (temp_time >= p->vibr->flen) /*  Check for end of sound */
            temp_time -= p->vibr->flen;      /*  loop back to beginning */
          while (temp_time < FL(0.0))        /*  Check for end of sound */
            temp_time += p->vibr->flen;      /*  loop back to beginning */
        }
#endif
        temp = (int32) temp_time;    /*  Integer part of time address    */
                                /*  fractional part of time address */
        alpha = temp_time - (MYFLT)temp;
        p->v_lastOutput = p->vibr->ftable[temp]; /* Do linear interpolation */
                        /*  same as alpha*data[temp+1] + (1-alpha)data[temp] */
        p->v_lastOutput = p->v_lastOutput +
          (alpha * (p->vibr->ftable[temp+1] - p->v_lastOutput));
                                /* End of vibrato tick */

       DLineL_setDelay(&p->neckDelay,
                       (p->baseDelay * (FL(1.0) - p->lastbeta)) +
                       (p->baseDelay * *p->vibAmt * p->v_lastOutput));
      }
      else
       DLineL_setDelay(&p->neckDelay,
                       (p->baseDelay * (FL(1.0) - p->lastbeta)));

      lastOutput = BiQuad_tick(&p->bodyFilt, p->bridgeDelay.lastOutput);

      ar[n] = lastOutput*AMP_SCALE * amp *FL(1.8);
    }
    return OK;
}
Пример #5
0
// throws if establishing a dependency from this to child would form a cycle
void c_BlockableWaitHandle::detectCycle(c_WaitableWaitHandle* child) const {
  if (UNLIKELY(isDescendantOf(child))) {
    Object e(createCycleException(child));
    throw e;
  }
}
Пример #6
0
/**
 * Find n nearest returns number of points found, with results in nearest.
 * Normal is optional, but if given will limit results to points in normal direction from co.
 *
 * \param r_nearest: An array of nearest, sized at least \a n.
 */
int BLI_kdtree_find_nearest_n__normal(
        const KDTree *tree, const float co[3], const float nor[3],
        KDTreeNearest r_nearest[],
        uint n)
{
	const KDTreeNode *nodes = tree->nodes;
	const KDTreeNode *root;
	uint *stack, defaultstack[KD_STACK_INIT];
	float cur_dist;
	uint totstack, cur = 0;
	uint i, found = 0;

#ifdef DEBUG
	BLI_assert(tree->is_balanced == true);
#endif

	if (UNLIKELY((tree->root == KD_NODE_UNSET) || n == 0))
		return 0;

	stack = defaultstack;
	totstack = KD_STACK_INIT;

	root = &nodes[tree->root];

	cur_dist = squared_distance(root->co, co, nor);
	add_nearest(r_nearest, &found, n, root->index, cur_dist, root->co);

	if (co[root->d] < root->co[root->d]) {
		if (root->right != KD_NODE_UNSET)
			stack[cur++] = root->right;
		if (root->left != KD_NODE_UNSET)
			stack[cur++] = root->left;
	}
	else {
		if (root->left != KD_NODE_UNSET)
			stack[cur++] = root->left;
		if (root->right != KD_NODE_UNSET)
			stack[cur++] = root->right;
	}

	while (cur--) {
		const KDTreeNode *node = &nodes[stack[cur]];

		cur_dist = node->co[node->d] - co[node->d];

		if (cur_dist < 0.0f) {
			cur_dist = -cur_dist * cur_dist;

			if (found < n || -cur_dist < r_nearest[found - 1].dist) {
				cur_dist = squared_distance(node->co, co, nor);

				if (found < n || cur_dist < r_nearest[found - 1].dist)
					add_nearest(r_nearest, &found, n, node->index, cur_dist, node->co);

				if (node->left != KD_NODE_UNSET)
					stack[cur++] = node->left;
			}
			if (node->right != KD_NODE_UNSET)
				stack[cur++] = node->right;
		}
		else {
			cur_dist = cur_dist * cur_dist;

			if (found < n || cur_dist < r_nearest[found - 1].dist) {
				cur_dist = squared_distance(node->co, co, nor);
				if (found < n || cur_dist < r_nearest[found - 1].dist)
					add_nearest(r_nearest, &found, n, node->index, cur_dist, node->co);

				if (node->right != KD_NODE_UNSET)
					stack[cur++] = node->right;
			}
			if (node->left != KD_NODE_UNSET)
				stack[cur++] = node->left;
		}
		if (UNLIKELY(cur + 3 > totstack)) {
			stack = realloc_nodes(stack, &totstack, defaultstack != stack);
		}
	}

	for (i = 0; i < found; i++)
		r_nearest[i].dist = sqrtf(r_nearest[i].dist);

	if (stack != defaultstack)
		MEM_freeN(stack);

	return (int)found;
}
Пример #7
0
int clarin(CSOUND *csound, CLARIN *p)
{
    MYFLT *ar = p->ar;
    uint32_t offset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT amp = (*p->amp)*AMP_RSCALE; /* Normalise */
    MYFLT nGain = *p->noiseGain;
    int v_len = (int)p->vibr->flen;
    MYFLT *v_data = p->vibr->ftable;
    MYFLT vibGain = *p->vibAmt;
    MYFLT vTime = p->v_time;

    if (p->envelope.rate==FL(0.0)) {
      p->envelope.rate =  amp /(*p->attack*CS_ESR);
      p->envelope.value = p->envelope.target = FL(0.55) + amp*FL(0.30);
    }
    p->outputGain = amp + FL(0.001);
    DLineL_setDelay(&p->delayLine, /* length - approx filter delay */
        (CS_ESR/ *p->frequency) * FL(0.5) - FL(1.5));
    p->v_rate = *p->vibFreq * p->vibr->flen * csound->onedsr;
                                /* Check to see if into decay yet */
    if (p->kloop>0 && p->h.insdshead->relesing) p->kloop=1;
    if ((--p->kloop) == 0) {
      p->envelope.state = 1;  /* Start change */
      p->envelope.rate = p->envelope.value / (*p->dettack * CS_ESR);
      p->envelope.target =  FL(0.0);
#ifdef BETA
      csound->Message(csound, "Set off phase time = %f Breath v,r = %f, %f\n",
                              (MYFLT) CS_KCNT * CS_ONEDKR,
                              p->envelope.value, p->envelope.rate);
#endif
    }
    if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
    }
    for (n=offset;n<nsmps;n++) {
      MYFLT   pressureDiff;
      MYFLT   breathPressure;
      int32    temp;
      MYFLT   temp_time, alpha;
      MYFLT   nextsamp;
      MYFLT   v_lastOutput;
      MYFLT   lastOutput;

      breathPressure = Envelope_tick(&p->envelope);
      breathPressure += breathPressure * nGain * Noise_tick(csound,&p->noise);
                                     /* Tick on vibrato table   */
      vTime += p->v_rate;            /*  Update current time    */
      while (vTime >= v_len)         /*  Check for end of sound */
        vTime -= v_len;              /*  loop back to beginning */
      while (vTime < FL(0.0))        /*  Check for end of sound */
        vTime += v_len;              /*  loop back to beginning */

      temp_time = vTime;

#ifdef have_phase
      if (p->v_phaseOffset != FL(0.0)) {
        temp_time += p->v_phaseOffset;   /*  Add phase offset       */
        while (temp_time >= v_len)       /*  Check for end of sound */
          temp_time -= v_len;            /*  loop back to beginning */
        while (temp_time < FL(0.0))      /*  Check for end of sound */
          temp_time += v_len;            /*  loop back to beginning */
      }
#endif
      temp = (int32) temp_time;    /*  Integer part of time address    */
                                   /*  fractional part of time address */
      alpha = temp_time - (MYFLT)temp;
      v_lastOutput = v_data[temp]; /* Do linear interpolation */
      /*  same as alpha*data[temp+1] + (1-alpha)data[temp] */
      v_lastOutput += (alpha * (v_data[temp+1] - v_lastOutput));
      /* End of vibrato tick */
      breathPressure += breathPressure * vibGain * v_lastOutput;
      pressureDiff = OneZero_tick(&p->filter, /* differential pressure  */
                                  DLineL_lastOut(&p->delayLine));
      pressureDiff = (-FL(0.95)*pressureDiff) - breathPressure;
      /* of reflected and mouth */
      nextsamp = pressureDiff * ReedTabl_LookUp(&p->reedTable,pressureDiff);
      nextsamp =  breathPressure + nextsamp;
      /* perform scattering in economical way */
      lastOutput = DLineL_tick(&p->delayLine, nextsamp);
      lastOutput *= p->outputGain;
      ar[n] = lastOutput*AMP_SCALE;
    }
    p->v_time = vTime;

    return OK;
}
static void V8TestInterfaceNamedConstructorConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    if (!info.IsConstructCall()) {
        V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::constructorNotCallableAsFunction("Audio"));
        return;
    }

    if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExistingObject) {
        v8SetReturnValue(info, info.Holder());
        return;
    }
    ExceptionState exceptionState(ExceptionState::ConstructionContext, "TestInterfaceNamedConstructor", info.Holder(), info.GetIsolate());
    if (UNLIKELY(info.Length() < 1)) {
        setMinimumArityTypeError(exceptionState, 1, info.Length());
        exceptionState.throwIfNeeded();
        return;
    }
    V8StringResource<> stringArg;
    bool defaultUndefinedOptionalBooleanArg;
    int defaultUndefinedOptionalLongArg;
    V8StringResource<> defaultUndefinedOptionalStringArg;
    V8StringResource<> defaultNullStringOptionalstringArg;
    V8StringResource<> optionalStringArg;
    {
        int numArgsPassed = info.Length();
        while (numArgsPassed > 0) {
            if (!info[numArgsPassed - 1]->IsUndefined())
                break;
            --numArgsPassed;
        }
        stringArg = info[0];
        if (!stringArg.prepare())
            return;
        defaultUndefinedOptionalBooleanArg = toBoolean(info.GetIsolate(), info[1], exceptionState);
        if (exceptionState.throwIfNeeded())
            return;
        defaultUndefinedOptionalLongArg = toInt32(info.GetIsolate(), info[2], NormalConversion, exceptionState);
        if (exceptionState.throwIfNeeded())
            return;
        defaultUndefinedOptionalStringArg = info[3];
        if (!defaultUndefinedOptionalStringArg.prepare())
            return;
        if (!info[4]->IsUndefined()) {
            defaultNullStringOptionalstringArg = info[4];
            if (!defaultNullStringOptionalstringArg.prepare())
                return;
        } else {
            defaultNullStringOptionalstringArg = nullptr;
        }
        if (UNLIKELY(numArgsPassed <= 5)) {
            Document& document = *toDocument(currentExecutionContext(info.GetIsolate()));
            TestInterfaceNamedConstructor* impl = TestInterfaceNamedConstructor::createForJSConstructor(document, stringArg, defaultUndefinedOptionalBooleanArg, defaultUndefinedOptionalLongArg, defaultUndefinedOptionalStringArg, defaultNullStringOptionalstringArg, exceptionState);
            if (exceptionState.hadException()) {
                exceptionState.throwIfNeeded();
                return;
            }
            v8::Local<v8::Object> wrapper = info.Holder();
            wrapper = impl->associateWithWrapper(info.GetIsolate(), &V8TestInterfaceNamedConstructorConstructor::wrapperTypeInfo, wrapper);
            v8SetReturnValue(info, wrapper);
            return;
        }
        optionalStringArg = info[5];
        if (!optionalStringArg.prepare())
            return;
    }
    Document& document = *toDocument(currentExecutionContext(info.GetIsolate()));
    TestInterfaceNamedConstructor* impl = TestInterfaceNamedConstructor::createForJSConstructor(document, stringArg, defaultUndefinedOptionalBooleanArg, defaultUndefinedOptionalLongArg, defaultUndefinedOptionalStringArg, defaultNullStringOptionalstringArg, optionalStringArg, exceptionState);
    if (exceptionState.hadException()) {
        exceptionState.throwIfNeeded();
        return;
    }
    v8::Local<v8::Object> wrapper = info.Holder();
    wrapper = impl->associateWithWrapper(info.GetIsolate(), &V8TestInterfaceNamedConstructorConstructor::wrapperTypeInfo, wrapper);
    v8SetReturnValue(info, wrapper);
}
Пример #9
0
static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
{
    int         cntdev, devnum, opendevs, i;
    PmEvent     buffer;
    PmError     retval;
    PmDeviceInfo *info;
//     PortMidiStream *midistream;
    pmall_data *data = NULL;
    pmall_data *next = NULL;


    if (start_portmidi(csound) != 0)
      return -1;
    /* check if there are any devices available */
    cntdev = portMidi_getDeviceCount(0);
    portMidi_listDevices(csound, 0);
    /* look up device in list */
    if (dev == NULL || dev[0] == '\0')
      devnum =
        portMidi_getPackedDeviceID((int)Pm_GetDefaultInputDeviceID(), 0);
    else if (UNLIKELY((dev[0] < '0' || dev[0] > '9') && dev[0] != 'a')) {
      portMidiErrMsg(csound,
                     Str("error: must specify a device number (>=0) or"
                         " 'a' for all, not a name"));
      return -1;
    }
    else if (dev[0] != 'a') {
      devnum = (int)atoi(dev);
      if (UNLIKELY(devnum < 0 || devnum >= cntdev)) {
        portMidiErrMsg(csound, Str("error: device number is out of range"));
        return -1;
      }
    }
    else {
    // allow to proceed if 'a' is given even if there are no MIDI devices
      devnum = -1;
    }

    if (UNLIKELY(cntdev < 1 && (dev==NULL || dev[0] != 'a'))) {
      return portMidiErrMsg(csound, Str("no input devices are available"));
    }
    opendevs = 0;
    for (i = 0; i < cntdev; i++) {
      if (devnum == i || devnum == -1) {
        if (opendevs == 0) {
          data = (pmall_data *) malloc(sizeof(pmall_data));
          next = data;
          data->next = NULL;
          opendevs++;
        }
        else {
          next->next = (pmall_data *) malloc(sizeof(pmall_data));
          next = next->next;
          next->next = NULL;
          opendevs++;
        }
        info = portMidi_getDeviceInfo(i, 0);
        if (info->interf != NULL)
          csound->Message(csound,
                          Str("PortMIDI: Activated input device %d: '%s' (%s)\n"),
                          i, info->name, info->interf);
        else
          csound->Message(csound,
                          Str("PortMIDI: Activated input device %d: '%s'\n"),
                          i, info->name);
        retval = Pm_OpenInput(&next->midistream,
                 (PmDeviceID) portMidi_getRealDeviceID(i, 0),
                         NULL, 512L, (PmTimeProcPtr) NULL, NULL);
        if (UNLIKELY(retval != pmNoError)) {
          // Prevent leaking memory from "data"
          if (data) {
            next = data->next;
            free(data);
          }
          return portMidiErrMsg(csound, Str("error opening input device %d: %s"),
                                          i, Pm_GetErrorText(retval));
        }
          /* only interested in channel messages (note on, control change, etc.) */
        /* GAB: fixed for portmidi v.23Aug06 */
        Pm_SetFilter(next->midistream, (PM_FILT_ACTIVE | PM_FILT_SYSEX));
        /* empty the buffer after setting filter */
        while (Pm_Poll(next->midistream) == TRUE) {
          Pm_Read(next->midistream, &buffer, 1);
        }
      }
    }
    *userData = (void*) data;
    /* report success */
    return 0;
}
Пример #10
0
int32_t
vsw16_sse2_forward(vsw16_query_t *query, const uint8_t *target, int32_t tlen, 
                   int32_t query_start_clip, int32_t query_end_clip,
                   vsw_opt_t *opt, int16_t *query_end, int16_t *target_end,
                   int32_t direction, int32_t *overflow, int32_t *n_best, int32_t score_thr)
{
  int32_t slen, i, j, k, sum = 0;
#ifdef VSW_DEBUG
  int32_t l;
#endif
  uint16_t cmp;
  vsw16_int_t gmax, best;
  vsw16_int_t zero, imin = 0, imax = 0;
  __m128i zero_mm, zero_start_mm, negative_infinity_mm, positive_infinity_mm, reduce_mm;
  __m128i pen_gapoe, pen_gape, *H0, *H1, *E;

  // initialization
  // normalize these
  zero = query->zero_aln_score; // where the normalized zero alignment score occurs
  negative_infinity_mm = __vsw16_mm_set1_epi16(query->min_aln_score); // the minimum possible value
  positive_infinity_mm = __vsw16_mm_set1_epi16(query->max_aln_score); // the minimum possible value
  score_thr += zero; // for the scoring threshold
  // these are not normalized
  pen_gapoe = __vsw16_mm_set1_epi16(opt->pen_gapo + opt->pen_gape); // gap open penalty
  pen_gape = __vsw16_mm_set1_epi16(opt->pen_gape); // gap extend penalty
  zero_mm = __vsw16_mm_set1_epi16(zero); // where the normalized zero alignment score occurs
  zero_start_mm = __vsw16_mm_set1_epi16(zero); // where the normalized zero alignment score occurs
  gmax = vsw16_min_value;
  best = vsw16_min_value;
  if(NULL != n_best) (*n_best) = 0;
  reduce_mm = __vsw16_mm_set1_epi16(vsw16_mid_value);
  // vectors
  H0 = query->H0; 
  H1 = query->H1; 
  E = query->E; 
  slen = query->slen;
  if(NULL != overflow) *overflow = 0;
#ifdef VSW_DEBUG
  fprintf(stderr, "qlen=%d tlen=%d\n", query->qlen, tlen);
  fprintf(stderr, "query_start_clip=%d query_end_clip=%d\n",
          query_start_clip, query_end_clip);
#endif

  // select query end only
  // check stripe #: __vsw16_query_index_to_stripe_number(query->qlen, slen) 
  // check byte # __vsw16_query_index_to_byte_number(query->qlen, slen)

  if(0 == query_start_clip) {
      __m128i f;
      // Set start
      for(j = 0; j < slen; j++) {
          // initialize E to negative infinity 
          __vsw_mm_store_si128(E + j, negative_infinity_mm); // E(0,j)
      }
      // NB: setting the start == 0 will be done later
      // set the leading insertions 
      f = __vsw16_mm_set1_epi16(query->min_aln_score);
      f = __vsw16_mm_insert_epi16(f, zero, 0); 
      for(j = 0; j < vsw16_values_per_128_bits; ++j) {
          f = __vsw16_mm_insert(f , -opt->pen_gapo + -opt->pen_gape + (-opt->pen_gape * slen * j) + zero, j);
      }
      for(j = 0; j < slen; j++) {
          f = __vsw16_mm_subs_epi16(f, pen_gape); // f=F(i,j)-pen_gape
          f = __vsw16_mm_max_epi16(f, negative_infinity_mm); // bound with -inf
          __vsw_mm_store_si128(H0 + ((slen + j - 1) % slen), f); // H(0,j)
      }
  }
  else {
      // Initialize all zeros
      for(i = 0; i < slen; ++i) {
          __vsw_mm_store_si128(E + i, zero_mm);
          __vsw_mm_store_si128(H0 + i, zero_mm);
      }
  }

  // the core loop
  for(i = 0, sum = 0; i < tlen; i++) { // for each base in the target
      __m128i e, h, f, g, max, min, *S;

      max = __vsw16_mm_set1_epi16(query->min_aln_score); // max is negative infinity
      min = __vsw16_mm_set1_epi16(query->max_aln_score); // min is positive infinity
      S = query->query_profile + target[i] * slen; // s is the 1st score vector

      // load H(i-1,-1)
      h = __vsw_mm_load_si128(H0 + slen - 1); // the last stripe, which holds the j-1 
      if(UNLIKELY(0 < i)) { // only if we have previous results
          h = __vsw_mm_slli_si128(h, vsw16_shift_bytes); // shift left since x64 is little endian
      }
      h = __vsw16_mm_insert_epi16(h, zero, 0);

      // e does not need to be set

      // set F to -inf
      f = __vsw16_mm_set1_epi16(query->min_aln_score);
      // leading insertions
      g = __vsw16_mm_set1_epi16(query->min_aln_score);
      if(0 == query_start_clip) { 
          g = __vsw16_mm_set1_epi16(query->min_aln_score);
          g = __vsw16_mm_insert_epi16(g, -opt->pen_gapo + opt->pen_gape + zero, 0);
          for(j = 1; LIKELY(j < vsw16_values_per_128_bits); j++) {
              // NB: do not include the gap extend, that will be added below
              // BEFORE considering H
              g = __vsw16_mm_insert(g, -opt->pen_gapo + (-opt->pen_gape * (j * slen - 1)) + zero, j);
          }
      }

      for(j = 0; LIKELY(j < slen); ++j) { // for each stripe in the query
          // NB: at the beginning, 
          // h=H(i-1,j-1)
          // e=E(i,j)
          // f=F(i,j)
          /* SW cells are computed in the following order:
           *   H(i,j)   = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
           *   E(i+1,j) = max{H(i,j)-q, E(i,j)-r}
           *   F(i,j+1) = max{H(i,j)-q, F(i,j)-r}
           */
          if(1 == query_start_clip) {
              // start anywhere within the query, though not before the start
              h = __vsw16_mm_max_epi16(h, zero_start_mm);  
          }
          else {
              g = __vsw16_mm_subs_epi16(g, pen_gape); // leading insertion
#ifdef VSW_DEBUG 
              /*
                 fprintf(stderr, "h i=%d j=%d", i, j);
                 for(k = 0; k < vsw16_values_per_128_bits; k++) { // for each start position in the stripe
                 fprintf(stderr, " (%d,%d)", 
                 ((vsw16_int_t*)(&h))[k] - zero,
                 ((vsw16_int_t*)(&g))[k] - zero);
                 }
                 fprintf(stderr, "\n");
                 */
#endif
              h = __vsw16_mm_max_epi16(h, g);
          }
          // compute H(i,j); 
#ifdef VSW_DEBUG 
          /*
             __m128i s = __vsw_mm_load_si128(S + j);
             fprintf(stderr, "s i=%d j=%d", i, j);
             for(k = 0; k < vsw16_values_per_128_bits; k++) { // for each start position in the stripe
             fprintf(stderr, " %4d", ((vsw16_int_t*)(&s))[k]);
             }
             fprintf(stderr, "\n");
             fprintf(stderr, "h i=%d j=%d", i, j);
             for(k = 0; k < vsw16_values_per_128_bits; k++) { // for each start position in the stripe
             fprintf(stderr, " %4d", ((vsw16_int_t*)(&h))[k] - zero);
             }
             fprintf(stderr, "\n");
             */
#endif
          h = __vsw16_mm_adds_epi16(h, __vsw_mm_load_si128(S + j)); // h=H(i-1,j-1)+S(i,j)
          e = __vsw_mm_load_si128(E + j); // e=E(i,j)
          h = __vsw16_mm_max_epi16(h, e); // h=H(i,j) = max{E(i,j), H(i-1,j-1)+S(i,j)}
          h = __vsw16_mm_max_epi16(h, f); // h=H(i,j) = max{max{E(i,j), H(i-1,j-1)+S(i,j)}, F(i,j)}
          h = __vsw16_mm_max_epi16(h, negative_infinity_mm); // bound with -inf
          max = __vsw16_mm_max_epi16(max, h); // save the max values in this stripe versus the last
          min = __vsw16_mm_min_epi16(min, h); // save the max values in this stripe versus the last
          __vsw_mm_store_si128(H1 + j, h); // save h to H(i,j)
          // next, compute E(i+1,j)
          h = __vsw16_mm_subs_epi16(h, pen_gapoe); // h=H(i,j)-pen_gapoe
          e = __vsw16_mm_subs_epi16(e, pen_gape); // e=E(i,j)-pen_gape
          e = __vsw16_mm_max_epi16(e, h); // e=E(i+1,j) = max{E(i,j)-pen_gape, H(i,j)-pen_gapoe}
          e = __vsw16_mm_max_epi16(e, negative_infinity_mm); // bound with -inf
          __vsw_mm_store_si128(E + j, e); // save e to E(i+1,j)
          // now compute F(i,j+1)
          //h = __vsw16_mm_subs_epi16(h, pen_gapoe); // h=H(i,j)-pen_gapoe
          f = __vsw16_mm_subs_epi16(f, pen_gape); // f=F(i,j)-pen_gape
          f = __vsw16_mm_max_epi16(f, h); // f=F(i,j+1) = max{F(i,j)-pen_gape, H(i,j)-pen_gapoe}
          f = __vsw16_mm_max_epi16(f, negative_infinity_mm); // bound with -inf
          // get H(i-1,j) and prepare for the next j
          h = __vsw_mm_load_si128(H0 + j); // h=H(i-1,j)
      }

      // NB: we do not need to set E(i,j) as we disallow adjacent insertion and then deletion
      // iterate through each value stored in a stripe
      f = __vsw16_mm_set1_epi16(query->min_aln_score);
      // we require at most 'vsw16_values_per_128_bits' iterations to guarantee F propagation
      for(k = 0; LIKELY(k < vsw16_values_per_128_bits); ++k) { // this block mimics SWPS3; NB: H(i,j) updated in the lazy-F loop cannot exceed max
          f = __vsw_mm_slli_si128(f, vsw16_shift_bytes); // since x86 is little endian
          f = __vsw16_mm_insert_epi16(f, query->min_aln_score, 0); // set F(i-1,-1)[0] as negative infinity (normalized)
          for(j = 0; LIKELY(j < slen); ++j) { 
              h = __vsw_mm_load_si128(H1 + j); // h=H(i,j)
              h = __vsw16_mm_max_epi16(h, f); // h=H(i,j) = max{H(i,j), F(i,j)}
              h = __vsw16_mm_max_epi16(h, negative_infinity_mm); // bound with -inf
              __vsw_mm_store_si128(H1 + j, h); // save h to H(i,j) 
              h = __vsw16_mm_subs_epi16(h, pen_gapoe); // h=H(i,j)-gapo
              f = __vsw16_mm_subs_epi16(f, pen_gape); // f=F(i,j)-pen_gape
              f = __vsw16_mm_max_epi16(f, negative_infinity_mm); // bound with -inf
              // check to see if h could have been updated by f?
              // NB: the comparison below will have some false positives, in
              // other words h == f a priori, but this is rare.
              cmp = __vsw16_mm_movemask_epi16(__vsw16_mm_cmpgt_epi16(f, h));
              if (LIKELY(cmp = 0x0000)) goto end_loop; // ACK: goto statement
              f = __vsw16_mm_max_epi16(f, h); // f=F(i,j+1) = max{F(i,j)-pen_gape, H(i,j)-pen_gapoe}
          }
      }
end_loop:
#ifdef VSW_DEBUG 
      fprintf(stderr, "H1 i=%d target[i]=%d", i, target[i]);
      for(k = l = 0; k < vsw16_values_per_128_bits; k++) { // for each start position in the stripe
          for(j = 0; j < slen; j++, l++) {
              fprintf(stderr, " %d:%d", l, ((vsw16_int_t*)(H1 + j))[k] - zero);
          }
      }
      fprintf(stderr, "\n");
#endif
      __vsw16_max(imax, max); // imax is the maximum number in max
      if(query->max_aln_score - query->max_edit_score < imax) { // overflow
          if(NULL != overflow) *overflow = 1;
          return vsw16_min_value;
      }
      if(imax > gmax) { 
          gmax = imax; // global maximum score 
      }
      if(score_thr <= imax && best <= imax) { // potential best score
          vsw16_int_t *t;
          //int32_t save_score = 0;
          //if(imax > best || (1 == direction && imax == best)) save_score = 1;
          if(query_end_clip == 0) { // check the last
              j = (query->qlen-1) % slen; // stripe
              k = (query->qlen-1) / slen; // byte
              t = (vsw16_int_t*)(H1 + j);
#ifdef VSW_DEBUG 
              fprintf(stderr, "j=%d k=%d slen=%d qlen=%d best=%d pot=%d\n", j, k, slen, query->qlen, best-zero, t[k]-zero);
#endif
              if(NULL != n_best) {
                  if(best == (int32_t)t[k]) { // duplicate best score
                      (*n_best)++;
                  }
                  else if(best < (int32_t)t[k]) {
                      (*n_best) = 1;
                  }
              }
              if(1 == vsw16_sse2_dir_cmp(best, (*query_end), (*target_end), (int32_t)t[k], query->qlen-1, i, direction)) {
                  (*query_end) = query->qlen-1;
                  (*target_end) = i;
                  best = t[k];
#ifdef VSW_DEBUG 
                  fprintf(stderr, "FOUND A i=%d query->qlen-1=%d query_end=%d target_end=%d best=%d\n", i, query->qlen-1, *query_end, *target_end, best-zero);
#endif
              }
          }
          else { // check all
              int32_t found_best = 0;
              t = (vsw16_int_t*)H1;
              /*
              if(best < imax || (best == imax && 1 == direction)) {
                  *query_end = -1;
              }
              */
              for(j = 0; LIKELY(j < slen); ++j) { // for each stripe in the query
                  for(k = 0; k < vsw16_values_per_128_bits; k++, t++) { // for each cell in the stripe
                      if(NULL != n_best) {
                          if(best == (int32_t)*t) { // duplicate best score
                              (*n_best)++;
                          }
                          else if(best < (int32_t)*t) {
                              (*n_best) = 1;
                          }
                      }
                      int32_t cur_qe = j + ((k & (vsw16_values_per_128_bits-1)) * slen);
                      if(1 == vsw16_sse2_dir_cmp(best, (*query_end), (*target_end), (int32_t)*t, cur_qe, i, direction)) {
                          found_best = 1;
                          best = *t;
                          (*query_end) = cur_qe;
                          (*target_end) = i;
#ifdef VSW_DEBUG 
                          fprintf(stderr, "FOUND B j=%d k=%d query_end=%d best=%d\n", j, k, *query_end, best-zero);
#endif
                      }
                  }
              }
              if(1 == found_best && -1 == *query_end) {
                  if(-1 == *query_end) {
                      fprintf(stderr, "bug encountered\n");
                      exit(1);
                  }
              }
              //fprintf(stderr, "FOUND B i=%d imax=%d best=%d query_end=%d target_end=%d\n", i, imax-zero, best-zero, *query_end, *target_end);
          }
      }
      if(query->max_aln_score - query->max_edit_score < imax) { // overflow
          if(NULL != overflow) {
              *overflow = 1;
              return vsw16_min_value;
          }
          // When overflow is going to happen, subtract vsw16_mid_value from all scores. This heuristic
          // may miss the best alignment, but in practice this should happen very rarely.
          sum += vsw16_mid_value; 
          if(query->min_aln_score + vsw16_mid_value < gmax) gmax -= vsw16_mid_value;
          else gmax = query->min_aln_score;
          for(j = 0; LIKELY(j < slen); ++j) {
              h = __vsw16_mm_subs_epi16(__vsw_mm_load_si128(H1 + j), reduce_mm);
              __vsw_mm_store_si128(H1 + j, h);
              e = __vsw16_mm_subs_epi16(__vsw_mm_load_si128(E + j), reduce_mm);
              __vsw_mm_store_si128(E + j, e);
          }
      }
      // check for underflow
      __vsw16_min(imin, min); // imin is the minimum number in min
      if(imin < vsw16_min_value - query->min_edit_score) {
          fprintf(stderr, "bug encountered\n");
          exit(1);
      }
      S = H1; H1 = H0; H0 = S; // swap H0 and H1
  }
  if(vsw16_min_value == best) {
      (*query_end) = (*target_end) = -1;
      return best;
  }
  return best + sum - zero;
}
Пример #11
0
char *
realpathat2(int dirfd, char *dirfdpath, const char *name, char *resolved,
        struct stat *st)
{
    char *rpath, *dest, extra_buf[PATH_MAX];
    const char *start, *end, *rpath_limit;
    int num_links = 0;
    ptrdiff_t dirfdlen;
    char *pathat;

    if (UNLIKELY(name == NULL)) {
        /* As per Single Unix Specification V2 we must return an error if
           either parameter is a null pointer.  We extend this to allow
           the RESOLVED parameter to be NULL in case the we are expected to
           allocate the room for the return value.  */
        errno = EINVAL;
        return NULL;
    }

    /* If any of the additional parameters are null, or if the name to
       resolve the real path is an absolute path, use the standard
       realpath() routine. */
    if (UNLIKELY(dirfd < 0 || dirfdpath == NULL || name[0] == '/'))
        return realpath(name, resolved);

    if (name[0] == '\0') {
        if (UNLIKELY(fstat(dirfd, st) < 0))
            return NULL;
        if (LIKELY(!resolved))
            return strdup(dirfdpath);
        return strcpy(resolved, dirfdpath);
    }

    if (LIKELY(!resolved)) {
        rpath = malloc(PATH_MAX);
        if (UNLIKELY(!rpath))
            return NULL;
    } else
        rpath = resolved;
    rpath_limit = rpath + PATH_MAX;

    strcpy(rpath, dirfdpath);
    dest = rawmemchr(rpath, '\0');
    dirfdlen = dest - rpath;

    for (start = end = name; *start; start = end) {
        int n;

        /* Skip sequence of multiple path-separators.  */
        while (*start == '/')
            ++start;

        /* Find end of path component.  */
        for (end = start; *end && *end != '/'; ++end)
            /* Nothing.  */ ;

        if (end - start == 0)
            break;
        else if (end - start == 1 && start[0] == '.')
            /* nothing */ ;
        else if (end - start == 2 && start[0] == '.' && start[1] == '.') {
            /* Back up to previous component, ignore if at root already.  */
            if (dest > rpath + 1)
                while ((--dest)[-1] != '/');
        } else {
            size_t new_size;

            if (dest[-1] != '/')
                *dest++ = '/';

            if (dest + (end - start) >= rpath_limit) {
                ptrdiff_t dest_offset = dest - rpath;
                char *new_rpath;

                if (UNLIKELY(resolved != NULL)) {
                    errno = ENAMETOOLONG;
                    if (dest > rpath + 1)
                        dest--;
                    *dest = '\0';
                    goto error;
                }

                new_size = (size_t)(rpath_limit - rpath);
                if (end - start + 1 > PATH_MAX)
                    new_size += (size_t)(end - start + 1);
                else
                    new_size += PATH_MAX;
                new_rpath = (char *) realloc(rpath, new_size);
                if (UNLIKELY(new_rpath == NULL))
                    goto error;
                rpath = new_rpath;
                rpath_limit = rpath + new_size;

                dest = rpath + dest_offset;
            }

            dest = mempmove(dest, start, (size_t)(end - start));
            *dest = '\0';

            if (LIKELY(!strncmp(rpath, dirfdpath, (size_t)dirfdlen))) {
                pathat = rpath + dirfdlen + 1;
                if (*pathat == '\0')
                    pathat = rpath;
            } else {
                pathat = rpath;
            }

            if (UNLIKELY(fstatat(dirfd, pathat, st, AT_SYMLINK_NOFOLLOW) < 0))
                goto error;

            if (UNLIKELY(S_ISLNK(st->st_mode))) {
                char buf[PATH_MAX];
                size_t len;

                if (UNLIKELY(++num_links > MAXSYMLINKS)) {
                    errno = ELOOP;
                    goto error;
                }

                n = (int)readlinkat(dirfd, pathat, buf, PATH_MAX - 1);
                if (UNLIKELY(n < 0))
                    goto error;
                buf[n] = '\0';

                len = strlen(end);
                if (UNLIKELY((long int) (n + (long int)len) >= PATH_MAX)) {
                    errno = ENAMETOOLONG;
                    goto error;
                }

                /* Careful here, end may be a pointer into extra_buf... */
                memmove(&extra_buf[n], end, len + 1);
                end = memcpy(extra_buf, buf, (size_t)n);

                if (buf[0] == '/')
                    dest = rpath + 1;    /* It's an absolute symlink */
                else
                    /* Back up to previous component, ignore if at root already: */
                    if (dest > rpath + 1)
                        while ((--dest)[-1] != '/');
            } else if (UNLIKELY(!S_ISDIR(st->st_mode) && *end != '\0')) {
                errno = ENOTDIR;
                goto error;
            }
        }
    }

    if (dest > rpath + 1 && dest[-1] == '/')
        --dest;
    *dest = '\0';

    assert(resolved == NULL || resolved == rpath);
    return rpath;

  error:
    assert(resolved == NULL || resolved == rpath);
    if (resolved == NULL)
        free(rpath);
    return NULL;
}
Пример #12
0
void Variant::unserialize(VariableUnserializer *uns,
                          Uns::Mode mode /* = Uns::Mode::Value */) {

  // NOTE: If you make changes to how serialization and unserialization work,
  // make sure to update the reserialize() method in "runtime/ext/ext_apc.cpp"
  // and to update test_apc_reserialize() in "test/ext/test_ext_apc.cpp".

  char type, sep;
  type = uns->readChar();
  sep = uns->readChar();

  if (type != 'R') {
    uns->add(this, mode);
  }

  if (type == 'N') {
    if (sep != ';') throw Exception("Expected ';' but got '%c'", sep);
    setNull(); // NULL *IS* the value, without we get undefined warnings
    return;
  }
  if (sep != ':') {
    throw Exception("Expected ':' but got '%c'", sep);
  }

  switch (type) {
  case 'r':
    {
      int64_t id = uns->readInt();
      Variant *v = uns->getByVal(id);
      if (v == nullptr) {
        throw Exception("Id %" PRId64 " out of range", id);
      }
      operator=(*v);
    }
    break;
  case 'R':
    {
      int64_t id = uns->readInt();
      Variant *v = uns->getByRef(id);
      if (v == nullptr) {
        throw Exception("Id %" PRId64 " out of range", id);
      }
      assignRef(*v);
    }
    break;
  case 'b': { int64_t v = uns->readInt(); operator=((bool)v); } break;
  case 'i': { int64_t v = uns->readInt(); operator=(v);       } break;
  case 'd':
    {
      double v;
      char ch = uns->peek();
      bool negative = false;
      char buf[4];
      if (ch == '-') {
        negative = true;
        ch = uns->readChar();
        ch = uns->peek();
      }
      if (ch == 'I') {
        uns->read(buf, 3); buf[3] = '\0';
        if (strcmp(buf, "INF")) {
          throw Exception("Expected 'INF' but got '%s'", buf);
        }
        v = atof("inf");
      } else if (ch == 'N') {
        uns->read(buf, 3); buf[3] = '\0';
        if (strcmp(buf, "NAN")) {
          throw Exception("Expected 'NAN' but got '%s'", buf);
        }
        v = atof("nan");
      } else {
        v = uns->readDouble();
      }
      operator=(negative ? -v : v);
    }
    break;
  case 's':
    {
      String v;
      v.unserialize(uns);
      operator=(v);
      if (!uns->endOfBuffer()) {
        // Semicolon *should* always be required,
        // but PHP's implementation allows omitting it
        // and still functioning.
        // Worse, it throws it away without any check.
        // So we'll do the same.  Sigh.
        uns->readChar();
      }
      return;
    }
    break;
  case 'S':
    if (uns->type() == VariableUnserializer::Type::APCSerialize) {
      union {
        char buf[8];
        StringData *sd;
      } u;
      uns->read(u.buf, 8);
      operator=(u.sd);
    } else {
      throw Exception("Unknown type '%c'", type);
    }
    break;
  case 'a':
    {
      // check stack depth to avoid overflow
      check_native_recursion();

      Array v = Array::Create();
      v.unserialize(uns);
      operator=(v);
      return; // array has '}' terminating
    }
    break;
  case 'L':
    {
      int64_t id = uns->readInt();
      uns->expectChar(':');
      String rsrcName;
      rsrcName.unserialize(uns);
      uns->expectChar('{');
      uns->expectChar('}');
      auto rsrc = makeSmartPtr<DummyResource>();
      rsrc->o_setResourceId(id);
      rsrc->m_class_name = rsrcName;
      operator=(rsrc);
      return; // resource has '}' terminating
    }
    break;
  case 'O':
  case 'V':
  case 'K':
    {
      String clsName;
      clsName.unserialize(uns);

      uns->expectChar(':');
      int64_t size = uns->readInt();
      uns->expectChar(':');
      uns->expectChar('{');

      const bool allowObjectFormatForCollections = true;

      Class* cls;
      // If we are potentially dealing with a collection, we need to try to
      // load the collection class under an alternate name so that we can
      // deserialize data that was serialized before the migration of
      // collections to the HH namespace.

      if (type != 'O') {
        // Collections are CPP builtins; don't attempt to autoload
        cls = Unit::getClass(clsName.get(), /* autoload */ false);
        if (!cls) {
          cls = tryAlternateCollectionClass(clsName.get());
        }
      } else if (allowObjectFormatForCollections) {
        // In order to support the legacy {O|V}:{Set|Vector|Map}
        // serialization, we defer autoloading until we know that there's
        // no alternate (builtin) collection class.
        cls = Unit::getClass(clsName.get(), /* autoload */ false);
        if (!cls) {
          cls = tryAlternateCollectionClass(clsName.get());
        }
        if (!cls) {
          cls = Unit::loadClass(clsName.get()); // with autoloading
        }
      } else {
        cls = Unit::loadClass(clsName.get()); // with autoloading
      }

      Object obj;
      if (RuntimeOption::UnserializationWhitelistCheck &&
          (type == 'O') &&
          !uns->isWhitelistedClass(clsName)) {
        const char* err_msg =
          "The object being unserialized with class name '%s' "
          "is not in the given whitelist. "
          "See http://fburl.com/SafeSerializable for more detail";
        if (RuntimeOption::UnserializationWhitelistCheckWarningOnly) {
          raise_warning(err_msg, clsName.c_str());
        } else {
          raise_error(err_msg, clsName.c_str());
        }
      }
      if (cls) {
        // Only unserialize CPP extension types which can actually
        // support it. Otherwise, we risk creating a CPP object
        // without having it initialized completely.
        if (cls->instanceCtor() && !cls->isCppSerializable()) {
          assert(obj.isNull());
        } else {
          obj = ObjectData::newInstance(cls);
          if (UNLIKELY(cls == c_Pair::classof() && size != 2)) {
            throw Exception("Pair objects must have exactly 2 elements");
          }
        }
      } else {
        obj = ObjectData::newInstance(
          SystemLib::s___PHP_Incomplete_ClassClass);
        obj->o_set(s_PHP_Incomplete_Class_Name, clsName);
      }
      operator=(obj);

      if (size > 0) {
        // check stack depth to avoid overflow
        check_native_recursion();

        if (type == 'O') {
          // Collections are not allowed
          if (obj->isCollection()) {
            throw Exception("%s does not support the 'O' serialization "
                            "format", clsName.data());
          }

          Variant serializedNativeData = init_null();
          bool hasSerializedNativeData = false;

          /*
            Count backwards so that i is the number of properties
            remaining (to be used as an estimate for the total number
            of dynamic properties when we see the first dynamic prop).
            see getVariantPtr
          */
          for (int64_t i = size; i--; ) {
            Variant v;
            v.unserialize(uns, Uns::Mode::Key);
            String key = v.toString();
            int ksize = key.size();
            const char *kdata = key.data();
            int subLen = 0;
            if (key == ObjectData::s_serializedNativeDataKey) {
              serializedNativeData.unserialize(uns);
              hasSerializedNativeData = true;
            } else if (kdata[0] == '\0') {
              if (UNLIKELY(!ksize)) {
                raise_error("Cannot access empty property");
              }
              // private or protected
              subLen = strlen(kdata + 1) + 2;
              if (UNLIKELY(subLen >= ksize)) {
                if (subLen == ksize) {
                  raise_error("Cannot access empty property");
                } else {
                  throw Exception("Mangled private object property");
                }
              }
              String k(kdata + subLen, ksize - subLen, CopyString);
              Class* ctx = (Class*)-1;
              if (kdata[1] != '*') {
                ctx = Unit::lookupClass(
                  String(kdata + 1, subLen - 2, CopyString).get());
              }
              unserializeProp(uns, obj.get(), k, ctx, key, i + 1);
            } else {
              unserializeProp(uns, obj.get(), key, nullptr, key, i + 1);
            }

            if (i > 0) {
              auto lastChar = uns->peekBack();
              if ((lastChar != ';') && (lastChar != '}')) {
                throw Exception("Object property not terminated properly");
              }
            }
          }

          // nativeDataWakeup is called last to ensure that all properties are
          // already unserialized. We also ensure that nativeDataWakeup is
          // invoked regardless of whether or not serialized native data exists
          // within the serialized content.
          if (obj->getAttribute(ObjectData::HasNativeData) &&
              obj->getVMClass()->getNativeDataInfo()->isSerializable()) {
            Native::nativeDataWakeup(obj.get(), serializedNativeData);
          } else if (hasSerializedNativeData) {
            raise_warning("%s does not expect any serialized native data.",
                          clsName.data());
          }
        } else {
          assert(type == 'V' || type == 'K');
          if (!obj->isCollection()) {
            throw Exception("%s is not a collection class", clsName.data());
          }
          collectionUnserialize(obj.get(), uns, size, type);
        }
      }
      uns->expectChar('}');

      if (uns->type() != VariableUnserializer::Type::DebuggerSerialize ||
          (cls && cls->instanceCtor() && cls->isCppSerializable())) {
        // Don't call wakeup when unserializing for the debugger, except for
        // natively implemented classes.
        obj->invokeWakeup();
      }

      check_request_surprise_unlikely();

      return; // object has '}' terminating
    }
    break;
  case 'C':
    {
      if (uns->type() == VariableUnserializer::Type::DebuggerSerialize) {
        raise_error("Debugger shouldn't call custom unserialize method");
      }
      String clsName;
      clsName.unserialize(uns);

      uns->expectChar(':');
      String serialized;
      serialized.unserialize(uns, '{', '}');

      auto const obj = [&]() -> Object {
        if (auto const cls = Unit::loadClass(clsName.get())) {
          return g_context->createObject(cls, init_null_variant,
            false /* init */);
        }
        if (!uns->allowUnknownSerializableClass()) {
          raise_error("unknown class %s", clsName.data());
        }
        Object ret = create_object_only(s_PHP_Incomplete_Class);
        ret->o_set(s_PHP_Incomplete_Class_Name, clsName);
        ret->o_set("serialized", serialized);
        return ret;
      }();

      if (!obj->instanceof(SystemLib::s_SerializableClass)) {
        raise_warning("Class %s has no unserializer",
                      obj->getClassName().data());
      } else {
        obj->o_invoke_few_args(s_unserialize, 1, serialized);
        obj.get()->clearNoDestruct();
      }

      operator=(obj);
      return; // object has '}' terminating
    }
    break;
  default:
    throw Exception("Unknown type '%c'", type);
  }
  uns->expectChar(';');
}
Пример #13
0
status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{
    AutoMutex lock(mLock);
    int active;
    status_t result = NO_ERROR;
    audio_track_cblk_t* cblk = mCblk;
    uint32_t framesReq = audioBuffer->frameCount;
    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;

    audioBuffer->frameCount  = 0;
    audioBuffer->size        = 0;

    uint32_t framesReady = cblk->framesReady();

    if (framesReady == 0) {
        cblk->lock.lock();
        goto start_loop_here;
        while (framesReady == 0) {
            active = mActive;
            if (UNLIKELY(!active)) {
                cblk->lock.unlock();
                return NO_MORE_BUFFERS;
            }
            if (UNLIKELY(!waitCount)) {
                cblk->lock.unlock();
                return WOULD_BLOCK;
            }
            if (!(cblk->flags & CBLK_INVALID_MSK)) {
                mLock.unlock();
                result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
                cblk->lock.unlock();
                mLock.lock();
                if (mActive == 0) {
                    return status_t(STOPPED);
                }
                cblk->lock.lock();
            }
            if (cblk->flags & CBLK_INVALID_MSK) {
                goto create_new_record;
            }
            if (__builtin_expect(result!=NO_ERROR, false)) {
                cblk->waitTimeMs += waitTimeMs;
                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
                    LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
                            "user=%08x, server=%08x", cblk->user, cblk->server);
                    cblk->lock.unlock();
                    result = mAudioRecord->start();
                    cblk->lock.lock();
                    if (result == DEAD_OBJECT) {
                        android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
create_new_record:
                        result = AudioRecord::restoreRecord_l(cblk);
                    }
                    if (result != NO_ERROR) {
                        LOGW("obtainBuffer create Track error %d", result);
                        cblk->lock.unlock();
                        return result;
                    }
                    cblk->waitTimeMs = 0;
                }
                if (--waitCount == 0) {
                    cblk->lock.unlock();
                    return TIMED_OUT;
                }
            }
            // read the server count again
        start_loop_here:
            framesReady = cblk->framesReady();
        }
        cblk->lock.unlock();
    }

    cblk->waitTimeMs = 0;

    if (framesReq > framesReady) {
        framesReq = framesReady;
    }

    uint32_t u = cblk->user;
    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;

    if (u + framesReq > bufferEnd) {
        framesReq = bufferEnd - u;
    }

    audioBuffer->flags       = 0;
    audioBuffer->channelCount= mChannelCount;
    audioBuffer->format      = mFormat;
    audioBuffer->frameCount  = framesReq;
    audioBuffer->size        = framesReq*cblk->frameSize;
    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
    active = mActive;
    return active ? status_t(NO_ERROR) : status_t(STOPPED);
}
Пример #14
0
/**
 * \return a face index in \a faces and set \a r_is_flip if the face is flipped away from the center.
 */
static int recalc_face_normals_find_index(BMesh *bm, BMFace **faces, const int faces_len, bool *r_is_flip)
{
	const float eps = FLT_EPSILON;
	float cent_area_accum = 0.0f;
	float cent[3];
	const float cent_fac = 1.0f / (float)faces_len;

	bool is_flip = false;
	int f_start_index;
	int i;

	/* Search for the best loop. Members are compared in-order defined here. */
	struct {
		/* Squared distance from the center to the loops vertex 'l->v'.
		 * The normalized direction between the center and this vertex is also used for the dot-products below. */
		float dist_sq;
		/* Signed dot product using the normalized edge vector,
		 * (best of 'l->prev->v' or 'l->next->v'). */
		float edge_dot;
		/* Unsigned dot product using the loop-normal
		 * (sign is used to check if we need to flip) */
		float loop_dot;
	} best, test;

	UNUSED_VARS_NDEBUG(bm);

	zero_v3(cent);

	/* first calculate the center */
	for (i = 0; i < faces_len; i++) {
		float f_cent[3];
		const float f_area = BM_face_calc_area(faces[i]);
		BM_face_calc_center_mean_weighted(faces[i], f_cent);
		madd_v3_v3fl(cent, f_cent, cent_fac * f_area);
		cent_area_accum += f_area;

		BLI_assert(BMO_face_flag_test(bm, faces[i], FACE_TEMP) == 0);
		BLI_assert(BM_face_is_normal_valid(faces[i]));
	}

	if (cent_area_accum != 0.0f) {
		mul_v3_fl(cent, 1.0f / cent_area_accum);
	}

	/* Distances must start above zero,
	 * or we can't do meaningful calculations based on the direction to the center */
	best.dist_sq = eps;
	best.edge_dot = best.loop_dot = -FLT_MAX;

	/* used in degenerate cases only */
	f_start_index = 0;

	/**
	 * Find the outer-most vertex, comparing distance to the center,
	 * then the outer-most loop attached to that vertex.
	 *
	 * Important this is correctly detected,
	 * where casting a ray from the center wont hit any loops past this one.
	 * Otherwise the result may be incorrect.
	 */
	for (i = 0; i < faces_len; i++) {
		BMLoop *l_iter, *l_first;

		l_iter = l_first = BM_FACE_FIRST_LOOP(faces[i]);
		do {
			bool is_best_dist_sq;
			float dir[3];
			sub_v3_v3v3(dir, l_iter->v->co, cent);
			test.dist_sq = len_squared_v3(dir);
			is_best_dist_sq =      (test.dist_sq  > best.dist_sq);
			if (is_best_dist_sq || (test.dist_sq == best.dist_sq)) {
				float edge_dir_pair[2][3];
				mul_v3_fl(dir, 1.0f / sqrtf(test.dist_sq));

				sub_v3_v3v3(edge_dir_pair[0], l_iter->next->v->co, l_iter->v->co);
				sub_v3_v3v3(edge_dir_pair[1], l_iter->prev->v->co, l_iter->v->co);

				if ((normalize_v3(edge_dir_pair[0]) > eps) &&
				    (normalize_v3(edge_dir_pair[1]) > eps))
				{
					bool is_best_edge_dot;
					test.edge_dot = max_ff(dot_v3v3(dir, edge_dir_pair[0]),
					                       dot_v3v3(dir, edge_dir_pair[1]));
					is_best_edge_dot =                         (test.edge_dot  > best.edge_dot);
					if (is_best_dist_sq || is_best_edge_dot || (test.edge_dot == best.edge_dot)) {
						float loop_dir[3];
						cross_v3_v3v3(loop_dir, edge_dir_pair[0], edge_dir_pair[1]);
						if (normalize_v3(loop_dir) > eps) {
							float loop_dir_dot;
							/* Highly unlikely the furthest loop is also the concave part of an ngon,
							 * but it can be contrived with _very_ non-planar faces - so better check. */
							if (UNLIKELY(dot_v3v3(loop_dir, l_iter->f->no) < 0.0f)) {
								negate_v3(loop_dir);
							}
							loop_dir_dot = dot_v3v3(dir, loop_dir);
							test.loop_dot = fabsf(loop_dir_dot);
							if (is_best_dist_sq || is_best_edge_dot || (test.loop_dot > best.loop_dot)) {
								best = test;
								f_start_index = i;
								is_flip = (loop_dir_dot < 0.0f);
							}
						}
					}
				}
			}
		} while ((l_iter = l_iter->next) != l_first);
	}

	*r_is_flip = is_flip;
	return f_start_index;
}
Пример #15
0
/**
 * Find nearest returns index, and -1 if no node is found.
 */
int BLI_kdtree_find_nearest(
        const KDTree *tree, const float co[3],
        KDTreeNearest *r_nearest)
{
	const KDTreeNode *nodes = tree->nodes;
	const KDTreeNode *root, *min_node;
	uint *stack, defaultstack[KD_STACK_INIT];
	float min_dist, cur_dist;
	uint totstack, cur = 0;

#ifdef DEBUG
	BLI_assert(tree->is_balanced == true);
#endif

	if (UNLIKELY(tree->root == KD_NODE_UNSET))
		return -1;

	stack = defaultstack;
	totstack = KD_STACK_INIT;

	root = &nodes[tree->root];
	min_node = root;
	min_dist = len_squared_v3v3(root->co, co);

	if (co[root->d] < root->co[root->d]) {
		if (root->right != KD_NODE_UNSET)
			stack[cur++] = root->right;
		if (root->left != KD_NODE_UNSET)
			stack[cur++] = root->left;
	}
	else {
		if (root->left != KD_NODE_UNSET)
			stack[cur++] = root->left;
		if (root->right != KD_NODE_UNSET)
			stack[cur++] = root->right;
	}

	while (cur--) {
		const KDTreeNode *node = &nodes[stack[cur]];

		cur_dist = node->co[node->d] - co[node->d];

		if (cur_dist < 0.0f) {
			cur_dist = -cur_dist * cur_dist;

			if (-cur_dist < min_dist) {
				cur_dist = len_squared_v3v3(node->co, co);
				if (cur_dist < min_dist) {
					min_dist = cur_dist;
					min_node = node;
				}
				if (node->left != KD_NODE_UNSET)
					stack[cur++] = node->left;
			}
			if (node->right != KD_NODE_UNSET)
				stack[cur++] = node->right;
		}
		else {
			cur_dist = cur_dist * cur_dist;

			if (cur_dist < min_dist) {
				cur_dist = len_squared_v3v3(node->co, co);
				if (cur_dist < min_dist) {
					min_dist = cur_dist;
					min_node = node;
				}
				if (node->right != KD_NODE_UNSET)
					stack[cur++] = node->right;
			}
			if (node->left != KD_NODE_UNSET)
				stack[cur++] = node->left;
		}
		if (UNLIKELY(cur + 3 > totstack)) {
			stack = realloc_nodes(stack, &totstack, defaultstack != stack);
		}
	}

	if (r_nearest) {
		r_nearest->index = min_node->index;
		r_nearest->dist = sqrtf(min_dist);
		copy_v3_v3(r_nearest->co, min_node->co);
	}

	if (stack != defaultstack)
		MEM_freeN(stack);

	return min_node->index;
}
Пример #16
0
static int ReadMidiData_(CSOUND *csound, void *userData,
                         unsigned char *mbuf, int nbytes)
{
    int             n, retval, st, d1, d2;
    PmEvent         mev;
    pmall_data *data;
    /*
     * Reads from MIDI input device linked list.
     */
    n = 0;
    data = (pmall_data *)userData;
    while (data) {
      retval = Pm_Poll(data->midistream);
      if (retval != FALSE) {
        if (UNLIKELY(retval < 0))
          return portMidiErrMsg(csound, Str("error polling input device"));
        while ((retval = Pm_Read(data->midistream, &mev, 1L)) > 0) {
          st = (int)Pm_MessageStatus(mev.message);
          d1 = (int)Pm_MessageData1(mev.message);
          d2 = (int)Pm_MessageData2(mev.message);
          /* unknown message or sysex data: ignore */
          if (UNLIKELY(st < 0x80))
            continue;
          /* ignore most system messages */
          if (UNLIKELY(st >= 0xF0 &&
                       !(st == 0xF8 || st == 0xFA || st == 0xFB ||
                         st == 0xFC || st == 0xFF)))
            continue;
          nbytes -= (datbyts[(st - 0x80) >> 4] + 1);
          if (UNLIKELY(nbytes < 0)) {
            portMidiErrMsg(csound, Str("buffer overflow in MIDI input"));
            break;
          }
          /* channel messages */
          n += (datbyts[(st - 0x80) >> 4] + 1);
          switch (datbyts[(st - 0x80) >> 4]) {
            case 0:
              *mbuf++ = (unsigned char) st;
              break;
            case 1:
              *mbuf++ = (unsigned char) st;
              *mbuf++ = (unsigned char) d1;
              break;
            case 2:
              *mbuf++ = (unsigned char) st;
              *mbuf++ = (unsigned char) d1;
              *mbuf++ = (unsigned char) d2;
              break;
          }
        }
        if (UNLIKELY(retval < 0)) {
          portMidiErrMsg(csound, Str("read error %d"), retval);
          if (n < 1)
            n = -1;
        }
      }
      data = data->next;
    }
    /* return the number of bytes read */
    return n;
}
Пример #17
0
/**
 * A version of #BLI_kdtree_find_nearest which runs a callback
 * to filter out values.
 *
 * \param filter_cb: Filter find results,
 * Return codes: (1: accept, 0: skip, -1: immediate exit).
 */
int BLI_kdtree_find_nearest_cb(
        const KDTree *tree, const float co[3],
        int (*filter_cb)(void *user_data, int index, const float co[3], float dist_sq), void *user_data,
        KDTreeNearest *r_nearest)
{
	const KDTreeNode *nodes = tree->nodes;
	const KDTreeNode *min_node = NULL;

	uint *stack, defaultstack[KD_STACK_INIT];
	float min_dist = FLT_MAX, cur_dist;
	uint totstack, cur = 0;

#ifdef DEBUG
	BLI_assert(tree->is_balanced == true);
#endif

	if (UNLIKELY(tree->root == KD_NODE_UNSET))
		return -1;

	stack = defaultstack;
	totstack = KD_STACK_INIT;

#define NODE_TEST_NEAREST(node) \
{ \
	const float dist_sq = len_squared_v3v3((node)->co, co); \
	if (dist_sq < min_dist) { \
		const int result = filter_cb(user_data, (node)->index, (node)->co, dist_sq); \
		if (result == 1) { \
			min_dist = dist_sq; \
			min_node = node; \
		} \
		else if (result == 0) { \
			/* pass */ \
		} \
		else { \
			BLI_assert(result == -1); \
			goto finally; \
		} \
	} \
} ((void)0)

	stack[cur++] = tree->root;

	while (cur--) {
		const KDTreeNode *node = &nodes[stack[cur]];

		cur_dist = node->co[node->d] - co[node->d];

		if (cur_dist < 0.0f) {
			cur_dist = -cur_dist * cur_dist;

			if (-cur_dist < min_dist) {
				NODE_TEST_NEAREST(node);

				if (node->left != KD_NODE_UNSET)
					stack[cur++] = node->left;
			}
			if (node->right != KD_NODE_UNSET)
				stack[cur++] = node->right;
		}
		else {
			cur_dist = cur_dist * cur_dist;

			if (cur_dist < min_dist) {
				NODE_TEST_NEAREST(node);

				if (node->right != KD_NODE_UNSET)
					stack[cur++] = node->right;
			}
			if (node->left != KD_NODE_UNSET)
				stack[cur++] = node->left;
		}
		if (UNLIKELY(cur + 3 > totstack)) {
			stack = realloc_nodes(stack, &totstack, defaultstack != stack);
		}
	}

#undef NODE_TEST_NEAREST


finally:
	if (stack != defaultstack)
		MEM_freeN(stack);

	if (min_node) {
		if (r_nearest) {
			r_nearest->index = min_node->index;
			r_nearest->dist = sqrtf(min_dist);
			copy_v3_v3(r_nearest->co, min_node->co);
		}

		return min_node->index;
	}
	else {
		return -1;
	}
}
Пример #18
0
status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{
    AutoMutex lock(mLock);
    int active;
    status_t result = NO_ERROR;
    audio_track_cblk_t* cblk = mCblk;
    uint32_t framesReq = audioBuffer->frameCount;
    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;

    audioBuffer->frameCount  = 0;
    audioBuffer->size = 0;

    uint32_t framesAvail = cblk->framesAvailable();

    cblk->lock.lock();
    if (cblk->flags & CBLK_INVALID_MSK) {
        goto create_new_track;
    }
    cblk->lock.unlock();

    if (framesAvail == 0) {
        cblk->lock.lock();
        goto start_loop_here;
        while (framesAvail == 0) {
            active = mActive;
            if (UNLIKELY(!active)) {
                LOGV("Not active and NO_MORE_BUFFERS");
                cblk->lock.unlock();
                return NO_MORE_BUFFERS;
            }
            if (UNLIKELY(!waitCount)) {
                cblk->lock.unlock();
                return WOULD_BLOCK;
            }
            if (!(cblk->flags & CBLK_INVALID_MSK)) {
                mLock.unlock();
                result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
                cblk->lock.unlock();
                mLock.lock();
                if (mActive == 0) {
                    return status_t(STOPPED);
                }
                cblk->lock.lock();
            }

            if (cblk->flags & CBLK_INVALID_MSK) {
                goto create_new_track;
            }
            if (__builtin_expect(result!=NO_ERROR, false)) {
                cblk->waitTimeMs += waitTimeMs;
                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
                    // timing out when a loop has been set and we have already written upto loop end
                    // is a normal condition: no need to wake AudioFlinger up.
                    if (cblk->user < cblk->loopEnd) {
                        LOGW(   "obtainBuffer timed out (is the CPU pegged?) %p "
                                "user=%08x, server=%08x", this, cblk->user, cblk->server);
                        //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140)
                        cblk->lock.unlock();
                        result = mAudioTrack->start();
                        cblk->lock.lock();
                        if (result == DEAD_OBJECT) {
                            android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
create_new_track:
                            result = restoreTrack_l(cblk, false);
                        }
                        if (result != NO_ERROR) {
                            LOGW("obtainBuffer create Track error %d", result);
                            cblk->lock.unlock();
                            return result;
                        }
                    }
                    cblk->waitTimeMs = 0;
                }

                if (--waitCount == 0) {
                    cblk->lock.unlock();
                    return TIMED_OUT;
                }
            }
            // read the server count again
        start_loop_here:
            framesAvail = cblk->framesAvailable_l();
        }
        cblk->lock.unlock();
    }

    // restart track if it was disabled by audioflinger due to previous underrun
    if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) {
        android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
        LOGW("obtainBuffer() track %p disabled, restarting", this);
        mAudioTrack->start();
    }

    cblk->waitTimeMs = 0;

    if (framesReq > framesAvail) {
        framesReq = framesAvail;
    }

    uint32_t u = cblk->user;
    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;

    if (u + framesReq > bufferEnd) {
        framesReq = bufferEnd - u;
    }

    audioBuffer->flags = mMuted ? Buffer::MUTE : 0;
    audioBuffer->channelCount = mChannelCount;
    audioBuffer->frameCount = framesReq;
    audioBuffer->size = framesReq * cblk->frameSize;
    if (audio_is_linear_pcm(mFormat)) {
        audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT;
    } else {
        audioBuffer->format = mFormat;
    }
    audioBuffer->raw = (int8_t *)cblk->buffer(u);
    active = mActive;
    return active ? status_t(NO_ERROR) : status_t(STOPPED);
}
Пример #19
0
mp_limb_t
mpn_dc_div_qr (mp_ptr qp,
		  mp_ptr np, mp_size_t nn,
		  mp_srcptr dp, mp_size_t dn,
		  mp_limb_t dinv)
{
  mp_size_t qn;
  mp_limb_t qh, cy;
  mp_ptr tp;
  TMP_DECL;

  TMP_MARK;

  ASSERT (dn >= 6);		/* to adhere to mpn_sb_div_qr's limits */
  ASSERT (nn - dn >= 3);	/* to adhere to mpn_sb_div_qr's limits */
  ASSERT (dp[dn-1] & GMP_NUMB_HIGHBIT);

  tp = TMP_ALLOC_LIMBS (DC_DIVAPPR_Q_N_ITCH(dn));

  qn = nn - dn;
  qp += qn;
  np += nn;
  dp += dn;

  if (qn > dn)
    {
      /* Reduce qn mod dn without division, optimizing small operations.  */
      do
	qn -= dn;
      while (qn > dn);

      qp -= qn;			/* point at low limb of next quotient block */
      np -= qn;			/* point in the middle of partial remainder */

      /* Perform the typically smaller block first.  */
      if (qn == 1)
	{
	  mp_limb_t q, n2, n1, n0, d1, d0;

	  /* Handle qh up front, for simplicity. */
	  qh = mpn_cmp (np - dn + 1, dp - dn, dn) >= 0;
	  if (qh)
	    ASSERT_NOCARRY (mpn_sub_n (np - dn + 1, np - dn + 1, dp - dn, dn));

	  /* A single iteration of schoolbook: One 3/2 division,
	     followed by the bignum update and adjustment. */
	  n2 = np[0];
	  n1 = np[-1];
	  n0 = np[-2];
	  d1 = dp[-1];
	  d0 = dp[-2];

	  ASSERT (n2 < d1 || (n2 == d1 && n1 <= d0));

	  if (UNLIKELY (n2 == d1) && n1 == d0)
	    {
	      q = GMP_NUMB_MASK;
	      cy = mpn_submul_1 (np - dn, dp - dn, dn, q);
	      ASSERT (cy == n2);
	    }
	  else
	    {
	      tdiv_qr_3by2 (q, n1, n0, n2, n1, n0, d1, d0, dinv);

	      if (dn > 2)
		{
		  mp_limb_t cy, cy1;
		  cy = mpn_submul_1 (np - dn, dp - dn, dn - 2, q);

		  cy1 = n0 < cy;
		  n0 = (n0 - cy) & GMP_NUMB_MASK;
		  cy = n1 < cy1;
		  n1 = (n1 - cy1) & GMP_NUMB_MASK;
		  np[-2] = n0;

		  if (UNLIKELY (cy != 0))
		    {
		      n1 += d1 + mpn_add_n (np - dn, np - dn, dp - dn, dn - 1);
		      qh -= (q == 0);
		      q = (q - 1) & GMP_NUMB_MASK;
		    }
		}
	      else
		np[-2] = n0;

	      np[-1] = n1;
	    }
	  qp[0] = q;
	}
      else
	{
      /* Do a 2qn / qn division */
	  if (qn == 2)
	    qh = mpn_divrem_2 (qp, 0L, np - 2, 4, dp - 2); /* FIXME: obsolete function. Use 5/3 division? */
	  else if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
	    qh = mpn_sb_div_qr (qp, np - qn, 2 * qn, dp - qn, qn, dinv);
	  else
	    qh = mpn_dc_div_qr_n (qp, np - qn, dp - qn, qn, dinv, tp);

	  if (qn != dn)
	    {
	      if (qn > dn - qn)
		mpn_mul (tp, qp, qn, dp - dn, dn - qn);
	      else
		mpn_mul (tp, dp - dn, dn - qn, qp, qn);

	      cy = mpn_sub_n (np - dn, np - dn, tp, dn);
	      if (qh != 0)
		cy += mpn_sub_n (np - dn + qn, np - dn + qn, dp - dn, dn - qn);

	      while (cy != 0)
		{
		  qh -= mpn_sub_1 (qp, qp, qn, 1);
		  cy -= mpn_add_n (np - dn, np - dn, dp - dn, dn);
		}
	    }
	}

      qn = nn - dn - qn;
      do
	{
	  qp -= dn;
	  np -= dn;
	  ASSERT_NOCARRY(mpn_dc_div_qr_n (qp, np - dn, dp - dn, dn, dinv, tp));
	  qn -= dn;
	}
      while (qn > 0);
    }
  else
    {
      qp -= qn;			/* point at low limb of next quotient block */
      np -= qn;			/* point in the middle of partial remainder */

      if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
	qh = mpn_sb_div_qr (qp, np - qn, 2 * qn, dp - qn, qn, dinv);
      else
	qh = mpn_dc_div_qr_n (qp, np - qn, dp - qn, qn, dinv, tp);

      if (qn != dn)
	{
	  if (qn > dn - qn)
	    mpn_mul (tp, qp, qn, dp - dn, dn - qn);
	  else
	    mpn_mul (tp, dp - dn, dn - qn, qp, qn);

	  cy = mpn_sub_n (np - dn, np - dn, tp, dn);
	  if (qh != 0)
	    cy += mpn_sub_n (np - dn + qn, np - dn + qn, dp - dn, dn - qn);

	  while (cy != 0)
	    {
	      qh -= mpn_sub_1 (qp, qp, qn, 1);
	      cy -= mpn_add_n (np - dn, np - dn, dp - dn, dn);
	    }
	}
    }

  TMP_FREE;
  return qh;
}
Пример #20
0
/**
 * \brief Mesh -> BMesh
 *
 * \warning This function doesn't calculate face normals.
 */
void BM_mesh_bm_from_me(
        BMesh *bm, Mesh *me,
        const bool calc_face_normal, const bool set_key, int act_key_nr)
{
	MVert *mvert;
	MEdge *medge;
	MLoop *mloop;
	MPoly *mp;
	KeyBlock *actkey, *block;
	BMVert *v, **vtable = NULL;
	BMEdge *e, **etable = NULL;
	BMFace *f;
	float (*keyco)[3] = NULL;
	int totuv, totloops, i, j;

	int cd_vert_bweight_offset;
	int cd_edge_bweight_offset;
	int cd_edge_crease_offset;
	int cd_shape_keyindex_offset;

	/* free custom data */
	/* this isnt needed in most cases but do just incase */
	CustomData_free(&bm->vdata, bm->totvert);
	CustomData_free(&bm->edata, bm->totedge);
	CustomData_free(&bm->ldata, bm->totloop);
	CustomData_free(&bm->pdata, bm->totface);

	if (!me || !me->totvert) {
		if (me) { /*no verts? still copy customdata layout*/
			CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_ASSIGN, 0);
			CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_ASSIGN, 0);
			CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_ASSIGN, 0);
			CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_ASSIGN, 0);

			CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
			CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
			CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
			CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
		}
		return; /* sanity check */
	}

	vtable = MEM_mallocN(sizeof(void **) * me->totvert, "mesh to bmesh vtable");

	CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
	CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
	CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
	CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);

	/* make sure uv layer names are consisten */
	totuv = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
	for (i = 0; i < totuv; i++) {
		int li = CustomData_get_layer_index_n(&bm->pdata, CD_MTEXPOLY, i);
		CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
	}

	if ((act_key_nr != 0) && (me->key != NULL)) {
		actkey = BLI_findlink(&me->key->block, act_key_nr - 1);
	}
	else {
		actkey = NULL;
	}

	if (me->key) {
		CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);

		/* check if we need to generate unique ids for the shapekeys.
		 * this also exists in the file reading code, but is here for
		 * a sanity check */
		if (!me->key->uidgen) {
			fprintf(stderr,
			        "%s had to generate shape key uid's in a situation we shouldn't need to! "
			        "(bmesh internal error)\n",
			        __func__);

			me->key->uidgen = 1;
			for (block = me->key->block.first; block; block = block->next) {
				block->uid = me->key->uidgen++;
			}
		}

		if (actkey && actkey->totelem == me->totvert) {
			keyco = actkey->data;
			bm->shapenr = act_key_nr;
		}

		for (i = 0, block = me->key->block.first; block; block = block->next, i++) {
			CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY,
			                           CD_ASSIGN, NULL, 0, block->name);

			j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i);
			bm->vdata.layers[j].uid = block->uid;
		}
	}

	CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
	CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
	CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
	CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);

	BM_mesh_cd_flag_apply(bm, me->cd_flag);

	cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
	cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
	cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
	cd_shape_keyindex_offset = me->key ? CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) : -1;

	for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
		v = vtable[i] = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
		BM_elem_index_set(v, i); /* set_ok */

		/* transfer flag */
		v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT);

		/* this is necessary for selection counts to work properly */
		if (mvert->flag & SELECT) {
			BM_vert_select_set(bm, v, true);
		}

		normal_short_to_float_v3(v->no, mvert->no);

		/* Copy Custom Data */
		CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);

		if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);

		/* set shapekey data */
		if (me->key) {
			/* set shape key original index */
			if (cd_shape_keyindex_offset != -1) BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);

			for (block = me->key->block.first, j = 0; block; block = block->next, j++) {
				float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, j);

				if (co) {
					copy_v3_v3(co, ((float *)block->data) + 3 * i);
				}
			}
		}
	}

	bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */

	if (!me->totedge) {
		MEM_freeN(vtable);
		return;
	}

	etable = MEM_mallocN(sizeof(void **) * me->totedge, "mesh to bmesh etable");

	medge = me->medge;
	for (i = 0; i < me->totedge; i++, medge++) {
		e = etable[i] = BM_edge_create(bm, vtable[medge->v1], vtable[medge->v2], NULL, BM_CREATE_SKIP_CD);
		BM_elem_index_set(e, i); /* set_ok */

		/* transfer flags */
		e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT);

		/* this is necessary for selection counts to work properly */
		if (medge->flag & SELECT) {
			BM_edge_select_set(bm, e, true);
		}

		/* Copy Custom Data */
		CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);

		if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
		if (cd_edge_crease_offset  != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset,  (float)medge->crease  / 255.0f);

	}

	bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */

	mloop = me->mloop;
	mp = me->mpoly;
	for (i = 0, totloops = 0; i < me->totpoly; i++, mp++) {
		BMLoop *l_iter;
		BMLoop *l_first;

		f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart,
		                              bm, vtable, etable);

		if (UNLIKELY(f == NULL)) {
			printf("%s: Warning! Bad face in mesh"
			       " \"%s\" at index %d!, skipping\n",
			       __func__, me->id.name + 2, i);
			continue;
		}

		/* don't use 'i' since we may have skipped the face */
		BM_elem_index_set(f, bm->totface - 1); /* set_ok */

		/* transfer flag */
		f->head.hflag = BM_face_flag_from_mflag(mp->flag & ~ME_FACE_SEL);

		/* this is necessary for selection counts to work properly */
		if (mp->flag & ME_FACE_SEL) {
			BM_face_select_set(bm, f, true);
		}

		f->mat_nr = mp->mat_nr;
		if (i == me->act_face) bm->act_face = f;

		j = mp->loopstart;
		l_iter = l_first = BM_FACE_FIRST_LOOP(f);
		do {
			/* don't use 'j' since we may have skipped some faces, hence some loops. */
			BM_elem_index_set(l_iter, totloops++); /* set_ok */

			/* Save index of correspsonding MLoop */
			CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
		} while ((l_iter = l_iter->next) != l_first);

		/* Copy Custom Data */
		CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);

		if (calc_face_normal) {
			BM_face_normal_update(f);
		}
	}

	bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* added in order, clear dirty flag */

	if (me->mselect && me->totselect != 0) {

		BMVert **vert_array = MEM_mallocN(sizeof(BMVert *) * bm->totvert, "VSelConv");
		BMEdge **edge_array = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, "ESelConv");
		BMFace **face_array = MEM_mallocN(sizeof(BMFace *) * bm->totface, "FSelConv");
		MSelect *msel;

#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
		{
#pragma omp section
			{ BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)vert_array, bm->totvert); }
#pragma omp section
			{ BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)edge_array, bm->totedge); }
#pragma omp section
			{ BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)face_array, bm->totface); }
		}

		for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) {
			switch (msel->type) {
				case ME_VSEL:
					BM_select_history_store(bm, (BMElem *)vert_array[msel->index]);
					break;
				case ME_ESEL:
					BM_select_history_store(bm, (BMElem *)edge_array[msel->index]);
					break;
				case ME_FSEL:
					BM_select_history_store(bm, (BMElem *)face_array[msel->index]);
					break;
			}
		}

		MEM_freeN(vert_array);
		MEM_freeN(edge_array);
		MEM_freeN(face_array);
	}
	else {
		me->totselect = 0;
		if (me->mselect) {
			MEM_freeN(me->mselect);
			me->mselect = NULL;
		}
	}

	MEM_freeN(vtable);
	MEM_freeN(etable);
}
Пример #21
0
int flute(CSOUND *csound, FLUTE *p)
{
    MYFLT       *ar = p->ar;
    uint32_t offset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT       amp = (*p->amp)*AMP_RSCALE; /* Normalise */
    MYFLT       temp;
    int         v_len = (int)p->vibr->flen;
    MYFLT       *v_data = p->vibr->ftable;
    MYFLT       v_time = p->v_time;
    MYFLT       vibGain = *p->vibAmt;
    MYFLT       jetRefl, endRefl, noisegain;

    if (amp!=p->lastamp) {      /* If amplitude has changed */
                     /* This should be controlled by attack */
      ADSR_setAttackRate(csound, &p->adsr, amp * FL(0.02));
      p->maxPress = (FL(1.1) + (amp * FL(0.20))) / FL(0.8);
      p->outputGain = amp + FL(0.001);
      p->lastamp = amp;
    }
    p->v_rate = *p->vibFreq * v_len * csound->onedsr;
                                /* Start SetFreq */
    if (p->lastFreq != *p->frequency) { /* It changed */
      p->lastFreq = *p->frequency;
      if (p->limit>p->lastFreq) {
        p->lastFreq = p->limit;
        csound->Warning(csound, Str("frequency too low, set to minimum"));
      }
      p->lastJet = *p->jetRatio;
      /* freq = (2/3)*p->frequency as we're overblowing here */
      /* but 1/(2/3) is 1.5 so multiply for speed */
                            /* Length - approx. filter delay */
      temp = FL(1.5)* CS_ESR / p->lastFreq - FL(2.0);
      DLineL_setDelay(&p->boreDelay, temp); /* Length of bore tube */
      DLineL_setDelay(&p->jetDelay, temp * p->lastJet); /* jet delay shorter */
    }
    else if (*p->jetRatio != p->lastJet) { /* Freq same but jet changed */
      p->lastJet = *p->jetRatio;
                                            /* Length - approx. filter delay */
      temp = FL(1.5)* CS_ESR / p->lastFreq - FL(2.0);
      DLineL_setDelay(&p->jetDelay, temp * p->lastJet); /* jet delay shorter */
    }
                                /* End SetFreq */

    if (p->kloop>FL(0.0) && p->h.insdshead->relesing) p->kloop=FL(1.0);
    if ((--p->kloop) == 0) {
      p->adsr.releaseRate = p->adsr.value / (*p->dettack * CS_ESR);
      p->adsr.target = FL(0.0);
      p->adsr.rate = p->adsr.releaseRate;
      p->adsr.state = RELEASE;
    }
    noisegain = *p->noiseGain; jetRefl = *p->jetRefl; endRefl = *p->endRefl;
    if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
    }
    for (n=offset;n<nsmps;n++) {
      int32     temp;
      MYFLT     temf;
      MYFLT     temp_time, alpha;
      MYFLT     pressDiff;
      MYFLT     randPress;
      MYFLT     breathPress;
      MYFLT     lastOutput;
      MYFLT     v_lastOutput;

      breathPress = p->maxPress * ADSR_tick(&p->adsr); /* Breath Pressure */
      randPress = noisegain*Noise_tick(csound,&p->noise); /* Random Deviation */
                                      /* Tick on vibrato table */
      v_time += p->v_rate;            /*  Update current time    */
      while (v_time >= v_len)         /*  Check for end of sound */
        v_time -= v_len;              /*  loop back to beginning */
      while (v_time < FL(0.0))        /*  Check for end of sound */
        v_time += v_len;              /*  loop back to beginning */

      temp_time = v_time;

#ifdef phase_offset
      if (p->v_phaseOffset != FL(0.0)) {
        temp_time += p->v_phaseOffset;/*  Add phase offset       */
        while (temp_time >= v_len)    /*  Check for end of sound */
          temp_time -= v_len;         /*  loop back to beginning */
        while (temp_time < FL(0.0))   /*  Check for end of sound */
          temp_time += v_len;         /*  loop back to beginning */
      }
#endif

      temp = (int32) temp_time;        /*  Integer part of time address    */
                                      /*  fractional part of time address */
      alpha = temp_time - (MYFLT)temp;
      v_lastOutput = v_data[temp];    /* Do linear interpolation */
      /*  same as alpha*data[temp+1] + (1-alpha)data[temp] */
      v_lastOutput += (alpha * (v_data[temp+1] - v_lastOutput));
                                      /* End of vibrato tick */
      randPress += vibGain * v_lastOutput; /* + breath vibrato       */
      randPress *= breathPress;            /* All scaled by Breath Pressure */
      temf = OnePole_tick(&p->filter, DLineL_lastOut(&p->boreDelay));
      temf = DCBlock_tick(&p->dcBlock, temf);   /* Block DC on reflection */
      pressDiff = breathPress + randPress       /* Breath Pressure   */
                     - (jetRefl * temf);        /*  - reflected      */
      pressDiff = DLineL_tick(&p->jetDelay, pressDiff);  /* Jet Delay Line */
      pressDiff = JetTabl_lookup(pressDiff)     /* Non-Lin Jet + reflected */
                     + (endRefl * temf);
                                       /* Bore Delay and "bell" filter  */
      lastOutput = FL(0.3) * DLineL_tick(&p->boreDelay, pressDiff);

      lastOutput *= p->outputGain;
      ar[n] = lastOutput*AMP_SCALE*FL(1.4);
    }

    p->v_time = v_time;
    return OK;
}
Пример #22
0
int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
{
	float dx, dx1;
	float y1, y2;
	float xo, yo;

	if ((!g->width) || (!g->height))
		return 1;

	if (g->build_tex == 0) {
		GlyphCacheBLF *gc = font->glyph_cache;

		if (font->max_tex_size == -1)
			glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size);

		if (gc->cur_tex == -1) {
			blf_glyph_cache_texture(font, gc);
			gc->x_offs = gc->pad;
			gc->y_offs = 0;
		}

		if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) {
			gc->x_offs = gc->pad;
			gc->y_offs += gc->max_glyph_height;

			if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) {
				gc->y_offs = 0;
				blf_glyph_cache_texture(font, gc);
			}
		}

		g->tex = gc->textures[gc->cur_tex];
		g->xoff = gc->x_offs;
		g->yoff = gc->y_offs;

		/* prevent glTexSubImage2D from failing if the character
		 * asks for pixels out of bounds, this tends only to happen
		 * with very small sizes (5px high or less) */
		if (UNLIKELY((g->xoff + g->width)  > gc->p2_width)) {
			g->width  -= (g->xoff + g->width)  - gc->p2_width;
			BLI_assert(g->width > 0);
		}
		if (UNLIKELY((g->yoff + g->height) > gc->p2_height)) {
			g->height -= (g->yoff + g->height) - gc->p2_height;
			BLI_assert(g->height > 0);
		}


		glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
		glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		glBindTexture(GL_TEXTURE_2D, g->tex);
		glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap);
		glPopClientAttrib();

		g->uv[0][0] = ((float)g->xoff) / ((float)gc->p2_width);
		g->uv[0][1] = ((float)g->yoff) / ((float)gc->p2_height);
		g->uv[1][0] = ((float)(g->xoff + g->width)) / ((float)gc->p2_width);
		g->uv[1][1] = ((float)(g->yoff + g->height)) / ((float)gc->p2_height);

		/* update the x offset for the next glyph. */
		gc->x_offs += (int)(BLI_rctf_size_x(&g->box) + gc->pad);

		gc->rem_glyphs--;
		g->build_tex = 1;
	}

	xo = 0.0f;
	yo = 0.0f;

	if (font->flags & BLF_SHADOW) {
		xo = x;
		yo = y;
		x += font->shadow_x;
		y += font->shadow_y;
	}

	dx = floor(x + g->pos_x);
	dx1 = dx + g->width;
	y1 = y + g->pos_y;
	y2 = y + g->pos_y - g->height;

	if (font->flags & BLF_CLIPPING) {
		if (!BLI_rctf_isect_pt(&font->clip_rec, dx + font->pos[0], y1 + font->pos[1]))
			return 0;
		if (!BLI_rctf_isect_pt(&font->clip_rec, dx + font->pos[0], y2 + font->pos[1]))
			return 0;
		if (!BLI_rctf_isect_pt(&font->clip_rec, dx1 + font->pos[0], y2 + font->pos[1]))
			return 0;
		if (!BLI_rctf_isect_pt(&font->clip_rec, dx1 + font->pos[0], y1 + font->pos[1]))
			return 0;
	}

	if (font->tex_bind_state != g->tex) {
		glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = g->tex));
	}

	if (font->flags & BLF_SHADOW) {

		switch (font->shadow) {
			case 3:
				blf_texture3_draw(font->shadow_col, g->uv, dx, y1, dx1, y2);
				break;
			case 5:
				blf_texture5_draw(font->shadow_col, g->uv, dx, y1, dx1, y2);
				break;
			default:
				glColor4fv(font->shadow_col);
				blf_texture_draw(g->uv, dx, y1, dx1, y2);
				break;
		}

		glColor4fv(font->orig_col);

		x = xo;
		y = yo;

		dx = floor(x + g->pos_x);
		dx1 = dx + g->width;
		y1 = y + g->pos_y;
		y2 = y + g->pos_y - g->height;
	}

	switch (font->blur) {
		case 3:
			blf_texture3_draw(font->orig_col, g->uv, dx, y1, dx1, y2);
			break;
		case 5:
			blf_texture5_draw(font->orig_col, g->uv, dx, y1, dx1, y2);
			break;
		default:
			blf_texture_draw(g->uv, dx, y1, dx1, y2);
			break;
	}

	return 1;
}
Пример #23
0
int brass(CSOUND *csound, BRASS *p)
{
    MYFLT *ar = p->ar;
    uint32_t offset = p->h.insdshead->ksmps_offset;
    uint32_t early  = p->h.insdshead->ksmps_no_end;
    uint32_t n, nsmps = CS_KSMPS;
    MYFLT amp = (*p->amp)*AMP_RSCALE; /* Normalise */
    MYFLT maxPressure = p->maxPressure = amp;
    int v_len = (int)p->vibr->flen;
    MYFLT *v_data = p->vibr->ftable;
    MYFLT vibGain = *p->vibAmt;
    MYFLT vTime = p->v_time;

    p->v_rate = *p->vibFreq * v_len * csound->onedsr;
    /*   vibr->setFreq(6.137); */
    /* vibrGain = 0.05; */            /* breath periodic vibrato component  */
    if (p->kloop>0 && p->h.insdshead->relesing) p->kloop=1;
    if ((--p->kloop) == 0) {
      ADSR_setReleaseRate(csound, &p->adsr, amp * FL(0.005));
      ADSR_keyOff(&p->adsr);
    }
    if (p->frq != *p->frequency) {             /* Set frequency if changed */
      p->frq = *p->frequency;
      if (p->limit > p->frq) {
        p->frq =p->limit;
        csound->Warning(csound, Str("frequency too low, set to minimum"));
      }
      p->slideTarget = (CS_ESR / p->frq * FL(2.0)) + FL(3.0);
                        /* fudge correction for filter delays */
       /*  we'll play a harmonic */
      if (DLineA_setDelay(csound, &p->delayLine, p->slideTarget)) return OK;
      p->lipTarget = p->frq;
      p->lipT = FL(0.0);                /* So other part is set */
    } /* End of set frequency */
    if (*p->liptension != p->lipT) {
      p->lipT = *p->liptension;
      LipFilt_setFreq(csound, &p->lipFilter,
                      p->lipTarget * (MYFLT)pow(4.0,(2.0* p->lipT) -1.0));
    }

    if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
    if (UNLIKELY(early)) {
      nsmps -= early;
      memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
    }
    for (n=offset;n<nsmps;n++) {
      MYFLT     breathPressure;
      MYFLT     lastOutput;
      int       temp;
      MYFLT     temp_time, alpha;
      MYFLT     v_lastOutput;
      MYFLT     ans;

      breathPressure = maxPressure * ADSR_tick(&p->adsr);
                                /* Tick on vibrato table */
      vTime += p->v_rate;            /*  Update current time    */
      while (vTime >= v_len)         /*  Check for end of sound */
        vTime -= v_len;              /*  loop back to beginning */
      while (vTime < FL(0.0))        /*  Check for end of sound */
        vTime += v_len;              /*  loop back to beginning */

      temp_time = vTime;

#ifdef phase_offset
      if (p->v_phaseOffset != FL(0.0)) {
        temp_time += p->v_phaseOffset;   /*  Add phase offset       */
        while (temp_time >= v_len)       /*  Check for end of sound */
          temp_time -= v_len;            /*  loop back to beginning */
        while (temp_time < FL(0.0))      /*  Check for end of sound */
          temp_time += v_len;            /*  loop back to beginning */
      }
#endif

      temp = (int) temp_time;            /*  Integer part of time address    */
                                         /*  fractional part of time address */
      alpha = temp_time - (MYFLT)temp;
      v_lastOutput = v_data[temp];  /* Do linear interpolation, same as */
      v_lastOutput +=               /*alpha*data[temp+1]+(1-alpha)data[temp] */
        (alpha * (v_data[temp+1] - v_lastOutput));
                                /* End of vibrato tick */
      breathPressure += vibGain * v_lastOutput;
      lastOutput =
        DLineA_tick(&p->delayLine,        /* bore delay  */
             DCBlock_tick(&p->dcBlock,    /* block DC    */
                LipFilt_tick(&p->lipFilter,
                             FL(0.3) * breathPressure, /* mouth input */
                                               /* and bore reflection */
                             FL(0.85) * p->delayLine.lastOutput)));
      ans = lastOutput*AMP_SCALE*FL(3.5);
      ar[n] = ans;
    }

    p->v_time = vTime;
    return OK;
}
Пример #24
0
static const_buf_t
rem_from_buf(const_buf_t b, const char *s, size_t z)
{
	static char *akaspc;
	static size_t akaspz;
	char *ap;

	if (UNLIKELY(s < b.d || s + z > b.d + b.z)) {
		/* definitely not in our array */
		return b;
	} else if (UNLIKELY(b.z > akaspz)) {
		akaspz = ((b.z - 1) / 64U + 1U) * 64U;
		akaspc = realloc(akaspc, akaspz);
	}
	/* S points to the element to delete */
	ap = akaspc;
	if (s > b.d) {
		/* cpy the stuff before S */
		memcpy(ap, b.d, (s - b.d));
		ap += s - b.d;
	}
	if (s - b.d + z < b.z) {
		/* cpy the stuff after S */
		b.z -= s - b.d + z;
		memcpy(ap, s + z, b.z);
		ap += b.z;
	}
	return (const_buf_t){.z = ap - akaspc, .d = akaspc};
}

static rtz_buf_t
get_name_r(rotz_t cp, rtz_vtxkey_t svtx)
{
	const_buf_t cb;

	if (UNLIKELY((cb = get_aliases(cp, svtx)).d == NULL)) {
		return (rtz_buf_t){0U};
	}
	/* we're interested in the first name only */
	cb.z = strlen(cb.d);
	return (rtz_buf_t){.z = cb.z, .d = strndup(cb.d, cb.z)};
}

static int
add_vertex(rotz_t cp, const char *v, size_t z, rtz_vtx_t i)
{
	if (UNLIKELY(put_vertex(cp, v, z, i) < 0)) {
		return -1;
	}
	/* act as though we're renaming the vertex */
	return rnm_vertex(cp, rtz_vtxkey(i), v, z);
}

static int
rem_vertex(rotz_t cp, rtz_vtx_t i, const char *v, size_t z)
{
	rtz_vtxkey_t vkey = rtz_vtxkey(i);
	const_buf_t al;
	int res = 0;

	/* get all them aliases */
	if (LIKELY((al = get_aliases(cp, vkey)).d != NULL)) {
		/* go through all names in the alias list */
		for (const char *x = al.d, *const ex = al.d + al.z;
		     x < ex; x += z + 1) {
			z = strlen(x);
			res += unput_vertex(cp, x, z);
		}
	} else {
		/* just to be sure */
		res += unput_vertex(cp, v, z);
	}
	res += unrnm_vertex(cp, rtz_vtxkey(i));
	return res;
}
Пример #25
0
MINLINE float sasqrtf(float fac)
{
	if (UNLIKELY(fac <= 0.0f)) return 0.0f;
	else                       return sqrtf(fac);
}
Пример #26
0
mp_size_t
mpn_gcdext (mp_ptr gp, mp_ptr up, mp_size_t *usizep,
	    mp_ptr ap, mp_size_t an, mp_ptr bp, mp_size_t n)
{
  mp_size_t talloc;
  mp_size_t scratch;
  mp_size_t matrix_scratch;
  mp_size_t ualloc = n + 1;

  mp_size_t un;
  mp_ptr u0;
  mp_ptr u1;

  mp_ptr tp;

  TMP_DECL;

  ASSERT (an >= n);
  ASSERT (n > 0);

  TMP_MARK;

  /* FIXME: Check for small sizes first, before setting up temporary
     storage etc. */
  talloc = MPN_GCDEXT_LEHMER_N_ITCH(n);

  /* For initial division */
  scratch = an - n + 1;
  if (scratch > talloc)
    talloc = scratch;

  if (ABOVE_THRESHOLD (n, GCDEXT_DC_THRESHOLD))
    {
      /* For hgcd loop. */
      mp_size_t hgcd_scratch;
      mp_size_t update_scratch;
      mp_size_t p1 = CHOOSE_P_1 (n);
      mp_size_t p2 = CHOOSE_P_2 (n);
      mp_size_t min_p = MIN(p1, p2);
      mp_size_t max_p = MAX(p1, p2);
      matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n - min_p);
      hgcd_scratch = mpn_hgcd_itch (n - min_p);
      update_scratch = max_p + n - 1;

      scratch = matrix_scratch + MAX(hgcd_scratch, update_scratch);
      if (scratch > talloc)
	talloc = scratch;

      /* Final mpn_gcdext_lehmer_n call. Need space for u and for
	 copies of a and b. */
      scratch = MPN_GCDEXT_LEHMER_N_ITCH (GCDEXT_DC_THRESHOLD)
	+ 3*GCDEXT_DC_THRESHOLD;

      if (scratch > talloc)
	talloc = scratch;

      /* Cofactors u0 and u1 */
      talloc += 2*(n+1);
    }

  tp = TMP_ALLOC_LIMBS(talloc);

  if (an > n)
    {
      mpn_tdiv_qr (tp, ap, 0, ap, an, bp, n);

      if (mpn_zero_p (ap, n))
	{
	  MPN_COPY (gp, bp, n);
	  *usizep = 0;
	  TMP_FREE;
	  return n;
	}
    }

  if (BELOW_THRESHOLD (n, GCDEXT_DC_THRESHOLD))
    {
      mp_size_t gn = mpn_gcdext_lehmer_n(gp, up, usizep, ap, bp, n, tp);

      TMP_FREE;
      return gn;
    }

  MPN_ZERO (tp, 2*ualloc);
  u0 = tp; tp += ualloc;
  u1 = tp; tp += ualloc;

  {
    /* For the first hgcd call, there are no u updates, and it makes
       some sense to use a different choice for p. */

    /* FIXME: We could trim use of temporary storage, since u0 and u1
       are not used yet. For the hgcd call, we could swap in the u0
       and u1 pointers for the relevant matrix elements. */

    struct hgcd_matrix M;
    mp_size_t p = CHOOSE_P_1 (n);
    mp_size_t nn;

    mpn_hgcd_matrix_init (&M, n - p, tp);
    nn = mpn_hgcd (ap + p, bp + p, n - p, &M, tp + matrix_scratch);
    if (nn > 0)
      {
	ASSERT (M.n <= (n - p - 1)/2);
	ASSERT (M.n + p <= (p + n - 1) / 2);

	/* Temporary storage 2 (p + M->n) <= p + n - 1 */
	n = mpn_hgcd_matrix_adjust (&M, p + nn, ap, bp, p, tp + matrix_scratch);

	MPN_COPY (u0, M.p[1][0], M.n);
	MPN_COPY (u1, M.p[1][1], M.n);
	un = M.n;
	while ( (u0[un-1] | u1[un-1] ) == 0)
	  un--;
      }
    else
      {
	/* mpn_hgcd has failed. Then either one of a or b is very
	   small, or the difference is very small. Perform one
	   subtraction followed by one division. */
	mp_size_t gn;
	mp_size_t updated_un = 1;

	u1[0] = 1;

	/* Temporary storage 2n + 1 */
	n = mpn_gcdext_subdiv_step (gp, &gn, up, usizep, ap, bp, n,
				    u0, u1, &updated_un, tp, tp + n);
	if (n == 0)
	  {
	    TMP_FREE;
	    return gn;
	  }

	un = updated_un;
	ASSERT (un < ualloc);
      }
  }

  while (ABOVE_THRESHOLD (n, GCDEXT_DC_THRESHOLD))
    {
      struct hgcd_matrix M;
      mp_size_t p = CHOOSE_P_2 (n);
      mp_size_t nn;

      mpn_hgcd_matrix_init (&M, n - p, tp);
      nn = mpn_hgcd (ap + p, bp + p, n - p, &M, tp + matrix_scratch);
      if (nn > 0)
	{
	  mp_ptr t0;

	  t0 = tp + matrix_scratch;
	  ASSERT (M.n <= (n - p - 1)/2);
	  ASSERT (M.n + p <= (p + n - 1) / 2);

	  /* Temporary storage 2 (p + M->n) <= p + n - 1 */
	  n = mpn_hgcd_matrix_adjust (&M, p + nn, ap, bp, p, t0);

	  /* By the same analysis as for mpn_hgcd_matrix_mul */
	  ASSERT (M.n + un <= ualloc);

	  /* FIXME: This copying could be avoided by some swapping of
	   * pointers. May need more temporary storage, though. */
	  MPN_COPY (t0, u0, un);

	  /* Temporary storage ualloc */
	  un = hgcd_mul_matrix_vector (&M, u0, t0, u1, un, t0 + un);

	  ASSERT (un < ualloc);
	  ASSERT ( (u0[un-1] | u1[un-1]) > 0);
	}
      else
	{
	  /* mpn_hgcd has failed. Then either one of a or b is very
	     small, or the difference is very small. Perform one
	     subtraction followed by one division. */
	  mp_size_t gn;
	  mp_size_t updated_un = un;

	  /* Temporary storage 2n + 1 */
	  n = mpn_gcdext_subdiv_step (gp, &gn, up, usizep, ap, bp, n,
				      u0, u1, &updated_un, tp, tp + n);
	  if (n == 0)
	    {
	      TMP_FREE;
	      return gn;
	    }

	  un = updated_un;
	  ASSERT (un < ualloc);
	}
    }

  if (UNLIKELY (mpn_cmp (ap, bp, n) == 0))
    {
      /* Must return the smallest cofactor, +u1 or -u0 */
      int c;

      MPN_COPY (gp, ap, n);

      MPN_CMP (c, u0, u1, un);
      ASSERT (c != 0);
      if (c < 0)
	{
	  MPN_NORMALIZE (u0, un);
	  MPN_COPY (up, u0, un);
	  *usizep = -un;
	}
      else
	{
	  MPN_NORMALIZE_NOT_ZERO (u1, un);
	  MPN_COPY (up, u1, un);
	  *usizep = un;
	}

      TMP_FREE;
      return n;
    }
  else if (mpn_zero_p (u0, un))
    {
      mp_size_t gn;
      ASSERT (un == 1);
      ASSERT (u1[0] == 1);

      /* g = u a + v b = (u u1 - v u0) A + (...) B = u A + (...) B */
      gn = mpn_gcdext_lehmer_n (gp, up, usizep, ap, bp, n, tp);

      TMP_FREE;
      return gn;
    }
  else
    {
      /* We have A = ... a + ... b
		 B =  u0 a +  u1 b

		 a = u1  A + ... B
		 b = -u0 A + ... B

	 with bounds

	   |u0|, |u1| <= B / min(a, b)

	 Compute g = u a + v b = (u u1 - v u0) A + (...) B
	 Here, u, v are bounded by

	 |u| <= b,
	 |v| <= a
      */

      mp_size_t u0n;
      mp_size_t u1n;
      mp_size_t lehmer_un;
      mp_size_t lehmer_vn;
      mp_size_t gn;

      mp_ptr lehmer_up;
      mp_ptr lehmer_vp;
      int negate;

      lehmer_up = tp; tp += n;

      /* Call mpn_gcdext_lehmer_n with copies of a and b. */
      MPN_COPY (tp, ap, n);
      MPN_COPY (tp + n, bp, n);
      gn = mpn_gcdext_lehmer_n (gp, lehmer_up, &lehmer_un, tp, tp + n, n, tp + 2*n);

      u0n = un;
      MPN_NORMALIZE (u0, u0n);
      if (lehmer_un == 0)
	{
	  /* u == 0  ==>  v = g / b == 1  ==> g = - u0 A + (...) B */
	  MPN_COPY (up, u0, u0n);
	  *usizep = -u0n;

	  TMP_FREE;
	  return gn;
	}

      lehmer_vp = tp;
      /* Compute v = (g - u a) / b */
      lehmer_vn = compute_v (lehmer_vp,
			     ap, bp, n, gp, gn, lehmer_up, lehmer_un, tp + n + 1);

      if (lehmer_un > 0)
	negate = 0;
      else
	{
	  lehmer_un = -lehmer_un;
	  negate = 1;
	}

      u1n = un;
      MPN_NORMALIZE (u1, u1n);

      /* It's possible that u0 = 1, u1 = 0 */
      if (u1n == 0)
	{
	  ASSERT (un == 1);
	  ASSERT (u0[0] == 1);

	  /* u1 == 0 ==> u u1 + v u0 = v */
	  MPN_COPY (up, lehmer_vp, lehmer_vn);
	  *usizep = negate ? lehmer_vn : - lehmer_vn;

	  TMP_FREE;
	  return gn;
	}

      ASSERT (lehmer_un + u1n <= ualloc);
      ASSERT (lehmer_vn + u0n <= ualloc);

      /* Now u0, u1, u are non-zero. We may still have v == 0 */

      /* Compute u u0 */
      if (lehmer_un <= u1n)
	/* Should be the common case */
	mpn_mul (up, u1, u1n, lehmer_up, lehmer_un);
      else
	mpn_mul (up, lehmer_up, lehmer_un, u1, u1n);

      un = u1n + lehmer_un;
      un -= (up[un - 1] == 0);

      if (lehmer_vn > 0)
	{
	  mp_limb_t cy;

	  /* Overwrites old u1 value */
	  if (lehmer_vn <= u0n)
	    /* Should be the common case */
	    mpn_mul (u1, u0, u0n, lehmer_vp, lehmer_vn);
	  else
	    mpn_mul (u1, lehmer_vp, lehmer_vn, u0, u0n);

	  u1n = u0n + lehmer_vn;
	  u1n -= (u1[u1n - 1] == 0);

	  if (u1n <= un)
	    {
	      cy = mpn_add (up, up, un, u1, u1n);
	    }
	  else
	    {
	      cy = mpn_add (up, u1, u1n, up, un);
	      un = u1n;
	    }
	  up[un] = cy;
	  un += (cy != 0);

	  ASSERT (un < ualloc);
	}
      *usizep = negate ? -un : un;

      TMP_FREE;
      return gn;
    }
}
Пример #27
0
MINLINE double sqrt3d(double d)
{
	if      (UNLIKELY(d == 0.0)) return 0.0;
	else if (UNLIKELY(d <  0.0)) return -exp(log(-d) / 3.0);
	else                         return  exp(log( d) / 3.0);
}
Пример #28
0
static bool scanfill_preprocess_self_isect(
        ScanFillContext *sf_ctx,
        PolyInfo *poly_info,
        const unsigned short poly_nr,
        ListBase *filledgebase)
{
	PolyInfo *pi = &poly_info[poly_nr];
	GHash *isect_hash = NULL;
	ListBase isect_lb = {NULL};

	/* warning, O(n2) check here, should use spatial lookup */
	{
		ScanFillEdge *eed;

		for (eed = pi->edge_first;
		     eed;
		     eed = (eed == pi->edge_last) ? NULL : eed->next)
		{
			ScanFillEdge *eed_other;

			for (eed_other = eed->next;
			     eed_other;
			     eed_other = (eed_other == pi->edge_last) ? NULL : eed_other->next)
			{
				if (!ELEM(eed->v1, eed_other->v1, eed_other->v2) &&
				    !ELEM(eed->v2, eed_other->v1, eed_other->v2) &&
				    (eed != eed_other))
				{
					/* check isect */
					float pt[2];
					BLI_assert(eed != eed_other);

					if (isect_seg_seg_v2_point(eed->v1->co, eed->v2->co,
					                           eed_other->v1->co, eed_other->v2->co,
					                           pt) == 1)
					{
						ScanFillIsect *isect;

						if (UNLIKELY(isect_hash == NULL)) {
							isect_hash = BLI_ghash_ptr_new(__func__);
						}

						isect = MEM_mallocN(sizeof(ScanFillIsect), __func__);

						BLI_addtail(&isect_lb, isect);

						copy_v2_v2(isect->co, pt);
						isect->co[2] = eed->v1->co[2];
						isect->v = BLI_scanfill_vert_add(sf_ctx, isect->co);
						isect->v->poly_nr = eed->v1->poly_nr;  /* NOTE: vert may belong to 2 polys now */
						VFLAG_SET(isect->v, V_ISISECT);
						edge_isect_ls_add(isect_hash, eed, isect);
						edge_isect_ls_add(isect_hash, eed_other, isect);
					}
				}
			}
		}
	}

	if (isect_hash == NULL) {
		return false;
	}

	/* now subdiv the edges */
	{
		ScanFillEdge *eed;

		for (eed = pi->edge_first;
		     eed;
		     eed = (eed == pi->edge_last) ? NULL : eed->next)
		{
			if (eed->user_flag & E_ISISECT) {
				ListBase *e_ls = BLI_ghash_lookup(isect_hash, eed);

				LinkData *isect_link;

				/* maintain coorect terminating edge */
				if (pi->edge_last == eed) {
					pi->edge_last = NULL;
				}

				if (BLI_listbase_is_single(e_ls) == false) {
					BLI_sortlist_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb);
				}

				/* move original edge to filledgebase and add replacement
				 * (which gets subdivided next) */
				{
					ScanFillEdge *eed_tmp;
					eed_tmp = BLI_scanfill_edge_add(sf_ctx, eed->v1, eed->v2);
					BLI_remlink(&sf_ctx->filledgebase, eed_tmp);
					BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_tmp);
					BLI_remlink(&sf_ctx->filledgebase, eed);
					BLI_addtail(filledgebase, eed);
					if (pi->edge_first == eed) {
						pi->edge_first = eed_tmp;
					}
					eed = eed_tmp;
				}

				for (isect_link = e_ls->first; isect_link; isect_link = isect_link->next) {
					ScanFillIsect *isect = isect_link->data;
					ScanFillEdge *eed_subd;

					eed_subd = BLI_scanfill_edge_add(sf_ctx, isect->v, eed->v2);
					eed_subd->poly_nr = poly_nr;
					eed->v2 = isect->v;

					BLI_remlink(&sf_ctx->filledgebase, eed_subd);
					BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_subd);

					/* step to the next edge and continue dividing */
					eed = eed_subd;
				}

				BLI_freelistN(e_ls);
				MEM_freeN(e_ls);

				if (pi->edge_last == NULL) {
					pi->edge_last = eed;
				}
			}
		}
	}

	BLI_freelistN(&isect_lb);
	BLI_ghash_free(isect_hash, NULL, NULL);

	{
		ScanFillEdge *e_init;
		ScanFillEdge *e_curr;
		ScanFillEdge *e_next;

		ScanFillVert *v_prev;
		ScanFillVert *v_curr;

		int inside = false;

		/* first vert */
#if 0
		e_init = pi->edge_last;
		e_curr = e_init;
		e_next = pi->edge_first;

		v_prev = e_curr->v1;
		v_curr = e_curr->v2;
#else

		/* find outside vertex */
		{
			ScanFillEdge *eed;
			ScanFillEdge *eed_prev;
			float min_x = FLT_MAX;

			e_curr = pi->edge_last;
			e_next = pi->edge_first;

			eed_prev = pi->edge_last;
			for (eed = pi->edge_first;
			     eed;
			     eed = (eed == pi->edge_last) ? NULL : eed->next)
			{
				if (eed->v2->co[0] < min_x) {
					min_x = eed->v2->co[0];
					e_curr = eed_prev;
					e_next = eed;

				}
				eed_prev = eed;
			}

			e_init = e_curr;
			v_prev = e_curr->v1;
			v_curr = e_curr->v2;
		}
#endif

		BLI_assert(e_curr->poly_nr == poly_nr);
		BLI_assert(pi->edge_last->poly_nr == poly_nr);

		do {
			ScanFillVert *v_next;

			v_next = (e_next->v1 == v_curr) ? e_next->v2 : e_next->v1;
			BLI_assert(ELEM(v_curr, e_next->v1, e_next->v2));

			/* track intersections */
			if (inside) {
				EFLAG_SET(e_next, E_ISDELETE);
			}
			if (v_next->user_flag & V_ISISECT) {
				inside = !inside;
			}
			/* now step... */

			v_prev = v_curr;
			v_curr = v_next;
			e_curr = e_next;

			e_next = edge_step(poly_info, poly_nr, v_prev, v_curr, e_curr);

		} while (e_curr != e_init);
	}

	return true;
}
Пример #29
0
MINLINE float saasin(float fac)
{
	if      (UNLIKELY(fac <= -1.0f)) return (float)-M_PI / 2.0f;
	else if (UNLIKELY(fac >=  1.0f)) return (float) M_PI / 2.0f;
	else                             return asinf(fac);
}
Пример #30
0
CachedUnit loadUnitNonRepoAuth(StringData* requestedPath,
                               const struct stat* statInfo,
                               OptLog& ent,
                               const Native::FuncTable& nativeFuncs,
                               const RepoOptions& options,
                               FileLoadFlags& flags) {
  LogTimer loadTime("load_ms", ent);
  if (strstr(requestedPath->data(), "://") != nullptr) {
    // URL-based units are not currently cached in memory, but the Repo still
    // caches them on disk.
    return createUnitFromUrl(requestedPath, nativeFuncs, flags);
  }

  rqtrace::EventGuard trace{"WRITE_UNIT"};

  // The string we're using as a key must be static, because we're using it as
  // a key in the cache (across requests).
  auto const path =
    makeStaticString(
      // XXX: it seems weird we have to do this even though we already ran
      // resolveVmInclude.
      (FileUtil::isAbsolutePath(requestedPath->toCppString())
       ?  String{requestedPath}
        : String(SourceRootInfo::GetCurrentSourceRoot()) + StrNR(requestedPath)
      ).get()
    );

  auto const rpath = [&] () -> const StringData* {
    if (RuntimeOption::CheckSymLink) {
      std::string rp = StatCache::realpath(path->data());
      if (rp.size() != 0) {
        if (rp.size() != path->size() ||
            memcmp(rp.data(), path->data(), rp.size())) {
          return makeStaticString(rp);
        }
      }
    }
    return path;
  }();

  Stream::Wrapper* w = nullptr;
  auto& cache = getNonRepoCache(rpath, w);

  assertx(
    !w || &cache != &s_nonRepoUnitCache ||
    !RuntimeOption::EvalUnixServerQuarantineUnits
  );

  // Freeing a unit while holding the tbb lock would cause a rank violation when
  // recycle-tc is enabled as reclaiming dead functions requires that the code
  // and metadata locks be acquired.
  Unit* releaseUnit = nullptr;
  SCOPE_EXIT { if (releaseUnit) delete releaseUnit; };

  auto const updateAndUnlock = [] (auto& cachedUnit, auto p) {
    auto old = cachedUnit.update_and_unlock(std::move(p));
    if (old) {
      // We don't need to do anything explicitly; the copy_ptr
      // destructor will take care of it.
      Treadmill::enqueue([unit_to_delete = std::move(old)] () {});
    }
  };

  auto cuptr = [&] {
    NonRepoUnitCache::const_accessor rpathAcc;

    cache.insert(rpathAcc, rpath);
    auto& cachedUnit = rpathAcc->second.cachedUnit;
    if (auto const tmp = cachedUnit.copy()) {
      if (!isChanged(tmp, statInfo, options)) {
        flags = FileLoadFlags::kHitMem;
        if (ent) ent->setStr("type", "cache_hit_readlock");
        return tmp;
      }
    }

    cachedUnit.lock_for_update();
    try {
      if (auto const tmp = cachedUnit.copy()) {
        if (!isChanged(tmp, statInfo, options)) {
          cachedUnit.unlock();
          flags = FileLoadFlags::kWaited;
          if (ent) ent->setStr("type", "cache_hit_writelock");
          return tmp;
        }
        if (ent) ent->setStr("type", "cache_stale");
      } else {
        if (ent) ent->setStr("type", "cache_miss");
      }

      trace.finish();
      auto const cu = createUnitFromFile(rpath, &releaseUnit, w, ent,
                                         nativeFuncs, options, flags);
      auto const isICE = cu.unit && cu.unit->isICE();
      auto p = copy_ptr<CachedUnitWithFree>(cu, statInfo, isICE, options);
      // Don't cache the unit if it was created in response to an internal error
      // in ExternCompiler. Such units represent transient events.
      if (UNLIKELY(isICE)) {
        cachedUnit.unlock();
        return p;
      }
      updateAndUnlock(cachedUnit, p);
      return p;
    } catch (...) {
      cachedUnit.unlock();
      throw;
    }
  }();

  auto const ret = cuptr->cu;

  if (!ret.unit || !ret.unit->isICE()) {
    if (path != rpath) {
      NonRepoUnitCache::const_accessor pathAcc;
      cache.insert(pathAcc, path);
      if (pathAcc->second.cachedUnit.get().get() != cuptr) {
        auto& cachedUnit = pathAcc->second.cachedUnit;
        cachedUnit.lock_for_update();
        updateAndUnlock(cachedUnit, std::move(cuptr));
      }
    }
  }

  return ret;
}