1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/* audiodevs: Abstraction layer for audio hardware & samples
Copyright (C) 2003-2004 Nemosoft Unv.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For questions, remarks, patches, etc. for this program, the author can be
reached at camstream@smcc.demon.nl.
*/
#ifndef RINGBUFFER_HPP
#define RINGBUFFER_HPP
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <qlist.h>
#include <qobject.h>
#include <qthread.h>
#include "AudioSample.h"
// Forward declarations
class CRingBufferWriter;
class CRingBufferReader;
class CRingBuffer: public QObject
{
friend class CRingBufferWriter;
friend class CRingBufferReader;
Q_OBJECT
private:
QMutex Head; ///< The head-pointer lock
QMutex Lists; ///< For manipulating the lists
QList<CRingBufferWriter> Writers;
QList<CRingBufferReader> Readers;
unsigned int BufferSpace, BufferHead, MaxLength;
void *Buffer;
/* Statistical data */
long BytesWritten; ///< Total amount of bytes put in buffer
int Overflows; ///< Number of times our buffer got full
/* Called by Writers */
void AttachWriter(CRingBufferWriter *s);
void DetachWriter(CRingBufferWriter *s);
int AddToBuffer(void *data, int len, bool must_fit);
int SpaceLeft();
int SpaceUsed();
/* Called by Readers */
void AttachReader(CRingBufferReader *r);
void DetachReader(CRingBufferReader *r);
/* Called by both Readers and Writers */
void Flush();
public:
CRingBuffer(unsigned int buffer_space);
~CRingBuffer();
unsigned int GetBufferLength();
signals:
void ReaderAttached();
void ReaderDetached();
void WriterAttached();
void WriterDetached();
void BufferFlushed();
};
class CRingBufferWriter
{
private:
CRingBuffer *pRing;
CRingBufferWriter(const CRingBufferWriter &) {}; // copies are impossible
public:
CRingBufferWriter(CRingBuffer *ring);
~CRingBufferWriter();
int WriteToBuffer(void *, int len, bool must_fit = false) const;
int SpaceLeft() const;
int SpaceUsed() const;
void Flush() const;
};
class CRingBufferReader: public QObject
{
friend class CRingBuffer;
Q_OBJECT
private:
CRingBuffer *pRing;
QMutex Lock;
QWaitCondition DataReady;
unsigned int BufferTail, MyBufferLength;
unsigned int LowWaterMark, HighWaterMark;
CRingBufferReader(const CRingBufferReader &r) {}; // copies are impossible
public:
CRingBufferReader(CRingBuffer *ring);
~CRingBufferReader();
int SpaceUsed() const;
int ReadFromBufferTail(void *, unsigned int len);
int ReadFromBufferHead(void *, unsigned int len, bool clear = false, unsigned long time = ULONG_MAX);
virtual bool event(QEvent *e); // overloaded
void SetLowWaterMark(unsigned int);
unsigned int GetLowWaterMark() const;
void SetHighWaterMark(unsigned int);
unsigned int GetHighWaterMark() const;
signals:
void DataArrived(int bytes);
void BufferFlushed();
};
#endif
|