Analyzer & Equalizer. Afdeling for kommunikations teknologi 19. december 2002 Aalborg Universitet. Gruppe 506

Relaterede dokumenter
1 Problemanalyse Unified Modeling Language Problemformulering... 4

Analyzer & Equalizer. Afdeling for kommunikations teknologi 19. december 2002 Aalborg Universitet. Gruppe 506

1 Problemanalyse Unified Modeling Language Problemformulering... 4

PC-baseret analyzer og equalizer

PC-baseret analyzer og equalizer

Testsignaler til kontrol af en målekæde

4. Semesterprojekt System Arkitektur. MyP3000 I4PRJ4 E2004

DM507 Algoritmer og datastrukturer

Hassansalem.dk/delpin User: admin Pass: admin BACKEND

Målet for disse slides er at diskutere nogle metoder til at gemme og hente data effektivt.

Systemkald DM Obligatoriske opgave. Antal sider: 7 inkl. 2 bilag Afleveret: d. 18/ Afleveret af: Jacob Christiansen,

Øvelsesvejledning. Frekvenskarakteristikker Simulering og realisering af passive filtre.

Målet for disse slides er at beskrive nogle algoritmer og datastrukturer relateret til at gemme og hente data effektivt.

Total systembeskrivelse af AD1847

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

ELCANIC A/S. ENERGY METER Type ENG110. Version Inkl. PC program: ENG110. Version Betjeningsvejledning

Visualiseringsprogram

Software Construction 1. semester (SWC) januar 2014 Spørgsmål 1

3 Overføringsfunktion

Klasse 1.4 Michael Jokil

Software Dokumentation

Streame fra Winamp til Dreambox/pc på netværk.

Kursusgang 11. Oversigt: Sidste kursusgang Værktøjer til udvikling og implementering af HCI-design Oversigt over Java Swing

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

Indholdsfortegnelse for kapitel 2

Miniprojekt2011. Formålet er at lære og indlære god objektorienteret programudvikling og programmering med Java, samt undervejs at opfylde studiekrav.

Daglig brug af JitBesked 2.0

DM507 Algoritmer og datastrukturer

Online billede filtrering

Hvad skal du vide for at bygge din egen computer?

Piano Tuning & String Analyzing Tool

Kursus i brug af Pinnacle Studio 9

C R. Figur 1 Figur 2. er eksempler på kredsløbsfunktioner. Derimod er f.eks. indgangsimpedansen

DM507 Algoritmer og datastrukturer

AVR MP Ingeniørhøjskolen i Århus Michael Kaalund

Programmering i C. Lektion september 2009

Problemstilling ved DBK integration i BIM Software Hvad skal der til. Nicolai Karved, Betech Data A/S

CCS Formål Produktblad December 2015

Abstrakte datatyper C#-version

MP3 player med DMX interface.

DANMARKS TEKNISKE UNIVERSITET

09/ Version 1.4 Side 1 af 37

Call Recorder Apresa Brugermanual

PHP 3 UGERS FORLØB PHP, MYSQL & SQL

HTX, RTG. Rumlige Figurer. Matematik og programmering

Vejledning til Teknisk opsætning

Tilgang til data. To udbredte metoder for at tilgå data: Sekventiel tilgang Random access: tilgang via ID (også kaldet key, nøgle) for dataelementer.

DM507 Algoritmer og datastrukturer

Signalbehandling og matematik 1 (Tidsdiskrete signaler og systemer)

ITWIN1. Afsluttende projekt. PhotoDays. Benjamin Sørensen (02284) Tomas Stæhr Berg (03539)

Programmering C RTG

dmasark Aflevering - Uge 50

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

Andreas Lauge V. Hansen klasse 3.3t Roskilde HTX

Version Dato Beskrivelse /11/2012 Initial version /03/2013 Tilføjet eksempel med Template Agent, generelt udvidet dokumentet.

Michael Jokil

Arduinostyret klimaanlæg Afsluttende projekt informationsteknologi B

SOFTWARE DOKUMENTATION

MANUAL. Præsentation af Temperaturloggerdata. Version 2.0

Installation af GPS med tilslutning til USB port

SÅDAN BRUGER DU REGNEARK INTRODUKTION

Software Construction 1 semester (SWC) Spørgsmål 1

FESD-standardiseringsgruppen Att: Palle Aagaard IT- og Telestyrelsen IT-strategisk kontor Holsteinsgade København Ø

Case: Svømmeklubben Delfinen

Design og udvikling af et blodtryks ma lesystem

Ugeseddel 4 1. marts - 8. marts

Hurtig Start Guide 1

Rapport. Undersøgelse af Dantale DVD i forhold til CD. Udført for Erik Kjærbøl, Bispebjerg hospital og Jens Jørgen Rasmussen, Slagelse sygehus

MSI pakke til distribution af AutoPilot komponenter.

Det Teknisk-Naturvidenskabelige Fakultet Aalborg Universitet

AUTOMATION SERVICE. Sådan anvender du programmet Automation Service. Udviklet af PC SCHEMATIC A/S

DM507 Algoritmer og datastrukturer

Indhold. Maskinstruktur Kapitel 1. Assemblersprog Indledning Hop-instruktioner Input og output...

Indhold. Evalueringsvejledning. En undersøgelse fra start til slut involverer 4 programmer: - SurveyXact - Excel - E-learn - SiteCore

Arduino Programmering

Programmering C Eksamensprojekt. Lavet af Suayb Köse & Nikolaj Egholk Jakobsen

Tilgang til data. To udbredte metoder for at tilgå data: Sekventiel tilgang Random access: tilgang via ID (key, nøgle) for dataelementer.

2. De 7 signaler skal kodes til en 3-bit kode. Enkodningen skal prioriteres som beskrevet i afsnit?? på side??.

DIVISIONSMATCHBEREGNING VERSION 1.07

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

Elektronisk signering manual 1.3

SwipBox forsendelses modul til Magento

Opgave: BOW Bowling. Rules of Bowling. danish. BOI 2015, dag 1. Tilgængelig hukommelse: 256 MB

EDI. Microsoft Dynamics NAV 2009 SP1 Klassisk. Side 1. Copyright: Naddon version

Indhold. Figur 1: Blokdiagram over regulatorprincip

Ruko SmartAir. Updater installation

Automatisk Vandingssystem

Curriculum Vitae. Uddannelse: 2001 Civilingeniør fra Danmaks tekniske universitet, fagprofil: styring og regulering.

GSM port styring 400 brugere

DM507 Algoritmer og datastrukturer

APPENDIX A INTRODUKTION TIL DERIVE

Adobe Digital Editions

Hvem er vi? Kursus Introduktion. Kursuslærerne. Agenda for i dag

Continia e faktura Brugermanual. Version 3.08 december Continia Software A/S Hjulmagervej 55 DK-9000 Aalborg Denmark

Vejledning: AMUUDBUD.DK

Det skrå kast, en simulation

DM507 Algoritmer og datastrukturer

Transkript:

Analyzer & Equalizer Afdeling for kommunikations teknologi 19. december 2002 Aalborg Universitet Gruppe 506

AALBORG UNIVERSITET INSTITUT FOR ELEKTRONISKE SYSTEMER AFDELING FOR KOMMUNIKATIONSTEKNOLOGI Fredrik Bajersvej 7 DK-9220 Aalborg Øst Telefon 96 35 80 80 TITEL: Analyzer & Equalizer TEMA: Apparat/system konstruktion PROJEKTPERIODE: 5. semester september til december 2002 PROJEKTGRUPPE: 506 GRUPPEMEDLEMMER: Dan Dejgård Hermansen Kristian Kjær Hans Johnny Nørgaard Madsen Torben Nørregaard Matzen Morten Højfeldt Rasmussen Steven André Skaaning Jesper Mølgaard Sommerset SYNOPSIS Formålet med dette projekt er SKAL SKRIVES... VEJLEDER: Søren Krarup Olesen OPLAGSTAL: 10 RAPPORT: 62 AFSLUTTET: 19. december 2002 Projektgruppe 506, Aalborg Universitet

