changeset 209:538322113524 Dev_main

Merge from the default branch
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Tue, 16 Jun 2015 14:14:08 +0100
parents d12dbbab3565 (current diff) 43dc4a1c3adf (diff)
children 7658d51a9ccb
files ape.js core.js example_eval/project.xml
diffstat 8 files changed, 193 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/ape.js	Thu Jun 11 10:06:58 2015 +0100
+++ b/ape.js	Tue Jun 16 14:14:08 2015 +0100
@@ -255,9 +255,7 @@
 		var trackURL = audioHolderObject.hostURL + element.url;
 		var audioObject = audioEngineContext.newTrack(element);
 		
-		if (commentShow) {
-			var node = interfaceContext.createCommentBox(audioObject);
-		}
+		var node = interfaceContext.createCommentBox(audioObject);
 		
 		// Create a slider per track
 		audioObject.interfaceDOM = new sliderObject(audioObject);
--- a/core.js	Thu Jun 11 10:06:58 2015 +0100
+++ b/core.js	Tue Jun 16 14:14:08 2015 +0100
@@ -1100,8 +1100,14 @@
 {
 	// This takes an array of information and randomises the order
 	var N = input.length;
-	var K = N;
+	
+	var inputSequence = []; // For safety purposes: keep track of randomisation
+	for (var counter = 0; counter < N; ++counter) 
+		inputSequence.push(counter) // Fill array
+	var inputSequenceClone = inputSequence.slice(0);
+	
 	var holdArr = [];
+	var outputSequence = [];
 	for (var n=0; n<N; n++)
 	{
 		// First pick a random number
@@ -1110,7 +1116,11 @@
 		r = Math.floor(r*input.length);
 		// Pick out that element and delete from the array
 		holdArr.push(input.splice(r,1)[0]);
+		// Do the same with sequence
+		outputSequence.push(inputSequence.splice(r,1)[0]);
 	}
+	console.log(inputSequenceClone.toString()); // print original array to console
+	console.log(outputSequence.toString()); 	// print randomised array to console
 	return holdArr;
 }
 
--- a/example_eval/project.xml	Thu Jun 11 10:06:58 2015 +0100
+++ b/example_eval/project.xml	Tue Jun 16 14:14:08 2015 +0100
@@ -12,7 +12,7 @@
 				<option id="player">Play an instrument</option>
 			</checkbox>
 			<number id="age" min="0">Please enter your age</number>
-			<statement>Please listen to all mixes</statement>
+			<statement>Please listen to all fragments</statement>
 		</PreTest>
 		<PostTest>
 			<question id="SessionID" mandatory="true">Please enter your name.</question>
@@ -35,7 +35,7 @@
 			<metricEnable>elementListenTracker</metricEnable>
 		</Metric>
 	</setup>
-	<audioHolder id='0' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='0' loop='true' elementComments='true'>
+	<audioHolder id='test-0' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='0' loop='true' elementComments='true'>
 		<interface>
 			<title>Example Test Question</title>
 			<scale position="0">Min</scale>
@@ -69,12 +69,53 @@
 			<option name="bright">Bright</option>
 			<option name="punchy">Punchy</option>
 			<option name="dark">Dark</option>
-			<option name="moody">Moody</option>
-			<option name="dull">Dull</option>
+			<option name="muddy">Muddy</option>
+			<option name="thin">Thin</option>
 		</CommentQuestion>
 		<PreTest/>
 		<PostTest>
-			<question id="genre" mandatory="true">Please enter the genre</question>
+			<question id="genre" mandatory="true">Please enter the genre.</question>
 		</PostTest>
 	</audioHolder>
+    <audioHolder id='test-1' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='0' loop='true' elementComments='true'>
+        <interface>
+            <title>Example Test Question</title>
+            <scale position="0">Min</scale>
+            <scale position="100">Max</scale>
+            <scale position="50">Middle</scale>
+            <scale position="75">75</scale>
+            <commentBoxPrefix>Comment on fragment</commentBoxPrefix>
+        </interface>
+        <audioElements url="0.wav" id="0"/>
+        <audioElements url="1.wav" id="1"/>
+        <audioElements url="2.wav" id="2"/>
+        <audioElements url="3.wav" id="3"/>
+        <audioElements url="4.wav" id="4"/>
+        <audioElements url="5.wav" id="5"/>
+        <audioElements url="6.wav" id="6"/>
+        <!-- <audioElements url="7.wav" id="7"/>
+         <audioElements url="8.wav" id="8"/>
+         <audioElements url="9.wav" id="9"/>
+         <audioElements url="10.wav" id="10"/>-->
+        <CommentQuestion id='mixingExperience' type="text">What is your mixing experience?</CommentQuestion>
+        <CommentQuestion id="preference" type="radio">
+            <statement>Please enter your ranking preference on this song.</statement>
+            <option name="worst">Very Bad</option>
+            <option name="bad"></option>
+            <option name="OK">OK</option>
+            <option name="Good"></option>
+            <option name="Great">Great</option>
+        </CommentQuestion>
+        <CommentQuestion id="preference" type="checkbox">
+            <statement>Describe this song</statement>
+            <option name="funky">Funky</option>
+            <option name="mellow">Mellow</option>
+            <option name="laidback">Laid back</option>
+            <option name="heavy">Heavy</option>
+        </CommentQuestion>
+        <PreTest/>
+        <PostTest>
+            <question id="genre" mandatory="true">Please enter the genre.</question>
+        </PostTest>
+    </audioHolder>
 </BrowserEvalProjectDocument>
