summaryrefslogtreecommitdiffstats
path: root/flow/bytestreamtoaudio_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flow/bytestreamtoaudio_impl.cpp')
-rw-r--r--flow/bytestreamtoaudio_impl.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/flow/bytestreamtoaudio_impl.cpp b/flow/bytestreamtoaudio_impl.cpp
new file mode 100644
index 0000000..de9ef7c
--- /dev/null
+++ b/flow/bytestreamtoaudio_impl.cpp
@@ -0,0 +1,119 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "resample.h"
+
+#include <cstring>
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class PacketRefiller : public Refiller {
+protected:
+ queue< DataPacket<mcopbyte>* > inqueue;
+ int pos;
+
+public:
+ PacketRefiller() : pos(0)
+ {
+ }
+ void process(DataPacket<mcopbyte>* packet)
+ {
+ inqueue.push(packet);
+ }
+ unsigned long read(unsigned char *buffer, unsigned long bytes)
+ {
+ unsigned long done = 0;
+ while(!inqueue.empty())
+ {
+ long tocopy = bytes - done;
+ if(tocopy == 0) return bytes; /* complete? */
+
+ DataPacket<mcopbyte> *packet = inqueue.front();
+ if(tocopy > (packet->size - pos))
+ tocopy = (packet->size - pos);
+
+ memcpy(&buffer[done],&packet->contents[pos],tocopy);
+ pos += tocopy;
+ done += tocopy;
+
+ if(pos == packet->size) {
+ packet->processed();
+ pos = 0;
+ inqueue.pop();
+ }
+ }
+ return done;
+ }
+};
+
+class ByteStreamToAudio_impl : public ByteStreamToAudio_skel,
+ public StdSynthModule
+{
+ PacketRefiller refiller;
+ Resampler resampler;
+ long _samplingRate, _channels, _bits;
+public:
+ ByteStreamToAudio_impl() :resampler(&refiller),
+ _samplingRate(44100), _channels(2), _bits(16)
+ {
+ //
+ }
+
+ long samplingRate() { return _samplingRate; }
+ void samplingRate(long newRate) {
+ _samplingRate = newRate;
+ resampler.setStep((float)_samplingRate / samplingRateFloat);
+ }
+
+ long channels() { return _channels; }
+ void channels(long newChannels) {
+ _channels = newChannels;
+ resampler.setChannels(_channels);
+ }
+
+ long bits() { return _bits; }
+ void bits(long newBits) {
+ _bits = newBits;
+ resampler.setBits(_bits);
+ }
+
+ bool running() { return !resampler.underrun(); }
+
+ void process_indata(DataPacket<mcopbyte> *packet)
+ {
+ refiller.process(packet);
+ }
+
+ void calculateBlock(unsigned long samples)
+ {
+ resampler.run(left,right,samples);
+ }
+};
+
+REGISTER_IMPLEMENTATION(ByteStreamToAudio_impl);
+
+}