You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.2 KiB
74 lines
2.2 KiB
/*
|
|
* Copyright 2012 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <time.h>
|
|
#include <string.h>
|
|
|
|
#include "synth.h"
|
|
#include "ringbuffer.h"
|
|
|
|
RingBuffer::RingBuffer() {
|
|
rd_ix_ = 0;
|
|
wr_ix_ = 0;
|
|
}
|
|
|
|
int RingBuffer::BytesAvailable() {
|
|
return (wr_ix_ - rd_ix_) & (kBufSize - 1);
|
|
}
|
|
|
|
int RingBuffer::WriteBytesAvailable() {
|
|
return (rd_ix_ - wr_ix_ - 1) & (kBufSize - 1);
|
|
}
|
|
|
|
int RingBuffer::Read(int size, uint8_t *bytes) {
|
|
int rd_ix = rd_ix_;
|
|
SynthMemoryBarrier(); // read barrier, make sure data is committed before ix
|
|
int fragment_size = min(size, kBufSize - rd_ix);
|
|
memcpy(bytes, buf_ + rd_ix, fragment_size);
|
|
if (size > fragment_size) {
|
|
memcpy(bytes + fragment_size, buf_, size - fragment_size);
|
|
}
|
|
SynthMemoryBarrier(); // full barrier, make sure read commits before updating
|
|
rd_ix_ = (rd_ix + size) & (kBufSize - 1);
|
|
return size;
|
|
}
|
|
|
|
int RingBuffer::Write(const uint8_t *bytes, int size) {
|
|
int remaining = size;
|
|
while (remaining > 0) {
|
|
int rd_ix = rd_ix_;
|
|
int wr_ix = wr_ix_;
|
|
int space_available = (rd_ix - wr_ix - 1) & (kBufSize - 1);
|
|
if (space_available == 0) {
|
|
struct timespec sleepTime;
|
|
sleepTime.tv_sec = 0;
|
|
sleepTime.tv_nsec = 1000000;
|
|
nanosleep(&sleepTime, NULL);
|
|
} else {
|
|
int wr_size = min(remaining, space_available);
|
|
int fragment_size = min(wr_size, kBufSize - wr_ix);
|
|
memcpy(buf_ + wr_ix, bytes, fragment_size);
|
|
if (wr_size > fragment_size) {
|
|
memcpy(buf_, bytes + fragment_size, wr_size - fragment_size);
|
|
}
|
|
SynthMemoryBarrier(); // write barrier, make sure data commits
|
|
wr_ix_ = (wr_ix + wr_size) & (kBufSize - 1);
|
|
remaining -= wr_size;
|
|
bytes += wr_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
|