Vysoké učení technické v Brně Fakulta strojního inženýrství Technická 2, Brno 616 69
Semestrální projekt do kurzu RZS Téma: zpracování záznamu audiosignálu z gramofonu
Zpracoval: Jan Chalupa VUT ID: 115617
Úvod: Cílem bylo získat záznam zbavený nežádoucích rušivých signálů, jako je lupání a praskání, které vzniká nečistotami nebo vadami v drážkách vinylové desky.
Skript: Byl vytvořen v prostředí Matlab, jeho funkce spočívá v načtení zvukového souboru, který obsahuje výše zmíněné vady. Po načtení se provede dvojitá derivace pomocí konvoluce. Derivací zjistíme místa kde dochází k nárazové změně signálu, která je způsobená buďto vysokými kmitočty, nebo zmíněnou vadou v drážce desky. Vzhledem k výsledkům derivace se dají vlivy vysokých kmitočtů zanedbat. Detekce vad je vylepšena proměnnou hranicí vyhodnocování vzorků. viz. graf1.
Graf 1: graf derivace v oblasti problému, zobrazení proměnné hranice vyhodnocení vady vzorků
Problematické vzorky jsou zaznamenány do matice repair, ze které se později načítají informace při prokládání křivek. Od hranic problematického místa vezmeme určitý počet správných vzorků a vypočteme z nich průměrnou hodnotu. Tyto hodnoty využijeme pro vytvoření směrnice přímky, kterou proložíme právě opravované místo.
Vlastní oprava signálu spočívá ve spojování liniovou křivkou přes problematický úsek viz. graf2.
Graf 2: prokládání křivky problematickou oblastí
Na grafu2 je vidět „rozeskákané“ hodnoty původního singálu(modře), červeně je zobrazena náhradní křivka. Algoritmus čištění probíhá 6krát za sebou, tím pádem se můžou znovu opravovat místa, která vykazují velmi rozsáhlou chybu. Viz graf3.
Graf 3: vícestupňová oprava vadného intervalu
Příklady oprav:
Graf 4: soubor grafů, dílčí opravy poškozených míst
Srovnání původního a opraveného souboru dat, na grafech jsou zřetelně potlačené peaky způsobené vadami desky:
Graf 5: srovnání původního a nové části souboru dat1
Graf 6: srovnání původního a nové části souboru dat2
Krácený zdrojový kód: %% load wav file and definitons y = wavread('Recording 10.wav'); %select part to clean wavestart=1; waveend=length(y); wavwrite(y(wavestart:1:waveend,:),44000,'outpuvodni.wav'); %difinitons of variables d=[0 2 -2 0 0 0]; delka=waveend-wavestart; %% select and clean channel for chan=1:2 channel=0; channel=y(wavestart:1:waveend,chan); puvodni(:,chan)=channel; cycles=7; %% clean loop start while cycles>1 disp(['repairing channel: ', num2str(chan) ' cycles left: ', num2str(cycles-1)]) ; cycles=cycles-1; %cycle decrement %% double derivation u=conv(d,channel); b=conv(d,conv(d,u)); display('convolution finished'); ab=abs(b); %% mean values calculation in intervals of X samples 'wide=samples;' wide=100; %width of interval counter=0; %counter for intervals for i=1:wide:delka counter=counter+1; meanab(counter)=mean(ab(i:(i+wide),1)); end meanab(counter+2)=meanab(counter); meanab(counter+1)=meanab(counter); display('mean intevals finished'); %% find erors meancount=0; %counter for selecting mean value in desired signal interval widecount=0; %width bound counter counter=1; %errorarray fill counter temp=meanab(1); %condition definition for i=1:1:delka widecount=widecount+1; if widecount==wide widecount=0; meancount=meancount+1; temp=meanab(meancount); end if ab(i) > temp+0.5 %derivation higher then temp+0.3 errorarray(counter)=i; counter=counter+1; end end
display('error found');
%% make repair matrix %lower bound has added 2 presamples higher addition of postsamples repaircount=1; %counter for recording interval with erorr repair=[0 0]; repair(1,1)=errorarray(1); for i=1:1:(counter-2); difference=errorarray(i+1)-errorarray(i); if difference>3 repair(repaircount,2)=errorarray(i); repaircount=repaircount+1; repair(repaircount,1)=errorarray(i+1); end end repair(repaircount,2)=errorarray(counter-1); display('repair matrix made');
%% repair %lower bound has added 2 presamples higher addition of postsamples repaircount=1; equation=0; count=0; for i=2:1:length(repair); a=repair(i,1); b=repair(i,2); int=12+b-a; meanA=mean( channel((a-9):(a-6),1)); meanB=mean( channel((b+1):(b+4),1)); equation(i)=(meanA - meanB)/int; %compute directive count=0; for u=(a-5):1:(b+1) %interpose line between two points of signal count=count+1; channel(u,1)=meanA- equation(i)*count; end end disp(['repair sectors left: ', num2str(length(repair))]) ; display(' '); end %while end-number of cleaning procedure outputchan(:,chan)=channel; end %for end-channel selection
Po spuštění skriptu se vytvoří soubory outpuvodni.wav a outclean.wav.
Přílohy: Datové přílohy: Recording 10.wav Chalupa_projekt_cisteni_nahravky.m Chalupa_projekt_cisteni_nahravky_grafy.m
Obrazové přílohy: compare1.png compare2.png compare3.png rep1.png rep2.png rep3.png rep4.png rep5.png rep6.png derivation.png