THE AUDITORY MODELING TOOLBOX

Applies to version: 1.6.0

View the help

Go to function

sig_barumerli2024
Spatialization of sound sources as FrAMBI examples

Program code:

function [environment, options] = sig_barumerli2024(flag, options)
%sig_barumerli2024 Spatialization of sound sources as FrAMBI examples
%
%   Usage: [environment, options] = sig_barumerli2024(flags, options)
%
%   Input parameters:
%     flag    : String describing the type of the environment:
%
%               - 'horizontal': Spatializes a sound source in the horizontal 
%                 plane. It is used by the agent BARUMERLI2024_ITDLATERAL.
%
%               - 'mockup': A mockup of spatialization in the vertical plane. 
%                 It is used by the agent BARUMERLI2024_MOCKUP.
%
%     options : Optional structure representing the FrAMBI options.
%
%   Output parameters:
%     environment: Structure representing the FrAMBI environment. See the 
%                  general description of FrAMBI for more details. In 
%                  addition, the following environment-specific fields are 
%                  created: 
%
%                  - name*: String describing the environment. Default: 
%                    The string from flag.
%
%                  - model*: Structure defining the functionality of the
%                    environment by storing functions handles in fields 
%                    initialize, execute, and conclude. 
%
%                  - state.parameters*: Parameter structure as in FRAMBI_PARAMETERS 
%                    storing the states of the evironment:
%
%                    - angle*: The sound source angle (in degrees).
%                      Default: 0 degrees. 
%
%                    - duration*: The duration (in s) of the sound. 
%                      Used in the 'horizontal' environment only. 
%                      Default: 150 ms. 
%
%                    - angular_speed*: The angular speed (in degrees/s) of 
%                      the sound source. 
%                      Used in the 'horizontal' environment only. 
%                      Default: 0 degrees/s, i.e., stationary source. 
%
%                    - time_increment*: The duration between the looks 
%                      updating the source movement. 
%                      Used in the 'horizontal' environment only. 
%                      Default: 150 ms, i.e., a single look. 
%                  
%                  - hrtf*: SOFA structure storing the HRTF set used for 
%                    the spatialization. 
%                    Used in the 'horizontal' environment only. 
%
%                  - sound.fs*: Sampling rate (in Hz) of the HRTF set. It is 
%                    used as the sampling rate of the sound. 
%                    Used in the 'horizontal' environment only. 
%
%     options :  Structure representing the FrAMBI options. No agent-specific 
%                fields are added.
%
%
%   SIG_BARUMERLI2024('horizontal',..) generates a FrAMBI environment simulating
%   a sound source rotating in the horizontal plane. The sound is spatialized 
%   using a preloaded HRTF set. The environment updates the source position 
%   over time according to the specified angular speed and sound duration. 
%   Note that to reduce computational time, the spatialization is done at 
%   the initialization of the environment for all source angles. 
%   It defines the following functionality linked with local functions: 
%
%   - model.initialize is linked with local_initialize, in which 
%     the sound for the whole trial is generated (as a 
%     white-noise burst) and spatialized. The sound is stored as sound.signal. 
%     Further, the simulation time is reset and stored as time. 
%
%   - model.execute is linked with local_execute, in which the chunk of 
%     the sound to be observed by the agent 
%     is returned as output.signal together with the sampling rate 
%     as output.fs. Further, the hidden environmental states such as 
%     the source angle and time are updated. 
%
%   - model.conclude is linked with local_conclude, in which the 
%     environment concludes whether the trial has reached its end. 
%     It returns true if the time passes the sound duration.
%
%   SIG_BARUMERLI2024('mockup',..) generates a FrAMBI environment as a  mockup 
%   for the vertical-plane sound-source localization. In this mockup, 
%   the source angle is directly accessible by the agent, which then 
%   does not need to infer it at all. The mockup uses the model.execute functionality
%   only which is linked with local_execute_mockup. It returns the angle 
%   of the source directly as the output to the agent. This results in fast 
%   simulation useful for educational purposes only. 
%
%
%   See also: exp_barumerli2024 frambi_simulate barumerli2024_itdlateral barumerli2024_mockup
%
%   References:
%     R. Barumerli and P. Majdak. FrAMBI: A Software Framework for Auditory
%     Modeling Based on Bayesian Inference. under review at Neuroinformatics,
%     2024.
%     
%
%   Url: http://amtoolbox.org/amt-1.6.0/doc/signals/sig_barumerli2024.php


