Mercurial > audlegacy-plugins
diff src/console/Fir_Resampler.cxx @ 316:fb513e10174e trunk
[svn] - merge libconsole-blargg into mainline libconsole:
+ obsoletes plugins-ugly:sapplug
| author | nenolod |
|---|---|
| date | Thu, 30 Nov 2006 19:54:33 -0800 |
| parents | 3da1b8942b8b |
| children | 3b3887985a5c |
line wrap: on
line diff
--- a/src/console/Fir_Resampler.cxx Wed Nov 29 14:42:11 2006 -0800 +++ b/src/console/Fir_Resampler.cxx Thu Nov 30 19:54:33 2006 -0800 @@ -1,5 +1,4 @@ - -// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/ +// Game_Music_Emu 0.5.1. http://www.slack.net/~ant/ #include "Fir_Resampler.h" @@ -14,81 +13,45 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include BLARGG_SOURCE_BEGIN - -// to do: fix problems with rolloff < 0.99 or so, and rolloff == 1.0, and related problems - -// Sinc impulse genertor - -const bool show_impulse = 0; +#include "blargg_source.h" -static const double pi = 3.1415926535897932384626433832795029L; +#undef PI +#define PI 3.1415926535897932384626433832795029 -class Dsf { - double rolloff; - double factor; -public: - Dsf( double r ) : rolloff( r ) - { - factor = 1.0; - //if ( rolloff < 1.0 ) - // factor = 1.0 / (*this)( 0 ); - } +static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale, + int count, short* out ) +{ + double const maxh = 256; + double const step = PI / maxh * spacing; + double const to_w = maxh * 2 / width; + double const pow_a_n = pow( rolloff, maxh ); + scale /= maxh * 2; - double operator () ( double angle ) const - { - double const n_harm = 256; - angle /= n_harm; - double pow_a_n = pow( rolloff, n_harm ); - //double rescale = 1.0 / n_harm; - - double num = 1.0 - rolloff * cos( angle ) - - pow_a_n * cos( n_harm * angle ) + - pow_a_n * rolloff * cos( (n_harm - 1) * angle ); - double den = 1 + rolloff * (rolloff - 2 * cos( angle )); - - return (num / den - 1) / n_harm * factor; - } -}; - -template<class Sinc> -void gen_sinc( int width, double offset, double spacing, int count, double scale, short* p, - const Sinc& sinc ) -{ - double range = pi * (width / 2); - double step = pi * spacing; - double a = -step * (count / 2 - 1); - a -= offset * step; - + double angle = (count / 2 - 1 + offset) * -step; while ( count-- ) { - double w = a / range; - double y = 0.0; - if ( fabs( w ) < 1.0 ) + *out++ = 0; + double w = angle * to_w; + if ( fabs( w ) < PI ) { - double window = cos( pi * w ) * 0.5 + 0.5; - y = sinc( a ) * window; + double rolloff_cos_a = rolloff * cos( angle ); + double num = 1 - rolloff_cos_a - + pow_a_n * cos( maxh * angle ) + + pow_a_n * rolloff * cos( (maxh - 1) * angle ); + double den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff; + double sinc = scale * num / den - scale; + + out [-1] = (short) (cos( w ) * sinc + sinc); } - - *p++ = (short) (y * scale); - a += step; + angle += step; } } -/* -static double plain_sinc( double a ) -{ - return fabs( a ) < 0.00001 ? 1.0 : sin( a ) / a; -} -*/ - -// Fir_Resampler - Fir_Resampler_::Fir_Resampler_( int width, sample_t* impulses_ ) : width_( width ), write_offset( width * stereo - stereo ), @@ -102,9 +65,7 @@ ratio_ = 1.0; } -Fir_Resampler_::~Fir_Resampler_() -{ -} +Fir_Resampler_::~Fir_Resampler_() { } void Fir_Resampler_::clear() { @@ -118,9 +79,9 @@ blargg_err_t Fir_Resampler_::buffer_size( int new_size ) { - BLARGG_RETURN_ERR( buf.resize( new_size + write_offset ) ); + RETURN_ERR( buf.resize( new_size + write_offset ) ); clear(); - return blargg_success; + return 0; } double Fir_Resampler_::time_ratio( double new_factor, double rolloff, double gain ) @@ -156,21 +117,11 @@ double filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_; double pos = 0.0; input_per_cycle = 0; - Dsf dsf( rolloff ); for ( int i = 0; i < res; i++ ) { - if ( show_impulse ) - printf( "pos = %f\n", pos ); - - gen_sinc( int (width_ * filter + 1) & ~1, pos, filter, (int) width_, - double (0x7fff * gain * filter), impulses + i * width_, dsf ); - - if ( show_impulse ) - { - for ( int j = 0; j < width_; j++ ) - printf( "%d ", (int) impulses [i * width_ + j] ); - printf( "\n" ); - } + gen_sinc( rolloff, int (width_ * filter + 1) & ~1, pos, filter, + double (0x7FFF * gain * filter), + (int) width_, impulses + i * width_ ); pos += fstep; input_per_cycle += step; @@ -182,20 +133,14 @@ } } - if ( show_impulse ) - { - printf( "skip = %8lX\n", (long) skip_bits ); - printf( "step = %d\n", step ); - } - clear(); return ratio_; } -int Fir_Resampler_::input_needed( long output_count ) const +int Fir_Resampler_::input_needed( blargg_long output_count ) const { - long input_count = 0; + blargg_long input_count = 0; unsigned long skip = skip_bits >> imp; int remain = res - imp; @@ -217,13 +162,13 @@ return input_extra; } -int Fir_Resampler_::avail_( long input_count ) const +int Fir_Resampler_::avail_( blargg_long input_count ) const { int cycle_count = input_count / input_per_cycle; int output_count = cycle_count * res * stereo; input_count -= cycle_count * input_per_cycle; - unsigned long skip = skip_bits >> imp; + blargg_ulong skip = skip_bits >> imp; int remain = res - imp; while ( input_count >= 0 ) { @@ -243,7 +188,6 @@ { int remain = write_pos - buf.begin(); int avail = remain - width_ * stereo; - if ( avail < 0 ) avail = 0; // inserted if ( count > avail ) count = avail; @@ -253,4 +197,3 @@ return count; } -
