Mercurial > audio-send
view Alc/alcRing.c @ 19:22ac5a0367cd
finally, a first pass at ear.org
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 03 Nov 2011 14:54:45 -0700 |
parents | f9476ff7637e |
children |
line wrap: on
line source
1 /**2 * OpenAL cross platform audio library3 * Copyright (C) 1999-2007 by authors.4 * This library is free software; you can redistribute it and/or5 * modify it under the terms of the GNU Library General Public6 * License as published by the Free Software Foundation; either7 * version 2 of the License, or (at your option) any later version.8 *9 * This library is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 * Library General Public License for more details.13 *14 * You should have received a copy of the GNU Library General Public15 * License along with this library; if not, write to the16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,17 * Boston, MA 02111-1307, USA.18 * Or go to http://www.gnu.org/copyleft/lgpl.html19 */21 #include "config.h"23 #include <string.h>24 #include <stdlib.h>26 #include "alMain.h"29 struct RingBuffer {30 ALubyte *mem;32 ALsizei frame_size;33 ALsizei length;34 ALint read_pos;35 ALint write_pos;37 CRITICAL_SECTION cs;38 };41 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length)42 {43 RingBuffer *ring = calloc(1, sizeof(*ring) + ((length+1) * frame_size));44 if(ring)45 {46 ring->mem = (ALubyte*)(ring+1);48 ring->frame_size = frame_size;49 ring->length = length+1;50 ring->read_pos = 0;51 ring->write_pos = 0;53 InitializeCriticalSection(&ring->cs);54 }55 return ring;56 }58 void DestroyRingBuffer(RingBuffer *ring)59 {60 if(ring)61 {62 DeleteCriticalSection(&ring->cs);63 free(ring);64 }65 }67 ALsizei RingBufferSize(RingBuffer *ring)68 {69 ALsizei s;71 EnterCriticalSection(&ring->cs);72 s = (ring->write_pos-ring->read_pos+ring->length) % ring->length;73 LeaveCriticalSection(&ring->cs);75 return s;76 }78 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)79 {80 int remain;82 EnterCriticalSection(&ring->cs);84 remain = (ring->read_pos-ring->write_pos-1+ring->length) % ring->length;85 if(remain < len) len = remain;87 if(len > 0)88 {89 remain = ring->length - ring->write_pos;90 if(remain < len)91 {92 memcpy(ring->mem+(ring->write_pos*ring->frame_size), data,93 remain*ring->frame_size);94 memcpy(ring->mem, data+(remain*ring->frame_size),95 (len-remain)*ring->frame_size);96 }97 else98 memcpy(ring->mem+(ring->write_pos*ring->frame_size), data,99 len*ring->frame_size);101 ring->write_pos += len;102 ring->write_pos %= ring->length;103 }105 LeaveCriticalSection(&ring->cs);106 }108 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)109 {110 int remain;112 EnterCriticalSection(&ring->cs);114 remain = ring->length - ring->read_pos;115 if(remain < len)116 {117 memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), remain*ring->frame_size);118 memcpy(data+(remain*ring->frame_size), ring->mem, (len-remain)*ring->frame_size);119 }120 else121 memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), len*ring->frame_size);123 ring->read_pos += len;124 ring->read_pos %= ring->length;126 LeaveCriticalSection(&ring->cs);127 }