diff --git a/app/src/main/rs/calibration_detector.rsh b/app/src/main/rs/calibration_detector.rsh index adb691c..2293b96 100644 --- a/app/src/main/rs/calibration_detector.rsh +++ b/app/src/main/rs/calibration_detector.rsh @@ -19,18 +19,14 @@ limitations under the License. #include "constants.rsh" #include "state.rsh" +#include "pulse.rsh" static int calibration_detected(int cnt_quantized) { - static int ssb_counter; - int ssb_level = cnt_quantized == 0; - int ssb_pulse = !ssb_level && ssb_counter >= ssb_length; - ssb_counter = ssb_level ? ssb_counter + 1 : 0; - - static int bit_pos, vis_pos, vis_code; + static int bit_pos = 8, vis_pos, vis_code; static int vis_counter, bit_counter; - if (ssb_pulse) { + if (pulse_detected(&start_bit_detector, cnt_quantized == 0)) { vis_code = 0; bit_pos = 0; vis_pos = 2 * bit_length; diff --git a/app/src/main/rs/decoder.rs b/app/src/main/rs/decoder.rs index 4694c19..0cb696f 100644 --- a/app/src/main/rs/decoder.rs +++ b/app/src/main/rs/decoder.rs @@ -21,6 +21,7 @@ limitations under the License. #include "ema.rsh" #include "ddc.rsh" #include "fmd.rsh" +#include "pulse.rsh" #include "scanline_estimator.rsh" #include "calibration_detector.rsh" #include "initialization.rsh" @@ -39,7 +40,7 @@ void reset_buffer() prev_sync_pos = sync_pos = 0; buffer_pos = 0; seperator_counter = 0; - sync_counter = sync_length; + fake_pulse(&sync_pulse_detector); buffer_cleared = 1; for (int i = 0; i < maximum_width * maximum_height; ++i) pixel_buffer[i] = rgb(0, 0, 0); @@ -275,11 +276,10 @@ void decode(int samples) { int dat_quantized = round(dat_value); int sync_level = cnt_active && cnt_quantized == 0; - int sync_pulse = !sync_level && sync_counter >= sync_length; - sync_counter = sync_level ? sync_counter + 1 : 0; + int sync_pulse = pulse_detected(&sync_pulse_detector, sync_level); if (sync_pulse) { prev_sync_pos = sync_pos; - sync_pos = buffer_pos - sync_buildup_length; + sync_pos = buffer_pos + trailing_edge_position(&sync_pulse_detector); } static int reset_on_first_sync; diff --git a/app/src/main/rs/initialization.rsh b/app/src/main/rs/initialization.rsh index 60b0868..2bc6c12 100644 --- a/app/src/main/rs/initialization.rsh +++ b/app/src/main/rs/initialization.rsh @@ -41,16 +41,15 @@ void initialize(float rate, int length, int iw, int ih, int sw, int sh, int sgw, hpos = 0; prev_sync_pos = sync_pos = 0; buffer_pos = 0; - sync_counter = 0; seperator_counter = 0; 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); + + const float sync_tolerance = 0.7; + sync_pulse_detector_5ms = init_pulse(sync_tolerance * 5.0f, sync_buildup_ms, sample_rate); + sync_pulse_detector_9ms = init_pulse(sync_tolerance * 9.0f, sync_buildup_ms, sample_rate); + sync_pulse_detector_20ms = init_pulse(sync_tolerance * 20.0f, sync_buildup_ms, sample_rate); + sync_pulse_detector = init_pulse(2.0f, sync_buildup_ms, sample_rate); robot36_scanline_length = round((robot36_scanline_ms * sample_rate) / 1000.0f); robot72_scanline_length = round((robot72_scanline_ms * sample_rate) / 1000.0f); @@ -72,12 +71,12 @@ void initialize(float rate, int length, int iw, int ih, int sw, int sh, int sgw, maximum_absolute_deviaton = 0.5f * pairwise_minimum_of_scanline_time_distances * sample_rate; maximum_variance = pown(0.0005f * sample_rate, 2); - const float vis_seconds = 0.3f; - const float bit_seconds = 0.03f; - const float ssb_tolerance = 0.9f; - vis_length = vis_seconds * sample_rate; - bit_length = bit_seconds * sample_rate; - ssb_length = ssb_tolerance * bit_seconds * sample_rate; + const float vis_ms = 300.0f; + const float bit_ms = 30.0f; + vis_length = round((vis_ms * sample_rate) / 1000.0f); + bit_length = round((bit_ms * sample_rate) / 1000.0f); + const float start_bit_tolerance = 0.9f; + start_bit_detector = init_pulse(start_bit_tolerance * bit_ms, 0, sample_rate); const float dat_carrier = 1900.0f; const float cnt_carrier = 1200.0f; diff --git a/app/src/main/rs/modes.rsh b/app/src/main/rs/modes.rsh index 8589e52..c9e2e3f 100644 --- a/app/src/main/rs/modes.rsh +++ b/app/src/main/rs/modes.rsh @@ -33,7 +33,7 @@ void raw_mode() freerun_height = maximum_height; bitmap_width = maximum_width; bitmap_height = maximum_height; - sync_length = minimum_sync_length; + sync_pulse_detector = init_pulse(2.0f, sync_buildup_ms, sample_rate); minimum_length = 0.05f * sample_rate; maximum_length = buffer_length; scanline_length = maximum_length; @@ -55,7 +55,7 @@ void robot36_mode() const float uv_scan_ms = 44.0f; const float seperator_ms = 4.5f; seperator_length = round((seperator_ms * sample_rate) / 1000.0f); - sync_length = tolerance * (sync_ms * sample_rate) / 1000.0f; + sync_pulse_detector = init_pulse(tolerance * sync_ms, sync_buildup_ms, sample_rate); float y_begin_ms = sync_porch_ms; float y_end_ms = y_begin_ms + y_scan_ms; @@ -92,7 +92,7 @@ void robot72_mode() const float uv_scan_ms = 69.0f; const float seperator_ms = 4.5f; seperator_length = round((seperator_ms * sample_rate) / 1000.0f); - sync_length = tolerance * (sync_ms * sample_rate) / 1000.0f; + sync_pulse_detector = init_pulse(tolerance * sync_ms, sync_buildup_ms, sample_rate); float y_begin_ms = sync_porch_ms; float y_end_ms = y_begin_ms + y_scan_ms; @@ -132,7 +132,7 @@ static void pd_mode(int mode, int scanline, int blur, float yuv_scan_ms, int wid const float tolerance = 0.8f; const float sync_ms = 20.0f; const float porch_ms = 2.08f; - sync_length = tolerance * (sync_ms * sample_rate) / 1000.0f; + sync_pulse_detector = init_pulse(tolerance * sync_ms, sync_buildup_ms, sample_rate); float y_even_begin_ms = porch_ms; float y_even_end_ms = y_even_begin_ms + yuv_scan_ms; @@ -177,7 +177,7 @@ static void martin_mode(int mode, int scanline, int blur, float rgb_scan_ms) const float sync_porch_ms = 0.572f; const float seperator_ms = 0.572f; seperator_length = round((seperator_ms * sample_rate) / 1000.0f); - sync_length = tolerance * (sync_ms * sample_rate) / 1000.0f; + sync_pulse_detector = init_pulse(tolerance * sync_ms, sync_buildup_ms, sample_rate); float g_begin_ms = sync_porch_ms; float g_end_ms = g_begin_ms + rgb_scan_ms; @@ -213,7 +213,7 @@ static void scottie_mode(int mode, int scanline, int blur, float rgb_scan_ms) const float sync_porch_ms = 1.5f; const float seperator_ms = 1.5f; seperator_length = round((seperator_ms * sample_rate) / 1000.0f); - sync_length = tolerance * (sync_ms * sample_rate) / 1000.0f; + sync_pulse_detector = init_pulse(tolerance * sync_ms, sync_buildup_ms, sample_rate); float r_begin_ms = sync_porch_ms; float r_end_ms = r_begin_ms + rgb_scan_ms; @@ -249,7 +249,7 @@ void wraaseSC2_180_mode() const float sync_ms = 5.5225f; const float sync_porch_ms = 0.5f; const float rgb_scan_ms = 235.0f; - sync_length = tolerance * (sync_ms * sample_rate) / 1000.0f; + sync_pulse_detector = init_pulse(tolerance * sync_ms, sync_buildup_ms, sample_rate); float r_begin_ms = sync_porch_ms; float r_end_ms = r_begin_ms + rgb_scan_ms; diff --git a/app/src/main/rs/pulse.rsh b/app/src/main/rs/pulse.rsh new file mode 100644 index 0000000..4a6ba4d --- /dev/null +++ b/app/src/main/rs/pulse.rsh @@ -0,0 +1,46 @@ +/* +Copyright 2015 Ahmet Inan + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + +#ifndef PULSE_RSH +#define PULSE_RSH + +typedef struct { + int counter, length, buildup; +} pulse_t; + +static pulse_t init_pulse(float length, float buildup, int rate) +{ + return (pulse_t){ 0, round((length * rate) / 1000.0f), round((buildup * rate) / 1000.0f) }; +} + +static int pulse_detected(pulse_t *pulse, int level) +{ + int trailing_edge = !level && pulse->counter >= pulse->length; + pulse->counter = level ? pulse->counter + 1 : 0; + return trailing_edge; +} + +static void fake_pulse(pulse_t *pulse) +{ + pulse->counter = pulse->length; +} + +static int trailing_edge_position(pulse_t *pulse) +{ + return -pulse->buildup; +} + +#endif \ No newline at end of file diff --git a/app/src/main/rs/scanline_estimator.rsh b/app/src/main/rs/scanline_estimator.rsh index 3fdc92d..8ee6604 100644 --- a/app/src/main/rs/scanline_estimator.rsh +++ b/app/src/main/rs/scanline_estimator.rsh @@ -20,27 +20,24 @@ limitations under the License. #include "constants.rsh" #include "state.rsh" #include "sma.rsh" +#include "pulse.rsh" static int scanline_estimator(int sync_level) { - 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; - static int scanline_counter_5ms, scanline_counter_9ms, scanline_counter_20ms; ++scanline_counter_5ms; ++scanline_counter_9ms; ++scanline_counter_20ms; - if (!sync_pulse) - return -1; - 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; - if (sync_len >= min_sync_length_20ms) { + int sync_pulse_5ms = pulse_detected(&sync_pulse_detector_5ms, sync_level); + int sync_pulse_9ms = pulse_detected(&sync_pulse_detector_9ms, sync_level); + int sync_pulse_20ms = pulse_detected(&sync_pulse_detector_20ms, sync_level); + + if (sync_pulse_20ms) { static sma_t sma; sma_add(&sma, scanline_counter_20ms); scanline_counter_20ms = 0; @@ -85,7 +82,7 @@ static int scanline_estimator(int sync_level) return mode_pd240; else if (min_adev == pd290_adev) return mode_pd290; - } else if (sync_len >= min_sync_length_9ms) { + } else if (sync_pulse_9ms) { static sma_t sma; sma_add(&sma, scanline_counter_9ms); scanline_counter_9ms = 0; @@ -121,7 +118,7 @@ static int scanline_estimator(int sync_level) return mode_scottie2; else if (min_adev == scottieDX_adev) return mode_scottieDX; - } else if (sync_len >= min_sync_length_5ms) { + } else if (sync_pulse_5ms) { static sma_t sma; sma_add(&sma, scanline_counter_5ms); scanline_counter_5ms = 0; diff --git a/app/src/main/rs/state.rsh b/app/src/main/rs/state.rsh index bac29ae..25db770 100644 --- a/app/src/main/rs/state.rsh +++ b/app/src/main/rs/state.rsh @@ -20,6 +20,8 @@ limitations under the License. static ema_t avg_power; static ddc_t cnt_ddc, dat_ddc; static fmd_t cnt_fmd, dat_fmd; +static pulse_t sync_pulse_detector, start_bit_detector; +static pulse_t sync_pulse_detector_5ms, sync_pulse_detector_9ms, sync_pulse_detector_20ms; static int disable_analyzer; static int automatic_mode_detection; static int debug_mode; @@ -27,8 +29,6 @@ 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 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_length, bit_length, ssb_length; static int buffer_length, buffer_mask, buffer_pos; @@ -38,13 +38,12 @@ static int maximum_width, maximum_height; static int freerun_height; static int spectrum_width, spectrum_height; static int spectrogram_width, spectrogram_height; -static int sync_length, sync_counter, vpos, hpos; +static int vpos, hpos; static int seperator_counter, seperator_length; static int u_sep_begin, u_sep_end, v_sep_begin, v_sep_end; static int y_even_begin, y_even_end, y_odd_begin, y_odd_end; static int y_begin, y_end, u_begin, u_end, v_begin, v_end; static int r_begin, r_end, b_begin, b_end, g_begin, g_end; -static int sync_buildup_length; static int robot36_scanline_length; static int robot72_scanline_length; static int martin1_scanline_length;