# HG changeset patch # User Daniele Barchiesi # Date 1326113880 0 # Node ID f8bc99a5470c3b555aeebc51086f641611017bc7 # Parent 0dc98f1c60bb931075f1ec364014933ea6f93c69 Added test for audio buffer function diff -r 0dc98f1c60bb -r f8bc99a5470c util/classes/@audio/audio.m --- 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 diff -r 0dc98f1c60bb -r f8bc99a5470c util/classes/@audio/buffer.m --- 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 diff -r 0dc98f1c60bb -r f8bc99a5470c util/classes/@audio/plot.m --- 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; diff -r 0dc98f1c60bb -r f8bc99a5470c util/classes/tests/test_buffer.m --- /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