Changeset 38741 for platform/foobar2000

Show
Ignore:
Timestamp:
12/26/10 20:40:31 (3 years ago)
Author:
topia
Message:

* rewrite sli formula operators.
* add seen counting.
* revert useless previous sli_label change.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • platform/foobar2000/trunk/foo_loop/sli_loop.cpp

    r38737 r38741  
    1818 
    1919#define SLI_FLAGS 16 
     20typedef unsigned int t_sli_value; 
    2021#define SLI_MIN_FLAG_VALUE 0 
    2122#define SLI_MAX_FLAG_VALUE 9999 
     
    3536        loop_condition(const char * confname, const char * symbol, bool is_valid) : 
    3637          confname(confname), symbol(symbol), is_valid(is_valid) {} 
    37         virtual bool check(unsigned int a, unsigned int b) = 0; 
     38        virtual bool check(t_sli_value a, t_sli_value b) = 0; 
    3839}; 
    3940 
     
    4142public: 
    4243        loop_condition_no() : loop_condition("no", NULL, false) {}; 
    43         virtual bool check(unsigned int a, unsigned int b) { return true; } 
     44        virtual bool check(t_sli_value a, t_sli_value b) { return true; } 
    4445}; 
    4546 
     
    4849public: \ 
    4950        loop_condition_ ##name () : loop_condition( #name, #op, true ) {}; \ 
    50         virtual bool check(unsigned int a, unsigned int b) { return a op b; } \ 
     51        virtual bool check(t_sli_value a, t_sli_value b) { return a op b; } \ 
    5152}; 
    5253 
     
    6566        formula_operator(const char * symbol, bool require_operand) : 
    6667                symbol(symbol), require_operand(require_operand) {} 
    67         virtual unsigned int calculate(unsigned int original, unsigned int operand) = 0; 
    68 }; 
    69  
    70 class formula_operator_set : public formula_operator { 
    71 public: 
    72         formula_operator_set() : formula_operator("=", true) {} 
    73         virtual unsigned int calculate(unsigned int original, unsigned int operand) { 
    74                 return operand; 
    75         } 
    76 }; 
    77  
    78 class formula_operator_add : public formula_operator { 
    79 public: 
    80         formula_operator_add() : formula_operator("+=", true) {} 
    81         virtual unsigned int calculate(unsigned int original, unsigned int operand) { 
    82                 return pfc::min_t<unsigned int>(original + operand, SLI_MAX_FLAG_VALUE); 
    83         } 
    84 }; 
    85  
    86 class formula_operator_sub : public formula_operator { 
    87 public: 
    88         formula_operator_sub() : formula_operator("-=", true) {} 
    89         virtual unsigned int calculate(unsigned int original, unsigned int operand) { 
    90                 if (original >= operand) return original - operand; 
    91                 else return 0; 
    92         } 
    93 }; 
    94  
    95 class formula_operator_inc : public formula_operator { 
    96 public: 
    97         formula_operator_inc() : formula_operator("++", false) {} 
    98         virtual unsigned int calculate(unsigned int original, unsigned int operand) { 
    99                 if (original == SLI_MAX_FLAG_VALUE) return original; 
    100                 else return original + 1; 
    101         } 
    102 }; 
    103  
    104 class formula_operator_dec : public formula_operator { 
    105 public: 
    106         formula_operator_dec() : formula_operator("--", false) {} 
    107         virtual unsigned int calculate(unsigned int original, unsigned int operand) { 
    108                 if (original >= 1) return original - 1; 
    109                 else return 0; 
    110         } 
    111 }; 
     68        virtual t_sli_value calculate(t_sli_value original, t_sli_value operand) = 0; 
     69}; 
     70 
     71class sli_flag_value_clipper { 
     72public: 
     73        static inline t_sli_value check_clip(t_sli_value value) { 
     74                return pfc::clip_t<t_sli_value>(value, SLI_MIN_FLAG_VALUE, SLI_MAX_FLAG_VALUE); 
     75        } 
     76        static inline t_sli_value check_min(t_sli_value value) { 
     77                return pfc::max_t<t_sli_value>(value, SLI_MIN_FLAG_VALUE); 
     78        } 
     79        static inline t_sli_value check_max(t_sli_value value) { 
     80                return pfc::min_t<t_sli_value>(value, SLI_MAX_FLAG_VALUE); 
     81        } 
     82}; 
     83 
     84#define DEFINE_FORMULA_OP(name, symbol, value, clipper) \ 
     85class formula_operator_ ##name : public formula_operator { \ 
     86public: \ 
     87        formula_operator_ ##name() : formula_operator(#symbol, true) {}; \ 
     88        virtual t_sli_value calculate(t_sli_value original, t_sli_value operand) { \ 
     89                return sli_flag_value_clipper::check_ ##clipper(value); \ 
     90        } \ 
     91}; 
     92 
     93DEFINE_FORMULA_OP(set, =, operand, clip); 
     94DEFINE_FORMULA_OP(add, +=, original+operand, max); 
     95DEFINE_FORMULA_OP(sub, -=, original-operand, min); 
     96DEFINE_FORMULA_OP(inc, ++, original+1, max); 
     97DEFINE_FORMULA_OP(dec, --, original-1, min); 
    11298 
    11399class sli_link : public loop_event_point_baseimpl { 
    114100public: 
     101        //! set smooth sample count. return true if this link use smoothing, otherwise false. 
    115102        virtual bool set_smooth_samples(t_size samples) = 0; 
    116103        FB2K_MAKE_SERVICE_INTERFACE(sli_link, loop_event_point); 
     
    121108        t_size smooth_samples; 
    122109protected: 
    123         sli_link_impl() : from(0), to(0), smooth(false), condition(NULL), refvalue(0), condvar(0), smooth_samples(0) {} 
     110        sli_link_impl() : from(0), to(0), smooth(false), condition(NULL), refvalue(0), condvar(0), smooth_samples(0), 
     111                seens(0) {} 
    124112        ~sli_link_impl() { 
    125113                if (condition != NULL) delete condition; 
     
    137125        bool smooth; 
    138126        loop_condition * condition; 
    139         unsigned int refvalue; 
    140         unsigned int condvar; 
     127        t_sli_value refvalue; 
     128        t_sli_value condvar; 
     129        t_size seens; 
    141130 
    142131        virtual void get_info(file_info & p_info, const char * p_prefix, t_uint32 sample_rate) { 
     
    168157                p_info.info_set(name, buf);      
    169158        } 
     159 
     160        virtual bool has_dynamic_info() const {return true;} 
     161        virtual bool set_dynamic_info(file_info & p_info, const char * p_prefix, t_uint32 sample_rate) { 
     162                pfc::string8 name; 
     163                name << p_prefix << "seens"; 
     164                p_info.info_set_int(name, seens); 
     165                return true; 
     166        } 
     167        virtual bool reset_dynamic_info(file_info & p_info, const char * p_prefix) { 
     168                pfc::string8 name; 
     169                name << p_prefix << "seens"; 
     170                return p_info.info_remove(name); 
     171        } 
     172 
    170173        virtual void check() const { 
    171174                if (from == to) throw exception_loop_bad_point(); 
     
    177180                if (p_input->get_no_looping() || !check_condition(p_input)) return false; 
    178181                p_input->raw_seek(to, p_abort); 
     182                ++seens; 
    179183                return true; 
    180184        } 
     
    183187class sli_label : public loop_event_point_baseimpl { 
    184188public: 
     189        sli_label() : loop_event_point_baseimpl(on_looping | on_no_looping), position(0), seens(0) {} 
    185190        virtual t_uint64 get_position() const {return position;} 
    186191        virtual t_uint64 get_prepare_position() const {return position;} 
    187192        t_uint64 position; 
     193        t_size seens; 
    188194        pfc::string8 name; 
    189195        virtual void check() const {} 
     
    214220                } 
    215221        } 
     222 
     223        virtual bool has_dynamic_info() const {return true;} 
     224        virtual bool set_dynamic_info(file_info & p_info, const char * p_prefix, t_uint32 sample_rate) { 
     225                pfc::string8 name; 
     226                name << p_prefix << "seens"; 
     227                p_info.info_set_int(name, seens); 
     228                return true; 
     229        } 
     230        virtual bool reset_dynamic_info(file_info & p_info, const char * p_prefix) { 
     231                pfc::string8 name; 
     232                name << p_prefix << "seens"; 
     233                return p_info.info_remove(name); 
     234        } 
     235 
    216236        virtual bool process(loop_type_base::ptr p_input, t_uint64 p_start, audio_chunk & p_chunk, mem_block_container * p_raw, abort_callback & p_abort) { 
    217                 return process(p_input, p_start, p_chunk, p_abort); 
     237                return process(p_input, p_abort); 
    218238        } 
    219239        virtual bool process(loop_type_base::ptr p_input, abort_callback & p_abort); 
    220         virtual bool process(loop_type_base::ptr p_input, t_uint64 p_start, audio_chunk & p_chunk, abort_callback & p_abort); 
    221240}; 
    222241 
     
    227246                if (oper != NULL) delete oper; 
    228247        } 
    229         unsigned int flag; 
     248        t_sli_value flag; 
    230249        formula_operator * oper; 
    231250        bool indirect; 
    232         unsigned int value; 
     251        t_sli_value value; 
    233252}; 
    234253 
     
    318337                        } else if (!pfc::stricmp_ascii(name, "RefValue")) { 
    319338                                if (!pfc::string_is_numeric(value)) return false; 
    320                                 link.refvalue = pfc::clip_t(atoi(value), SLI_MIN_FLAG_VALUE, SLI_MAX_FLAG_VALUE); 
     339                                link.refvalue = pfc::clip_t<t_sli_value>(pfc::atoui_ex(value, ~0), SLI_MIN_FLAG_VALUE, SLI_MAX_FLAG_VALUE); 
    321340                        } else if (!pfc::stricmp_ascii(name, "CondVar")) { 
    322341                                if (!pfc::string_is_numeric(value)) return false; 
    323                                 link.condvar = pfc::clip_t(atoi(value), 0, SLI_FLAGS-1); 
     342                                link.condvar = pfc::clip_t<t_sli_value>(pfc::atoui_ex(value, ~0), 0, SLI_FLAGS-1); 
    324343                        } else { 
    325344                                return false; 
     
    371390        while (pfc::char_is_numeric(p[ptr])) ptr++; 
    372391        if (ptr == 0) return false; 
    373         p_out.flag = pfc::clip_t<unsigned int>(pfc::atoui_ex(p, ptr), 0, SLI_FLAGS-1); 
     392        p_out.flag = pfc::clip_t<t_sli_value>(pfc::atoui_ex(p, ptr), 0, SLI_FLAGS-1); 
    374393        p += ptr; 
    375394        // after flag, should be ']' 
     
    413432        while (pfc::char_is_numeric(p[ptr])) ptr++; 
    414433        if (ptr == 0) return false; 
    415         p_out.value = pfc::clip_t<unsigned int>(pfc::atoui_ex(p, ptr), SLI_MIN_FLAG_VALUE, 
    416                 (p_out.indirect ? SLI_FLAGS-1 : SLI_MAX_FLAG_VALUE)); 
     434        if (p_out.indirect) 
     435                p_out.value = pfc::clip_t<t_sli_value>(pfc::atoui_ex(p, ptr), 0, SLI_FLAGS-1); 
     436        else 
     437                p_out.value = pfc::clip_t<t_sli_value>(pfc::atoui_ex(p, ptr), SLI_MIN_FLAG_VALUE, SLI_MAX_FLAG_VALUE); 
    417438        p += ptr; 
    418439        if (p_out.indirect) { 
     
    610631                        t_size flagnum = m_flags.get_size(); 
    611632                        t_size flag = formula.flag; 
    612                         unsigned int value = formula.value; 
     633                        t_sli_value value = formula.value; 
    613634                        if (formula.indirect) { 
    614635                                value = m_flags[value]; 
     
    641662        // this event do not process on no_looping 
    642663        if ((p_input->get_no_looping() && from >= to) || !check_condition(p_input)) return false; 
     664        ++seens; 
    643665        t_size point = pfc::downcast_guarded<t_size>(from - p_start); 
    644666        loop_type_sli::ptr p_input_special; 
     
    649671        } 
    650672        // smooth 
    651         PFC_ASSERT(p_raw == NULL); 
     673        PFC_ASSERT(p_raw == NULL); // we do not support raw streaming with smoothing 
    652674        t_size smooth_first_samples = smooth_samples; 
    653675        t_size require_samples = point + p_input_special->get_crossfade_samples_half(); 
    654676        t_size samples = p_chunk.get_sample_count(); 
    655         if (require_samples > samples) { 
     677        if (require_samples > samples) 
    656678                samples += p_input->get_more_chunk(p_chunk, p_raw, p_abort, require_samples - samples); 
    657         } 
    658         if (require_samples < samples) { 
     679        if (require_samples < samples) 
    659680                truncate_chunk(p_chunk, p_raw, require_samples);// only debug mode ? 
    660         } 
    661681        t_size smooth_latter_samples = pfc::min_t(require_samples, samples) - point; 
    662682        // seek 
     
    683703} 
    684704 
    685 bool sli_label::process(loop_type_base::ptr p_input, t_uint64 p_start, audio_chunk & p_chunk, abort_callback & p_abort) { 
    686         if (cfg_sli_label_logging.get()) { 
    687                 if ((p_start + p_chunk.get_sample_count()) > get_position()) 
    688                         console::formatter() << "SLI: Label: " << name << " at " <<  
    689                         format_samples_ex(get_position(), p_chunk.get_sample_rate()); 
    690         } 
    691         return process(p_input, p_abort); 
    692 } 
    693  
    694705bool sli_label::process(loop_type_base::ptr p_input, abort_callback & p_abort) { 
    695706        // this event do not process on no_looping 
    696         if (p_input->get_no_looping()) return false; 
     707        if (cfg_sli_label_logging.get()) { 
     708                console::formatter() << "SLI: Label: " << name << " at " <<  
     709                format_samples_ex(get_position(), p_input->get_sample_rate()); 
     710        } 
     711        ++seens; 
    697712        if (name[0] != ':') return false; 
    698713        loop_type_sli::ptr p_input_special; 
     
    724739                        throw exception_io_data(); 
    725740                } 
    726                 PFC_ASSERT(m_looptype.is_valid()); 
    727741        } 
    728742