-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathroboticdistortion.m
More file actions
55 lines (43 loc) · 1.68 KB
/
Copy pathroboticdistortion.m
File metadata and controls
55 lines (43 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
function [outputSignal, Fs] = roboticdistortion(inputFile)
if nargin < 1
inputFile = 'inputfiles/voice-sample.wav'; % fallback
end
[audio, fs] = audioread(inputFile);
audio = audio(:,1);
audio = audio / max(abs(audio)); % Normalize
windowSize = 1024; % FFT size
hopSize = windowSize / 4; % Overlap, 75%
shiftAmount = 0.001; % how much we shift the frequencies, smaller=more natural
phaseRand = 0.3; % phase randomization amount
% Process with STFT
numWindows = floor((length(audio) - windowSize)/hopSize) + 1;
output = zeros(size(audio));
for i = 1:numWindows
startIdx = (i-1)*hopSize + 1;
frame = audio(startIdx:startIdx+windowSize-1);
% Apply window
win = hamming(windowSize);
frameWindowed = frame .* win;
% DFT
F = fft(frameWindowed);
% robotic core code
shift = round(length(F) * shiftAmount); % shift by shiftAmount% of spectrum
F_robot = [F(shift+1:end); zeros(shift,1)]; % simple shift
mag = abs(F_robot);
% uncomment one of the two lines below for random or zero phase
% phase = angle(F_robot) + (rand(size(F_robot))-0.5)*phaseRand; % random phase
phase = zeros(size(F_robot)); % zero phase instead of random, for more robotic sound
F_robot = mag .* exp(1j * phase);
% Inverse DFT
frameOut = real(ifft(F_robot));
frameOut = frameOut .* win; % window again
% Overlap-add
output(startIdx:startIdx+windowSize-1) = output(startIdx:startIdx+windowSize-1) + frameOut;
end
% Normalize
output = output / max(abs(output));
% Save output
audiowrite('outputs/robotic_voice.wav', output, fs);
outputSignal = audioread('outputs/robotic_voice.wav');
[~, Fs] = audioread(inputFile);
end