~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to lib-src/portaudio-v19/pablio/ringbuffer.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * $Id: ringbuffer.c,v 1.4 2006/09/23 18:42:46 llucius Exp $
3
 
 * ringbuffer.c
4
 
 * Ring Buffer utility..
5
 
 *
6
 
 * Author: Phil Burk, http://www.softsynth.com
7
 
 *
8
 
 * This program uses the PortAudio Portable Audio Library.
9
 
 * For more information see: http://www.portaudio.com
10
 
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
11
 
 *
12
 
 * Permission is hereby granted, free of charge, to any person obtaining
13
 
 * a copy of this software and associated documentation files
14
 
 * (the "Software"), to deal in the Software without restriction,
15
 
 * including without limitation the rights to use, copy, modify, merge,
16
 
 * publish, distribute, sublicense, and/or sell copies of the Software,
17
 
 * and to permit persons to whom the Software is furnished to do so,
18
 
 * subject to the following conditions:
19
 
 *
20
 
 * The above copyright notice and this permission notice shall be
21
 
 * included in all copies or substantial portions of the Software.
22
 
 *
23
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26
 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
27
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
28
 
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29
 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
 
 */
31
 
 
32
 
/*
33
 
 * The text above constitutes the entire PortAudio license; however, 
34
 
 * the PortAudio community also makes the following non-binding requests:
35
 
 *
36
 
 * Any person wishing to distribute modifications to the Software is
37
 
 * requested to send the modifications to the original developer so that
38
 
 * they can be incorporated into the canonical version. It is also 
39
 
 * requested that these non-binding requests be included along with the 
40
 
 * license above.
41
 
 */
42
 
 
43
 
#include <stdio.h>
44
 
#include <stdlib.h>
45
 
#include <math.h>
46
 
#include "ringbuffer.h"
47
 
#include <string.h>
48
 
 
49
 
/***************************************************************************
50
 
 * Initialize FIFO.
51
 
 * numBytes must be power of 2, returns -1 if not.
52
 
 */
53
 
long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr )
54
 
{
55
 
    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
56
 
    rbuf->bufferSize = numBytes;
57
 
    rbuf->buffer = (char *)dataPtr;
58
 
    RingBuffer_Flush( rbuf );
59
 
    rbuf->bigMask = (numBytes*2)-1;
60
 
    rbuf->smallMask = (numBytes)-1;
61
 
    return 0;
62
 
}
63
 
/***************************************************************************
64
 
** Return number of bytes available for reading. */
65
 
long RingBuffer_GetReadAvailable( RingBuffer *rbuf )
66
 
{
67
 
    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
68
 
}
69
 
/***************************************************************************
70
 
** Return number of bytes available for writing. */
71
 
long RingBuffer_GetWriteAvailable( RingBuffer *rbuf )
72
 
{
73
 
    return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
74
 
}
75
 
 
76
 
/***************************************************************************
77
 
** Clear buffer. Should only be called when buffer is NOT being read. */
78
 
void RingBuffer_Flush( RingBuffer *rbuf )
79
 
{
80
 
    rbuf->writeIndex = rbuf->readIndex = 0;
81
 
}
82
 
 
83
 
/***************************************************************************
84
 
** Get address of region(s) to which we can write data.
85
 
** If the region is contiguous, size2 will be zero.
86
 
** If non-contiguous, size2 will be the size of second region.
87
 
** Returns room available to be written or numBytes, whichever is smaller.
88
 
*/
89
 
long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
90
 
                                 void **dataPtr1, long *sizePtr1,
91
 
                                 void **dataPtr2, long *sizePtr2 )
92
 
