Skip to content

Sound Interpretation

Bouncer edited this page Nov 2, 2015 · 1 revision

In this template the goal is to capture interpretations of a sound.

Annotation setting

The worker is asked to listen to three sounds, and for each provide comma separated keywords that best describe what is heard. The worker is asked not to use phonetic words such as ‘shhhhh’, ‘trrr’ or ‘whoooop’, not to write sentences such as ‘this is someone whistling’, to spell words correctly, and to separate the keywords with commas.

Result vector

The crowd answers are stored in a vector, where each dimension is the existence of an annotated keyword for that sound. This means that for each unique sound, the keywords are aggregated by all crowd workers to form the vector. The value is the frequency of annotations for that keyword. [keyword 1, keyword 2, etc.]

Screenshot

The crowd worker listens to the sound and provides the keywords in free text input. The keywords are previewed below the input field.

Code:

CML:

<center>
  <audio class="audio" src="{{experiment_url}}" preload="none" controls="controls">Please update your browser to the latest version in order to complete this task.</audio>
  <br />
  <cml:text name="keywords" default="Keywords" label="Provide keywords to describe the sound you just heard" validates="required ss-required minLength:3"></cml:text>
  <div class='tags'></div>
  <span class="instructions">Please use short comma separated keywords</span>
</center>

<div class='events'>
  <cml:hidden name='e_abort' value='0' />  <cml:hidden name='e_canplay' value='0' />  <cml:hidden name='e_canplaythrough' value='0' />  <cml:hidden name='e_durationchange' value='0' />  <cml:hidden name='e_emptied' value='0' />  <cml:hidden name='e_ended' value='0' />  <cml:hidden name='e_error' value='0' /> <cml:hidden name='e_loadeddata' value='0' />  <cml:hidden name='e_loadedmetadata' value='0' /><cml:hidden name='e_loadstart' value='0' />  <cml:hidden name='e_pause' value='0' /><cml:hidden name='e_play' value='0' />  <cml:hidden name='e_playing' value='0' />  <cml:hidden name='e_progress' value='0' />  <cml:hidden name='e_ratechange' value='0' />  <cml:hidden name='e_seeked' value='0' /><cml:hidden name='e_seeking' value='0' />  <cml:hidden name='e_stalled' value='0' />  <cml:hidden name='e_suspend' value='0' />  <cml:hidden name='e_timeupdate' value='0' />  <cml:hidden name='e_volumechange' value='0' />  <cml:hidden name='e_waiting' value='0' />
</div>

<cml:hidden label="contributors_browser" validates="user_agent" />

CSS:

.instructions {
  color: #e32636; 
  background-image: none !important;
  display:none;
}

.tags .tag {
  margin-right: 4px;
}

.cml .cml_field {
  margin: 0 0 6px;
}

.cml .legend {
  margin-bottom: 10px;
}

JS:

require(['jquery-noconflict'], function(jQuery) {
  
  Window.implement('$', function(el, nc){
    return document.id(el, nc, this.document);
  });
  var $ = window.jQuery;  
 
  // all events that can be captured. log everything a worker does
  var events = ['abort', // Fires when the loading of an audio/video is aborted
                'canplay', // Fires when the browser can start playing the audio/video
                'canplaythrough', // Fires when the browser can play through the audio/video without stopping for buffering
                'durationchange', // Fires when the duration of the audio/video is changed
                'emptied', // Fires when the current playlist is empty
                'ended', // Fires when the current playlist is ended
                'error', //  Fires when an error occurred during the loading of an audio/video
                'loadeddata', // Fires when the browser has loaded the current frame of the audio/video
                'loadedmetadata', // Fires when the browser has loaded meta data for the audio/video
                'loadstart', // Fires when the browser starts looking for the audio/video
                'pause', // Fires when the audio/video has been paused
                'play', // Fires when the audio/video has been started or is no longer paused
                'playing', // Fires when the audio/video is playing after having been paused or stopped for buffering
                'progress', //  Fires when the browser is downloading the audio/video
                'ratechange', // Fires when the playing speed of the audio/video is changed
                'seeked', // Fires when the user is finished moving/skipping to a new position in the audio/video
                'seeking', // Fires when the user starts moving/skipping to a new position in the audio/video
                'stalled', // Fires when the browser is trying to get media data, but data is not available
                'suspend', // Fires when the browser is intentionally not getting media data
                'timeupdate', //  Fires when the current playback position has changed
                'volumechange', // Fires when the volume has been changed
                'waiting' // Fires when the video stops because it needs to buffer the next frame
               ];
  
  // randomize unit order  
  (function($) {
    
    $.fn.randomize = function(childElem) {
      return this.each(function() {
        var $this = $(this);
        var elems = $this.children(childElem);
        
        elems.sort(function() { return (Math.round(Math.random())-0.5); });  
        
        $this.remove(childElem);  
        
        for(var i=0; i < elems.length; i++)
          $this.children('div:first-child').after(elems[i]);      
        
      });    
    }
      })(jQuery);
  
  $("#job_units").randomize(".jsawesome");

  
  // number all units in the task
  $('.keywords').each(function( index ) {
    $(this).parents('.cml_field').find('.legend').text(function(i, v) {
      return parseInt(index + 1) + '. ' + v;
    });
  });
  
  $('.submit').attr('disabled',true);
  
  // show tag examples
  $('.keywords').on('input',function(e){
    var tags = $.map($(this).val().split(","), $.trim);
    
    var result = [];
    var error = 0;
    $.each(tags, function(i, v) {
      if(v.length > 0 && v != " ") {
        if(v.length < (15 * v.split(' ').length) && v.split(' ').length < 4 && v.match(/^([a-zA-Z0-9 _-]+)$/)) {
          result += "<span class='tag btn btn-success btn-xs'>" + v + "</span>";
        } else {
          result += "<span class='tag btn btn-danger btn-xs'>" + v + "</span>";
          error = 1;
        }
      }
    });
    if(error == 1) {
      $(this).parents('.jsawesome').find('.instructions').show();     
    } else {
      $(this).parents('.jsawesome').find('.instructions').hide();
    }
    $(this).parents('.jsawesome').find('.tags').html(result);
  });
  
  
  // for all events, update input field on trigger
  for(e=0; e < events.length; e++) {
    $('.audio').on(events[e], function(event) { 
      $(this).parents('.jsawesome').find('input.e_' + event.type).val( function(i, v) {
        return parseInt(v) + 1;
      });
      // if event is ended and all audio has ended
      if(event.type == 'ended' && $(".e_ended").filter(function() { return  $(this).val() >= 1; }).length == $('.e_ended').length) {       
        $('.submit').attr('disabled',false);
      }
    });
  }  

});
Clone this wiki locally