Пример #1
0
void cPack_onMessage(HvBase *_c, ControlPack *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  // ensure let index is less than number elements in internal msg
  int numElements = msg_getNumElements(o->msg);
  switch (letIn) {
    case 0: { // first inlet stores all values of input msg and triggers an output
      for (int i = hv_min_i(numElements, msg_getNumElements(m))-1; i >= 0; --i) {
        switch (msg_getType(m, i)) {
          case HV_MSG_FLOAT: msg_setFloat(o->msg, i, msg_getFloat(m, i)); break;
          case HV_MSG_SYMBOL:
          case HV_MSG_HASH: msg_setHash(o->msg, i, msg_getHash(m, i)); break;
          default: break;
        }
      }
      msg_setTimestamp(o->msg, msg_getTimestamp(m));
      sendMessage(_c, 0, o->msg);
      break;
    }
    default: { // rest of inlets just store values
      switch (msg_getType(m, 0)) {
        case HV_MSG_FLOAT: msg_setFloat(o->msg, letIn, msg_getFloat(m, 0)); break;
        case HV_MSG_SYMBOL:
        case HV_MSG_HASH: msg_setHash(o->msg, letIn, msg_getHash(m, 0)); break;
        default: break;
      }
      break;
    }
  }
}
Пример #2
0
void sTabwrite_onMessage(HvBase *_c, SignalTabwrite *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  switch (letIn) {
    // inlet 0 is the signal inlet
    case 1: {
      switch (msg_getType(m,0)) {
        case BANG: o->head = 0; break;
        case FLOAT: {
          o->head = (msg_getFloat(m,0) >= 0.0f) ? (hv_uint32_t) msg_getFloat(m,0) : HV_TABWRITE_STOPPED;
          break;
        }
        case SYMBOL: {
          if (msg_compareSymbol(m, 0, "stop")) {
            o->head = HV_TABWRITE_STOPPED;
          }
          break;
        }
        default: break;
      }
      break;
    }
    case 2: {
      if (msg_isHashLike(m,0)) {
        o->table = ctx_getTableForHash(_c, msg_getHash(m,0));
      }
      break;
    }
    default: break;
  }
}
Пример #3
0
void cTabwrite_onMessage(HvBase *_c, ControlTabwrite *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  switch (letIn) {
    case 0: {
      if (msg_isFloat(m,0) && o->table != NULL) {
        hTable_getBuffer(o->table)[o->x] = msg_getFloat(m,0); // update Y value
      }
      break;
    }
    case 1: {
      if (msg_isFloat(m,0) && o->table != NULL) {
        const int x = (int) msg_getFloat(m,0);
        if (x >= 0 && x < hTable_getSize(o->table)) {
          o->x = x; // update X value
        }
      }
      break;
    }
    case 2: {
      if (msg_isHashLike(m,0)) {
        o->table = ctx_getTableForHash(_c,msg_getHash(m,0)); // update table
      }
      break;
    }
    default: return;
  }
}
Пример #4
0
void cDelay_onMessage(HvBase *_c, ControlDelay *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  switch (letIn) {
    case 0: {
      if (msg_compareSymbol(m, 0, "flush")) {
        // send all messages immediately
        for (int i = 0; i < __HV_DELAY_MAX_MESSAGES; i++) {
          HvMessage *n = o->msgs[i];
          if (n != NULL) {
            msg_setTimestamp(n, msg_getTimestamp(m)); // update the timestamp to now
            sendMessage(_c, 0, n); // send the message
            ctx_cancelMessage(_c, n, sendMessage); // then clear it
            // NOTE(mhroth): there may be a problem here if a flushed message causes a clear message to return
            // to this object in the same step
          }
        }
        hv_memset(o->msgs, __HV_DELAY_MAX_MESSAGES*sizeof(HvMessage *));
      } else if (msg_compareSymbol(m, 0, "clear")) {
        // cancel (clear) all (pending) messages
        for (int i = 0; i < __HV_DELAY_MAX_MESSAGES; i++) {
          HvMessage *n = o->msgs[i];
          if (n != NULL) {
            ctx_cancelMessage(_c, n, sendMessage);
          }
        }
        hv_memset(o->msgs, __HV_DELAY_MAX_MESSAGES*sizeof(HvMessage *));
      } else {
        hv_uint32_t ts = msg_getTimestamp(m);
        msg_setTimestamp((HvMessage *) m, ts+o->delay); // update the timestamp to set the delay
        int i;
        for (i = 0; i < __HV_DELAY_MAX_MESSAGES; i++) {
          if (o->msgs[i] == NULL) {
            o->msgs[i] = ctx_scheduleMessage(_c, m, sendMessage, 0);
            break;
          }
        }
        hv_assert(i < __HV_DELAY_MAX_MESSAGES); // scheduled message limit reached
        msg_setTimestamp((HvMessage *) m, ts); // return to the original timestamp
      }
      break;
    }
    case 1: {
      if (msg_isFloat(m,0)) {
        // set delay in milliseconds
        o->delay = ctx_millisecondsToSamples(_c,msg_getFloat(m,0));
      }
      break;
    }
    case 2: {
      if (msg_isFloat(m,0)) {
        // set delay in samples
        o->delay = (hv_uint32_t) msg_getFloat(m,0);
      }
      break;
    }
    default: break;
  }
}
Пример #5
0
void sBiquad_k_onMessage(SignalBiquad_k *o, int letIn, const HvMessage *const m) {
  if (msg_isFloat(m,0)) {
    switch (letIn) {
      case 1: o->b0 = msg_getFloat(m,0); break;
      case 2: o->b1 = msg_getFloat(m,0); break;
      case 3: o->b2 = msg_getFloat(m,0); break;
      case 4: o->a1 = msg_getFloat(m,0); break;
      case 5: o->a2 = msg_getFloat(m,0); break;
      default: return;
    }
    sBiquad_k_updateCoefficients(o);
  }
}
void cVar_onMessage(HvBase *_c, ControlVar *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  switch (letIn) {
    case 0: {
      switch (msg_getType(m,0)) {
        case HV_MSG_BANG: {
          HvMessage *n = HV_MESSAGE_ON_STACK(1);
          if (o->e.type == HV_MSG_FLOAT) msg_initWithFloat(n, msg_getTimestamp(m), o->e.data.f);
          else if (o->e.type == HV_MSG_HASH) msg_initWithHash(n, msg_getTimestamp(m), o->e.data.h);
          else return;
          sendMessage(_c, 0, n);
          break;
        }
        case HV_MSG_FLOAT: {
          o->e.type = HV_MSG_FLOAT;
          o->e.data.f = msg_getFloat(m,0);
          sendMessage(_c, 0, m);
          break;
        }
        case HV_MSG_SYMBOL:
        case HV_MSG_HASH: {
          o->e.type = HV_MSG_HASH;
          o->e.data.h = msg_getHash(m,0);
          sendMessage(_c, 0, m);
          break;
        }
        default: return;
      }
      break;
    }
    case 1: {
      switch (msg_getType(m,0)) {
        case HV_MSG_FLOAT: {
          o->e.type = HV_MSG_FLOAT;
          o->e.data.f = msg_getFloat(m,0);
          break;
        }
        case HV_MSG_SYMBOL:
        case HV_MSG_HASH: {
          o->e.type = HV_MSG_HASH;
          o->e.data.h = msg_getHash(m,0);
          break;
        }
        default: break;
      }
    }
    default: return;
  }
}
Пример #7
0
void sSamphold_onMessage(HvBase *_c, SignalSamphold *o, int letIndex,
                         const HvMessage *const m, void *sendMessage) {
    switch (letIndex) {
    case 2: {
        if (msg_isFloat(m,0)) {
#if HV_SIMD_AVX
            o->s = _mm256_set1_ps(msg_getFloat(m,0));
#elif HV_SIMD_SSE
            o->s = _mm_set1_ps(msg_getFloat(m,0));
#elif HV_SIMD_NEON
            o->s = vdupq_n_f32(msg_getFloat(m,0));
#else
            o->s = msg_getFloat(m,0);
#endif
        }
        break;
    }
    default:
        break;
    }
}
Пример #8
0
void cSlice_onMessage(HvBase *_c, ControlSlice *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  switch (letIn) {
    case 0: {
      // if the start point is greater than the number of elements in the source message, do nothing
      if (o->i < msg_getNumElements(m)) {
        int x = msg_getNumElements(m) - o->i; // number of elements in the new message
        if (o->n > 0) x = hv_min_i(x, o->n);
        HvMessage *n = HV_MESSAGE_ON_STACK(x);
        msg_init(n, x, msg_getTimestamp(m));
        hv_memcpy(&n->elem, &m->elem+o->i, x*sizeof(Element));
        sendMessage(_c, 0, n);
      } else {
        // if nothing can be sliced, send a bang out of the right outlet
        HvMessage *n = HV_MESSAGE_ON_STACK(1);
        msg_initWithBang(n, msg_getTimestamp(m));
        sendMessage(_c, 1, n);
      }
      break;
    }
    case 1: {
      if (msg_isFloat(m,0)) {
        o->i = (int) msg_getFloat(m,0);
        if (msg_isFloat(m,1)) {
          o->n = (int) msg_getFloat(m,1);
        }
      }
      break;
    }
    case 2: {
      if (msg_isFloat(m,0)) {
        o->n = (int) msg_getFloat(m,0);
      }
      break;
    }
    default: break;
  }
}
Пример #9
0
void cTabread_onMessage(HvBase *_c, ControlTabread *o, int letIn, const HvMessage *const m,
    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
  switch (letIn) {
    case 0: {
      if (msg_isFloat(m,0) && msg_getFloat(m,0) >= 0.0f && o->table != NULL) {
        const hv_uint32_t x = (hv_uint32_t) msg_getFloat(m,0);
        if (x < hTable_getSize(o->table)) {
          HvMessage *n = HV_MESSAGE_ON_STACK(1);
          msg_initWithFloat(n, msg_getTimestamp(m), hTable_getBuffer(o->table)[x]);
          sendMessage(_c, 0, n);
        }
      }
      break;
    }
    case 1: {
      if (msg_isHashLike(m,0)) {
        o->table = ctx_getTableForHash(_c, msg_getHash(m,0));
      }
      break;
    }
    default: return;
  }
}
Пример #10
0
void sLine_onMessage(HvBase *_c, SignalLine *o, int letIn,
  const HvMessage * const m, void *sendMessage) {
  if (msg_isFloat(m,0)) {
    if (msg_isFloat(m,1)) {
      // new ramp
      int n = ctx_millisecondsToSamples(_c, msg_getFloat(m,1));
#if HV_SIMD_AVX
      float x = (o->n[1] > 0) ? (o->x[7] + (o->m[7]/8.0f)) : o->t[7]; // current output value
      float s = (msg_getFloat(m,0) - x) / ((float) n); // slope per sample
      o->n = _mm_set_epi32(n-3, n-2, n-1, n);
      o->x = _mm256_set_ps(x+7.0f*s, x+6.0f*s, x+5.0f*s, x+4.0f*s, x+3.0f*s, x+2.0f*s, x+s, x);
      o->m = _mm256_set1_ps(8.0f*s);
      o->t = _mm256_set1_ps(msg_getFloat(m,0));
#elif HV_SIMD_SSE
      float x = (o->n[1] > 0) ? (o->x[3] + (o->m[3]/4.0f)) : o->t[3];
      float s = (msg_getFloat(m,0) - x) / ((float) n); // slope per sample
      o->n = _mm_set_epi32(n-3, n-2, n-1, n);
      o->x = _mm_set_ps(x+3.0f*s, x+2.0f*s, x+s, x);
      o->m = _mm_set1_ps(4.0f*s);
      o->t = _mm_set1_ps(msg_getFloat(m,0));
#elif HV_SIMD_NEON
      float x = (o->n[3] > 0) ? (o->x[3] + (o->m[3]/4.0f)) : o->t[3];
      float s = (msg_getFloat(m,0) - x) / ((float) n);
      o->n = (int32x4_t) {n, n-1, n-2, n-3};
      o->x = (float32x4_t) {x, x+s, x+2.0f*s, x+3.0f*s};
      o->m = vdupq_n_f32(4.0f*s);
      o->t = vdupq_n_f32(msg_getFloat(m,0));
#else // HV_SIMD_NONE
      o->x = (o->n > 0) ? (o->x + o->m) : o->t; // new current value
      o->n = n; // new distance to target
      o->m = (msg_getFloat(m,0) - o->x) / ((float) n); // slope per sample
      o->t = msg_getFloat(m,0);
#endif
    } else {
      // Jump to value
#if HV_SIMD_AVX
      o->n = _mm_setzero_si128();
      o->x = _mm256_set1_ps(msg_getFloat(m,0));
      o->m = _mm256_setzero_ps();
      o->t = _mm256_set1_ps(msg_getFloat(m,0));
#elif HV_SIMD_SSE
      o->n = _mm_setzero_si128();
      o->x = _mm_set1_ps(msg_getFloat(m,0));
      o->m = _mm_setzero_ps();
      o->t = _mm_set1_ps(msg_getFloat(m,0));
#elif HV_SIMD_NEON
      o->n = vdupq_n_s32(0);
      o->x = vdupq_n_f32(0.0f);
      o->m = vdupq_n_f32(0.0f);
      o->t = vdupq_n_f32(0.0f);
#else // HV_SIMD_NONE
      o->n = 0;
      o->x = msg_getFloat(m,0);
      o->m = 0.0f;
      o->t = msg_getFloat(m,0);
#endif
    }
  } else if (msg_compareSymbol(m,0,"stop")) {
    // Stop line at current position
#if HV_SIMD_AVX
    // note o->n[1] is a 64-bit integer; two packed 32-bit ints. We only want to know if the high int is positive,
    // which can be done simply by testing the long int for positiveness.
    float x = (o->n[1] > 0) ? (o->x[7] + (o->m[7]/8.0f)) : o->t[7];
    o->n = _mm_setzero_si128();
    o->x = _mm256_set1_ps(x);
    o->m = _mm256_setzero_ps();
    o->t = _mm256_set1_ps(x);
#elif HV_SIMD_SSE
    float x = (o->n[1] > 0) ? (o->x[3] + (o->m[3]/4.0f)) : o->t[3];
    o->n = _mm_setzero_si128();
    o->x = _mm_set1_ps(x);
    o->m = _mm_setzero_ps();
    o->t = _mm_set1_ps(x);
#elif HV_SIMD_NEON
    float x = (o->n[3] > 0) ? (o->x[3] + (o->m[3]/4.0f)) : o->t[3];
    o->n = vdupq_n_s32(0);
    o->x = vdupq_n_f32(x);
    o->m = vdupq_n_f32(0.0f);
    o->t = vdupq_n_f32(x);
#else // HV_SIMD_NONE
    o->n = 0;
    o->x += o->m;
    o->m = 0.0f;
    o->t = o->x;
#endif
  }
}
Пример #11
0
float hv_msg_getFloat(const HvMessage *const m, int i) {
  return msg_getFloat(m,i);
}