\ No newline at end of file
--- a/scripts/comment_parser.py	Thu Jun 11 10:06:58 2015 +0100
+++ b/scripts/comment_parser.py	Tue Jun 16 14:14:08 2015 +0100
@@ -11,6 +11,9 @@
         # get list of all page names
         for audioholder in root.findall("./audioholder"):   # iterate over pages
             page_name = audioholder.get('id')               # get page name
+            
+            if page_name is None: # ignore 'empty' audio_holders
+                break
 
             # create folder [page_name] if not yet created
             if not os.path.exists(page_name):
@@ -18,21 +21,26 @@
 
             # for page [page_name], print comments related to fragment [id]
             for audioelement in root.findall("*/[@id='"+page_name+"']/audioelement"):
-                audio_id = str(audioelement.get('id'))
-                # append to file [page_name]/[page_name]-comments-[id].csv
-                with open(page_name+'/'+page_name+'-comments-'+audio_id+'.csv', 'a') as csvfile:
-                    commentstr = root.find("*/[@id='"
-                                           + page_name
-                                           + "']/audioelement/[@id='"
-                                           + audio_id
-                                           + "']/comment/response").text
-                    writer = csv.writer(csvfile, delimiter=',')
-                    writer.writerow([commentstr.encode("utf-8")])
-                    #TODO Comma doesn't act as delimiter now!
-                    # (when adding more than just a comment per line):
-                    # writer.writerow([file + ',' + commentstr.encode("utf-8")])
+                if audioelement is not None: # Check it exists
+                    audio_id = str(audioelement.get('id'))
 
-                    #TODO Replace 'new line' with something else?
+                    # append to file [page_name]/[page_name]-comments-[id].csv
+                    with open(page_name+'/'+page_name+'-comments-'+audio_id+'.csv', 'a') as csvfile:
+                        writer = csv.writer(csvfile, delimiter=',')
+                        commentstr = root.find("*/[@id='"
+                                               + page_name
+                                               + "']/audioelement/[@id='"
+                                               + audio_id
+                                               + "']/comment/response").text
+                        if commentstr is None:
+                            writer.writerow([''])
+                        else:
+                            writer.writerow([commentstr.encode("utf-8")])
+                        #TODO Comma doesn't act as delimiter now!
+                        # (when adding more than just a comment per line):
+                        # writer.writerow([file + ',' + commentstr.encode("utf-8")])
 
-                    #TODO 'Append' means duplicate entries if run several times...
+                        #TODO Replace 'new line' with something else?
 
+                        #TODO 'Append' means duplicate entries if run several times...
+
--- a/scripts/score_boxplot.py	Thu Jun 11 10:06:58 2015 +0100
+++ b/scripts/score_boxplot.py	Tue Jun 16 14:14:08 2015 +0100
@@ -67,4 +67,5 @@
         #plt.show() # show plot
         #exit()
 
-        plt.savefig(rating_folder+page_name+"-ind.png")
+        plt.savefig(rating_folder+page_name+"-box.png")
+        plt.close()
--- a/scripts/score_individual.py	Thu Jun 11 10:06:58 2015 +0100
+++ b/scripts/score_individual.py	Tue Jun 16 14:14:08 2015 +0100
@@ -8,9 +8,12 @@
 colormap = ['b', 'r', 'g', 'c', 'm', 'y', 'k'] # colormap for to cycle through
 markerlist = ["x", ".", "o", "*", "+", "v", ">", "<", "8", "s", "p"]
 
+show_legend = False
+
 # get every csv file in folder
 for file in os.listdir(rating_folder):
     if file.endswith(".csv"):
+        
         page_name = file[:-4] # file name (without extension) is page ID
 
         with open(rating_folder+file, 'r') as readfile: # read this csv file
@@ -34,7 +37,7 @@
                         )
                 increment += 1 # increase counter
                 linehandles.append(plothandle)
-                legendnames.append(subject_id)
+                legendnames.append(subject_id.decode("utf-8")) # avoid decoding problems
 
 
             plt.xlabel('Fragment')
@@ -45,16 +48,18 @@
             plt.ylabel('Rating')
             plt.ylim(0,1)
 
