diff --git a/app/src/main/rs/initialization.rsh b/app/src/main/rs/initialization.rsh index 8df5c52..277e727 100644 --- a/app/src/main/rs/initialization.rsh +++ b/app/src/main/rs/initialization.rsh @@ -46,6 +46,10 @@ void initialize(float rate, int length, int iw, int ih, int sw, int sh, int sgw, buffer_cleared = 0; free_running = 1; minimum_sync_length = 0.002f * sample_rate; + const float sync_len_tolerance = 0.7; + min_sync_length_5ms = sync_len_tolerance * 0.005f * sample_rate; + min_sync_length_9ms = sync_len_tolerance * 0.009f * sample_rate; + min_sync_length_20ms = sync_len_tolerance * 0.020f * sample_rate; sync_buildup_length = round((sync_buildup_ms * sample_rate) / 1000.0f); robot36_scanline_length = round((robot36_scanline_ms * sample_rate) / 1000.0f); @@ -64,8 +68,12 @@ void initialize(float rate, int length, int iw, int ih, int sw, int sh, int sgw, pd240_scanline_length = round((pd240_scanline_ms * sample_rate) / 1000.0f); pd290_scanline_length = round((pd290_scanline_ms * sample_rate) / 1000.0f); - const float pairwise_minimum_of_scanline_time_distances = 0.0079825f; - maximum_absolute_deviaton = 0.5f * pairwise_minimum_of_scanline_time_distances * sample_rate; + const float pairwise_minimum_of_scanline_time_distances_5ms = 0.219648f; + const float pairwise_minimum_of_scanline_time_distances_9ms = 0.022308f; + const float pairwise_minimum_of_scanline_time_distances_20ms = 0.050176f; + maximum_abs_dev_5ms = 0.5f * pairwise_minimum_of_scanline_time_distances_5ms * sample_rate; + maximum_abs_dev_9ms = 0.5f * pairwise_minimum_of_scanline_time_distances_9ms * sample_rate; + maximum_abs_dev_20ms = 0.5f * pairwise_minimum_of_scanline_time_distances_20ms * sample_rate; maximum_variance = pown(0.0005f * sample_rate, 2); const float first_leader_tolerance = 0.3f; diff --git a/app/src/main/rs/scanline_estimator.rsh b/app/src/main/rs/scanline_estimator.rsh index 28bae8a..66e81d7 100644 --- a/app/src/main/rs/scanline_estimator.rsh +++ b/app/src/main/rs/scanline_estimator.rsh @@ -23,55 +23,42 @@ limitations under the License. static int scanline_estimator(int sync_level) { - static scanline_counter, sync_counter; - + static int sync_counter; int sync_pulse = !sync_level && sync_counter >= minimum_sync_length; + int sync_len = sync_counter; sync_counter = sync_level ? sync_counter + 1 : 0; - if (!sync_pulse) { - ++scanline_counter; - return -1; - } + static int scanline_counter_5ms, scanline_counter_9ms, scanline_counter_20ms; + ++scanline_counter_5ms; + ++scanline_counter_9ms; + ++scanline_counter_20ms; - if (scanline_counter >= buffer_length) - scanline_counter = 0; - - static sma_t sma; - sma_add(&sma, scanline_counter); - scanline_counter = 0; - - if (sma_variance(&sma) > maximum_variance) + if (!sync_pulse) return -1; - int mean = sma_mean(&sma); + scanline_counter_5ms = scanline_counter_5ms >= buffer_length ? 0 : scanline_counter_5ms; + scanline_counter_9ms = scanline_counter_9ms >= buffer_length ? 0 : scanline_counter_9ms; + scanline_counter_20ms = scanline_counter_20ms >= buffer_length ? 0 : scanline_counter_20ms; - int robot36_adev = abs(mean - robot36_scanline_length); - int robot72_adev = abs(mean - robot72_scanline_length); - int martin1_adev = abs(mean - martin1_scanline_length); - int martin2_adev = abs(mean - martin2_scanline_length); - int scottie1_adev = abs(mean - scottie1_scanline_length); - int scottie2_adev = abs(mean - scottie2_scanline_length); - int scottieDX_adev = abs(mean - scottieDX_scanline_length); - int wraaseSC2_180_adev = abs(mean - wraaseSC2_180_scanline_length); - int pd50_adev = abs(mean - pd50_scanline_length); - int pd90_adev = abs(mean - pd90_scanline_length); - int pd120_adev = abs(mean - pd120_scanline_length); - int pd160_adev = abs(mean - pd160_scanline_length); - int pd180_adev = abs(mean - pd180_scanline_length); - int pd240_adev = abs(mean - pd240_scanline_length); - int pd290_adev = abs(mean - pd290_scanline_length); + if (sync_len >= min_sync_length_20ms) { + static sma_t sma; + sma_add(&sma, scanline_counter_20ms); + scanline_counter_20ms = 0; - int min_adev = min( - min( - min( - min(robot36_adev, robot72_adev), - min(martin1_adev, martin2_adev) - ), min( - min(scottie1_adev, scottie2_adev), - min(scottieDX_adev, wraaseSC2_180_adev) - ) - ), - min( + if (sma_variance(&sma) > maximum_variance) + return -1; + + int mean = sma_mean(&sma); + + int pd50_adev = abs(mean - pd50_scanline_length); + int pd90_adev = abs(mean - pd90_scanline_length); + int pd120_adev = abs(mean - pd120_scanline_length); + int pd160_adev = abs(mean - pd160_scanline_length); + int pd180_adev = abs(mean - pd180_scanline_length); + int pd240_adev = abs(mean - pd240_scanline_length); + int pd290_adev = abs(mean - pd290_scanline_length); + + int min_adev = min( min( min(pd50_adev, pd90_adev), min(pd120_adev, pd160_adev) @@ -80,41 +67,88 @@ static int scanline_estimator(int sync_level) min(pd180_adev, pd240_adev), pd290_adev ) - ) - ); + ); - if (min_adev > maximum_absolute_deviaton) - return -1; - else if (min_adev == robot36_adev) - return mode_robot36; - else if (min_adev == robot72_adev) - return mode_robot72; - else if (min_adev == martin1_adev) - return mode_martin1; - else if (min_adev == martin2_adev) - return mode_martin2; - else if (min_adev == scottie1_adev) - return mode_scottie1; - else if (min_adev == scottie2_adev) - return mode_scottie2; - else if (min_adev == scottieDX_adev) - return mode_scottieDX; - else if (min_adev == wraaseSC2_180_adev) - return mode_wraaseSC2_180; - else if (min_adev == pd50_adev) - return mode_pd50; - else if (min_adev == pd90_adev) - return mode_pd90; - else if (min_adev == pd120_adev) - return mode_pd120; - else if (min_adev == pd160_adev) - return mode_pd160; - else if (min_adev == pd180_adev) - return mode_pd180; - else if (min_adev == pd240_adev) - return mode_pd240; - else if (min_adev == pd290_adev) - return mode_pd290; + if (min_adev > maximum_abs_dev_20ms) + return -1; + else if (min_adev == pd50_adev) + return mode_pd50; + else if (min_adev == pd90_adev) + return mode_pd90; + else if (min_adev == pd120_adev) + return mode_pd120; + else if (min_adev == pd160_adev) + return mode_pd160; + else if (min_adev == pd180_adev) + return mode_pd180; + else if (min_adev == pd240_adev) + return mode_pd240; + else if (min_adev == pd290_adev) + return mode_pd290; + } else if (sync_len >= min_sync_length_9ms) { + static sma_t sma; + sma_add(&sma, scanline_counter_9ms); + scanline_counter_9ms = 0; + + if (sma_variance(&sma) > maximum_variance) + return -1; + + int mean = sma_mean(&sma); + + int robot36_adev = abs(mean - robot36_scanline_length); + int robot72_adev = abs(mean - robot72_scanline_length); + int scottie1_adev = abs(mean - scottie1_scanline_length); + int scottie2_adev = abs(mean - scottie2_scanline_length); + int scottieDX_adev = abs(mean - scottieDX_scanline_length); + + int min_adev = min( + min( + min(robot36_adev, robot72_adev), + min(scottie1_adev, scottie2_adev) + ), + scottieDX_adev + ); + + if (min_adev > maximum_abs_dev_9ms) + return -1; + else if (min_adev == robot36_adev) + return mode_robot36; + else if (min_adev == robot72_adev) + return mode_robot72; + else if (min_adev == scottie1_adev) + return mode_scottie1; + else if (min_adev == scottie2_adev) + return mode_scottie2; + else if (min_adev == scottieDX_adev) + return mode_scottieDX; + } else if (sync_len >= min_sync_length_5ms) { + static sma_t sma; + sma_add(&sma, scanline_counter_5ms); + scanline_counter_5ms = 0; + + if (sma_variance(&sma) > maximum_variance) + return -1; + + int mean = sma_mean(&sma); + + int martin1_adev = abs(mean - martin1_scanline_length); + int martin2_adev = abs(mean - martin2_scanline_length); + int wraaseSC2_180_adev = abs(mean - wraaseSC2_180_scanline_length); + + int min_adev = min( + min(martin1_adev, martin2_adev), + wraaseSC2_180_adev + ); + + if (min_adev > maximum_abs_dev_5ms) + return -1; + else if (min_adev == martin1_adev) + return mode_martin1; + else if (min_adev == martin2_adev) + return mode_martin2; + else if (min_adev == wraaseSC2_180_adev) + return mode_wraaseSC2_180; + } return -1; } diff --git a/app/src/main/rs/state.rsh b/app/src/main/rs/state.rsh index b657d1c..3bd222d 100644 --- a/app/src/main/rs/state.rsh +++ b/app/src/main/rs/state.rsh @@ -26,8 +26,10 @@ static int debug_mode; static int current_decoder; static int user_blur, blur_power, free_running; static int sample_rate, sync_pos, prev_sync_pos; -static int maximum_variance, maximum_absolute_deviaton; +static int maximum_variance; +static int maximum_abs_dev_5ms, maximum_abs_dev_9ms, maximum_abs_dev_20ms; static int minimum_sync_length; +static int min_sync_length_5ms, min_sync_length_9ms, min_sync_length_20ms; static int scanline_length, minimum_length, maximum_length; static int vis_timeout, vis_length, bit_length; static int break_timeout, break_length;