Forord Denne rapport er udarbejdet af gruppe 506, 5. semester på elektronik og elektroteknik ved Institut for elektroniske systemer, Aalborg Universitet. Målgruppen for rapporten er medstuderende. Referencer til den benyttede litteratur er udført efter Harvard-metoden, med kilderne opstillet alafabetisk efter forfatteren, hvor denne kendes. En reference før et punktum henviser til specifik information i den foregående sætning. En henvisning efter et punktum henviser til det foregående afsnit. Hvor en kilde danner grundlag for et helt kapitel er dette anført i starten af kapitlet. Vedlagt findes en CD, som indeholder datablade, rapporten i PDF- og DVI-format, samt kildekode til den under projektet udarbejdede software. En henvisning til en fil på den vedlagte CD er i rapportteksten udført som følger: (?, projektoplaeg.pdf). Filen "projektoplaeg.pdf"kan her findes i biblioteket "rapport/"på CD en. Henvisning til et brudstykke af kildekoden er i rapportteksten udført som følger: /* Kode taget fra aegui.cpp */. Kildekodeudsnittet kan her findes under afsnittet aegui.cpp i appendiks. [*Note *] Dokumentation for klassetest forefindes i de relaterende afsnit under softwaredesign, hvorimod integrationstestene for klasserne forefindes i appendiks. Apparaturliste, eldiagram samt komponentliste er indsat sidst i rapporten. Muligvis skal der næv om testrammernes plac hvorvidt de er i appendi Hvor tal i hexadecimal benyttes er disse anført med syntaksen: 0xA1, som representere tallet 161 i traditionel decimalnotation, hvor 0x-præfikset angiver hexadecimalnotation. I forbindelse med forsøg i det lyddøde rum vil vi gerne rette tak til Claus Vestergaard for en storstillet hjælp med apparaturvalg, opstilling og målinger. Dan Dejgaard Hermansen Kristian Kjær Hans Johnny Nørgaard Madsen Torben Nørregaard Matzen Morten Højfeldt Rasmussen Steven André Skaaning Jesper Mølgaard Sommerset Aalborg Universitet, 19. december 2002

Indhold 1 Indledning 1 2 Problemanalyse 2 2.1 Softwareanalyse og -design med UML.................. 2 2.2 Foranalyse................................. 3 2.3 Analyse.................................. 3 2.4 Design................................... 5 2.5 Afslutning på problemanalysen...................... 8 3 Designfase 9 3.1 Design af filtre.............................. 9 3.1.1 Frekvensområde og opdeling i frekvensbånd.......... 9 3.1.2 Udregning af knækfrekvenser.................. 9 3.1.3 Program til udregning af knækfrekvenser............ 9 3.1.4 Båndpasfiltre til analyzer..................... 11 3.1.5 Digital filterdesign........................ 13 3.1.6 Test................................ 14 3.2 Design af software............................ 15 4 Softwaredesign 21 4.1 Indledning................................. 21 4.2 Fejlhåndtering............................... 21 4.3 CExternal................................. 23 4.3.1 System V IPC........................... 24 4.3.2 Tilfældet CExternal........................ 24 4.3.3 Test................................ 26 4.4 CSound.................................. 26 4.4.1 Behandling af data til CSoundCard............... 26 4.4.2 Afspilning af pink noise..................... 26 4.4.3 Fejlhåndtering.......................... 27 4.4.4 Testramme for funktionerne................... 27 4.5 Interface til lydkort............................ 27 4.5.1 Initialisering af lydkort...................... 27 4.5.2 Afspilning og optagelse..................... 28 4.5.3 Test................................ 29 4.6 CAnalyzer................................. 29 4.6.1 Båndpasfiltrenes RMS-værdier.................. 30 4.6.2 Returnering af RMS-værdier................... 31

Indhold iii 4.6.3 Fejlhåndtering.......................... 31 4.6.4 Testramme for funktionaliterne.................. 32 4.7 Implementering af filtre.......................... 32 4.7.1 Test af CFilter.......................... 33 4.8 Den grafiske brugerflade......................... 33 4.8.1 Qt................................. 34 4.8.2 Projektets grafiske brugerflade.................. 35 4.8.3 Aegui - GUI s main window................... 36 4.8.4 CButton.............................. 37 4.8.5 GraphWindow.......................... 40 4.8.6 Kodning af en speciel Qt widget................. 41 4.8.7 CSliderWindow.......................... 42 4.8.8 CPlayWindow.......................... 44 4.8.9 Trådet styring af data, signaler og fejlhåndtering........ 46 4.9 Integrationstest.............................. 50 5 Konklusion 51 6 Nomenklaturliste 52 A Mikrofon 53 A.1 Forsøg i lyddødt rum........................... 53 B Apparaturliste 56 C Komponentliste 57 D UML 58 E Kildekode 59 Bilag 60

Figurer 2.1 Deployment diagram for analyzeren.................... 3 2.2 Deployment diagram for equalizeren................... 4 2.3 Deployment diagram for kalibreringen.................. 4 2.4 Use case diagram for GUI......................... 6 2.5 Sekvensdiagram for adjust frequency characteristics........... 7 3.1 Forhold mellem opdeling i 1 N og 1 1 oktav båndbredde........ 10 3.2 Filtrenes overlapning............................ 11 3.3 a) 2. orden og b) 3. ordens polplacering i s-domænet.......... 12 3.4 y n som respons på en puls x n 32000 filtreret gennem et 5. ordens filter. Det bemærkes at filtreret er stabilt................. 15 4.1 Dobbeltbuffer-systemet.......................... 28 4.2 Således er data til lydkortet formateret.................. 29 4.3 Illustration af placering af RMS-værdier i rmscoeff()........... 31 4.4 Udkast til GUI, udarbejdet fra usecases.................. 36 4.5 Illustration af vinduet med nogle af knapperne og radionbutton...... 38 4.6 Illustration af signalvejen ved knaptryk.................. 39 4.7 Oversigt over integrationstestens første trin før overgangen til Main... 50 A.1 Placering af mikrofon og højttaleren i henhold til hinanden........ 53 A.2 Forsøgopstilling for måling af frekvenskarakteristik. Cifrerne representerer apparaturerne fra tabel B.1, og Mic representerer den konstruerede mikrofon.................................. 54 A.3 Frekvenskarakteristik for reference mikrofonen.............. 55 A.4 Frekvenskarakteristik for den konstruerede mikrofonen.......... 55 A.5 Differencering af frekvenskarakteristik for den konstruerede og reference mikrofonen.............................. 55 C.1 Diagram for konstruktionen af mikrofonen samt forstærker til produktet. 57

Tabeller 3.1 Metodespecifikation for CExternal..................... 16 3.2 Metodespecifikation for CButton...................... 17 3.3 Metodespecifikation for CSound...................... 18 3.4 Metodespecifikation for CSoundCard................... 18 3.5 Metodespecifikation for CAnalyzer.................... 19 3.6 Metodespecifikation for CEqualizer.................... 19 3.7 Metodespecifikation for CGraphWindow................. 19 3.8 Metodespecifikation for CSliderWindow.................. 20 3.9 Metodespecifikation for CSlider...................... 20 3.10 Metodespecifikation for CFilter...................... 20 4.1 Metodeoversigt for klassen CAnalyzer.................. 30 4.2 Trykknapper................................ 38 4.3 Metodeoversigt for klassen GUIThread................. 46 6.1 Nomenklaturliste............................. 52 B.1 Apparatur................................. 56

