Difference between revisions of "Ripple Sounds"
Line 8: | Line 8: | ||
===FFT-iFFT method=== | ===FFT-iFFT method=== | ||
+ | The FFT-iFFT method starts out with two copies of a signal (often noise) which are temporal modulated, one with a sine and one with a cosine modulation with the same frequency. In the next step the spectra are taken by performing a FFT on both modulated signals . After that, both spectra are spectral modulated respectively with a sine and a cosine. The resulting spectra are transformed back to the time domain by taking the inverse-FFT. The next step is summing both modulated signals with a + or a minus sign, resulting in upward moving or downward moving ripples. The last step is multiplying the resulting ripples with a modulation depth (0..1) and adding this to the original sound. | ||
− | Below is an example of an implementation in | + | Below is an example of an implementation in Matlab. It is based on a broadband signal consisting of pink noise. |
The input parameters are: | The input parameters are: | ||
{| class="wikitable" | {| class="wikitable" |
Revision as of 12:35, 11 September 2024
Introduction
Ripple sounds are temporal and spectral modulated sounds (or noise). They mimic some aspects of vowels. They are often used in experiments for cochlear implant users.
There are basically two methods for creating ripple sounds, which are described in detail below:
- the FFT-iFFT method
- the band-filter method
FFT-iFFT method
The FFT-iFFT method starts out with two copies of a signal (often noise) which are temporal modulated, one with a sine and one with a cosine modulation with the same frequency. In the next step the spectra are taken by performing a FFT on both modulated signals . After that, both spectra are spectral modulated respectively with a sine and a cosine. The resulting spectra are transformed back to the time domain by taking the inverse-FFT. The next step is summing both modulated signals with a + or a minus sign, resulting in upward moving or downward moving ripples. The last step is multiplying the resulting ripples with a modulation depth (0..1) and adding this to the original sound.
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 the 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 in pinkNoise_time. 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 and this will destroy the necessary interference in the last line.
Band filter method
%todo
References
% todo