%   #Requirements: MATLAB SOFA
%   #Author: Roberto Barumerli (2023): Original implemenation. 
%   #Author: Piotr Majdak (2024): Initial implementation based on barumerli2024_dynamic from see https://gitlab.com/robaru/amt_clone/-/tree/frambi_release
%   #Author: Roberto Barumerli (2024): Further integration in AMT and documentation. 
%   #Author: Piotr Majdak (2024): Adaptations for the AMT 1.6.

% This file is licensed unter the GNU General Public License (GPL) either 
% version 3 of the license, or any later version as published by the Free Software 
% Foundation. Details of the GPLv3 can be found in the AMT directory "licences" and 
% at <https://www.gnu.org/licenses/gpl-3.0.html>. 
% You can redistribute this file and/or modify it under the terms of the GPLv3. 
% This file is distributed without any warranty; without even the implied warranty 
% of merchantability or fitness for a particular purpose. 

if ~exist('options','var'), options=[]; end

switch flag
	case 'horizontal'
%% define the environment with a source in the horizontal plane
    environment.name = 'horizontal';
    
    % parameters
    params = frambi_parameters('init', struct);
    
    params = frambi_parameters('set', params, {'angle'}, 0); % default: direction at the front
    params = frambi_parameters('set', params, {'duration'}, .15); 
    params = frambi_parameters('set', params, {'angular_speed'}, 0); % default: stationary sound source
    params = frambi_parameters('set', params, {'time_increment'}, params.duration.value); % default: one increment
    
    environment.state.parameters = params;     
    
      % additional state's values
    hrtf = amt_load('barumerli2024', 'Kemar_HRTF_sofa.sofa');
    environment.state.hrtf = hrtf;
    environment.state.sound.fs = hrtf.Data.SamplingRate; % fs of the HRTFs => fs of the sound      
      % add functions
    environment.model.initialize = @local_initialize;
    environment.model.execute = @local_execute;
    environment.model.conclude = @local_conclude;
      % validate structure 
    options=frambi_validate(options);
    environment=frambi_validate(environment);

	case 'mockup'
%% define the mockup environment
    environment.name = 'mockup';
      % add state and parameters
    environment.state.parameters = frambi_parameters('init', struct, {'angle'}, 0);		
      % define functions
    environment.model.execute = @local_execute_mockup; % it's a mockup: the environment passes its state as ouput to the agent
      % validate structures
    options=frambi_validate(options);
    environment=frambi_validate(environment);
end % end of main

%% horizontal environment: intialize 
function estate = local_initialize(estate)
      % generate the sound of the source
    source = randn(estate.parameters.duration.value * estate.sound.fs, 1); 
      % calculate the end angle of the moving source
    angle_end = estate.parameters.angular_speed.value * estate.parameters.duration.value + estate.parameters.angle.value;
      % spatialize the sound emitted by a moving source
    estate.sound.signal = SOFAspat(source, estate.hrtf, [estate.parameters.angle.value, angle_end], 0); 
      % reset the time
    estate.time = 0; 

%% horizontal environment: execute 
function [estate] = local_execute(estate, action, options)
      % generate output
    time_idx = round(estate.time*estate.sound.fs + (1:estate.parameters.time_increment.value*estate.sound.fs));
    estate.output.signal = estate.sound.signal(time_idx,:);
    estate.output.fs = estate.sound.fs;
      % increment time 
    estate.time = estate.time + estate.parameters.time_increment.value;
      % update source's direction 
    estate.angle = estate.parameters.angular_speed.value * estate.time + estate.parameters.angle.value;      

%% horizontal environments: conclude 
function stop = local_conclude(estate, options)
      % the rounding prevents numerical errors
    stop = (estate.time + estate.parameters.time_increment.value) > estate.parameters.duration.value;

%% mockup environment: execute
function [estate] = local_execute_mockup(estate, action, options)
    estate.output = estate.parameters.angle.value;