1 Indledning Projektoplægget (?, projektoplaeg.pdf) for dette projekt omtaler bl.a. måling af fysiske systemer, såsom mikrofoner, filtre, m.m, i sand tid. Målingerne for systemerne skal være informationsgivende om frekvensgangen, samt afslørende for forvrængningskomponenters størrelse og natur. Gruppen har et personligt engaragement i produkt udover projketsmæssige aspekter, idet alle gruppens medlemmer er indehavere af pc er, samt tilhørende multimediehøjttaler. I den forbindelse er det interessant, hvilken kvalitet og egenskaber højttaler og ikke mindst lyden har, der observeres af brugeren. Et system, der kan måle og foretage en analyse af målinger i forbindelse med frekvensanalyse, vil være informationsgivende, men vil ikke løse problemet. Til dette vil en equalizer med oplysningerne fra målingerne være problemløseren, idet den aktivt kompenseres for højttalernes, samt tilnærmelsesvis omgivelsernes, manglende egenskaber og kvalitet. Brugen af systemet skal være fleksibelt, idet der ikke er to brugere, som er ens angående lydopfattelse og lydindstilling. Det skal derfor være muligt med personlige indstillinger, hvilket brugeren muligvis skal guides igennem, da systemet kræver lidt kendskab til funktionen af frekvensområder. Inden systemet kan anvendes skal den designes og konstrueres, hvilket leder til følgende initierende problem: Initierende problem Problemet som gennem projektet skal løses kan formuleres som følger: Hvordan opbygges et system, der kan kompensere for dårlig lyd i (multimedie-) højttalere?

ledning er ikke god - ives! 2 Problemanalyse [*Note *] Projektoplægget til dette projekt henvender sig bl.a. til computerentusiaster og - interesserede, der ønsker den bedst opnåelige lyd fra en PC. Dette mål kan nås vha. et system bestående af en analyzer og en equalizer, hvorigennem frekvensindholdet i lyden korrigeres. Systemet vil være til gavn for såvel afspilning af musik og film som lyd fra spil, da systemet giver en bedre lydoplevelse for brugeren. Om systemet skal bestå af hardware og software eller være ren software er afhængigt af markedsefterspørgsel, men da PC er efterhånden bliver kraftigere og har en større ydeevne, vil det være fordelagtigt, at det er et softwaresystem, idet systemintegration er mere enkelt end, hvis det er et system delvist af hardware og software. En ren softwareløsning kræver kun installation af et program, hvorimod en ny hardwareenhed kræver installation af såvel et program som tilslutning af en ekstern eller intern enhed. Idet Gruppen og dens medstuderende, som computerbrugere, vil være en del af målgruppen for produktet, vil det være nærliggende at opsætte kriterier for kravene udfra denne mindre gruppes ønsker til system funktioner. Til opstilling af kravene benyttes det objektorienterede designsprog, UML 1. 2.1 Softwareanalyse og -design med UML Processen ved udvikling af software kan modelleres på mange forskellige måder strækkende sig fra ustruktureret til struktureret. Der kan findes fordele og ulemper ved begge ekstremer, men erfaringsmæssigt er objektorienteret (OO) softwareudvikling stort set et andet udtryk for den strukturerede tankegang. Da gruppen i løbet af semestret har gennemgået et kursus i objektorienteret analyse og design (OOAD) er det derfor oplagt, at tage udgangspunkt heri og samtidig implementere dette i et OO programmeringssprog. Valget af programmeringssprog er, trods kursets fokusering på Java, faldet på C++ af flere årsager. Fra forrige semester har gruppen erfaring med C og desuden har vejleder indgående kendskab til C++, hvilket i forbindelse med problemløsning har været en fordel. Kurset i OOAD har taget udgangspunkt i konceptet kaldet Unified Modeling Language (UML), som mest af alt kan karakteriseres som værende en række standardiserede værktøjer, der kan benyttes sammen eller hver for sig, alt efter hvilke værktøjer og strategier, der ønskes benyttet til løsningen. Der er skrevet en stor mængde litteratur om UML, hvorfor denne rapport udelukkende omhandler gruppens valg af værktøjer og strategier til problemløsningen. 1 Unified Modeling Language

Foranalyse 3 Problemanalysen afspejler gruppens OOAD, der har ligget til grund for den efterfølgende implementering. Den opdeles således i en foranalyse, analysen og slutteligt designet. Selve implementeringen beskrives i det efterfølgende kapitel. 2.2 Foranalyse I en ikke undervisningsmæssig situation ville en foranalyse indebære samtaler med kunden, for at både kunden og udviklerne af systemet kunne spore sig ind på indholdet i systemet og omfanget af den arbejdsmæssige byrde. På baggrund af disse samtaler udarbejdes skitser af delsystemernes fysiske arkitektur. Skitserne kaldes deployment diagrammer og konventionelt opbygget med bestemte symboler. De følgende tre deployment diagrammer på figur 2.1 til 2.3 på næste side benytter sig ikke fuldstændigt af de konventionelle symboler, men tjener stadig samme formål. F1 RMS1 F2 RMS2 Filter Mic F29 RMS29 Figur 2.1: Deployment diagram for analyzeren. På figur 2.1 vises systemets analyzerfunktion og det fremgår heraf, at et signal sendes igennem en mikrofon, hvorefter det opdeles i her 29 filtre (F1...F29). Herefter udregnes gennemsnitsværdien for energien for hvert filterfrekvensbånd (RMS1...RMS29),som endeligt udskrives på skærmen i form af et piktogram, altså et grafisk brugerinterface. Figur 2.2 på næste side viser en lydfil afspillet igennem en player med efterfølgende filtrering i de 29 filtre. Sammensætningen af filtrene afhænger af kalibreringen, der kan ses på figur 2.3 på den følgende side. Kalibreringen foregår i hovedtræk ved at udsende et på forhånd kendt signal, der her er et hvidt støjsignal med samme energimængde i hvert frekvensbånd. Efter at være blevet udsendt igennem højttaleren analyseres signalet og findes ændret indenfor en vis margen, hvoraf højttalerens frekvenskarakteristik kan udregnes. På baggrund af den målte afvigelse udregnes filtrene, så de kompenserer for ændringerne i højttaleren. Herefter gentages processen indtil filtrene er tilpasset, og den afspillede lydfil matcher den analyserede. 2.3 Analyse I foranalysen blev udarbejdet deployment diagrammer for de tre overordnede delsystemer analyzer, equalizer og kalibrering. På baggrund af disse opstilles en række use cases

4 Problemanalyse F1 F2 + Wav Player F29 Figur 2.2: Deployment diagram for equalizeren. A A A f + f f Analyzer Equalizer File Nej: Nye filtre Margin ok? Ja: Stop Figur 2.3: Deployment diagram for kalibreringen.

