Web-based perception experiments

From Phonlab
Revision as of 09:22, 9 February 2018 by Keithjohnson (talk | contribs)
Jump to navigationJump to search

Experiments can be hosted on the Department of Linguistics server, and then distributed to listeners by email link, or via Amazon Mechanical Turk.

An example is here: example experiment

A Javascript library audexp.js makes it realatively easy to implement the following four typical kinds of experiments:

  • Identification (id) - a single audio file is played, and a two-alternative forced choice (2AFC) is given.
  • Discrimination (ax) - two audio files are played, and a 2AFC is given.
  • Rating (r) - a single audio file is played, and a rating number (from 1 to 7) is given.
  • Contrast Rating (cr) - two audio files are played, and a rating number is given.


Your html code must have four features:

1) after loading audexp.js, load a javascript file that defines:

  • an array (or two arrays) of filenames that will be presented.
  • a variable called 'block'
    • here's an example of such a file
    • this .js file was created with a small perl script from a .csv spreadsheet.
    • the html header contains the following two lines to get the audexp.js library and the experiment-specific list of sound files.
 <script src="js/audexp.js"></script>
 <script src="js/blocktest_list.js"></script>

2) a call to load the experiment when the page is loaded

  • this call specifies the type of experiment (in this case 'id')
  • whether to randomize the order of presentation of the list of sound files
  • the interstimulus interval for 'ax' and 'cr' types
  • and the intertrial interval for all experiments.


 <body onload="load('id',false,500,2000);">

3) Three or for <span...> elements that will be used to give feedback to listeners.

<span id="wr"></span>  is used to show warnings
<span id="f1">sound 1</span>  is used to indicate that an audio file is playing 
<span id="f2">sound 2</span>  is used to indicate that an audio file is playing 
<span id="key">#</span> is used to indicate which key the listener pressed

4) A <form ...> element named "dataform"

    • the order of the input items determines the column order in the output file>
<form method="POST" id="dataform" action="process.php?p=id&n=1">
     <input type="hidden" name="subject" value=<?php echo $subj; ?> />
     <input type="hidden" name="trial" />
     <input type="hidden" name="list" />
     <input type="hidden" name="file1" />
     <input type="hidden" name="filedur" />
     <input type="hidden" name="mystatus" />
     <input type="hidden" name="loadtime" />
     <input type="hidden" name="response" />
     <input type="hidden" name="rt" />
</form>

Saving data to a server file

Finally, in (4) above you may have noticed there was reference to a file: process.php. Here is the entire contents of this file.

  • It constructs a filename from the parameters that you pass to it, and then stores the data from a single key press response as a line in the data file.
    • for example, "process.php?p=id&n=1" translates into the filename "id_data1.csv"
  • The <input..> elements of "dataform" (# 4 above) are now saved as columns in the data file.
  • The data file must already exist on the server
    • This script adds lines, but does not create a new file
    • The data file must be writable, for example: chmod a+w id_data1.csv
<?php
$prefix = $_GET["p"];
$n = $_GET["n"];
$datafile = $prefix . "_data" . $n . ".csv";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $data = "empty";
  foreach($_POST as $key=>$value) {      // we don't have to know the keys
      if ($data == "empty") { $data = $value; }
      else {$data = $data . "," . $value;}
  }
  $data = $data . "\n";
  $ret = file_put_contents($datafile,$data,FILE_APPEND| LOCK_EX);
  if ($ret) {
     echo "saved data";
  } else {
     echo "there was a problem writing the data";
  } 
} else {
 http_response_code(403);
 echo "invalid submission";
}
?>