aRts audio server
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.

stereofftscope_impl.cc 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. Copyright (C) 2000 Stefan Westerfeld
  3. stefan@space.twc.de
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library 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 GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #include "artsflow.h"
  18. #include "fft.h"
  19. #include "stdsynthmodule.h"
  20. #include <math.h>
  21. #include <iostream>
  22. using namespace std;
  23. using namespace Arts;
  24. namespace Arts {
  25. class StereoFFTScope_impl : public StereoFFTScope_skel, public StdSynthModule {
  26. protected:
  27. static const unsigned long SAMPLES = 4096;
  28. vector<float> _scope;
  29. /*
  30. * some gcc versions expose ugly behaviour with virtual inheritance:
  31. * putting window[4096] & inbuffer[4096] here bloats the vtable then,
  32. * and tells you to recompile with -fhuge-objects ... so allocate them
  33. * dynamically
  34. */
  35. float *window;
  36. float *inbuffer;
  37. unsigned long inbufferpos;
  38. public:
  39. void do_fft()
  40. {
  41. float out_real[SAMPLES],out_img[SAMPLES];
  42. arts_fft_float(SAMPLES,0,inbuffer,0,out_real,out_img);
  43. _scope.clear();
  44. unsigned int i = 3;
  45. unsigned int j = 0;
  46. for(;;) {
  47. float xrange = 0.0;
  48. while(j != i)
  49. {
  50. xrange += (fabs(out_img[j]) + fabs(out_real[j]))/(float)SAMPLES;
  51. j++;
  52. }
  53. _scope.push_back(xrange);
  54. if(i == SAMPLES/2) return;
  55. i += i/2;
  56. if(i > SAMPLES/2) i = SAMPLES/2;
  57. }
  58. }
  59. void streamInit()
  60. {
  61. unsigned long i;
  62. for(i=0;i<SAMPLES;i++)
  63. {
  64. float x = (float)i/(float)SAMPLES;
  65. window[i] = sin(x*M_PI)*sin(x*M_PI);
  66. inbuffer[i] = 0;
  67. }
  68. do_fft(); // initialize so that we never return an empty scope
  69. }
  70. void streamStart()
  71. {
  72. inbufferpos = 0;
  73. }
  74. vector<float> *scope()
  75. {
  76. return new vector<float>(_scope);
  77. }
  78. /*
  79. in audio stream inleft, inright;
  80. out audio stream outleft, outright;
  81. */
  82. void calculateBlock(unsigned long samples)
  83. {
  84. unsigned long i;
  85. for(i=0;i<samples;i++)
  86. {
  87. inbuffer[inbufferpos] =
  88. (inleft[i] + inright[i])*window[inbufferpos];
  89. if(++inbufferpos == SAMPLES)
  90. {
  91. do_fft();
  92. inbufferpos = 0;
  93. }
  94. /*
  95. monitoring only tasks can't be done with that StereoEffect
  96. interface nicely - copy input to output until there is
  97. something better
  98. */
  99. outleft[i] = inleft[i];
  100. outright[i] = inright[i];
  101. }
  102. }
  103. /* prevent vtable overflows (see above) */
  104. StereoFFTScope_impl() {
  105. window = new float[SAMPLES];
  106. inbuffer = new float[SAMPLES];
  107. }
  108. ~StereoFFTScope_impl() {
  109. delete [] window;
  110. delete [] inbuffer;
  111. }
  112. };
  113. const unsigned long StereoFFTScope_impl::SAMPLES;
  114. REGISTER_IMPLEMENTATION(StereoFFTScope_impl);
  115. }