@prefix mo: . @prefix math: . @prefix log: . @prefix af: . @prefix ctr: . @prefix qm-vamp: . @prefix xsd: . @prefix tl: . @prefix vamp: . @prefix sig: . @prefix sim: . @prefix event: . @prefix dcterms: . _:transform_keydetect a vamp:Transform ; vamp:plugin qm-vamp:qm-keydetector ; vamp:step_size "32768"^^xsd:int ; vamp:block_size "32768"^^xsd:int ; vamp:sample_rate "44100"^^xsd:float ; vamp:parameter_binding [ vamp:parameter [ vamp:identifier "length" ] ; vamp:value "100"^^xsd:float ; ] ; vamp:parameter_binding [ vamp:parameter [ vamp:identifier "tuning" ] ; vamp:value "440"^^xsd:float ; ] ; vamp:output qm-vamp:qm-keydetector_output_key . :pick_second_key dcterms:description "a simple algorithm that takes as input (subject) a list of keys and keychange times and returns as output (object) the key change occurring immediately after the first"@en . { ?track1 mo:available_as ?af1 . ?af1 mo:encodes ?signal1 . ?signal1 a mo:Signal ; mo:time [ a tl:Interval ; tl:onTimeLine :signal_timeline_1 ] . _:keychange1 a af:KeyChange ; event:time [ a tl:Instant ; tl:onTimeLine :signal_timeline_1 ; tl:at ?key_change_time1 ; ] ; vamp:computed_by _:transform_keydetect ; af:feature ?key1 . } ctr:cc { ?track2 mo:available_as ?af2 . ?af2 mo:encodes ?signal2 . ?signal2 a mo:Signal ; mo:time [ a tl:Interval ; tl:onTimeLine :signal_timeline_2 ] . _:keychange2 a af:KeyChange ; event:time [ a tl:Instant ; tl:onTimeLine :signal_timeline_2 ; tl:at ?key_change_time2 ; ] ; vamp:computed_by _:transform_keydetect ; af:feature ?key2 . } . (?key1 ?key_change_time1) :pick_second_key ?pkey1 . (?key2 ?key_change_time2) :pick_second_key ?pkey2 . {?pkey1 math:equalTo ?pkey2 } log:implies {_:keysimilarity a sim:Similarity ; sim:element ?track1 ; sim:element ?track2 . } .