diff options
Diffstat (limited to 'attic/muse_qt4_evolution/muse/fifo.cpp')
-rw-r--r-- | attic/muse_qt4_evolution/muse/fifo.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/attic/muse_qt4_evolution/muse/fifo.cpp b/attic/muse_qt4_evolution/muse/fifo.cpp new file mode 100644 index 00000000..12c2febf --- /dev/null +++ b/attic/muse_qt4_evolution/muse/fifo.cpp @@ -0,0 +1,183 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "fifo.h" +#include "globals.h" +#include "al/dsp.h" + +//--------------------------------------------------------- +// clear +//--------------------------------------------------------- + +void FifoBase::clear() + { + ridx = 0; + widx = 0; + counter = 0; + } + +//--------------------------------------------------------- +// push +//--------------------------------------------------------- + +void FifoBase::push() + { + widx = (widx + 1) % FIFO_BUFFER; +// q_atomic_increment(&counter); + ++counter; + } + +//--------------------------------------------------------- +// pop +//--------------------------------------------------------- + +void FifoBase::pop() + { + ridx = (ridx + 1) % FIFO_BUFFER; + // q_atomic_decrement(&counter); + --counter; + } + +//--------------------------------------------------------- +// Fifo +//--------------------------------------------------------- + +Fifo::Fifo() + { + nbuffer = FIFO_BUFFER; + buffer = new FifoBuffer*[nbuffer]; + for (int i = 0; i < nbuffer; ++i) + buffer[i] = new FifoBuffer; + clear(); + } + +Fifo::~Fifo() + { + for (int i = 0; i < nbuffer; ++i) + delete buffer[i]; + delete[] buffer; + } + +//--------------------------------------------------------- +// put +// return true if fifo full +//--------------------------------------------------------- + +bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos) + { + if (counter == nbuffer) { + printf("FIFO %p overrun at 0x%x\n", this, pos); + return true; + } + FifoBuffer* b = buffer[widx]; + int n = segs * samples; + if (b->maxSize < n) { + if (b->buffer) + free(b->buffer); + posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n); + b->maxSize = n; + } + b->size = samples; + b->segs = segs; + b->pos = pos; + for (int i = 0; i < segs; ++i) + AL::dsp->cpy(b->buffer + i * samples, src[i], samples); + push(); + return false; + } + +//--------------------------------------------------------- +// get +// return true if fifo empty +//--------------------------------------------------------- + +bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned pos) + { + FifoBuffer* b; + bool errMsg = true; + for (;;) { + if (counter == 0) { + printf("FIFO %p underrun at 0x%x\n", this, pos); + return true; + } + b = buffer[ridx]; + if (pos == b->pos) + break; + // + // skip all buffer until we get the rigth one or the + // fifo is empty + // +// if (errMsg) + printf("Fifo %p::get(0x%x) n=%d, discard wrong prefetch block(s) 0x%x\n", + this, pos, counter, b->pos); + pop(); + errMsg = false; + } + for (int i = 0; i < segs; ++i) + dst[i] = b->buffer + samples * (i % b->segs); + pop(); + return false; + } + +//--------------------------------------------------------- +// get +// return true if fifo empty +//--------------------------------------------------------- + +bool Fifo::get(int segs, unsigned long samples, float** dst) + { + FifoBuffer* b; + if (counter == 0) { + printf("FIFO %p underrun --cannot happen!\n", this); + return true; + } + b = buffer[ridx]; + for (int i = 0; i < segs; ++i) + dst[i] = b->buffer + samples * (i % b->segs); + pop(); + return false; + } + +//--------------------------------------------------------- +// getWriteBuffer +// return true, if no more buffer available +// (overflow) +//--------------------------------------------------------- + +bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned pos) + { + if (counter == nbuffer) + return true; + FifoBuffer* b = buffer[widx]; + int n = segs * samples; + if (b->maxSize < n) { + if (b->buffer) + free(b->buffer); + posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n); + b->maxSize = n; + } + for (int i = 0; i < segs; ++i) + buf[i] = b->buffer + i * samples; + b->size = samples; + b->segs = segs; + b->pos = pos; + return false; + } + |