Design 5 der i sætninger beskriver hvilke krav brugeren stiller til systemet. Hver enkelt use case formuleres i samarbejde med kunden som i dette tilfælde anses som værende bruger af systemet, og som ikke besidder nogen forhåndsviden om den efterfølgende implementation. I gruppens tilfælde er situationen ikke helt reel, men ud fra et objektivt synspunkt fandtes følgende use cases: Brugeren trykker på en knap og det måltes frekvensgang reguleres efter den ønskede frekvensgang. Brugeren skaber den frekvenskarakteristik han ønsker højttaleren og rummet skal have i målepunktet. Brugeren trykker på en knap og får vist højttalerens og rummets frekvenskarakteristik (ved mikrofonens placering. Brugeren trykker på en knap og får grafisk præsenteret det måltes frekvensindhold i realtid. Brugeren skal kunne afspille lyd, således at det behandles gennem equalizeren. De fundne use cases tegnes ind i et use case diagram, som ses i figur 2.4 på næste side. Denne type diagram viser de enkelte use cases, indkapslet i det system de tilhører, samt deres forbindelse til eksterne aktører. Aktører er i denne sammenhæng alle brugere eller systemer der kommunikerer med det analyserede system. To undersystemer, analyzeren og equalizeren, er ved udarbejdelse af use case diagrammet blevet defineret, og de fem use cases er blevet samlet i use case diagrammet for GUI 2, da det er dette undersystem brugeren ser. Use case diagrammet kan efterfølgende benyttes som baggrund for en uddybende diskussion med kunden, hvor udvikleren kan komme med opklarende spørgsmål og lignende for at sikre, at projektet er godt begyndt. Generelt for OO tankegang er tilbagevendende møder med kunden med efterfølgende iterationer i analysen, for jo oftere designet kontrolleres sammen med kunden desto mindre ændringer skal gennemføres per iteration. 2.4 Design Efter de overordnede krav er blevet opstillet igennem use cases, er for hver use case klargjort til yderligere analyse. Hver use case gennemgås sekventielt med efterfølgende udarbejdelse af dertil hørende sekvensdiagrammer. Et eksempel på et sekvensdiagram for use case Adjust Frequency Characteristic findes på figur 2.5 på side 7. For hver funktion der skal udføres vil der i sekvensdiagrammet være et nyt punkt og på denne måde udarbejdes klasserne og deres indhold. De funktioner der skal udføres, svarer til metoderne i klasserne og der kan således udarbejdes en metodespecifikation for hver enkelt metode. Et eksempel på metodespecifikation ses herunder: 2 Graphical User Interface

6 Problemanalyse 1.1, GUI Brugeren trykker på en knap og får grafisk præsenteret det måltes frekvensindhold i realtid Brugeren trykker på en knap og det måltes frekvensgang reguleres efter den ønskede frekvensgang. Show RT frequency characteristic GUI <<extend>> <<extend>> Show speaker char. Brugeren trykker på en knap og får vist højtalerens (og rummets) frekvens karakteristik (ved mic. placering) Bruger Correct measured f char. <<include>> Adjust wanted f char. Analyzer Equalizer Brugeren skaber den frekvens karakteristik han ønsker højtaleren (og rummet) skal have i målepunktet. Play song Stop playing Brugeren kan starte afspilning af en sang, valgt blandt et antal sange, gennem equalizeren. Brugeren kan stoppe afspilningen af den valgte sang 1.1, GUI Figur 2.4: Use case diagram for GUI.

Design 7 Navn receivesignal() Input Signal fra sendsignal(). Beskrivelse Modtager startsignal fra andet subsystem (analyzer/equalizer eller GUI). Output Metodekald. I princippet burde metodespecifikationerne været tilstrækkeligt til at kunne implementere de enkelte metoder. I praksis kræves undervejs en del uddybninger og interface metoderne og klasserne imellem skal stemme overens, hvilket som oftest vil foregå i forbindelse med integrationstesten som omtales i afsnit.[*note *] hvilket afsnit bliver det? 1.1, Adjust frequency characteristic (equ) Receive signal Play noise Store sound instance Filter sound Find RMS Get wanted frequency characteristic from file Compare measured and wanted frequency characteristic Adjust filter coefficients 1.1, Adjust frequency characteristic (equ) Figur 2.5: Sekvensdiagram for adjust frequency characteristics.

8 Problemanalyse 2.5 Afslutning på problemanalysen Together skal nævnes, ok? Igennem problemanalysen er gennemgået hvorledes gruppen har benyttet sig af OOAD ved brug af UML. De anvendte værktøjer og strategier fra UML er blevet eksemplificeret. Ved udarbejdelsen af use case- og sekvensdiagrammer er benyttet er program kaldet Together, som også har været anvendt i undervisningen. [*Note *] Yderligere information om Together findes ikke nævneværdigt i rapporten. Den samlede UML dokumentation med diagrammer findes i appendiks D. Udover de her gennemgåede diagrammer findes også et klassediagram, der viser samtlige klasser; et antal kollaborationsdiagrammer som uddybes i afsnit?? på side?? omkring integrationstest og slutteligt samtlige metodespecifikationer ordnet under klasserne. På vedlagte CD findes samme dokumentation i html-format, så det kan ses via enhver webbrowser med java-understøttelse.

3.1 Design af filtre 3 Designfase For at analysere signalets frekvensindhold, sendes dette gennem et givet antal båndpasfiltre. Antallet af filtre, og båndpasbredden bestemmes af frekvensområdet der analyseres i, og båndopdelings-metoden. 3.1.1 Frekvensområde og opdeling i frekvensbånd Det hørbare område strækker sig fra 20 Hz til 20 khz[*note *], hvorfor dette frekvensom- litt. henvisning!!! råde vælges, dog reduceres den øvre grænse til 16 khz pga. af den valgte mikrofon[*note *]. Opdeling i frekvensbånd foretages efter konstant procentopdelt båndbredde, hvilket henvisning!!! vil sige, at båndbredden udgør en konstant procentdel af den enkelte centerfrekvens. Båndbredden opdeles efter oktav-princippet, dette medfører en logaritmisk frekvensskala, hvilket er i overensstemmelse med den måde, hvorpå det menneskelige øre hører. Den procentdel af centerfrekvensen som båndbredden udgør, bestemmes efter følgende formel: 2 1 N 1 100 (3.1), hvor 1 N angiver båndbredden i oktav. Ofte benyttede båndbredder:1 1, 1 3, 1 12 og 1 24 oktav. (?) 3.1.2 Udregning af knækfrekvenser Ifølge afsnit XX[*Note *] skal der kunne vælges et vilkårlig antal bånd. Dette kan løses ved at angive 1 N oktav båndbredde som input til et program, der opdeler frekvensområdet i F antal Bånd. Desto højere værdi, der påtrykkes N desto højere F, hvormed opløsningen i frekvensområdet øges. Input kan også direkte være iform af F antal bånd, hvilket vil fremgå af efterfølgende udregninger. Output fra samme program returnerer samtlige knækfrekvenser i frekvensområdet. ref til noget krav/design 3.1.3 Program til udregning af knækfrekvenser Der tages i programmet udgangspunkt i en centerfrekvens på 1000 Hz og 1 1 oktavs båndbredde. Udfra disse og båndbredden 1 N eller antallet af bånd F, findes de resterende centerfrekvenser f C_x i frekvensområdet således (se figur 3.1):

10 Designfase x 0 1 2.... F 1/N oktavs centerfrekvenser 15,63 16000 f C_x Hz 6 0 1/1 oktavs centerfrekvenser 4 D f C_D 15,63 1000 16000 Hz Figur 3.1: Forhold mellem opdeling i 1 N og 1 1 oktav båndbredde., hvor f C_x f C_D 2 x 1 N (3.2) f C_D 1000 2 D D 6 4 udgør den laveste og højeste 1 1 oktavs centerfrekvens på hhv. 15 63Hz og 16000kHz, og x 0 1 2 F angiver opdeling i de nye 1 N oktavs centerfrekvenser f C_x (se figur 3.1). Ved at benytte sig af laveste og højeste 1 1 oktav centerfrekvens indsat i (3.2): f C_D D 4 f C_DD 6 2 x 1 N (3.3), uddrages gennem x F et udtryk for1 N, til at indsætte i formel (3.2), når f C_x skal findes ved F antal bånd som input: 1 N log f C_DD 4 log f C_D D 6 log 2 F "! # log 1024 log 2 F$ 1 (3.4) På samme måde uddrages et udtryk for antallet af bånd F ved 1 N som input: F log f C_D D 4 log f C_D D 6 log 2 1 N! # log 1024 log 2 1 N (3.5) Der gives følgende tal-eksempel på at udregne f C_x for filter nummer 6 (x 6) ved 10 filtre (F 10):

& Design af filtre 11 f C_x 1000 2$ 6 % 2& 6 log' 1024( log' 2 10 (*)%),+ 1000Hz Udfra de fundne centerfrekvenser f C_x beregnes de tilhørende knækfrekvenser efter en modificeret version af udtrykket 3.1. Udtrykket, der er fremyndet gennem studier af figur 3.1, opdeles i to formler; f HP for nedre knækfrekvens og f LP for øvre. 1 f HP 2$ N- 2 f C_x (3.6) f LP 2 N- 1 2 f C_x (3.7) Fremgangsmåden bliver derfor, ved F antal bånd som input, at beregne 1 N(formel 3.4), og dernæst udregne f HP og f LP for samtlige 0. x. F. For 1 N som input beregnes F (formel 3.5), og derefter f HP og f LP for samtlige 0. x. F. db 0 3 Hz f HP f C_x f HP f LP f C_x f LP f HP f C_x f LP Figur 3.2: Filtrenes overlapning. 3.1.4 Båndpasfiltre til analyzer Signalets frekvensindhold findes ved at anvende en række båndpasfiltre på signalet for at opdele dette i række frekvensbånd som omtalt i afsnit 3.1.1 og frem, hvorefter RMS niveauet svarende til energien findes for hvert bånd. Båndpasforstærkningen skal være 0 db og ved øvre og nedre knækfrekvens skal forstærkningen være faldet til 3 db således at summen af båndpasfiltrenes overføringsfunktioner er 0 db. Filtersummen vil afvige fra 0 db idet nabofiltrene vil overlappe og derved give et yderligere bidrag. Størrelsen af dette bidrag afhænger derfor af filterordnen og båndbredden. Således at en højere orden og større båndbredde giver en mindre afvigelse.

