function fft_ifft_lock( filePath, fileName )
%--------------------------------------------------------------------------
% FFT to IFFT Phase-Locked Vocoder
%
% Cooper Baker - 2014
%--------------------------------------------------------------------------
close all;
% Settings
%--------------------------------------------------------------------------
windowSize = 1024;
overlap = 4;
stretchFactor = 2;
window = hann( windowSize, 'periodic' );
tag = 'lock';
% Initializations
%--------------------------------------------------------------------------
if any( exist( 'fileName' ) ~= 1 )
[ fileName, filePath ] = uigetfile( '*.wav', 'Audio File' );
end
[ input, sr ] = audioread( [ filePath, fileName ] );
hopSize = windowSize / overlap;
sampleHopSize = hopSize / stretchFactor;
input = [ zeros( windowSize, 1) ; input ; zeros( windowSize - mod( length( input ), windowSize ), 1 ) ];
output = zeros( windowSize + length( input ) * stretchFactor, 1 );
frameIndex = 1;
frameMax = length( output ) - windowSize;
sampleIndex = 1;
sampleMax = length( input ) - windowSize - hopSize;
spec = zeros( windowSize, 1 );
% create progress bar dialog box
bar = waitbar( 0, '0%', 'Name', sprintf( '%s: processing %s...', mfilename, fileName ) );
% Processing Loop
%--------------------------------------------------------------------------
while sampleIndex < sampleMax;
% copy and window the input frames
frameBack = input( sampleIndex + 1 : sampleIndex + windowSize ) .* window;
frameFront = input( sampleIndex + 1 + hopSize : sampleIndex + windowSize + hopSize ) .* window;
% perform an fft on the input frame
specBack = fft( frameBack );
specFront = fft( frameFront );
% save previous spec and add salt
specOld = spec + realmin;
% calculate phase accumulation
specPhase = ( conj( specBack ) .* specOld ) ./ abs( specOld );
% calculate phase locked spectrum
specPhaseLock = circshift( specPhase, 1 ) + specPhase + circshift( specPhase, -1 );
% perform phase vocoding
% phase lock
spec = ( specPhaseLock .* specFront ) ./ abs( specPhaseLock + realmin );
% no phase lock
% spec = ( specPhase .* specFront ) ./ abs( specPhase + realmin );
% perform an ifft on the spectrum
frame = ifft( spec );
% discard imaginary data
frame = real( frame );
% apply the window
frame = frame .* window;
% overlap-add the frame into the output buffer
output( frameIndex + 1 : frameIndex + windowSize ) = output( frameIndex + 1 : frameIndex + windowSize ) + frame;
% increment location indices
sampleIndex = sampleIndex + sampleHopSize;
frameIndex = frameIndex + hopSize;
% update the progress bar
progress = ( sampleIndex / sampleMax );
waitbar( progress, bar, sprintf( '%2.3f%%', progress * 100 ) )
end
% close progress bar dialog box
close( bar );
% Output
%--------------------------------------------------------------------------
% crop output buffer
output = output( windowSize + 1 : length( output ) );
% normalize output buffer
normCoeff = 1 / max( abs( output ) );
output = output * normCoeff;
% plot output
timevector = linspace( 0, length( output )/sr, length( output ) );
plot( timevector, output );
% create comment string
commentString = sprintf( 'WinSize: %.0f,\nOverlap: %.0f,\nStretch: %.2f,\nWindow: %s', windowSize, overlap, stretchFactor, 'Hann' );
% write audio file to disk
[ a, fileName, b ] = fileparts( fileName );
outFile = sprintf( '%s.%s.wav', fileName, tag );
audiowrite( outFile, output, sr, 'BitsPerSample', 32, 'Artist', 'NormCoeff', 'Title', num2str( normCoeff ), 'Comment', commentString );
% EOF
%--------------------------------------------------------------------------
% FFT to IFFT Phase-Locked Vocoder
%
% Cooper Baker - 2014
%--------------------------------------------------------------------------
close all;
% Settings
%--------------------------------------------------------------------------
windowSize = 1024;
overlap = 4;
stretchFactor = 2;
window = hann( windowSize, 'periodic' );
tag = 'lock';
% Initializations
%--------------------------------------------------------------------------
if any( exist( 'fileName' ) ~= 1 )
[ fileName, filePath ] = uigetfile( '*.wav', 'Audio File' );
end
[ input, sr ] = audioread( [ filePath, fileName ] );
hopSize = windowSize / overlap;
sampleHopSize = hopSize / stretchFactor;
input = [ zeros( windowSize, 1) ; input ; zeros( windowSize - mod( length( input ), windowSize ), 1 ) ];
output = zeros( windowSize + length( input ) * stretchFactor, 1 );
frameIndex = 1;
frameMax = length( output ) - windowSize;
sampleIndex = 1;
sampleMax = length( input ) - windowSize - hopSize;
spec = zeros( windowSize, 1 );
% create progress bar dialog box
bar = waitbar( 0, '0%', 'Name', sprintf( '%s: processing %s...', mfilename, fileName ) );
% Processing Loop
%--------------------------------------------------------------------------
while sampleIndex < sampleMax;
% copy and window the input frames
frameBack = input( sampleIndex + 1 : sampleIndex + windowSize ) .* window;
frameFront = input( sampleIndex + 1 + hopSize : sampleIndex + windowSize + hopSize ) .* window;
% perform an fft on the input frame
specBack = fft( frameBack );
specFront = fft( frameFront );
% save previous spec and add salt
specOld = spec + realmin;
% calculate phase accumulation
specPhase = ( conj( specBack ) .* specOld ) ./ abs( specOld );
% calculate phase locked spectrum
specPhaseLock = circshift( specPhase, 1 ) + specPhase + circshift( specPhase, -1 );
% perform phase vocoding
% phase lock
spec = ( specPhaseLock .* specFront ) ./ abs( specPhaseLock + realmin );
% no phase lock
% spec = ( specPhase .* specFront ) ./ abs( specPhase + realmin );
% perform an ifft on the spectrum
frame = ifft( spec );
% discard imaginary data
frame = real( frame );
% apply the window
frame = frame .* window;
% overlap-add the frame into the output buffer
output( frameIndex + 1 : frameIndex + windowSize ) = output( frameIndex + 1 : frameIndex + windowSize ) + frame;
% increment location indices
sampleIndex = sampleIndex + sampleHopSize;
frameIndex = frameIndex + hopSize;
% update the progress bar
progress = ( sampleIndex / sampleMax );
waitbar( progress, bar, sprintf( '%2.3f%%', progress * 100 ) )
end
% close progress bar dialog box
close( bar );
% Output
%--------------------------------------------------------------------------
% crop output buffer
output = output( windowSize + 1 : length( output ) );
% normalize output buffer
normCoeff = 1 / max( abs( output ) );
output = output * normCoeff;
% plot output
timevector = linspace( 0, length( output )/sr, length( output ) );
plot( timevector, output );
% create comment string
commentString = sprintf( 'WinSize: %.0f,\nOverlap: %.0f,\nStretch: %.2f,\nWindow: %s', windowSize, overlap, stretchFactor, 'Hann' );
% write audio file to disk
[ a, fileName, b ] = fileparts( fileName );
outFile = sprintf( '%s.%s.wav', fileName, tag );
audiowrite( outFile, output, sr, 'BitsPerSample', 32, 'Artist', 'NormCoeff', 'Title', num2str( normCoeff ), 'Comment', commentString );
% EOF