diff Plugins/Input/console/Dual_Resampler.cpp @ 493:c04dff121e1d trunk

[svn] hostile merge, phase 2: reimport based on new plugin code
author nenolod
date Tue, 24 Jan 2006 20:19:01 -0800
parents
children f12d7e208b43
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/Dual_Resampler.cpp	Tue Jan 24 20:19:01 2006 -0800
@@ -0,0 +1,120 @@
+
+// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
+
+#include "Dual_Resampler.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
+can redistribute it and/or modify it under the terms of the GNU Lesser
+General Public License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version. This
+module 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 Lesser General Public License for
+more details. You should have received a copy of the GNU Lesser General
+Public License along with this module; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include BLARGG_SOURCE_BEGIN
+
+int const resampler_extra = 256;
+
+Dual_Resampler::Dual_Resampler()
+{
+}
+
+Dual_Resampler::~Dual_Resampler()
+{
+}
+
+blargg_err_t Dual_Resampler::resize( int pairs )
+{
+	BLARGG_RETURN_ERR( sample_buf.resize( pairs * 2 ) );
+	buf_pos = sample_buf.size();
+	oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
+	return resampler.buffer_size( oversamples_per_frame + resampler_extra );
+}
+
+void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, sample_t* out )
+{
+	long pair_count = sample_buf.size() >> 1;
+	blip_time_t blip_time = blip_buf.count_clocks( pair_count );
+	int sample_count = oversamples_per_frame - resampler.written();
+	
+	int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
+	assert( unsigned (new_count - sample_count) < resampler_extra );
+	
+	blip_buf.end_frame( blip_time );
+	assert( blip_buf.samples_avail() == pair_count );
+	
+	resampler.write( new_count );
+	
+	long count = resampler.read( sample_buf.begin(), sample_buf.size() );
+	assert( count == (long) sample_buf.size() );
+	
+	mix_samples( blip_buf, out );
+	blip_buf.remove_samples( pair_count );
+}
+
+void Dual_Resampler::play( long count, sample_t* out, Blip_Buffer& blip_buf )
+{
+	// empty extra buffer
+	long remain = sample_buf.size() - buf_pos;
+	if ( remain )
+	{
+		if ( remain > count )
+			remain = count;
+		count -= remain;
+		memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
+		out += remain;
+		buf_pos += remain;
+	}
+	
+	// entire frames
+	while ( count >= (long) sample_buf.size() )
+	{
+		play_frame_( blip_buf, out );
+		out += sample_buf.size();
+		count -= sample_buf.size();
+	}
+	
+	// extra
+	if ( count )
+	{
+		play_frame_( blip_buf, sample_buf.begin() );
+		buf_pos = count;
+		memcpy( out, sample_buf.begin(), count * sizeof *out );
+		out += count;
+	}
+}
+
+#include BLARGG_ENABLE_OPTIMIZER
+
+void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, sample_t* out )
+{
+	Blip_Reader sn;
+	int bass = sn.begin( blip_buf );
+	const sample_t* in = sample_buf.begin();
+	
+	for ( int n = sample_buf.size() >> 1; n--; )
+	{
+		int s = sn.read();
+		long l = (long) in [0] * 2 + s;
+		sn.next( bass );
+		long r = in [1];
+		if ( (BOOST::int16_t) l != l )
+			l = 0x7FFF - (l >> 24);
+		r = r * 2 + s;
+		in += 2;
+		out [0] = l;
+		out [1] = r;
+		out += 2;
+		if ( (BOOST::int16_t) r != r )
+			out [-1] = 0x7FFF - (r >> 24);
+	}
+	
+	sn.end( blip_buf );
+}
+