diff options
Diffstat (limited to 'flow/bytestreamtoaudio_impl.cpp')
-rw-r--r-- | flow/bytestreamtoaudio_impl.cpp | 119 |
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); + +} |