From 5618d058a33bf3ec4c6759a793ab9517edc8f66e Mon Sep 17 00:00:00 2001 From: Chris Moeller Date: Wed, 26 Mar 2014 21:49:31 -0700 Subject: [PATCH] Updated DUMB and modplay, and added a setting to control the resampling used by both, as well as by BASSMIDI, which will use sinc if specified --- Application/AppController.m | 2 + .../Dumb/Dumb.xcodeproj/project.pbxproj | 8 - Frameworks/Dumb/dumb/include/dumb.h | 23 +- .../Dumb/dumb/include/internal/blip_buf.h | 80 - .../Dumb/dumb/include/internal/resampler.h | 9 +- Frameworks/Dumb/dumb/src/helpers/blip_buf.c | 354 --- Frameworks/Dumb/dumb/src/helpers/resamp2.inc | 17 - Frameworks/Dumb/dumb/src/helpers/resamp3.inc | 84 - Frameworks/Dumb/dumb/src/helpers/resample.c | 58 +- Frameworks/Dumb/dumb/src/helpers/resample.inc | 152 -- Frameworks/Dumb/dumb/src/helpers/resampler.c | 216 +- Frameworks/Dumb/dumb/src/it/itrender.c | 39 - Frameworks/Dumb/dumb/vc6/dumb/.gitignore | 3 - Frameworks/Dumb/dumb/vc6/dumb/dumb.vcproj | 2007 ----------------- Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj | 221 -- .../Dumb/dumb/vc6/dumb/dumb.vcxproj.filters | 341 --- Frameworks/modplay/modplay/resampler.c | 218 +- Frameworks/modplay/modplay/resampler.h | 9 +- Plugins/Dumb/DumbDecoder.m | 30 +- Plugins/MIDI/MIDI/MIDIDecoder.mm | 7 +- Plugins/modplay/modplay/modDecoder.m | 21 +- .../General/English.lproj/Preferences.xib | 67 +- .../General/General.xcodeproj/project.pbxproj | 6 + .../General/GeneralPreferencesPlugin.m | 2 +- Preferences/General/MIDIPane.m | 2 +- .../ResamplerBehaviorArrayController.h | 13 + .../ResamplerBehaviorArrayController.m | 42 + 27 files changed, 583 insertions(+), 3448 deletions(-) delete mode 100644 Frameworks/Dumb/dumb/include/internal/blip_buf.h delete mode 100644 Frameworks/Dumb/dumb/src/helpers/blip_buf.c delete mode 100644 Frameworks/Dumb/dumb/vc6/dumb/.gitignore delete mode 100644 Frameworks/Dumb/dumb/vc6/dumb/dumb.vcproj delete mode 100644 Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj delete mode 100644 Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj.filters create mode 100644 Preferences/General/ResamplerBehaviorArrayController.h create mode 100644 Preferences/General/ResamplerBehaviorArrayController.m diff --git a/Application/AppController.m b/Application/AppController.m index f4cee322a..6784a69d5 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -487,6 +487,8 @@ increase/decrease as long as the user holds the left/right, plus/minus button */ [userDefaultsValuesDict setObject:@"enqueue" forKey:@"openingFilesAlteredBehavior"]; [userDefaultsValuesDict setObject:@"albumGainWithPeak" forKey:@"volumeScaling"]; + + [userDefaultsValuesDict setObject:@"cubic" forKey:@"resampling"]; [userDefaultsValuesDict setObject:[NSNumber numberWithInteger:kCogStatusStopped] forKey:@"lastPlaybackStatus"]; [userDefaultsValuesDict setObject:[NSNumber numberWithInteger:-1] forKey:@"lastTrackPlaying"]; diff --git a/Frameworks/Dumb/Dumb.xcodeproj/project.pbxproj b/Frameworks/Dumb/Dumb.xcodeproj/project.pbxproj index 3b26ef20e..01a83a7e0 100644 --- a/Frameworks/Dumb/Dumb.xcodeproj/project.pbxproj +++ b/Frameworks/Dumb/Dumb.xcodeproj/project.pbxproj @@ -102,8 +102,6 @@ 8370B68A17F61038001A4D7A /* readstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 8370B66117F61038001A4D7A /* readstm.c */; }; 8370B68B17F61038001A4D7A /* readstm2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8370B66217F61038001A4D7A /* readstm2.c */; }; 8370B7EA17F62A40001A4D7A /* resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 8370B7E817F62A40001A4D7A /* resampler.h */; }; - 83C8DF1D18C6B31400750AF7 /* blip_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8DF1C18C6B31400750AF7 /* blip_buf.c */; }; - 83C8DF1F18C6B32100750AF7 /* blip_buf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8DF1E18C6B32100750AF7 /* blip_buf.h */; }; 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -211,8 +209,6 @@ 8370B66117F61038001A4D7A /* readstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = readstm.c; sourceTree = ""; }; 8370B66217F61038001A4D7A /* readstm2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = readstm2.c; sourceTree = ""; }; 8370B7E817F62A40001A4D7A /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = ""; }; - 83C8DF1C18C6B31400750AF7 /* blip_buf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blip_buf.c; sourceTree = ""; }; - 83C8DF1E18C6B32100750AF7 /* blip_buf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blip_buf.h; sourceTree = ""; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8DC2EF5B0486A6940098B216 /* Dumb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Dumb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; @@ -307,7 +303,6 @@ 17C8F60D0CBEE797008D969D /* internal */ = { isa = PBXGroup; children = ( - 83C8DF1E18C6B32100750AF7 /* blip_buf.h */, 8370B7E817F62A40001A4D7A /* resampler.h */, 8370B61E17F60FE2001A4D7A /* barray.h */, 8370B62017F60FE2001A4D7A /* dumbfile.h */, @@ -354,7 +349,6 @@ 17C8F61E0CBEE797008D969D /* helpers */ = { isa = PBXGroup; children = ( - 83C8DF1C18C6B31400750AF7 /* blip_buf.c */, 8370B62E17F61001001A4D7A /* barray.c */, 8370B63017F61001001A4D7A /* resampler.c */, 8370B63117F61001001A4D7A /* lpc.c */, @@ -450,7 +444,6 @@ buildActionMask = 2147483647; files = ( 8370B62D17F60FE2001A4D7A /* tarray.h in Headers */, - 83C8DF1F18C6B32100750AF7 /* blip_buf.h in Headers */, 8370B62617F60FE2001A4D7A /* barray.h in Headers */, 17C8F63E0CBEE797008D969D /* dumb.h in Headers */, 17C8F6400CBEE797008D969D /* it.h in Headers */, @@ -588,7 +581,6 @@ 17C8F6620CBEE797008D969D /* loadxm.c in Sources */, 17C8F6630CBEE797008D969D /* loadxm2.c in Sources */, 8370B67117F61038001A4D7A /* loadpsm.c in Sources */, - 83C8DF1D18C6B31400750AF7 /* blip_buf.c in Sources */, 8370B67617F61038001A4D7A /* loadriff2.c in Sources */, 8370B66C17F61038001A4D7A /* loadmtm2.c in Sources */, 8370B67A17F61038001A4D7A /* read669.c in Sources */, diff --git a/Frameworks/Dumb/dumb/include/dumb.h b/Frameworks/Dumb/dumb/include/dumb.h index f2b614235..7d987b0d8 100644 --- a/Frameworks/Dumb/dumb/include/dumb.h +++ b/Frameworks/Dumb/dumb/include/dumb.h @@ -377,8 +377,6 @@ int dumb_it_scan_for_playable_orders(DUMB_IT_SIGDATA *sigdata, dumb_scan_callbac DUH_SIGRENDERER *dumb_it_start_at_order(DUH *duh, int n_channels, int startorder); -void dumb_it_set_resampling_quality(DUMB_IT_SIGRENDERER * sigrenderer, int quality); - enum { DUMB_IT_RAMP_NONE = 0, @@ -674,11 +672,14 @@ void dumb_destroy_click_remover_array(int n, DUMB_CLICK_REMOVER **cr); /* Resampling Helpers */ #define DUMB_RQ_ALIASING 0 -#define DUMB_RQ_LINEAR 1 -#define DUMB_RQ_CUBIC 2 -#define DUMB_RQ_FIR 3 -#define DUMB_RQ_N_LEVELS 4 -extern int dumb_resampling_quality; +#define DUMB_RQ_BLEP 1 +#define DUMB_RQ_LINEAR 2 +#define DUMB_RQ_CUBIC 3 +#define DUMB_RQ_FIR 4 +#define DUMB_RQ_N_LEVELS 5 + +extern int dumb_resampling_quality; /* This specifies the default */ +void dumb_it_set_resampling_quality(DUMB_IT_SIGRENDERER * sigrenderer, int quality); /* This overrides it */ typedef struct DUMB_RESAMPLER DUMB_RESAMPLER; @@ -686,11 +687,6 @@ typedef struct DUMB_VOLUME_RAMP_INFO DUMB_VOLUME_RAMP_INFO; typedef void (*DUMB_RESAMPLE_PICKUP)(DUMB_RESAMPLER *resampler, void *data); -#ifndef BLIP_T_DEFINED -#define BLIP_T_DEFINED -typedef struct blip_t blip_t; -#endif - struct DUMB_RESAMPLER { void *src; @@ -708,9 +704,6 @@ struct DUMB_RESAMPLER signed char x8[3*2]; } x; int overshot; - int last_clock; - int last_amp[2]; - blip_t* blip_buffer[2]; double fir_resampler_ratio; void* fir_resampler[2]; }; diff --git a/Frameworks/Dumb/dumb/include/internal/blip_buf.h b/Frameworks/Dumb/dumb/include/internal/blip_buf.h deleted file mode 100644 index 6bf37836e..000000000 --- a/Frameworks/Dumb/dumb/include/internal/blip_buf.h +++ /dev/null @@ -1,80 +0,0 @@ -/** \file -Sample buffer that resamples from input clock rate to output sample rate */ - -/* blip_buf 1.1.0 */ -#ifndef BLIP_BUF_H -#define BLIP_BUF_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** First parameter of most functions is blip_t*, or const blip_t* if nothing -is changed. */ -#ifndef BLIP_T_DEFINED -#define BLIP_T_DEFINED -typedef struct blip_t blip_t; -#endif - -/** Creates new buffer that can hold at most sample_count samples. Sets rates -so that there are blip_max_ratio clocks per sample. Returns pointer to new -buffer, or NULL if insufficient memory. */ -blip_t* blip_new( int sample_count ); - -blip_t* blip_dup( blip_t* ); - -/** Sets approximate input clock rate and output sample rate. For every -clock_rate input clocks, approximately sample_rate samples are generated. */ -void blip_set_rates( blip_t*, double clock_rate, double sample_rate ); - -enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate, -clock_rate must not be greater than sample_rate*blip_max_ratio. */ -blip_max_ratio = 1 << 20 }; - -/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */ -void blip_clear( blip_t* ); - -/** Adds positive/negative delta into buffer at specified clock time. */ -void blip_add_delta( blip_t*, unsigned int clock_time, int delta ); - -/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */ -void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta ); - -/** Length of time frame, in clocks, needed to make sample_count additional -samples available. */ -int blip_clocks_needed( const blip_t*, int sample_count ); - -enum { /** Maximum number of samples that can be generated from one time frame. */ -blip_max_frame = 4000 }; - -/** Makes input clocks before clock_duration available for reading as output -samples. Also begins new time frame at clock_duration, so that clock time 0 in -the new time frame specifies the same clock as clock_duration in the old time -frame specified. Deltas can have been added slightly past clock_duration (up to -however many clocks there are in two output samples). */ -void blip_end_frame( blip_t*, unsigned int clock_duration ); - -/** Number of buffered samples available for reading. */ -int blip_samples_avail( const blip_t* ); - -/** Reads and removes at most 'count' samples and writes them to 'out'. If -'stereo' is true, writes output to every other element of 'out', allowing easy -interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed -samples. Returns number of samples actually read. */ -int blip_read_samples( blip_t*, int out [], int count ); - -/** Reads the current integrator and returns it */ -int blip_peek_sample( blip_t* ); - -/** Frees buffer. No effect if NULL is passed. */ -void blip_delete( blip_t* ); - - -/* Deprecated */ -typedef blip_t blip_buffer_t; - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/Frameworks/Dumb/dumb/include/internal/resampler.h b/Frameworks/Dumb/dumb/include/internal/resampler.h index f3e7bf874..4d409efef 100644 --- a/Frameworks/Dumb/dumb/include/internal/resampler.h +++ b/Frameworks/Dumb/dumb/include/internal/resampler.h @@ -32,10 +32,11 @@ enum { RESAMPLER_QUALITY_MIN = 0, RESAMPLER_QUALITY_ZOH = 0, - RESAMPLER_QUALITY_LINEAR = 1, - RESAMPLER_QUALITY_CUBIC = 2, - RESAMPLER_QUALITY_SINC = 3, - RESAMPLER_QUALITY_MAX = 3 + RESAMPLER_QUALITY_BLEP = 1, + RESAMPLER_QUALITY_LINEAR = 2, + RESAMPLER_QUALITY_CUBIC = 3, + RESAMPLER_QUALITY_SINC = 4, + RESAMPLER_QUALITY_MAX = 4 }; void resampler_set_quality(void *, int quality); diff --git a/Frameworks/Dumb/dumb/src/helpers/blip_buf.c b/Frameworks/Dumb/dumb/src/helpers/blip_buf.c deleted file mode 100644 index 9f26f71cb..000000000 --- a/Frameworks/Dumb/dumb/src/helpers/blip_buf.c +++ /dev/null @@ -1,354 +0,0 @@ -/* blip_buf 1.1.0. http://www.slack.net/~ant/ */ - -#include "internal/blip_buf.h" - -#include -#include -#include -#include - -/* Library Copyright (C) 2003-2009 Shay Green. This library 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 -library 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 */ - -#if defined (BLARGG_TEST) && BLARGG_TEST - #include "blargg_test.h" -#endif - -/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000. -Avoids constants that don't fit in 32 bits. */ -#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF - typedef unsigned long fixed_t; - enum { pre_shift = 32 }; - -#elif defined(ULLONG_MAX) - typedef unsigned long long fixed_t; - enum { pre_shift = 32 }; - -#else - typedef unsigned fixed_t; - enum { pre_shift = 0 }; - -#endif - -enum { time_bits = pre_shift + 20 }; - -static fixed_t const time_unit = (fixed_t) 1 << time_bits; - -enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */ -enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */ - -enum { half_width = 8 }; -enum { buf_extra = half_width*2 + end_frame_extra }; -enum { phase_bits = 5 }; -enum { phase_count = 1 << phase_bits }; -enum { delta_bits = 15 }; -enum { delta_unit = 1 << delta_bits }; -enum { frac_bits = time_bits - pre_shift }; - -/* We could eliminate avail and encode whole samples in offset, but that would -limit the total buffered samples to blip_max_frame. That could only be -increased by decreasing time_bits, which would reduce resample ratio accuracy. -*/ - -/** Sample buffer that resamples to output rate and accumulates samples -until they're read out */ -struct blip_t -{ - fixed_t factor; - fixed_t offset; - int avail; - int size; - int integrator; -}; - -typedef int buf_t; - -/* probably not totally portable */ -#define SAMPLES( buf ) ((buf_t*) ((buf) + 1)) - -/* Arithmetic (sign-preserving) right shift */ -#define ARITH_SHIFT( n, shift ) \ - ((n) >> (shift)) - -enum { max_sample = +32767 }; -enum { min_sample = -32768 }; - -#define CLAMP( n ) \ - {\ - if ( (short) n != n )\ - n = ARITH_SHIFT( n, 16 ) ^ max_sample;\ - } - -static void check_assumptions( void ) -{ - int n; - - #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF - #error "int must be at least 32 bits" - #endif - - assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */ - - n = max_sample * 2; - CLAMP( n ); - assert( n == max_sample ); - - n = min_sample * 2; - CLAMP( n ); - assert( n == min_sample ); - - assert( blip_max_ratio <= time_unit ); - assert( blip_max_frame <= (fixed_t) -1 >> time_bits ); -} - -blip_t* blip_new( int size ) -{ - blip_t* m; - assert( size >= 0 ); - - m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) ); - if ( m ) - { - m->factor = time_unit / blip_max_ratio; - m->size = size; - blip_clear( m ); - check_assumptions(); - } - return m; -} - -blip_t* blip_dup( blip_t* m ) -{ - size_t size = sizeof *m + (m->size + buf_extra) * sizeof(buf_t); - blip_t* r = (blip_t*) malloc( size ); - if ( r ) memcpy( r, m, size ); - return r; -} - -void blip_delete( blip_t* m ) -{ - if ( m != NULL ) - { - /* Clear fields in case user tries to use after freeing */ - memset( m, 0, sizeof *m ); - free( m ); - } -} - -void blip_set_rates( blip_t* m, double clock_rate, double sample_rate ) -{ - double factor = time_unit * sample_rate / clock_rate; - m->factor = (fixed_t) factor; - - /* Fails if clock_rate exceeds maximum, relative to sample_rate */ - assert( 0 <= factor - m->factor && factor - m->factor < 1 ); - - /* Avoid requiring math.h. Equivalent to - m->factor = (int) ceil( factor ) */ - if ( m->factor < factor ) - m->factor++; - - /* At this point, factor is most likely rounded up, but could still - have been rounded down in the floating-point calculation. */ -} - -void blip_clear( blip_t* m ) -{ - /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if - factor is rounded up. factor-1 is suitable if factor is rounded down. - Since we don't know rounding direction, factor/2 accommodates either, - with the slight loss of showing an error in half the time. Since for - a 64-bit factor this is years, the halving isn't a problem. */ - - m->offset = m->factor / 2; - m->avail = 0; - m->integrator = 0; - memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) ); -} - -int blip_clocks_needed( const blip_t* m, int samples ) -{ - fixed_t needed; - - /* Fails if buffer can't hold that many more samples */ - assert( samples >= 0 && m->avail + samples <= m->size ); - - needed = (fixed_t) samples * time_unit; - if ( needed < m->offset ) - return 0; - - return (needed - m->offset + m->factor - 1) / m->factor; -} - -void blip_end_frame( blip_t* m, unsigned t ) -{ - fixed_t off = t * m->factor + m->offset; - m->avail += off >> time_bits; - m->offset = off & (time_unit - 1); - - /* Fails if buffer size was exceeded */ - assert( m->avail <= m->size ); -} - -int blip_samples_avail( const blip_t* m ) -{ - return m->avail; -} - -static void remove_samples( blip_t* m, int count ) -{ - buf_t* buf = SAMPLES( m ); - int remain = m->avail + buf_extra - count; - m->avail -= count; - - memmove( &buf [0], &buf [count], remain * sizeof buf [0] ); - memset( &buf [remain], 0, count * sizeof buf [0] ); -} - -int blip_read_samples( blip_t* m, int out [], int count ) -{ - assert( count >= 0 ); - - if ( count > m->avail ) - count = m->avail; - - if ( count ) - { - buf_t const* in = SAMPLES( m ); - buf_t const* end = in + count; - int sum = m->integrator; - do - { - /* Eliminate fraction */ - int s = ARITH_SHIFT( sum, delta_bits - 8 ); - - sum += *in++; - - *out = s; - out++; - - /* High-pass filter */ - sum -= s >> (8 - (delta_bits - bass_shift)); //<< (delta_bits - bass_shift - 8); - } - while ( in != end ); - m->integrator = sum; - - remove_samples( m, count ); - } - - return count; -} - -int blip_peek_sample( blip_t* m ) -{ - return ARITH_SHIFT( m->integrator, delta_bits - 8 ); -} - -/* Things that didn't help performance on x86: - __attribute__((aligned(128))) - #define short int - restrict -*/ - -/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ -static short const bl_step [phase_count + 1] [half_width] = -{ -{ 43, -115, 350, -488, 1136, -914, 5861,21022}, -{ 44, -118, 348, -473, 1076, -799, 5274,21001}, -{ 45, -121, 344, -454, 1011, -677, 4706,20936}, -{ 46, -122, 336, -431, 942, -549, 4156,20829}, -{ 47, -123, 327, -404, 868, -418, 3629,20679}, -{ 47, -122, 316, -375, 792, -285, 3124,20488}, -{ 47, -120, 303, -344, 714, -151, 2644,20256}, -{ 46, -117, 289, -310, 634, -17, 2188,19985}, -{ 46, -114, 273, -275, 553, 117, 1758,19675}, -{ 44, -108, 255, -237, 471, 247, 1356,19327}, -{ 43, -103, 237, -199, 390, 373, 981,18944}, -{ 42, -98, 218, -160, 310, 495, 633,18527}, -{ 40, -91, 198, -121, 231, 611, 314,18078}, -{ 38, -84, 178, -81, 153, 722, 22,17599}, -{ 36, -76, 157, -43, 80, 824, -241,17092}, -{ 34, -68, 135, -3, 8, 919, -476,16558}, -{ 32, -61, 115, 34, -60, 1006, -683,16001}, -{ 29, -52, 94, 70, -123, 1083, -862,15422}, -{ 27, -44, 73, 106, -184, 1152,-1015,14824}, -{ 25, -36, 53, 139, -239, 1211,-1142,14210}, -{ 22, -27, 34, 170, -290, 1261,-1244,13582}, -{ 20, -20, 16, 199, -335, 1301,-1322,12942}, -{ 18, -12, -3, 226, -375, 1331,-1376,12293}, -{ 15, -4, -19, 250, -410, 1351,-1408,11638}, -{ 13, 3, -35, 272, -439, 1361,-1419,10979}, -{ 11, 9, -49, 292, -464, 1362,-1410,10319}, -{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, -{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, -{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, -{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, -{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, -{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, -{ 0, 43, -115, 350, -488, 1136, -914, 5861} -}; - -/* Shifting by pre_shift allows calculation using unsigned int rather than -possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient. -And by having pre_shift 32, a 32-bit platform can easily do the shift by -simply ignoring the low half. */ - -void blip_add_delta( blip_t* m, unsigned time, int delta ) -{ - unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); - buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); - - int const phase_shift = frac_bits - phase_bits; - int phase = fixed >> phase_shift & (phase_count - 1); - short const* in = bl_step [phase]; - short const* rev = bl_step [phase_count - phase]; - - int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); - int delta2 = (delta * interp) >> delta_bits; - delta -= delta2; - - /* Fails if buffer size was exceeded */ - assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); - - out [0] += in[0]*delta + in[half_width+0]*delta2; - out [1] += in[1]*delta + in[half_width+1]*delta2; - out [2] += in[2]*delta + in[half_width+2]*delta2; - out [3] += in[3]*delta + in[half_width+3]*delta2; - out [4] += in[4]*delta + in[half_width+4]*delta2; - out [5] += in[5]*delta + in[half_width+5]*delta2; - out [6] += in[6]*delta + in[half_width+6]*delta2; - out [7] += in[7]*delta + in[half_width+7]*delta2; - - in = rev; - out [ 8] += in[7]*delta + in[7-half_width]*delta2; - out [ 9] += in[6]*delta + in[6-half_width]*delta2; - out [10] += in[5]*delta + in[5-half_width]*delta2; - out [11] += in[4]*delta + in[4-half_width]*delta2; - out [12] += in[3]*delta + in[3-half_width]*delta2; - out [13] += in[2]*delta + in[2-half_width]*delta2; - out [14] += in[1]*delta + in[1-half_width]*delta2; - out [15] += in[0]*delta + in[0-half_width]*delta2; -} - -void blip_add_delta_fast( blip_t* m, unsigned time, int delta ) -{ - unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); - buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); - - int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1); - int delta2 = delta * interp; - - /* Fails if buffer size was exceeded */ - assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); - - out [7] += delta * delta_unit - delta2; - out [8] += delta2; -} diff --git a/Frameworks/Dumb/dumb/src/helpers/resamp2.inc b/Frameworks/Dumb/dumb/src/helpers/resamp2.inc index b343d23b2..50c79b806 100644 --- a/Frameworks/Dumb/dumb/src/helpers/resamp2.inc +++ b/Frameworks/Dumb/dumb/src/helpers/resamp2.inc @@ -94,12 +94,8 @@ static int process_pickup(DUMB_RESAMPLER *resampler) #define SET_VOLUME_VARIABLES SET_MONO_DEST_VOLUME_VARIABLES #define RETURN_VOLUME_VARIABLES RETURN_MONO_DEST_VOLUME_VARIABLES #define VOLUMES_ARE_ZERO MONO_DEST_VOLUMES_ARE_ZERO -#define MIX_ALIAS(count) MONO_DEST_MIX_ALIAS(count) -#define PEEK_ALIAS MONO_DEST_PEEK_ALIAS #define PEEK_FIR MONO_DEST_PEEK_FIR #define MIX_FIR MONO_DEST_MIX_FIR -#define MIX_LINEAR(op, upd, o0, o1) MONO_DEST_MIX_LINEAR(op, upd, o0, o1) -#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) #define MIX_ZEROS(op) *dst++ op 0 #include "resamp3.inc" @@ -140,32 +136,19 @@ static int process_pickup(DUMB_RESAMPLER *resampler) if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \ } #define VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0) -#define MIX_ALIAS(count) STEREO_DEST_MIX_ALIAS(count) -#define PEEK_ALIAS STEREO_DEST_PEEK_ALIAS #define PEEK_FIR STEREO_DEST_PEEK_FIR #define MIX_FIR STEREO_DEST_MIX_FIR -#define MIX_LINEAR(op, upd, o0, o1) STEREO_DEST_MIX_LINEAR(op, upd, o0, o1) -#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) #define MIX_ZEROS(op) { *dst++ op 0; *dst++ op 0; } #include "resamp3.inc" -#undef STEREO_DEST_MIX_CUBIC -#undef MONO_DEST_MIX_CUBIC -#undef STEREO_DEST_MIX_LINEAR -#undef MONO_DEST_MIX_LINEAR -#undef STEREO_DEST_MIX_ALIAS -#undef MONO_DEST_MIX_ALIAS #undef MONO_DEST_VOLUMES_ARE_ZERO #undef SET_MONO_DEST_VOLUME_VARIABLES #undef RETURN_MONO_DEST_VOLUME_VARIABLES #undef MONO_DEST_VOLUME_ZEROS #undef MONO_DEST_VOLUME_VARIABLES #undef MONO_DEST_VOLUME_PARAMETERS -#undef STEREO_DEST_PEEK_ALIAS -#undef MONO_DEST_PEEK_ALIAS -#undef POKE_ALIAS #undef MONO_DEST_PEEK_FIR #undef STEREO_DEST_PEEK_FIR #undef MONO_DEST_MIX_FIR diff --git a/Frameworks/Dumb/dumb/src/helpers/resamp3.inc b/Frameworks/Dumb/dumb/src/helpers/resamp3.inc index 8da8410f5..12820f268 100644 --- a/Frameworks/Dumb/dumb/src/helpers/resamp3.inc +++ b/Frameworks/Dumb/dumb/src/helpers/resamp3.inc @@ -52,7 +52,6 @@ long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, VOLU long todo; LONG_LONG todo64; int quality; - int blip_samples[256*SRC_CHANNELS]; int check; if (!resampler || resampler->dir == 0) return 0; @@ -105,41 +104,6 @@ long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, VOLU LONG_LONG new_subpos = subpos + (LONG_LONG)dt * todo; pos += (long)(new_subpos >> 16); subpos = (long)new_subpos & 65535; - } else if (quality <= DUMB_RQ_ALIASING) { - /* Aliasing, backwards */ - int todo_clocks = todo << 16, todo_clocks_set = todo_clocks; - SRCTYPE xbuf[2*SRC_CHANNELS]; - SRCTYPE *x = &xbuf[0]; - check = resampler->start; - COPYSRC(xbuf, 0, resampler->X, 1); - COPYSRC(xbuf, 1, resampler->X, 2); - if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536; - while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) { - // TODO: check what happens when multiple tempo slides occur per row - HEAVYASSERT(pos >= resampler->start); - POKE_ALIAS(0); - pos--; - x += SRC_CHANNELS; - } - x = &src[pos*SRC_CHANNELS]; - while ( todo_clocks ) { - todo_clocks_set = todo_clocks; - if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536; - todo_clocks -= todo_clocks_set; - while ( resampler->last_clock < todo_clocks_set && pos >= check ) { - POKE_ALIAS(2); - pos--; - x -= SRC_CHANNELS; - } - todo = todo_clocks_set >> 16; - check = 0; - if ( resampler->last_clock < todo_clocks_set ) { - check = ( todo_clocks_set - resampler->last_clock + 65535 ) >> 16; - } - todo -= check; - MIX_ALIAS( todo ); - done -= check; - } } else { /* FIR resampling, backwards */ SRCTYPE *x; @@ -185,40 +149,6 @@ long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, VOLU LONG_LONG new_subpos = subpos + (LONG_LONG)dt * todo; pos += (long)(new_subpos >> 16); subpos = (long)new_subpos & 65535; - } else if (quality <= DUMB_RQ_ALIASING) { - /* Aliasing, forwards */ - int todo_clocks = todo << 16, todo_clocks_set = todo_clocks; - SRCTYPE xbuf[2*SRC_CHANNELS]; - SRCTYPE *x = &xbuf[0]; - check = resampler->end; - COPYSRC(xbuf, 0, resampler->X, 1); - COPYSRC(xbuf, 1, resampler->X, 2); - if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536; - while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) { - HEAVYASSERT(pos < resampler->end); - POKE_ALIAS(0); - pos++; - x += SRC_CHANNELS; - } - x = &src[pos*SRC_CHANNELS]; - while ( todo_clocks ) { - todo_clocks_set = todo_clocks; - if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536; - todo_clocks -= todo_clocks_set; - while ( resampler->last_clock < todo_clocks_set && pos < check ) { - POKE_ALIAS(-2); - pos++; - x += SRC_CHANNELS; - } - todo = todo_clocks_set >> 16; - check = 0; - if ( resampler->last_clock < todo_clocks_set ) { - check = ( todo_clocks_set - resampler->last_clock + 65535 ) >> 16; - } - todo -= check; - MIX_ALIAS( todo ); - done -= check; - } } else { /* FIR resampling, forwards */ SRCTYPE *x; @@ -299,33 +229,19 @@ void dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, VOLUME_PARAMETE if (resampler->dir < 0) { HEAVYASSERT(pos >= resampler->start); - if (quality <= DUMB_RQ_ALIASING) { - /* Aliasing, backwards */ - PEEK_ALIAS; - } else { /* FIR resampling, backwards */ PEEK_FIR; - } } else { HEAVYASSERT(pos < resampler->end); - if (quality <= DUMB_RQ_ALIASING) { - /* Aliasing */ - PEEK_ALIAS; - } else { /* FIR resampling, forwards */ PEEK_FIR; - } } } #undef MIX_ZEROS -#undef MIX_CUBIC -#undef MIX_LINEAR -#undef MIX_ALIAS #undef MIX_FIR -#undef PEEK_ALIAS #undef PEEK_FIR #undef VOLUMES_ARE_ZERO #undef SET_VOLUME_VARIABLES diff --git a/Frameworks/Dumb/dumb/src/helpers/resample.c b/Frameworks/Dumb/dumb/src/helpers/resample.c index 4a3a08b7a..987746ee3 100644 --- a/Frameworks/Dumb/dumb/src/helpers/resample.c +++ b/Frameworks/Dumb/dumb/src/helpers/resample.c @@ -45,7 +45,6 @@ #include #include "dumb.h" -#include "internal/blip_buf.h" #include "internal/resampler.h" @@ -73,11 +72,12 @@ * specification doesn't override it. The following values are valid: * * 0 - DUMB_RQ_ALIASING - fastest - * 1 - DUMB_RQ_LINEAR - * 2 - DUMB_RQ_CUBIC - * 3 - DUMB_RQ_FIR - nicest + * 1 - DUMB_RQ_BLEP - nicer than aliasing, but slower + * 2 - DUMB_RQ_LINEAR + * 3 - DUMB_RQ_CUBIC + * 4 - DUMB_RQ_FIR - nicest * - * Values outside the range 0-3 will behave the same as the nearest + * Values outside the range 0-4 will behave the same as the nearest * value within the range. */ int dumb_resampling_quality = DUMB_RQ_CUBIC; @@ -157,23 +157,7 @@ void _dumb_init_cubic(void) #define SRCTYPE sample_t #define SRCBITS 24 -#define ALIAS(x) (x >> 8) #define FIR(x) (x >> 8) -#define LINEAR(x0, x1) (x0 + MULSC(x1 - x0, subpos)) -/* -#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \ - a = (3 * (x1 - x2) + (x3 - x0)) >> 1; \ - b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) >> 1; \ - c = (x2 - x0) >> 1; \ -} -#define CUBIC(d) MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + d, vol) -*/ -#define CUBIC(x0, x1, x2, x3) ( \ - MULSC(x0, cubicA0[subpos >> 6] << 2) + \ - MULSC(x1, cubicA1[subpos >> 6] << 2) + \ - MULSC(x2, cubicA1[1 + (subpos >> 6 ^ 1023)] << 2) + \ - MULSC(x3, cubicA0[1 + (subpos >> 6 ^ 1023)] << 2)) -#define CUBICVOL(x, vol) MULSC(x, vol) #include "resample.inc" /* Undefine the simplified macros. */ @@ -194,46 +178,14 @@ void _dumb_init_cubic(void) #define SUFFIX _16 #define SRCTYPE short #define SRCBITS 16 -#define ALIAS(x) (x) #define FIR(x) (x) -#define LINEAR(x0, x1) ((x0 << 8) + MULSC16(x1 - x0, subpos)) -/* -#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \ - a = (3 * (x1 - x2) + (x3 - x0)) << 7; \ - b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) << 7; \ - c = (x2 - x0) << 7; \ -} -#define CUBIC(d) MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + (d << 8), vol) -*/ -#define CUBIC(x0, x1, x2, x3) ( \ - x0 * cubicA0[subpos >> 6] + \ - x1 * cubicA1[subpos >> 6] + \ - x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \ - x3 * cubicA0[1 + (subpos >> 6 ^ 1023)]) -#define CUBICVOL(x, vol) (int)((LONG_LONG)(x) * (vol << 10) >> 32) #include "resample.inc" /* Create resamplers for 8-bit source samples. */ #define SUFFIX _8 #define SRCTYPE signed char #define SRCBITS 8 -#define ALIAS(x) (x << 8) #define FIR(x) (x << 8) -#define LINEAR(x0, x1) ((x0 << 16) + (x1 - x0) * subpos) -/* -#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \ - a = 3 * (x1 - x2) + (x3 - x0); \ - b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) << 15; \ - c = (x2 - x0) << 15; \ -} -#define CUBIC(d) MULSC(MULSC(MULSC((a * subpos >> 1) + b, subpos) + c, subpos) + (d << 16), vol) -*/ -#define CUBIC(x0, x1, x2, x3) (( \ - x0 * cubicA0[subpos >> 6] + \ - x1 * cubicA1[subpos >> 6] + \ - x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \ - x3 * cubicA0[1 + (subpos >> 6 ^ 1023)]) << 6) -#define CUBICVOL(x, vol) (int)((LONG_LONG)(x) * (vol << 12) >> 32) #include "resample.inc" diff --git a/Frameworks/Dumb/dumb/src/helpers/resample.inc b/Frameworks/Dumb/dumb/src/helpers/resample.inc index 84eead97f..7e1e3e2cf 100644 --- a/Frameworks/Dumb/dumb/src/helpers/resample.inc +++ b/Frameworks/Dumb/dumb/src/helpers/resample.inc @@ -69,11 +69,6 @@ void dumb_reset_resampler(DUMB_RESAMPLER *resampler, SRCTYPE *src, int src_chann } for (i = 0; i < src_channels*3; i++) resampler->X[i] = 0; resampler->overshot = -1; - resampler->last_clock = 0; - resampler->last_amp[0] = 0; - resampler->last_amp[1] = 0; - blip_clear(resampler->blip_buffer[0]); - blip_clear(resampler->blip_buffer[1]); resampler->fir_resampler_ratio = 0; resampler_clear(resampler->fir_resampler[0]); resampler_clear(resampler->fir_resampler[1]); @@ -87,21 +82,6 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, l { DUMB_RESAMPLER *resampler = malloc(sizeof(*resampler)); if (!resampler) return NULL; - resampler->blip_buffer[0] = blip_new( 256 ); - if (!resampler->blip_buffer[0]) - { - free(resampler); - return NULL; - } - resampler->blip_buffer[1] = blip_new( 256 ); - if (!resampler->blip_buffer[1]) - { - free(resampler->blip_buffer[0]); - free(resampler); - return NULL; - } - blip_set_rates(resampler->blip_buffer[0], 65536, 1); - blip_set_rates(resampler->blip_buffer[1], 65536, 1); dumb_reset_resampler(resampler, src, src_channels, pos, start, end, quality); return resampler; } @@ -153,38 +133,15 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, l } #define RETURN_MONO_DEST_VOLUME_VARIABLES if ( volume ) volume->volume = (float)volr / 16777216.0f #define MONO_DEST_VOLUMES_ARE_ZERO (vol == 0 && volt == 0) -#define POKE_ALIAS(offset) { \ - int delta = ALIAS(x[offset]) - resampler->last_amp[0]; \ - resampler->last_amp[0] += delta; \ - if ( delta ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, delta ); \ - resampler->last_clock += inv_dt; \ -} #define POKE_FIR(offset) { \ resampler_write_sample( resampler->fir_resampler[0], FIR(x[offset]) ); \ } -#define MONO_DEST_PEEK_ALIAS *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), vol ) #define MONO_DEST_PEEK_FIR *dst = MULSC( resampler_get_sample( resampler->fir_resampler[0] ), vol ) #define MONO_DEST_MIX_FIR { \ *dst++ += MULSC( resampler_get_sample( resampler->fir_resampler[0] ), vol ); \ UPDATE_VOLUME( volume, vol ); \ } #define ADVANCE_FIR resampler_remove_sample( resampler->fir_resampler[0] ) -#define MONO_DEST_MIX_ALIAS(count) { \ - int n = 0; \ - resampler->last_clock -= count * 65536; \ - blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \ - blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \ - LOOP4( count, \ - *dst++ += MULSC( blip_samples[n], vol ); \ - n++; \ - UPDATE_VOLUME( volume, vol ); \ - ); \ -} -#define STEREO_DEST_PEEK_ALIAS { \ - int sample = blip_peek_sample( resampler->blip_buffer[0] ); \ - *dst++ = MULSC( sample, lvol ); \ - *dst++ = MULSC( sample, rvol ); \ -} #define STEREO_DEST_PEEK_FIR { \ int sample = resampler_get_sample( resampler->fir_resampler[0] ); \ *dst++ = MULSC( sample, lvol ); \ @@ -197,41 +154,6 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, l UPDATE_VOLUME( volume_left, lvol ); \ UPDATE_VOLUME( volume_right, rvol ); \ } -#define STEREO_DEST_MIX_ALIAS(count) { \ - int sample, n = 0; \ - resampler->last_clock -= count * 65536; \ - blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \ - blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \ - LOOP4( count, \ - sample = blip_samples[n++]; \ - *dst++ += MULSC( sample, lvol ); \ - *dst++ += MULSC( sample, rvol ); \ - UPDATE_VOLUME( volume_left, lvol ); \ - UPDATE_VOLUME( volume_right, rvol ); \ - ); \ -} -#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \ - *dst++ op MULSC(LINEAR(x[o0], x[o1]), vol); \ - if ( upd ) UPDATE_VOLUME( volume, vol ); \ -} -#define STEREO_DEST_MIX_LINEAR(op, upd, o0, o1) { \ - int xm = LINEAR(x[o0], x[o1]); \ - *dst++ op MULSC(xm, lvol); \ - *dst++ op MULSC(xm, rvol); \ - if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \ - if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \ -} -#define MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \ - *dst++ op CUBICVOL(CUBIC(x0[o0], x[o1], x[o2], x3[o3]), vol); \ - if ( upd ) UPDATE_VOLUME( volume, vol ); \ -} -#define STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \ - int xm = CUBIC(x0[o0], x[o1], x[o2], x3[o3]); \ - *dst++ op CUBICVOL(xm, lvol); \ - *dst++ op CUBICVOL(xm, rvol); \ - if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \ - if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \ -} #include "resamp2.inc" /* Create stereo source resampler. */ @@ -288,23 +210,10 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, l if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \ } #define MONO_DEST_VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0) -#define POKE_ALIAS(offset) { \ - int deltal = ALIAS(x[(offset)*2+0]) - resampler->last_amp[0]; \ - int deltar = ALIAS(x[(offset)*2+1]) - resampler->last_amp[1]; \ - resampler->last_amp[0] += deltal; \ - resampler->last_amp[1] += deltar; \ - if ( deltal ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, deltal ); \ - if ( deltar ) blip_add_delta( resampler->blip_buffer[1], resampler->last_clock, deltar ); \ - resampler->last_clock += inv_dt; \ -} #define POKE_FIR(offset) { \ resampler_write_sample( resampler->fir_resampler[0], FIR(x[(offset)*2+0]) ); \ resampler_write_sample( resampler->fir_resampler[1], FIR(x[(offset)*2+1]) ); \ } -#define MONO_DEST_PEEK_ALIAS { \ - *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ) + \ - MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \ -} #define MONO_DEST_PEEK_FIR { \ *dst = MULSC( resampler_get_sample( resampler->fir_resampler[0] ), lvol ) + \ MULSC( resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \ @@ -319,24 +228,6 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, l resampler_remove_sample( resampler->fir_resampler[0] ); \ resampler_remove_sample( resampler->fir_resampler[1] ); \ } -#define MONO_DEST_MIX_ALIAS(count) { \ - int n = 0; \ - resampler->last_clock -= count * 65536; \ - blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \ - blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \ - blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \ - blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \ - LOOP4( count, \ - *dst++ += MULSC( blip_samples[n], lvol ) + MULSC( blip_samples[256+n], rvol ); \ - n++; \ - UPDATE_VOLUME( volume_left, lvol ); \ - UPDATE_VOLUME( volume_right, rvol ); \ - ); \ -} -#define STEREO_DEST_PEEK_ALIAS { \ - *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ); \ - *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \ -} #define STEREO_DEST_PEEK_FIR { \ *dst++ = MULSC( resampler_get_sample( resampler->fir_resampler[0] ), lvol ); \ *dst++ = MULSC( resampler_get_sample( resampler->fir_resampler[1] ), rvol ); \ @@ -347,45 +238,6 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, l UPDATE_VOLUME( volume_left, lvol ); \ UPDATE_VOLUME( volume_right, rvol ); \ } -#define STEREO_DEST_MIX_ALIAS(count) { \ - int n = 0; \ - resampler->last_clock -= count * 65536; \ - blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \ - blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \ - blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \ - blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \ - LOOP4( count, \ - *dst++ += MULSC( blip_samples[n], lvol); \ - *dst++ += MULSC( blip_samples[256+n], rvol); \ - n++; \ - UPDATE_VOLUME( volume_left, lvol ); \ - UPDATE_VOLUME( volume_right, rvol ); \ - ); \ -} -#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \ - *dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol) + MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \ - if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \ - if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \ -} -#define STEREO_DEST_MIX_LINEAR(op, upd, o0, o1) { \ - *dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol); \ - *dst++ op MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \ - if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \ - if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \ -} -#define MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \ - *dst++ op \ - CUBICVOL(CUBIC(x0[(o0)*2], x[(o1)*2], x[(o2)*2], x3[(o3)*2]), lvol) + \ - CUBICVOL(CUBIC(x0[(o0)*2+1], x[(o1)*2+1], x[(o2)*2+1], x3[(o3)*2+1]), rvol); \ - if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \ - if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \ -} -#define STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) { \ - *dst++ op CUBICVOL(CUBIC(x0[(o0)*2], x[(o1)*2], x[(o2)*2], x3[(o3)*2]), lvol); \ - *dst++ op CUBICVOL(CUBIC(x0[(o0)*2+1], x[(o1)*2+1], x[(o2)*2+1], x3[(o3)*2+1]), rvol); \ - if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \ - if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \ -} #include "resamp2.inc" @@ -398,10 +250,6 @@ void dumb_end_resampler(DUMB_RESAMPLER *resampler) -#undef CUBICVOL -#undef CUBIC -#undef LINEAR -#undef ALIAS #undef FIR #undef SRCBITS #undef SRCTYPE diff --git a/Frameworks/Dumb/dumb/src/helpers/resampler.c b/Frameworks/Dumb/dumb/src/helpers/resampler.c index 6cec3d05e..ade585b89 100644 --- a/Frameworks/Dumb/dumb/src/helpers/resampler.c +++ b/Frameworks/Dumb/dumb/src/helpers/resampler.c @@ -60,10 +60,10 @@ __cpuid(int *data, int selector) #endif static int query_cpu_feature_sse() { - int buffer[4]; - __cpuid(buffer,1); - if ((buffer[3]&(1<<25)) == 0) return 0; - return 1; + int buffer[4]; + __cpuid(buffer,1); + if ((buffer[3]&(1<<25)) == 0) return 0; + return 1; } static int resampler_has_sse = 0; @@ -109,9 +109,13 @@ typedef struct resampler { int write_pos, write_filled; int read_pos, read_filled; - unsigned short phase; + unsigned int phase; unsigned int phase_inc; + unsigned int inv_phase; + unsigned int inv_phase_inc; unsigned char quality; + float last_amp; + float accumulator; float buffer_in[resampler_buffer_size * 2]; float buffer_out[resampler_buffer_size + SINC_WIDTH * 2 - 1]; } resampler; @@ -127,7 +131,11 @@ void * resampler_create(void) r->read_filled = 0; r->phase = 0; r->phase_inc = 0; + r->inv_phase = 0; + r->inv_phase_inc = 0; r->quality = RESAMPLER_QUALITY_MAX; + r->last_amp = 0; + r->accumulator = 0; memset( r->buffer_in, 0, sizeof(r->buffer_in) ); memset( r->buffer_out, 0, sizeof(r->buffer_out) ); @@ -151,7 +159,11 @@ void * resampler_dup(const void * _r) r_out->read_filled = r_in->read_filled; r_out->phase = r_in->phase; r_out->phase_inc = r_in->phase_inc; + r_out->inv_phase = r_in->inv_phase; + r_out->inv_phase_inc = r_in->inv_phase_inc; r_out->quality = r_in->quality; + r_out->last_amp = r_in->last_amp; + r_out->accumulator = r_in->accumulator; memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) ); memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) ); @@ -169,7 +181,11 @@ void resampler_dup_inplace(void *_d, const void *_s) r_out->read_filled = r_in->read_filled; r_out->phase = r_in->phase; r_out->phase_inc = r_in->phase_inc; + r_out->inv_phase = r_in->inv_phase; + r_out->inv_phase_inc = r_in->inv_phase_inc; r_out->quality = r_in->quality; + r_out->last_amp = r_in->last_amp; + r_out->accumulator = r_in->accumulator; memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) ); memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) ); } @@ -181,6 +197,17 @@ void resampler_set_quality(void *_r, int quality) quality = RESAMPLER_QUALITY_MIN; else if (quality > RESAMPLER_QUALITY_MAX) quality = RESAMPLER_QUALITY_MAX; + if ( r->quality != quality ) + { + if ( quality == RESAMPLER_QUALITY_BLEP || r->quality == RESAMPLER_QUALITY_BLEP ) + { + r->read_pos = 0; + r->read_filled = 0; + r->last_amp = 0; + r->accumulator = 0; + memset( r->buffer_out, 0, sizeof(r->buffer_out) ); + } + } r->quality = (unsigned char)quality; } @@ -196,6 +223,7 @@ static int resampler_min_filled(resampler *r) { default: case RESAMPLER_QUALITY_ZOH: + case RESAMPLER_QUALITY_BLEP: return 1; case RESAMPLER_QUALITY_LINEAR: @@ -223,14 +251,18 @@ void resampler_clear(void *_r) r->read_pos = 0; r->read_filled = 0; r->phase = 0; - memset(r->buffer_in, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); - memset(r->buffer_in + resampler_buffer_size, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); + memset(r->buffer_in, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); + memset(r->buffer_in + resampler_buffer_size, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); + if (r->quality == RESAMPLER_QUALITY_BLEP) + memset(r->buffer_out, 0, sizeof(r->buffer_out)); } void resampler_set_rate(void *_r, double new_factor) { resampler * r = ( resampler * ) _r; r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION ); + new_factor = 1.0 / new_factor; + r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION ); } void resampler_write_sample(void *_r, short s) @@ -294,6 +326,134 @@ static int resampler_run_zoh(resampler * r, float ** out_, float * out_end) return used; } +static int resampler_run_blep(resampler * r, float ** out_, float * out_end) +{ + int in_size = r->write_filled; + float const* in_ = r->buffer_in + resampler_buffer_size + r->write_pos - r->write_filled; + int used = 0; + in_size -= 1; + if ( in_size > 0 ) + { + float* out = *out_; + float const* in = in_; + float const* const in_end = in + in_size; + float last_amp = r->last_amp; + int inv_phase = r->inv_phase; + int inv_phase_inc = r->inv_phase_inc; + + const int step = RESAMPLER_RESOLUTION; + + do + { + float kernel[SINC_WIDTH * 2], kernel_sum = 0.0; + int i = SINC_WIDTH; + float sample; + + if ( out + SINC_WIDTH * 2 > out_end ) + break; + + for (; i >= -SINC_WIDTH + 1; --i) + { + int pos = i * step; + kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(inv_phase - pos)]; + } + sample = *in++ - last_amp; + last_amp += sample; + sample /= kernel_sum; + for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i) + out[i] += sample * kernel[i]; + + inv_phase += inv_phase_inc; + + out += inv_phase >> RESAMPLER_SHIFT; + + inv_phase &= RESAMPLER_RESOLUTION-1; + } + while ( in < in_end ); + + r->inv_phase = inv_phase; + r->last_amp = last_amp; + *out_ = out; + + used = (int)(in - in_); + + r->write_filled -= used; + } + + return used; +} + +#ifdef RESAMPLER_SSE +static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end) +{ + int in_size = r->write_filled; + float const* in_ = r->buffer_in + resampler_buffer_size + r->write_pos - r->write_filled; + int used = 0; + in_size -= 1; + if ( in_size > 0 ) + { + float* out = *out_; + float const* in = in_; + float const* const in_end = in + in_size; + float last_amp = r->last_amp; + int inv_phase = r->inv_phase; + int inv_phase_inc = r->inv_phase_inc; + + const int step = RESAMPLER_RESOLUTION; + + do + { + // accumulate in extended precision + float kernel_sum = 0.0; + __m128 kernel[SINC_WIDTH / 2]; + __m128 temp1, temp2; + __m128 samplex; + float sample; + float *kernelf = (float*)(&kernel); + int i = SINC_WIDTH; + + if ( out + SINC_WIDTH * 2 > out_end ) + break; + + for (; i >= -SINC_WIDTH + 1; --i) + { + int pos = i * step; + kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(inv_phase - pos)]; + } + sample = *in++ - last_amp; + last_amp += sample; + sample /= kernel_sum; + samplex = _mm_set1_ps( sample ); + for (i = 0; i < SINC_WIDTH / 2; ++i) + { + temp1 = _mm_load_ps( (const float *)( kernel + i ) ); + temp1 = _mm_mul_ps( temp1, samplex ); + temp2 = _mm_loadu_ps( (const float *) out + i * 4 ); + temp1 = _mm_add_ps( temp1, temp2 ); + _mm_storeu_ps( (float *) out + i * 4, temp1 ); + } + + inv_phase += inv_phase_inc; + + out += inv_phase >> RESAMPLER_SHIFT; + + inv_phase &= RESAMPLER_RESOLUTION - 1; + } + while ( in < in_end ); + + r->inv_phase = inv_phase; + r->last_amp = last_amp; + *out_ = out; + + used = (int)(in - in_); + + r->write_filled -= used; + } + + return used; +} +#endif + static int resampler_run_linear(resampler * r, float ** out_, float * out_end) { int in_size = r->write_filled; @@ -326,7 +486,7 @@ static int resampler_run_linear(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -374,7 +534,7 @@ static int resampler_run_cubic(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -428,7 +588,7 @@ static int resampler_run_cubic_sse(resampler * r, float ** out_, float * out_end } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -483,7 +643,7 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -556,7 +716,7 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -586,6 +746,25 @@ static void resampler_fill(resampler * r) resampler_run_zoh( r, &out, out + write_size ); break; + case RESAMPLER_QUALITY_BLEP: + { + int used; + int write_extra = 0; + if ( write_pos >= r->read_pos ) + write_extra = r->read_pos; + if ( write_extra > SINC_WIDTH * 2 - 1 ) + write_extra = SINC_WIDTH * 2 - 1; + memcpy( r->buffer_out + resampler_buffer_size, r->buffer_out, write_extra * sizeof(r->buffer_out[0]) ); + if ( resampler_has_sse ) + used = resampler_run_blep_sse( r, &out, out + write_size + write_extra ); + else + used = resampler_run_blep( r, &out, out + write_size + write_extra ); + memcpy( r->buffer_out, r->buffer_out + resampler_buffer_size, write_extra * sizeof(r->buffer_out[0]) ); + if (!used) + return; + break; + } + case RESAMPLER_QUALITY_LINEAR: resampler_run_linear( r, &out, out + write_size ); break; @@ -623,11 +802,14 @@ int resampler_get_sample_count(void *_r) int resampler_get_sample(void *_r) { resampler * r = ( resampler * ) _r; - if ( r->read_filled < 1 ) + if ( r->read_filled < 1 && r->phase_inc) resampler_fill( r ); if ( r->read_filled < 1 ) return 0; - return (int)(r->buffer_out[ r->read_pos ] * 8388608.0); + if ( r->quality == RESAMPLER_QUALITY_BLEP ) + return (r->buffer_out[ r->read_pos ] + r->accumulator) * 8388608.0; + else + return r->buffer_out[ r->read_pos ] * 8388608.0; } void resampler_remove_sample(void *_r) @@ -635,6 +817,12 @@ void resampler_remove_sample(void *_r) resampler * r = ( resampler * ) _r; if ( r->read_filled > 0 ) { + if ( r->quality == RESAMPLER_QUALITY_BLEP ) + { + r->accumulator += r->buffer_out[ r->read_pos ]; + r->buffer_out[ r->read_pos ] = 0; + r->accumulator -= r->accumulator * (1.0 / 8192.0); + } --r->read_filled; r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size; } diff --git a/Frameworks/Dumb/dumb/src/it/itrender.c b/Frameworks/Dumb/dumb/src/it/itrender.c index 4905a3398..57e5c55a0 100644 --- a/Frameworks/Dumb/dumb/src/it/itrender.c +++ b/Frameworks/Dumb/dumb/src/it/itrender.c @@ -26,7 +26,6 @@ #include "internal/it.h" #include "internal/lpc.h" -#include "internal/blip_buf.h" #include "internal/resampler.h" // #define BIT_ARRAY_BULLSHIT @@ -36,34 +35,15 @@ static IT_PLAYING *new_playing() IT_PLAYING * r = (IT_PLAYING*) malloc(sizeof(*r)); if (r) { - r->resampler.blip_buffer[0] = blip_new( 256 ); - if ( !r->resampler.blip_buffer[0] ) - { - free( r ); - return NULL; - } - r->resampler.blip_buffer[1] = blip_new( 256 ); - if ( !r->resampler.blip_buffer[1] ) - { - free( r->resampler.blip_buffer[0] ); - free( r ); - return NULL; - } - blip_set_rates(r->resampler.blip_buffer[0], 65536, 1); - blip_set_rates(r->resampler.blip_buffer[1], 65536, 1); r->resampler.fir_resampler_ratio = 0.0; r->resampler.fir_resampler[0] = resampler_create(); if ( !r->resampler.fir_resampler[0] ) { - free( r->resampler.blip_buffer[1] ); - free( r->resampler.blip_buffer[0] ); free( r ); return NULL; } r->resampler.fir_resampler[1] = resampler_create(); if ( !r->resampler.fir_resampler[1] ) { resampler_delete( r->resampler.fir_resampler[0] ); - free( r->resampler.blip_buffer[1] ); - free( r->resampler.blip_buffer[0] ); free( r ); return NULL; } @@ -75,8 +55,6 @@ static void free_playing(IT_PLAYING * r) { resampler_delete( r->resampler.fir_resampler[1] ); resampler_delete( r->resampler.fir_resampler[0] ); - blip_delete( r->resampler.blip_buffer[1] ); - blip_delete( r->resampler.blip_buffer[0] ); free( r ); } @@ -166,32 +144,15 @@ static IT_PLAYING *dup_playing(IT_PLAYING *src, IT_CHANNEL *dstchannel, IT_CHANN dst->resampler = src->resampler; dst->resampler.pickup_data = dst; - dst->resampler.blip_buffer[0] = blip_dup( src->resampler.blip_buffer[0] ); - if ( !dst->resampler.blip_buffer[0] ) - { - free( dst ); - return NULL; - } - dst->resampler.blip_buffer[1] = blip_dup( src->resampler.blip_buffer[1] ); - if ( !dst->resampler.blip_buffer[1] ) - { - blip_delete( dst->resampler.blip_buffer[0] ); - free( dst ); - return NULL; - } dst->resampler.fir_resampler_ratio = src->resampler.fir_resampler_ratio; dst->resampler.fir_resampler[0] = resampler_dup( src->resampler.fir_resampler[0] ); if ( !dst->resampler.fir_resampler[0] ) { - blip_delete( dst->resampler.blip_buffer[1] ); - blip_delete( dst->resampler.blip_buffer[0] ); free( dst ); return NULL; } dst->resampler.fir_resampler[1] = resampler_dup( src->resampler.fir_resampler[1] ); if ( !dst->resampler.fir_resampler[1] ) { resampler_delete( dst->resampler.fir_resampler[0] ); - blip_delete( dst->resampler.blip_buffer[1] ); - blip_delete( dst->resampler.blip_buffer[0] ); free( dst ); return NULL; } diff --git a/Frameworks/Dumb/dumb/vc6/dumb/.gitignore b/Frameworks/Dumb/dumb/vc6/dumb/.gitignore deleted file mode 100644 index 32cff875e..000000000 --- a/Frameworks/Dumb/dumb/vc6/dumb/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.user -Debug -Release \ No newline at end of file diff --git a/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcproj b/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcproj deleted file mode 100644 index 525bc56fc..000000000 --- a/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcproj +++ /dev/null @@ -1,2007 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj b/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj deleted file mode 100644 index c9144467d..000000000 --- a/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {612D360C-A51B-4B34-8F49-33F42A2957F5} - dumb - - - - - - - - - - - - StaticLibrary - true - v110_xp - - - StaticLibrary - v110_xp - - - - - - - - - - - - - <_ProjectFileVersion>10.0.21006.1 - AllRules.ruleset - - - AllRules.ruleset - - - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - _USE_SSE;_DEBUG;WIN32;_LIB;DUMB_DECLARE_DEPRECATED;DEBUGMODE=1;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - Level3 - true - EditAndContinue - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - MaxSpeed - AnySuitable - ../../include;%(AdditionalIncludeDirectories) - _USE_SSE;NDEBUG;WIN32;_LIB;DUMB_DECLARE_DEPRECATED;%(PreprocessorDefinitions) - true - MultiThreaded - true - Level3 - true - ProgramDatabase - Default - Fast - NoExtensions - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - true - true - - - Document - true - true - - - Document - true - true - - - - - - - - - - - - - - - - - - - - diff --git a/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj.filters b/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj.filters deleted file mode 100644 index 449103e42..000000000 --- a/Frameworks/Dumb/dumb/vc6/dumb/dumb.vcxproj.filters +++ /dev/null @@ -1,341 +0,0 @@ - - - - - {419c5e1f-2bf4-473a-b2e5-2e531285aa62} - - - {44b333b3-1607-4820-82bc-e4c21a40e31a} - - - {0b122556-3781-4ef3-87fe-ffa5fb50b493} - - - {e961cd19-26f6-4df0-b895-e099d3e81db9} - - - {82e35139-08ff-4e99-a3ce-2254d7427ec4} - - - {5f7fc0f6-4008-4166-83ad-e5d914718bd0} - - - {0fd0715e-5824-4419-aa5b-2d4272d222ce} - - - {b9e26fe7-6056-4580-b2c6-10e6116d4129} - - - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\core - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\helpers - - - src\it\loaders - - - src\it\loaders - - - src\it - - - src\it - - - src\it\readers - - - src\it\readers - - - src\it - - - src\it - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it\readers - - - src\it - - - src\helpers - - - src\it\readers - - - src\it\readers - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\loaders - - - src\it\readers - - - src\it\readers - - - src\helpers - - - src\helpers - - - - - include - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - include\internal - - - - - src\helpers - - - src\helpers - - - src\helpers - - - diff --git a/Frameworks/modplay/modplay/resampler.c b/Frameworks/modplay/modplay/resampler.c index 5a06ef0ac..1bcab7f26 100644 --- a/Frameworks/modplay/modplay/resampler.c +++ b/Frameworks/modplay/modplay/resampler.c @@ -60,10 +60,10 @@ __cpuid(int *data, int selector) #endif static int query_cpu_feature_sse() { - int buffer[4]; - __cpuid(buffer,1); - if ((buffer[3]&(1<<25)) == 0) return 0; - return 1; + int buffer[4]; + __cpuid(buffer,1); + if ((buffer[3]&(1<<25)) == 0) return 0; + return 1; } static int resampler_has_sse = 0; @@ -109,9 +109,13 @@ typedef struct resampler { int write_pos, write_filled; int read_pos, read_filled; - unsigned short phase; + unsigned int phase; unsigned int phase_inc; + unsigned int inv_phase; + unsigned int inv_phase_inc; unsigned char quality; + float last_amp; + float accumulator; float buffer_in[resampler_buffer_size * 2]; float buffer_out[resampler_buffer_size + SINC_WIDTH * 2 - 1]; } resampler; @@ -127,7 +131,11 @@ void * resampler_create(void) r->read_filled = 0; r->phase = 0; r->phase_inc = 0; + r->inv_phase = 0; + r->inv_phase_inc = 0; r->quality = RESAMPLER_QUALITY_MAX; + r->last_amp = 0; + r->accumulator = 0; memset( r->buffer_in, 0, sizeof(r->buffer_in) ); memset( r->buffer_out, 0, sizeof(r->buffer_out) ); @@ -151,7 +159,11 @@ void * resampler_dup(const void * _r) r_out->read_filled = r_in->read_filled; r_out->phase = r_in->phase; r_out->phase_inc = r_in->phase_inc; + r_out->inv_phase = r_in->inv_phase; + r_out->inv_phase_inc = r_in->inv_phase_inc; r_out->quality = r_in->quality; + r_out->last_amp = r_in->last_amp; + r_out->accumulator = r_in->accumulator; memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) ); memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) ); @@ -169,7 +181,11 @@ void resampler_dup_inplace(void *_d, const void *_s) r_out->read_filled = r_in->read_filled; r_out->phase = r_in->phase; r_out->phase_inc = r_in->phase_inc; + r_out->inv_phase = r_in->inv_phase; + r_out->inv_phase_inc = r_in->inv_phase_inc; r_out->quality = r_in->quality; + r_out->last_amp = r_in->last_amp; + r_out->accumulator = r_in->accumulator; memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) ); memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) ); } @@ -181,6 +197,17 @@ void resampler_set_quality(void *_r, int quality) quality = RESAMPLER_QUALITY_MIN; else if (quality > RESAMPLER_QUALITY_MAX) quality = RESAMPLER_QUALITY_MAX; + if ( r->quality != quality ) + { + if ( quality == RESAMPLER_QUALITY_BLEP || r->quality == RESAMPLER_QUALITY_BLEP ) + { + r->read_pos = 0; + r->read_filled = 0; + r->last_amp = 0; + r->accumulator = 0; + memset( r->buffer_out, 0, sizeof(r->buffer_out) ); + } + } r->quality = (unsigned char)quality; } @@ -196,6 +223,7 @@ static int resampler_min_filled(resampler *r) { default: case RESAMPLER_QUALITY_ZOH: + case RESAMPLER_QUALITY_BLEP: return 1; case RESAMPLER_QUALITY_LINEAR: @@ -223,14 +251,18 @@ void resampler_clear(void *_r) r->read_pos = 0; r->read_filled = 0; r->phase = 0; - memset(r->buffer_in, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); - memset(r->buffer_in + resampler_buffer_size, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); + memset(r->buffer_in, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); + memset(r->buffer_in + resampler_buffer_size, 0, (SINC_WIDTH - 1) * sizeof(r->buffer_in[0])); + if (r->quality == RESAMPLER_QUALITY_BLEP) + memset(r->buffer_out, 0, sizeof(r->buffer_out)); } void resampler_set_rate(void *_r, double new_factor) { resampler * r = ( resampler * ) _r; r->phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION ); + new_factor = 1.0 / new_factor; + r->inv_phase_inc = (int)( new_factor * RESAMPLER_RESOLUTION ); } void resampler_write_sample(void *_r, short s) @@ -294,6 +326,134 @@ static int resampler_run_zoh(resampler * r, float ** out_, float * out_end) return used; } +static int resampler_run_blep(resampler * r, float ** out_, float * out_end) +{ + int in_size = r->write_filled; + float const* in_ = r->buffer_in + resampler_buffer_size + r->write_pos - r->write_filled; + int used = 0; + in_size -= 1; + if ( in_size > 0 ) + { + float* out = *out_; + float const* in = in_; + float const* const in_end = in + in_size; + float last_amp = r->last_amp; + int inv_phase = r->inv_phase; + int inv_phase_inc = r->inv_phase_inc; + + const int step = RESAMPLER_RESOLUTION; + + do + { + float kernel[SINC_WIDTH * 2], kernel_sum = 0.0; + int i = SINC_WIDTH; + float sample; + + if ( out + SINC_WIDTH * 2 > out_end ) + break; + + for (; i >= -SINC_WIDTH + 1; --i) + { + int pos = i * step; + kernel_sum += kernel[i + SINC_WIDTH - 1] = sinc_lut[abs(inv_phase - pos)]; + } + sample = *in++ - last_amp; + last_amp += sample; + sample /= kernel_sum; + for (sample = 0, i = 0; i < SINC_WIDTH * 2; ++i) + out[i] += sample * kernel[i]; + + inv_phase += inv_phase_inc; + + out += inv_phase >> RESAMPLER_SHIFT; + + inv_phase &= RESAMPLER_RESOLUTION-1; + } + while ( in < in_end ); + + r->inv_phase = inv_phase; + r->last_amp = last_amp; + *out_ = out; + + used = (int)(in - in_); + + r->write_filled -= used; + } + + return used; +} + +#ifdef RESAMPLER_SSE +static int resampler_run_blep_sse(resampler * r, float ** out_, float * out_end) +{ + int in_size = r->write_filled; + float const* in_ = r->buffer_in + resampler_buffer_size + r->write_pos - r->write_filled; + int used = 0; + in_size -= 1; + if ( in_size > 0 ) + { + float* out = *out_; + float const* in = in_; + float const* const in_end = in + in_size; + float last_amp = r->last_amp; + int inv_phase = r->inv_phase; + int inv_phase_inc = r->inv_phase_inc; + + const int step = RESAMPLER_RESOLUTION; + + do + { + // accumulate in extended precision + float kernel_sum = 0.0; + __m128 kernel[SINC_WIDTH / 2]; + __m128 temp1, temp2; + __m128 samplex; + float sample; + float *kernelf = (float*)(&kernel); + int i = SINC_WIDTH; + + if ( out + SINC_WIDTH * 2 > out_end ) + break; + + for (; i >= -SINC_WIDTH + 1; --i) + { + int pos = i * step; + kernel_sum += kernelf[i + SINC_WIDTH - 1] = sinc_lut[abs(inv_phase - pos)]; + } + sample = *in++ - last_amp; + last_amp += sample; + sample /= kernel_sum; + samplex = _mm_set1_ps( sample ); + for (i = 0; i < SINC_WIDTH / 2; ++i) + { + temp1 = _mm_load_ps( (const float *)( kernel + i ) ); + temp1 = _mm_mul_ps( temp1, samplex ); + temp2 = _mm_loadu_ps( (const float *) out + i * 4 ); + temp1 = _mm_add_ps( temp1, temp2 ); + _mm_storeu_ps( (float *) out + i * 4, temp1 ); + } + + inv_phase += inv_phase_inc; + + out += inv_phase >> RESAMPLER_SHIFT; + + inv_phase &= RESAMPLER_RESOLUTION - 1; + } + while ( in < in_end ); + + r->inv_phase = inv_phase; + r->last_amp = last_amp; + *out_ = out; + + used = (int)(in - in_); + + r->write_filled -= used; + } + + return used; +} +#endif + static int resampler_run_linear(resampler * r, float ** out_, float * out_end) { int in_size = r->write_filled; @@ -326,7 +486,7 @@ static int resampler_run_linear(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -374,7 +534,7 @@ static int resampler_run_cubic(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -428,7 +588,7 @@ static int resampler_run_cubic_sse(resampler * r, float ** out_, float * out_end } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -483,7 +643,7 @@ static int resampler_run_sinc(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -556,7 +716,7 @@ static int resampler_run_sinc_sse(resampler * r, float ** out_, float * out_end) } while ( in < in_end ); - r->phase = (unsigned short) phase; + r->phase = phase; *out_ = out; used = (int)(in - in_); @@ -586,6 +746,25 @@ static void resampler_fill(resampler * r) resampler_run_zoh( r, &out, out + write_size ); break; + case RESAMPLER_QUALITY_BLEP: + { + int used; + int write_extra = 0; + if ( write_pos >= r->read_pos ) + write_extra = r->read_pos; + if ( write_extra > SINC_WIDTH * 2 - 1 ) + write_extra = SINC_WIDTH * 2 - 1; + memcpy( r->buffer_out + resampler_buffer_size, r->buffer_out, write_extra * sizeof(r->buffer_out[0]) ); + if ( resampler_has_sse ) + used = resampler_run_blep_sse( r, &out, out + write_size + write_extra ); + else + used = resampler_run_blep( r, &out, out + write_size + write_extra ); + memcpy( r->buffer_out, r->buffer_out + resampler_buffer_size, write_extra * sizeof(r->buffer_out[0]) ); + if (!used) + return; + break; + } + case RESAMPLER_QUALITY_LINEAR: resampler_run_linear( r, &out, out + write_size ); break; @@ -615,7 +794,7 @@ static void resampler_fill(resampler * r) int resampler_get_sample_count(void *_r) { resampler * r = ( resampler * ) _r; - if ( r->read_filled < 1 ) + if ( r->read_filled < 1 && (r->quality != RESAMPLER_QUALITY_BLEP || r->inv_phase_inc)) resampler_fill( r ); return r->read_filled; } @@ -623,11 +802,14 @@ int resampler_get_sample_count(void *_r) float resampler_get_sample(void *_r) { resampler * r = ( resampler * ) _r; - if ( r->read_filled < 1 ) + if ( r->read_filled < 1 && r->phase_inc) resampler_fill( r ); if ( r->read_filled < 1 ) return 0; - return r->buffer_out[ r->read_pos ]; + if ( r->quality == RESAMPLER_QUALITY_BLEP ) + return r->buffer_out[ r->read_pos ] + r->accumulator; + else + return r->buffer_out[ r->read_pos ]; } void resampler_remove_sample(void *_r) @@ -635,6 +817,12 @@ void resampler_remove_sample(void *_r) resampler * r = ( resampler * ) _r; if ( r->read_filled > 0 ) { + if ( r->quality == RESAMPLER_QUALITY_BLEP ) + { + r->accumulator += r->buffer_out[ r->read_pos ]; + r->buffer_out[ r->read_pos ] = 0; + r->accumulator -= r->accumulator * (1.0 / 8192.0); + } --r->read_filled; r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size; } diff --git a/Frameworks/modplay/modplay/resampler.h b/Frameworks/modplay/modplay/resampler.h index ca89b1db8..42ad64dd0 100644 --- a/Frameworks/modplay/modplay/resampler.h +++ b/Frameworks/modplay/modplay/resampler.h @@ -32,10 +32,11 @@ enum { RESAMPLER_QUALITY_MIN = 0, RESAMPLER_QUALITY_ZOH = 0, - RESAMPLER_QUALITY_LINEAR = 1, - RESAMPLER_QUALITY_CUBIC = 2, - RESAMPLER_QUALITY_SINC = 3, - RESAMPLER_QUALITY_MAX = 3 + RESAMPLER_QUALITY_BLEP = 1, + RESAMPLER_QUALITY_LINEAR = 2, + RESAMPLER_QUALITY_CUBIC = 3, + RESAMPLER_QUALITY_SINC = 4, + RESAMPLER_QUALITY_MAX = 4 }; void resampler_set_quality(void *, int quality); diff --git a/Plugins/Dumb/DumbDecoder.m b/Plugins/Dumb/DumbDecoder.m index ff7406371..62b90fed6 100755 --- a/Plugins/Dumb/DumbDecoder.m +++ b/Plugins/Dumb/DumbDecoder.m @@ -16,9 +16,6 @@ #import "Logging.h" -#include -#include - #import "PlaylistController.h" @implementation DumbDecoder @@ -133,14 +130,6 @@ static unsigned int cpu_freq = 0; { if (self == [DumbDecoder class]) { - int mib[2]; - size_t len; - - mib[0] = CTL_HW; - mib[1] = HW_CPU_FREQ; - len = sizeof(cpu_freq); - sysctl(mib, 2, &cpu_freq, &len, NULL, 0); - // do this here so we don't have to wait on it later _dumb_init_cubic(); _dumb_init_sse(); @@ -209,10 +198,21 @@ int callbackLoop(void *data) } DUMB_IT_SIGRENDERER * itsr = duh_get_it_sigrenderer( dsr ); - { - if (cpu_freq >= 2200000000) - dumb_it_set_resampling_quality( itsr, DUMB_RQ_FIR ); - } + + int resampling_int = -1; + NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"]; + if ([resampling isEqualToString:@"zoh"]) + resampling_int = 0; + else if ([resampling isEqualToString:@"blep"]) + resampling_int = 1; + else if ([resampling isEqualToString:@"linear"]) + resampling_int = 2; + else if ([resampling isEqualToString:@"cubic"]) + resampling_int = 3; + else if ([resampling isEqualToString:@"sinc"]) + resampling_int = 4; + + dumb_it_set_resampling_quality( itsr, resampling_int ); dumb_it_set_ramp_style(itsr, 2); dumb_it_set_loop_callback( itsr, callbackLoop, &loops); dumb_it_set_xm_speed_zero_callback( itsr, dumb_it_callback_terminate, 0); diff --git a/Plugins/MIDI/MIDI/MIDIDecoder.mm b/Plugins/MIDI/MIDI/MIDIDecoder.mm index f416fd49a..6050ac4ca 100755 --- a/Plugins/MIDI/MIDI/MIDIDecoder.mm +++ b/Plugins/MIDI/MIDI/MIDIDecoder.mm @@ -114,7 +114,12 @@ BMPlayer * bmplayer = new BMPlayer; player = bmplayer; - bmplayer->setSincInterpolation( true ); + bool resampling_sinc = false; + NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"]; + if ([resampling isEqualToString:@"sinc"]) + resampling_sinc = true; + + bmplayer->setSincInterpolation( resampling_sinc ); bmplayer->setSampleRate( 44100 ); if ( [soundFontPath length] ) diff --git a/Plugins/modplay/modplay/modDecoder.m b/Plugins/modplay/modplay/modDecoder.m index 8692b368b..a4df6baa2 100755 --- a/Plugins/modplay/modplay/modDecoder.m +++ b/Plugins/modplay/modplay/modDecoder.m @@ -14,7 +14,7 @@ BOOL s3m_probe_length( unsigned long * intro_length, unsigned long * loop_length, const void * src, unsigned long size, unsigned int subsong ) { - void * st3play = st3play_Alloc( 44100, 1, 2 ); + void * st3play = st3play_Alloc( 44100, 0, 0 ); if ( !st3play ) return NO; if ( !st3play_LoadModule( st3play, src, size ) ) @@ -66,7 +66,7 @@ BOOL s3m_probe_length( unsigned long * intro_length, unsigned long * loop_length BOOL xm_probe_length( unsigned long * intro_length, unsigned long * loop_length, const void * src, unsigned long size, unsigned int subsong ) { - void * ft2play = ft2play_Alloc( 44100, 1, 2 ); + void * ft2play = ft2play_Alloc( 44100, 0, 0 ); if ( !ft2play ) return NO; if ( !ft2play_LoadModule( ft2play, src, size ) ) @@ -182,9 +182,22 @@ BOOL xm_probe_length( unsigned long * intro_length, unsigned long * loop_length, - (BOOL)decoderInitialize { + int resampling_int = -1; + NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"]; + if ([resampling isEqualToString:@"zoh"]) + resampling_int = 0; + else if ([resampling isEqualToString:@"blep"]) + resampling_int = 1; + else if ([resampling isEqualToString:@"linear"]) + resampling_int = 2; + else if ([resampling isEqualToString:@"cubic"]) + resampling_int = 3; + else if ([resampling isEqualToString:@"sinc"]) + resampling_int = 4; + if ( type == TYPE_S3M ) { - player = st3play_Alloc( 44100, 1, 2 ); + player = st3play_Alloc( 44100, resampling_int, 2 ); if ( !player ) return NO; @@ -195,7 +208,7 @@ BOOL xm_probe_length( unsigned long * intro_length, unsigned long * loop_length, } else if ( type == TYPE_XM ) { - player = ft2play_Alloc( 44100, 1, 2 ); + player = ft2play_Alloc( 44100, resampling_int, 2 ); if ( !player ) return NO; diff --git a/Preferences/General/English.lproj/Preferences.xib b/Preferences/General/English.lproj/Preferences.xib index a4d68e8d0..53670abed 100644 --- a/Preferences/General/English.lproj/Preferences.xib +++ b/Preferences/General/English.lproj/Preferences.xib @@ -1,8 +1,8 @@ - + - + @@ -30,7 +30,7 @@ - + @@ -120,7 +120,7 @@ - + - + @@ -473,7 +473,7 @@ - + @@ -489,7 +489,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name + slug + preference + + - \ No newline at end of file + diff --git a/Preferences/General/General.xcodeproj/project.pbxproj b/Preferences/General/General.xcodeproj/project.pbxproj index 8f7421bcf..2d94b0e56 100644 --- a/Preferences/General/General.xcodeproj/project.pbxproj +++ b/Preferences/General/General.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 17E41DB80C130AA500AC744D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 17E41DB70C130AA500AC744D /* Localizable.strings */; }; 17E78A7E0D68BE3C005C5A59 /* file_tree.png in Resources */ = {isa = PBXBuildFile; fileRef = 17E78A7D0D68BE3C005C5A59 /* file_tree.png */; }; 17E78B6A0D68C1E3005C5A59 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17E78B680D68C1E3005C5A59 /* Preferences.xib */; }; + 8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */; }; 8384917718084D9F00E7332D /* appearance.png in Resources */ = {isa = PBXBuildFile; fileRef = 8384917518084D9F00E7332D /* appearance.png */; }; 8384917818084D9F00E7332D /* growl.png in Resources */ = {isa = PBXBuildFile; fileRef = 8384917618084D9F00E7332D /* growl.png */; }; 8384918C1808596A00E7332D /* NDHotKey.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 838491841808588D00E7332D /* NDHotKey.framework */; }; @@ -94,6 +95,8 @@ 17E78A7D0D68BE3C005C5A59 /* file_tree.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = file_tree.png; path = Icons/file_tree.png; sourceTree = ""; }; 17E78B690D68C1E3005C5A59 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/Preferences.xib; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* General_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = General_Prefix.pch; sourceTree = ""; }; + 8372053518E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResamplerBehaviorArrayController.h; sourceTree = ""; }; + 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResamplerBehaviorArrayController.m; sourceTree = ""; }; 8384913618081ECB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = ""; }; 8384917518084D9F00E7332D /* appearance.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = appearance.png; path = Icons/appearance.png; sourceTree = ""; }; 8384917618084D9F00E7332D /* growl.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = growl.png; path = Icons/growl.png; sourceTree = ""; }; @@ -227,6 +230,8 @@ 17D503410ABDB1660022D1E8 /* Custom */ = { isa = PBXGroup; children = ( + 8372053518E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.h */, + 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */, 170744AB0BFF3938002475C9 /* AppcastArrayController.h */, 170744AC0BFF3938002475C9 /* AppcastArrayController.m */, 8E6C139E0AACBAB500819171 /* HotKeyControl.h */, @@ -412,6 +417,7 @@ 17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */, 170744AD0BFF3938002475C9 /* AppcastArrayController.m in Sources */, 99F1813F0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.m in Sources */, + 8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Preferences/General/GeneralPreferencesPlugin.m b/Preferences/General/GeneralPreferencesPlugin.m index 2304b9c1b..9f45d857c 100644 --- a/Preferences/General/GeneralPreferencesPlugin.m +++ b/Preferences/General/GeneralPreferencesPlugin.m @@ -13,7 +13,7 @@ + (void)initialize { - NSValueTransformer *pathToFileTransformer = [[[PathToFileTransformer alloc] init]autorelease]; + NSValueTransformer *pathToFileTransformer = [[[PathToFileTransformer alloc] init] autorelease]; [NSValueTransformer setValueTransformer:pathToFileTransformer forName:@"PathToFileTransformer"]; } diff --git a/Preferences/General/MIDIPane.m b/Preferences/General/MIDIPane.m index cef8b769b..d93985309 100644 --- a/Preferences/General/MIDIPane.m +++ b/Preferences/General/MIDIPane.m @@ -12,7 +12,7 @@ - (NSString *)title { - return NSLocalizedStringFromTableInBundle(@"MIDI", nil, [NSBundle bundleForClass:[self class]], @""); + return NSLocalizedStringFromTableInBundle(@"Synthesis", nil, [NSBundle bundleForClass:[self class]], @""); } - (NSImage *)icon diff --git a/Preferences/General/ResamplerBehaviorArrayController.h b/Preferences/General/ResamplerBehaviorArrayController.h new file mode 100644 index 000000000..562d0a010 --- /dev/null +++ b/Preferences/General/ResamplerBehaviorArrayController.h @@ -0,0 +1,13 @@ +// +// ResamplerBehaviorArrayController.h +// General +// +// Created by Christopher Snowhill on 03/26/14. +// +// + +#import + +@interface ResamplerBehaviorArrayController : NSArrayController + +@end diff --git a/Preferences/General/ResamplerBehaviorArrayController.m b/Preferences/General/ResamplerBehaviorArrayController.m new file mode 100644 index 000000000..b980700d8 --- /dev/null +++ b/Preferences/General/ResamplerBehaviorArrayController.m @@ -0,0 +1,42 @@ +// +// ResamplerBehaviorArrayController.m +// General +// +// Created by Christopher Snowhill on 03/26/14. +// +// + +#import "ResamplerBehaviorArrayController.h" + +@implementation ResamplerBehaviorArrayController +- (void)awakeFromNib +{ + [self removeObjects:[self arrangedObjects]]; + + [self addObject: + [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedStringFromTableInBundle(@"Zero Order Hold", nil, [NSBundle bundleForClass:[self class]], @"") , @"name", + @"zoh", @"preference",nil]]; + + [self addObject: + [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedStringFromTableInBundle(@"Blep Synthesis", nil, [NSBundle bundleForClass:[self class]], @"") , @"name", + @"blep", @"preference",nil]]; + + [self addObject: + [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedStringFromTableInBundle(@"Linear Interpolation", nil, [NSBundle bundleForClass:[self class]], @"") , @"name", + @"linear", @"preference",nil]]; + + [self addObject: + [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedStringFromTableInBundle(@"Cubic Interpolation", nil, [NSBundle bundleForClass:[self class]], @"") , @"name", + @"cubic", @"preference",nil]]; + + [self addObject: + [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedStringFromTableInBundle(@"Sinc Interpolation", nil, [NSBundle bundleForClass:[self class]], @"") , @"name", + @"sinc", @"preference",nil]]; +} + +@end