Difference between revisions of "Web-based perception experiments"

From Phonlab
Jump to navigationJump to search
Line 31: Line 31:
   
   
In the php script, the javascript lines above are generated with an embedded bit of php code. This makes it possible for me to deploy different experiments (that just differ in the list of sound files that will be played), using the same php script. The script constructs different list files on the fly from the "list" variable that is given in the URL.
+
In the php script, the javascript lines above are generated with an embedded bit of php code (as below). This makes it possible for me to deploy different experiments (that just differ in the list of sound files that will be played), using the same php script. The script constructs different list file names on the fly from the "list" variable that is given in the URL.
   
 
<script src="js/audexp.js"></script>
 
<script src="js/audexp.js"></script>

Revision as of 08:47, 14 February 2018

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>

In the experiment linked above, the link is to a php script which dynamically constructs the html code that is delivered the user's web browser. The word 'test' is passed to the php script in the URL: http://linguistics.berkeley.edu/~kjohnson/rating_exp.php?list=test

The list variable is read from the php $_GET variable:

<?php
  $block = $GET["list"];
?>


In the php script, the javascript lines above are generated with an embedded bit of php code (as below). This makes it possible for me to deploy different experiments (that just differ in the list of sound files that will be played), using the same php script. The script constructs different list file names on the fly from the "list" variable that is given in the URL.

<script src="js/audexp.js"></script>
<script src="js/block<?php echo $block; ?>_list.js"></script>


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

  • this call specifies the type of experiment (in the script below this is '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 four span elements that will be used to give feedback to listeners.

  • Show warnings to the listener
<span id="wr"></span>
  • indicate that an audio file is playing
<span id="f1">sound 1</span>
  • indicate that a second audio file is playing (for ax, and cr type experiments)
<span id="f2">sound 2</span>
  • give feedback to the lister, showing which key they pressed.
<span id="key">#</span>

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>

The experiment php script linked at the top of this page generated a unique subject number for the user with a little php code:

<?php
   $block = $_GET["list"];
   $subj = uniqid($block);
?>

This subject number will start with the word or number that you passed to the script as 'list' in the url (http:\\linguistics.berkeley.edu\~kjohnson\rate_exp.php?list=test).


Saving data to a server file

Finally, in (4) above you may have noticed there was reference to a file: process.php. Here is that file.


<?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";
}
?>
  • This script 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


  • You can read the data file directly into R from your server address:
data <- read.csv("http://linguistics.berkeley.edu/~kjohnson/talkers/id_data.csv",header=TRUE);