ivan@136
|
1 function data = generateAudioDeclippingProblem(soundfile, clippingLevel, windowSize, overlap, wa, ws, wd, Dict_fun, redundancyFactor)
|
ivan@136
|
2 %% Generate Audio Declipping Problem
|
ivan@136
|
3 %
|
ivan@140
|
4 % generateAudioDeclippingProblem is part of the SMALLbox [1] and generates
|
ivan@140
|
5 % Audio declipping is a problem proposed in Audio Inpaining Toolbox and
|
ivan@140
|
6 % in [2].
|
ivan@140
|
7 %
|
ivan@161
|
8 % The function takes as an optional input
|
ivan@161
|
9 % soundfile - name of the file
|
ivan@161
|
10 % clippingLevel - (default 0.6)
|
ivan@161
|
11 % windowSize - 1D frame size (eg 512)
|
ivan@161
|
12 % overlap - ammount of overlaping frames between 0 and 1
|
ivan@161
|
13 % wa,ws,wd - analisys, synthesis and dictionary window functions
|
ivan@161
|
14 %
|
ivan@161
|
15 % Dict_fun - function to be used to generate dictionary
|
ivan@161
|
16 % redundancyFactor - overcompletness of dictionary (default 2)
|
ivan@161
|
17 %
|
ivan@161
|
18 % The function outputs the structure with following fields:
|
ivan@161
|
19 % original - original signal
|
ivan@161
|
20 % clipped - clipped signal
|
ivan@161
|
21 % clipMask - mask indicating clipped samples
|
ivan@161
|
22 % clippingLevel - (default 0.6)
|
ivan@161
|
23 % Upper_Limit - maximum value of original data
|
ivan@161
|
24 % fs - sample rate of the original signal in Hertz
|
ivan@161
|
25 % nbits - the number of bits per sample
|
ivan@161
|
26 % sigma - added noise level
|
ivan@161
|
27 % B - dictionary to be used for sparse representation
|
ivan@161
|
28 % M - measurement matrix (non-clipped data in b)
|
ivan@161
|
29 % b - matrix of clipped frames
|
ivan@161
|
30 % m - size od dictionary atom
|
ivan@161
|
31 % n - number of frames to be represented
|
ivan@161
|
32 % p - number of atoms in dictionary
|
ivan@161
|
33 % windowSize - 1D frame size (eg 512)
|
ivan@161
|
34 % overlap - ammount of overlaping frames between 0 and 1
|
ivan@161
|
35 % wa,ws, wd - analisys, synthesis and dictionary window functions
|
ivan@161
|
36 %
|
ivan@140
|
37 % [1] I. Damnjanovic, M. E. P. Davies, and M. P. Plumbley "SMALLbox - an
|
ivan@140
|
38 % evaluation framework for sparse representations and dictionary
|
ivan@140
|
39 % learning algorithms," V. Vigneron et al. (Eds.): LVA/ICA 2010,
|
ivan@140
|
40 % Springer-Verlag, Berlin, Germany, LNCS 6365, pp. 418-425
|
ivan@140
|
41 % [2] A. Adler, V. Emiya, M. G. Jafari, M. Elad, R. Gribonval, and M. D.
|
ivan@140
|
42 % Plumbley, “Audio Inpainting,” submitted to IEEE Trans. Audio, Speech,
|
ivan@140
|
43 % and Lang. Proc., 2011, http://hal.inria.fr/inria-00577079/en/.
|
ivan@140
|
44
|
ivan@136
|
45
|
ivan@136
|
46 % Centre for Digital Music, Queen Mary, University of London.
|
ivan@136
|
47 % This file copyright 2011 Ivan Damnjanovic.
|
ivan@136
|
48 %
|
ivan@136
|
49 % This program is free software; you can redistribute it and/or
|
ivan@136
|
50 % modify it under the terms of the GNU General Public License as
|
ivan@136
|
51 % published by the Free Software Foundation; either version 2 of the
|
ivan@136
|
52 % License, or (at your option) any later version. See the file
|
ivan@136
|
53 % COPYING included with this distribution for more information.
|
ivan@136
|
54 %
|
ivan@136
|
55 %%
|
ivan@136
|
56 FS=filesep;
|
ivan@136
|
57 TMPpath=pwd;
|
ivan@136
|
58
|
ivan@136
|
59 if ~ exist( 'soundfile', 'var' ) || isempty(soundfile)
|
ivan@136
|
60 %ask for file name
|
luis@186
|
61 [pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m'));
|
ivan@136
|
62 cd([pathstr1,FS,'data',FS,'audio']);
|
ivan@136
|
63 [filename,pathname] = uigetfile({'*.mat; *.mid; *.wav'},'Select a file to transcribe');
|
luis@186
|
64 [pathstr, name, ext] = fileparts(filename);
|
ivan@136
|
65 data.name=name;
|
ivan@136
|
66
|
ivan@136
|
67 if strcmp(ext,'.mid')
|
ivan@136
|
68 midi=readmidi(filename);
|
ivan@136
|
69 % data.notesOriginal=midiInfo(midi);
|
ivan@136
|
70 y=midi2audio(midi);
|
ivan@136
|
71 wavwrite(y, 44100, 16, 'temp.wav');
|
ivan@136
|
72 [x.signal, x.fs, x.nbits]=wavread('temp.wav');
|
ivan@136
|
73 delete('temp.wav');
|
ivan@136
|
74 elseif strcmp(ext,'.wav')
|
ivan@136
|
75 % cd([pathstr1,FS, 'data', FS, 'audio', FS, 'midi']);
|
ivan@136
|
76 % filename1=[name, '.mid'];
|
ivan@136
|
77 % if exist(filename1, 'file')
|
ivan@136
|
78 % midi=readmidi(filename1);
|
ivan@136
|
79 % data.notesOriginal=midiInfo(midi);
|
ivan@136
|
80 % end
|
ivan@136
|
81 cd([pathstr1,FS, 'data', FS, 'audio', FS, 'wav']);
|
ivan@136
|
82 [x.signal, x.fs, x.nbits]=wavread(filename);
|
ivan@136
|
83 else
|
ivan@136
|
84 % cd([pathstr1,FS, 'data', FS, 'audio', FS, 'midi']);
|
ivan@136
|
85 % filename1=[name, '.mid'];
|
ivan@136
|
86 % if exist(filename1, 'file')
|
ivan@136
|
87 % midi=readmidi(filename1);
|
ivan@136
|
88 % data.notesOriginal=midiInfo(midi);
|
ivan@136
|
89 % end
|
ivan@136
|
90 cd([pathstr1,FS, 'data', FS, 'audio', FS, 'mat']);
|
ivan@136
|
91 x=load([pathname,filename]);
|
ivan@136
|
92 end
|
ivan@136
|
93 else
|
ivan@136
|
94 [x.signal, x.fs, x.nbits]=wavread(soundfile);
|
luis@186
|
95 [pathstr, name, ext] = fileparts(soundfile);
|
ivan@136
|
96 data.name=name;
|
ivan@136
|
97 end
|
ivan@136
|
98
|
ivan@136
|
99 if ~ exist( 'clippingLevel', 'var' ) || isempty(clippingLevel), clippingLevel = 0.6; end
|
ivan@136
|
100 if ~ exist( 'windowSize', 'var' ) || isempty(windowSize), windowSize = 256; end
|
ivan@136
|
101 if ~ exist( 'overlap', 'var' ) || isempty(overlap), overlap = 0.5; end
|
ivan@136
|
102 if ~ exist( 'wa', 'var' ) || isempty(wa), wa = @wRect; end % Analysis window
|
ivan@136
|
103 if ~ exist( 'ws', 'var' ) || isempty(ws), ws = @wSine; end % Synthesis window
|
ivan@136
|
104 if ~ exist( 'wd', 'var' ) || isempty(wd), wd = @wRect; end % Weighting window for dictionary atoms
|
ivan@136
|
105
|
ivan@136
|
106 %% preparing signal
|
ivan@136
|
107
|
ivan@136
|
108 [problemData, solutionData] = generateDeclippingProblem(x.signal,clippingLevel);
|
ivan@136
|
109
|
ivan@136
|
110 x_clip = im2colstep(problemData.x,[windowSize 1],[overlap*windowSize 1]);
|
ivan@136
|
111 x_clip= diag(wa(windowSize)) * x_clip;
|
ivan@137
|
112 blkMask=im2colstep(double(~problemData.IMiss),[windowSize 1],[overlap*windowSize 1]);
|
ivan@136
|
113
|
ivan@136
|
114 %% Building dictionary
|
ivan@136
|
115 if ~exist( 'redundancyFactor', 'var' ) || isempty(redundancyFactor), redundancyFactor = 2; end % Weighting window for dictionary atoms
|
ivan@136
|
116 if exist('Dict_fun', 'var')&&~isempty(Dict_fun)
|
ivan@136
|
117 param=struct('N', windowSize, 'redundancyFactor', redundancyFactor, 'wd', wd);
|
ivan@136
|
118 data.B = Dict_fun(param);
|
ivan@136
|
119 end
|
ivan@136
|
120
|
ivan@136
|
121 data.b = x_clip;
|
ivan@136
|
122 data.M = blkMask;
|
ivan@136
|
123 data.original = solutionData.xClean;
|
ivan@136
|
124 data.clipped = problemData.x;
|
ivan@136
|
125 data.clipMask = problemData.IMiss;
|
ivan@136
|
126 data.clippingLevel = clippingLevel;
|
ivan@136
|
127 data.windowSize = windowSize;
|
ivan@136
|
128 data.overlap = overlap;
|
ivan@136
|
129 data.ws = ws;
|
ivan@136
|
130 data.wa = wa;
|
ivan@136
|
131 data.wd = wd;
|
ivan@136
|
132
|
ivan@136
|
133 data.fs = x.fs;
|
ivan@136
|
134 data.nbits = x.nbits;
|
ivan@161
|
135 data.Upper_Limit = max(solutionData.xClean);
|
ivan@136
|
136 [data.m, data.n] = size(x_clip);
|
ivan@136
|
137 data.p = windowSize*redundancyFactor; %number of dictionary elements
|
ivan@136
|
138
|
ivan@136
|
139 cd(TMPpath);
|
ivan@136
|
140
|
ivan@136
|
141 end
|