from A/B comparison listening test script by Evan Ruzanski
This script M file automates and manages a double-blind AB comparison test.

comparison.m
% MP3 vs. CD-quality blind A/B comparison across different genres of music
%   Follow on-screen instructions.  Saves .csv file to working directory
%
% AUTHOR: Evan Ruzanski, UCSB, 2/23/2003

clear all
clc
format short g

% Build track selection matrix (5 X 6*(7)) of genre and bitrate strings as follows: 
%----------------------------------------------------------------------------------------------
% Genre                     1.4Mbps     192kbps     128kbps     96kbps      64kbps      32kbps 
%----------------------------------------------------------------------------------------------
% Classical (Nocturne)      CH0         CH1         CH2         CH3         CH4         CH5
% Classical (Capriccio)     BA0         BA1         BA2         BA3         BA4         BA5
% Soft Rock                 BJ0         BJ1         BJ2         BJ3         BJ4         BJ5
% Hard Rock                 KO0         KO1         KO2         KO3         KO4         KO5
% Rap                       BI0         BI1         BI2         BI3         BI4         BI5                   
%----------------------------------------------------------------------------------------------

S=[1:7]; % Choose storage array for string lengths = file name lengths

M(1,S) = 'CH0.wav';                 % <- CHANGE THESE FILE NAMES TO THE NAMES OF THE DESIRED FILES TO TEST
M(1,1*length(S)+S) = 'CH1.wav';     % KEEP FILENAME LENGTHS THE SAME AS THESE
M(1,2*length(S)+S) = 'CH2.wav';
M(1,3*length(S)+S) = 'CH3.wav';
M(1,4*length(S)+S) = 'CH4.wav';
M(1,5*length(S)+S) = 'CH5.wav';

M(2,S) = 'BA0.wav';
M(2,1*length(S)+S) = 'BA1.wav';
M(2,2*length(S)+S) = 'BA2.wav';
M(2,3*length(S)+S) = 'BA3.wav';
M(2,4*length(S)+S) = 'BA4.wav';
M(2,5*length(S)+S) = 'BA5.wav';

M(3,S) = 'BJ0.wav';
M(3,1*length(S)+S) = 'BJ1.wav';
M(3,2*length(S)+S) = 'BJ2.wav';
M(3,3*length(S)+S) = 'BJ3.wav';
M(3,4*length(S)+S) = 'BJ4.wav';
M(3,5*length(S)+S) = 'BJ5.wav';

M(4,S) = 'KO0.wav';
M(4,1*length(S)+S) = 'KO1.wav';
M(4,2*length(S)+S) = 'KO2.wav';
M(4,3*length(S)+S) = 'KO3.wav';
M(4,4*length(S)+S) = 'KO4.wav';
M(4,5*length(S)+S) = 'KO5.wav';

M(5,S) = 'BI0.wav';
M(5,1*length(S)+S) = 'BI1.wav';
M(5,2*length(S)+S) = 'BI2.wav';
M(5,3*length(S)+S) = 'BI3.wav';
M(5,4*length(S)+S) = 'BI4.wav';
M(5,5*length(S)+S) = 'BI5.wav';

% Create actual play vs. choice play(ed) matrices
Q(5,6) = 0; % "In CD vs. <this bitrate (col)>, in which position was the CD played?"
P(5,6) = 0; % "In CD vs. <this bitrate (col)>, the CD was chosen to be in this position."

%Display instructions to user
disp('Listen carefully to the following 25 pairs of music segments.  After each segment is complete, you will       ');
disp('be asked to press ENTER to continue.  After the second selection, you will be asked to choose which segment   ');
disp('played was the CD file and which was the MP3 file.  Select your choice by entering a "1" or "2", with         ');
disp('a "1" selection stating the first segment played was the CD track and a "2" stating the second track was the  ');
disp('CD track. Assume the CD file to be of higher quality.  Press ENTER after your choice.  Have fun!              ');
disp('                                                                                                              ');
disp('Press ENTER to begin');

pause

% Begin experiment
for k = 1:25
    
    g = 1; % Create matrix test variable
    while g == 1, 
        c = ceil(5*rand(1)); % Generate random number between 1 and 5 for row (genre) selection
        d = ceil(5*rand(1))+1; % Generate random number between 2 and 6 for column (bitrate) selection
        
        if P(c,d) == 0 % Avoid repetition
            [x,fsx] = wavread(char(M(c,S))); % CD track
            [y,fsy] = wavread(char(M(c,(d-1)*length(S)+S))); % MP3 track
            
            z = rand(1)-0.5; % Generate random number for CD position
            if z >= 0
                Q(c,d) = 1;
                wavplay(x,fsx);
                disp('Press ENTER to hear the second segment')
                pause
                wavplay(y,fsy);
            else
                Q(c,d) = 2;
                wavplay(y,fsy);
                disp('Press ENTER to hear the second segment')
                pause
                wavplay(x,fsx);
            end % END IF
            
            while (P(c,d) ~= 1) & (P(c,d) ~= 2) % Ensure valid user input
                P(c,d) = input('Which segment was the CD track? ');
            end % END WHILE
            
            g=0;
        end % END IF
    end % END WHILE
    
    disp('                                                                                                              ');
    disp('Press ENTER to continue')
    pause
    disp('                                                                                                              ');
   
end

disp('This concludes the test.  Thank you.')
pause

% LOAD saved array of previous results (NB: ensure file is not currently in use)
R = csvread('results.csv');

index = 1;
for u = 1:5 % Append column array via recursion
    for v = 1:6
        R(index,1) = R(index,1) + abs(Q(u,v)-P(u,v));
        index = index + 1;
    end
end
R(31,1) = R(31,1) + 1; % Update experiment iteration numbe

% SAVE array of updated results (column array), keeps R variable active in current workspace
save('results.csv','R','-ASCII')

% Get accumulated P(E) matrix
PofE = R./R(31,1);

% OPTIONAL (comment or modify as necessary): Plot updated results
br = [192 128 96 64 32];
figure(1)
stem(br,R(2:6))
eval(['title(''Experimental Results for Classical (Nocturne) for ', num2str(R(31,1)),' runs'')'])
xlabel('kbps');ylabel('Accumulated # of incorrect selections');grid;
axis([0 200 0 R(31,1)])

figure(2)
stem(br,R(8:12))
eval(['title(''Experimental Results for Classical (Capriccio) for ', num2str(R(31,1)),' runs'')'])
xlabel('kbps');ylabel('Accumulated # of incorrect selections');grid;
axis([0 200 0 R(31,1)])

figure(3)
stem(br,R(14:18))
eval(['title(''Experimental Results for Soft Rock for ', num2str(R(31,1)),' runs'')'])
xlabel('kbps');ylabel('Accumulated # of incorrect selections');grid;
axis([0 200 0 R(31,1)])

figure(4)
stem(br,R(20:24))
eval(['title(''Experimental Results for Heavy Metal for ', num2str(R(31,1)),' runs'')'])
xlabel('kbps');ylabel('Accumulated # of incorrect selections');grid;
axis([0 200 0 R(31,1)])

figure(5)
stem(br,R(26:30))
eval(['title(''Experimental Results for Rap for ', num2str(R(31,1)),' runs'')'])
xlabel('kbps');ylabel('Accumulated # of incorrect selections');grid;
axis([0 200 0 R(31,1)])

% EOF "comparison.m"

    

Contact us at files@mathworks.com