2 * Copyright (c) 1999-2000, Eric Moon.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "RawBuffer.h"
37 #include <RealtimeAlloc.h>
41 // -------------------------------------------------------- //
42 // ctor/dtor/accessors
43 // -------------------------------------------------------- //
45 // allocate buffer (if frames > 0)
50 rtm_pool
* pFromPool
) :
54 m_frameSize(frameSize
),
57 m_bCircular(bCircular
),
65 // point to given data (does NOT take responsibility for
66 // deleting it; use adopt() for that.)
72 rtm_pool
* pFromPool
) :
76 m_frameSize(frameSize
),
79 m_bCircular(bCircular
),
83 RawBuffer::RawBuffer(const RawBuffer
& clone
) {
87 // generate a reference to the buffer
88 RawBuffer
& RawBuffer::operator=(const RawBuffer
& clone
) {
89 m_pData
= clone
.m_pData
;
90 m_allocatedSize
= clone
.m_allocatedSize
;
91 m_frameSize
= clone
.m_frameSize
;
92 m_frames
= clone
.m_frames
;
93 m_bCircular
= clone
.m_bCircular
;
94 m_pPool
= clone
.m_pPool
;
100 // deallocate if I own the data
101 RawBuffer::~RawBuffer() {
105 char* RawBuffer::data() const { return (char*)m_pData
; }
106 // returns pointer to given frame
107 char* RawBuffer::frame(uint32 frame
) const {
108 return data() + (frame
* frameSize());
110 uint32
RawBuffer::frameSize() const { return m_frameSize
; }
111 uint32
RawBuffer::frames() const { return m_frames
; }
112 uint32
RawBuffer::size() const { return m_frames
* m_frameSize
; }
114 bool RawBuffer::isCircular() const { return m_bCircular
; }
115 bool RawBuffer::ownsBuffer() const { return m_bOwnData
; }
117 rtm_pool
* RawBuffer::pool() const { return m_pPool
; }
119 // resize buffer, re-allocating if necessary to contain
120 // designated number of frames.
121 // Does not preserve buffer contents.
123 void RawBuffer::resize(uint32 frames
) {
124 uint32 sizeRequired
= frames
* m_frameSize
;
126 // already have enough storage?
127 if(sizeRequired
< m_allocatedSize
&&
133 // free existing storage
137 m_pData
= (m_pPool
) ?
138 rtm_alloc(m_pPool
, sizeRequired
) :
139 new int8
[sizeRequired
];
142 m_allocatedSize
= sizeRequired
;
147 // take ownership of buffer from target
148 // (deletes current buffer data, if any owned)
150 void RawBuffer::adopt(
157 // clean up myself first
161 operator=(RawBuffer(pData
, frameSize
, frames
, bCircular
, pPool
));
167 // returns false if the target doesn't own the data, but references it
168 // one way or the other
170 bool RawBuffer::adopt(RawBuffer
& target
) {
175 // take ownership if possible
177 if(!target
.m_bOwnData
) {
182 target
.m_bOwnData
= false;
187 // adopt currently ref'd data (if any; returns false if no buffer data or
190 bool RawBuffer::adopt() {
191 if(!m_pData
|| m_bOwnData
)
198 // -------------------------------------------------------- //
200 // -------------------------------------------------------- //
202 // fill the buffer with zeroes
204 void RawBuffer::zero() {
205 if(!m_pData
|| !m_frames
)
208 memset(m_pData
, 0, m_frames
* m_frameSize
);
211 // raw copy to destination buffer, returning the number of
212 // frames written, and adjusting both offsets accordingly.
214 // no frames will be written if the buffers' frame sizes
217 uint32
RawBuffer::rawCopyTo(
219 uint32
* pioFromFrame
,
220 uint32
* pioTargetFrame
,
221 uint32 frames
) const {
223 if(m_frameSize
!= target
.m_frameSize
)
228 ASSERT(target
.m_pData
);
230 // convert frame counts to byte offsets
231 uint32 fromOffset
= *pioFromFrame
* m_frameSize
;
232 uint32 targetOffset
= *pioTargetFrame
* m_frameSize
;
234 // figure buffer sizes in bytes
235 uint32 size
= m_frames
* m_frameSize
;
236 uint32 targetSize
= target
.m_frames
* target
.m_frameSize
;
238 // figure amount to write
239 uint32 toCopy
= frames
* m_frameSize
;
240 if(target
.m_bCircular
) {
241 if(toCopy
> targetSize
)
244 if(toCopy
> (targetSize
-targetOffset
))
245 toCopy
= (targetSize
-targetOffset
);
247 uint32 remaining
= toCopy
;
252 // figure a contiguous area to fill
253 uint32 targetChunk
= targetSize
- targetOffset
;
255 if(targetChunk
> remaining
)
256 targetChunk
= remaining
;
258 // fill it (from one or more source areas)
259 while(targetChunk
> 0) {
261 // figure a contiguous source area
262 uint32 sourceChunk
= size
- fromOffset
;
263 if(sourceChunk
> targetChunk
)
264 sourceChunk
= targetChunk
;
268 (int8
*)target
.m_pData
+ targetOffset
,
269 (int8
*)m_pData
+ fromOffset
,
273 targetOffset
+= sourceChunk
;
274 if(targetOffset
== targetSize
)
277 fromOffset
+= sourceChunk
;
278 if(fromOffset
== size
)
281 // figure remaining portion of target area to fill
282 targetChunk
-= sourceChunk
;
283 remaining
-= sourceChunk
;
288 *pioFromFrame
= fromOffset
/ m_frameSize
;
289 *pioTargetFrame
= targetOffset
/ m_frameSize
;
294 // more convenient version of above if you don't care
295 // how the offsets change.
297 uint32
RawBuffer::rawCopyTo(
301 uint32 frames
) const {
303 return rawCopyTo(target
, &fromOffset
, &targetOffset
, frames
);
306 // -------------------------------------------------------- //
307 // internal operations
308 // -------------------------------------------------------- //
310 // free owned data, if any
311 // [16jun99] uses proper rtm_free() call if needed
312 void RawBuffer::free() {
313 if(!(m_bOwnData
&& m_pData
))
319 delete [] (int8
*)m_pData
;
325 // END -- RawBuffer.cpp --