/externals/creb/modules/qmult~.c

https://github.com/pd-l2ork/pd · C · 166 lines · 101 code · 43 blank · 22 comment · 4 complexity · 2e1e9a070184b9d5f742b817bd820512 MD5 · raw file

  1. /*
  2. * qmult.c - quaternion multiplication dsp object
  3. * Copyright (c) 2000-2003 by Tom Schouten
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "m_pd.h"
  20. #include <math.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <math.h>
  24. typedef struct qmultctl
  25. {
  26. t_float *c_inputleft[4];
  27. t_float *c_inputright[4];
  28. t_float *c_output[4];
  29. } t_qmultctl;
  30. typedef struct qmult
  31. {
  32. t_object x_obj;
  33. t_float x_f;
  34. t_qmultctl x_ctl;
  35. } t_qmult;
  36. static t_int *qmult_perform(t_int *word)
  37. {
  38. t_qmultctl *ctl = (t_qmultctl *)(word[1]);
  39. t_int n = (t_int)(word[2]);
  40. t_int i;
  41. t_float *in0l = ctl->c_inputleft[0];
  42. t_float *in1l = ctl->c_inputleft[1];
  43. t_float *in2l = ctl->c_inputleft[2];
  44. t_float *in3l = ctl->c_inputleft[3];
  45. t_float *in0r = ctl->c_inputright[0];
  46. t_float *in1r = ctl->c_inputright[1];
  47. t_float *in2r = ctl->c_inputright[2];
  48. t_float *in3r = ctl->c_inputright[3];
  49. t_float *out0 = ctl->c_output[0];
  50. t_float *out1 = ctl->c_output[1];
  51. t_float *out2 = ctl->c_output[2];
  52. t_float *out3 = ctl->c_output[3];
  53. t_float wl, xl, yl, zl;
  54. t_float wr, xr, yr, zr;
  55. t_float w, x, y, z;
  56. for (i=0;i<n;i++)
  57. {
  58. /* read input quaternions */
  59. wl = *in0l++;
  60. xl = *in1l++;
  61. yl = *in2l++;
  62. zl = *in3l++;
  63. wr = *in0r++;
  64. xr = *in1r++;
  65. yr = *in2r++;
  66. zr = *in3r++;
  67. /* multiply quaternions */
  68. w = wl * wr;
  69. x = wl * xr;
  70. y = wl * yr;
  71. z = wl * zr;
  72. w -= xl * xr;
  73. x += xl * wr;
  74. y -= xl * zr;
  75. z += xl * yr;
  76. w -= yl * yr;
  77. x += yl * zr;
  78. y += yl * wr;
  79. z -= yl * xr;
  80. w -= zl * zr;
  81. x -= zl * yr;
  82. y += zl * xr;
  83. z += zl * wr;
  84. /* write output quaternion */
  85. *out0++ = w;
  86. *out1++ = x;
  87. *out2++ = y;
  88. *out3++ = z;
  89. }
  90. return (word+3);
  91. }
  92. static void qmult_dsp(t_qmult *x, t_signal **sp)
  93. {
  94. int i;
  95. for (i=0;i<4;i++)
  96. {
  97. x->x_ctl.c_inputleft[i] = sp[i]->s_vec;
  98. x->x_ctl.c_inputright[i] = sp[i+4]->s_vec;
  99. x->x_ctl.c_output[i] = sp[i+8]->s_vec;
  100. }
  101. dsp_add(qmult_perform, 2, &x->x_ctl, sp[0]->s_n);
  102. }
  103. static void qmult_free(t_qmult *x)
  104. {
  105. }
  106. t_class *qmult_class;
  107. static void *qmult_new(t_floatarg channels)
  108. {
  109. int i;
  110. t_qmult *x = (t_qmult *)pd_new(qmult_class);
  111. for (i=1;i<8;i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd,
  112. gensym("signal"), gensym("signal"));
  113. for (i=0;i<4;i++) outlet_new(&x->x_obj, gensym("signal"));
  114. return (void *)x;
  115. }
  116. void qmult_tilde_setup(void)
  117. {
  118. //post("qmult~ v0.1");
  119. qmult_class = class_new(gensym("qmult~"), (t_newmethod)qmult_new,
  120. (t_method)qmult_free, sizeof(t_qmult), 0, 0);
  121. CLASS_MAINSIGNALIN(qmult_class, t_qmult, x_f);
  122. class_addmethod(qmult_class, (t_method)qmult_dsp, gensym("dsp"), 0);
  123. }