Exemplo n.º 1
0
void HrtfData::loadFromBuffer(unsigned int length, char* buffer, unsigned int forSr) {
    //we now handle endianness.
    int32_t endianness_marker =convi(buffer);
    if(endianness_marker != 1) reverse_endianness(buffer, length, 4);
    //read it again; if it is still not 1, something has gone badly wrong.
    endianness_marker = convi(buffer);
    if(endianness_marker != 1) ERROR(Lav_ERROR_HRTF_INVALID, "Could not correct endianness for this architecture.");

    char* iterator = buffer;
    const unsigned int window_size = 4;

    //read the header information.
    iterator += window_size;//skip the endianness marker, which is handled above.
    samplerate = convi(iterator);

    iterator += window_size;
    hrir_count = convi(iterator);
    iterator += window_size;
    elev_count = convi(iterator);
    iterator += window_size;
    min_elevation = convi(iterator);
    iterator += window_size;
    max_elevation = convi(iterator);
    iterator += window_size;

    //this is the first "dynamic" piece of information.
    azimuth_counts = new int[elev_count];
    for(int i = 0; i < elev_count; i++) {
        azimuth_counts[i] = convi(iterator);
        iterator += window_size;
    }

    //sanity check: we must have as many hrirs as the sum of the above array.
    int32_t sum_sanity_check = 0;
    for(int i = 0; i < elev_count; i++) sum_sanity_check +=azimuth_counts[i];
    if(sum_sanity_check != hrir_count) ERROR(Lav_ERROR_HRTF_INVALID, "Not enough or too many responses.");

    int before_hrir_length = convi(iterator);
    iterator += window_size;

    unsigned int length_so_far = iterator-buffer;
    size_t size_remaining = length-length_so_far;
    //we must have enough remaining to be all hrir hrirs.
    size_t hrir_size = before_hrir_length*hrir_count*sizeof(float);
    if(hrir_size != size_remaining) ERROR(Lav_ERROR_HRTF_INVALID, "Not enough HRIR data.");

    //last step.  Initialize the HRIR array.
    hrirs = new float**[elev_count];
    //do the azimuth dimension.
    for(int i = 0; i < elev_count; i++) {
        hrirs[i] = new float*[azimuth_counts[i]];
    }

    //the above gives us what amounts to a 2d array.  The first dimension represents elevation.  The second dimension represents azimuth going clockwise.
    //fill it.
    float* tempBuffer = allocArray<float>(before_hrir_length);
    int final_hrir_length = 0;
    for(int elev = 0; elev < elev_count; elev++) {
        for(int azimuth = 0; azimuth < azimuth_counts[elev]; azimuth++) {
            memcpy(tempBuffer, iterator, sizeof(float)*before_hrir_length);
            staticResamplerKernel(samplerate, forSr, 1, before_hrir_length, tempBuffer, &final_hrir_length, &hrirs[elev][azimuth]);
            iterator+=before_hrir_length*sizeof(float);
        }
    }
    hrir_length = final_hrir_length;
    samplerate = forSr;
    freeArray(tempBuffer);

    if(temporary_buffer1) freeArray(temporary_buffer1);
    if(temporary_buffer2) freeArray(temporary_buffer2);
    temporary_buffer1 = allocArray<float>(hrir_length);
    temporary_buffer2 = allocArray<float>(hrir_length);

    //stuff for linear phase filters.
    fft_time_data = allocArray<float>(hrir_length*2);
    fft_data = allocArray<kiss_fft_cpx>(hrir_length+1); //half the bins, plus dc.
    fft = kiss_fftr_alloc(hrir_length*2, 0, nullptr, nullptr);
    ifft = kiss_fftr_alloc(hrir_length*2, 1, nullptr, nullptr);
}
Exemplo n.º 2
0
/*======== void parse_file () ==========
Inputs:   char * filename 
          struct matrix * transform, 
          struct matrix * pm,
          screen s
Returns: 

Goes through the file named filename and performs all of the actions listed in that file.
The file follows the following format:
     Every command is a single character that takes up a line
     Any command that requires arguments must have those arguments in the second line.
     The commands are as follows:
         l: add a line to the edge matrix - 
	    takes 6 arguemnts (x0, y0, z0, x1, y1, z1)
	 i: set the transform matrix to the identity matrix - 
	 s: create a scale matrix, 
	    then multiply the transform matrix by the scale matrix - 
	    takes 3 arguments (sx, sy, sz)
	 t: create a translation matrix, 
	    then multiply the transform matrix by the translation matrix - 
	    takes 3 arguments (tx, ty, tz)
	 x: create an x-axis rotation matrix,
	    then multiply the transform matrix by the rotation matrix -
	    takes 1 argument (theta)
	 y: create an y-axis rotation matrix,
	    then multiply the transform matrix by the rotation matrix -
	    takes 1 argument (theta)
	 z: create an z-axis rotation matrix,
	    then multiply the transform matrix by the rotation matrix -
	    takes 1 argument (theta)
	 a: apply the current transformation matrix to the 
	    edge matrix
	 v: draw the lines of the edge matrix to the screen
	    display the screen
	 g: draw the lines of the edge matrix to the screen
	    save the screen to a file -
	    takes 1 argument (file name)
	 q: end parsing

See the file script for an example of the file format


IMPORTANT MATH NOTE:
the trig functions int math.h use radian mesure, but us normal
humans use degrees, so the file will contain degrees for rotations,
be sure to conver those degrees to radians (M_PI is the constant
for PI)

jdyrlandweaver
====================*/
void parse_file ( char * filename, 
                  struct matrix * transform, 
                  struct matrix * pm,
                  screen s) {
  color c;
  c.red = 255;
  c.green = 255;
  c.blue = 255;

  char *b = (char *)malloc(sizeof(char) * 100);
  int fd = open("script_c", O_CREAT | O_RDONLY | O_APPEND, 0666);
  while(b[0] != 'q'){
    b = get_arg(fd, b);
    if(b[0] == 'l'){
      int x0 = convi(fd, b);
      int y0 = convi(fd, b);
      int z0 = convi(fd, b);
      int x1 = convi(fd, b);
      int y1 = convi(fd, b);
      int z1 = convi(fd, b);
      add_edge(pm, x0, y0, z0, x1, y1, z1);
    }
    else if(b[0] == 'i'){
      ident(transform);
    }
    else if(b[0] == 's'){
      double sx = convf(fd, b);
      double sy = convf(fd, b);
      double sz = convf(fd, b);
      struct matrix* tmp = make_scale(sx, sy, sz);
      matrix_mult(tmp, transform);
    }
    else if(b[0] == 't'){
      double tx = convf(fd, b);
      double ty = convf(fd, b);
      double tz = convf(fd, b);
      struct matrix* tmp = make_translate(tx, ty, tz);
      matrix_mult(tmp, transform);
    }
    else if(b[0] == 'x'){
      double theta = convf(fd, b);
      struct matrix* tmp = make_rotX(theta);
      matrix_mult(tmp, transform);
    }
    else if(b[0] == 'y'){
      double theta = convf(fd, b);
      struct matrix* tmp = make_rotY(theta);
      matrix_mult(tmp, transform);
    }
    else if(b[0] == 'z'){
      double theta = convf(fd, b);
      struct matrix* tmp = make_rotZ(theta);
      matrix_mult(tmp, transform);
    }
    else if(b[0] == 'a')
      matrix_mult(transform, pm);
    else if(b[0] == 'v'){
      clear_screen(s);
      draw_lines(pm, s, c);
      display(s);
    }
    else if(b[0] == 'g'){
      clear_screen(s);
      draw_lines(pm, s, c);
      b = get_arg(fd, b);
      save_extension(s, b);
    }
  }
  free(b);
}