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.

218 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. #include <type_traits>
  22. template<typename T>
  23. class FFTWBuffer
  24. {
  25. public:
  26. FFTWBuffer()
  27. {
  28. static_assert(std::is_floating_point<T>::value,"FFTWBuffer only works with floating point types");
  29. }
  30. ~FFTWBuffer()
  31. {
  32. freeimpl(m_buf);
  33. }
  34. void resize(int size, bool clear)
  35. {
  36. // come on, zero size doesn't make sense!
  37. jassert(size>0);
  38. if (size==m_size && clear==false)
  39. return;
  40. if (m_buf)
  41. freeimpl(m_buf);
  42. mallocimpl(m_buf,size);
  43. if (clear)
  44. for (int i=0;i<size;++i)
  45. m_buf[i]=T();
  46. m_size = size;
  47. }
  48. T& operator[](int index)
  49. {
  50. jassert(index >= 0 && index < m_size);
  51. return m_buf[index];
  52. }
  53. const T& operator[](int index) const
  54. {
  55. jassert(index >= 0 && index < m_size);
  56. return m_buf[index];
  57. }
  58. T* data()
  59. {
  60. // callers to this will likely just blow themselves up if they get a nullptr back
  61. jassert(m_buf!=nullptr);
  62. return m_buf;
  63. }
  64. int getSize() { return m_size; }
  65. FFTWBuffer(FFTWBuffer&& other) : m_buf(other.m_buf), m_size(other.m_size)
  66. {
  67. other.m_buf = nullptr;
  68. other.m_size = 0;
  69. }
  70. FFTWBuffer& operator = (FFTWBuffer&& other)
  71. {
  72. std::swap(other.m_buf, m_buf);
  73. std::swap(other.m_size, m_size);
  74. return *this;
  75. }
  76. // These buffers probably shouldn't be copied anywhere, so just disallow that for now
  77. FFTWBuffer(const FFTWBuffer&) = delete;
  78. FFTWBuffer& operator = (const FFTWBuffer&) = delete;
  79. private:
  80. T* m_buf = nullptr;
  81. int m_size = 0;
  82. void mallocimpl(T*& buf,int size)
  83. {
  84. if constexpr (std::is_same<T,float>::value)
  85. buf = (float*)fftwf_malloc(size*sizeof(float));
  86. else
  87. buf = (double*)fftw_malloc(size * sizeof(double));
  88. }
  89. void freeimpl(T*& buf)
  90. {
  91. if (buf!=nullptr)
  92. {
  93. if constexpr (std::is_same<T, float>::value)
  94. fftwf_free(buf);
  95. else
  96. fftw_free(buf);
  97. buf = nullptr;
  98. }
  99. }
  100. };
  101. enum FFTWindow{W_RECTANGULAR,W_HAMMING,W_HANN,W_BLACKMAN,W_BLACKMAN_HARRIS};
  102. class FFT
  103. {//FFT class that considers phases as random
  104. public:
  105. FFT(int nsamples_, bool no_inverse=false);//samples must be even
  106. ~FFT();
  107. void smp2freq();//input is smp, output is freq (phases are discarded)
  108. void freq2smp();//input is freq,output is smp (phases are random)
  109. void applywindow(FFTWindow type);
  110. std::vector<REALTYPE> smp;//size of samples/2
  111. std::vector<REALTYPE> freq;//size of samples
  112. int nsamples=0;
  113. private:
  114. fftwf_plan planfftw,planifftw;
  115. FFTWBuffer<REALTYPE> data;
  116. struct{
  117. std::vector<REALTYPE> data;
  118. FFTWindow type;
  119. }window;
  120. std::mt19937 m_randgen;
  121. std::uniform_int_distribution<unsigned int> m_randdist{0,32767};
  122. };
  123. class Stretch
  124. {
  125. public:
  126. Stretch(REALTYPE rap_,int in_bufsize_,FFTWindow w=W_HAMMING,bool bypass_=false,REALTYPE samplerate_=44100,int stereo_mode_=0);
  127. //in_bufsize is also a half of a FFT buffer (in samples)
  128. virtual ~Stretch();
  129. int get_max_bufsize(){
  130. return bufsize*3;
  131. };
  132. int get_bufsize(){
  133. return bufsize;
  134. };
  135. virtual void setBufferSize(int sz);
  136. REALTYPE get_onset_detection_sensitivity(){
  137. return onset_detection_sensitivity;
  138. };
  139. REALTYPE process(REALTYPE *smps,int nsmps);//returns the onset value
  140. void set_freezing(bool new_freezing){
  141. freezing=new_freezing;
  142. };
  143. bool isFreezing() { return freezing; }
  144. 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
  145. int get_nsamples(REALTYPE current_pos_percents);//how many samples are required
  146. 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)
  147. int get_skip_nsamples();//used for shorten
  148. void set_rap(REALTYPE newrap);//set the current stretch value
  149. void set_onset_detection_sensitivity(REALTYPE detection_sensitivity);;
  150. void here_is_onset(REALTYPE onset);
  151. virtual void setSampleRate(REALTYPE sr) { samplerate = jlimit(1000.0f, 384000.0f, sr); }
  152. REALTYPE getSampleRate() { return samplerate; }
  153. FFTWindow window_type;
  154. protected:
  155. int bufsize=0;
  156. virtual void process_spectrum(REALTYPE *){};
  157. virtual REALTYPE get_stretch_multiplier(REALTYPE pos_percents);
  158. REALTYPE samplerate=0.0f;
  159. private:
  160. void do_analyse_inbuf(REALTYPE *smps);
  161. void do_next_inbuf_smps(REALTYPE *smps);
  162. REALTYPE do_detect_onset();
  163. // REALTYPE *in_pool;//de marimea in_bufsize
  164. REALTYPE rap,onset_detection_sensitivity;
  165. std::vector<REALTYPE> old_out_smps;
  166. std::vector<REALTYPE> old_freq;
  167. std::vector<REALTYPE> new_smps,old_smps,very_old_smps;
  168. std::unique_ptr<FFT> infft,outfft;
  169. std::unique_ptr<FFT> fft;
  170. long double remained_samples;//0..1
  171. long double extra_onset_time_credit;
  172. REALTYPE c_pos_percents;
  173. int skip_samples;
  174. bool require_new_buffer;
  175. bool bypass,freezing;
  176. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Stretch)
  177. };