function fft_bank( filePath, fileName )
%--------------------------------------------------------------------------
% FFT to Oscillator Bank Phase Vocoder
%
% adapted from:
% VX_tstretch_bank.m [DAFXbook, 2nd ed., chapter 7]
%
% Cooper Baker - 2014
%--------------------------------------------------------------------------
close all;
% Settings
%--------------------------------------------------------------------------
windowSize = 1024;
overlap = 4;
stretchFactor = 2;
window = hann( windowSize, 'periodic' );
tag = 'bank';
% Initializations
%--------------------------------------------------------------------------
if any( exist( 'fileName' ) ~= 1 )
[ fileName, filePath ] = uigetfile( '*.wav', 'Audio File' );
end
[ input, sr ] = audioread( [ filePath, fileName ] );
inputHopSize = windowSize / overlap;
synthHopSize = inputHopSize * stretchFactor;
input = [ zeros( windowSize, 1) ; input ; zeros( windowSize - mod( length( input ), windowSize ), 1 ) ];
output = zeros( windowSize + length( input ) * stretchFactor, 1 );
halfWinSize = windowSize / 2;
inputIndex = 0;
inputMax = length( input ) - windowSize;
outputIndex = 0;
magOld = zeros( halfWinSize, 1 );
phaseOld = zeros( halfWinSize, 1 );
phaseOut = zeros( halfWinSize, 1 );
synthHop = zeros( synthHopSize, 1 );
omega = 2 * pi * inputHopSize * [ 0 : halfWinSize - 1 ]' / windowSize;
% create progress bar dialog box
bar = waitbar( 0, '0%', 'Name', sprintf( '%s: processing %s...', mfilename, fileName ) );
% Processing Loop
%--------------------------------------------------------------------------
while inputIndex < inputMax;
%copy and window the input frame
inputFrame = input( inputIndex + 1 : inputIndex + windowSize ) .* window;
% perform an fft on the input frame
fullSpect = fft( inputFrame );
% copy relevant half of the spectrum
spect = fullSpect( 1 : halfWinSize );
% cartesian to polar conversion
mag = abs( spect );
phase = angle( spect );
% calculate phase delta
phaseDelta = (phase - phaseOld - omega);
phaseDelta = mod( phaseDelta + pi, -2 * pi ) + pi;
phaseDelta = phaseDelta + omega;
% calculate increments for oscillator bank interpolation
magInc = ( mag - magOld ) / synthHopSize;
phaseInc = phaseDelta / inputHopSize;
% sample by sample oscillator bank synthesis
for synthIndex = 1 : synthHopSize;
% linearly interpolate magnitude and phase
magOld = magOld + magInc;
phaseOut = phaseOut + phaseInc;
% synthesize waveform
synthHop( synthIndex ) = magOld' * cos( phaseOut );
end
% save polar values for next frame
magOld = mag;
phaseOld = phase;
phaseOut = mod( phaseOut + pi, -2 * pi ) + pi;
% normalize the frame
synthHop = synthHop / windowSize;
% concatenate synthesized audio to output buffer
output( outputIndex + 1 : outputIndex + synthHopSize ) = synthHop;
% increment location values
inputIndex = inputIndex + inputHopSize;
outputIndex = outputIndex + synthHopSize;
% update the progress bar
progress = ( inputIndex / inputMax );
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 );
% make 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 Oscillator Bank Phase Vocoder
%
% adapted from:
% VX_tstretch_bank.m [DAFXbook, 2nd ed., chapter 7]
%
% Cooper Baker - 2014
%--------------------------------------------------------------------------
close all;
% Settings
%--------------------------------------------------------------------------
windowSize = 1024;
overlap = 4;
stretchFactor = 2;
window = hann( windowSize, 'periodic' );
tag = 'bank';
% Initializations
%--------------------------------------------------------------------------
if any( exist( 'fileName' ) ~= 1 )
[ fileName, filePath ] = uigetfile( '*.wav', 'Audio File' );
end
[ input, sr ] = audioread( [ filePath, fileName ] );
inputHopSize = windowSize / overlap;
synthHopSize = inputHopSize * stretchFactor;
input = [ zeros( windowSize, 1) ; input ; zeros( windowSize - mod( length( input ), windowSize ), 1 ) ];
output = zeros( windowSize + length( input ) * stretchFactor, 1 );
halfWinSize = windowSize / 2;
inputIndex = 0;
inputMax = length( input ) - windowSize;
outputIndex = 0;
magOld = zeros( halfWinSize, 1 );
phaseOld = zeros( halfWinSize, 1 );
phaseOut = zeros( halfWinSize, 1 );
synthHop = zeros( synthHopSize, 1 );
omega = 2 * pi * inputHopSize * [ 0 : halfWinSize - 1 ]' / windowSize;
% create progress bar dialog box
bar = waitbar( 0, '0%', 'Name', sprintf( '%s: processing %s...', mfilename, fileName ) );
% Processing Loop
%--------------------------------------------------------------------------
while inputIndex < inputMax;
%copy and window the input frame
inputFrame = input( inputIndex + 1 : inputIndex + windowSize ) .* window;
% perform an fft on the input frame
fullSpect = fft( inputFrame );
% copy relevant half of the spectrum
spect = fullSpect( 1 : halfWinSize );
% cartesian to polar conversion
mag = abs( spect );
phase = angle( spect );
% calculate phase delta
phaseDelta = (phase - phaseOld - omega);
phaseDelta = mod( phaseDelta + pi, -2 * pi ) + pi;
phaseDelta = phaseDelta + omega;
% calculate increments for oscillator bank interpolation
magInc = ( mag - magOld ) / synthHopSize;
phaseInc = phaseDelta / inputHopSize;
% sample by sample oscillator bank synthesis
for synthIndex = 1 : synthHopSize;
% linearly interpolate magnitude and phase
magOld = magOld + magInc;
phaseOut = phaseOut + phaseInc;
% synthesize waveform
synthHop( synthIndex ) = magOld' * cos( phaseOut );
end
% save polar values for next frame
magOld = mag;
phaseOld = phase;
phaseOut = mod( phaseOut + pi, -2 * pi ) + pi;
% normalize the frame
synthHop = synthHop / windowSize;
% concatenate synthesized audio to output buffer
output( outputIndex + 1 : outputIndex + synthHopSize ) = synthHop;
% increment location values
inputIndex = inputIndex + inputHopSize;
outputIndex = outputIndex + synthHopSize;
% update the progress bar
progress = ( inputIndex / inputMax );
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 );
% make 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