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.

120 lines
2.8KB

  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 "stdsynthmodule.h"
  19. #include "resample.h"
  20. #include <cstring>
  21. using namespace std;
  22. using namespace Arts;
  23. namespace Arts {
  24. class PacketRefiller : public Refiller {
  25. protected:
  26. queue< DataPacket<mcopbyte>* > inqueue;
  27. int pos;
  28. public:
  29. PacketRefiller() : pos(0)
  30. {
  31. }
  32. void process(DataPacket<mcopbyte>* packet)
  33. {
  34. inqueue.push(packet);
  35. }
  36. unsigned long read(unsigned char *buffer, unsigned long bytes)
  37. {
  38. unsigned long done = 0;
  39. while(!inqueue.empty())
  40. {
  41. long tocopy = bytes - done;
  42. if(tocopy == 0) return bytes; /* complete? */
  43. DataPacket<mcopbyte> *packet = inqueue.front();
  44. if(tocopy > (packet->size - pos))
  45. tocopy = (packet->size - pos);
  46. memcpy(&buffer[done],&packet->contents[pos],tocopy);
  47. pos += tocopy;
  48. done += tocopy;
  49. if(pos == packet->size) {
  50. packet->processed();
  51. pos = 0;
  52. inqueue.pop();
  53. }
  54. }
  55. return done;
  56. }
  57. };
  58. class ByteStreamToAudio_impl : public ByteStreamToAudio_skel,
  59. public StdSynthModule
  60. {
  61. PacketRefiller refiller;
  62. Resampler resampler;
  63. long _samplingRate, _channels, _bits;
  64. public:
  65. ByteStreamToAudio_impl() :resampler(&refiller),
  66. _samplingRate(44100), _channels(2), _bits(16)
  67. {
  68. //
  69. }
  70. long samplingRate() { return _samplingRate; }
  71. void samplingRate(long newRate) {
  72. _samplingRate = newRate;
  73. resampler.setStep((float)_samplingRate / samplingRateFloat);
  74. }
  75. long channels() { return _channels; }
  76. void channels(long newChannels) {
  77. _channels = newChannels;
  78. resampler.setChannels(_channels);
  79. }
  80. long bits() { return _bits; }
  81. void bits(long newBits) {
  82. _bits = newBits;
  83. resampler.setBits(_bits);
  84. }
  85. bool running() { return !resampler.underrun(); }
  86. void process_indata(DataPacket<mcopbyte> *packet)
  87. {
  88. refiller.process(packet);
  89. }
  90. void calculateBlock(unsigned long samples)
  91. {
  92. resampler.run(left,right,samples);
  93. }
  94. };
  95. REGISTER_IMPLEMENTATION(ByteStreamToAudio_impl);
  96. }