Skip to content

Instantly share code, notes, and snippets.

@Mizzlr
Last active September 22, 2020 20:07
Show Gist options
  • Save Mizzlr/a4c32a393935a85574f2797ad5f09545 to your computer and use it in GitHub Desktop.
Save Mizzlr/a4c32a393935a85574f2797ad5f09545 to your computer and use it in GitHub Desktop.
Matlab script to equalize a song.
#! /usr/bin/octave -qf
pkg load signal
% read the file name
fprintf('\n\nInitializing equalizer ...\n');
% setting default values for Equalizer
Equalizer.type = 'Custom';
Equalizer.amps = [7 7 2 0.25 0];
Equalizer.freqs = [100 500 1000 5000 10000];
varargin = argv();
wav_file_name = varargin{1};
% parse command line arguments
if nargin == 4
saving_file_name = varargin{2};
amps = strsplit(varargin{3},':');
freqs = strsplit(varargin{4},':');
for i=1:length(amps)
Equalizer.amps(i) = str2num(cell2mat(amps(1,i)));
Equalizer.freqs(i) = str2num(cell2mat(freqs(1,i)));
end
elseif nargin == 3
saving_file_name = varargin{2};
Equalizer.type = varargin{3};
if length(Equalizer.type) == 2
if Equalizer.type == 'XB'
Equalizer.amps = [8 8 6 5 5];
elseif Equalizer.type == 'BP'
Equalizer.amps = [7 8 5 6 7];
elseif Equalizer.type == 'BL'
Equalizer.amps = [5 5 5 5 5];
elseif Equalizer.type == 'BT'
Equalizer.amps = [5 5 6 7 8];
elseif Equalizer.type == 'VL'
Equalizer.amps = [5 5 6 7 6];
end
else
cells = strsplit(varargin{3},':');
Equalizer.type = 'Custom';
if length(cells) ~= 5
fprintf('Invalid option for equalizer.Must be one of the following. ');
fprintf('\n\tXB --> eXtreme Bass');
fprintf('\n\tBP --> Bass Punch');
fprintf('\n\tBL --> BaLanced');
fprintf('\n\tBT --> Brilliant Treble');
fprintf('\n\tVL --> Vocalizer\n');
exit
end
for i=1:length(cells)
Equalizer.amps(i) = str2num(cell2mat(cells(1,i)));
end
end
elseif nargin == 2
saving_file_name = varargin{2};
else
saving_file_name = 'out.wav';
end
% change the scale from dB to ratio of intensities
Equalizer.amps = 10 .^ ((Equalizer.amps - 1)/4) / 10;
% compute file size and sampling rate
[siz, channels] = wavread(wav_file_name,'size');
[_, Fs, nbits] = wavread(wav_file_name,1);
% set equalization time duration
window_time_duration = 2000 ;%milliseconds
window_length = window_time_duration / 1000 * Fs;
num_frames = floor(siz / window_length);
% compute equalization amplitudes
amplitudes = ones(Equalizer.freqs(1),1) * Equalizer.amps(1);
for i=2:length(Equalizer.freqs)
bandwidth = Equalizer.freqs(i) - Equalizer.freqs(i-1) - 1;
step = (Equalizer.amps(i) - Equalizer.amps(i-1)) / bandwidth;
amps = [Equalizer.amps(i-1): step : Equalizer.amps(i)];
amplitudes = [amplitudes ; amps'];
end
if (window_length > length(amplitudes))
amps = ones(window_length - length(amplitudes),1) * Equalizer.amps(end) ;
amplitudes = [amplitudes ; amps];
else
amplitudes = amplitudes(1:window_length);
end
%[amplitudes , [1:length(amplitudes)]']; % just for debugging
amplitudes = amplitudes * ones(1,channels);
%amplitudes(1:20,:) = zeros(size(amplitudes(1:20,:))); % ingnore 0-20Hz
half_amplitudes = amplitudes(1:ceil(length(amplitudes) / 2),:)';
amplitudes = [half_amplitudes'; fliplr(half_amplitudes)'];
% equalize the song window by window
equalized_song = [];
equalized_song2 = [];
dump = [];
dump2 = [];
fprintf('Equalizer settings: %s\n', Equalizer.type)
fprintf('\tFrequency | Amplitude\n')
fprintf('\t----------+-----------\n');
for i=1:length(Equalizer.freqs);
fprintf('\t%d\t |\t%.2f\n', Equalizer.freqs(i), Equalizer.amps(i) );
end
fprintf('\nEqualizing song %s ...\n', wav_file_name);
for i=0:num_frames-2
% print progress
fprintf('\tProgress %d / %d [%.2f%%]\r', ...
i, num_frames-2, 100 * i / (num_frames-2));
% extract the window
window_start = round(i*window_length + 1);
window_stop = round((i+1) * window_length);
window = wavread(wav_file_name,[window_start window_stop]);
window2 = wavread(wav_file_name,[window_start + window_length / 2 , ...
window_stop + window_length / 2]);
% compute fft of the window
FFT = fft(window);
FFT2 = fft(window2);
% equalize the frame
FFT = FFT .* amplitudes;
FFT2 = FFT2 .* amplitudes;
% compute amplified window
equalized_window = ifft(FFT);
equalized_window2 = ifft(FFT2);
equalized_song = [equalized_song ; equalized_window];
equalized_song2 = [equalized_song2; equalized_window2];
% dump once every 20 frames, to optimize concatenation
if mod(i, 20) == 0 && i ~= 0
dump = [dump; equalized_song];
dump2 = [dump2; equalized_song2];
equalized_song = [];
equalized_song2 = [];
end
end
%dump rest of the song
dump = [dump; equalized_song];
dump2 = [dump2; equalized_song2];
equalized_song = dump;
equalized_song2 = dump2;
fprintf('\nRemoving abrupt changes in audio,\n');
fprintf('by Triangular filter ...\n');
step = 2 / window_length;
sawtooth = repmat([[0:step:1]' ; [1:-step:0]'],1,channels);
sawtooth2 = repmat([[1:-step:0]' ; [0:step:1]'],1,channels);
start_ = 1;
equalized_song = [ equalized_song ;
zeros(window_length / 2, channels) ];
equalized_song2 = [ zeros(window_length / 2,channels);
equalized_song2 ];
for i=1:num_frames-1
fprintf('\tProgress %d / %d [%.2f%%]\r', ...
i-1, num_frames-2, 100 * (i-1) / (num_frames-2));
stop_ = start_ + length(sawtooth) - 1;
equalized_song(start_:stop_,:) = equalized_song(start_:stop_,:) .* sawtooth;
equalized_song2(start_:stop_,:) = equalized_song2(start_:stop_,:) ...
.* sawtooth2;
start_ = start_ + length(sawtooth);
end
fprintf('\nMultiplexing audio streams ...\n');
merged_song = equalized_song + equalized_song2;
%save the song
fprintf('Saving song as %s ...\n', saving_file_name);
wavwrite(merged_song, Fs, nbits, saving_file_name);
fprintf('Done\n\n');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment