1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// A ring buffer to hold arbitrary data. Provides no thread safety. Unless 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// otherwise specified, functions return 0 on success and -1 on error. 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 149fb16139d917ba32720e031d3c871987d418668fpbos@webrtc.org#include "webrtc/modules/audio_processing/utility/ring_buffer.h" 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org#include <stddef.h> // size_t 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h> 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h> 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgenum Wrap { 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SAME_WRAP, 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DIFF_WRAP 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgstruct RingBuffer { 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t read_pos; 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t write_pos; 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t element_count; 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t element_size; 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum Wrap rw_wrap; 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* data; 32b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org}; 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Get address of region(s) from which we can read data. 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// If the region is contiguous, |data_ptr_bytes_2| will be zero. 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// If non-contiguous, |data_ptr_bytes_2| will be the size in bytes of the second 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// region. Returns room available to be read or |element_count|, whichever is 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// smaller. 39b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgstatic size_t GetBufferReadRegions(RingBuffer* buf, 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t element_count, 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void** data_ptr_1, 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t* data_ptr_bytes_1, 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void** data_ptr_2, 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t* data_ptr_bytes_2) { 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const size_t readable_elements = WebRtc_available_read(buf); 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const size_t read_elements = (readable_elements < element_count ? 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org readable_elements : element_count); 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const size_t margin = buf->element_count - buf->read_pos; 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Check to see if read is not contiguous. 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (read_elements > margin) { 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Write data in two blocks that wrap the buffer. 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_1 = buf->data + buf->read_pos * buf->element_size; 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_bytes_1 = margin * buf->element_size; 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_2 = buf->data; 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_bytes_2 = (read_elements - margin) * buf->element_size; 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_1 = buf->data + buf->read_pos * buf->element_size; 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_bytes_1 = read_elements * buf->element_size; 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_2 = NULL; 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr_bytes_2 = 0; 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return read_elements; 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 68db32d60125dfe78a1eb475f39672484c63b034b1andrew@webrtc.orgRingBuffer* WebRtc_CreateBuffer(size_t element_count, size_t element_size) { 69b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org RingBuffer* self = NULL; 70b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (element_count == 0 || element_size == 0) { 71db32d60125dfe78a1eb475f39672484c63b034b1andrew@webrtc.org return NULL; 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 74b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org self = malloc(sizeof(RingBuffer)); 75b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 76db32d60125dfe78a1eb475f39672484c63b034b1andrew@webrtc.org return NULL; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->data = malloc(element_count * element_size); 80b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self->data) { 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org free(self); 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self = NULL; 83db32d60125dfe78a1eb475f39672484c63b034b1andrew@webrtc.org return NULL; 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->element_count = element_count; 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->element_size = element_size; 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 89db32d60125dfe78a1eb475f39672484c63b034b1andrew@webrtc.org return self; 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 92b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgint WebRtc_InitBuffer(RingBuffer* self) { 93b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->read_pos = 0; 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->write_pos = 0; 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->rw_wrap = SAME_WRAP; 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize buffer to zeros 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(self->data, 0, self->element_count * self->element_size); 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 107b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgvoid WebRtc_FreeBuffer(void* handle) { 108b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org RingBuffer* self = (RingBuffer*)handle; 109b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 110b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org return; 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org free(self->data); 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org free(self); 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 117b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgsize_t WebRtc_ReadBuffer(RingBuffer* self, 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void** data_ptr, 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* data, 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t element_count) { 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (self == NULL) { 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (data == NULL) { 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* buf_ptr_1 = NULL; 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* buf_ptr_2 = NULL; 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t buf_ptr_bytes_1 = 0; 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t buf_ptr_bytes_2 = 0; 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const size_t read_count = GetBufferReadRegions(self, 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org element_count, 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &buf_ptr_1, 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &buf_ptr_bytes_1, 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &buf_ptr_2, 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &buf_ptr_bytes_2); 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (buf_ptr_bytes_2 > 0) { 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We have a wrap around when reading the buffer. Copy the buffer data to 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // |data| and point to it. 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(data, buf_ptr_1, buf_ptr_bytes_1); 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(((char*) data) + buf_ptr_bytes_1, buf_ptr_2, buf_ptr_bytes_2); 146b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org buf_ptr_1 = data; 147b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org } else if (!data_ptr) { 148b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org // No wrap, but a memcpy was requested. 149b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org memcpy(data, buf_ptr_1, buf_ptr_bytes_1); 150b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org } 151b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (data_ptr) { 152b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org // |buf_ptr_1| == |data| in the case of a wrap. 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *data_ptr = buf_ptr_1; 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update read position 157b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org WebRtc_MoveReadPtr(self, (int) read_count); 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return read_count; 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 163b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgsize_t WebRtc_WriteBuffer(RingBuffer* self, 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const void* data, 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t element_count) { 166b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 169b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!data) { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 174b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org const size_t free_elements = WebRtc_available_write(self); 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const size_t write_elements = (free_elements < element_count ? free_elements 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : element_count); 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t n = write_elements; 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const size_t margin = self->element_count - self->write_pos; 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (write_elements > margin) { 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Buffer wrap around when writing. 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(self->data + self->write_pos * self->element_size, 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org data, margin * self->element_size); 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->write_pos = 0; 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org n -= margin; 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->rw_wrap = DIFF_WRAP; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(self->data + self->write_pos * self->element_size, 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ((const char*) data) + ((write_elements - n) * self->element_size), 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org n * self->element_size); 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->write_pos += n; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return write_elements; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 197b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgint WebRtc_MoveReadPtr(RingBuffer* self, int element_count) { 198b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We need to be able to take care of negative changes, hence use "int" 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // instead of "size_t". 205b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org const int free_elements = (int) WebRtc_available_write(self); 206b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org const int readable_elements = (int) WebRtc_available_read(self); 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int read_pos = (int) self->read_pos; 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (element_count > readable_elements) { 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org element_count = readable_elements; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (element_count < -free_elements) { 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org element_count = -free_elements; 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org read_pos += element_count; 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (read_pos > (int) self->element_count) { 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Buffer wrap around. Restart read position and wrap indicator. 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org read_pos -= (int) self->element_count; 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->rw_wrap = SAME_WRAP; 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (read_pos < 0) { 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Buffer wrap around. Restart read position and wrap indicator. 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org read_pos += (int) self->element_count; 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->rw_wrap = DIFF_WRAP; 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org self->read_pos = (size_t) read_pos; 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return element_count; 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 234b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgsize_t WebRtc_available_read(const RingBuffer* self) { 235b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (self->rw_wrap == SAME_WRAP) { 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return self->write_pos - self->read_pos; 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return self->element_count - self->read_pos + self->write_pos; 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 246b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.orgsize_t WebRtc_available_write(const RingBuffer* self) { 247b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org if (!self) { 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 251b3e5a623285b082a23655cdc02f35a40f652acdfandrew@webrtc.org return self->element_count - WebRtc_available_read(self); 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 253