1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * $Id: pa_ringbuffer.c 1421 2009-11-18 16:09:05Z bjornroche $ 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Portable Audio I/O Library 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Ring Buffer utility. 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Author: Phil Burk, http://www.softsynth.com 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * modified for SMP safety on Mac OS X by Bjorn Roche 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * modified for SMP safety on Linux by Leland Lucius 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * also, allowed for const where possible 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * modified for multiple-byte-sized data elements by Sven Fischer 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Note that this is safe only for a single-thread reader and a 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * single-thread writer. 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This program uses the PortAudio Portable Audio Library. 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * For more information see: http://www.portaudio.com 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 1999-2000 Ross Bencina and Phil Burk 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Permission is hereby granted, free of charge, to any person obtaining 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * a copy of this software and associated documentation files 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * (the "Software"), to deal in the Software without restriction, 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * including without limitation the rights to use, copy, modify, merge, 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * publish, distribute, sublicense, and/or sell copies of the Software, 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and to permit persons to whom the Software is furnished to do so, 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * subject to the following conditions: 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The above copyright notice and this permission notice shall be 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * included in all copies or substantial portions of the Software. 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The text above constitutes the entire PortAudio license; however, 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the PortAudio community also makes the following non-binding requests: 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Any person wishing to distribute modifications to the Software is 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * requested to send the modifications to the original developer so that 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * they can be incorporated into the canonical version. It is also 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * requested that these non-binding requests be included along with the 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * license above. 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @file 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org @ingroup common_src 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 55bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include <math.h> 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h> 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h> 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h> 59bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/modules/audio_device/mac/portaudio/pa_memorybarrier.h" 60bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/modules/audio_device/mac/portaudio/pa_ringbuffer.h" 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Initialize FIFO. 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * elementCount must be power of 2, returns -1 if not. 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr ) 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */ 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rbuf->bufferSize = elementCount; 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rbuf->buffer = (char *)dataPtr; 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUtil_FlushRingBuffer( rbuf ); 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rbuf->bigMask = (elementCount*2)-1; 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rbuf->smallMask = (elementCount)-1; 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rbuf->elementSizeBytes = elementSizeBytes; 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Return number of elements available for reading. */ 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ) 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUtil_ReadMemoryBarrier(); 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask ); 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Return number of elements available for writing. */ 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ) 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */ 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf)); 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Clear buffer. Should only be called when buffer is NOT being read. */ 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ) 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rbuf->writeIndex = rbuf->readIndex = 0; 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Get address of region(s) to which we can write data. 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** If the region is contiguous, size2 will be zero. 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** If non-contiguous, size2 will be the size of second region. 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Returns room available to be written or elementCount, whichever is smaller. 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void **dataPtr1, ring_buffer_size_t *sizePtr1, 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void **dataPtr2, ring_buffer_size_t *sizePtr2 ) 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t index; 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t available = PaUtil_GetRingBufferWriteAvailable( rbuf ); 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( elementCount > available ) elementCount = available; 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check to see if write is not contiguous. */ 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index = rbuf->writeIndex & rbuf->smallMask; 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( (index + elementCount) > rbuf->bufferSize ) 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Write data in two blocks that wrap the buffer. */ 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t firstHalf = rbuf->bufferSize - index; 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr1 = firstHalf; 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr2 = &rbuf->buffer[0]; 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr2 = elementCount - firstHalf; 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr1 = elementCount; 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr2 = NULL; 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr2 = 0; 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return elementCount; 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ) 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* we need to ensure that previous writes are seen before we update the write index */ 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUtil_WriteMemoryBarrier(); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask; 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Get address of region(s) from which we can read data. 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** If the region is contiguous, size2 will be zero. 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** If non-contiguous, size2 will be the size of second region. 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Returns room available to be written or elementCount, whichever is smaller. 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void **dataPtr1, ring_buffer_size_t *sizePtr1, 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void **dataPtr2, ring_buffer_size_t *sizePtr2 ) 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t index; 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t available = PaUtil_GetRingBufferReadAvailable( rbuf ); 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( elementCount > available ) elementCount = available; 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check to see if read is not contiguous. */ 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index = rbuf->readIndex & rbuf->smallMask; 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( (index + elementCount) > rbuf->bufferSize ) 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Write data in two blocks that wrap the buffer. */ 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t firstHalf = rbuf->bufferSize - index; 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr1 = firstHalf; 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr2 = &rbuf->buffer[0]; 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr2 = elementCount - firstHalf; 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr1 = elementCount; 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *dataPtr2 = NULL; 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *sizePtr2 = 0; 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return elementCount; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org*/ 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ) 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* we need to ensure that previous writes are always seen before updating the index. */ 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUtil_WriteMemoryBarrier(); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Return elements written. */ 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount ) 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t size1, size2, numWritten; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void *data1, *data2; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( size2 > 0 ) 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy( data1, data, size1*rbuf->elementSizeBytes ); 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org data = ((char *)data) + size1*rbuf->elementSizeBytes; 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy( data2, data, size2*rbuf->elementSizeBytes ); 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy( data1, data, size1*rbuf->elementSizeBytes ); 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten ); 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return numWritten; 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*************************************************************************** 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org** Return elements read. */ 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount ) 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ring_buffer_size_t size1, size2, numRead; 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void *data1, *data2; 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if( size2 > 0 ) 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy( data, data1, size1*rbuf->elementSizeBytes ); 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org data = ((char *)data) + size1*rbuf->elementSizeBytes; 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy( data, data2, size2*rbuf->elementSizeBytes ); 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy( data, data1, size1*rbuf->elementSizeBytes ); 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead ); 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return numRead; 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 228