12 Designfase Filtreordenen kan bestemmes ud fra krav defineret i anderkendte standarder f.eks DIN. Idet analyseren skal køre i realtid kræves det at de implementerede digitale båndpasfiltre kan procesere en sample og beregne RMS hurtigere end 1 f s. Dette betyder at filterorden og antal filtre begrænses af maskinens regnekapacitet. Idet båndpasfiltrene skal være symmetriske skal høj- og lavpas filtrene være af sammme orden, dette medfører at båndpasfilterets orden altid vil være lige. Der ønskes maksimal fladhed i pasbåndet, hvilket betyder at typen skal være af Butterworth. Dette svarer til at filterets poler ligger på en cirkel med radius Ω 0 og er fordelt lige i s-planets venstrehalvplan som skitseret på figur 3.3. Det generelle Butterworth lavpasfilter af N te orden hvor pasbåndsforstærkningen er 0 db kan udtrykkes som formel 3.8. H l p N s / n0 1 π Θ 2n 1 Ω 0 s Ω 0 e jθ (3.8) 2N 1 π 2 a b Figur 3.3: a) 2. orden og b) 3. ordens polplacering i s-domænet Af beregnings grunde opdeles det generelle Butterworth filter af N te orden i en række 2. ordens filtre med komplexkonjugerede poler samt et 1. ordens filter ved ulige filterorden. En kaskadekobling af disse 1. og 2. ordens sektioner vil give det ønskede Butterworth filter. Generelt 2. ordens filter i frekvensdomænet med Laplace operatoren s. H 1 H 2 P Ω 0 e jθ a jb 1 Ω s / 0 Ω s P 0 s Ω 1 0 Ω s / 2 0 Ω s P s P23 2 0 s 2 2as a 1 2 b 1 2 Ω 2 0 s 2 2Ω 0 cos Θ s Ω 1 2 0 Eksempel på et 5. ordens lavpas filter som skal indgå i et 10. ordens båndpasfilter.

Design af filtre 13 H l p Ω s 4 2 0 s 2 2Ω 0 cos Θ 1 s Ω 1 2 0 π Θ n 2n 1 π 2 5 1 2 6 Θ 1 10 π 1085 8 Θ 2 10 π 1445 Ω 2 0 s 2 2Ω 0 cos Θ 2 s 1 Ω 2 0 Ω 0 s 1 Ω 0 TODO?: Bestemmelse af minimum filterorden for eks. 1 og 1/3 oktav bp-filtre. 3.1.5 Digital filterdesign Udfra filtrets overføringsfunktion i det analoge s-domnæne skal dette z-transformeres. Dette kan gøres ved matched, impuls invariant eller bilineær z-transformation. I denne situration anvendes bilineær z-transformation for at udgå aliasing. Aliasing er et problem for de øvre båndpasfiltre som ikke er væsentligt dæmpet ved den halve samplingsfrekvens. Dette vil medføre en amplitude karakteristik som afviger væsentligt fra det analoge prototype filter. Bilineær z-transform: Ved at anvende denne transformation undgås aliaserings fejl og er derfor den beste tilnærmelse til det prototype filtret. Ved denne transformation erstates s i teorien af formel 3.9 men da ln ikke er på lukket form laves en rimelig tilnærmelse, hvilket ses i formel 3.10. s 1 T 2 s 1 z$ 1 T 1 1 z$ 1 lnz (3.9) (3.10) Ved transformationen bliver venstre halvplan i s domænet kortlagt i z domænet inden for enhedscirklen, således at 6 Ω 6 bliver til π 6 ω 6 π. Dette betyder at den analoge frekvens Ω bliver komprimeret og derfor er det nødvendigt at udføre en prewarp af knækfrekvenserne for at rette op på frekvenskarakteristikken af de digitale filtre. Prewarpningskonstanten C erstatter T 2 i formel 3.10, og udregnes ved formel 3.11 C arctan ωt 2 (3.11) De fundne 1. og 2. ordens sektioner i s-domænet z-transformeres individuelt idet z- koefficienterne umiddelbart kan beregnes udfra formler udledt fra det generelle frekvensnormerede 1. og 2. ordens filter i s-domænet. Et eksempel på udregning ses herunder, hvor formel 3.12 på den følgende side udregner en fællesnævner og z-koefficienterne

7 14 Designfase til et 2. ordens lavpasfilter udregnes i formlerne 3.13 til 3.15 (?, side 376). Disse betegnes a 0 til a 2 for tællerkoefficienterne og b 0 til b 2 for nævnerkoefficienterne. C er prewarpningskonstanten og n er den enkelte pol, der regnes på. common_denum 1 2cos cplx n C 1 C 2 (3.12) a 0 1 common_denum b 0 1 (3.13) 2 a 1 2a 0 b 1 1 C 2 common_denum a 2 a 0 b 2 1 2cos 1 cplx n C C 1 2 common_denum (3.14) (3.15) Dette giver en 2. ordens sektion i z-domænet beskrevet ved formel 3.16, der på y n - form ser ud som i formel 3.18. Dette filter, og en kaskade af flere 1. ordens og 2. ordens sektioner, kan direkte implementeres i C++, som det ønskes gjort i denne rapport. a H z / 0 a 1 1 z$ 1 a 1 2 z$ 2 b 0 b 1 1 z$ 1 b 1 2 z$ b 2 0 1 (3.16) (3.17) y n 8 a 0 x n a 1 1 x n 1 a 1 2 x n 2 b 1 y n 1 b 2 y n 2 (3.18) 3.1.6 Test rtest! Til test af de designede filtres stabilitet, undersøges om polerne i overføringsfunktionen H z ligger indenfor enhedscirkelen i z-planet. Er dette tilfældet for alle 1. og 2. ordens sektioner, vurderes filtrene som stabile. Med matlab-funktionen pzmap undersøges de enkelte sektioner, og da der ikke fandtes poler med en amplitude større end 1, betragtes filtrene som stabile. Dette kan endvidere bekræftes ved, i tidsdomænet, at kaskadekoble 1. og 2. ordens sektioner af båndpasfiltre af en given orden og påtrykke filteret en puls x n af arbitrær størrelse til tiden n 0. Til alle tider n 9 0 gælder x n : 0. Det kan nu forventes at y n <; 0 for n ;, hvilket blev påvist med med et 5. ordens filter, hvor det var tydeligt at y n gik mod 0, og systemet er derfor stabilt. Dette er illustreret på figur 3.4 på næste side, og matlabfilen for denne test kan ses i??? [*Note *] Det kan her nævnes at det først blev forsøgt at multiplicere 1. og 2. ordens sektionerne, således at overføringsfunktionen i z-domænet blev til én overføringsfunktion. Ved denne multiplicering blev der observeret en afvigelse i de endelige filterkoefficienter, og ved et 6. ordens båndpasfilter blev systemet ustabilt. Det blev derfor vedtaget at filtrere gennem en sektion af gangen. Gennem.m-filen bpf.m blev bodeplot af de designede filtre tegnet, og resultatet