-            plt.legend(linehandles, legendnames,
-                       loc='upper right',
-                       bbox_to_anchor=(1.1, 1),
-                       borderaxespad=0.,
-                       numpoints=1 # remove extra marker
-                       )
+            if show_legend:
+                plt.legend(linehandles, legendnames,
+                           loc='upper right',
+                           bbox_to_anchor=(1.1, 1),
+                           borderaxespad=0.,
+                           numpoints=1 # remove extra marker
+                           )
 
             #TODO Put legend outside of box
 
             #plt.show() # show plot
             #exit()
-
+            
             plt.savefig(rating_folder+page_name+"-ind.png")
+            plt.close()
--- a/scripts/score_parser.py	Thu Jun 11 10:06:58 2015 +0100
+++ b/scripts/score_parser.py	Tue Jun 16 14:14:08 2015 +0100
@@ -18,6 +18,9 @@
         for audioholder in root.findall("./audioholder"):    # iterate over pages
             page_name = audioholder.get('id') # get page name
             #print ["DEBUG    page " + page_name]
+            
+            if page_name is None: # ignore 'empty' audio_holders
+                break
 
             file_name = 'ratings/'+page_name+'-ratings.csv' # score file name
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/timeline_view.py	Tue Jun 16 14:14:08 2015 +0100
@@ -0,0 +1,94 @@
+import xml.etree.ElementTree as ET
+import os
+import matplotlib.pyplot as plt
+
+colormap = ['b', 'r', 'g', 'c', 'm', 'y', 'k'] # colormap for to cycle through
+
+timeline_folder = 'timelines/' # folder where to store timelines, e.g. 'timelines/'
+
+
+# create timeline_folder if not yet created
+if not os.path.exists(timeline_folder):
+    os.makedirs(timeline_folder)
+
+# get every XML file in folder
+for file in os.listdir("."): # You have to put this script in folder where output XML files are.
+    if file.endswith(".xml"):
+        tree = ET.parse(file)
+        root = tree.getroot()
+        subject_id = file[:-4] # drop '.xml'
+        
+        # ONE TIMELINE PER PAGE - make new plot per page
+
+        # get list of all page names
+        for audioholder in root.findall("./audioholder"):   # iterate over pages
+            page_name = audioholder.get('id')               # get page name
+            
+            if page_name is None: # ignore 'empty' audio_holders
+                break
+
+            # SORT AUDIO ELEMENTS ALPHABETICALLY
+            audioelements = root.findall("*/[@id='"+page_name+"']/audioelement")
+            
+            data = []
+            for elem in audioelements: # from http://effbot.org/zone/element-sort.htm
+                key = elem.get("id")
+                data.append((key, elem))
+            data.sort()
+            
+            N_audioelements = len(audioelements) # number of audio elements for this page
+            increment = 0 # increased for every new audioelement
+            audioelements_names = [] # store names of audioelements
+            
+            # for page [page_name], print comments related to fragment [id]
+            for tuple in data:
+            	audioelement = tuple[1]
+                if audioelement is not None: # Check it exists
+                    audio_id = str(audioelement.get('id'))
+                    audioelements_names.append(audio_id)
+                    
+                    # for this audioelement, loop over all listen events
+                    listen_events = root.findall("*/[@id='"
+                                           + page_name
+                                           + "']/audioelement/[@id='"
+                                           + audio_id
+                                           + "']/metric/metricresult/[@name='elementListenTracker']/event")
+                    for event in listen_events:
+                        # get testtime: start and stop
+                        start_time = event.find('testtime').get('start')
+                        stop_time  = event.find('testtime').get('stop')
+                        # event lines:
+                        plt.plot([start_time, start_time], # x-values
+                            [0, N_audioelements+1], # y-values
+                            color='k'
+                            )
+                        plt.plot([stop_time, stop_time], # x-values
+                            [0, N_audioelements+1], # y-values
+                            color='k'
+                            )
+                        # plot time: 
+                        plt.plot([start_time, stop_time], # x-values
+                            [N_audioelements-increment, N_audioelements-increment], # y-values
+                            color=colormap[increment%len(colormap)],
+                            linewidth=6
+                            )
+                        
+                increment+=1
+                                           
+            #TODO: if 'nonsensical' or unknown: dashed line until next event
+            #TODO: Vertical lines for fragment looping point
+            
+            plt.title('Timeline ' + file) #TODO add song too
+            plt.xlabel('Time [seconds]')
+            plt.ylabel('Fragment')
+            plt.ylim(0, N_audioelements+1)
+            
+            #y-ticks: fragment IDs, top to bottom
+            plt.yticks(range(N_audioelements, 0, -1), audioelements_names) # show fragment names
+
+
+            #plt.show() # uncomment to show plot; comment when just saving
+            #exit()
+            
+            plt.savefig(timeline_folder+subject_id+"-"+page_name+".png")
+            plt.close()
\ No newline at end of file