part 01b:

A second source moves counter-clockwise at a constant speed, making a full rotation in 1 second. Synthesize 2 seconds of the received binaural signal.

approach:

To get the sound source to rotate in a counter-clockwise direction (opposite from part 01a), the only changes needed are swapping the channels being read from the HRTF data.

code:

function [signal_full] = project_02_part01b(fs, rotation_time, rotations, number_of_measurements)

%comment out fs, rotation_time, rotations, and number_of_measurements to specify values from command line
fs = 44100;                     %sampling rate
rotation_time = 1;              %time it takes in seconds for a full rotation
secs = rotation_time/2;         %time it takes for half a rotation (from 0 to 180 degrees)
rotations = 2;                  %number of rotations to perform (use whole numbers only!)
elev = 0;                       %elevation angle remains 0 for this simulation
azim = 0;                       %azimuth angle of 0 = directly in front of observer; positive degrees rotate clockwise
number_of_measurements = 37;    %37 HRTF measurements are provided, from 0 to 180 degrees, in 5 degree increments

total_samples = fs*secs;
chunk_size = floor(total_samples/number_of_measurements);               %number of samples to split each noise chunk into
leftover_samples = total_samples - chunk_size*number_of_measurements;   %number of samples left over after rounding chunk_size

noise = randn(1,fs*secs);

i = 0;
N_start = 1;
%a convolved signal has a length of length(N)+length(M)-1:
%with overlap-add, the length of the final signal will be the length of the
%entire noise signal (total_samples), plus the length of M (128), minus 1
signal360to180 = zeros(2,total_samples+128-1);
while i < number_of_measurements
    N = noise(N_start:N_start+chunk_size-1);
    
    %appends leftover samples to last N chunk
    if (leftover_samples > 0) && (i == number_of_measurements-1)
        N = noise(N_start:N_start+chunk_size-1 + leftover_samples);
        %leftovers_plus_N_length = length(N);
    end
    
    M = readhrtf(elev,azim,'H');
    %swap reading of left and right channels of HRTF data to move sound in
    %CCW manner
    M_left = M(2,:);
    M_right = M(1,:);
    
    %convolve noise and HRTF data
    signal360to180_left = conv(N,M_left);
    signal360to180_right = conv(N,M_right);

    %overlap-add
    signal360to180(1,N_start:N_start+length(N)+length(M)-2) = signal360to180(1,N_start:N_start+length(N)+length(M)-2) + signal360to180_left;
    signal360to180(2,N_start:N_start+length(N)+length(M)-2) = signal360to180(2,N_start:N_start+length(N)+length(M)-2) + signal360to180_right;
    
    %increment variables
    N_start = N_start + chunk_size;
    azim = azim + 5;
    i = i + 1;
end

signal_full = zeros(2*rotations*length(signal360to180),2);

%copy signal360to180 (first half rotation) to signal_full
signal_full(1:length(signal360to180),1) = signal360to180(1,:);
signal_full(1:length(signal360to180),2) = signal360to180(2,:);

%create 2nd half rotation of signal_full
%swapping the channels causes the sound to move from 0 back to 180 degrees CW
%fliplr (reverse matrix order) then causes the sound to move from 180 to 0 degrees CCW as intended
signal_full(length(signal360to180)+1:2*length(signal360to180),1) = fliplr(signal360to180(2,:));
signal_full(length(signal360to180)+1:2*length(signal360to180),2) = fliplr(signal360to180(1,:));

%copies full rotation as many times as needed
for i = 2:rotations
    signal_full((i*2-2)*length(signal360to180)+1:(i*2)*length(signal360to180),1) = signal_full(1:2*length(signal360to180),1);
    signal_full((i*2-2)*length(signal360to180)+1:(i*2)*length(signal360to180),2) = signal_full(1:2*length(signal360to180),2);
end

subplot(211), plot(signal_full(:,1),'Color',[1,0.12,0.12]), grid on, axis tight;
title('Left channel'), xlabel('time (samples)'), ylabel('amplitude');
subplot(212), plot(signal_full(:,2),'g'), grid on, axis tight;
title('Right channel'), xlabel('time (samples)'), ylabel('amplitude');

%double max(max()) needed, because max() on a matrix returns a row vector
signal_full = signal_full/max(max(abs(signal_full))); %normalizes input

%print project_02_part01b -dpng -r100;
%wavwrite(signal_full,fs,'project_02_part01b');

soundsc(signal_full,fs);
        

graphs:

project_02_part01b.png

files:

project_02_part01b.m
project_02_part01b.wav