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.

446 lines
12KB

  1. /*
  2. Copyright (C) 2009 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. #include <math.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include "ProcessedStretch.h"
  19. ProcessedStretch::ProcessedStretch(REALTYPE rap_,int in_bufsize_,FFTWindow w,bool bypass_,REALTYPE samplerate_,int stereo_mode_)
  20. : Stretch(rap_,in_bufsize_,w,bypass_,samplerate_,stereo_mode_)
  21. {
  22. };
  23. ProcessedStretch::~ProcessedStretch()
  24. {
  25. // delete [] fbfreq;
  26. };
  27. void ProcessedStretch::set_parameters(ProcessParameters *ppar)
  28. {
  29. pars=*ppar;
  30. //update_free_filter();
  31. }
  32. void ProcessedStretch::setBufferSize(int sz)
  33. {
  34. jassert(sz > 0);
  35. Stretch::setBufferSize(sz);
  36. //if (nfreq != sz)
  37. {
  38. nfreq = bufsize;
  39. infreq = floatvector(nfreq);
  40. sumfreq = floatvector(nfreq);
  41. tmpfreq1 = floatvector(nfreq);
  42. tmpfreq2 = floatvector(nfreq);
  43. //fbfreq=new REALTYPE[nfreq];
  44. free_filter_freqs = floatvector(nfreq);
  45. for (int i = 0; i < nfreq; i++) {
  46. free_filter_freqs[i] = 1.0;
  47. // fbfreq[i]=0.0;
  48. };
  49. }
  50. }
  51. /*
  52. void ProcessedStretch::copy(const realvector& freq1,realvector& freq2)
  53. {
  54. for (int i=0;i<nfreq;i++) freq2[i]=freq1[i];
  55. };
  56. */
  57. void ProcessedStretch::copy(REALTYPE* freq1, REALTYPE* freq2)
  58. {
  59. for (int i = 0; i<nfreq; i++) freq2[i] = freq1[i];
  60. };
  61. void ProcessedStretch::add(REALTYPE *freq2,REALTYPE *freq1,REALTYPE a){
  62. for (int i=0;i<nfreq;i++) freq2[i]+=freq1[i]*a;
  63. };
  64. void ProcessedStretch::mul(REALTYPE *freq1,REALTYPE a){
  65. for (int i=0;i<nfreq;i++) freq1[i]*=a;
  66. };
  67. void ProcessedStretch::zero(REALTYPE *freq1){
  68. for (int i=0;i<nfreq;i++) freq1[i]=0.0;
  69. };
  70. REALTYPE ProcessedStretch::get_stretch_multiplier(REALTYPE pos_percents){
  71. REALTYPE result=1.0;
  72. /*
  73. if (pars.stretch_multiplier.get_enabled()){
  74. result*=pars.stretch_multiplier.get_value(pos_percents);
  75. };
  76. */
  77. ///REALTYPE transient=pars.get_transient(pos_percents);
  78. ///printf("\n%g\n",transient);
  79. ///REALTYPE threshold=0.05;
  80. ///REALTYPE power=1000.0;
  81. ///transient-=threshold;
  82. ///if (transient>0){
  83. /// transient*=power*(1.0+power);
  84. /// result/=(1.0+transient);
  85. ///};
  86. ///printf("tr=%g\n",result);
  87. return result;
  88. };
  89. void ProcessedStretch::process_spectrum(REALTYPE *freq)
  90. {
  91. for (auto& e : m_spectrum_processes)
  92. {
  93. spectrum_copy(nfreq, freq, infreq.data());
  94. if (e == 0 && pars.harmonics.enabled)
  95. spectrum_do_harmonics(pars, tmpfreq1, nfreq, samplerate, infreq.data(), freq);
  96. if (e == 1 && pars.tonal_vs_noise.enabled)
  97. spectrum_do_tonal_vs_noise(pars,nfreq,samplerate,tmpfreq1, infreq.data(), freq);
  98. if (e == 2 && pars.freq_shift.enabled)
  99. spectrum_do_freq_shift(pars,nfreq,samplerate,infreq.data(), freq);
  100. if (e == 3 && pars.pitch_shift.enabled)
  101. spectrum_do_pitch_shift(pars,nfreq,infreq.data(), freq, pow(2.0f, pars.pitch_shift.cents / 1200.0f));
  102. if (e == 4 && pars.octave.enabled)
  103. spectrum_do_octave(pars,nfreq,samplerate, sumfreq, tmpfreq1, infreq.data(), freq);
  104. if (e == 5 && pars.spread.enabled)
  105. spectrum_spread(nfreq,samplerate,tmpfreq1,infreq.data(), freq, pars.spread.bandwidth);
  106. if (e == 6 && pars.filter.enabled)
  107. spectrum_do_filter(pars,nfreq,samplerate,infreq.data(), freq);
  108. if (e == 7 && pars.compressor.enabled)
  109. spectrum_do_compressor(pars,nfreq, infreq.data(), freq);
  110. }
  111. #ifdef USE_OLD_SPEC_PROC
  112. if (pars.harmonics.enabled) {
  113. copy(freq,infreq.data());
  114. do_harmonics(infreq.data(),freq);
  115. };
  116. if (pars.tonal_vs_noise.enabled){
  117. copy(freq,infreq.data());
  118. do_tonal_vs_noise(infreq.data(),freq);
  119. };
  120. if (pars.freq_shift.enabled) {
  121. copy(freq,infreq.data());
  122. do_freq_shift(infreq.data(),freq);
  123. };
  124. if (pars.pitch_shift.enabled) {
  125. copy(freq,infreq.data());
  126. do_pitch_shift(infreq.data(),freq,pow(2.0,pars.pitch_shift.cents/1200.0));
  127. };
  128. if (pars.octave.enabled){
  129. copy(freq,infreq.data());
  130. do_octave(infreq.data(),freq);
  131. };
  132. if (pars.spread.enabled){
  133. copy(freq,infreq.data());
  134. do_spread(infreq.data(),freq);
  135. };
  136. if (pars.filter.enabled){
  137. copy(freq,infreq.data());
  138. do_filter(infreq.data(),freq);
  139. };
  140. if (pars.free_filter.get_enabled()){
  141. copy(freq,infreq.data());
  142. do_free_filter(infreq.data(),freq);
  143. };
  144. if (pars.compressor.enabled){
  145. copy(freq,infreq.data());
  146. do_compressor(infreq.data(),freq);
  147. };
  148. #endif
  149. };
  150. //void ProcessedStretch::process_output(REALTYPE *smps,int nsmps){
  151. //};
  152. void ProcessedStretch::do_harmonics(REALTYPE *freq1,REALTYPE *freq2){
  153. REALTYPE freq=pars.harmonics.freq;
  154. REALTYPE bandwidth=pars.harmonics.bandwidth;
  155. int nharmonics=pars.harmonics.nharmonics;
  156. if (freq<10.0) freq=10.0;
  157. REALTYPE *amp=tmpfreq1.data();
  158. for (int i=0;i<nfreq;i++) amp[i]=0.0;
  159. for (int nh=1;nh<=nharmonics;nh++){//for each harmonic
  160. REALTYPE bw_Hz;//bandwidth of the current harmonic measured in Hz
  161. REALTYPE bwi;
  162. REALTYPE fi;
  163. REALTYPE f=nh*freq;
  164. if (f>=samplerate/2) break;
  165. bw_Hz=(pow(2.0f,bandwidth/1200.0f)-1.0f)*f;
  166. bwi=bw_Hz/(2.0f*samplerate);
  167. fi=f/samplerate;
  168. REALTYPE sum=0.0f;
  169. REALTYPE max=0.0f;
  170. for (int i=1;i<nfreq;i++){//todo: optimize here
  171. REALTYPE hprofile;
  172. hprofile=profile((i/(REALTYPE)nfreq*0.5f)-fi,bwi);
  173. amp[i]+=hprofile;
  174. if (max<hprofile) max=hprofile;
  175. sum+=hprofile;
  176. };
  177. };
  178. REALTYPE max=0.0;
  179. for (int i=1;i<nfreq;i++){
  180. if (amp[i]>max) max=amp[i];
  181. };
  182. if (max<1e-8f) max=1e-8f;
  183. for (int i=1;i<nfreq;i++){
  184. //REALTYPE c,s;
  185. REALTYPE a=amp[i]/max;
  186. if (!pars.harmonics.gauss) a=(a<0.368f?0.0f:1.0f);
  187. freq2[i]=freq1[i]*a;
  188. };
  189. };
  190. void ProcessedStretch::do_freq_shift(REALTYPE *freq1,REALTYPE *freq2){
  191. zero(freq2);
  192. int ifreq=(int)(pars.freq_shift.Hz/(samplerate*0.5)*nfreq);
  193. for (int i=0;i<nfreq;i++){
  194. int i2=ifreq+i;
  195. if ((i2>0)&&(i2<nfreq)) freq2[i2]=freq1[i];
  196. };
  197. };
  198. void ProcessedStretch::do_pitch_shift(REALTYPE *freq1,REALTYPE *freq2,REALTYPE _rap){
  199. zero(freq2);
  200. if (_rap<1.0){//down
  201. for (int i=0;i<nfreq;i++){
  202. int i2=(int)(i*_rap);
  203. if (i2>=nfreq) break;
  204. freq2[i2]+=freq1[i];
  205. };
  206. };
  207. if (_rap>=1.0){//up
  208. _rap=1.0f/_rap;
  209. for (int i=0;i<nfreq;i++){
  210. freq2[i]=freq1[(int)(i*_rap)];
  211. };
  212. };
  213. };
  214. void ProcessedStretch::do_octave(REALTYPE *freq1,REALTYPE *freq2){
  215. zero(sumfreq.data());
  216. if (pars.octave.om2>1e-3){
  217. do_pitch_shift(freq1,tmpfreq1.data(),0.25);
  218. add(sumfreq.data(),tmpfreq1.data(),pars.octave.om2);
  219. };
  220. if (pars.octave.om1>1e-3){
  221. do_pitch_shift(freq1,tmpfreq1.data(),0.5);
  222. add(sumfreq.data(),tmpfreq1.data(),pars.octave.om1);
  223. };
  224. if (pars.octave.o0>1e-3){
  225. add(sumfreq.data(),freq1,pars.octave.o0);
  226. };
  227. if (pars.octave.o1>1e-3){
  228. do_pitch_shift(freq1,tmpfreq1.data(),2.0);
  229. add(sumfreq.data(),tmpfreq1.data(),pars.octave.o1);
  230. };
  231. if (pars.octave.o15>1e-3){
  232. do_pitch_shift(freq1,tmpfreq1.data(),3.0);
  233. add(sumfreq.data(),tmpfreq1.data(),pars.octave.o15);
  234. };
  235. if (pars.octave.o2>1e-3){
  236. do_pitch_shift(freq1,tmpfreq1.data(),4.0);
  237. add(sumfreq.data(),tmpfreq1.data(),pars.octave.o2);
  238. };
  239. REALTYPE sum=0.01f+pars.octave.om2+pars.octave.om1+pars.octave.o0+pars.octave.o1+pars.octave.o15+pars.octave.o2;
  240. if (sum<0.5f) sum=0.5f;
  241. for (int i=0;i<nfreq;i++) freq2[i]=sumfreq[i]/sum;
  242. };
  243. void ProcessedStretch::do_filter(REALTYPE *freq1,REALTYPE *freq2){
  244. REALTYPE low=0,high=0;
  245. if (pars.filter.low<pars.filter.high){//sort the low/high freqs
  246. low=pars.filter.low;
  247. high=pars.filter.high;
  248. }else{
  249. high=pars.filter.low;
  250. low=pars.filter.high;
  251. };
  252. int ilow=(int) (low/samplerate*nfreq*2.0f);
  253. int ihigh=(int) (high/samplerate*nfreq*2.0f);
  254. REALTYPE dmp=1.0;
  255. REALTYPE dmprap=1.0f-pow(pars.filter.hdamp*0.5f,4.0f);
  256. for (int i=0;i<nfreq;i++){
  257. REALTYPE a=0.0f;
  258. if ((i>=ilow)&&(i<ihigh)) a=1.0f;
  259. if (pars.filter.stop) a=1.0f-a;
  260. freq2[i]=freq1[i]*a*dmp;
  261. dmp*=dmprap+1e-8f;
  262. };
  263. };
  264. void ProcessedStretch::update_free_filter()
  265. {
  266. /*
  267. pars.free_filter.update_curve();
  268. if (pars.free_filter.get_enabled()) {
  269. for (int i=0;i<nfreq;i++){
  270. REALTYPE freq=(REALTYPE)i/(REALTYPE) nfreq*samplerate*0.5f;
  271. free_filter_freqs[i]=pars.free_filter.get_value(freq);
  272. };
  273. }else{
  274. for (int i=0;i<nfreq;i++){
  275. free_filter_freqs[i]=1.0f;
  276. };
  277. };
  278. */
  279. };
  280. void ProcessedStretch::do_free_filter(REALTYPE *freq1,REALTYPE *freq2){
  281. for (int i=0;i<nfreq;i++){
  282. freq2[i]=freq1[i]*free_filter_freqs[i];
  283. };
  284. };
  285. void ProcessedStretch::do_spread(REALTYPE *freq1,REALTYPE *freq2){
  286. spread(freq1,freq2,pars.spread.bandwidth);
  287. };
  288. void ProcessedStretch::spread(REALTYPE *freq1,REALTYPE *freq2,REALTYPE spread_bandwidth){
  289. //convert to log spectrum
  290. REALTYPE minfreq=20.0f;
  291. REALTYPE maxfreq=0.5f*samplerate;
  292. REALTYPE log_minfreq=log(minfreq);
  293. REALTYPE log_maxfreq=log(maxfreq);
  294. for (int i=0;i<nfreq;i++){
  295. REALTYPE freqx=i/(REALTYPE) nfreq;
  296. REALTYPE x=exp(log_minfreq+freqx*(log_maxfreq-log_minfreq))/maxfreq*nfreq;
  297. REALTYPE y=0.0f;
  298. int x0=(int)floor(x); if (x0>=nfreq) x0=nfreq-1;
  299. int x1=x0+1; if (x1>=nfreq) x1=nfreq-1;
  300. REALTYPE xp=x-x0;
  301. if (x<nfreq){
  302. y=freq1[x0]*(1.0f-xp)+freq1[x1]*xp;
  303. };
  304. tmpfreq1[i]=y;
  305. };
  306. //increase the bandwidth of each harmonic (by smoothing the log spectrum)
  307. int n=2;
  308. REALTYPE bandwidth=spread_bandwidth;
  309. REALTYPE a=1.0f-pow(2.0f,-bandwidth*bandwidth*10.0f);
  310. a=pow(a,8192.0f/nfreq*n);
  311. for (int k=0;k<n;k++){
  312. tmpfreq1[0]=0.0f;
  313. for (int i=1;i<nfreq;i++){
  314. tmpfreq1[i]=tmpfreq1[i-1]*a+tmpfreq1[i]*(1.0f-a);
  315. };
  316. tmpfreq1[nfreq-1]=0.0f;
  317. for (int i=nfreq-2;i>0;i--){
  318. tmpfreq1[i]=tmpfreq1[i+1]*a+tmpfreq1[i]*(1.0f-a);
  319. };
  320. };
  321. freq2[0]=0;
  322. REALTYPE log_maxfreq_d_minfreq=log(maxfreq/minfreq);
  323. for (int i=1;i<nfreq;i++){
  324. REALTYPE freqx=i/(REALTYPE) nfreq;
  325. REALTYPE x=log((freqx*maxfreq)/minfreq)/log_maxfreq_d_minfreq*nfreq;
  326. REALTYPE y=0.0;
  327. if ((x>0.0)&&(x<nfreq)){
  328. int x0=(int)floor(x); if (x0>=nfreq) x0=nfreq-1;
  329. int x1=x0+1; if (x1>=nfreq) x1=nfreq-1;
  330. REALTYPE xp=x-x0;
  331. y=tmpfreq1[x0]*(1.0f-xp)+tmpfreq1[x1]*xp;
  332. };
  333. freq2[i]=y;
  334. };
  335. };
  336. void ProcessedStretch::do_compressor(REALTYPE *freq1,REALTYPE *freq2){
  337. REALTYPE rms=0.0;
  338. for (int i=0;i<nfreq;i++) rms+=freq1[i]*freq1[i];
  339. rms=sqrt(rms/nfreq)*0.1f;
  340. if (rms<1e-3f) rms=1e-3f;
  341. REALTYPE _rap=pow(rms,-pars.compressor.power);
  342. for (int i=0;i<nfreq;i++) freq2[i]=freq1[i]*_rap;
  343. };
  344. void ProcessedStretch::do_tonal_vs_noise(REALTYPE *freq1,REALTYPE *freq2){
  345. spread(freq1,tmpfreq1.data(),pars.tonal_vs_noise.bandwidth);
  346. if (pars.tonal_vs_noise.preserve>=0.0){
  347. REALTYPE mul=(pow(10.0f,pars.tonal_vs_noise.preserve)-1.0f);
  348. for (int i=0;i<nfreq;i++) {
  349. REALTYPE x=freq1[i];
  350. REALTYPE smooth_x=tmpfreq1[i]+1e-6f;
  351. REALTYPE result=0.0f;
  352. result=x-smooth_x*mul;
  353. if (result<0.0f) result=0.0f;
  354. freq2[i]=result;
  355. };
  356. }else{
  357. REALTYPE mul=(pow(5.0f,1.0f+pars.tonal_vs_noise.preserve)-1.0f);
  358. for (int i=0;i<nfreq;i++) {
  359. REALTYPE x=freq1[i];
  360. REALTYPE smooth_x=tmpfreq1[i]+1e-6f;
  361. REALTYPE result=0.0f;
  362. result=x-smooth_x*mul+0.1f*mul;
  363. if (result<0.0f) result=x;
  364. else result=0.0f;
  365. freq2[i]=result;
  366. };
  367. };
  368. };
  369. std::vector<SpectrumProcess> make_spectrum_processes()
  370. {
  371. std::vector<SpectrumProcess> m_spectrum_processes;
  372. m_spectrum_processes.emplace_back("Harmonics",0);
  373. m_spectrum_processes.emplace_back("Tonal vs Noise",1);
  374. m_spectrum_processes.emplace_back("Frequency shift",2);
  375. m_spectrum_processes.emplace_back("Pitch shift",3);
  376. m_spectrum_processes.emplace_back("Octaves mix",4);
  377. m_spectrum_processes.emplace_back("Spread",5);
  378. m_spectrum_processes.emplace_back("Filter",6);
  379. m_spectrum_processes.emplace_back("Compressor",7);
  380. return m_spectrum_processes;
  381. }