gambatte-libretro/common/ringbuffer.h

113 lines
3.0 KiB
C
Raw Normal View History

- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
/***************************************************************************
* Copyright (C) 2008 by Sindre Aamås *
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
* aamas@stud.ntnu.no *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
#include "array.h"
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
#include <cstddef>
#include <algorithm>
#include <cstring>
template<typename T>
class RingBuffer {
Array<T> buf;
std::size_t sz;
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
std::size_t rpos;
std::size_t wpos;
public:
RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); }
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
std::size_t avail() const {
return (wpos < rpos ? 0 : sz) + rpos - wpos - 1;
}
void clear() {
wpos = rpos = 0;
}
void fill(T value);
void read(T *out, std::size_t num);
void reset(std::size_t sz_in);
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
std::size_t size() const {
return sz - 1;
}
std::size_t used() const {
return (wpos < rpos ? sz : 0) + wpos - rpos;
}
void write(const T *in, std::size_t num);
};
template<typename T>
void RingBuffer<T>::fill(const T value) {
std::fill(buf + 0, buf + sz, value);
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
rpos = 0;
wpos = sz - 1;
}
template<typename T>
void RingBuffer<T>::read(T *out, std::size_t num) {
if (rpos + num > sz) {
const std::size_t n = sz - rpos;
std::memcpy(out, buf + rpos, n * sizeof(T));
rpos = 0;
num -= n;
out += n;
}
std::memcpy(out, buf + rpos, num * sizeof(T));
if ((rpos += num) == sz)
rpos = 0;
}
template<typename T>
void RingBuffer<T>::reset(const std::size_t sz_in) {
sz = sz_in + 1;
rpos = wpos = 0;
buf.reset(sz_in ? sz : 0);
}
- Real-time, sophisticated resampling framework with several performance/quality profiles for dynamically generated windowed sinc and CIC chains based on analysis of fourier transforms and optimal cost equations. Fast 2-tap linear as a low quality alternative. - libgambatte: Use deltas and a running sum to decrease buffer writes in sound emulation sample generation. - libgambatte: Rearrange sound emulation event loop to optimize for high-frequency event units. - libgambatte: Initialize palette arrays to avoid valgrind noise. - Don't do resampling in libgambatte. Update API to reflect this. - Move non-emulation common code to a common directory to avoid duplication. - Update front-ends to new libgambatte API. - Utilize resampling framework in front-ends. Selectable resamplers. - Improved adaptive sleep class that estimates oversleep. - Gambatte SDL: Estimate actual output sample rate in terms of OS timers and derive frame rate from it. - Gambatte SDL: Move AudioData and RingBuffer classes to separate files. - Gambatte SDL: Make underruns slightly less painful, by resetting buffer positions. - Gambatte Qt: Update AudioEngine to support sample rate estimation in terms of OS timers. - Gambatte Qt: Implement sample rate estimation in ALSA and OSS audio engines. - Gambatte Qt: AlsaEngine: Revert to using snd_pcm_avail_update for buffer status since snd_pcm_delay may consider external latencies. - Gambatte Qt: AlsaEngine: Use snd_pcm_hw_params_set_buffer_time_near. Don't request a particular number of periods per buffer. - Gambatte Qt: AlsaEngine: Use hw as default custom device string, rather than hw:0,0. - Gambatte Qt: OssEngine: Don't trust GETOSPACE fragment info. - Gambatte Qt: Estimate optimal frame rate based on sample rate estimations. - Gambatte Qt: Extend BlitterWidget to support estimation of vsynced frame rate in terms of OS timers. - Gambatte Qt: Implement vsync frame rate estimation in QGlBlitter, Direct3DBlitter and DirectDrawBlitter. - Gambatte Qt: Use a combination of OS timer sample rate estimation and vsync frame rate estimation to derive resampling ratio for no-frame-duplication vsync. - Gambatte Qt: Change API to reflect MediaSources not being responsible for resampling. - Gambatte Qt: Make sure to parent PaletteDialog list model, so it gets deleted properly. - Various refactoring, small changes and stuff I forgot. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@165 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
2008-10-13 21:08:08 +00:00
template<typename T>
void RingBuffer<T>::write(const T *in, std::size_t num) {
if (wpos + num > sz) {
const std::size_t n = sz - wpos;
std::memcpy(buf + wpos, in, n * sizeof(T));
wpos = 0;
num -= n;
in += n;
}
std::memcpy(buf + wpos, in, num * sizeof(T));
if ((wpos += num) == sz)
wpos = 0;
}
#endif