{
93
 
    long   index;
94
 
    long   available = RingBuffer_GetWriteAvailable( rbuf );
95
 
    if( numBytes > available ) numBytes = available;
96
 
    /* Check to see if write is not contiguous. */
97
 
    index = rbuf->writeIndex & rbuf->smallMask;
98
 
    if( (index + numBytes) > rbuf->bufferSize )
99
 
    {
100
 
        /* Write data in two blocks that wrap the buffer. */
101
 
        long   firstHalf = rbuf->bufferSize - index;
102
 
        *dataPtr1 = &rbuf->buffer[index];
103
 
        *sizePtr1 = firstHalf;
104
 
        *dataPtr2 = &rbuf->buffer[0];
105
 
        *sizePtr2 = numBytes - firstHalf;
106
 
    }
107
 
    else
108
 
    {
109
 
        *dataPtr1 = &rbuf->buffer[index];
110
 
        *sizePtr1 = numBytes;
111
 
        *dataPtr2 = NULL;
112
 
        *sizePtr2 = 0;
113
 
    }
114
 
    return numBytes;
115
 
}
116
 
 
117
 
 
118
 
/***************************************************************************
119
 
*/
120
 
long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes )
121
 
{
122
 
    return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
123
 
}
124
 
 
125
 
/***************************************************************************
126
 
** Get address of region(s) from which we can read data.
127
 
** If the region is contiguous, size2 will be zero.
128
 
** If non-contiguous, size2 will be the size of second region.
129
 
** Returns room available to be written or numBytes, whichever is smaller.
130
 
*/
131
 
long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
132
 
                                void **dataPtr1, long *sizePtr1,
133
 
                                void **dataPtr2, long *sizePtr2 )
134
 
{
135
 
    long   index;
136
 
    long   available = RingBuffer_GetReadAvailable( rbuf );
137
 
    if( numBytes > available ) numBytes = available;
138
 
    /* Check to see if read is not contiguous. */
139
 
    index = rbuf->readIndex & rbuf->smallMask;
140
 
    if( (index + numBytes) > rbuf->bufferSize )
141
 
    {
142
 
        /* Write data in two blocks that wrap the buffer. */
143
 
        long firstHalf = rbuf->bufferSize - index;
144
 
        *dataPtr1 = &rbuf->buffer[index];
145
 
        *sizePtr1 = firstHalf;
146
 
        *dataPtr2 = &rbuf->buffer[0];
147
 
        *sizePtr2 = numBytes - firstHalf;
148
 
    }
149
 
    else
150
 
    {
151
 
        *dataPtr1 = &rbuf->buffer[index];
152
 
        *sizePtr1 = numBytes;
153
 
        *dataPtr2 = NULL;
154
 
        *sizePtr2 = 0;
155
 
    }
156
 
    return numBytes;
157
 
}
158
 
/***************************************************************************
159
 
*/
160
 
long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes )
161
 
{
162
 
    return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
163
 
}
164
 
 
165
 
/***************************************************************************
166
 
** Return bytes written. */
167
 
long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes )
168
 
{
169
 
    long size1, size2, numWritten;
170
 
    void *data1, *data2;
171
 
    numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
172
 
    if( size2 > 0 )
173
 
    {
174
 
 
175
 
        memcpy( data1, data, size1 );
176
 
        data = ((char *)data) + size1;
177
 
        memcpy( data2, data, size2 );
178
 
    }
179
 
    else
180
 
    {
181
 
        memcpy( data1, data, size1 );
182
 
    }
183
 
    RingBuffer_AdvanceWriteIndex( rbuf, numWritten );
184
 
    return numWritten;
185
 
}
186
 
 
187
 
/***************************************************************************
188
 
** Return bytes read. */
189
 
long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes )
190
 
{
191
 
    long size1, size2, numRead;
192
 
    void *data1, *data2;
193
 
    numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
194
 
    if( size2 > 0 )
195
 
    {
196
 
        memcpy( data, data1, size1 );
197
 
        data = ((char *)data) + size1;
198
 
        memcpy( data, data2, size2 );
199
 
    }
200
 
    else
201
 
    {
202
 
        memcpy( data, data1, size1 );
203
 
    }
204
 
    RingBuffer_AdvanceReadIndex( rbuf, numRead );
205
 
    return numRead;
206
 
}