changeset 182:f8bc99a5470c danieleb

Added test for audio buffer function
author Daniele Barchiesi <daniele.barchiesi@eecs.qmul.ac.uk>
date Mon, 09 Jan 2012 12:58:00 +0000
parents 0dc98f1c60bb
children 0d7a81655ef2
files util/classes/@audio/audio.m util/classes/@audio/buffer.m util/classes/@audio/plot.m util/classes/tests/test_buffer.m
diffstat 4 files changed, 82 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/util/classes/@audio/audio.m	Thu Jan 05 15:46:13 2012 +0000
+++ b/util/classes/@audio/audio.m	Mon Jan 09 12:58:00 2012 +0000
@@ -1,24 +1,37 @@
+%% AUDIO OBJECT CLASS
+% Class designed to analyse and process audio signals
+%%
 classdef audio
-	%% Audio object
-	properties
-		s  %vector containing the audio signal
-		S  %matrix containing frames of audio for subsequent processing
-		fs %sampling frequency
-		nBits %number of bits per sample
-		name %string containing the name of the audio file
-		format %string containing the format of the audio file
-		bufferOperator %struct containing the parameters of the buffer operator (used by unbuffer to invert it)
+	properties (SetAccess = protected)
+		s				%vector containing the audio signal
+		fs				%sampling frequency
+		nBits			%number of bits per sample
+		name			%string containing the name of the audio file
+		format			%string containing the format of the audio file
+		bufferOperator	%struct containing the parameters of the buffer operator
+		S				%matrix containing frames of audio
 	end
 	
 	methods
 		%% Constructor
 		function obj = audio(varargin)
+			%%% obj = audio(varargin)
+			% Audio object constructor.
+			% INPUT: either a path to an audio file, or the following
+			% arguments.
+			% - s: vector containing the audio samples
+			% - fs: sampling frequency
+			% - nBits: number of bits per sample
+			% - name: name of the audio object
+			% - format: format of the audio object
+			%
 			% if no arguments are specified, prompt for the choice of an
 			% audio file
 			if ~nargin
 				[fileName,pathname] = uigetfile({'*.wav; *.aiff;'},'Select an audio file');
 				varargin{1} = strcat(pathname,filesep,fileName);
 			end
+			% if a file is specified, read it from disk
 			if ischar(varargin{1})
 				[~, obj.name obj.format] = fileparts(varargin{1});
 				switch obj.format
@@ -27,6 +40,7 @@
 					otherwise
 						error('Unsupported audio format')
 				end
+			% if properties are specified, set them to input values
 			else
 				obj.s = varargin{1};
 				if nargin>1, obj.fs = varargin{2}; else obj.fs = []; end
--- a/util/classes/@audio/buffer.m	Thu Jan 05 15:46:13 2012 +0000
+++ b/util/classes/@audio/buffer.m	Mon Jan 09 12:58:00 2012 +0000
@@ -1,8 +1,14 @@
+%% Buffer function
+% Buffers the samples of the audio object into the columns of the matrix S
+% based on the input parameters
+%%
 function obj = buffer(obj,wLength,overlap,window,method)
 
 %% Check inputs & Defaults
 error(nargchk(2, 5, nargin, 'struct'));
-
+if rem(length(obj.s),wLength)
+	error('The wLength must be an integer divisor of the signal length!'); 
+end
 if ~exist('overlap','var') || isempty(overlap), overlap = 0; end
 if ~exist('method','var') || isempty(method), method = 'standard'; end
 
@@ -15,10 +21,10 @@
 			error('The window chosen is not valid because it cannot be inverted!');
 		end
 		obj.S = diag(window(wLength))*buffer(obj.s,wLength,overlap,'nodelay');
-	case 'lot'
-		if ~exist('window','var') || isempty(window), window = 'sin2'; end
-		s_lot = lot(obj.s,wLength,'id',overlap,window);
-		obj.S = buffer(s_lot,wLength);
+% 	case 'lot'
+% 		if ~exist('window','var') || isempty(window), window = 'sin2'; end
+% 		s_lot = lot(obj.s,wLength,'id',overlap,window);
+% 		obj.S = buffer(s_lot,wLength);
 	otherwise
 		error('Please specify a valid buffer method');
 end
--- a/util/classes/@audio/plot.m	Thu Jan 05 15:46:13 2012 +0000
+++ b/util/classes/@audio/plot.m	Mon Jan 09 12:58:00 2012 +0000
@@ -16,9 +16,6 @@
 pauseButtonH = uicontrol(playbackPanelH,'Style','togglebutton','String','||','Units',...
 	'Normalized','Position',[centers(6) 0.2 buttWidth 0.6]);
 
-waveformPanelH = uipanel(gcf,'Units','Normalized','Position',[.02 .12 .96 .86]);
-waveformAxesH = axes('Parent',waveformPanelH);
-
 %% Plot the time domain signal
 s = obj.s;
 fs = obj.fs;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/classes/tests/test_buffer.m	Mon Jan 09 12:58:00 2012 +0000
@@ -0,0 +1,48 @@
+%% Buffer Test
+% Test script for the function audio->buffer which takes an audio object as
+% an input and buffers it into frames. The test assesses wether all the
+% possible buffer methods are invertible.
+%%
+
+N = 500;					% number of audio samples
+TOL = 200;					% tolerance (in decibels)
+verb = true;				% verbose
+
+obj = audio(randn(N,1));	% audio object
+% wLengts: one window, two windows, maximum number of windows
+temp = factor(N);
+wLengths = [N; fix(N/2); fix(N/temp(end))];
+% overlaps: zero, half window, max
+overlapNames = {'zero','half-window','maximum'};
+overlaps = {@(n)0, @(n)n/2, @(n)n-1};
+% windows: valid windows
+windows = {@hanning,@hamming,@triang,@rectwin};
+% methods: valid methods
+methods = {'standard'};
+
+
+nLen  = length(wLengths);
+nOver = length(overlaps);
+nWin  = length(windows);
+nMet  = length(methods);
+count = 1;
+for iLen=1:nLen
+	for iOver=1:nOver
+		for iWin=1:nWin
+			for iMet=1:nMet
+				if verb
+				printf('\n buffer test %d/%d - %d window length, %s overlap, %s window and %s method ... ',...
+					count,nMet*nWin*nOver*nLen,wLengths(iLen),overlapNames{iOver},func2str(windows{iWin}),methods{iMet});
+				end
+				obj = buffer(obj,wLengths(iLen),overlaps{iOver}(wLengths(iLen)),windows{iWin},methods{iMet});
+				s_rec = obj.unbuffer;
+				if snr(obj.s,s_rec) > TOL
+					if verb, printf('Passed'); end
+				else
+					error('Test failed!');
+				end
+				count = count+1;
+			end
+		end
+	end
+end