mirror of
https://github.com/libretro/beetle-pce-fast-libretro.git
synced 2024-11-23 16:00:08 +00:00
189 lines
4.1 KiB
C++
189 lines
4.1 KiB
C++
|
|
// Blip_Buffer 0.3.0. http://www.slack.net/~ant/nes-emu/
|
|
|
|
#include <blip/Stereo_Buffer.h>
|
|
|
|
/* Library Copyright (C) 2004 Shay Green. Blip_Buffer is free software;
|
|
you can redistribute it and/or modify it under the terms of the GNU
|
|
General Public License as published by the Free Software Foundation;
|
|
either version 2 of the License, or (at your option) any later version.
|
|
Stereo_Buffer 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
|
|
for more details. You should have received a copy of the GNU General
|
|
Public License along with Stereo_Buffer; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
Stereo_Buffer::Stereo_Buffer() {
|
|
}
|
|
|
|
Stereo_Buffer::~Stereo_Buffer() {
|
|
}
|
|
|
|
bool Stereo_Buffer::set_sample_rate( long rate, int msec )
|
|
{
|
|
for ( int i = 0; i < buf_count; i++ ) {
|
|
if ( bufs [i].set_sample_rate( rate, msec ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Stereo_Buffer::clock_rate( long rate )
|
|
{
|
|
for ( int i = 0; i < buf_count; i++ )
|
|
bufs [i].clock_rate( rate );
|
|
}
|
|
|
|
void Stereo_Buffer::bass_freq( int bass )
|
|
{
|
|
for ( unsigned i = 0; i < buf_count; i++ )
|
|
bufs [i].bass_freq( bass );
|
|
}
|
|
|
|
void Stereo_Buffer::clear()
|
|
{
|
|
stereo_added = false;
|
|
was_stereo = false;
|
|
for ( int i = 0; i < buf_count; i++ )
|
|
bufs [i].clear();
|
|
}
|
|
|
|
void Stereo_Buffer::end_frame( blip_time_t clock_count, bool stereo )
|
|
{
|
|
for ( unsigned i = 0; i < buf_count; i++ )
|
|
{
|
|
bufs [i].end_frame( clock_count );
|
|
}
|
|
stereo_added |= stereo;
|
|
}
|
|
|
|
|
|
|
|
long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples )
|
|
{
|
|
long count = bufs [0].samples_avail();
|
|
if ( count > max_samples / 2 )
|
|
count = max_samples / 2;
|
|
if ( count )
|
|
{
|
|
if ( stereo_added || was_stereo )
|
|
{
|
|
mix_stereo( out, count );
|
|
|
|
bufs [0].remove_samples( count );
|
|
bufs [1].remove_samples( count );
|
|
bufs [2].remove_samples( count );
|
|
}
|
|
else
|
|
{
|
|
mix_mono( out, count );
|
|
|
|
bufs [0].remove_samples( count );
|
|
|
|
bufs [1].remove_silence( count );
|
|
bufs [2].remove_silence( count );
|
|
}
|
|
|
|
// to do: this might miss opportunities for optimization
|
|
if ( !bufs [0].samples_avail() ) {
|
|
was_stereo = stereo_added;
|
|
stereo_added = false;
|
|
}
|
|
}
|
|
|
|
return count * 2;
|
|
}
|
|
|
|
void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count )
|
|
{
|
|
Blip_Reader left;
|
|
Blip_Reader right;
|
|
Blip_Reader center;
|
|
|
|
left.begin( bufs [1] );
|
|
right.begin( bufs [2] );
|
|
int bass = center.begin( bufs [0] );
|
|
|
|
while ( count-- )
|
|
{
|
|
int c = center.read();
|
|
out [0] = c + left.read();
|
|
out [1] = c + right.read();
|
|
out += 2;
|
|
|
|
center.next( bass );
|
|
left.next( bass );
|
|
right.next( bass );
|
|
}
|
|
|
|
center.end( bufs [0] );
|
|
right.end( bufs [2] );
|
|
left.end( bufs [1] );
|
|
}
|
|
|
|
void Stereo_Buffer::mix_stereo( float* out, long count )
|
|
{
|
|
Blip_Reader left;
|
|
Blip_Reader right;
|
|
Blip_Reader center;
|
|
|
|
left.begin( bufs [1] );
|
|
right.begin( bufs [2] );
|
|
int bass = center.begin( bufs [0] );
|
|
|
|
while ( count-- )
|
|
{
|
|
int c = center.read();
|
|
out [0] = (float)(c + left.read()) / 32768;
|
|
out [1] = (float)(c + right.read()) / 32768;
|
|
out += 2;
|
|
|
|
center.next( bass );
|
|
left.next( bass );
|
|
right.next( bass );
|
|
}
|
|
|
|
center.end( bufs [0] );
|
|
right.end( bufs [2] );
|
|
left.end( bufs [1] );
|
|
}
|
|
|
|
void Stereo_Buffer::mix_mono( blip_sample_t* out, long count )
|
|
{
|
|
Blip_Reader in;
|
|
int bass = in.begin( bufs [0] );
|
|
|
|
while ( count-- )
|
|
{
|
|
int sample = in.read();
|
|
out [0] = sample;
|
|
out [1] = sample;
|
|
out += 2;
|
|
in.next( bass );
|
|
}
|
|
|
|
in.end( bufs [0] );
|
|
}
|
|
|
|
void Stereo_Buffer::mix_mono( float* out, long count )
|
|
{
|
|
Blip_Reader in;
|
|
int bass = in.begin( bufs [0] );
|
|
|
|
while ( count-- )
|
|
{
|
|
int sample = in.read();
|
|
out [0] = (float)(sample) / 32768;
|
|
out [1] = (float)(sample) / 32768;
|
|
out += 2;
|
|
in.next( bass );
|
|
}
|
|
|
|
in.end( bufs [0] );
|
|
}
|
|
|