You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
5.4KB

  1. /*
  2. Copyright (C) 2011 Nasca Octavian Paul
  3. Author: Nasca Octavian Paul
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of version 2 of the GNU General Public License
  6. as published by the Free Software Foundation.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License (version 2) for more details.
  11. You should have received a copy of the GNU General Public License (version 2)
  12. along with this program; if not, write to the Free Software Foundation,
  13. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15. #ifndef FREEEDIT_H
  16. #define FREEEDIT_H
  17. #define FREE_EDIT_MAX_POINTS 50
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include "globals.h"
  21. #include "XMLwrapper.h"
  22. #define LOG_2 0.693147181
  23. #define LOG_10 2.302585093
  24. #define dB2rap(dB) ((exp((dB)*LOG_10/20.0)))
  25. #define rap2dB(rap) ((20*log(rap)/LOG_10))
  26. struct FreeEditPos{
  27. REALTYPE x,y;
  28. bool enabled;
  29. };
  30. enum FREE_EDIT_EXTREME_SCALE{
  31. FE_LINEAR=0,
  32. FE_LOG=1,
  33. FE_DB=2
  34. };
  35. class FreeEditExtremes{
  36. public:
  37. FreeEditExtremes(){
  38. init();
  39. };
  40. void init(REALTYPE min_=0.0,REALTYPE max_=1.0,FREE_EDIT_EXTREME_SCALE scale_=FE_LINEAR,bool lock_min_max_=false,bool lock_scale_=false){
  41. min=min_;
  42. max=max_;
  43. scale=scale_;
  44. lock_min_max=lock_min_max_;
  45. lock_scale=lock_scale_;
  46. correct_values();
  47. };
  48. //converting functions
  49. inline REALTYPE coord_to_real_value(REALTYPE coord){//coord = 0.0 .. 1.0
  50. REALTYPE result;
  51. switch(scale){
  52. case FE_LOG://log
  53. result=exp(log(min)+coord*(log(max)-log(min)));
  54. return result;
  55. default://linear or dB
  56. result=min+coord*(max-min);
  57. return result;
  58. };
  59. };
  60. inline REALTYPE real_value_to_coord(REALTYPE val){//coord = 0.0 .. 1.0
  61. switch(scale){
  62. case FE_LOG://log
  63. {
  64. REALTYPE coord=log(val/min)/log(max/min);
  65. clamp1(coord);
  66. return coord;
  67. };
  68. default://linear
  69. {
  70. REALTYPE diff=max-min;
  71. REALTYPE coord;
  72. if (fabs(diff)>0.0001) coord=(val-min)/diff;
  73. else coord=min;
  74. clamp1(coord);
  75. return coord;
  76. };
  77. };
  78. };
  79. //max and min functions
  80. void set_min(REALTYPE val){
  81. if (lock_min_max) return;
  82. min=val;
  83. correct_values();
  84. };
  85. REALTYPE get_min(){
  86. return min;
  87. };
  88. void set_max(REALTYPE val){
  89. if (lock_min_max) return;
  90. max=val;
  91. correct_values();
  92. };
  93. REALTYPE get_max(){
  94. return max;
  95. };
  96. //scale functions
  97. FREE_EDIT_EXTREME_SCALE get_scale(){
  98. return scale;
  99. };
  100. void set_scale(FREE_EDIT_EXTREME_SCALE val){
  101. if (lock_scale) return;
  102. scale=val;
  103. };
  104. void add2XML(XMLwrapper *xml){
  105. xml->addparreal("min",min);
  106. xml->addparreal("max",max);
  107. };
  108. void getfromXML(XMLwrapper *xml){
  109. set_min(xml->getparreal("min",min));
  110. set_max(xml->getparreal("max",max));
  111. };
  112. private:
  113. inline REALTYPE clamp1(REALTYPE m){
  114. if (m<0.0) return 0.0;
  115. if (m>1.0) return 1.0;
  116. return m;
  117. };
  118. void correct_values(){
  119. if (scale!=FE_LOG) return;
  120. if (min<1e-8) min=1e-8;
  121. if (max<1e-8) max=1e-8;
  122. };
  123. bool lock_min_max,lock_scale;
  124. REALTYPE min,max;
  125. FREE_EDIT_EXTREME_SCALE scale;
  126. };
  127. class FreeEdit{
  128. public:
  129. enum INTERP_MODE{
  130. LINEAR=0,
  131. COSINE=1
  132. };
  133. FreeEdit();
  134. FreeEdit (const FreeEdit &other);
  135. const FreeEdit &operator=(const FreeEdit &other);
  136. void deep_copy_from(const FreeEdit &other);
  137. void add2XML(XMLwrapper *xml);
  138. void getfromXML(XMLwrapper *xml);
  139. //Enabled functions
  140. bool get_enabled(){
  141. return enabled;
  142. };
  143. void set_enabled(bool val){
  144. enabled=val;
  145. };
  146. inline int get_npoints(){
  147. return npos;
  148. };
  149. //manipulation functions
  150. inline bool is_enabled(int n){
  151. if ((n<0)||(n>=npos)) return false;
  152. return pos[n].enabled;
  153. };
  154. inline void set_enabled(int n,bool enabled){
  155. if ((n<0)||(n>=npos)) return;
  156. pos[n].enabled=enabled;
  157. };
  158. inline REALTYPE get_posx(int n){
  159. if ((n<0)||(n>=npos)) return 0.0;
  160. return pos[n].x;
  161. };
  162. inline REALTYPE get_posy(int n){
  163. if ((n<0)||(n>=npos)) return 0.0;
  164. return pos[n].y;
  165. };
  166. inline void set_posx(int n,REALTYPE x){
  167. if ((n<2)||(n>=npos)) return;//don't allow to set the x position of the first two positions
  168. pos[n].x=clamp1(x);
  169. };
  170. inline void set_posy(int n,REALTYPE y){
  171. if ((n<0)||(n>=npos)) return;
  172. pos[n].y=clamp1(y);
  173. };
  174. void set_all_values(REALTYPE val){
  175. for (int i=0;i<npos;i++){
  176. if (pos[i].enabled) pos[i].y=extreme_y.real_value_to_coord(val);
  177. }
  178. };
  179. //interpolation mode
  180. INTERP_MODE get_interp_mode(){
  181. return interp_mode;
  182. };
  183. void set_interp_mode(INTERP_MODE interp_mode_){
  184. interp_mode=interp_mode_;
  185. };
  186. //smooth
  187. REALTYPE get_smooth(){
  188. return smooth;
  189. };
  190. void set_smooth(REALTYPE smooth_){
  191. smooth=clamp1(smooth_);;
  192. };
  193. //getting the curve
  194. void get_curve(int datasize,REALTYPE *data,bool real_values);
  195. ~FreeEdit(){
  196. delete []pos;
  197. };
  198. //making/updating the curve
  199. void update_curve(int size=16384);
  200. REALTYPE get_value(REALTYPE x);
  201. //extremes
  202. FreeEditExtremes extreme_x,extreme_y;
  203. struct{
  204. REALTYPE *data;
  205. int size;
  206. }curve;
  207. private:
  208. inline REALTYPE clamp1(REALTYPE m){
  209. if (m<0.0) return 0.0;
  210. if (m>1.0) return 1.0;
  211. return m;
  212. };
  213. inline void swap(REALTYPE &m1,REALTYPE &m2){
  214. REALTYPE tmp=m1;
  215. m1=m2;
  216. m2=tmp;
  217. };
  218. FreeEditPos *pos;
  219. int npos;
  220. REALTYPE smooth;
  221. INTERP_MODE interp_mode;
  222. bool enabled;
  223. };
  224. #endif