memcpy(data_, data + size_1, size_2);
end_index_ = size_2;
}
size_ += bytes_to_write;
return bytes_to_write;
}
size_t CircularBuffer::read(char *data, size_t bytes)
{
if (bytes == 0) return 0;
size_t capacity = capacity_;
size_t bytes_to_read = std::min(bytes, size_);
// Read in a single step
if (bytes_to_read <= capacity - beg_index_)
{
memcpy(data, data_ + beg_index_, bytes_to_read);
beg_index_ += bytes_to_read;
if (beg_index_ == capacity) beg_index_ = 0;
}
// Read in two steps
else
{
size_t size_1 = capacity - beg_index_;
memcpy(data, data_ + beg_index_, size_1);
size_t size_2 = bytes_to_read - size_1;
memcpy(data + size_1, data_, size_2);
beg_index_ = size_2;
}
size_ -= bytes_to_read;
return bytes_to_read;
}Similar phenomenon can be observed in API of the FMOD sound library. Just like graphical textures in DirectX, sound samples in FMOD can also be "locked" to get pointer to a raw memory we can read or fill. But DirectX textures lie in the continuous memory region, so we get a single pointer. The only difficult thing in understanding locking textures is the concept of "stride", which can be greater than the width of a single row. Here in FMOD the Sound::lock() method returns two pointers and two lengths, probably because the locked region can wrap over end of internally used circular buffer like the one shown above.