Design af software 15 1500 Filtrering med 5.ordens filter 1000 500 y[n] 0 500 1000 1500 0 20 40 60 80 100 120 140 160 180 200 n Figur 3.4: y=n> som respons på en puls x=n>@? 32000 filtreret gennem et 5. ordens filter. Det bemærkes at filtreret er stabilt 3.2 Design af software [*Note *] skal de private metod (cleanup)

16 Designfase Navn sendsignal() Input Trigger fra knap eller objekt. Beskrivelse Benyttes til at starte forløb i et andet subsystem (analyzer/equalizer eller GUI). Output (er ikke sikker; flag, semaphore, messagequeue etc.). Navn receivesignal() Input Signal fra sendsignal(). Beskrivelse Modtager startsignal fra andet subsystem (analyzer/equalizer eller GUI). Output Metodekald. Navn senddata() Input data:short[], target:short. Beskrivelse Sender data fra et subsystem til et objekt (target:short) i et andet. Output (Kald til subsystem) data:short[], target:short Navn receivedata() Input data:short[], target:short. Beskrivelse Modtager data fra andet subsystem og foretager et metodekald ud fra target. Output Metodekald samt data:short[] Navn getstatus() Input void Beskrivelse Henter aktuel status for system Output currentstatus:short Navn setstatus() Input short fra knaptryk eller receivesignal() i CExternal Beskrivelse Opdaterer currentstatus:short Output void Tabel 3.1: Metodespecifikation for CExternal.

Design af software 17 Navn quit() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til analyser/equalizer om at lukke processerne og lukker GUI Output Kald af sendsignal i CExternal og close Navn showspkchar() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til analyser/equalizer om at vise højttalerens frekvenskarakteristik Output Kald af sendsignal og setstatus i CExternal Navn showrtfreq() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til analyser/equalizer om at vise frekvensindholdet i realtid Output Kald af sendsignal og setstatus i CExternal Navn correctspeakers() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til analyser/equalizer om at starte korrektionen af højttalerne Output Kald af sendsignal og setstatus i CExternal Navn playsong() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til?????? Output Kald af sendsignal i CExternal og setstatus Navn stopplaying() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til?????? Output Kald af sendsignal i CExternal og setstatus Navn storewanted() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til?????? Output Kald af sendsignal i CExternal og setstatus Navn setdefaults() Input Tryk fra bruger på GUI-knap Beskrivelse Sender signal til?????? Output Kald af sendsignal i CExternal og setstatus Navn setstatus() Input????? Beskrivelse Sender signal til?????? Output Kald af?????? Navn fetchstatus() Input????? Beskrivelse Sender signal til?????? Output Kald af????? Tabel 3.2: Metodespecifikation for CButton.

18 Designfase Navn Input Beskrivelse Output Navn Input Beskrivelse Output playnoise() void Afspiller en fil med pink noise void outputsound() void Sender data fra sound:signed short[] til CSoundCard void Tabel 3.3: Metodespecifikation for CSound. Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output getipointer() void Henter pointer til inputbuffer signed short* getopointer() void Henter pointer til outputbuffer signed short* getbufferlength() void Henter in- og outputbuffernes længde int init() int bits, int sampling_frequency Initialiserer lydkortet void start() void Sætter lydkortet i gang med at afspille og optage void pause() void Pauser afspilning og optagelse void stop() void Stopper afspilning og optagelse void cleanup() int err Lukker lydkortet, unmapper mapped memmory og kaster en fejlbesked void Tabel 3.4: Metodespecifikation for CSoundCard.

Design af software 19 Navn Input Beskrivelse Output Navn Input Beskrivelse Output findrms() filteredseq:signed short[] Bestemmer RMS værdien af en lydsekvens rmscoeff:*char returnrms() void Returnerer rmscoeff[] til brug ved grafgeneration. rmscoeff:char[] Tabel 3.5: Metodespecifikation for CAnalyzer. Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output Navn Input Beskrivelse Output calcdiffkvot() correctedcoeff:double[] Finder forholdet mellem målt energi og energi i pink-noisefilen i de enkelte bånd diffkvot:double[] fetchwanted() Henter ønsket frekvenskarakteristik fra filen <slidervalues> wantedfreqchar:double[] subwantedfromdiff() diffkvot:double[], wantedfreqchar:double[] Beregner og gemmer forskellen mellem den ønskede frekvenskar. og den faktiske i bandamp:short[] og filen <bandamp>. void fetchbandamp() Henter båndpasforstærkninger fra filen <bandamp> og gemmer i bandamp:short[] void Tabel 3.6: Metodespecifikation for CEqualizer. Navn Input Beskrivelse Output Navn Input Beskrivelse Output drawgraph() coeff:double[] Tegner analyzer-graf ud fra modtagne værdier. void getcoeff() void Koefficienter fra CExternal gemmes i coeff:double[] void Tabel 3.7: Metodespecifikation for CGraphWindow.

20 Designfase Navn Input Beskrivelse Output Navn Input Beskrivelse Output storewanted() void Gemmer aktuelle sliderindstillinger i filen <slidervalues> void fetchwanted() void Henter ønsket frekvenskarakteristik fra filen <slidervalues> double[] Tabel 3.8: Metodespecifikation for CSliderWindow. Navn Input Beskrivelse Output Navn Input Beskrivelse Output setsliders() void Indstiller sliders; hvis kaldt uden parameter nulstilles sliders og værdierne i filen <slidervalues> void fetchsliders() void Returnerer aktuelle slider-værdier. double[] Tabel 3.9: Metodespecifikation for CSlider. Navn Input Beskrivelse Output Navn Input Beskrivelse Output filtersamples() void Filtrerer en række samples, hentet med getsequence i CSound void fetchseq() sound:signed short[] Returnerer de filtrerede sekvenser signed short[] Tabel 3.10: Metodespecifikation for CFilter.

