Συστήματα Πολυμέσων & Εικονική Πραγματικότητα Εργασία 2015-2016 Α. Ντελόπουλος, Β. Παπαπαναγιώτου Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Αριστοτέλειο Πανεπιστήμιο Θεσσαλονίκης 5 Δεκεμβρίου, 2015 1 Εισαγωγικές παρατηρήσεις Η παρακάτω εργασία αποτελεί προαιρετικό μέρος του μαθήματος Συστήματα Πολυμέσων και Εικονική Πραγματικότητα και η εκτέλεσή της συνεισϕέρει έως 4 επιπλέον μονάδες στην τελική βαθμολογία. Η εργασία θα πρέπει να εκτελεσθεί σε ομάδες ενός ή δύο ατόμων, και αποτελείται από 2 ενότητες. Η πρώτη ενότητα περιλαμβάνει 5 ζητούμενα. Τα ζητούμενα μπορούν να εκτελεσθούν ανεξάρτητα το ένα από το άλλο, και η ορθή υλοποίηση κάθε ζητούμενου συμβάλει κατά 0.4 μονάδες. Η ενότητα αυτή περιλαμβάνει την κατασκευή 5 συστημάτων, τα οποία σχετίζονται με τη γενική δομή ενός κωδικοποιητή. Μπορείτε προαιρετικά να χρησιμοποιείτε τα εργαλεία που δίνονται στο site του μαθήματος http://vader.ee.auth.gr/mugteaching/msvr.html για να ελέγχετε τις υλοποιήσεις σας. Η δεύτερη ενότητα προϋποθέτει την ορθή εκτέλεση της πρώτης υποενότητας. Έχει τη μορϕή διαγωνισμού, και συνεισϕέρει 2 μονάδες στον νικητή του διαγωνισμού. Στους υπόλοιπους συμμετέχοντες συνεισϕέρει λιγότερες μονάδες, οι οποίες υπολογίζονται από την επίδοση του κάθε διαγωνιζόμενου, σε σχέση με την επίδοση του νικητή. 1
2 Επιμέρους συστήματα του κωδικοποιητή & αποκωδικοποιητή 2.1 Σύστημα υποδειγματοληψίας Έστω διακριτό σήμα x(i), i Z, το οποίο έχει προκύψει έπειτα από δειγματοληψία αναλογικού σήματος, με συχνότητα δειγματοληψίας f s1. Κατασκευάστε τη συνάρτηση y=changefs(x,fs1,fs2) ο οποία λαμβάνει ως είσοδο το διακριτό σήμα x συχνότητας δειγματοληψίας fs1, καθώς και μία νέα συχνότητα δειγματοληψίας fs2, και επιστρέϕει το σήμα y το οποίο προκύπτει αλλάζοντας τη συχνότητα δειγματοληψίας του x από fs1 σε fs2, είτε με υποδειγματοληψία (downsampling) είτε με υπερδειγματοληψία (up-sampling). Για την άρση της απροσδιοριστίας σε σχέση με την τοποθέτηση των νέων δειγμάτων ως προς τα παλιά, υιοθετήστε την σύμβαση ότι οι χρόνοι του πρώτου δείγματος των δύο ακολουθιών συμπίπτουν. Στην πραγματικότητα, η έξοδος της συνάρτησης δεν εξαρτάται από τις τιμές των fs1 και fs2 χωριστά, αλλά μόνο από το λόγο τους fs/fs2. Για λόγους συμβατότητας, η έξοδος της συνάρτησης θα πρέπει να έχει μήκος floor(fs2/fs1*(length(x)-1)) Δεν επιτρέπεται να χρησιμοποιήσετε έτοιμες συναρτήσεις όπως τις resample, upsample και downsample. Χρησιμοποιήστε την testq1() για να ελέγξετε την υλοποίησή σας. 2.2 Σύστημα γραμμικής πρόβλεψης Δεδομένου ενός μονοδιάστατου σήματος x(i), i Z, και ενός ακεραίου m > 0, ορίζουμε το διάνυσμα x m [k] όπου k Z ως x m [k] = [x(k), x(k 1),, x(k m + 1)] T (1) Έστω πεπερασμένου μήκους διακριτό σήμα x(i), i [0, N 1]. Ο βέλτιστος γραμμικός προβλέπτης τάξης m για το σήμα x(i) είναι ο για τον οποίον η συνάρτηση κόστους ˆx(i) = w T x m [i 1] (2) J = N 1 i=m (x(i) ˆx(i)) 2 (3) ελαχιστοποιείται ως προς το διάνυσμα συντελεστών w. Κατασκευάστε τη συνάρτηση 2
w=lpcoeffs(x,m) η οποία υπολογίζει τους συντελεστές του βέλτιστου προβλέπτη. Δεν επιτρέπεται να χρησιμοποιήσετε έτοιμες συναρτήσεις όπως ar. Χρησιμοποιήστε την testq2() που σας δίνεται για να υπολογίσετε το τετραγωνικό σϕάλμα της πρόβλεψης και να αξιολογήσετε την υλοποίησή σας. 2.3 Σύστημα κβαντιστή & αποκβανιστή Έστω βαθμωτό μέγεθος x. Υλοποιήστε τη συνάρτηση κβαντισμού q=quant(x,d) η οποία επιστρέϕει το σύμβολο του κβαντιστή στο οποία αντιστοιχεί το δείγμα x. Οι στάθμες απόϕασης δίνονται στο διάνυσμα D μήκους k. Συγκεκριμένα, οι στάθμες αυτές ορίζουν τις ζώνες απόϕασης (, D(1)], (D(1), D(2)], κ.λπ., και (D(k), + ). Η έξοδος q της συνάρτησης αναπαριστά το παραγόμενο σύμβολο στην έξοδο του κβαντιστή. Χρησιμοποιείστε την σύμβαση ότι το q είναι ακέραιος και δηλώνει τον αύξοντα αριθμό της ζώνης, δηλαδή q {1, 2,..., k + 1}. Κατασκευάστε τον αντίστοιχο αποκβαντιστή x=iquant(q,l) ο οποίος επιστρέϕει την αποκβαντισμένη τιμή του σύμβολου q, και το διάνυσμα L μήκους k+1 περιέχει τις στάθμες κβαντισμού. Τέλος, κατασκευάστε τη συνάρτηση [D,L]=quantLevels(n,xmin,xmax) η οποία υπολογίζει τις στήλες D και L οι οποίες αντιστοιχούν στην ειδική περίπτωση του ομοιόμορϕου κβαντιστή ο οποίος χρησιμοποιεί n bits και υποδιαιρεί το διάστημα [xmin, xmax] σε 2 n ίσες ζώνες απόϕασης. Οι τιμές xmin και xmax προσδιορίζουν το εύρος τιμών της εισόδου του κβαντιστή. Οι στάθμες κβαντισμού θα πρέπει να βρίσκονται στο μέσο της αντίστοιχης ζώνης. Χρησιμοποιήστε την testq3() που σας δίνεται για να ελέγξετε την υλοποίησή σας. 2.4 Κωδικοποίηση & αποκωδικοποίηση A-DPCM Υλοποιείστε τη συνάρτηση [rq,wq]=adpcm(x,d,l,m,wmin,wmax,n) 3
η οποία πραγματοποιεί A-DPCM κωδικοποίηση. Το x είναι ένα διάνυσμα που περιέχει διαδοχικά δείγματα. Τα D και L είναι οι ζώνες από- ϕασης και στάθμες κβαντισμού αντίστοιχα, του κβαντιστή των σϕαλμάτων πρόβλεψης r (residuals). Υλοποιήστε ένα μοντέλο γραμμικής πρόβλεψης τάξης m, οι συντελεστές του οποίου κβαντίζονται με έναν ομοιόμορϕο κβαντιστή, ο οποίος προσδιορίζεται από τις παραμέτρους xmin, xmax και n, όπως αναϕέρεται και στην ενότητα 3.1.3. Η έξοδος της συνάρτησης είναι τα σύμβολα του κβαντιστή των σϕαλμάτων πρόβλεψης rq και τα σύμβολα του κβαντιστή των συντελεστών του μοντέλου γραμμικής πρόβλεψης wq. Στη συνέχεια, υλοποιείστε τη συνάρτηση xd=iadpcm(rq,wq,l,wmin,wmax,n) η οποία ``αντιστρέϕει'' τη διαδικασία της adpcm. Το xd είναι ένα διάνυσμα που περιέχεια τα αποκωδικοποιημένα (decoded) δείγματα. Το rq περιέχει τα τα σύμβολα των σϕαλμάτων πρόβλεψης, τα οποία πρέπει να αποκβαντιστούν μέσω του αποκβαντιστή με στάθμες κβαντισμού L. Τέλος, το wq περιέχει τους m συντελεστές πρόβλεψης, οι οποίοι έχουν κβαντιστεί και πρέπει να αποκβαντιστούν από το ζεύγος κβαντιστήαποκβαντιστή που προδιαγράϕεται από τις παραμέτρους xmin, xmax και n. Χρησιμοποιήστε την testq4() που σας δίνεται για να ελέγξετε την υλοποίησή σας. 2.5 Κωδικοποίηση & αποκωδικοποίηση Huffman Στη συνέχεια υλοποιήστε ένα σύστημα κωδικοποίησης Huffman. Αρχικά υλοποιήστε τη συνάρτηση s=hufflut(p) όπου τα s και p είναι διανύσματα ίσου μήκους n. Το p(i) είναι η πιθανότητα εμϕάνισης του i-οστού συμβόλου, ενώ το s είναι ένα cell array, και το s(i) αποτελείται αποκλειστικά από '0' και '1', και είναι ο κώδικας Huffman του συμβόλου. Κατασκευάστε την ακόλουθη συνάρτηση η οποία υλοποιεί τον ευθή μετασχηματισμό Huffman b=huff(q,s) όπου q είναι ένα δυάνισμα με τους αύξοντες αριθμούς συμβόλων, και το b ένα character array που περιέχει αποκλειστικά '0' και '1' και είναι το bit stream που παράγεται από τα κωδικοποιημένα σύμβολα. Το διάνυσμα s είναι το διάνυσμα που παράγει η προηγούμενη συνάρτηση (hufflut). 4
Τέλος, κατασκευάστε την συνάρτηση η οποία υλοποιεί τον αντίστροϕο μετασχηματισμό Huffman [q,n]=ihuff(b,s) όπου το b είναι ένα character array παρόμοιο με αυτό της εξόδου της huff, και s ο πίνακας συμβόλων που παράγει η hufflut. Το διάνυσμα q περιέχει τις αποκωδικοποιημένες τιμές που προκύπτουν από την επεξεργασία του bit stream b. Θεωρήστε ότι η αποκωδικοποίηση ξεκινά υποχρεωτικά από το πρώτο στοιχείο του b. Προκειμένου η συνάρτηση αυτή να μπορεί να χρησιμοποιηθεί σε απροσδιόριστου μήκους bit streams b, η υλοποίηση πρέπει να αποκωδικοποιεί όσα περισσότερα σύμβολα μπορεί από το bit stream b, και να επιστρέϕει τον αριθμό n των bits που δεν κατάϕερε να αποκωδικοποιήσει, ώστε αυτά να χρησιμοποιηθούν στην επόμενη κλήση της ihuff. Δεν επιτρέπεται να χρησιμοποιήσετε έτοιμες συναρτήσεις όπως τις huffmandict και huffmanenco. Χρησιμοποιήστε την testq5() που σας δίνεται για να ελέγξετε την υλοποίησή σας. 3 Ολοκληρωμένο σύστημα κωδικοποιητή & αποκωδικοποιητή Η δεύτερη ενότητα έχει τη μορϕή διαγωνισμού. Καλείστε να κατασκευάσετε ένα ζευγάρι κωδικοποιητή και αποκωδικοποιητή για στερεοϕωνικά μουσικά κομμάτια ήχου, με συχνότητα δειγματοληψίας 44.1 khz ανά κανάλι. 3.1 Κινούμενο παράθυρο Τόσο ο κωδικοποιητής, όσο και ο αποκωδικοποιτής, θα πρέπει να επεξεργάζονται παράθυρα σταθερού μήκους n. Κατασκευάστε τη συνάρτηση η οποία επιστρέϕει αυτή την τιμή. 3.2 Κωδικοποιητής n=getparams() Στη συνέχεια, κατασκευάστε τη βασική συνάρτηση κωδικοποίησης ενός παραθύρου [b,newstate]=encoder(x,state) 5
όπου x είναι ένα παράθυρο n δειγμάτων, και state είναι τύπου struct και περιέχει ένα σύνολο παραμέτρων που χρειάζεται ο κωδικοποιητής σας (πχ huffman codebooks). Η έξοδος b είναι ένα bit stream (διάνυσμα μεταβλητού μήκους char με μοναδικές τιμές τις '0' και '1'), και είναι η κωδικοποιημένη εκδοχή του παραθύρου, ενώ η newstate είναι ένα struct ακριβώς ίδιας δομής με το state, και θα χρησιμοποιηθεί ως είσοδος μαζί με το επόμενο παράθυρο δειγμάτων στην encoder. Η δομή του bit stream b μπορεί να σχεδιαστεί ελεύθερα από εσάς. Μία πιθανή σχεδιάση είναι να χωρίζεται το bit stream σε δύο τμήματα: ένα header σταθερού μήκους που περιέχει παραμέτρους κωδικοποιήσης για το παράθυρο, και ένα μεταβλητού μήκους τμήμα που περιέχει κώδικες huffman. Επίσης, μπορείτε να υιοθετήσετε μία λογική ομαδοποίησης διαδοχικών παραθύρων, τα οποία θα μοιράζονται κάποιες παραμέτρους κωδικοποιήσης. Σε αυτή την περίπτωση το bit stream θα μπορούσε να έχει και ένα τρίτο, προαιρετικό μέρος (δηλαδή δε θα υπάρχει σε κάθε παράθυρο υποχρεωτικά, αλλά μόνο σε κάποια), που θα μεταϕέρει αυτές τις παραμέτρους που αϕορούν την ομάδα παραθύρων. Επίσης, κατασκευάστε την state=initstateencoder() η οποία αρχικοποιεί τις παραμέτρους. Τέλος, κατασκευάστε την συνάρτηση myencoder(wavfilename,codedfilename) η οποία λαμβάνει το όνομα ενός αρχείου τύπου wav προς κωδικοποίηση στη wavfilename, το κωδικοποιεί, και αποθηκεύει την κωδικοποιημένη εκδοχή στο αρχείο με όνομα που προσδιορίζεται από την codedfilename. Το αρχείο αυτό θα πρέπει να είναι ένα mat file και να περιέχει μία μόνο μεταβλητή, την b, η οποία θα είναι ένα bit stream. 3.3 Αποκωδικοποιητής Κατασκευάστε τη συνάρτηση [x,newstate]=decoder(b,state) η οποία αποκωδικοποιεί το διάνυσμα b, το οποίο έχει προκύψει ως έξοδος του κωδικοποιητή σας για κάποιο παράθυρο, και τη state=initstatedecoder() η οποία αρχικοποιεί τις παραμέτρους για την αποκωδικοποίηση. Ας σημειωθεί ότι οι μεταβλητές state και newstate που εμϕανίζονται στις δύο παραπάνω συναρτήσεις είναι όλες τύπου struct και είναι ίδιας ακριβώς δομής μεταξύ τους. Ωστόσο, δεν έχουν (απαραίτητα) 6
σχέση με τις ομόνυμες μεταβλητές που εμϕανίζονται στον κωδικοποιητή. Τέλος, κατασκευάστε και τη συνάρτηση mydecoder(codedfilename,wavfilename) η οποία αντιστρέϕει την myencoder. 3.4 Διαγωνισμός Για να ελέγξετε την επίδοση του συστήματός σας, ακολουθήστε την εξής διαδικασία. Τοποθετείστε όλα τα αρχεία που περιέχουν τις συναρτήσεις του κεϕαλαίου 3 σε ένα ϕάκελο. Επίσης τοποθετείστε τα εργαλεία αξιολόγησης καθώς και τα αρχεία ήχου (audio samples) που θα βρείτε στο site της εργασίας στον ίδιο ϕάκελο. Στη συνέχεια θα χρειαστεί να εκτελέσετε μία ϕορά το script setup. Aπό το σημείο και αυτό, μπορείτε να ελέγχετε τις επιδόσεις του κωδικοποιητή σας εκτελώντας το script submit. Η καλύτερη επίδοση ανά ομάδα θα εμϕανίζεται στο site. Για να ενημερώνετε το site για τις δικές σας επιδόσεις, αρκεί την ώρα που εκτελείτε το submit να είστε συνδεδεμένοι στο διαδύκτιο. Ο κώδικας του κωδικοποιητή και του αποκωδικοποιητή σας θα πρέπει να είναι ορθά δομιμένος, σύμϕωνα με τις αρχές του δομημένου προγραμματισμού. Αποϕύγετε να εκτελείτε την ίδια υπολογιστή διαδικασία σε δύο ή παραπάνω διαϕορετά σημεία στον κώδικά σας, χρησιμοποιώντας κατάλληλα σχεδιασμένες συναρτήσεις. Τέλος, αν χρειαστείτε αυτούσιες συναρτήσεις που έχετε υλοποιήσει στην πρώτη ενότητα της εργασίας, μην αντιγράϕετε τα αρχεία των συναρτήσεων στο ϕάκελο taskq6, αλλά χρησιμοποιήστε τις εντολές addpath και rmpath με relative paths. Πχ, για να έχετε διαθέσιμη την συνατηση changefs, χρησιμοποιήστε τις addpath../taskq1 y=changefs(x,fs1,fs2); rmpath../taskq1 θεωρώντας ότι βρίσκεστε τον ϕάκελο taskq6. 4 Αξιολόγηση & Παραδοτέα Οι εργασίες θα αξιολογηθούν μετά τη λήξη της ημερομηνίας υποβολής των εργασιών. Για την πρώτη ενότητα, η σημαντικότερη παράμετρος είναι η ορθή (βάσει θεωρίας) υλοποίηση των ζητούμενων. Για τη δεύτερη ενότητα, οι κωδικοποιητές θα ελεγχθούν ώστε να αποϕευχθούν μη ορθές υλοποιήσεις, πχ υλοποιήσεις οι οποίες ``ξεγελούν'' το 7
Φάκελος task1 task2 task3 task4 task5 task6 Πίνακας 1: Διάρθρωση των αρχείων κώδικα Αρχεία changefs.m lpcoeffs.m Quant.m, iquant.m, quantlevels.m adpcm.m, iadpcm.m hufflut.m, huff.m, ihuff.m getparams.m, encoder.m, initstateencoder.m, myencoder.m, decoder.m, initstatedecoder.m, mydecoder.m, και όσα άλλα αρχεία χρειάζεστε σύστημα και πετυχαίνουν πλασματικά scores. Το score υπολογίζεται λαμβάνοντας υπόψη (α) το βαθμό συμπίεσης, και (β) το σϕάλμα ανακατασκευής. Παραδώστε 1. Τα αρχεία κώδικα MATLAB που υλοποιήσατε με αναλυτικά σχολιασμένο κώδικα στα αγγλικά, χωρισμένα σε 6 ϕακέλους, κατά αντιστοιχία με τα 5 συστήματα της πρώτης ενότητας και το ολοκληρωμένο σύστημα κωδικοποιητή/αποκωδικοποιητή της δεύτερης ενότητας. Συμβουλευτείτε τον Πίνακα 1. 2. Αναϕορά σε PDF που θα περιγράϕει τον τρόπο υλοποίησης του προβλήματος (μαθηματικά και προγραμματιστικά) και θα παρουσιάζει - σχολιάζει τα αποτελέσματα σε χωριστή ενότητα για κάθε σύστημα. Επιπλέον Υποβάλετε ένα και μόνο αρχείο, τύπου zip. Το όνομα του αρχείου πρέπει να είναι AEM1.zip για τις ομάδες ενός ατόμου και AEM1_AEM2.zip για τις ομάδες δύο ατόμων, όπου AEM1 είναι το ΑΕΜ του πρώτου ϕοιτητή της ομάδας, και AEM2 είναι το ΑΕΜ του δεύτερου ϕοιτητή της ομάδας, αν υπάρχει. Το προς υποβολή αρχείο πρέπει να περιέχει τους 5 ϕακέλους που αναϕέρονται στον Πίνακα 1 και το αρχείο report.pdf το οποίο θα είναι η αναϕορά της εργασίας. Αν κατασκευάσετε και χρησιμοποιήσετε επιπλέον συναρτήσεις από αυτές που ζητούνται, τοποθετήστε τα αντίστοιχα αρχεία κώδικα στον κατάλληλο ϕάκελο. 8
Μην υποβάλετε αρχεία που δεν χρειάζονται για την λειτουργία του κώδικά σας, ή ϕακέλους/αρχεία που δημιουργεί το λειτουργικό σας, πχ ``Thumbs.db'', ``.DS_Store'', ``.directory''. Μην υποβάλετε τα εργαλεία που σας δίνονται (testq*, setup.p, κλπ) Μην υποβάλετε τα δείγματα ήχου που σας δίνονται. Η αναϕορά πρέπει να είναι ένα αρχείο τύπου PDF, και να έχει όνομα report.pdf. Για την ονομασία των αρχείων, ϕακέλων, κλπ που περιέχονται στο προς υποβολή αρχείο, χρησιμοποιείτε μόνο αγγλικούς χαρακτήρες, και όχι ελληνικούς ή άλλα σύμβολα, πχ ``#'', ``$'', ``%'' κλπ. Όλα τα αρχεία εκτός της αναϕοράς πρέπει να είναι αρχεία κειμένου τύπου UTF-8. Καλή επιτυχία! 9