function demosampling4 % Demo yksittäisen kosinisignaalin käytöksestä, % kun sen taajuutta kasvatetaan. Näkymät aika- ja taajuustasossa. % Demoa voi kuunnella!!! % % IKKUNA No. 1: % Ylin ikkuna: jatkuva-aikaisen signaalin x(t) spektri. Yksi kosini % tuottaa kaksi piikkiä spektriin symmetrisesti y-akselin % molemmin puolin. Spektri ei ole jaksollinen. % Keski-ikkuna: diskreettiaikaisen signaalin/sekvenssin x[n] % spektri -2.2 fs .. 2.2 fs. Spektri on jaksollinen. % Näytteenotto voidaan ajatella jatkuva-aikaisen signaalin % spektrin kopiointina näytteenottotaajuuden välein (2pi) ja % summattuna komponentit yhteen. Väli 0 .. fs/2 on tummennettu, % koska sille kaistalle osuvat kosinit voidaan kuulla rekonstruktiossa. % Alin ikkuna: diskreettiaikaisen signaalin spektri 0 .. 0.5 fs % Siis zoomaus keski-ikkunasta, se osa signaalia, joka voidaan % havaita. Kun diskreettiaikainen sekvenssi x[n] palautetaan % jatkuva-aikaiseksi xr(t), vain tässä alueessa olevat komponentit % (ja niiden vastinkappaleet vastaavalla negatiivisella taajuudella) % voidaan havaita. % % IKKUNA No. 2: % Aikatason kuva. Sinisellä alkuperäinen kosinisignaali. % Punaisilla palloilla kuvattu näytteistetty lukujono. % Jos taajuus yli fs/2, niin sitten näytetään hitain % kosini, joka sopii samaan näytteistettyyn lukujonoon. % Eli juuri se taajuus, joka näkyy spektrissä 0 .. fs/2 välissä. % % Paina päästäksesi eteenpäin. Tällöin kuulet myös kyseisen % kosinikomponentin äänen. % % % Ohjelmalla demonstroidaan vierastumisilmiötä (aliasing). % % Jos kosinin taajuus on yli fs/2:n, se vierastuu matalemmalle taajuudelle. % Matemaattisesti tämän voi ajatella esimerkillä, jossa fs=10000 Hz, % ja alkuperäinen jatkuva-aikaisen kosinin taajuus f1=5500 Hz. % Koska f1 > fs/2, tapahtuu vierastuminen: % x(t) = cos(2 pi 5500 t) % x[n] = x(nT_s) = x(n/fs) % t <- n/fs % = cos(2 pi 5500/10000 n) % = cos(2 pi 5500/10000 n - 2 pi 10000/10000 n) % väh. 2pi-monikerta % = cos(2 pi -4500/10000 n) % = cos(2 pi 4500/10000 n) % kosini on parillinen % xr(t) = cos(2 pi 4500 t) % n <- t fs % % Eli huomataan, että liian vähän näytteistetystä signaalista x(t) % saadun diskreettiaikaisen lukujono x[n] sopii MYÖS % rekonstruoituun/palautettuun jatkuva-aikaiseen signaaliin xr(t), % joka onkin ERI kuin alkuperäinen x(t). Tässä tapauksessa, % kun näytteenottotaajuus on 10000 Hz ja signaalin x(t) kosinin % taajuus 5500 Hz, niin se vierastuu koska 5500 > 10000/2, % ja palautetun signaalin xr(t) taajuus on fs-f1=10000-5500=4500. % % Jos x(t):llä f1=11000 Hz, niin palautettu taajuus olisi % f1-fs = 1000 Hz. Jos x(t):llä f1=33000 Hz, niin palautettu % f1-3*fs = 3000 Hz. Jos x(t):llä f1 = 37000 Hz, niin palautettu % 4*fs-f1 = 3000 Hz, jne. % % Jatkuva-aikaisen signaalin näytteenotto voidaan taajuustasossa % siis ajatella JOKO % (1) KOPIOIMISENA jokaisen 2pi:n välein eli jokainen % näytteenottotaajuuden välein, spektrit summataan yhteen % jokaisessa kohdassa % (2) PEILAAMISENA jokaisen pi:n ympäri eli jokaisen % puolen näytteenottotaajuuden ympäri, spektrit summataan % yhteen jokaisessa kohdassa. *) % % Demossa kosinin taajuus muuttuu f0 Hz:stä fi Hz:n askelin % 1.2 fs Hz:iin asti. Koodissa f0 = 500, fi = 500 ja fs = 10000. % % % Jukka Parviainen, T-61.140, 16.4.2003 / 1.4.2004 / 27.4.2004 % Informaatiotekniikan laboratorio, TKK. % % *) VIRHEITÄ: % Spektripiikit on aina skaalattu ykköseen, mikä ei aivan pidä % paikkaansa. Jos et tiedä miksi, älä huolestu vaan mene eteenpäin. % ALUSTUS % % Alustetaan kaksi ikkunaa, Nro 1 on taajuusikkuna ja Nro 2 % on aikatason ikkuna. Lisäksi siirretään hieman ikkunaa Nro 2 % oikealle; tämä siksi, jos ikkunat ensimmäistä kertaa demottaessa % ovat toistensa päällä, niin käyttäjä tajuaa, että toinenkin % ikkuna avautui. figure(1); % taajuusikkuna clf; figure(2); clf; ppp = get(gcf,'Position'); set(gcf,'Position',ppp+[30 30 0 0]); % siirretään figure(1); % aktivoidaan taajuustason ikkuna % näytteenottotaajuudet Fs = 10000; % näytteenottotaajuus fsc = 200000; % simuloidaan jatkuva-aikaista % ensimmäinen taajuus ja kuinka paljon taajuutta kasvatetaan f0 = 500; fi = 500; % aika-akselit t = [0 : 1/Fs : 0.3]; % viimeinen arvo määrää piippauksen pituuden t = t(1:1024); % ...mutta otetaankin vain 1024 näytettä = 1024/Fs sek. tc = [0 : 1/fsc : 0.1]; tc = tc(1:2^14); % oikeita vähän reilummin... % spektrin värjäys - ongelmia dataprojektin kanssa :( % käytetään joko col tai col2 % % TÄRKEÄT VÄRIT OVAT RIVIT 3 4 ja 5. rivi. YHTEENSÄ 7x3 matriisi col2 = [[1 0 1]; [0.2 0.3 0]; [0 1 0.3]; [0 0 1]; [.5 .5 .5]; [.7 .2 .3]; [1 1 0]]; %[0 1 0.3] % muita värejä?! %col = ['b', 'b','b','b','b', 'b','b']; %col = ['b', 'r','g','b','r', 'g','b']; %col = ['g', 'r', 'c', 'b', 'm', 'k', 'y']; % Kolmiospektrin väri tulee myös ylläolevista. kolmvari = col2(4,:); % Diskreetin sekvenssin piirtoväri ikkunassa Nro 2 dvari = [0 0 0]; % VARSINAINEN TYÖ: % % For-looppi jokaista kosinitaajuutta kohti, lopussa % on "pause", jolla ohjelman ajo keskeytetään siksi, % kunnes käyttäjä painaa jotain nappulaa. for m = [f0:fi:1.2*Fs] f1 = m; y = cos(2*pi*f1*t ); % "todellinen" yc = cos(2*pi*f1*tc); % "simuloitu" kuvaajia varten % lasketaan Fourier-muunnokset ja taajuusakselit ycF = abs(fft(hamming(length(yc))'.*yc)); ycF = ycF/max(ycF); wc = linspace(-fsc/2, fsc/2, length(ycF)); yF = abs(fft(hamming(length(y))'.*y)); yF = yF/max(yF); w = linspace(0, Fs, length(yF)); % kolmiospektriä varten kohta: kolm = find(abs(ycF) > 0.8); kolm = round([-kolm(1) kolm(1)]+(length(ycF)/2)); % PIIRROKSET % piirretään jatkuva-aikainen ikkunan Nro 1 yläosaan: subplot(311); cla; p1 = plot(wc, fftshift(ycF)); set(p1, 'Linewidth', 3); grid on; axis([-2.2*Fs 2.2*Fs -0.2 1.1]); title(['Jatkuvan kosinin f = ' num2str(f1) ' Hz spektri. Skaala -2.2fs .. 2.2fs']); % piirretään kolmioaalto hold on; pk = plot([wc(kolm(1)) 0 wc(kolm(2))],[0 1 0]); set(pk, 'LineStyle', '--', 'Color', kolmvari); % piirretään diskreettiaikainen ikkunan Nro 1 keskelle: subplot(312); cla; % kiinnostava kaista 0 .. pi tummenetaan ff = fill([0 Fs/2 Fs/2 0],[0 0 1.1 1.1],[0.8 0.8 0.8]); hold on; % li = line([0 Fs/2], [-0.18 -0.18]); % tämä jana taitaa sekoittaa % set(li, 'LineWidth', 3); % piirretään varsinaiset komponentit k=0; wwj = linspace(-fsc/2 , fsc/2 , length(ycF)); p2 = plot(wwj, fftshift(ycF)); set(p2, 'Linewidth', 3, 'Color', col2(k+4,:)); li = line([0 fi -fi; 0 0 0], [-0.1 -0.15 -0.15; -0.2 -0.1 -0.1]); set(li, 'Color', col2(4,:),'LineWidth',5); % piirretään loput monikerrat, joista tapahtuu vierastumista % kun f_high > fs/2 for k=[-3:-1 1:3] % spektripiikit p2 = plot(wwj+k*Fs, fftshift(ycF)); set(p2, 'Linewidth', 3, 'Color', col2(k+4,:)); % nuolet alapuolelle li = line([k*Fs k*Fs+fi k*Fs-fi; k*Fs k*Fs k*Fs],[-0.1 -0.15 -0.15; -0.2 -0.1 -0.1]); set(li, 'Color', col2(k+4,:),'LineWidth',5); % lisätään kolmiospektrit pk = plot([wc(kolm(1)) 0 wc(kolm(2))]+k*Fs,[0 1 0]); set(pk, 'LineStyle', '--', 'Color', col2(k+4,:)); end; % HUOM! Nuolet kuvastavat näytteenottotaajuuden monikertoja % ne eivät ole mitään signaalikomponentteja % piirretään kolmioaalto hold on; pk = plot([wc(kolm(1)) 0 wc(kolm(2))],[0 1 0]); set(pk, 'LineStyle', '--', 'Color', kolmvari); title(['Diskreetin kosinin f = ' num2str(f1) ' Hz spektri, kun fs = ' num2str(Fs) ' Hz']); grid on; axis([-2.2*Fs 2.2*Fs -0.2 1.1]); % Ikkunan Nro 1 % alimpaan kuvaajaan tulee kiinnotava kaista 0 .. pi eli 0 .. fs/2 subplot(313); p3 = plot(w, yF); set(p3, 'Linewidth', 3); vari = floor(f1 / (Fs/2)); switch vari case 0, set(p3, 'Color', col2(4,:)); case 1, set(p3, 'Color', col2(5,:)); case 2, set(p3, 'Color', col2(3,:)); otherwise, set(p3, 'Color', col2(4,:)); end; axis([0 Fs/2 -0.2 1.1]); grid on; title(['Diskreettiaikainen spektri 0 .. ' num2str(Fs/2) ' Hz - palautetun signaalin spektri']); set(gca, 'Color', [.8 .8 .8]); % Tässä välissä soitetaan kosinin ääni ja jäädään % odottelemaan, että piirrokset ehtivät valmiiksi. soundsc(y, Fs); % AKTIVOIDAAN AIKATASON IKKUNA figure(2); clf; p1 = plot(tc, yc); set(p1, 'LineWidth', 2); % jatkuva signaali hold on; vari = floor(f1 / (Fs/2)); switch vari case 1, % Ollaan kohdassa fs/2 .. fs, eli vierastuu eka kertaa tmp = cos(2*pi*(Fs-f1)*tc); p3 = plot(tc, tmp); set(p3, 'Color', col2(5,:), 'LineWidth', 3); p3 = plot(tc, tmp); set(p3, 'Color', [0 0 0]); legend({'Alkuperainen','Palautettu'}); case 2, % Ollaan kohdassa fs .. 3fs/2, eli vierastuu toka kertaa tmp = cos(2*pi*(f1-Fs)*tc); p3 = plot(tc, tmp); set(p3, 'Color', col2(3,:), 'LineWidth', 3); p3 = plot(tc, tmp); set(p3, 'Color', [0 0 0]); legend({'Alkuperainen','Palautettu'}); end; tmpx = [0 : 1/Fs : 0.01]; tmpy = (-1.5)*ones(1, length(tmpx)); p4 = plot(tmpx,tmpy,'d'); set(p4, 'MarkerSize', 16, 'LineWidth', 2, 'Color', dvari); p4 = plot(tmpx,tmpy,'-'); set(p4, 'LineWidth', 2, 'Color', dvari); t4 = text(0.1/1E3, -1.3, ['fs = ' num2str(Fs) ' Hz, Ts = 1/fs = ' num2str(1/Fs) ' s']); set(t4, 'FontSize', 20, 'FontWeight', 'Bold', 'Color', dvari); p4 = stem(t, y, 'o'); set(p4, 'MarkerSize', 16, 'LineWidth', 3, 'Color', dvari); title(['Aikatason jatkuva kosini f = ' num2str(f1) ' Hz']); xlabel('aika (s)'); grid on; axis([0 0.0011 -1.8 1.2]); shg; % PALATAAN TAKAISIN IKKUNAAN Nro 1 figure(1); shg; % Jäädään odottelemaan käyttäjän näppäimenlyöntiä...a pause; end;