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.

synth_record_impl.cc 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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 "debug.h"
  19. #include "convert.h"
  20. #include "objectmanager.h"
  21. #include "audiosubsys.h"
  22. #include "dispatcher.h"
  23. #include "iomanager.h"
  24. #include "flowsystem.h"
  25. #include "stdsynthmodule.h"
  26. #include <stdio.h>
  27. #include <iostream>
  28. #include <cstring>
  29. #undef DEBUG_WAVEFORM
  30. #ifdef DEBUG_WAVEFORM
  31. #include <fstream>
  32. #endif
  33. using namespace std;
  34. using namespace Arts;
  35. namespace Arts {
  36. class Synth_RECORD_impl : virtual public Synth_RECORD_skel,
  37. virtual public ASConsumer,
  38. virtual public StdSynthModule
  39. {
  40. #ifdef DEBUG_WAVEFORM
  41. ofstream plotfile;
  42. #endif
  43. protected:
  44. AudioSubSystem *as;
  45. bool haveSubSys;
  46. typedef unsigned char uchar;
  47. unsigned char *inblock;
  48. unsigned long maxsamples;
  49. unsigned long channels;
  50. int format;
  51. int bits;
  52. public:
  53. #ifdef DEBUG_WAVEFORM
  54. Synth_RECORD_impl()
  55. : plotfile( "/dev/shm/synth_record.plot" )
  56. {
  57. }
  58. #endif
  59. /*
  60. * functions from the SynthModule interface (which is inherited by
  61. * SynthPlay)
  62. */
  63. void streamInit() {
  64. as = AudioSubSystem::the();
  65. channels = as->channels();
  66. format = as->format();
  67. bits = as->bits();
  68. maxsamples = 0;
  69. inblock = 0;
  70. haveSubSys = as->attachConsumer(this);
  71. if(!haveSubSys)
  72. {
  73. arts_info("Synth_RECORD: audio subsystem is already used");
  74. return;
  75. }
  76. }
  77. void streamEnd() {
  78. arts_debug("Synth_RECORD: detaching");
  79. if(haveSubSys) as->detachConsumer();
  80. if(inblock)
  81. {
  82. delete[] inblock;
  83. inblock = 0;
  84. }
  85. }
  86. AutoSuspendState autoSuspend()
  87. {
  88. return static_cast<AutoSuspendState>(asSuspend|asProducer);
  89. }
  90. void calculateBlock(unsigned long samples)
  91. {
  92. // no audio subsystem, no play
  93. if(!as->running() || !haveSubSys) return;
  94. if(samples > maxsamples)
  95. {
  96. maxsamples = samples;
  97. if(inblock) delete[] inblock;
  98. inblock = new uchar[maxsamples * channels * bits / 8];
  99. }
  100. assert(channels);
  101. as->read(inblock,channels * (bits/8) * samples);
  102. arts_assert(format == 8 || format == 16 || format == 17 || format == 32);
  103. if(format == 8)
  104. {
  105. if(channels == 1)
  106. convert_mono_8_float(samples,inblock,left);
  107. if(channels == 2)
  108. convert_stereo_i8_2float(samples,inblock,left,right);
  109. }
  110. else if(format == 16)
  111. {
  112. if(channels == 1)
  113. convert_mono_16le_float(samples,inblock,left);
  114. if(channels == 2)
  115. convert_stereo_i16le_2float(samples,inblock,left,right);
  116. }
  117. else if(format == 17)
  118. {
  119. if(channels == 1)
  120. convert_mono_16be_float(samples,inblock,left);
  121. if(channels == 2)
  122. convert_stereo_i16be_2float(samples,inblock,left,right);
  123. }
  124. else if(format == 32)
  125. {
  126. if(channels == 2)
  127. {
  128. float * end = (float *)(inblock + 8 * samples);
  129. float * floatbuffer = (float *)inblock;
  130. while(floatbuffer < end)
  131. {
  132. #ifdef DEBUG_WAVEFORM
  133. plotfile << *floatbuffer << "\n";
  134. #endif
  135. *left++ = *floatbuffer++;
  136. *right++ = *floatbuffer++;
  137. }
  138. }
  139. else if(channels == 1)
  140. memcpy(left, inblock, samples);
  141. }
  142. }
  143. /**
  144. * havemore from the ASConsumer interface (AudioSubSystem)
  145. */
  146. void haveMore()
  147. {
  148. _node()->requireFlow();
  149. }
  150. };
  151. REGISTER_IMPLEMENTATION(Synth_RECORD_impl);
  152. }
  153. // vim: sw=4 ts=4