4.1 Indledning 4.2 Fejlhåndtering 4 Softwaredesign I C++ findes en indbygget mekanisme til fejlhåndtering kaldet exception handling. Via exceptions kan et objekt, der fejler, informere sig selv eller andre i stakken højere placerede objekter om fejlen. Afhængigt af fejlens betydning for afviklingen af hovedprogrammet i main, er exception handleren i simple tilfælde placeret i det fejlende objekt og i mere alvorlige tilfælde i main; typisk dog i main. Exception handling er opbygget omkring brugen af try, throw og catch. I selve objektet indsættes throw-kommandoen på de steder i metoderne, hvor der ønskes en fejlhåndtering. I hovedprogrammets main pakkes de dele af metodekaldene, der ønskes kontrolleret for exceptions, ind i try s klammer. Og slutteligt forefindes catch i main til at opfange de afsendte exceptions fra metodekaldene indkapslet i try. For at sofistikere fejlhåndteringen kan de enkelte exceptions bestå af specifikke argumenter såsom brug af metoder. Tilsvarende opfanges specifikt de enkelte fejlobjekter, og på denne måde kan en præcis fejlbeskrivelse inddelt i forskellige fejlområder håndteres og forevises brugeren. Der findes mange forskellige måder at opbygge fejlhåndteringen på, og den i dette projekt benyttede fejlhåndtering baserer sig på brugen af klasser. Der er således oprettet følgende fire overordnede klasser: GUIErrors. AnalyzerErrors. EqualyzerErrors. MiscErrors. GUIErrors omfatter exceptions fra GUI, og disse vil blive behandlet udelukkende i GUIens egen exception handler, da GUI kører som et selvstændigt program. De resterende omfatter exceptions fra AnalyzerEqualizer-programmet, og indgår således i dette programs fejlhåndtering. Fælles for alle fire klasser er, at der udskrives fejlbeskeder både via GUI og via en konsol, da dette sikrer, at fejlbeskeden når frem. Om nødvendigt giver tekstboksen mulighed

22 Softwaredesign for, at brugeren skal tage stilling til hvordan fejlen skal håndteres. Der vil være specialtilfælde, hvor eksempelvis de to hovedprogrammer ikke kan kommunikere, hvilket gør at der ikke kan udskrives en fejlbesked via GUI. Følgende eksempel viser et exception throw fra metoden makeerror(), der programmæssigt er placeret under Analyzer en, hvorfor fejlbeskeder fra denne hører under klassen CAnalyzerErrors. Exception-objektet kommer med to argumenter, hhv. fejlnummeret 1 og en specifik fejlbesked, der i dette tilfælde fortæller brugeren hvilken metode, der fejlede. void CmakeError::makeError(void) {... if(error=1){ throw CAnalyzerErrors(1,"makeError() has made en error!"); }... } Den praktiske opbygning er, at der til main i de to hovedprogrammer er knyttet en fejlhåndteringsfil kaldet CErrors.cpp med en tilsvarende h-fil. Denne indeholder alle fejlhåndteringer, og objekterne oprettes fra main når en exception er opfanget. Et eksempel på et catch med efterfølgende kald af exception handling er: CmakeError err; try /**:INFO: This is the method we want to * test for errors while running. */ { err.makeerror(); } /**:INFO: Here we will catch the specific * errors coming from the CmakeError instances */ catch(canalyzererrors errorinstance){ CErrors pass_to_handler; pass_to_handler.analyzererrors --> (errorinstance.errornumber,errorinstance.errorstring); } I dette eksempel er der tale om, at et objekt af klassen CmakeError fejler med en exception af klassen CAnalyzerError. Dette objekt oprettes med udgangspunkt i følgende fejlhåndtering, som for eksemplets skyld er simpel og udelukkende håndterer fejlen ved, at udskrive fejlbeskeden til hhv. GUI og konsol: void CErrors::AnalyzerErrors(int error,string s1) { CExternal outputgui1(analyzererror); CExternal outputgui2(analyzer); switch(error) { case 1:

CExternal 23 /** :INFO: Writes output to console */ /** :INFO: Standard text for the specific error * number plus the number is written to cout. */ cout << "GUI error number " << error << ":" << endl; /** :INFO: Specific text from the thrown * exception is written to cout. */ cout << s1 << endl; /** :INFO: Writes output to GUI */ outputgui2.sendsignal(error); outputgui2.senddata((char*)s1.c_str()); break; } default: break; } Udskrivning til konsollen er simpel og ligefrem. Ved udskrivning til GUI oprettes derimod et objekt af CExternal med en parameter ANALYZER for at angive, at det er en fejl fra Analyzeren. Derudover benyttes som tidligere fejlnummeret og den specifikke fejlbesked. Selve håndteringen af dette objekt tilhører ikke dette afsnit. For overskuelighedens skyld, er der her ikke inkluderet al koden, og eksemplet er som nævnt et eksempel på opbygningen. Selve implementeringen kan ses i appendiks [*Note *] hvilket appendix indeh den? 4.3 CExternal Klassen CExternal varetager kommunikation mellem de to processer systemet gennem analyse- og designfasen er blevet opdelt i. Denne kommunikation består af to ting: Signaler og data. Signalerne benyttes til at markere hvornår en af processerne skal starte en sekvens af metodekald, for at opfylde kravene fra en specifik usecase. Under behandling af samme usecase opstår behovet for at sende data imellem processerne. Den grafiske brugerflade skal f.eks. have returneret værdier til brug for at tegne analyzer-grafen. For at muliggøre kommunikationen kan findes under Linux (og nogle Unix-systemer) benytte System V IPC 1. System V IPC er en samling af en række systemkald, som stiller følgende værktøjer til rådighed ved kommunikation mellem processer: Semaphores. Shared memory. Message queues. 1 Inter Process Communication

24 Softwaredesign 4.3.1 System V IPC Semaphores Semaforer er en mekanisme der tillader styring af hvordan forskellige processer afvikles. En proces kan sættes i stå mens den venter på at en semafor får en bestemt værdi, og bruger således ingen ressourcer inden dette sker. Andre processer (eller evt. andre tråde i samme proces) kan derefter sætte semaforen, hvorefter afvikling af processen tages op igen. Koordineringen af semaforerne, og de processer der afhænger af semaforerne, varetages af styresystemet, der opretter og vedligeholder en kø der indeholder de aktive semaforer. Delt hukommelse Delt hukommelse (eng. shared memory) er som navnet antyder, et stykke hukommelse som flere processer har adgang til. Ved brug af et eller flere sådanne områder, og med den rette koordinering, kan processer dele data i begge retninger. Koordineringen kan f.eks foregå ved at sætte flag direkte i den delte hukommelse, og polle på disse, eller ved brug af de førnævnte semaforer, hvorved man undgår at polle, og derfor sparer systemressourcer. Message queues e 4kB? Dave? Det tredje værktøj der stilles til rådighed via. System V IPC er message queues. En message queue kombinerer egenskaber fra de to andre værktøjer, og kan således bruges både til styring af andre processers afvikling, og til udveksling af data. En besked sendes som en struct i C++, og kan, ud over en obligatorisk beskedtype, indeholde så mange forskellige datatyper som man har brug for, så længe den samlede mængde ikke overskrider 4 kb[*note *]. Beskedtypen kan i modtagerenden benyttes til at foretage prioritering af beskederne, til at udvælge specifikke beskeder, eller den kan ignoreres, hvilket bevirker at den første besked i køen, uanset type, modtages. Det skal bemærkes at en beskedkø ikke virker efter FIFO 2 princippet. Ved prioriteret modtagelse kan det altså lade sig gøre at tage den sidst ankomne besked ud af køen, hvis den matcher kriterierne bedst. 4.3.2 Tilfældet CExternal [*Note *] For at løse de opgaver CExternal skal løfte, kan enten en kombination af de to før- ste værktøjer, semaforer og shared memory, eller det sidste værktøj, message queues, benyttes. Da message queues kan håndtere både den indbyrdes styring, der her kaldes signaler, og overførsel af data, vælges denne løsning. Der skal i CExternal-klassen findes tre sæt metoder: sendsignal og receivesignal, der står for den indbyrdes styring mellem processerne, senddata og receivedata, der som navnene antyder, håndterer dataoverførsler, og senderrortype og receiveerrortype, der skrift? 2 First In, First Out

