Пример #1
0
void mtx_copy(float32_t eps) {
  float32_t errf;
  ambix_matrix_t *left=NULL, *right=NULL;
  unsigned int i;
  float32_t maxeps=eps;

  STARTTEST("\n");

  right=ambix_matrix_copy(left, NULL);
  fail_if((NULL!=right), __LINE__, "copying from NULL matrix erroneously succeeded");

  left=ambix_matrix_create();
  fail_if((left !=ambix_matrix_init(4, 3, left )), __LINE__, "initializing left matrix failed");
  ambix_matrix_fill_data(left, leftdata_4_3);

  right=ambix_matrix_copy(left, NULL);
  fail_if((NULL==right), __LINE__, "copying to NULL matrix failed");
  errf=matrix_diff(__LINE__, left, right, eps);
  fail_if(errf>0.f, __LINE__, "diffing mtx with copy0 returned %g (>%g)", errf, 0.f);

  right=ambix_matrix_copy(left, right);
  fail_if((NULL==right), __LINE__, "copying to right matrix failed");
  errf=matrix_diff(__LINE__, left, right, eps);
  fail_if(errf>0.f, __LINE__, "diffing mtx with copy returned %g (>%g)", errf, 0.f);

  ambix_matrix_destroy(left);
  ambix_matrix_destroy(right);
  STOPTEST("\n");

}
Пример #2
0
ambix_err_t ambix_set_adaptormatrix	(ambix_t*ambix, const ambix_matrix_t*matrix) {
  if(0) {
  } else if((ambix->filemode & AMBIX_READ ) && (AMBIX_BASIC   == ambix->info.fileformat)) {
    ambix_matrix_t*mtx=NULL;
    /* multiply the matrix with the previous adaptor matrix */
    if(AMBIX_EXTENDED == ambix->realinfo.fileformat) {
      mtx=ambix_matrix_multiply(matrix, &ambix->matrix, &ambix->matrix2);
      if(mtx != &ambix->matrix2)
        return AMBIX_ERR_UNKNOWN;
      ambix->use_matrix=2;
      return AMBIX_ERR_SUCCESS;
    } else {
      if(matrix->cols != ambix->realinfo.ambichannels) {
        return AMBIX_ERR_INVALID_DIMENSION;
      }
      mtx=ambix_matrix_copy(matrix, &ambix->matrix2);
      ambix->use_matrix=2;
    }
  } else if((ambix->filemode & AMBIX_WRITE) && (AMBIX_EXTENDED == ambix->info.fileformat)) {
    /* too late, writing started already */
    if(ambix->startedWriting)
      return AMBIX_ERR_UNKNOWN;

    /* check whether the matrix will expand to a full set */
    if(!ambix_is_fullset(matrix->rows))
      return AMBIX_ERR_INVALID_DIMENSION;

    if(!ambix_matrix_copy(matrix, &ambix->matrix))
      return AMBIX_ERR_UNKNOWN;
    /* ready to write it to file */
    ambix->pendingHeaders=1;
    return AMBIX_ERR_SUCCESS;
  }

  return AMBIX_ERR_UNKNOWN;
}
Пример #3
0
ambix_matrix_t*
ambix_matrix_fill(ambix_matrix_t*matrix, ambix_matrixtype_t typ) {
  int32_t rows=matrix->rows;
  int32_t cols=matrix->cols;
  int32_t r, c;
  float32_t**mtx=matrix->data;
  ambix_matrix_t*result=NULL;

  switch(typ) {
  default:
    return NULL;
  case (AMBIX_MATRIX_ZERO):
    for(r=0; r<rows; r++) {
      for(c=0; c<cols; c++)
        mtx[r][c]=0.;
    }
    break;
  case (AMBIX_MATRIX_ONE):
    for(r=0; r<rows; r++) {
      for(c=0; c<cols; c++)
        mtx[r][c]=1.;
    }
    break;
  case (AMBIX_MATRIX_IDENTITY):
    for(r=0; r<rows; r++) {
      for(c=0; c<cols; c++)
        mtx[r][c]=(float32_t)((r==c)?1.:0.);
    }
    break;

  case (AMBIX_MATRIX_FUMA): /* Furse Malham -> ACN/SN3D */
    result=_matrix_fuma2ambix(cols);
    if(!result)
      return NULL;
    matrix=ambix_matrix_copy(result, matrix);
    break;
  case (AMBIX_MATRIX_TO_FUMA): /* Furse Malham -> ACN/SN3D */
    result=_matrix_ambix2fuma(rows);
    if(!result)
      return NULL;
    matrix=ambix_matrix_copy(result, matrix);
    break;

  case (AMBIX_MATRIX_SID): /* SID -> ACN */ {
    float32_t*ordering=(float32_t*)malloc(rows*sizeof(float32_t));
    if(!ordering)
      return NULL;
    if(!_matrix_sid2acn(ordering, rows)) {
      free(ordering);
      return NULL;
    }
    matrix=_matrix_router(matrix, ordering, rows, 0);
    free(ordering);
  }
    break;
  case (AMBIX_MATRIX_TO_SID): /* ACN -> SID */ {
    float32_t*ordering=(float32_t*)malloc(rows*sizeof(float32_t));
    if(!_matrix_sid2acn(ordering, rows)) {
      free(ordering);
      return NULL;
    }
    matrix=_matrix_router(matrix, ordering, rows, 1);
    free(ordering);
  }
    break;


  case (AMBIX_MATRIX_N3D): /* N3D -> SN3D */ {
    float32_t*weights=NULL, *w_=NULL;
    int32_t counter=0;
    int32_t o=0, order=ambix_channels2order(rows);
    if(order<0)
      return NULL;
    weights=(float32_t*)malloc(rows*sizeof(float32_t));
    w_=weights;
    for(o=0; o<=order; o++) {
      const float32_t w=(float32_t)(1./sqrt(2.*o+1.));
      int32_t i;
      for(i=0; i<(2*o+1); i++) {
        *w_++=w;
        counter++;
      }
    }
    matrix=_matrix_diag(matrix, weights, rows);
    free(weights);
  }
    break;
  case (AMBIX_MATRIX_TO_N3D): /* SN3D -> N3D */ {
    float32_t*weights=NULL, *w_=NULL;
    int32_t counter=0;
    int32_t o, order=ambix_channels2order(rows);
    if(order<0)
      return NULL;
    weights=(float32_t*)malloc(rows*sizeof(float32_t));
    w_=weights;
    for(o=0; o<=order; o++) {
      const float32_t w=(float32_t)(sqrt(2.*o+1.));
      int32_t i;
      for(i=0; i<(2*o+1); i++) {
        *w_++=w;
        counter++;
      }
    }
   matrix=_matrix_diag(matrix, weights, rows);
    free(weights);
  }
    break;
  }
  if(result) ambix_matrix_destroy(result);

  return matrix;
}
Пример #4
0
static void *ambix_write_child_main(void *zz) {
  t_ambix_write *x = (t_ambix_write*)zz;
  ambix_t*ambix=NULL;
  pthread_mutex_lock(&x->x_mutex);
  while (1) {
    if (x->x_requestcode == REQUEST_NOTHING) {
      pthread_cond_signal(&x->x_answercondition);
      pthread_cond_wait(&x->x_requestcondition, &x->x_mutex);
    } else if (x->x_requestcode == REQUEST_OPEN) {
      int sysrtn, writeframes;
      ambix_info_t ainfo;

      /* copy file stuff out of the data structure so we can
         relinquish the mutex while we're in open_soundfile(). */
      int64_t onsetframes = x->x_onsetframes;

      ambix_fileformat_t fileformat = x->x_fileformat;
	  
	  ambix_sampleformat_t sampleformat = x->x_sampleformat;

      uint32_t ambichannels  = x->x_ambichannels;
      uint32_t xtrachannels  = x->x_extrachannels;
      int localfifosize = x->x_fifosize;

      float32_t*ambibuf = NULL;
      float32_t*xtrabuf = NULL;

      double samplerate = x->x_samplerate;

      ambix_matrix_t*matrix=NULL;

      char *filename = strndup(x->x_filename, MAXPDSTRING);

      if(x->x_matrix)
        matrix=ambix_matrix_copy(x->x_matrix, matrix);


      /* alter the request code so that an ensuing "open" will get
         noticed. */
      x->x_requestcode = REQUEST_BUSY;
      x->x_fileerror = 0;

      /* open the soundfile with the mutex unlocked */
      pthread_mutex_unlock(&x->x_mutex);

      memset(&ainfo, 0, sizeof(ainfo));

      ainfo.fileformat=fileformat;

      ainfo.ambichannels=ambichannels;
      ainfo.extrachannels=xtrachannels;

      ainfo.samplerate=samplerate;
      ainfo.sampleformat=sampleformat;
      /* if there's already a file open, close it.  This
         should never happen since ambix_write_open() calls stop if
         needed and then waits until we're idle. */
      if (ambix)
        ambix_close(ambix);
      ambix=ambix_open(filename, AMBIX_WRITE, &ainfo);

      free(filename);

      if(matrix) {
        if(ambix)
          ambix_set_adaptormatrix(ambix, matrix);

        ambix_matrix_destroy(matrix);
        matrix=NULL;
      }

      if(ambix && onsetframes) {
        ambix_seek(ambix, onsetframes, SEEK_SET);
      }

      if(ambix) {
        ambibuf = (float32_t*)calloc(localfifosize*ambichannels, sizeof(float32_t));
        xtrabuf = (float32_t*)calloc(localfifosize*xtrachannels, sizeof(float32_t));
      }

      pthread_mutex_lock(&x->x_mutex);
      if(NULL==ambix) {
        x->x_eof = 1;
        x->x_fileerror = errno;
        x->x_requestcode = REQUEST_NOTHING;
        continue;
      }

      /* check if another request has been made; if so, field it */
      if (x->x_requestcode != REQUEST_BUSY)
        continue;

      x->x_fifotail = 0;

      /* in a loop, wait for the fifo to have data and write it
         to disk */
      while (x->x_requestcode == REQUEST_BUSY ||
             (x->x_requestcode == REQUEST_CLOSE &&
              x->x_fifohead != x->x_fifotail)) {
        int fifosize = x->x_fifosize, fifotail;
        t_sample*buf = x->x_buf;

        /* if the head is < the tail, we can immediately write
           from tail to end of fifo to disk; otherwise we hold off
           writing until there are at least WRITESIZE bytes in the
           buffer */
        if (x->x_fifohead < x->x_fifotail ||
            x->x_fifohead >= x->x_fifotail + WRITFRAMES
            || (x->x_requestcode == REQUEST_CLOSE &&
                x->x_fifohead != x->x_fifotail)) {
          writeframes = (x->x_fifohead < x->x_fifotail ? fifosize : x->x_fifohead) - x->x_fifotail;
          if (writeframes > READFRAMES)
            writeframes = READFRAMES;
        } else {
          pthread_cond_signal(&x->x_answercondition);
          pthread_cond_wait(&x->x_requestcondition,
                            &x->x_mutex);
          continue;
        }
        fifotail = x->x_fifotail;
        pthread_mutex_unlock(&x->x_mutex);
        if(localfifosize<fifosize) {
          free(ambibuf); free(xtrabuf);
          localfifosize=fifosize;
          ambibuf = (float32_t*)calloc(localfifosize*ambichannels, sizeof(float32_t));
          xtrabuf = (float32_t*)calloc(localfifosize*xtrachannels, sizeof(float32_t));
        }
        split_samples(buf+fifotail*(ambichannels+xtrachannels), writeframes,
                      ambibuf, ambichannels,
                      xtrabuf, xtrachannels);

        sysrtn = ambix_writef_float32(ambix,
                                      ambibuf,
                                      xtrabuf,
                                      writeframes);
        pthread_mutex_lock(&x->x_mutex);
        if (x->x_requestcode != REQUEST_BUSY &&
            x->x_requestcode != REQUEST_CLOSE)
          break;

        if (sysrtn < writeframes) {
          x->x_fileerror = errno;
          break;
        } else {
          x->x_fifotail += sysrtn;

          if (x->x_fifotail == fifosize)
            x->x_fifotail = 0;
        }
        /* signal parent in case it's waiting for data */
        pthread_cond_signal(&x->x_answercondition);
      }
      free(ambibuf);free(xtrabuf);
    } else if (x->x_requestcode == REQUEST_CLOSE ||
             x->x_requestcode == REQUEST_QUIT) {
      int quit = (x->x_requestcode == REQUEST_QUIT);
      if (ambix) {
        pthread_mutex_unlock(&x->x_mutex);

        ambix_close(ambix);
        ambix=NULL;

        pthread_mutex_lock(&x->x_mutex);
      }
      x->x_requestcode = REQUEST_NOTHING;
      pthread_cond_signal(&x->x_answercondition);
      if (quit)
        break;
    } else {
    }
  }
  pthread_mutex_unlock(&x->x_mutex);
  return (0);
}