Difference between revisions of "Ripple Sounds"

From biophysics
Jump to navigation Jump to search
Line 81: Line 81:
 
</pre>
 
</pre>
  
N.B. It is important that pinkNoise_time in the last line is the same as in the first line. If you instead call the function pinknoise again in the last line it gives a wrong result.
+
N.B. It is important that you call the function 'pinknoise' only once and store the result. If you instead call the function pinknoise again in the last line it gives a wrong result, because each call creates a new random array. This destroys the necessary interference in the last line.
  
 
===Band filter method===
 
===Band filter method===

Revision as of 11:14, 16 August 2024

Introduction

%todo

FFT-iFFT method

Below is an example of an implementation in matlab. It is based on a broadband signal consisting of pink noise. The input parameters are:

Term Description
t time domain array in seconds
octaves frequency domain array in octaves
ripples_per_sec the ripple velocity in the time domain
phi a phase that can be added to the time modulation
ripples_per_octave the ripple density in the frequency domain
rippleType determines if the ripple is ascending or descending
modulationDepth half the amplitude of the modulation


The variables that are sin modulated are denoted by the prefix 'sin_', the cos modulated by the prefix 'cos_'.
The variables in the time domain are denoted by the suffix '_time' and variables in the frequency domain by the suffix '_freq'.

% Generate array with pink noise
pinkNoise_time = pinknoise(length(t));

% Create modulation functions for time domain (velocity modulation)
sin_modulation_time = sin(2 * pi * ripples_per_sec * t + phi);
cos_modulation_time = cos(2 * pi * ripples_per_sec * t + phi);        

% Create modulation functions for frequency domain (density modulation)
sin_modulation_freq = sin(2 * pi * ripples_per_octave * octaves);
cos_modulation_freq = cos(2 * pi * ripples_per_octave * octaves);
    
% Mirror the frequency modulation components for ifft compatibility
sin_modulation_freq = [sin_modulation_freq, fliplr(sin_modulation_freq)];
cos_modulation_freq = [cos_modulation_freq, fliplr(cos_modulation_freq)];

% Apply time modulation to pink noise in the time domain
sin_modulatedNoise_time = sin_modulation_time .* pinkNoise_time;
cos_modulatedNoise_time = cos_modulation_time .* pinkNoise_time;

% Perform fft to convert the signals to the frequency domain
sin_modulatedNoise_freq = fft(sin_modulatedNoise_time);
cos_modulatedNoise_freq = fft(cos_modulatedNoise_time);
  
% Apply frequency modulation in the frequency domain 
sin_rippledNoise_freq = sin_modulation_freq .* sin_modulatedNoise_freq;
cos_rippledNoise_freq = cos_modulation_freq .* cos_modulatedNoise_freq;   

% Perform ifft to get rippled noise in the time domain
sin_rippledNoise_time = ifft(sin_rippledNoise_freq, 'symmetric');
cos_rippledNoise_time = ifft(cos_rippledNoise_freq, 'symmetric');

% Determine the ripple type (ascending vs. descending)
switch rippleType
    case 'ascending'
        combinedRippledNoise_time = sin_rippledNoise_time + cos_rippledNoise_time;
    case 'descending'
        combinedRippledNoise_time = sin_rippledNoise_time - cos_rippledNoise_time;
end 

% Calculate the final rippled stimulus in the time domain          
rippledStimulus_time = pinkNoise_time + modulationDepth * combinedRippledNoise_time;

N.B. It is important that you call the function 'pinknoise' only once and store the result. If you instead call the function pinknoise again in the last line it gives a wrong result, because each call creates a new random array. This destroys the necessary interference in the last line.

Band filter method

%todo

References

% todo