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.

219 lines
5.8KB

  1. /*
  2. Copyright (C) 2006-2011 Nasca Octavian Paul
  3. Author: Nasca Octavian Paul
  4. Author/Copyright (C) 2017 Xenakios
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of version 2 of the GNU General Public License
  7. as published by the Free Software Foundation.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License (version 2) for more details.
  12. You should have received a copy of the GNU General Public License (version 2)
  13. along with this program; if not, write to the Free Software Foundation,
  14. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. */
  16. #pragma once
  17. #include "globals.h"
  18. #include "fftw3.h"
  19. #include "../JuceLibraryCode/JuceHeader.h"
  20. #include <random>
  21. template<typename T>
  22. class FFTWBuffer
  23. {
  24. public:
  25. FFTWBuffer()
  26. {
  27. static_assert(std::is_floating_point<T>::value,"FFTWBuffer only works with floating point types");
  28. }
  29. ~FFTWBuffer()
  30. {
  31. freeimpl(m_buf);
  32. }
  33. void resize(int size, bool clear)
  34. {
  35. // come on, zero size doesn't make sense!
  36. jassert(size>0);
  37. if (size==m_size && clear==false)
  38. return;
  39. if (m_buf)
  40. freeimpl(m_buf);
  41. mallocimpl(m_buf,size);
  42. if (clear)
  43. for (int i=0;i<size;++i)
  44. m_buf[i]=T();
  45. m_size = size;
  46. }
  47. T& operator[](int index)
  48. {
  49. jassert(index >= 0 && index < m_size);
  50. return m_buf[index];
  51. }
  52. const T& operator[](int index) const
  53. {
  54. jassert(index >= 0 && index < m_size);
  55. return m_buf[index];
  56. }
  57. T* data()
  58. {
  59. // callers to this will likely just blow themselves up if they get a nullptr back
  60. jassert(m_buf!=nullptr);
  61. return m_buf;
  62. }
  63. int getSize() { return m_size; }
  64. FFTWBuffer(FFTWBuffer&& other) : m_buf(other.m_buf), m_size(other.m_size)
  65. {
  66. other.m_buf = nullptr;
  67. other.m_size = 0;
  68. }
  69. FFTWBuffer& operator = (FFTWBuffer&& other)
  70. {
  71. std::swap(other.m_buf, m_buf);
  72. std::swap(other.m_size, m_size);
  73. return *this;
  74. }
  75. // These buffers probably shouldn't be copied anywhere, so just disallow that for now
  76. FFTWBuffer(const FFTWBuffer&) = delete;
  77. FFTWBuffer& operator = (const FFTWBuffer&) = delete;
  78. private:
  79. T* m_buf = nullptr;
  80. int m_size = 0;
  81. void mallocimpl(float*& buf,int size)
  82. {
  83. buf = (float*)fftwf_malloc(size*sizeof(float));
  84. }
  85. void mallocimpl(double*& buf,int size)
  86. {
  87. buf = (double*)fftw_malloc(size*sizeof(double));
  88. }
  89. void freeimpl(float*& buf)
  90. {
  91. if (buf!=nullptr)
  92. {
  93. fftwf_free(buf);
  94. buf = nullptr;
  95. }
  96. }
  97. void freeimpl(double*& buf)
  98. {
  99. if (buf!=nullptr)
  100. {
  101. fftw_free(buf);
  102. buf = nullptr;
  103. }
  104. }
  105. };
  106. enum FFTWindow{W_RECTANGULAR,W_HAMMING,W_HANN,W_BLACKMAN,W_BLACKMAN_HARRIS};
  107. class FFT
  108. {//FFT class that considers phases as random
  109. public:
  110. FFT(int nsamples_, bool no_inverse=false);//samples must be even
  111. ~FFT();
  112. void smp2freq();//input is smp, output is freq (phases are discarded)
  113. void freq2smp();//input is freq,output is smp (phases are random)
  114. void applywindow(FFTWindow type);
  115. std::vector<REALTYPE> smp;//size of samples/2
  116. std::vector<REALTYPE> freq;//size of samples
  117. int nsamples=0;
  118. private:
  119. fftwf_plan planfftw,planifftw;
  120. FFTWBuffer<REALTYPE> data;
  121. struct{
  122. std::vector<REALTYPE> data;
  123. FFTWindow type;
  124. }window;
  125. std::mt19937 m_randgen;
  126. std::uniform_int_distribution<unsigned int> m_randdist{0,32767};
  127. };
  128. class Stretch
  129. {
  130. public:
  131. Stretch(REALTYPE rap_,int in_bufsize_,FFTWindow w=W_HAMMING,bool bypass_=false,REALTYPE samplerate_=44100,int stereo_mode_=0);
  132. //in_bufsize is also a half of a FFT buffer (in samples)
  133. virtual ~Stretch();
  134. int get_max_bufsize(){
  135. return bufsize*3;
  136. };
  137. int get_bufsize(){
  138. return bufsize;
  139. };
  140. virtual void setBufferSize(int sz);
  141. REALTYPE get_onset_detection_sensitivity(){
  142. return onset_detection_sensitivity;
  143. };
  144. REALTYPE process(REALTYPE *smps,int nsmps);//returns the onset value
  145. void set_freezing(bool new_freezing){
  146. freezing=new_freezing;
  147. };
  148. bool isFreezing() { return freezing; }
  149. std::vector<REALTYPE> out_buf;//pot sa pun o variabila "max_out_bufsize" si asta sa fie marimea lui out_buf si pe out_bufsize sa il folosesc ca marime adaptiva
  150. int get_nsamples(REALTYPE current_pos_percents);//how many samples are required
  151. int get_nsamples_for_fill();//how many samples are required to be added for a complete buffer refill (at start of the song or after seek)
  152. int get_skip_nsamples();//used for shorten
  153. void set_rap(REALTYPE newrap);//set the current stretch value
  154. void set_onset_detection_sensitivity(REALTYPE detection_sensitivity);;
  155. void here_is_onset(REALTYPE onset);
  156. virtual void setSampleRate(REALTYPE sr) { samplerate = jlimit(1000.0f, 38400.0f, sr); }
  157. REALTYPE getSampleRate() { return samplerate; }
  158. FFTWindow window_type;
  159. protected:
  160. int bufsize=0;
  161. virtual void process_spectrum(REALTYPE *){};
  162. virtual REALTYPE get_stretch_multiplier(REALTYPE pos_percents);
  163. REALTYPE samplerate=0.0f;
  164. private:
  165. void do_analyse_inbuf(REALTYPE *smps);
  166. void do_next_inbuf_smps(REALTYPE *smps);
  167. REALTYPE do_detect_onset();
  168. // REALTYPE *in_pool;//de marimea in_bufsize
  169. REALTYPE rap,onset_detection_sensitivity;
  170. std::vector<REALTYPE> old_out_smps;
  171. std::vector<REALTYPE> old_freq;
  172. std::vector<REALTYPE> new_smps,old_smps,very_old_smps;
  173. std::unique_ptr<FFT> infft,outfft;
  174. std::unique_ptr<FFT> fft;
  175. long double remained_samples;//0..1
  176. long double extra_onset_time_credit;
  177. REALTYPE c_pos_percents;
  178. int skip_samples;
  179. bool require_new_buffer;
  180. bool bypass,freezing;
  181. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Stretch)
  182. };