CExternal 25 tager sig af fejlhåndteringens kommunikation mellem GUI og AnalyzerEqualyzer. Følgende afsnit gennemgår implementationen af disse tre metodepar i forhold til brugen af beskedkøen som værktøj. Styring Signalerne der skal flyttes med sendsignal og dennes modpart benyttes til at starte sekvenser af metodekald, der svarer til de usecases projektet fra starten er baseret på. Den eneste information der er nødvendig at sende med en besked i sendsignal er således en identifikation af den sekvens der skal startes. Denne gives i sendsignal som et nummer, og den overførte datastruktur består derfor af en long mtype der angiver beskedtypen, og en int signal der identificerer den ønskede sekvens.afhængigt af om CExternals constructor kaldes med parameteren GUI, parameteren ANALYZER, GUIERROR eller ANALYZERERROR sættes sendsignal til at sende beskeder af typen 1, 2, 3 eller 4. Modsvarende sættes receivesignal til at modtage beskeder af typerne 4, 3, 2 eller 1. Alternativt kunne metoderne være opbygget med prioriteret modtagelse, hvorved den anden del af datastrukturen, int signal, kunne spares. Dette kunne dog bevirke at den ene af processerne, hvis denne foretog et receivesignal kald efter et sendsignal, og før den anden proces, ville modtage sin egen besked. Den førstnævnte implementation blev derfor foretrukket. Dataoverførsel Metodeparret senddata og receivedata har som hovedfunktion at returnere de udregnede værdier der skal bruges til at tegne analyzergrafen på den grafiske brugerflade. Der er tale om en række talværdier, svarende i antal til de implementerede filtre. For at overføre denne række af værdier benyttes et array af typen char. Dette giver mulighed for en opløsning på grafens værdiakse på op til 256 punkter. Det skal bemærkes at værdien af en char kan ligge mellem 128 og 127, hvorfor det vil være nødvendigt at lade metoden findrms i klassen CAnalyzer returnere værdier mellem disse to grænser. Metoden receivedata skal returnere den data der modtages til en kaldende funktion. Hvis man i C++ returnerer et array fra en metode, får man reelt en pointer til adressen på dette array. Da metoden afsluttes ved kaldet af return, frigives den benyttede memory imidlertid, og den returnerede pointer er ikke længere brugbar. For at omgå dette problem oprettes et privat array i klassen, og en pointer til dette returneres. Da de to oprettede CExternal objekter ikke lukkes ned før hele programmet afsluttes, vil denne pointer også være brugbar uden for objektet. Metodeparret senderrortype og receiveerrortype fungerer i hovedtræk ligesom send- Data og receivedata, men har til formål at sende informationerne om fejltypen samt en specifik fejlbesked mellem AnalyzerEqualyzer og GUI. Fejlhåndteringen omtales yderligere i afsnittet Fejlhåndtering 4.2 på side 21. Fælles for alle metoderne er, at de med funktionen msgget opretter en message queue første gang de bliver kaldt. Køen får for Signal nøglen 0xCAFE, for Data nøglen FACE og for Error nøglen FEAC [*Note *]. Findes en kø med samme nøgle i forvejen, får msgget ingen betydning. De oprettede message queues skal nedlægges med funktionen msgctl, bør skrives til i fejlhånd snittet i stedet

26 Softwaredesign med kommandoen IPC_RMID ved programmets afslutning. Denne oprydning skal ligge i hhv. main-funktionen i den grafiske brugerflade, og main-funktionen i analyzer-/equalizerprogrammet. 4.3.3 Test For at teste de metoder CExternal indeholder, benyttes to små testprogrammer, testramme1 og testramme2. De to programmer opretter hver især et CExternal objekt, i testramme1 med parameteren ANALYZER, og i testramme2 med parameteren GUI, hvorved de to seperate processer i projektet simuleres. I hvert testprogram oprettes herefter to message queues, med hhv. nøglerne 0xCAFE og 0xFACE. I testramme1 kaldes send- Signal, og i testramme2 kaldes receivesignal. Denne sekvens gentages i den modsatte retning, og de modtagne signaler skrives til cout. Samme fremgangsmåde gentages for senddata og receivedata, med et array af characters oprettet til formålet. Til slut nedlægges de oprettede message queues, og de to programmer afsluttes. Testen forløb tilfredsstillende, CExternal anses for afsluttet og tages i brug i de andre klasser. 4.4 CSound Klassen CSound varetager fortolkning af instruktioner fra CPlayWindow og internt i klassen, til brug ved forsendelse af lyddata til CSoundCard. Funktionen består i modtagelse af instruktioner fra CPlayWindow og playnoise, der henholdvis er i GUI og klassen selv. Instruktionerne fra CPlayWindow kalder outputsound med parameteren const char, hvori stien til lydfilen er defineret, som skal håndteres og videresendes. Instruktionen for playnoise består i kaldet med en statisk sti til filen for pink noise. 4.4.1 Behandling af data til CSoundCard 4.4.2 Afspilning af pink noise Ved korrektion af højttalerne skal der afspilles et kendt signal, der dækker hele frekvensområdet for mikrofonen. Til dette formål anvendes pink noise, men white noise kan også anvendes, hvor gengivelsen af pink noise sker ved afspilning af en wave-filer, som skal ligge i samme mappe som filerne for klassen. Af hensyn til kaldet af filen skal det sikres, at filens placering er korrekt. Idet kaldet af playnoise vil fejle, hvis filens placering ikke stemmer overens med stien angivet i koden. /** :INFO: Play a pink noise file through outputsound */ void CSound::playNoise(){ } /** :NB: Make sure the file "pink.wav" is placed in * the same directory as the CSound.* files */ CSound noise = CSound(); noise.outputsound("pink.wav");

Interface til lydkort 27 4.4.3 Fejlhåndtering 4.4.4 Testramme for funktionerne 4.5 Interface til lydkort En instans af klassen CSoundCard ligner ikke et typisk objekt med en række instansvariable og metoder til at manipulere disse - i stedet er objektets primære formål at styre lydkortets optagning og afspilning. For at tilgå lydkortet anvendes en driver. Der er til linux/unix lavet et sæt drivere, der giver et ensartet API 3 kaldet OSS 4. Det er således muligt at tilgå et givent OSSkompatibelt lydkort i en computer kørende linux med de samme kald; programmet der implementerer disse er således portabelt. Ud over OSS findes ALSA 5, der giver mulighed for flere avancerede funktioner, men da disse ikke er nødvendige i dette projekt, og da OSS er den standard der pt. er til linux, anvendes ALSA ikke. Til at understøtte kodningen af CSoundCard anvendes de to internetsider (?) og (?) samt et konkret kodeeksempel af Søren K. Olesen. [*Note *] skal søren nævnes her? For at være i stand til at optage og afspille skal man kunne: Initialisere lydkortet. Skrive til og læse fra lydkortet. 4.5.1 Initialisering af lydkort Lydkortet sættes op med en række ioctl-kald; ioctl-funktionen manipulerer med et givent device s parametre - se manualsiderne for ioctl[*note *]. I disse sider står ok? int ioctl(int d, int request,...); hvor d er file descriptor 6, og hvor request fortæller hvilke parametre, der skal ændres (de forskellige requests anvendt kan findes på internetsiderne (?) og (?)). Det sidste felt kan bruges til at fortælle, hvordan parametrene skal ændres. Et eksempel på brugen af ioctl er ved opsætning af bitopløsningen: int actual_value = bits; if(ioctl(audio_fd, SNDCTL_DSP_SAMPLESIZE, &actual_value) == -1) clean\ Up(0x0030); if(actual_value!= bits) cleanup(0x0031); 3 Application Programming Interface 4 Open Sound System 5 Advanced Linux Sound Architecture 6 Et systemspecifikt nummer der bruges til at identificere den åbne fil for systemet