Handbok aRts
Handbok aRts
Nästa

Handbok aRts

Stefan Westerfeld

Jeff Tranter

Översättare: Stefan Asserhäll
Revision 1.00.09 (2001-06-10)

Härmed ges tillåtelse att kopiera, distribuera och/eller ändra detta dokument under villkoren i GNU Free Documentation License, Version 1.1 eller någon senare version publicerad av Free Software Foundation; utan invarianta avsnitt, utan framsidestexter och utan baksidestexter. En kopia av licensen inkluderas i avsnittet som heter "GNU Free Documentation License".

Den här handboken beskriver aRts, den analoga realtidssynthesizern.


Innehållsförteckning

1. Inledning
Vad är aRts?
Att använda den här handboken
Historik
2. aRts-verktyg
Inställningscentralen
artsd
artswrapper
artsshell
artsplay
artsdsp
artscat
artscontrol
artsc-config
mcopidl
3. aRts-byggare
Översikt
Handledning
Steg 1
Steg 2
Steg 3
Steg 4
Steg 5: Börja skicka omkring data ;)
Steg 6: Skicka data för avancerade användare
Steg 7: Midisyntes
Förslag
Exempel
4. aRts i detalj
Arkitektur
Moduler & portar
Strukturer
Latenstid
Vad är latenstid?
Latenstid i enkla program
Latenstid i program med ljudflöden
Några CPU-användningshänsyn
Några riktiga värden
Bussar
Handlaren
Namnrymder i aRts
Inledning
Hur aRts använder namnrymder
Interna funktioner: hur implementeringen fungerar
Trådar i aRts
Grundläggande information
När/hur ska låsning ske?
Trådrelaterade klasser
Referenser och felhantering
Grundläggande egenskaper för referenser
Fallet med misslyckanden
Interna funktioner: distribuerad referensräkning
Grafiska gränssnittselement
5. MIDI
Översikt
MIDI-hanteraren
Att använda aRts & Brahms
midisend
Att skapa instrument
Instrumentkartor
6. MCOP: objektmodell och strömmar
Översikt
Gränssnitt och IDL
Strömmar
Egenskaper
Metoder
Standardgränssnitt
Exempel
Mer om strömmar
Strömtyper
Att använda asynkrona strömmar
Förvalda strömmar
Ändringsmeddelanden för egenskaper
Att skicka ändringsmeddelanden
Tillämpningar för ändringsmeddelanden
Filen .mcoprc
MCOP för CORBA-användare
CORBA-funktioner som saknas i MCOP
CORBA-funktioner som är annorlunda i MCOP
MCOP-funktioner som inte finns i CORBA
MCOP-bindningen till C++ språket
Att implementera MCOP-objekt
Säkerhetshänsyn för MCOP
MCOP protokollspecifikation
Inledning
MCOP:s meddelandekodning
Meddelanden
Anrop
Inspektera gränssnitt
Typdefinitioner
Varför aRts inte använder DCOP
7. aRts programmeringsgränssnitt
Översikt
knotify
kaudioplayer
libkmid
kmedia2
ljudserver
artsflow
C API
Inledning
Snabbtur
Att kompilera och länka: artsc-config
Biblioteksreferens
8. aRts moduler
Inledning
Referens till syntesmoduler
Aritmetik + mixning
Bussar
Fördröjningar
Envelopper
Effekter
Filter
Midi + sekvensiering
Samplingar
Ljud-I/O
Tester
Oscillation & Modulation
Vågformer
Diverse
Referens till visuella moduler
9. Ändra program för att passa aRts
Att använda artsdsp
Lägga till inbyggt stöd för aRts
10. Att bidra till aRts
Hur du kan hjälpa till
E-postlistor
Kodningsstandarder
11. Framtida arbete
Hur gränssnitt fungerar
Codec, dataavkodning
Video
Trådning
Synkronisering
Dynamisk sammansättning
GUI
MIDI
12. Referenser
13. Vanliga frågor
14. aRts Copyright och licens
A. Installera aRts
Installera en färdigkompilerad binärutgåva
Bygga från källkod
B. Introduktion till digitalljud
C. Introduktion till MIDI
Gloslista
Kapitel 1. Inledning
Inledning
Föregående
Nästa

Kapitel 1. Inledning

Vad är aRts?

Den analoga realtidssynthesizern, eller aRts, är ett modulärt system för att syntetisera ljud och musik på en digital dator. Med små byggblock, som kallas moduler, kan användaren lätt bygga komplexa verktyg för att behandla ljud. Moduler tillhandahåller typiskt funktioner som vågformsgeneratorer, filter, ljudeffekter, samt mixning och uppspelning av digitalt ljud med olika filformat.

Ljudservern artsd blandar ljud från olika källor i realtid, vilket låter flera ljudprogram transparent få delad tillgång till ljudhårdvaran.

Genom att använda MCOP, multimediakommunikationsprotokollet, kan multimediaprogram bli nätverkstransparenta, säkerhetsidentifierade, och fungera på flera plattformar med gränssnitt som definieras på ett språkoberoende sätt med IDL. Äldre program som inte stöder aRts hanteras också. Som en central komponent i skrivbordsmiljön KDE 2, tillhandahåller aRts grunden för KDE:s arkitektur för multimedia, och kommer att stöda fler mediatyper inklusive video i framtiden. Som KDE, så kör aRts på flera operativsystem, inklusive Linux® och BSD-varianter. Det kan också användas oberoende av KDE.

Att använda den här handboken
Att använda den här handboken

Att använda den här handboken

Den här handboken är tänkt att ge fullständig dokumentation om aRts för användare med olika kunskapsnivåer. Beroende på om du är en vardagsanvändare av multimediaprogram som kör med hjälp av aRts eller en utvecklare av multimediaprogram, kan du välja att läsa handbokens avsnitt i olika ordning.

Vi föreslår att du först läser kapitlet Ladda ner och bygga aRts om du måste få aRts installerad och körbar från början. Om du redan har ett fungerande system, troligen installerade tillsammans med din operativsystemdistribution, kan du välja att hoppa över det här avsnittet.

Därefter bör du läsa avsnitten i kapitlet aRts verktyg, särskilt artsd, artscontrol;, artsshell, och artsdsp. Det här hjälper dig använda aRts på det effektivaste sättet.

Om du är intresserad av att tränga in ytterligare i aRts funktion, läs kapitlet om aRts-byggaren och gå igenom handledningen. Det här bör ge dig en förståelse för aRts kraftfulla möjligheter och de moduler som är tillgängliga att använda utan att behöva kunna programmera.

Om du vill lära dig mer om hur aRts fungerar internt, antingen för att utveckla multimediaprogram eller för att utöka aRts själv, läs några eller alla kapitlen om aRts i detalj. Det här bör ge dig en förståelse för alla koncept som krävs för aRts-programvaruutveckling.

Om du är särskilt intresserad av MIDI-funktionerna i aRts, bör du läsa kapitlet om MIDI.

Om du vill utveckla multimediaprogram som använder aRts, beskrivs de olika programvarugränssnitten (API) detaljerat i kapitlet aRts programvarugränssnitt.

Om du vill utöka aRts genom att skapa nya moduler, läs kapitlet aRts-moduler.

Om du ändrar ett befintligt program för att köra ihop med aRts, läs kapitlet Ändra program för att passa aRts.

Du kan också ta reda på hur du kan hjälpa till och bidra till aRts-projektet i kapitlet Bidra till aRts, läsa om kommande utveckling av aRts i kapitlet Framtida arbete, och hitta länkar till mer information i avsnittet Referenser.

Vi har också avrundat handboken med en del ytterligare material, inklusive svar på vanliga frågor, en lista på bidragsgivare, detaljer om aRts copyright och licenser, och en del bakgrundsmaterial om digitalljud och MIDI. En gloslista ingår också.

Notera

Den här handboken är fortfarande i stor utsträckning pågående arbete. Du får gärna bidra genom att skriva delar av den, men om du vill göra det, kontakta först Jeff Tranter eller Stefan Westerfeld för att undvika dubbelarbete.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Historik
Historik

Historik

Mot slutet av 1997 började Stefan Westerfeld arbeta med ett modulärt realtidssystem för ljudsyntes. Koden kördes ursprungligen på ett PowerPC-system med AIX®. Den första implementeringen var mycket enkel, men stödde ett flödessystem med fullständig funktion som kunde göra sådana saker som spela MP3-filer och skicka data genom ljudeffektmoduler.

Nästa steg var att implementera ett grafiskt gränssnitt, så att moduler kunde manipuleras grafiskt. Stefan hade en del god erfarenhet av att använda KDE, så därför valdes KDE som den grafiska verktygslådan, (med vetskap om att det kunde bli nödvändigt att göra en version med GNOME/Gtk+ också) och det här gjorde att Linux® senare valdes som den huvudsakliga utvecklingsplattformen. Projektet, som ursprungligen hette ksynth, döptes om till aRts och utvecklingstakten ökade. Vid det här laget var projektet nästan komplett, med ett CORBA-baserat protokoll, dussintals moduler, ett grafiskt modulredigeringsverktyg, C och C++ gränssnitt, dokumentation, verktyg och en e-postlista och webbsida med en liten grupp utvecklare. Projektet hade kommit en bra bit på vägen efter bara något mer än ett års utveckling.

När KDE-gruppen började planera för KDE 2.0, blev det klart att KDE behövde en kraftfullare infrastruktur för ljud och andra mediatyper. Beslutet togs att anpassa aRts, eftersom det var ett steg i rätt riktning med en beprövad arkitektur. En ny stor utvecklingsansträngning gjordes för den här nya versionen av aRts, framförallt utbytet av CORBA-koden mot ett helt nytt subsystem, MCOP, optimerat för multimedia. Version 0.4 av aRts ingick i utgåva 2.0 av KDE.

Arbetet med aRts forsätter, för att förbättra prestanda och lägga till nya funktioner. Observera att även om aRts nu är en central komponent i KDE, kan den användas utan KDE, och används också av program som går utanför traditionell multimedia. Projektet har skapat visst intresse från GNOME-gruppen, som öppnar en möjlighet att det i framtiden kan bli standardarkitekturen för multimedia på UNIX® skrivbordssystem.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 2. aRts-verktyg
aRts-verktyg
Föregående
Nästa

Kapitel 2. aRts-verktyg

Ett antal verktyg levereras tillsammans med aRts för att styra och anpassa dess beteende. Du behöver känna till de flesta av de här verktygen lite grand för att kunna använda aRts på ett effektivt sätt. Det här avsnittet beskriver vart och en av verktygen och deras kommandoväljare.

Inställningscentralen

När man kör aRts med KDE, tillhandahåller inställningscentralen en grupp med inställningar i kategorin Ljud. Vissa av de här används av aRts. Man kan också binda ljud till olika fönsterhanterings- och KDE-händelser med dialogrutan Ljud+Systemunderrättelser. Se handboken för inställningscentralen för mer information om hur dialogrutans inställningar används.

artsd
artsd

artsd

Tillgången till ljudhårdvaran kontrolleras av artsd, ljudservern för aRts. Det här tillåter att flera program samtidigt skickar en begäran till servern, där de kan blandas och spelas upp. Utan en central ljudserver skulle ett enstaka program som använder en ljudenhet förhindra andra program från att använda den.

För att använda aRts ska det finnas en och endast en kopia av artsd som kör. Den startas typiskt när KDE startas om detta är aktiverat i inställningscentralens Ljudserver modul.

Programmet accepterar följande väljare:

artsd [-n-p-N-W n] [-a audiomethod-r sampling rate-b bits-d-D devicename-F fragments-S size-s seconds-m appName] [-h-A-v-l level]

-r sampling rate

Ställ in samplingsfrekvens som ska användas.

-h

Visa kommandoanvändning.

-n

Aktivera nätverkstransparens.

-p port

Ange TCP-port som ska användas (förutsätter -n).

-u

Öppen, ingen identifiering (farligt).

-d

Aktivera full duplex.

-D devicename

Ange ljudenhet (vanligtvis /dev/dsp).

-F fragments

Ange antal fragment.

-S size

Ange fragmentstorlek i byte.

-s seconds

Ställ in fördröjningen innan vänteläget aktiveras i sekunder. Värdet noll stänger av vänteläget.

-m appName

Ange namnet på ett program som används för att visa fel, varningar och informationsmeddelanden. Om du kör KDE kan du använda verktyget artsmessage för det här.

-N

Öka storleken av nätverksbuffrarna till ett värde som är lämpligt för att köra med ett 10 Mbps lokalt nätverk. Det här är samma som att använda väljaren -w 5 (se nedan).

-w n

När artsd körs via en nätverksanslutning till en annan värddator vill man ofta använda en stor buffer för att undvika pauser. aRts föreslår en minimal bufferstorlek för program. Utan det här alternativet baseras den förvalda storleken på fragmentstorleken * antalet fragment. Med det här alternativet kan man öka storleken från den förvalda med en faktor n.

-l level

Ställ in informationsnivå: 3 (tyst), 2 (varningar), 1 (info), 0 (avlusning).

-v

Visa versionsnivå.

I de flesta fall är det nog att bara köra artsd.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artswrapper
artswrapper

artswrapper

För att ge bra realtidsegenskaper körs artsd oftast som en realtidsprocess (på plattformar där realtidsprioriteter stöds). Det här kräver root-behörighet, så för att minimera säkerhetspåverkan, kan artsd startas med det lilla omgärdande programmet artswrapper som helt enkelt byter till realtidsprioritet (medan det kör som root) och sedan startar artsd som en annan användare än root.

Om du gör artswrapper SUID root, kommer det troligen förbättra kvaliteten på ljudåtergivningen genom att reducera uppehåll i musiken. Dock ökar det också risken att ett fel i koden, eller en användare med uppsåt att skada kan krascha eller skada datorn på något sätt. Dessutom, att prioritera hög ljudkvalitet på fleranvändardatorer kan orsaka försämrad prestanda för användare som försöker använda datorn på ett “produktivt” sätt.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artsshell
artsshell

artsshell

Kommandot artsshell är avsett som ett verktyg för att utföra diverse funktioner som hör ihop med ljudservern. Förmodligen kommer verktyget att utökas med nya kommandon i framtiden (se kommentarerna i källkoden för några idéer).

Kommandot accepterar följande format:

artsshell [[suspend] | [status] | [terminate] | [autosuspend secs] | [networkbuffers n] | [volume [volume]] | [stereoeffect options]] [-h-q]

artsshell [väljare] kommando [kommandoalternativ]

Följande väljare stöds:

-q

Undertryck all utmatning.

-h

Visa kommandoanvändning.

Följande kommandon stöds:

suspend

Ange att ljudservern ska gå till vänteläget.

status

Visa statusinformation för ljudservern.

terminate

Avsluta ljudservern. Det här kan förvirra och/eller krascha alla program som för närvarande använder den.

autosuspend secs

Ställ in fördröjningen för aktivering av vänteläget till det angivna antalet sekunder. Ljudservern går till vänteläget om den är inaktiv så länge. Värdet noll stänger av vänteläget.

networkbuffers n

Ställer in storleken på nätverksbuffrarna till en faktor n gånger den förvalda storleken.

volume [volume]

Ställer in volymskalning för ljudserverns utmatning av ljud. Parametern volume är ett flyttal. Utan parameter visas nuvarande volym.

stereoeffect list

Visa alla tillgängliga stereoeffektmodulerna.

stereoeffect insert [top|bottom] namn

Infoga en stereoeffekt i stereoeffektstacken. Returnerar en identifierare som senare kan användas för att ta bort den. Effekten kan installeras längst upp eller längs ner (normalvärdet).

stereoeffect remove id

Tar bort stereoeffekten med identifieraren id från effektstacken.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artsplay
artsplay

artsplay

Programmet artsplay är ett enkelt verktyg för att spela en ljudfil. Det accepterar en enda parameter som motsvarar namnet på ljudfilen som skickas till ljudservern för att spelas. Ljudfilen kan vara vilken vanlig ljudfiltyp som helst, såsom wav eller au. Det här verktyget är bra för att prova om ljudservern fungerar. Genom att köra två kommandon parallellt eller i snabb följd kan man demonstrera hur ljudservern blandar mer än en ljudkälla.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artsdsp
artsdsp

artsdsp

Ljudservern hanterar bara program som stöder aRts. Många gamla program vill komma åt ljudenheten direkt. Kommandot artsdsp tillhandahåller en interimlösning som låter de flesta av dessa program köra oförändrade.

När ett program körs med artsdsp fångas alla försök att komma åt ljudenheten /dev/dsp och omvandlas till anrop till aRts programmeringsgränssnitt. Även om enhetsemuleringen inte är perfekt, så fungerar de flesta program på det här sättet, fastän med en viss försämring i prestanda och latenstid.

Kommandot artsdsp följer formatet:

artsdsp [väljare] program väljare

Följande väljare känns igen:

-h, --help

Visa kortfattad hjälp.

-n --name = namn

Använd namn för att identifiera en spelare för artsd.

-m --mmap

Emulera minnesmappning (t.ex för Quake).

-v --verbose

Visa väljare.

Ett typiskt anrop är:

artsdsp -v -m realplay song.mp3

Vissa program fungerar bättre med väljaren --mmap. Ljudenhetens alla funktioner är inte fullständigt emulerade, men de flesta program bör fungera. Om du hittar ett som inte gör det, skicka in en detaljerad felrapport så kan utvecklarna fixa det. Återigen, kom ihåg att det här är en intermediär lösning och något av en ful snabbfix. Den bästa lösningen är att lägga till inbyggt stöd för aRts i programmen. Om ditt favoritljudprogram inte har stöd för aRts, be utvecklaren att tillhandahålla det.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artscat
artscat

artscat

Det här är ett enkelt verktyg för att skicka råljuddata till ljudservern. Man måste ange dataformatet (samplingsfrekvens, samplingsstorlek och antal kanaler). Det här är troligen inte ett verktyg som man behöver använda ofta, men det kan vara bekvämt för provändamål. Kommandosyntaxen är:

artscat [ väljare ] [ filnamn ]

Om inget filnamn anges läser programmet från standardinmatningen. Följande väljare stöds:

-r samplingsfrekvens

Ställ in samplingsfrekvens som används.

-b bitar

Ställ in samplingsstorlek som används (8 eller 16).

-c kanaler

Välj antal kanaler (1 eller 2).

-h

Visa kommandoanvändning och avsluta.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artscontrol
artscontrol

artscontrol

Det här är ett grafiskt verktyg för att utföra ett antal uppgifter som hör ihop med ljudservern. Det förvalda fönstret visar två volymnivåvisare och ett skjutreglage för att ställa in den generella uppspelningsvolymen. Från menyn Visa kan du välja andra funktioner:

FFT-mätare

Öppnar ett fönster som visar en skärm med en realtidsspektrumanalysator.

Ljudhanterare

Visar aktiva ljudkällor och låter dig ansluta dem till alla tillgängliga bussar.

aRts status

Visar om ljudservern kör och om realtidsschemaläggning används. Anger när servern kommer att gå till vänteläget och låter dig gå till vänteläget omedelbart.

Midihanterare

Visar aktiva MIDI in- och utgångar och låter dig göra förbindelser [ATT GÖRA: fungerar det här ännu? Behöver mera detaljer].

FreeVerb

Ansluter en FreeVerb efterklangseffekt till stacken av aRts utmatningseffekter och låter dig kontrollera ljudeffektinställningarna grafiskt.

Leds liknande volymvisning

Ändrar volymindikeringen i huvudfönstret att använda ett visningsformat med färgade lysdioder istället för staplar.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artsc-config
artsc-config

artsc-config

Det här verktyget är till för att hjälpa utvecklare som använder C-programmeringsgränssnittet i aRts. Det matar ut de riktiga kompilator- och länkarväljare som behövs när man kompilerar och länkar med aRts. Det är tänkt att användas i make-filer för att hjälpa till med flyttbarhet. Kommandot accepterar tre väljare:

--cflags

Visar kompilatorväljare som behövs när man kompilerar med aRts C-programmeringsgränssnitt.

--libs

Visar länkarväljare som behövs när man länkar med aRts C-programmeringsgränssnitt.

---version

Visar versionen av kommandot artsc-config.

Typisk utmatning från kommandot visas nedan:

% artsc-config --cflags
-I/usr/local/kde2/include/artsc
% artsc-config --libs
-L/usr/local/kde2/lib -ldl -lartsc -DPIC -fPIC -lpthread
% artsc-config --version
0.9.5

Man ska kunna använda det här verktyget i en make-fil med en regel som:

artsc: artsc.c
        gcc `artsc-config --cflags` -o artsc artsc.c `artsc-config --libs`


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

mcopidl
mcopidl

mcopidl

Kommandot mcopidl är IDL-fil kompilatorn för MCOP, multimedia-kommunikationsprotokollet som används av aRts. Gränssnitt i aRts definieras med IDL, ett språkoberoende gränssnittsdefinitionsspråk. Verktyget mcopidl accepterar en IDL-fil som indata och skapar C++ deklarations- och källkodsfiler för en klass som implementerar gränssnittet. Kommandot accepterar följande syntax:

mcopidl [ väljare ] filnamn

Giltiga väljare är:

-I katalog

Sök i katalog efter deklarationsfiler.

-e namn

Hoppa över en struct, gränssnitt eller uppräkningstyp namn vid kodgenerering.

-t

Skapa också .mcoptype/.mcopclass filer som innehåller typinformation för IDL-filen.

Mer information om MCOP och IDL finns i avsnittet Gränssnitt och IDL.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 3. aRts-byggare
aRts-byggare
Föregående
Nästa

Kapitel 3. aRts-byggare

Översikt

Först av allt, när du försöker köra aRts-byggaren, ska du också köra ljudservern (artsd). Oftast, om du använder KDE 2.1, ska detta redan vara fallet. Om inte, så kan du ställa in automatisk start av ljudservern i inställningscentralen, med Ljud+Ljudserver.

När du kör aRts, körs alltid små moduler. aRts-byggaren är ett verktyg för att skapa nya strukturer av små ihopkopplade moduler. Du klickar helt enkelt i rutnätet för att lägga till en modul. För att göra detta, välj dem från menyn Moduler, och klicka någonstans på den gröngrå ytan.

Moduler har ofta portar (där ljudsignaler vanligtvis leds in eller ut). För att koppla ihop två portar, klicka på den första, som gör att den blir orange, och klicka sedan på den andra. Du kan bara förbinda en inport (på översidan av en modul) med en utport (på undersidan av en modul). Om du vill ange ett konstant värde för en port (eller koppla ifrån den), gör det genom att dubbelklicka på porten.

Handledning
Handledning

Handledning

Steg 1

Starta aRts-byggaren.

Du behöver en Synth_AMAN_PLAY-modul för att höra utdata som du skapar. Så skapa en Synth_AMAN_PLAY-modul genom att välja Moduler->Syntes->Ljud-IO->Synth_AMAN_PLAY och klicka på den tomma modulytan. Placera den nedanför den femte raden ungefär, eftersom vi kommer att lägga till en del grejor ovanför.

Modulen kommer att ha en parameter title (porten längst till vänster), och autoRestoreID (intill porten längst till vänster) för att den ska kunna hittas. För att fylla i de här, dubbelklicka på portarna, välj konstant värde och skriv handledning i textrutan. Klicka OK för att verkställa.

Välj Arkiv->Kör struktur. Du hör absolut ingenting. Uppspelningsmodulen behöver också någon indata... ;) Om du har lyssnat på tystnaden ett tag, klicka Avsluta och gå till steg 2.

Steg 2

Skapa en Synth_WAVE_SIN-modul (från Moduler->Syntes->Vågformer) och placera den ovanför Synth_AMAN_PLAY-modulen (lämna en rads mellanrum mellan dem).

Som du ser, så producerar den någon utdata, men kräver pos som indata. Låt oss först ansluta utporten till högtalarna. Klicka på porten out på Synth_WAVE_SIN och sedan på porten left på Synth_AMAN_PLAY. Voila, du har kopplat ihop två moduler.

Oscillatorer i aRts kräver inte en frekvens som indata, utan istället en position i vågformen. Positionen ska vara mellan 0 och 1, som i ett standardobjekt Synth_WAVE_SIN översätts till området 0 .. 2*Pi. För att skapa oscillerande värden från en frekvens, används en Synth_FREQUENCY modul.

Skapa en Synth_FREQUENCY-modul (från Moduler->Syntes->Oscillation & modulation) och anslut dess “pos” utgång till “pos” ingången på Synth_WAVE_SIN. Sätt frekvensporten för frekvensgeneratorn till det konstanta värdet 440.

Välj Arkiv->Kör struktur. Du kommer att höra en sinusvåg på 440 Hz i en av dina högtalare. Om du har lyssnat på den ett tag, klicka Avsluta och gå till steg 3.

Steg 3

OK, det vore trevligare om du kunde höra sinusvågen i båda högtalarna. Anslut den högra porten på Synth_PLAY till utgången från Synth_WAVE_SIN också.

Skapa ett Synth_SEQUENCE-objekt (från Moduler->Syntes->Midi & sekvensiering). Det ska placeras överst på skärmen. Om du behöver mer utrymme kan du flytta de andra modulerna genom att markera dem (för att markera flera moduler håll nere skifttangenten), och dra omkring dem.

Anslut nu frekvensutgången på Synth_SEQUENCE till frekvensingången på Synth_FREQUENCY-modulen. Ange sedan sekvensens hastighet som konstant värde 0.13 (hastigheten är porten längs till vänster).

Gå nu till porten längs till höger (seq) på Synth_SEQUENCE och skriv in A-3;C-4;E-4;C-4; som konstant värde. Det här anger en sekvens. Mer om detta i modulreferensen.

Notera

Synth_SEQUENCE behöver verkligen en sekvens och hastigheten. Utan dessa kanske du får minnesdumpar.

Välj Arkiv->Kör struktur. Du kommer att höra en trevlig sekvens spelas upp. Om du har njutit av känslan, klicka Avsluta och gå till steg 4.

Steg 4

Skapa en Synth_PSCALE-modul (från Moduler->Syntes->Envelopper). Koppla bort utgången från sinusvågen genom att dubbelklicka på den och välja inte ansluten. Anslut

  1. Utgången SIN till ingången på PSCALE

  2. PSCALE utgången till AMAN_PLAY på vänster sida

  3. PSCALE utgången till AMAN_PLAY på höger sida

  4. SEQUENCE pos till PSCALE pos

Till slut, sätt PSCALE top till något värde, till exempel 0.1.

Hur fungerar detta nu: Synth_SEQUENCE ger ytterligare information om positionen för tonen den spelar just nu, där 0 betyder precis påbörjad och 1 betyder avslutad. Modulen Synth_PSCALE skalar ljudflödet som skickas genom den från volymen 0 (tyst) till 1 (ursprunglig ljudstyrka) tillbaka till 0 (tyst) enligt positionen. Positionen där toppen ska ske kan anges som top. 0.1 betyder att efter 10 % av tonen har spelats har volymen nått sitt maximala värde, och börjar sedan avta.

Välj Arkiv->Kör struktur. Du kommer att höra en trevlig sekvens spelas upp. Om du har njutit av känslan, klicka Avsluta och gå till steg 5.

Steg 5: Börja skicka omkring data ;)

Starta en aRts-byggare till.

Placera en Synth_AMAN_PLAY i den, och ställ in den till ett vettigt namn. Placera en Synth_BUS_DOWNLINK i den och:

  1. Sätt Synth_BUS_DOWNLINK bus till ljud (det är bara ett namn, kalla den Fred om du vill)

  2. Anslut Synth_BUS_DOWNLINK left (vänster) till Synth_AMAN_PLAY left.

  3. Anslut Synth_BUS_DOWNLINK right (höger) till Synth_AMAN_PLAY right.

Börja köra strukturen. Som väntat hör du ingenting, ... inte än.

Gå tillbaka till strukturen med Synth_WAVE_SIN grejorna och byt ut Synth_AMAN_PLAY-modulen mot en Synth_BUS_UPLINK, och ställ in namnet till ljud (eller Fred om du vill). Att ta bort moduler görs genom att markera dem och välja Redigera->Ta bort från menyn (eller trycka på tangenten Del).

Välj Arkiv->Kör struktur. Du kommer att höra sekvensen med skalade toner, transporterad över bussen.

Om du vill ta reda på varför något sådant här kan vara användbart, klicka Avsluta (i aRts-byggaren som kör Synth_SEQUENCE grejorna, du kan låta den andra fortsätta köra) och gå till steg 6.

Steg 6: Skicka data för avancerade användare

Välj Arkiv->Byt namn på struktur från menyn i den aRts-byggare som innehåller Synth_SEQUENCE grejorna, och kalla den handledning. Tryck OK.

Välj Arkiv->Spara som.

Starta ytterligare en aRts-byggare och välj Arkiv->Öppna, och ladda handledningen igen.

Nu kan du välja Arkiv->Kör struktur i båda aRts-byggarna som har strukturen. Nu hör du samma sak två gånger. Beroende på när du startar dem kommer det att låta mer eller mindre bra.

En annan sak som kan vara bra att göra vid det här tillfället är att starta Noatun, och spela en mp3-fil. Starta sedan artscontrol. Gå till Visa->Visa ljudhanterare. Vad du ser är Noatun och din struktur “handledning” spela upp någonting. Det trevliga som du kan göra är: dubbelklicka på Noatun. Du får nu en lista på tillgängliga bussar. Och ser du? Du kan låta Noatun skicka sin utmatning via ljudbussen till uppspelningsstrukturen som din handledning tillhandahåller.

Steg 7: Midisyntes

Till slut, nu ska du kunna göra om din sinusvåg till ett riktigt instrument. Det här är bara meningsfullt om du har något lämpligt som kan skicka MIDI-händelser till aRts. Här beskriver jag hur du kan använda ett externt keyboard, men en sequencer, som Brahms, som känner till midibussen fungerar också.

Först av allt, rensa på ditt skrivbord till du bara har en aRts-byggare med sinusvågstrukturen igång (men låt den inte köra). Gå därefter tre gånger till Portar->Skapa IN-ljudsignal, och tre gånger till Portar->Skapa UT-ljudsignal. Placera portarna någonstans.

Gå till Portar+Ändra positioner/namn och döp portarna till frequency, velocity, pressed, left, right, done.

Till sist kan du ta bort modulen Synth_SEQUENCE, och istället ansluta inporten frequency för strukturen till frekvensporten på Synth_FREQUENCY. Hmm. Men vad ska man göra med pos?

Den här är inte tillgänglig, eftersom det inte finns någon algoritm i värden som kan förutse när användaren ska släppa tangenten han just tryckte ner på sitt midi-keyboard. Vi har istället parametern pressed, som bara anger om användaren fortfarande håller nere tangenten. (pressed = 1: tangenten fortfarande nertryckt, pressed = 0: tangenten släppt)

Det här betyder också att Synth_PSCALE-objektet måste bytas ut nu. Koppla in en Synth_ENVELOPE_ADSR istället (från Moduler->Syntes->Envelopper). Anslut:

  1. Strukturens pressed ingång till ADSR active

  2. SIN utgången till ADSR ingången

  3. ADSR utgången till den vänstra strukturutgången

  4. ADSR utgången till den högra strukturutgången

Ställ in parametrarna attack till 0.1, decay till 0.2, sustain till 0.7, release till 0.1.

En sak till som vi måste tänka på är att instrumentstrukturen måste på något sätt veta när den har spelat färdigt och då kunna rensas bort, eftersom den annars aldrig skulle stanna även om tangenten har släppts. Som tur är, vet ADSR enveloppen när det inte finns mer att höra, eftersom den ändå skalar ner signalen till noll vid någon tidpunkt efter tangenten har släppts.

Det här anges genom att sätta utgången done till 1. Så anslut den här till strukturens utgång. Strukturen tas bort så fort done blir 1.

Döp om din struktur till instrument_handledning (från Arkiv->Byt namn på struktur. Spara den sedan med Spara som (det förvalda namnet som nu anges ska vara instrument_handledning).

Starta aRts control, och gå till Visa->Visa midihanterare, och välj Lägg till->aRts synthes midi utmatning. Till sist ska du kunna välja ditt instrument (handledning) här.

Öppna en terminal och skriv midisend. Du kommer att se att midisend och instrumentet nu listas i aRts MIDIhanterare. Efter att ha valt båda två och tryckt på Anslut, är vi till sist klara. Ta ditt keyboard och börja spela (det måste förstås vara anslutet till din dator).

Förslag

Du bör nu kunna arbeta med aRts. Här är några tips om vad du nu skulle kunna göra för att förbättra dina strukturer:

  • Försök att använda något annat än en sinusvåg. Om du kopplar in en triangelvåg, TRI, tycker du troligen inte att ljudet är särskilt trevligt, Men försök att lägga till ett SHELVE_CUTOFF-filter direkt efter triangelvågen för att klippa frekvenserna ovanför en viss frekvens (försök med något i stil med 1000 Hz, eller ännu bättre två gånger indatafrekvensen eller indatafrekvensen + 2000 Hz eller något sådant).

  • Försök använda mer än en oscillator. Synth_XFADE kan användas för att övertona (blanda) två signaler, Synth_ADD för att addera dem.

  • Försök att sätta frekvenserna för oscillatorerna till något olika värden, det ger trevliga oscillationer.

  • Experimentera med mer än ett envelopp.

  • Försök syntetisera instrument med olika ljud till vänster och höger.

  • Försök efterbehandla signalen när den kommer ut från bussens nerlänk. Du skulle till exempel kunna blanda en fördröjd version av signalen med originalet för att få en ekoeffekt.

  • Försök att använda anslagsstyrkan, velocity (det här är styrkan som tangenten har tryckts ner med, man kan också kalla det volymen). Specialeffekter uppstår alltid om det här inte bara ändrar volymen på signalen som skapas, utan också instrumentets ljud (till exempel klippningsfrekvensen).

  • ...

Om du har skapat något storartat, fundera gärna på att tillhandahålla det till aRts webbsida, eller för att ingå i nästa utgåva.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Exempel
Exempel

Exempel

aRts-byggaren levereras med flera exempel, som kan öppnas med Arkiv->Öppna exempel.... Några av dem är i katalogen, medan några (som av någon anledning inte fungerar med den nuvarande utgåvan) har lämnats i todo-katalogen.

Exemplen kan delas in i flera kategorier:

  • Självständiga exempel som illustrerar hur var och en av de inbyggda aRts-modulerna används (som heter example_*.arts). De här skickar typiskt någon utmatning till ett ljudkort.

  • Instrument som byggs från aRts-moduler på lägre nivå (som heter instrument_*.arts). De här följer en standardkonvention för in- och utportar så att de kan användas av MIDI-hanteraren i artscontrol.

  • Mallar för att skapa nya moduler (som heter template_*.arts).

  • Effekter som kan användas som återanvändbara byggblock (som heter effect_*.arts) [ alla att göra ]

  • Mixerelement som används för att skapa mixrar, inklusive grafiska styrmoduler (som heter mixer_element_*.arts). [ alla att göra ]

  • Diverse moduler som inte passar in i någon av de ovanstående kategorierna.

Detaljerad beskrivning av varje modul:

example_stereo_beep.arts

Skapar en 440 Hz sinusvåg i vänster kanal och en 880 Hz sinusvåg i höger kanal, och skickar dem till ljudkortet. Den här hänvisas till i aRts dokumentation.

example_sine.arts

Skapar en 440 Hz sinusvåg.

example_pulse.arts

Skapar en 440 Hz pulsvåg med 20% aktivitet.

example_softsaw.arts

Skapar en 440 Hz sågtandsvåg.

example_square.arts

Skapar en 440 Hz fyrkantvåg.

example_tri.arts

Skapar en 440 Hz triangelvåg.

example_noise.arts

Skapar vitt brus.

example_dtmf1.arts

Skapar en dubbelton genom att producera sinusvågor med 697 och 1209 Hz, skala dem till 0,5 och addera dem. Det här är DTMF-tonen för siffran "1" på en knapptelefon.

example_atan_saturate.arts

Kör en triangelvåg genom ett atan-mättningsfilter.

example_autopanner.arts

Använder autopanorering för att panorera en 400 Hz sinusvåg mellan vänster och höger högtalare med en hastighet av 2 Hz.

example_brickwall.arts

Skalar en sinusvåg med en faktor 5 och kör den sedan genom en tegelväggsbegränsare.

example_bus.arts

Länkar ner från en buss som heter “Bus” och länkar upp till bussen “out_soundcard” med vänster och höger kanal utbytta.

example_cdelay.arts

Länkar ner från en buss som heter “Delay” och länkar upp höger kanal genom en 0,5 sekunders fördröjning, och vänster kanal oförändrad. Du kan använda artscontrol för att ansluta effekten till ljuduppspelning och observera resultatet.

example_delay.arts

Det här är samma sak som example_cdelay.arts men använder fördröjningseffekten.

example_capture_wav.arts

Det här använder Synth_CAPTURE_WAV för att spara en 400 Hz sinusvåg som en wav-fil. Kör modulen i några sekunder, och titta sedan på filen som skapats i /tmp. Du kan spela upp filen med en mediaspelare som kaiman.

example_data.arts

Det här använder Data-modulen för att skapa en konstant ström av värdet “3” och skickar det till en Debug-modul för att visa det periodiskt. Det innehåller också en Nil-modul, och visar hur den kan användas för att göra ingenting alls.

example_adsr.arts

Visar hur ett enkelt instrumentljud kan skapas med envelopp ADSR-modulen, som triggas repetitivt av en fyrkantvåg.

example_fm.arts

Det här använder FM Source-modulen för att skapa en 440 Hz sinusvåg som frekvensmoduleras med en 5 Hz hastighet.

example_freeverb.arts

Det här förbinder Freeverb-effekten från en bussnerlänk till en bussupplänk. Du kan använda artscontrol för att ansluta effekten till ljuduppspelning och observera resultatet.

example_flanger.arts

Det här implementerar en enkel flänseffekt (det verkar dock inte fungera än).

example_moog.arts

Den här strukturen kombinerar de två kanalerna från en buss till en, skickar den genom ett Moog VCF filer, och skickar det sedan till bussen out_soundcard.

example_pitch_shift.arts

Den här strukturen skickar vänsterkanalens ljuddata genom en tonhöjdsändringseffekt. Justera hastighetsparametern för att variera effekten.

example_rc.arts

Den här strukturen skickar vitt brus genom ett RC-filer och ut till ljudkortet. Genom att titta på FFT mätaren i artscontrol kan du se hur det här skiljer sig från en ofiltrerad brusvågform.

example_sequence.arts

Det här demonstrerar Sequence-modulen genom att spela en sekvens av toner.

example_shelve_cutoff.arts

Den här strukturen skickar vitt brus genom ett hyllklippningsfilter och ut till ljudkortet. Genom att titta på FFT mätaren i artscontrol kan du se hur det här skiljer sig från en ofiltrerad brusvågform.

example_equalizer.arts

Det här demonstrerar modulen Std_Equalizer. Det höjer de låga och höga frekvenserna med 6 dB.

example_tremolo.arts

Det här demonstrerar tremoloeffekten. Det modulerar vänster och höger kanal med ett 10 Hz tremolo.

example_xfade.arts

Det här exemplet blandar 440 och 880 Hz sinusvågor med en övertoning. Justera värdet på övertoningens procentingång från -1 till 1 för att kontrollera blandningen av de två signalerna.

example_pscale.arts

Det här illustrerar Pscale-modulen (jag är inte säker på att det är ett meningsfullt exempel).

example_play_wav.arts

Det här illustrerar modulen Play Wave. Du måste ange hela sökvägen till en .wav-fil som filnamnsparameter.

example_multi_add.arts

Det här visar modulen Multi Add, som accepterar vilket antal ingångar som helst. Det summerar tre Data-moduler som producerar indata 1, 2 och 3, och visar resultatet 6.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 4. aRts i detalj
aRts i detalj
Föregående
Nästa

Kapitel 4. aRts i detalj

Arkitektur


aRts strukturer.
Moduler & portar
Moduler & portar

Moduler & portar

Idén med aRts är att syntes kan göras med små moduler, som bara gör en enda sak, och sedan kombinera dem i komplexa strukturer. De små modulerna har normalt ingångar, där de kan ta emot några signaler eller parametrar, och utgångar där de producerar några signaler.

En modul (Synth_ADD) tar till exempel bara de två signalerna på sina ingångar och adderar dem. Resultatet är tillgängligt som en utsignal. De ställen där moduler tillhandahåller sina in- eller utsignaler kallas portar.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Strukturer
Strukturer

Strukturer

En struktur är en kombination av ihopkopplade moduler, där några kan ha parametrar som är direktkodade på deras inportar, andra kan vara ihopkopplade, och en del kan vara helt oanslutna.

Vad du kan göra med aRts-byggaren är att beskriva strukturer. Du beskriver vilka moduler du vill ska kopplas ihop med vilka andra moduler. När du är klar, kan du spara strukturbeskrivningen i en fil, eller be aRts att skapa (köra) den strukturen som du beskrivit.

Därefter hör du förmodligen något ljud, om du har gjort allt på rätt sätt.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Latenstid
Latenstid

Latenstid

Vad är latenstid?

Anta att du har ett program som heter “muspling” (som ska avge ett “pling” ljud om du klickar på en musknapp). Latenstiden är tiden mellan ditt finger trycker på musknappen och du hör plinget. Latenstiden för det här scenariot består av flera olika latenstider, som har olika orsaker.

Latenstid i enkla program

För det här enkla programmet uppstår latenstiden på följande ställen:

  • Tiden till kärnan har meddelat X11-servern att musknappen har tryckts ner.

  • Tiden till X11-servern har meddelat ditt program att musknappen har tryckts ner.

  • Tiden till muspling-programmet har bestämt att den här knappen var värd att få ett pling spelat.

  • Tiden det tar för muspling-programmet att tala om för ljudservern att den ska spela ett pling.

  • Tiden det tar för plinget (som ljudservern börjar mixa med övrig utmatning omedelbart) att ta sig igenom buffrad data, till det verkligen når stället där ljudkortet spelar.

  • Tiden det tar för pling-ljudet att gå från högtalarna till dina öron.

De första tre punkterna är latenstid utanför aRts. De är intressanta, men utanför det här dokumentets omfattning. Hur som helst, var medveten om att de finns, så att även om du har optimerat allting annat till verkligt små värden, så kanske du inte nödvändigtvis får exakt det resultat du förväntar dig.

Att be servern att spela någonting innebär oftast bara ett enda MCOP-anrop. Det finns mätningar som bekräftar att det går att be servern att spela någonting 9000 gånger per sekund med den nuvarande implementeringen, på samma värddator med Unix domänuttag. Jag antar att det mesta av det här är kärnans omkostnad, för att byta från en process till en annan. Naturligtvis ändras det här värdet med de exakta typerna på parametrarna. Om man överför en hel bild med ett anrop, blir det långsammare än om man bara överför ett "long" värde. Detsamma är sant för returvärdet. För vanliga strängar (som filnamnet på wav-filen som ska spelas) ska inte det här vara ett problem.

Det här betyder att vi kan approximera den här tiden med 1/9000 sekund, det vill säga under 0,15 ms. Vi kommer att se att detta inte är relevant.

Därefter kommer tiden efter servern börjar spela och ljudkortet tar emot någonting. Servern måste buffra data, så att inga pauser hörs när andra program, som din X11-server eller “muspling”-programmet, kör. Det sätt som detta hanteras på Linux® är att det finns ett antal fragment av en viss storlek. Servern fyller på fragment, och ljudkortet spelar fragment.

Så antag att det finns tre fragment. Servern fyller det första och ljudkortet börjar spela det. Servern fyller det andra. Servern fyller det tredje. Servern är klar och andra program kan nu göra någonting.

När ljudkortet har spelat det första fragmentet, börjar det spela det andra och servern börjar fylla det första igen, och så vidare.

Den maximala latenstiden du får med allt detta är (antal fragment) * (storlek på varje fragment) / (samplingsfrekvens * (storlek på varje sampling)). Om vi antar 44 kHz stereo, och sju fragment på 1024 byte (de nuvarande förvalda inställningarna i aRts), så får vi 40 ms.

De här värdena kan anpassas enligt dina behov. CPU-användningen ökar dock med mindre latenstider, eftersom ljudservern måste fylla på buffrarna oftare, och med mindre delar. Det är också oftast omöjligt att nå bättre värden utan att ge ljudservern realtidsprioritet, eftersom man annars ofta får pauser.

Det är i alla fall realistiskt att göra någonting i stil med 3 fragment med 256 byte vardera, som skulle ändra det här värdet till 4,4 ms. Med 4,4 ms fördröjning skulle aRts CPU-användning vara ungefär 7,5 %. Med en 40 ms fördröjning, skulle den vara ungefär 3 % (för en PII-350, och värdet kan bero på ditt ljudkort, version av kärnan och annat).

Så är det tiden som det tar för pling-ljudet att gå från högtalarna till dina öron. Antag att ditt avstånd från högtalarna är 2 meter. Ljud rör sig med hastigheten 330 meter per sekund. Så vi kan uppskatta den här tiden till 6 ms.

Latenstid i program med ljudflöden

Program med ljudflöden är de som skapar sitt ljud själva. Tänk dig ett spel som skickar ett konstant flöde med samplingar, och nu ska anpassas att spela upp ljud via aRts. Som ett exempel: när jag trycker på en tangent så hoppar figuren som jag använder, och ett bång-ljud spelas upp.

Först så måste du veta hur aRts hanterar strömmar. Det är mycket likt I/O med ljudkortet. Spelet skickar några paket med samplingar till ljudservern, låt oss anta tre stycken. Så fort som ljudservern är klar med det första paketet, skickar det en bekräftelse tillbaka till spelet att det paketet är klart.

Spelet skapar ytterligare ett ljudpaket och skickar det till servern. Under tiden börjar servern konsumera det andra ljudpaketet, och så vidare. Latenstiden här liknar den i det enklare fallet:

  • Tiden till kärnan har meddelat X11-servern att en knapp har tryckts ner.

  • Tiden till X11-servern har meddelat spelet att en knapp har tryckts ner.

  • Tiden till spelet har bestämt att den här knappen var värd att få ett bång spelat.

  • Tiden till ljudpaketet som spelet har börjat stoppa in bång-ljudet i når ljudservern.

  • Tiden det tar för bånget (som ljudservern börjar mixa med övrig utmatning omedelbart) att ta sig igenom buffrad data, till det verkligen når stället där ljudkortet spelar.

  • Tiden det tar för bång-ljudet från högtalarna att nå dina öron.

De externa latenstiderna, som ovan, är utanför det här dokumentets omfattning.

Det är uppenbart att latenstiden för strömmar beror på tiden det tar för alla paket som används att spelas en gång. Så den är (antal paket) * (storlek på varje paket) / (samplingsfrekvensen * (storlek på varje sampling)).

Som du ser är detta samma formel som gäller för fragmenten. För spel finns det dock ingen anledning att ha så korta fördröjningar som ovan. Jag skulle vilja säga att ett realistiskt exempel för ett spel skulle vara 2048 byte per paket, använd 3 paket. Latenstidsresultatet skulle då vara 35 ms.

Det här är baserat på följande: antag att ett spel renderar 25 bilder per sekund (för skärmen). Det är antagligen helt säkert att anta att en skillnad på en bild för ljudutmatningen inte skulle märkas. Därför är 1/25 sekunds fördröjning för ljudflöden acceptabelt, vilket i sin tur betyder att 40 ms skulle vara ok.

De flesta personer kör inte heller sina spel med realtidsprioritet, och faran med pauser i ljudet kan inte bortses ifrån. Strömmar med 3 paket på 256 byte är möjliga (jag provade det) - men orsakar mycket CPU-användning för strömhantering.

Latenstider på serversidan kan du beräkna precis som ovan.

Några CPU-användningshänsyn

Det finns många faktorer som påverkar CPU-användning i ett komplext scenario, med några program med ljudflöden och några andra program, några insticksprogram i servern, etc. För att ange några få:

  • CPU-användning för de nödvändiga beräkningarna.

  • aRts interna schemaläggningsomkostnad - hur aRts bestämmer när vilken modul ska beräkna vad.

  • Omkostnad för konvertering av heltal till flyttal.

  • MCOP protokollomkostnad.

  • Kärnans process/sammanhangsbyte.

  • Kärnans kommunikationsomkostnad.

För beräkning av rå CPU-användning, om du spelar upp två strömmar samtidigt måste du göra additioner. Om du applicerar ett filter, är vissa beräkningar inblandade. För att ta ett förenklat exempel, att addera två strömmar kräver kanske fyra CPU-cykler per addition, på en 350 MHz processor är detta 44100 * 2 * 4 / 350000000 = 0,1 % CPU-användning.

aRts interna schemaläggning: aRts behöver bestämma vilken insticksmodul som ska beräkna vad när. Detta tar tid. Använd ett profileringsverktyg om du är intresserad av det. Vad som kan sägas i allmänhet är att ju mindre realtid som används (dvs. ju större block som kan beräknas åt gången) desto mindre schemaläggningsomkostnad fås. Över beräkning av block med 128 samplingar åt gången (alltså med användning av fragmentstorlekar på 512 byte) är schemaläggningsomkostnad förmodligen inte värt att bry sig om.

Konvertering från heltal till flyttal: aRts använder flyttal som internt dataformat. De är enkla att hantera, och på moderna processorer inte mycket långsammare än heltalsoperationer. Om det i alla fall finns klienter som spelar data som inte är flyttal (som ett spel som ska göra sin ljudutmatning via aRts), behövs konvertering. Detsamma gäller om du vill spela upp ljud på ditt ljudkort. Ljudkortet behöver heltal, så du måste konvertera.

Här är värden för en Celeron, ungefärliga klockcykler per sampling, med -O2 och egcs 2.91.66 (mätta av Eugene Smith ). Det här är förstås ytterst processorberoende:

convert_mono_8_float: 14
convert_stereo_i8_2float: 28
convert_mono_16le_float: 40
interpolate_mono_16le_float: 200
convert_stereo_i16le_2float: 80
convert_mono_float_16le: 80

Så detta betyder 1 % CPU-användning för konvertering och 5 % för interpolation på den här 350 MHz processorn.

MCOP protokollomkostnad: MCOP klarar, som en tumregel, 9000 anrop per sekund. En stor del av detta är inte MCOP:s fel, utan hör ihop med de två orsakerna för kärnan som nämns nedan. Det här ger i alla fall en bas för att göra beräkningar av vad kostaden för strömhantering är.

Varje datapaket som skickas med en ström kan anses vara ett MCOP-anrop. Stora paket är förstås långsammare än 9000 paket/s, men det ger en god idé.

Antag att du använder paketstorlekar på 1024 byte. På så sätt, för att överföra en ström med 44 kHz stereo, behöver du överföra 44100 * 4 / 1024 = 172 paket per sekund. Antag att du kunde överföra 9000 paket med 100 % CPU-användning, då får du (172 *100) / 9000 = 2 % CPU-användning på grund av strömmen med 1024 byte paket.

Detta är en approximation. Det visar i alla fall att du skulle klara dig mycket bättre (om du har råd med latenstiden), med att till exempel använda paket på 4096 byte. Här kan vi skapa en kompakt formel, genom att beräkna paketstorleken som orsakar 100 % CPU-användning som 44100 * 4 / 9000 = 19,6 samplingar, och på så sätt få snabbformeln:

CPU-användning för en ström i procent = 1960 / (din paketstorlek)

som ger oss 0,5 % CPU-användning med en ström av 4096 byte paket.

Kärnans process/sammanhangsbyte: Det här är en del av MCOP-protokollets omkostnad. Att byta mellan två processer tar tid. Det blir en ny minnesmappning, cachar blir ogiltiga, och en del annat (om en expert på kärnan läser det här - tala om de exakta orsakerna för mig). Det här betyder: det tar tid.

Jag är inte säker på hur många processbyten Linux® kan göra per sekund, men värdet är inte oändligt. Så av MCOP-protokollets omkostnad, antar jag att en hel del beror på processbyten. När MCOP först påbörjades provade jag samma kommunikation inne i en process, och det var mycket snabbare (ungefär fyra gånger snabbare).

Kärnans kommunikationsomkostnad: Det här är en del av MCOP-protokollets omkostnad. Att överföra data mellan processer görs för närvarande via ett uttag (socket). Det här är bekvämt, eftersom den vanliga select() metoden kan användas för att avgöra när ett meddelande har anlänt. Det kan också kombineras med andra I/O-källor som ljud-I/O, X11-server eller vad som helst annat.

De här läs- och skrivanropen kostar definitivt processorcykler. För små anrop (som att överföra en midi-händelse) är det förmodligen inte så farligt, men för stora anrop (som att överföra en videobild med flera Mibyte) är det helt klart ett problem.

Att lägga till användning av delat minne till MCOP där det är lämpligt är förmodligen den bästa lösningen. Det måste dock göras transparent för tillämpningsprogrammeraren.

Ta ett profileringsverktyg och gör andra prov för att exakt ta reda på hur nuvarande ljudströmmar påverkas av att inte använda delat minne. Det är dock inte så dåligt, eftersom ljudströmmar (spela upp mp3) kan göras med totalt 6 % CPU-användning för artsd och artscat (och 5 % för mp3-avkodaren). Det här innefattar dock allting från nödvändiga beräkningar till omkostnad för uttaget, så jag skulle uppskatta att man skulle vinna ungefär 1 % på att använda delat minne.

Några riktiga värden

De här är gjorda med den nuvarande utvecklingsversionen. Jag ville också försöka med riktigt svåra fall, så det här är inte vad program för daglig användning skulle göra.

Jag skrev ett program som heter streamsound som skickar dataflöden till aRts. Här körs det med realtidsprioritet (utan problem), och en liten insticksmodul på serversidan (volymskalning och klippning):

4974 stefan    20   0  2360 2360  1784 S       0 17.7  1.8   0:21 artsd
 5016 stefan    20   0  2208 2208  1684 S       0  7.2  1.7   0:02 streamsound
 5002 stefan    20   0  2208 2208  1684 S       0  6.8  1.7   0:07 streamsound
 4997 stefan    20   0  2208 2208  1684 S       0  6.6  1.7   0:07 streamsound

Var och en av programmen skickar en ström med 3 fragment på 1024 byte (18 ms). Det finns tre sådana klienter som kör samtidigt. Jag vet att det verkar vara lite väl mycket, men som jag sa: ta ett profileringsverktyg och ta reda på vad som kostar tid, och om du vill, förbättra det.

Jag tror i alla fall inte att använda strömmar så här är realistiskt eller vettigt. För att göra det hela ännu mer extremt, försökte jag med den minsta möjliga latenstiden. Resultat: man kan använda strömmar utan avbrott med ett klientprogram, om man tar 2 fragment med 128 byte mellan aRts och ljudkortet, och mellan klientprogrammet och aRts. Det här betyder att man har en total maximal latenstid på 128 * 4 / 44100 * 4 = 3 ms, där 1,5 ms skapas på grund av I/O till ljudkortet och 1,5 ms skapas av kommunikation med aRts. Båda programmen måste köra med realtidsprioritet.

Men det här kostar en enorm mängd CPU. Det här exemplet kostar ungefär 45 % på min P-II/350. Det börjar också gå fel om man startar top, flyttar fönster på X11-skärmen eller gör disk-I/O. Allt det här har med kärnan att göra. Problemet är att schemalägga två eller flera processer med realtidsprioritet också kostar en enorm ansträngning, ännu mer än kommunikation och meddelande till varandra, etc.

Till sist, ett mer vardagligt exempel: Det här är aRts med artsd och en artscat (en klient med dataflöde) som kör 16 fragment på 4096 byte:

5548 stefan    12   0  2364 2364  1752 R       0  4.9  1.8   0:03 artsd
 5554 stefan     3   0   752  752   572 R       0  0.7  0.5   0:00 top
 5550 stefan     2   0  2280 2280  1696 S       0  0.5  1.7   0:00 artscat


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Bussar
Bussar

Bussar

Bussar är förbindelser som byggs dynamiskt för att överföra ljud. Det finns ett antal upplänkar och nerlänkar. Alla signaler från upplänkarna adderas och skickas till nerlänkarna.

Bussar är för närvarande implementerade för att fungera med stereo, så du kan bara överföra stereodata via bussar. Om du vill ha monodata, nå, överför det bara på en kanal och sätt den andra till noll eller något godtyckligt. Vad du måste göra är att skapa en eller flera Synth_BUS_UPLINK-objekt och ge dem ett bussnamn, som de ska prata med (t.ex. “ljud” eller “trummor”). Skicka sedan helt enkelt in data dit.

Därefter måste du skapa en eller flera Synth_BUS_DOWNLINK-objekt, och tala om bussnamnet för dem (“ljud” eller “trummor”... om det passar ihop, kommer data igenom), och det blandade ljudet kommer ut igen.

Upplänkarna och nerlänkarna kan finnas i olika strukturer, du kan till och med ha olika aRts-byggare som kör och starta en upplänk i en och ta emot data i den andra med en nerlänk.

Vad som är trevligt med bussar är att de är fullständigt dynamiska. Klienter kan kopplas in eller ur i farten. Det ska inte höras några klick eller brus när detta sker.

Du ska förstås inte koppla in eller ur en klient medan den spelar en signal, eftersom den förmodligen inte är noll när den kopplas ur, och då uppstår ett klick.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Handlaren
Handlaren

Handlaren

aRts/MCOP förlitar sig helt på att dela upp objekt i små komponenter. Det här gör allt mycket flexibelt, eftersom man lätt kan utöka systemet genom att lägga till nya komponenter, som implementerar nya effekter, filformat, oscillatorer, grafiska element, ... Eftersom nästan allt är komponenter, kan nästan allt lätt utökas utan att ändra befintlig källkod. Nya komponenter kan enkelt laddas dynamiskt för att förbättra program som redan finns.

För att detta ska fungera, behövs dock två saker:

  • Komponenter måste tala om att de finns - de måste beskriva vilka storartade saker de erbjuder, så att program kan använda dem.

  • Program måste aktivt leta efter komponenter som de skulle kunna använda, istället för att alltid använda samma komponent för en viss uppgift.

Kombinationen av det här: komponenter som säger “här är jag, jag är tuff, använd mig”, och program (eller om man vill, andra komponenter) som går ut och letar efter vilken komponent som de kan använda för att få någonting gjort, kallas att handla.

I aRts beskriver komponenter sig genom att ange värden som de “stöder” som egenskaper. En typisk egenskap för en filladdningskomponent kan vara filändelsen för filerna som den kan behandla. Typiska värden kan vara wav, aiff eller mp3.

I själva verket kan varje komponent välja att erbjuda många olika värden för en egenskap. Så en enda komponent skulle kunna erbjuda att läsa både wav och aiff filer, genom att ange att den stöder de här värdena för egenskapen “Extension”.

För att göra det här, måste en komponent lägga en .mcopclass-fil som innehåller egenskaperna den stöder på ett lämpligt ställe. För vårt exempel, kan den se ut så här (och skulle installeras i komponentkatalog/Arts/WavPlayObject.mcopclass):

Interface=Arts::WavPlayObject,Arts::PlayObject,Arts::SynthModule,Arts::Object
Author="Stefan Westerfeld <stefan@space.twc.de>"
URL="http://www.arts-project.org"
Extension=wav,aiff
MimeType=audio/x-wav,audio/x-aiff

Det är viktigt att filnamnet på .mcopclass-filen också anger vad komponentens gränssnitt heter. Handlaren tittar inte på innehållet alls, om filen (som här) heter Arts/WavPlayObject.mcopclass, och komponentgränssnittet heter Arts::WavPlayObject (moduler hör ihop med kataloger).

För att leta efter komponenter finns det två gränssnitt (som är definierade i core.idl, så de är tillgängliga i varje program), som heter Arts::TraderQuery och Arts::TraderOffer. Du går på en “shoppingrunda” efter komponenter så här:

  1. Skapa ett frågeobjekt:

    Arts::TraderQuery query;
    
  2. Ange vad du vill ha. Som du såg ovan, beskriver komponenter sig själva med egenskaper, som de sätter till vissa värden. Så att specificera vad du vill ha görs genom att välja komponenter som stöder ett visst värde för en egenskap. Det här sker med metoden supports i TraderQuery:

    query.supports("Interface","Arts::PlayObject");
        query.supports("Extension","wav");
    
  3. Till sist utförs förfrågan med metoden query. Sedan får du (förhoppningsvis) några erbjudanden:

    vector<Arts::TraderOffer> *offers = query.query();
    
  4. Nu kan du undersöka vad du hittade. Det viktiga är metoden interfaceName i TraderOffer, som ger dig namnen på komponenterna som svarade på frågan. Du kan också ta reda på ytterligare egenskaper med getProperty. Följande kod löper helt enkelt igenom alla komponenterna, skriver ut deras gränssnittsnamn (som skulle kunna användas för att skapa dem), och tar bort resultatet av frågan:

    vector<Arts::TraderOffer>::iterator i;
        for(i = offers->begin(); i != offers->end(); i++)
            cout << i->interfaceName() << endl;
        delete offers;
    

För att den här sortens handelsservice ska vara användbar, är det viktigt att på något sätt komma överens om vilka egenskaper som komponenter normalt ska definiera. Det är väsentligt att mer eller mindre alla komponenter inom ett visst område använder samma uppsättning egenskaper för att beskriva sig själva (och samma uppsättning värden när det behövs), så att program (eller andra komponenter) kan hitta dem.

Author (typ stäng, valfri): Upphovsman. Det här kan användas för att till sist låta världen få reda på att du skrivit någonting. Du kan skriva vad du vill här, en e-postadress är förstås en bra hjälp.

Buildable (typ boolean, rekommenderas): Byggbar. Det här anger om komponenten är användbar med RAD-verktyg (som aRts-byggaren) som använder komponenter genom att tilldela egenskaper och ansluta portar. Det rekommenderas att det här värdet sätts till true för nästan alla signalbehandlingskomponenter (som filer, ljudeffekter, oscillatorer, ...), och för alla andra objekt som kan användas på ett RAD-liknande sätt, men inte för interna objekt som till exempel Arts::InterfaceRepo.

Extension (typ sträng, använd där det passar): Filändelse. Alla moduler som hanterar filer bör fundera på att använda det här. Du anger filändelsen med små bokstäver utan “.” här, så något som wav ska fungera utmärkt.

Interface (typ sträng, krävs): Gränssnitt. Det här ska omfatta hela listan på (användbara) gränssnitt som din komponent stöder, troligen inklusive Arts::Object och om tillämpligt Arts::SynthModule.

Language (typ sträng, rekommenderas): Språk. Om du vill att din komponent ska laddas dynamiskt, måste du ange språket här. För närvarande är det enda tillåtna värdet C++, som betyder att komponenten är skriven med det normala C++ programmeringsgränssnittet. Om du anger detta, måste du också ange egenskapen “Library” nedan.

Library (typ sträng, använd där det passar): Bibliotek. Komponenter som är skrivna i C++ kan laddas dynamiskt. För att göra det måste du kompilera dem i en dynamiskt laddningsbar libtool (.la) modul. Här kan du ange namnet på .la-filen som innehåller din komponent. Kom ihåg att använda REGISTER_IMPLEMENTATION (som alltid).

MimeType (typ sträng, använd där det passar): Mimetyp. Alla som hanterar filer bör tänka sig att använda det här. Du ska ange standard-mimetypen med små bokstäver här, till exempel audio/x-wav.

URL (typ sträng, valfri): Om du vill tala om var man kan hitta en ny version av komponenten (eller en hemsida eller något annat), kan du göra det här. Det här ska vara en standard HTTP- eller FTP-webbadress.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Namnrymder i aRts
Namnrymder i aRts

Namnrymder i aRts

Inledning

Varje namnrymdsdeklaration hör ihop med en deklaration av en “modul” i MCOP IDL.

// mcop idl

module M {
    interface A
    {
    }
};

interface B;

I det här fallet skulle den genererade C++ koden för IDL-fragmentet se ut så här:

// C++ deklaration

namespace M {
    /* deklaration av A_base/A_skel/A_stub och liknande */
    class A {        // Smartwrap referensklass
        /* [...] */
    };
}

/* deklaration av B_base/B_skel/B_stub och liknande */
class B {
    /* [...] */
};

Så när du hänvisar till klasserna från exemplet ovan i din C++ kod, måste du skriva M::A, men bara B. Du kan förstås använda “using M” någonstans, som med alla namnrymnder i C++.

Hur aRts använder namnrymder

Det finns en global namnrymd som kallas “Arts”, som alla program och bibliotek som hör till aRts själv använder för att lägga sina deklarationer i. Det här betyder att när du skriver C++ kod som beror på aRts, måste du normalt använda prefixet Arts:: för varje klass som du använder, så här:

int main(int argc, char **argv)
{
    Arts::Dispatcher dispatcher;
    Arts::SimpleSoundServer server(Arts::Reference("global:Arts_SimpleSoundServer"));

    server.play("/var/foo/någon_fil.wav");

Det andra alternativet är att skriva "using" en gång, så här:

using namespace Arts;

int main(int argc, char **argv)
{
    Dispatcher dispatcher;
    SimpleSoundServer server(Reference("global:Arts_SimpleSoundServer"));

    server.play("/var/foo/någon_fil.wav");
    [...]

I IDL-filer, har du egentligen inget val. Om du skriver kod som tillhör aRts själv, måste du lägga den i modulen aRts.

// IDL-fil för aRts-kod:
#include <artsflow.idl>
module Arts {        // lägg den i Arts-namnrymd
    interface Synth_TWEAK : SynthModule
    {
        in audio stream invalue;
        out audio stream outvalue;
        attribute float tweakFactor;
    };
};

Om du skriver kod som inte hör till aRts själv, ska du inte lägga den i namnrymden “Arts”. Du kan dock skapa en egen namnrymd om du vill. Hur som helst, måste du använda prefix för klasser från aRts som du använder.

// IDL-fil för kod som inte hör till aRts:
#include <artsflow.idl>

// skriv antingen med eller utan moduldeklaration, och de genererade klasserna
// kommer inte att använda en namnrymd:
interface Synth_TWEAK2 : Arts::SynthModule
{
    in audio stream invalue;
    out audio stream outvalue;
    attribute float tweakFactor;
};

// du kan dock välja en egen namnrymd om du vill, så om du
// skriver programmet "PowerRadio", skulle du kunna göra så här:
module PowerRadio {
    struct Station {
        string name;
        float frequency;
    };

    interface Tuner : Arts::SynthModule {
        attribute Station station;     // inget prefix för Station, samma modul
        out audio stream left, right;
    };
};

Interna funktioner: hur implementeringen fungerar

MCOP behöver ofta hänvisa till namn på typer och gränssnitt för typkonverteringar, gränssnitt och metodsignaturer. Dessa representeras av strängar i de vanliga MCOP-datastrukturerna, medan namnrymden alltid är fullständigt representerad i C++ stilen. Det här betyder att strängarna skulle innehålla “M::A” och “B”, enligt exemplen ovan.

Observera att detta gäller till och med om namnrymdskvalificeringen inte angavs inne i IDL-texten, eftersom sammanhanget klargör vilken namnrymd gränssnittet A var tänkt att användas.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Trådar i aRts
Trådar i aRts

Trådar i aRts

Grundläggande information

Att använda trådar är inte möjligt på alla plattformar. Det här är orsaken att aRts ursprungligen skrevs utan att använda trådar alls. För nästan alla problem, finns det en lösning utan trådar som gör samma sak som varje lösning med trådar.

Till exempel, istället för att placera ljudutmatning i en separat tråd, och göra den blockerande, använder aRts ljudutmatning som inte blockerar, och räknar ut när nästa del av utdata ska skrivas med select().

aRts stöder åtminstone (i de senaste versionerna) de som vill implementera sina objekt med trådar. Till exempel om du redan har kod för en mp3-spelare, och koden förväntar sig att mp3-avkodaren ska köras i en separat tråd, är det oftast lättast att behålla den konstruktionen.

Implementeringen av aRts/MCOP är uppbyggd genom att dela tillståndet mellan olika objekt på tydliga och mindre tydliga sätt. En kort lista på delade tillstånd innefattar:

  • Avsändarobjektet som gör MCOP-kommunikation

  • Referensräkningen (Smartwrappers).

  • I/O-hanteraren som hanterar tidsgränser och fd-tidmätning.

  • Objekthanteraren som skapar objekt och laddar insticksmoduler dynamiskt.

  • Flödessystemet som anropar calculateBlock vid lämpliga tillfällen.

Inget av de ovanstående objekten förväntar sig att användas med samtidighet (dvs. anropas från olika trådar samtidigt). I allmänhet finns det två sätt att lösa detta:

  • Kräva att den som anropar vilken funktion som helst i objektet skaffar ett lås innan den används.

  • Göra objekten verkligt trådsäkra och/eller skapa instanser av dem för varje tråd.

aRts använder det första sättet. Du behöver ett lås varje gång du ska komma åt några av de här objekten. Det andra sättet är svårare att göra. En snabbfix som försöker åstadkomma detta finns på http://space.twc.de/~stefan/kde/download/arts-mt.tar.gz, men för närvarande fungerar förmodligen ett minimalt sätt bättre, och orsakar mindre problem med befintliga program.

När/hur ska låsning ske?

Du kan skaffa/släppa låset med de två funktionerna:

I allmänhet behöver du inte skaffa ett lås (och du ska inte försöka att göra det), om det redan hålls. En lista på villkor när detta är fallet är:

  • Du tar emot ett återanrop från I/O-hanteraren (tidsgräns eller fd).

  • Du anropas på grund av någon MCOP-begäran.

  • Du anropas från NotificationManager.

  • Du anropas från flödessystemet (calculateBlock)

Det finns också några undantag för funktioner som du bara kan anropa i huvudtråden, och av den anledningen aldrig behöver ett lås för att anropa dem:

  • Skapa och ta bort avsändaren eller I/O-hanteraren.

  • Dispatcher::run() / IOManager::run()

  • IOManager::processOneEvent()

Men det är allt. För allt annat som på något sätt hör ihop med aRts, måste du skaffa låset, och släppa det igen när du är klar. Här är ett enkelt exempel:

class SuspendTimeThread : Arts::Thread {
public:
    void run() {
        /*
         * du behöver det här låset därför att:
         *  - skapa en referens behöver ett lås (eftersom global: går till
         *    objekthanteraren, som i sin tur kan behöva GlobalComm
         *    objektet för att slå upp vart anslutningen ska göras)
         *  - tilldela en smartwrapper behöver ett lås
         *  - skapa ett objekt från en referens behöver ett lås (eftersom
         *    det kan behöva ansluta till en server)
         */
        Arts::Dispatcher::lock();
        Arts::SoundServer server = Arts::Reference("global:Arts_SoundServer");
        Arts::Dispatcher::unlock();

        for(;;) {            /*
             * du behöver ett lås här, eftersom
             *  - följa en referens för en smartwrapper behöver ett lås
             *    (eftersom det kan skapa objektet när det används)
             *  - att göra ett MCOP-anrop behöver ett lås
             */
            Arts::Dispatcher::lock();
            long seconds = server.secondsUntilSuspend();
            Arts::Dispatcher::unlock();

            printf("sekunder till vänteläge = %d",seconds);
            sleep(1);
        }
    }
}

Trådrelaterade klasser

Följande trådrelaterade klasser finns tillgängliga för närvarande:

  • Arts::Thread - som kapslar in en tråd.

  • Arts::Mutex - som kapslar in en mutex.

  • Arts::ThreadCondition - som ger stöd för att väcka upp trådar som väntar på att ett visst villkor ska bli sant.

  • Arts::SystemThreads - som kapslar in operativsystemets trådningslager (och ger några hjälpfunktioner för tillämpningsprogrammerare).

Se länkarna för dokumentation.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Referenser och felhantering
Referenser och felhantering

Referenser och felhantering

MCOP-referenser är ett av de mest centrala koncepten i MCOP programmering. Det här avsnittet försöker beskriva exakt hur referenser används, och behandlar särskilt felfall (serverkrascher).

Grundläggande egenskaper för referenser

  • En MCOP referens är inte ett objekt, utan en referens till ett objekt: Även om följande deklaration

       Arts::Synth_PLAY p;
    
    ser ut som en definition av ett objekt, så deklarerar det bara en referens till ett objekt. Som C++ programmerare, kan du också se den som Synth_PLAY *, en sorts pekare till ett Synth_PLAY-objekt. Det betyder i synnerhet att p kan vara samma sak som en NULL-pekare.

  • Du kan skapa en NULL-referens genom att explicit tilldela den.

    Arts::Synth_PLAY p = Arts::Synth_PLAY::null();
    
  • Att anropa objekt med en NULL-referens orsakar en minnesdump

    Arts::Synth_PLAY p = Arts::Synth_PLAY::null();
       string s = p.toString();
    

    orsakar en minnesdump. Om man jämför detta med en pekare, är det i stor sett samma som

       QWindow* w = 0;
       w->show();
    
    vilket varje C++ programmerare vet att man ska undvika.

  • Oinitierade objekt försöker att skapa sig själva när de först används

    Arts::Synth_PLAY p;
       string s = p.toString();
    

    är något annorlunda än att följa en NULL-pekare. Du talade inte alls om för objektet vad det är, och nu försöker du använda det. Gissningen här är att du vill ha en ny lokal instans av ett Arts::Synth_PLAY-objekt. Du kan förstås ha velat göra något annat (som att skapa objektet någon annanstans, eller använda ett befintligt fjärrobjekt). Det är i alla fall en bekväm genväg för att skapa objekt. Att skapa ett objekt när det först används fungerar inte när du väl har tilldelat det något annat (som en null-referens).

    Den motsvarande C++ terminologin skulle vara

       QWidget* w;
       w->show();
    
    som naturligtvis helt enkelt ger ett segmenteringsfel i C++. Så detta är annorlunda här. Det här sättet att skapa objekt är knepigt, eftersom det inte är nödvändigt att det finns en implementering för ditt gränssnitt.

    Betrakta till exempel ett abstrakt objekt som ett Arts::PlayObject. Det finns naturligtvis konkreta PlayObjects, som de för att spela mp3-filer eller wav-filer, men

       Arts::PlayObject po;
       po.play();
    
    misslyckas helt säkert. Problemet är att fastän ett PlayObject försöker skapas, så misslyckas det eftersom det bara finns objekt som Arts::WavPlayObject och liknande. Använd därför bara det här sättet att skapa objekt om du är säker på att det finns en implementering.

  • Referenser kan peka på samma objekt

    Arts::SimpleSoundServer s = Arts::Reference("global:Arts_SimpleSoundServer");
       Arts::SimpleSoundServer s2 = s;
    

    skapar två referenser som anger samma objekt. Det kopierar inte något värde, och skapar inte två objekt.

  • Alla objekt referensräknas. Så fort ett objekt inte har några referenser längre, tas det bort. Det finns inget sätt att uttryckligen ta bort ett objekt, men du kan dock använda något sådant här

       Arts::Synth_PLAY p;
       p.start();
       [...]
       p = Arts::Synth_PLAY::null();
    
    för att få Synth_PLAY-objektet att försvinna till slut. I synnerhet ska det aldrig vara nödvändigt att använda new och delete i samband med referenser.

Fallet med misslyckanden

Eftersom referenser kan peka på fjärrobjekt, kan servrarna som innehåller de här objekten krascha. Vad händer då?

  • En krasch ändrar inte om en referens är en null-referens. Det här betyder att om foo.isNull() var true innan en serverkrasch är den också true efter en serverkrasch (vilket är självklart). Det betyder också att om foo.isNull() var false innan en serverkrasch (foo angav ett objekt) är den också false efter serverkraschen.

  • Att anropa metoder med en giltig referens förblir säkert. Antag att servern som innehåller objektet calc kraschade. Fortfarande är anrop till objekt som

       int k = calc.subtract(i,j)
    
    säkra. Det är uppenbart att subtract måste returnera något här, vilket den inte kan eftersom fjärrobjektet inte längre finns. I det här fallet skulle (k == 0) vara sant. I allmänhet försöker operationer returnera något “neutralt” som resultat, som 0.0, en null-referens för objekt eller tomma strängar, när objektet inte längre finns.

  • Att kontrollera med error() avslöjar om något fungerade.

    För ovanstående fall, skulle

       int k = calc.subtract(i,j)
       if(k.error()) {
          printf("k är inte i-j!\n");
       }
    
    skriva ut k är inte i-j när fjärranropet inte fungerade. Annars är k verkligen resultatet av subtraktionsoperationen som utförs av fjärrobjektet (ingen serverkrasch). För metoder som gör saker som att ta bort en fil, kan du inte veta säkert om det verkligen skett. Naturligtvis skedde det om .error() är false. Men om .error() är true, finns det två möjligheter:

    • Filen togs bort, och servern kraschade precis efter den togs bort, men innan resultatet överfördes.

    • Servern kraschade innan den kunde ta bort filen.

  • Att använda nästlade anrop är farligt i ett program som ska vara kraschsäkert.

    Att använda något som liknar

       window.titlebar().setTitle("foo");
    
    är ingen bra Idé. Antag att du vet att fönstret innehåller en giltig fönsterreferens. Antag att du vet att window.titlebar() returnerar en referens till namnlisten eftersom fönsterobjektet är riktigt implementerat. Men satsen ovan är ändå inte säker.

    Vad kan hända om servern som innehåller fönsterobjektet har kraschat. Då, oberoende av hur bra implementeringen av Window är, så kommer du att få en null-referens som resultat av operationen window.titlebar(). Och sedan kommer förstås anropet till setTitle med den här null-referensen också leda till en krasch.

    Så en säker variant av detta skulle vara

       Titlebar titlebar = window.titlebar();
       if(!window.error())
          titlebar.setTitle("foo");
    
    och lägg till den riktiga felhanteringen om du vill. Om du inte litar på implementeringen av Window, kan du lika väl använda
       Titlebar titlebar = window.titlebar();
       if(!titlebar.isNull())
          titlebar.setTitle("foo");
    
    som båda är säkra.

Det finns andra felorsaker, som nerkoppling av nätverket (antag att du tar bort kabeln mellan din server och klient medan ditt program kör). Deras effekt är ändå likadan som en serverkrasch.

Totalt sett är det förstås en policyfråga hur strikt du försöker hantera kommunikationsfel i hela ditt program. Du kan följa metoden “om servern kraschar, måste vi avlusa den till den aldrig kraschar igen”, som skulle betyda att du inte behöver bry dig om alla de här problemen.

Interna funktioner: distribuerad referensräkning

Ett objekt måste ägas av någon för att finnas till. Om det inte gör det, kommer det upphöra att finnas till (mer eller mindre) omedelbart. Internt anges en ägare genom att anropa _copy(), som räknar upp en referensräknare, och en ägare tas bort genom att anropa _release(). Så fort referensräknaren når noll, så tas objektet bort.

Som en variation på temat, anges fjärranvändning med _useRemote(), och löses upp med _releaseRemote(). Dessa funktioner har en lista över vilken server som har anropat dem (och därför äger objektet). Det här används om servern kopplar ner (dvs. krasch, nätverksfel), för att ta bort referenser som fortfarande finns till objektet. Det här görs i _disconnectRemote().

Nu finns det ett problem. Betrakta ett returvärde. I vanliga fall ägs inte returvärdesobjektet av funktionen som anropas längre. Det ägs inte heller av den som anropar, förrän meddelandet som innehåller objektet har tagits emot. Så det finns en tid med objekt som “saknar ägare”.

Nu när vi skickar ett objekt kan man vara rimligt säker på att så fort det tas emot, ägs det av någon igen, om inte, återigen, mottagaren kraschar. Det här betyder i alla fall att speciell hänsyn måste tas för objekt åtminstone vid sändning, och troligen också vid mottagning, så att de inte tas bort meddetsamma.

Sättet som MCOP gör det här är genom att “tagga” objekt som håller på att kopieras över nätverket. Innan en sådan kopiering börjar, anropas _copyRemote. Det här förhindrar att objektet tas bort på ett tag (5 sekunder). Så fort mottagaren anropar _useRemote(), tas taggen bort igen. Så alla objekt som skickas över nätverket, taggas innan överföringen.

Om mottagaren tar emot ett objekt som finns på samma server, så används förstås inte _useRemote(). I det här specialfallet, finns funktionen _cancelCopyRemote() för att ta bort taggen manuellt. Förutom detta, finns det också en tidsbaserad borttagning av taggen, om taggning gjordes, men mottagaren verkligen inte fick objektet (på grund av krasch, nätverksfel). Det här görs med klassen ReferenceClean.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Grafiska gränssnittselement
Grafiska gränssnittselement

Grafiska gränssnittselement

Grafiska gränssnittselement är för närvarande på det experimentella stadiet. Det här avsnittet beskriver vad som är meningen ska hända med dem, så om du är en utvecklare, kan du förstå hur aRts kommer att hantera grafiska gränssnitt i framtiden. Det finns också redan en del kod på plats.

Grafiska gränssnittselement ska användas för att låta syntesstrukturer växelverka med användaren. I det enklaste fallet ska användaren kunna ändra några parametrar för en struktur direkt (som en förstärkningsfaktor som används innan den slutliga uppspelningsmodulen).

För mer komplexa fall, kan man tänka sig att användaren ändrar parametrar för grupper av strukturer och/eller strukturer som inte kör än, som att ändra ADSR enveloppen för det aktiva MIDI-instrumentet. Något annat skulle kunna vara att ange filnamnet för ett samplingsbaserat instrument.

Å andra sidan, skulle användaren kunna vilja övervaka vad synthezisern gör. Det skulle kunna finnas oscilloskop, spektrumanalysatorer volymmätare och “experiment” som till exempel räknar ut frekvensöverföringskurvan för en given filtermodul.

Till sist, ska grafiska gränssnittselement kunna kontrollera hela strukturen av allt som kör inne i aRts, och på vilket sätt. Användaren ska kunna tilldela instrument till midi-kanaler, starta nya effektbehandlingssteg, anpassa sin huvudmixerpanel (som själv är byggd av aRts-strukturer) för att få ytterligare en kanal eller använda en annan strategi för tonkontroll.

Som du ser, ska grafiska gränssnittselement ge alla möjligheterna i en virtuell studio som aRts simulerar åt användaren. Naturligtvis ska de också växelverka med midi-ingångar (som skjutreglage som också flyttas om de får MIDI-indata som ändrar motsvarande parameter), och troligen till och med skapa händelser själva, för att växelverkan med användaren ska kunna spelas in via en sequencer.

Tekniskt sett är Idén att ha en IDL-basklass för alla grafiska komponenter (Arts::Widget), och härleda ett antal vanliga komponenter från den (som Arts::Poti, Arts::Panel, Arts::Window, ...).

Därefter kan man implementera de här grafiska komponenterna med en verktygslåda, till exempel Qt™ eller Gtk. Till slut, bör effekter bygga sina grafiska gränssnitt från existerande komponenter. En efterklangseffekt skulle till exempel kunna bygga sitt grafiska gränssnitt från fem Arts::Poti-mojänger och ett Arts::Window. Så OM det finns en Qt™ implementering för de här grundkomponenterna, kan effekten visas med Qt™. Om det finns en Gtk implementering, fungerar det också med Gtk (och ser mer eller mindre likadant ut).

Till sist, eftersom vi använder IDL här, kan aRts-byggaren (eller andra verktyg) sätta ihop grafiska gränssnitt visuellt, eller automatgenerera grafiska gränssnitt, med tips för parametervärden, enbart baserat på gränssnitten. Det borde vara ganska rättframt att skriva en klass för att “skapa grafiskt gränssnitt från en beskrivning”, som tar en beskrivning av ett grafiskt gränssnitt (som innehåller de olika parametrarna och grafiska komponenterna), och skapar ett levande objekt för ett grafiskt gränssnitt från den.

Baserat på IDL och aRts/MCOP-komponentmodellen, bör det vara lätt att utöka de möjliga objekten som kan användas för det grafiska gränssnittet precis lika lätt som det är att lägga till en insticksmodul till aRts som till exempel implementerar ett nytt filter.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 5. MIDI
MIDI
Föregående
Nästa

Kapitel 5. MIDI

Översikt

MIDI-stödet i aRts kan göra ett antal olika saker. För det första, tillåter det kommunikation mellan olika delar av programvaran som producerar eller konsumerar MIDI-händelser. Om du till exempel har en sequencer och en samplingsenhet som båda använder aRts, kan aRts skicka MIDI-händelser från sequencern till samplingsenheten.

För det andra, kan aRts också hjälpa program att växelverka med hårdvaran. Om en programvarudel (till exempel samplingen) fungerar tillsammans med aRts, kan den dessutom ta emot MIDI-händelser från ett externt MIDI-keyboard.

Till slut, så utgör aRts en utmärkt modulär synthesizer. Den är konstruerat att göra just detta. Man kan alltså bygga instrument av små moduler med aRts-byggaren, och sedan använda instrumenten för att komponera eller spela musik. Syntes betyder inte nödvändigtvis bara ren syntes, utan det finns moduler som kan användas för att spela upp samplingar. På så sätt kan aRts vara både en samplingsenhet eller synt, och eftersom den är fullständigt modulär, är den mycket lätt att utöka, mycket lätt att experimentera med, kraftfull och flexibel.

MIDI-hanteraren
MIDI-hanteraren

MIDI-hanteraren

Den centrala komponenten i aRts som håller reda på vilka program som är anslutna och hur midi-händelser ska skickas mellan dem är midi-hanteraren. För att se eller påverka vad den gör, starta artscontrol. Välj sedan Visa+Visa midihanterare i menyn.

Till vänster ser man Midi-inmatning. Där listas alla objekt som skapar MIDI-händelser, som en extern MIDI-port som skickar data från ett anslutet MIDI-keyboard, en sequencer som spelar en sång och så vidare. Till höger ser man Midi-utmatning. Där listas allting som konsumerar MIDI-händelser, som en simulerad samplingsenhet (programvara), eller den externa MIDI-porten som en hårdvarusamplingsenhet är ansluten till utanför din dator. Nya program, som en sequencer eller liknande, registrerar sig själva, så att listan ändras med tiden.

Du kan ansluta ingångar och utgångar om du markerar en ingång i listan till vänster och en utgång till höger, och väljer Anslut med knappen nedanför. Koppla från fungerar på samma sätt. Du ser vad som är anslutet som små linjer mellan ingångar och utgångar, mitt i fönstret. Observera att du kan ansluta en ingång till mer än en utgång (och tvärtom).

Program (som sequencern Brahms) läggs till av sig själv när de startas och tas bort från listan när de avslutas. Men du kan också lägga till nya enheter med menyn Lägg till.

System midi port (OSS)

Det här skapar ett nytt aRts-objekt som kommunicerar med en extern midi-port.

Eftersom externa midi-portar både kan skicka och ta emot data, så läggs både en ingång och utgång till med det här valet. Med Linux®, ska du antingen ha en OSS-drivrutin (eller OSS/Free, som följer med Linux®-kärnan) eller en ALSA-drivrutin installerad för ditt ljudkort, för att det här ska fungera. Du blir tillfrågad om enhetens namn. Det här är oftast /dev/midi eller /dev/midi00.

Om du har mer än en MIDI-enhet eller en MIDI-återkopplingsenhet installerad, kan det dock finnas fler alternativ. För att visa information om midi-portar, starta inställningscentralen, och välj Information+Ljud.

aRts syntes midi utmatning

Det här lägger till en ny MIDI-utgång med ett aRts syntinstrument. Om du väljer menyalternativet, dyker en dialogruta upp som låter dig ange ett instrument. Du kan skapa nya instrument med aRts-byggaren. Alla .arts-filer med ett namn som börjar med instrument_ visas här.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Att använda aRts & Brahms
Att använda aRts & Brahms

Att använda aRts & Brahms

I själva verket är det riktigt lätt att komma igång. Du behöver en version av Brahms som fungerar med KDE 2.1, som finns i kmusic CVS-modulen. Det finns också information om hur man skaffar BrahmsaRts hemsida i avsnittet om nerladdning.

När du har startat programmet, syns det i MIDI-hanteraren. Om du vill använda syntes, lägg helt enkelt till ett MIDI-instrument med Lägg till+aRts syntes midi utmatning.

Välj ett instrument (till exempel organ2). Anslut instrumentet med knappen Anslut. Därefter kan du börja komponera i Brahms, och resultatet syntetiseras med aRts.

Det är oftast en god ide att ha artscontrol-fönstret öppet, och se till att volymen inte är för hög (ljudkvaliteten blir sämre när staplarna når den övre gränsen). Nu kan du börja skriva en ny aRts demo, och när du är klar kan du få den publicerad på aRts-project.org ;-).



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

midisend
midisend

midisend

midisend är ett litet program som låter dig skicka MIDI-händelser från skalet. Det registreras som en klient precis som alla andra program. Det enklaste sättet att använda det är att skriva

% midisend -f /dev/midi00 
som gör ungefär samma sak som att lägga till en MIDI-port i artscontrol. (Inte riktigt, därför att midisend skickar bara händelser). Skillnaden är att det är till exempel lätt att starta midisend på olika datorer (och på det sättet använda nätverkstransparens).

Det är också möjligt att låta midisend skicka data från stdin, vilket du kan använda för att skicka data från program som inte stöder aRts, så här:

% program_som_skickar_MIDI_händelser_på_standardutmatning | midisend -f -



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Att skapa instrument
Att skapa instrument

Att skapa instrument

Sättet som aRts utför midi-syntes är följande: Det finns strukturer som har ett antal ingångar, där de hämtar frekvensen, anslagsstyrkan (volymen) och en parameter som anger om tangenten fortfarande är nertryckt. Strukturen ska nu syntetisera exakt den tonen med den volymen, och reagera på parametern pressed (där pressed = 1 betyder att användaren håller nere tangenten och pressed = 0 betyder att användaren har släppt tangenten).

När MIDI-händelser anländer, skapar aRts nya strukturer för tonerna efter behov, anger parametrarna, och rensar bort dem när de är klara.

För att skapa och använda en sådan struktur, ska du göra följande:

  • För att komma igång är det bekvämaste sättet att öppna template_Instrument.arts i Arts-byggaren.

    Det här kan åstadkommas genom att använda Arkiv->Öppna exempel... och välja template_Instrument i fildialogrutan. Det här skapar en tom struktur med de nödvändiga parametrarna, som du bara behöver “fylla i”.

  • För att hantera parametern "pressed", är det praktiskt att använda Synth_ENVELOPE_ADSR, eller om en wav-fil med trumma spelas, spela bara upp den ändå och ignorera parametern.

  • Strukturen ska indikera när den inte behövs längre med utgången “done”. Om done är 1, antar aRts att strukturen kan tas bort. Praktiskt nog så tillhandahåller ADSR-enveloppen en parameter som anger när den är färdig, så du behöver bara ansluta den till done-utgången för strukturen.

  • Du bör döpa om din struktur till något namn som börjar med instrument_, som instrument_piano.arts - du bör spara filen med samma namn i katalogen $HOME/arts/structures (där aRts-byggaren normalt sparar filer).

  • Till sist, när du väl har sparat den, kan du använda den med artscontrol i MIDI-hanteraren.

  • Och din struktur ska förstås spela ljuddata som den skapar via vänster och höger utgång för strukturen, som sedan spelas med ljudhanteraren (du kan se det här i artscontrol), så att du till slut kan höra ljudet (eller efterbehandla det med ljudeffekter).

Ett bra sätt att lära sig hur man skapar instrument är att öppna ett befintligt instrument med Arkiv+Öppna Exempel och se hur det fungerar ;)



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Instrumentkartor
Instrumentkartor

Instrumentkartor

Instrumentkartor är instrument som beter sig olika beroende på tonhöjden, programmet, kanalen eller anslagsstyrkan. Man kan till exempel skapa ett piano med fem oktaver, och använda en sampling för varje oktav (med tonhöjden förskjuten i motsvarande mån). Det här låter mycket bättre än att bara använda en sampling.

Man kan också bygga en trumkarta, som spelar en särskild trumsampling för varje tangent.

Till sist är det mycket användbart om man kombinerar helt olika ljud i en instrumentkarta för olika program. På det här sättet kan man använda sin sequencer, externa keyboard eller en annan MIDI-källa för att byta mellan ljud utan att behöva manipulera aRts under arbetets gång.

Ett bra exempel på det här är arts_all, som helt enkelt kombinerar alla instrument som levereras med aRts i en karta. På så sätt behöver man bara ange att detta “instrument” ska användas en gång i artscontrol, och sedan kan man komponera en hel sång i en sequencer utan att överhuvudtaget bry sig om aRts. Behövs ett annat ljud? Ändra helt enkelt programmet i sequencern, och aRts tillhandahåller ett nytt ljud.

Att skapa sådana kartor är ganska rättframt. Man behöver bara skapa en textfil, och skriva regler som ser ut så här:

ON [ villkor ...] DO structure=någon_struktur.arts

Villkoren kan vara ett eller flera av följande:

pitch

Tonhöjden som spelas. Man använder det här om man vill dela instrumentet beroende på tonhöjd. I vårt ursprungliga exempel, skulle ett piano som använder olika samplingar för olika oktaver använda det här som villkor. Man kan ange en enkel tonhöjd, som pitch=62 eller ett intervall av tonhöjder, som pitch=60-72. De möjliga tonhöjderna går mellan 0 och 127.

program

Programmet som är aktivt på kanalen som tonen spelas upp i. Oftast låter sequencern dig välja “instrument” via programinställningen. Enkla program eller intervall är tillåtna, dvs. program=3 eller program=3-6. Möjliga program går mellan 0 och 127.

channel

Kanalen som tonen skickas på. Enkla kanaler eller intervall är tillåtna, dvs. channel=0 eller channel=0-8. Möjliga kanaler går mellan 0 och 15.

velocity

Anslagsstyrkan (volymen) som tonen har. Enkla anslagsstyrkor (vem skulle använda det?) eller intervall är tillåtna, dvs. velocity=127 eller velocity=64-127. Möjliga anslagsstyrkor går mellan 0 och 127.

Ett fullständigt exempel för en karta kan vara (det här kommer från den nuvarande instrument_arts_all.arts-map):

ON program=0 DO structure=instrument_tri.arts
ON program=1 DO structure=instrument_organ2.arts
ON program=2 DO structure=instrument_slide1.arts
ON program=3 DO structure=instrument_square.arts
ON program=4 DO structure=instrument_neworgan.arts
ON program=5 DO structure=instrument_nokind.arts
ON program=6 DO structure=instrument_full_square.arts
ON program=7 DO structure=instrument_simple_sin.arts
ON program=8 DO structure=instrument_simple_square.arts
ON program=9 DO structure=instrument_simple_tri.arts
ON program=10 DO structure=instrument_slide.arts
ON program=11 pitch=60 DO structure=instrument_deepdrum.arts
ON program=11 pitch=61 DO structure=instrument_chirpdrum.arts

Som du ser, väljs strukturen beroende på programmet. För program 11, syns en “trumkarta” (med två poster), som spelar en “deepdrum” med C-5 (tonhöjd = 60), och en “chirpdrum” med C#5 (tonhöjd = 61).

För att kartfiler automatiskt ska synas i artscontrol som ett alternativ bland instrumenten, måste de heta instrument_någonting.arts-map och antingen finnas i din hemkatalog i $HOME/arts/structures, eller i KDE-katalogen i $KDEDIR/share/apps/artsbuilder/examples. Strukturer som används av kartan kan antingen anges med en absolut sökväg, eller relativt till katalogen som kartfilen finns i.

Att utöka arts_all map eller till och med göra en fullständigt generell MIDI-karta för aRts är en bra idé för att göra aRts lättare att använda direkt som det är. Fundera gärna på att bidra med intressanta instrument som du skapar, så att de kan inkluderas i framtida versioner av aRts.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 6. MCOP: objektmodell och strömmar
MCOP: objektmodell och strömmar
Föregående
Nästa

Kapitel 6. MCOP: objektmodell och strömmar

Översikt

MCOP är standarden som aRts använder för:

  • Kommunikation mellan objekt.

  • Nätverkstransparens.

  • Beskriva objektgränssnitt.

  • Språkoberoende.

En viktig del av MCOP är gränssnittsbeskrivningsspråket, IDL, som används för att definiera många av aRts programmeringsgränssnitt och andra gränssnitt på ett språkoberoende sätt.

För att använda ett IDL-gränssnitt från C++, kompileras det med IDL kompilatorn till C++ kod. När du implementerar ett gränssnitt, härleder du från stomklassen som IDL kompilatorn har skapat. När man använder ett gränssnitt gör man det med ett omgärdande skal. På det här sättet kan MCOP använda ett protokoll om objektet du pratar med inte är lokalt - man får nätverkstransparens.

Det här kapitlet är ämnat att beskriva de grundläggande funktionerna i objektmodellen som är resultatet av att använda MCOP, protokollet, hur MCOP används med C++ (språkbindning), och så vidare.

Gränssnitt och IDL
Gränssnitt och IDL

Gränssnitt och IDL

Mycket av den service som tillhandahålls av aRts, som modulerna och ljudservern definieras i form av gränssnitt. Gränssnitt specificeras i ett programspråksoberoende format: IDL.

Det här tillåter att många av implementeringsdetaljerna som formatet på multimediadataflöden, nätverkstransparens och programspråksoberoende döljs för specifikationen av gränssnittet. Ett verktyg, mcopidl, översätter gränssnittsdefinitionen till ett specifikt programspråk (för närvarande stöds enbart C++).

Verktyget skapar en stomklass med all standardkod och grundläggande funktionalitet. Man härleder från den här klassen för att implementera de funktioner man vill ha.

Det IDL som används av aRts liknar det som används av CORBA och DCOM.

IDL-filer kan innehålla:

  • C-stil #include-direktiv för andra IDL-filer.

  • Definitioner av uppräkningstyper och struct-typer, som i C/C++.

  • Definitioner av gränssnitt.

I IDL definieras gränssnitt på ett sätt som påminner mycket om en C++ klass eller C-struct, dock med vissa begränsningar. Som i C++, så kan gränssnitt vara underklasser till andra gränssnitt med arv. Gränssnittsdefinitioner kan innehålla tre saker: Strömmar, egenskaper och metoder.

Strömmar

Strömmar definierar multimediadata, en av de viktigaste komponenterna i en modul. Strömmar definieras med följande format:

[ async ] in|out [ multi ] typ stream namn [ , namn ] ;

Strömmar har en definierad riktning i förhållande till modulen, som anges av de nödvändiga bestämningarna in eller out. Typargumentet definierar datatypen, som kan vara vilken som helst av typerna för egenskaper som beskrivs senare (alla stöds inte än). Många moduler använder strömtypen audio, som är ett alias för float eftersom det är det interna dataformatet för ljudströmmar. Flera strömmar av samma typ kan ingå i samma definition med namn separerade med kommatecken.

Strömmar är normalt synkrona, vilket betyder att de är kontinuerliga dataflöden med en konstant hastighet, som PCM-ljud. Bestämningen async anger en asynkron ström, som används för icke-kontinuerliga dataflöden. Det vanligaste exemplet på en asynkron ström är MIDI-meddelanden.

Nyckelordet multi, som bara är giltigt för indataströmmar, anger att gränssnittet stöder ett variabelt antal ingångar. Det här är användbart för att implementera enheter som en mixer som kan ta emot vilket antal indataströmmar som helst.

Egenskaper

Egenskaper är data som hör ihop med en instans av ett gränssnitt. De deklareras som medlemsvariabler i C++, och kan använda vilken som helst av de primitiva typerna boolean, byte, long, string, eller float. Du kan också använda egendefinierade struct- eller uppräkningstyper samt sekvenser av variabel storlek med syntaxen sekvens<typ>. Egenskaper kan valfritt markeras som skrivskyddade.

Metoder

Som i C++, kan metoder definieras i gränssnitt. Metodparametrarna är begränsade till samma typer som egenskaperna. Nyckelordet oneway anger en metod som returnerar omedelbart och körs asynkront.

Standardgränssnitt

Flera gränssnitt för standardmoduler är redan definierade åt dig i aRts, som StereoEffect, och SimpleSoundServer.

Exempel

Ett enkelt exempel på en modul taget från aRts är modulen med konstant fördröjning, som finns i filen kdemultimedia/arts/modules/artsmodules.idl. Gränssnittsdefinitionen anges nedan:

interface Synth_CDELAY : SynthModule {
        attribute float time;
        in audio stream invalue;
        out audio stream outvalue;
};

Modulen ärver SynthModule. Det gränssnittet, som finns i artsflow.idl, definierar alla standardmetoder som implementeras i alla syntesmoduler.

CDELAY-effekten fördröjer ett stereoljudflöde med tidsvärdet som anges som en flyttalsparameter. Gränssnittsdefinitionen har ett attribut av typen float för att lagra fördröjningsvärdet. Det definierar två indata- och två utdataströmmar (typiskt för stereoeffekter). Inga metoder krävs förutom de ärvda.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Mer om strömmar
Mer om strömmar

Mer om strömmar

Det här avsnittet täcker en del ytterligare ämnesområden som hör ihop med strömmar.

Strömtyper

Det finns olika krav för hur en modul kan hantera flöden. För att illustrera detta, betrakta följande exempel:

  • Skala en signal med en faktor två.

  • Utför frekvenskonvertering av samplingar.

  • Packa upp en runlength-kodad signal.

  • Läs MIDI-händelser från /dev/midi00 och infoga dem i en ström.

Det första fallet är det enklaste: när modulen tar emot 200 indatasamplingar producerar den 200 utdatasamplingar. Den producerar bara utdata när den får indata.

Det andra fallet producerar olika antal utdatasamplingar när den får 200 indatasamplingar. Det beror på vilken konvertering som utförs, men antalet är känt i förväg.

Det tredje fallet är ännu värre. Från utdata kan man inte ens gissa hur mycket data som skapas av 200 indatabyte (förmodligen mycket mer än 200 byte, men...).

Det sista fallet är en modul som aktiveras av sig själv, och ibland skapar data.

I aRtss-0.3.4, hanterades bara strömmar av den första typen, och de flesta saker fungerade bra. Det här är troligen vad du behöver mest när du skriver moduler som behandlar ljud. Problemen med de andra, mer komplexa sorternas flöden, är att de är svåra att programmera, och att man inte behöver funktionerna för det mesta. Det här är orsaken vi gör detta med två olika sorters strömtyper: synkrona och asynkrona.

Synkrona strömmar har följande egenskaper:

  • Moduler måste kunna beräkna data av vilken längd som helst, med tillräckligt mycket indata.

  • Alla strömmar har samma samplingsfrekvens.

  • Funktionen calculateBlock() anropas när tillräckligt med data är tillgängligt, och modulen kan lita på att pekarna anger data.

  • Det finns ingen allokering eller avallokering att göra.

Asynkrona strömmar, å andra sidan, beter sig så här:

  • Moduler kan producera data ibland, eller med olika samplingsfrekvens, eller bara om de får indata från någon fil. De måste inte följa regeln “måste kunna hantera begäran av vilken storlek som helst”.

  • Asynkrona strömmar för en modul kan ha helt skilda samplingsfrekvenser.

  • Utgående strömmar: det finns särskilda funktioner för att allokera paket, att skicka paket och en valfri mekanism för att fråga efter data som talar om när mer data ska skapas.

  • Inkommande strömmar: ett anrop skickas när ett nytt paket tas emot. Man måste tala om när man är färdig med att behandla all data i det paketet, och detta får inte ske omedelbart (man kan tala om det när som helst senare, och om alla har behandlat ett paket, kommer det att frigöras/återanvändas).

När strömmar deklareras, används nyckelordet “async” för att ange att strömmen ska vara asynkron. Så anta till exempel att du vill konvertera en asynkron ström av byte till en synkron ström av samplingar. Gränssnittet skulle då kunna se ut så här:

interface ByteStreamToAudio : SynthModule {
    async in byte stream indata;   // den asynkrona indatasamplingen

    out audio stream left,right;   // de synkrona utdatasamplingarna
};

Att använda asynkrona strömmar

Antag att du har bestämt dig för att skriva en modul som skapar asynkront ljud. Dess gränssnitt kan se ut så här:

interface SomeModule : SynthModule
{
    async out byte stream outdata;
};

Hur skickar man data? Den första metoden kallas “tryckleverans”. Med asynkrona strömmar skickar man data som paket. Det betyder att individuella paket skickas som i exemplet ovan. Den verkliga processen är: allokera ett paket, fyll det, skicka det.

Här följer det i form av kod. Först allokerar vi ett paket:

DataPacket<mcopbyte> *packet = outdata.allocPacket(100);

Vi fyller det:

// typkonvertera så att fgets får en (char *) pekare
char *data = (char *)packet->contents;

// som du ser, kan du krympa paketstorleken efter allokeringen
// om du vill
if(fgets(data,100,stdin))
    packet->size = strlen(data);
else
    packet->size = 0;

Nu skickar vi det:

packet->send();

Det här är mycket enkelt, men om vi vill skicka paket precis så snabbt som mottagaren kan hantera dem, behövs ett annat sätt, metoden med “dragleverans”. Man begär att skicka paket så snabbt som mottagaren är klar att behandla dem. Man börjar med en viss mängd paket som skickas. Medan mottagaren behandlar paket efter paket, börjar man fylla i dem med färsk data, och skickar dem igen.

Du startar det genom att anropa setPull. Till exempel:

outdata.setPull(8, 1024);

Det här betyder att du vill skicka paket via outdata. Du vill börja med att skicka 8 paket på en gång, och när mottagaren behandlar några av dem, vill du fylla dem igen.

Därefter behöver du implementera en metod som fyller paketen, som skulle kunna se ut så här:

void request_outdata(DataPacket<mcopbyte> *packet)
{
    packet->size = 1024;  // ska inte vara mer än 1024
    for(int i = 0;i < 1024; i++)
        packet->contents[i] = (mcopbyte)'A';
    packet->send();
}

Det är allt. När du inte har mer data, kan du börja skicka paket med storleken noll, som stoppar dragleveranserna.

Observera att det är väsentligt att ge metoden exakt namnet request_strömnamn.

Vi beskrev just att skicka data. Att ta emot data är mycket enklare. Antag att du har ett enkelt filter, ToLower, som helt enkelt konverterar alla bokstäver till små:

interface ToLower {
    async in byte stream indata;
    async out byte stream utdata;
};

Det här är verkligt enkelt att implementera. Här är hela implementationen:

class ToLower_impl : public ToLower_skel {
public:
    void process_indata(DataPacket<mcopbyte> *inpacket)
    {
        DataPacket<mcopbyte> *outpacket = outdata.allocPacket(inpacket->size);

        // omvandla till små bokstäver
        char *instring = (char *)inpacket->contents;
        char *outstring = (char *)outpacket->contents;

        for(int i=0;i<inpacket->size;i++)
            outstring[i] = tolower(instring[i]);

        inpacket->processed();
        outpacket->send();
    }
};

REGISTER_IMPLEMENTATION(ToLower_impl);

Återigen är det väsentligt att ge metoden namnet process_strömnamn.

Som du kan se, så får du ett anrop till en funktion för varje paket som anländer (process_indata i vårt fall). Du måste anropa metoden processed() för ett paket för att ange att du har behandlat det.

Här är ett implementeringstips: Om det tar lång tid att behandla data (dvs. om du måste vänta på utmatning till ljudkortet eller något sådant), anropa inte processed omedelbart, utan lagra hela datapaketet och anropa processed bara när du verkligen har behandlat paketet. På detta sätt, har avsändarna en chans att veta hur lång tid det verkligen tar att utföra arbetet.

Eftersom synkronisering inte är så trevlig med asynkrona strömmar, ska man använda synkrona strömmar så ofta det är möjligt, och asynkrona bara om det är nödvändigt.

Förvalda strömmar

Antag att du har två objekt, till exempel en AudioProducer och en AudioConsumer. AudioProducer har en utdataström och AudioConsumer har en indataström. Varje gång du vill förbinda dem, använder du de här två strömmarna. Den första användningen av förval är att låta dig upprätta förbindelsen utan att ange portarna i det här fallet.

Antag nu att de två objekten ovan kan hantera stereo, och båda har en “vänster” och “höger” port. Du skulle fortfarande vilja kunna koppla ihop dem lika lätt som tidigare. Men hur kan förbindelsesystemet veta vilken utgång som ska kopplas till vilken ingång? Det har inget sätt att koppla ihop strömmarna korrekt. Förval används då för att ange flera strömmar med en viss ordning. På så sätt, om du ansluter ett objekt med två förvalda utdataströmmar till ett annat med två förvalda indataströmmar, behöver du inte ange portarna, och förbindelserna görs på ett riktigt sätt.

Det här är förstås inte begränsat till stereo. Vilket antal strömmar som helst kan göras förvalda om det behövs, och anslutningsfunktionen kontrollerar att antalet förval för två objekt passar ihop (med de angivna riktningarna) om du inte anger portarna som ska användas.

Syntaxen är den följande: I IDL kan du använda nyckelordet default i strömdeklarationen, eller på en ensam rad. Till exempel:

interface TwoToOneMixer {
    default in audio stream input1, input2;
    out audio stream output;
};

I det här exemplet kommer objektet att förvänta sig att dess två indataportar ska anslutas med förval. Ordningen är den som anges på raden, så ett objekt som det här:

interface DualNoiseGenerator {
    out audio stream bzzt, couic;
    default couic, bzzt;
};

skapar automatiskt en förbindelse från “couic” till “input1”, och “bzzt” till “input2” Observera att eftersom det bara finns en utgång för mixern, kommer den att vara förvald i det här fallet (se nedan). Syntaxen som används i brusgeneratorn är användbar för att ange en annan ordning än i deklarationen, eller för att välja bara några få portar som förval. Riktningen på portarna på den här raden slås upp av mcopidl, så ange dem inte. Du kan till och med blanda in- och utportar på en sådan här rad, bara ordningen spelar roll.

Det finns några regler som följs när arv används:

  • Om en förvalslista anges i IDL så måste den användas. En förälders portar kan också ingå i listan, vare sig de var förval i föräldern eller inte.

  • Annars ärvs förälderns förval. Ordningen är förälder1 förval1, förälder1 förval2..., förälder2 förval1... Om det finns en gemensam förfader som använder två föräldragrenar, görs en hopslagning som liknar “virtual public” vid förvalets första plats i listan.

  • Om det fortfarande inte finns något förval och en enda ström i en viss riktning, så används den som förval för den riktningen.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Ändringsmeddelanden för egenskaper
Ändringsmeddelanden för egenskaper

Ändringsmeddelanden för egenskaper

Ändringsmeddelanden för egenskaper är ett sätt att veta när en egenskap ändras. De kan i viss utsträckning jämföras med en Qt™- eller Gtk-signal eller slot. Om du till exempel har ett grafiskt element, ett skjutreglage, som ställer in ett tal mellan 0 och 100, har du oftast ett objekt som gör något med talet (det kan till exempel kontrollera volymen på någon ljudsignal). Så du skulle vilja att så fort skjutreglaget flyttas ska objektet som ställer in volymen bli underrättat. En förbindelse mellan en sändare och mottagare.

MCOP hanterar detta genom att kunna ge meddelanden när egenskaper ändras. Allt som deklareras som “attribute” i IDL kan avge sådana ändringsmeddelanden, och ska göra det, när de än ändras. Allt som deklareras som “attribute” kan också ta emot sådana ändringsmeddelanden. Så om du till exempel har två IDL-gränssnitt som de här

interface Slider {
         attribute long min,max;
         attribute long position;
 };
 interface VolumeControl : Arts::StereoEffect {
     attribute long volume; // 0..100
 };

kan du förbinda dem med ändringsmeddelanden. Det fungerar med det normala flödessystemets anslutningsoperation. I det här fallet, ser C++ koden som ansluter två objekt ut så här:

#include <connect.h>
using namespace Arts;
[...]
connect(slider,"position_changed",volumeControl,"volume");

Som du kan se, erbjuder varje egenskap två olika strömmar, en för att skicka ändringsmeddelanden, som heter egenskapsnamn_changed, och en för att ta emot ändringsmeddelanden, som heter egenskapsnamn.

Det är viktigt att veta att ändringsmeddelanden och asynkrona strömmar passar ihop. De är också nätverkstransparenta. Så du kan ansluta en flyttalsegenskaps ändringsmeddelande för en grafisk komponent till en asynkron ström för en syntesmodul som kör på en annan dator. Det här betyder förstås också att ändringsmeddelanden inte är synkrona, vilket betyder att det kan ta tid innan de verkligen tas emot efter du har skickat dem.

Att skicka ändringsmeddelanden

När du implementerar objekt som har egenskaper, måste du skicka ändringsmeddelanden så snart en egenskap ändras. Koden för att göra detta ser ut så här:

void KPoti_impl::value(float newValue)
 {
     if(newValue != _value)
     {
         _value = newValue;
         value_changed(newValue); // <- skicka ändringsmeddelande
     }
 }

Det rekommenderas varmt att använda kod som den här för alla objekt som du implementerar, så att ändringsmeddelanden kan användas av andra. Du bör dock undvika att skicka meddelanden för ofta, så om du gör signalbehandling är det troligen bäst att hålla reda på när du skickade ditt senaste meddelande, så att du inte skickar ett för varje sampling.

Tillämpningar för ändringsmeddelanden

Det kommer att vara särskilt användbart att använda ändringsmeddelanden tillsammans med mätare (objekt som till exempel visualiserar ljuddata), grafiska gränssnitt, styrelement och monitorer. Kod som använder det här finns i kdelibs/arts/tests, och i den experimentella artsgui-implementeringen, som du hittar i kdemultimedia/arts/gui.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Filen .mcoprc
Filen .mcoprc

Filen .mcoprc

Filen .mcoprc (i varje användares hemkatalog) kan användas för att anpassa MCOP i viss mån. För närvarande är följande möjligt:

GlobalComm

Namnet på ett gränssnitt som ska användas för global kommunikation. Global kommunikation används för att hitta andra objekt och hämta den hemliga kakan. Alla MCOP klienter/servrar som ska kunna kommunicera med varandra måste ha ett GlobalComm-objekt för att kunna dela information. För närvarande är de möjliga värdena “Arts::TmpGlobalComm” för att kommunicera via katalogen /tmp/mcop-användarnamn (som bara fungerar på den lokala datorn) och “Arts::X11GlobalComm” för att kommunicera via rotfönsteregenskaperna på X11-servern.

TraderPath

Anger var handlarinformation ska hittas. Du kan ange mer än en katalog här, och separera dem med kommatecken.

ExtensionPath

Anger från vilka kataloger utökningar (i form av delade bibliotek) laddas. Flera värden kan separeras med kommatecken.

Ett exempel som använder allt det ovanstående är:

# $HOME/.mcoprc file
GlobalComm=Arts::X11GlobalComm

# om du är en utvecklare kan det vara bekvämt att lägga till en katalog i din
# hemkatalog till TraderPath/ExtensionPath sökvägarna för att kunna lägga
# till komponenter utan att installera dem
TraderPath="/opt/kde2/lib/mcop","/home/joe/mcopdevel/mcop"
ExtensionPath="/opt/kde2/lib","/home/joe/mcopdevel/lib"


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

MCOP för CORBA-användare
MCOP för CORBA-användare

MCOP för CORBA-användare

Om du har använt CORBA tidigare, kommer du att märka att MCOP är mycket likt. I själva verket så använde aRts CORBA innan version 0.4.

Den grundläggande idén med CORBA är likadan: man implementerar objekt (komponenter). Genom att använda funktionerna i MCOP är objekt inte bara tillgängliga som normala klasser från samma process (via standardmässiga C++ tekniker), utan de är också transparent tillgängliga för en fjärrserver. För att detta ska fungera, är det första du måste göra att specificera gränssnittet för dina objekt i en IDL-fil, precis som för CORBA-IDL. Det finns bara ett fåtal skillnader.

CORBA-funktioner som saknas i MCOP

I MCOP finns det inga “in” och “out” parametrar för metodanrop. Parametrar är alltid ingående, och returvärdet är alltid utgående, vilket betyder att gränssnittet:

// CORBA idl
interface Account {
  void deposit( in long amount );
  void withdraw( in long amount );
  long balance();
};

skrivs som

// MCOP idl
interface Account {
  void deposit( long amount );
  void withdraw( long amount );
  long balance();
};

i MCOP.

Det finns inget stöd för undantag. MCOP har inte undantag, det använder något annat för felhantering.

Det finns inga union-typer och inga typdefinitioner. Jag vet inte om det är en verklig svaghet, något man desperat behöver för att överleva.

Det finns inget stöd för att skicka gränssnitt eller objektreferenser

CORBA-funktioner som är annorlunda i MCOP

Du deklarerar sekvenser som “sequencetyp” i MCOP. Det finns inget behov av en typdefinition. Till exempel, istället för:

// CORBA idl
struct Line {
    long x1,y1,x2,y2;
};
typedef sequence<Line> LineSeq;
interface Plotter {
    void draw(in LineSeq lines);
};

skulle du skriva

// MCOP idl
struct Line {
    long x1,y1,x2,y2;
};
interface Plotter {
    void draw(sequence<Line> lines);
};

MCOP-funktioner som inte finns i CORBA

Du kan deklarera strömmar, som sedan behandlas av aRts grundstomme. Strömmar deklareras på ett sätt som liknar egenskaper. Till exempel:

// MCOP idl
interface Synth_ADD : SynthModule {
    in audio stream signal1,signal2;
    out audio stream outvalue;
};

Det här betyder att ditt objekt kommer att acceptera två inkommande synkrona ljudströmmar som kallas signal1 och signal2. Synkron betyder att de är strömmar som levererar x samplingar per sekund (eller annan tid), så att schemaläggaren alltid garanterar att du får en balanserad mängd indata (t.ex. 200 samplingar av signal1 finns och 200 samplingar av signal2 finns). Du garanterar att om ditt objekt anropas med de här 200 samplingarna av signal1 + signal2, så kan det skapa precis 200 samplingar utdata.

MCOP-bindningen till C++ språket

Det här skiljer sig från CORBA i huvudsak angående:

  • Strängar använder C++ STL-klassen string. När de lagras i sekvenser, lagras de “enkelt”, vilket betyder att de anses vara en primitiv typ. Därför behöver de kopieras.

  • long är enkla long (förväntas vara 32 bitar).

  • Sekvenser använder C++ STL-klassen vector.

  • Strukturer härleds alla från MCOP klassen Type, och skapas av MCOP IDL-kompilatorn. När de lagras i sekvenser, lagras de inte “enkelt”, utan som pekare, eftersom annars skulle för mycket kopiering uppstå.

Att implementera MCOP-objekt

Efter att ha skickat dem genom IDL-kompilatorn, måste du härleda från klassen _skel. Antag till exempel att du har definierat gränssnittet så här:

// MCOP idl: hello.idl
interface Hello {
    void hello(string s);
    string concat(string s1, string s2);
    long sum2(long a, long b);
};

Du skickar det genom IDL-kompilatorn genom att anropa mcopidl hello.idl, som i sin tur skapar hello.cc och hello.h. För att implementera det, behöver du en C++ klass som ärver stommen:

// C++ deklarationsfil - infoga hello.h någonstans
class Hello_impl : virtual public Hello_skel {
public:
    void hello(const string& s);
    string concat(const string& s1, const string& s2);
    long sum2(long a, long b);
};

Till sist måste du implementera metoderna som vanlig C++.

// C++ implementeringsfil

// som du ser skickas strängar som konstanta strängreferenser
void Hello_impl::hello(const string& s)
{
    printf("Hello '%s'!\n",s.c_str());
}

// när de är ett returvärde skickas de som "normala" strängar
string Hello_impl::concat(const string& s1, const string& s2)
{
    return s1+s2;
}

long Hello_impl::sum2(long a, long b)
{
    return a+b;
}

När du väl har gjort detta, har du ett objekt som kan kommunicera med MCOP. Skapa bara ett (med de normala C++ faciliteterna för att skapa ett objekt):

Hello_impl server;

Och så fort du ger någon referensen

string reference = server._toString();
    printf("%s\n",reference.c_str());

och går till MCOP:s väntesnurra

Dispatcher::the()->run();

kan alla komma åt objektet med

// den här koden kan köra var som helst - inte nödvändigtvis i samma process
// (den kan också köra på en annan dator/arkitektur)

    Hello *h = Hello::_fromString([objektreferensen som skrevs ut ovan]);

och anropa metoder:

if(h)
        h->hello("test");
    else
        printf("Åtkomst misslyckades?\n");


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Säkerhetshänsyn för MCOP
Säkerhetshänsyn för MCOP

Säkerhetshänsyn för MCOP

Eftersom en MCOP-server lyssnar på en TCP-port, kan potentiellt sett alla (om du är ansluten till Internet) försöka att ansluta till en MCOP-service. Därför är det viktigt att identifiera klienter. MCOP använder md5-auth protokollet.

Protokollet md5-auth gör följande för att försäkra att bara utvalda (pålitliga) klienter kan ansluta till en server:

  • Det antar att du kan ge varje klient en hemlig kaka.

  • Varje gång en klient ansluter, verifierar den att den här klienten känner till den hemliga kakan, utan att verkligen skicka den (inte ens på en form som någon som lyssnar på nätverkstrafik kan ta reda på).

För att ge varje klient den hemliga kakan, lägger MCOP (normalt) den i mcop katalogen (i /tmp/mcop-USER/secret-cookie). Du kan förstås kopiera den till andra datorer. Men om du gör det, använd då en säker överföringsmekanism, som scp (från ssh).

Identifieringen av klienter använder följande steg:

  1. [SERVER] skapa en ny (slumpmässig) kaka R

  2. [SERVER] skicka den till klienten

  3. [KLIENT] läs den "hemliga kakan" S från en fil

  4. [KLIENT] behandla kakorna R och S för att skapa kakan M med MD5-algoritmen

  5. [KLIENT] skicka M till servern

  6. [SERVER] verifiera att behandling av R och S ger precis samma sak som kakan M som togs emot från klienten. Om detta stämmer har identifieringen lyckats.

Den här algoritmen bör vara säker, under förutsättning att

  1. De hemliga och slumpmässiga kakorna är “slumpmässiga nog” och

  2. MD5-algoritmen inte tillåter att “originaltexten” kan avgöras, det vill säga den hemliga kakan S och den slumpmässiga kakan R (som är känd ändå), från den behandlade kakan M.

MCOP-protokollet startar varje ny förbindelse med en identifieringsprocess. Översiktligt ser den ut så här:

  1. Servern skickar meddelandet ServerHello, som beskriver de kända indentifieringsprotokollen.

  2. Klienten skickar meddelandet ClientHello, som innehåller identifieringsinformation.

  3. Servern skickar meddelandet AuthAccept.

För att se att säkerheten verkligen fungerar, bör vi titta på hur meddelanden behandlas för oidentifierade förbindelser:

  • Innan identifieringen lyckas, tar inte servern emot andra meddelanden från anslutningen. Istället, om servern till exempel förväntar sig meddelandet “ClientHello”, och får meddelandet mcopInvocation, så kopplar den ner förbindelsen.

  • Om klienten inte skickar ett giltigt MCOP-meddelande alls (inget magiskt värde MCOP i meddelandehuvudet) i identifieringsfasen, utan något annat, så kopplas förbindelsen ner.

  • Om klienten försöker skicka ett mycket mycket stort meddelande (> 4096 byte) under identifieringsfasen, kapas meddelandestorleken till 0 byte, vilket gör att det inte accepteras som identifiering. Det här är till för att förhindra att oidentifierade klienter skickar t.ex. ett 100 Mibyte meddelande, som skulle tas emot och kunna orsaka att servern får slut på minne.

  • Om klienten skickar ett felaktigt ClientHello meddelande (ett där avkodningen misslyckas), så kopplas förbindelsen ner.

  • Om klienten inte skickar något alls, ska en tidsgräns överskridas (ännu inte implementerat).



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

MCOP protokollspecifikation
MCOP protokollspecifikation

MCOP protokollspecifikation

Inledning

Den har begreppsmässiga likheter med CORBA, men är avsett för att kunna utökas på alla sätt som krävs för multimediaoperationer i realtid.

Den tillhandahåller en multimediaobjektmodell, som både kan användas för kommunikation mellan komponenter i ett adressrum (en process), och mellan komponenter som finns i olika trådar, processer eller på olika värddatorer.

Totalt sett, kommer den att konstrueras för extremt hög prestanda (så att allt ska optimeras för att vara våldsamt snabbt), lämpligt för mycket kommunikationsintensiva multimediaprogram. Att till exempel skicka runt video är en av tillämpningarna för MCOP, där de flesta CORBA-implementeringar skulle gå på knäna.

Gränssnittsdefinitionerna kan hantera följande själv:

  • Kontinuerliga dataflöden (som ljuddata).

  • Händelseflöden av data (som MIDI-händelser).

  • Riktig referensräkning.

och de viktigaste CORBA-knepen, som

  • Synkrona metodanrop.

  • Asynkrona metodanrop.

  • Konstruera användardefinierade datatyper.

  • Multipla arv.

  • Skicka objektreferenser.

MCOP:s meddelandekodning

Konstruktionsmål/idéer:

  • Kodning ska vara enkelt att implementera.

  • Avkodning kräver att mottagaren vet vilken typ som ska avkodas.

  • Mottagaren förväntas använda all information, så möjlighet att hoppa över data finns bara i protokollet såtillvida att:

    • Om man vet att ett block av data kommer att tas emot, behöver man inte titta på varje del efter en slutmarkör.

    • Om man vet att en sträng kommer att tas emot, behöver man inte läsa till en noll-byte för att ta reda på dess längd vid avkodning, men,

    • Om man vet att en sekvens av strängar kommer att tas emot måste man titta på längden för var och en av dem för att ta reda på slutet för sekvensen, eftersom strängar har variabel längd. Men om strängarna används för någonting nyttigt, måste det göras i alla fall, så det här är ingen förlust.

  • Så lite extra kostnad som möjligt.

Kodningen av de olika typerna visas i tabellen nedan:

TypKodningsprocessResultat
voidtypen void kodas genom att utelämna den, så ingenting skrivs till strömmen för den. 
longkodas som fyra byte, med den mest signifikanta först, så att talet 10001025 (som är 0x989a81) skulle kodas som:0x00 0x98 0x9a 0x81
uppräkningstyper

kodas som long

 
byte

kodas som en enda byte, så 0x42 skulle kodas som:

0x42
sträng

kodas som en long, som innehåller längden på den efterföljande strängen, och sedan sekvensen av tecken. Strängar måste sluta med en noll-byte (som ingår i längdberäkningen).

Viktigt

inklusive den sista 0 byten i längdräkningen!

hello” skulle kodas som:

0x00 0x00 0x00 0x06 0x68 0x65 0x6c 0x6c 0x6f 0x00
boolean

kodas som en byte, som innehåller 0 om false eller 1 om true, så att det booleska värdet true kodas som:

0x01
flyttal

kodas med fyra-byte IEEE754 representationen, detaljerad dokumentation om hur IEEE fungerar finns här: http://twister.ou.edu/workshop.docs/ common-tools/ numerical_comp_guide/ ncg_math.doc.html och här: http://java.sun.com/docs/books/ vmspec/ 2nd-edition/ html/ Overview.doc.html. Så värdet 2,15 skulle kodas som:

0x9a 0x99 0x09 0x40
struct

En struktur kodas genom att koda dess innehåll. Det krävs inga ytterligare prefix eller suffix, så att strukturen

struct test {
    string name;        // som är "hello"
    long value;         // som är 10001025  (0x989a81)
};

skulle kodas som:

0x00 0x00 0x00 0x06 0x68 0x65 0x6c 0x6c 0x6f 0x00 0x00 0x98 0x9a 0x81

sekvens

En sekvens kodas genom att lista antalet element som följer, och sedan koda elementen ett efter ett.

Så en sekvens med tre "long a", med a[0] = 0x12345678, a[1] = 0x01 och a[2] = 0x42 skulle kodas som

0x00 0x00 0x00 0x03 0x12 0x34 0x56 0x78 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x42

Om du behöver hänvisa till en typ, anges alla primitiva typer med namnen som finns ovan. Strukturer och uppräkningstyper får sina egna namn (som Header). Sekvenser benämns som *normal typ, så att en sekvens av long är “*long” och en sekvens av Header struct:ar är “*Header”.

Meddelanden

Formatet på MCOP:s meddelandehuvud definieras av den här strukturen:

struct Header {
    long magic;          // värdet 0x4d434f50, som kodas som MCOP
    long messageLength;
    long messageType;
};

De möjliga meddelandetyperna är för närvarande

mcopServerHello                = 1
 mcopClientHello                = 2
 mcopAuthAccept                        = 3
 mcopInvocation                        = 4
 mcopReturn                                = 5
 mcopOnewayInvocation   = 6

Lite information om MCOP:s meddelandehantering:

  • Varje meddelande börjar med ett huvud.

  • Vissa meddelandetyper ska ignoreras av servern, innan identifiering är färdig.

  • Efter att huvudet tagits emot, kan protokollhanteringen (anslutningen) ta emot meddelandet i sin helhet, utan att titta på innehållet.

Meddelandelängden i huvudet är förstås redundant i vissa fall, vilket gör att metoden inte alltid är minimal med avseende på antal byte.

Detta ger dock en enkel (och snabb) implementering för behandling av meddelanden som inte blockerar. Med hjälp av huvudet kan meddelanden tas emot av protokollhanteringsklasser i bakgrunden (utan blockering), om det finns många anslutningar till servern kan alla behandlas parallellt. Man behöver inte titta på meddelandets innehåll för att ta emot ett meddelande (och avgöra när man är klar), bara på huvudet, så koden för detta är ganska enkel.

När ett meddelande väl finns på plats, kan det avkodas och behandlas i ett enda steg, utan att bry sig om fall där all data kanske inte tagits emot (eftersom meddelandelängden garanterar att allt är på plats).

Anrop

För att anropa en fjärrmetod, måste man skicka följande struktur i ett MCOP-meddelande med messageType = 1 (mcopInvocation):

struct Invocation {
    long objectID;
    long methodID;
    long requestID;
};

därefter skickas parametrarna som en struktur, t.ex. om man anropar metoden "string concat(string s1, string s2)", skickas strukturen

struct InvocationBody {
    string s1;
    string s2;
};

om metoden deklarerades som envägs, vilket betyder asynkront utan returvärde, är det allt. Annars får man ett meddelande som svar med messageType = 2 (mcopReturn).

struct ReturnCode {
    long requestID;
    <resulttype> result;
};

där <resulttype> är typen för resultatet. Eftersom void-typer utelämnas vid kodning, kan man också bara ange requestID om man returnerar från en void-metod.

Så vår "string concat(string s1, string s2)" skulle ge en returkod som

struct ReturnCode {
    long   requestID;
    string result;
};

Inspektera gränssnitt

För att göra anrop, måste man känna till metoderna som ett objekt stöder. För att göra detta, är methodID 0, 1, 2 och 3 hårdkodade för vissa funktioner. Det vill säga

long _lookupMethod(MethodDef methodDef);                                // metod-id alltid 0
string _interfaceName();                                                                // metod-id alltid 1
InterfaceDef _queryInterface(string name);                                // metod-id alltid 2
TypeDef _queryType(string name);                                                // metod-id alltid 3

för att läsa detta, behövs förstås också

struct MethodDef {
        string  methodName;
        string  type;
        long    flags;        // nu satt till 0 (krävs för strömmar)
        sequence<ParamDef> signature;
};

struct ParamDef {
        string name;
        long   typeCode;
};

parameterfältet innehåller typkomponenter som anger typerna för parametrar. Typen för returkoden anges i typfältet för MethodDef.

För att vara strikt, är det bara metoderna _lookupMethod() och _interfaceName() som varierar från objekt till objekt, medan _queryInterface() och _queryType() alltid är likadana.

Vad är ett sådant här methodID? Om man gör ett MCOP-anrop, förväntas man skicka numret för metoden som anropas. Orsaken till detta är att nummer kan behandlas mycket snabbare än strängar när en MCOP-begäran körs.

Så hur skaffar man sig ett sådant här nummer? Om man känner till signaturen för metoden, dvs. en MethodDef som beskriver den (som innehåller namn, typ, parameternamn, parametertyper och liknande), så kan man skicka den till _lookupMethod för objektet där man vill anropa en metod. Eftersom _lookupMethod är hårdkodad till methodID 0, ska det inte vara några problem att göra detta.

Om man å andra sidan inte känner till metodens signatur, kan man ta reda på vilka metoder som stöds genom att använda _interfaceName, _queryInterface och _queryType.

Typdefinitioner

Användardefinierade datatyper beskrivs med strukturen TypeDef:

struct TypeComponent {
        string type;
        string name;
};

struct TypeDef {
        string name;

        sequence<TypeComponent> contents;
};


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Varför aRts inte använder DCOP
Varför aRts inte använder DCOP

Varför aRts inte använder DCOP

Eftersom KDE släppt CORBA helt och hållet, och istället använder DCOP överallt, uppstår förstås frågan varför inte aRts också gör det. Trots allt finns DCOP-stöd i KApplication, underhålls väl, förväntas integreras utmärkt med libICE, och allt möjligt annat.

Eftersom det (möjligtvis) kommer att finnas många som frågar om det verkligen är nödvändigt att ha MCOP förutom DCOP, så finns svaret här. Missförstå mig inte, jag försöker inte säga att “DCOP är dåligt”. Jag försöker bara säga “DCOP är inte rätt lösning för aRts” (medan det är en bra lösning för andra saker).

Först måste man förstå exakt vad DCOP skrevs för. Skapat på två dar under mötet KDE-TWO, var det avsett att vara så enkelt som möjligt, ett verkligt “lättviktigt” kommunikationsprotokoll. I synnerhet utelämnade implementeringen allt som kunde innebära komplexitet, till exempel ett fullständigt koncept angående hur datatyper ska kodas.

Fastän DCOP inte bryr sig om vissa saker (som hur man skickar en sträng på ett nätverkstransparent sätt), måste detta göras. Så allt som inte DCOP gör överlämnas till Qt™ i KDE-programmen som använder DCOP idag. Det här är i huvudsak typhantering (som använder Qt™:s serialiseringsoperator).

DCOP är ett minimalt protokoll som gör det helt möjlig för KDE-program att skicka enkla meddelanden som “öppna ett fönster som pekar på http://www.kde.org” eller “dina inställningar har ändrats”. Inne i aRts fokuseras dock på andra saker.

Idén är att små insticksmoduler i aRts ska kommunicera med sådana datastrukturer som “midi-händelser” och “sångpositionspekare” och “flödesgrafer”.

Detta är komplexa datatyper, som måste skickas mellan olika objekt, och hanteras som strömmar, eller parametrar. MCOP tillhandahåller ett typkoncept för att definiera komplexa datatyper från enklare (liknande struct:ar och fält i C++). DCOP bryr sig inte om typer alls, så det här problemet skulle lämnas till programmeraren, som att skriva C++ klasser för typerna, och försäkra sig om att de går att serialisera på ett riktigt sätt (till exempel stöd för Qt™:s serialiseringsoperator).

Men på det sättet skulle de inte vara tillgängliga för något annat än direkt kodning i C++. I synnerhet skulle man inte kunna skapa ett skriptspråk som skulle kunna känna till alla typer som en insticksmodul kan göra tillgängliga, eftersom de inte skulle vara självbeskrivande.

Samma argument gäller också gränssnitt i stor utsträckning. DCOP-objekt gör inte sina förhållanden, arvhierarkier, etc. tillgängliga. Om man skulle skriva en objektbläddrare som skulle visa “vilka egenskaper har det här objektet”, skulle man misslyckas.

Även om Matthias talade om för mig att man har en speciell funktion “functions” för varje objekt som informerar om vilka metoder som objektet stöder, utelämnar detta saker som egenskaper, strömmar och arvrelationer.

Det här gör att program som aRts-byggaren inte skulle fungera alls. Men kom ihåg, det var inte meningen att DCOP skulle vara en objektmodell (eftersom Qt™ redan har en med moc och liknande), inte heller vara något som CORBA, utan tillhandahålla kommunikation mellan program.

Orsaken att MCOP överhuvudtaget finns är att det måste fungera bra med strömmar mellan objekt. aRts använder många små insticksmoduler, som förbinds med strömmar. CORBA-versionen av aRts var tvungen att introducera en besvärande uppdelning mellan “SynthModule-objekt”, som var de interna arbetsmodulerna som skapade strömmar, och “CORBA-gränssnitt”, som var något externt.

Mycket kod bekymrade sig om att åstadkomma att växelverkan mellan “SynthModule-objekt” och “CORBA-gränssnittet” såg naturlig ut, men den gjorde aldrig det, eftersom CORBA inte kände till något alls om strömmar. MCOP gör det. Titta på koden (någonting i stil med simplesoundserver_impl.cc). Åtskilligt bättre! Strömmar kan deklareras i modulernas gränssnitt, och implementeras på ett sätt som ser naturligt ut.

Man kan inte förneka det. En av orsakerna att jag skrev MCOP var snabbhet. Här är några argument varför MCOP definitivt kommer att vara snabbare än DCOP (även utan att ange siffror).

Ett anrop i MCOP kommer att ha ett huvud med sex “long”. Det vill säga:

  • magiskt värde “MCOP

  • meddelandetyp (anrop)

  • storlek på begäran i byte

  • ID för begäran

  • ID för målobjektet

  • ID för målmetoden

Efter detta följer parametrarna. Observera att avkoda det här går extremt fort. Man kan använda tabelluppslagningar för att hitta avkodningsfunktionen för objektet och metoden, vilket betyder att komplexiteten är O(1) [det tar lika lång tid oberoende av hur många objekt som finns, och hur många funktioner som finns].

Om det här jämförs med DCOP, ser du att det finns åtminstone

  • en sträng för målobjektet - någonting i stil med “myCalculator

  • en sträng som liknar “addNumber(int,int)” för att ange metoden

  • ytterligare protokollinformation tillagd av libICE, och andra DCOP-specifika saker som jag inte känner till

De här är mycket svårare att avkoda, eftersom man måste tolka strängen, leta efter funktionen, etc.

Med DCOP skickas alla anrop genom en server (DCOPServer). Det betyder att hanteringen av ett synkront anrop ser ut så här:

  • Klientprocessen skickar anrop.

  • DCOPserver (mannen i mitten) tar emot anropet och ser efter vart det ska ta vägen, och skickar det till den “riktiga” servern.

  • Serverprocessen tar emot anropet, utför begäran och skickar resultatet.

  • DCOPserver (mannen i mitten) tar emot resultatet och ... skickar det till klienten.

  • Klienten avkodar svaret.

I MCOP ser samma anrop ut så här:

  • Klientprocessen skickar anrop.

  • Serverprocessen tar emot anropet, utför begäran och skickar resultatet.

  • Klienten avkodar svaret.

Antag att båda är riktigt implementerade. MCOP:s icke-hierarkiska strategi bör vara snabbare med en faktor två, än DCOP:s man i mitten-strategi. Observera dock att det förstås fanns orsaker att välja DCOP-strategin, som är att om du har 20 program som kör, och varje program pratar med varje annat program, så behöver man 20 anslutningar med DCOP, och 200 med MCOP. I fallet med multimedia är det dock inte meningen att detta ska vara ett vanligt scenario.

Jag försökte jämföra MCOP och DCOP, med att göra ett anrop som adderar två tal. Jag ändrade testdcop för att åstadkomma detta. Testen var dock kanske inte precis på DCOP-sidan. Jag anropade metoden i samma process som gjorde anropet till DCOP, och jag visste inte hur man blev av med ett avlusningsmeddelande, så jag använde omdirigering av utmatningen.

Testen använde bara ett objekt och en funktion, så resultaten för DCOP förväntas minska med fler objekt och funktioner, medan resultaten för MCOP bör förbli likadana. Dessutom var inte dcopserver-processen ansluten till andra program, och det kanske är så att om många program är anslutna så minskar överföringsprestanda.

Resultatet jag fick var att medan DCOP fick lite mer än 2000 anrop per sekund, fick MCOP något mer än 8000 anrop per sekund. Det betyder en faktor 4. Jag vet att MCOP inte är avstämd för den maximalt möjliga hastigheten än. (Som jämförelse: CORBA, med mico-implementeringen, klarar något mellan 1000 och 1500 anrop per sekund).

Om du vill ha “riktigare” data, fundera på att skriva något litet mätprogram för DCOP och skicka det till mig.

CORBA hade den trevliga funktionen att man kunde använda objekt som man implementerat, som “separat serverprocess”, eller som “bibliotek”. Man kunde använda samma kod för att göra det, och CORBA bestämde transparent vad som skulle göras. Med DCOP, är det inte riktigt meningen, och så vitt jag vet inte egentligen möjligt.

MCOP å andra sidan ska stöda detta från början. Så man kan köra en effekt inne i artsd. Men för en vågformseditor kan man välja att köra samma effekt inne i processen också.

Där DCOP i huvudsak är ett sätt att kommunicera mellan program, är MCOP också ett sätt att kommunicera inne i program. Särskilt för multimediaflöden är detta viktigt (eftersom man kan köra flera MCOP-objekt i parallell, för att lösa en multimediauppgift i ett program).

Fastän MCOP inte gör det för närvarande, är möjligheterna öppna att implementera servicekvalitetsfunktioner. Någonting i stil med att “den där MIDI-händelsen är verkligen riktigt viktig, jämfört med det här anropet”. Eller någonting som “måste vara där i tid”.

Å andra sidan kan strömöverföringar integreras i MCOP-protokollet på ett trevligt sätt, och kombineras med QoS-grejor. Under förutsättning att protokollet kan ändras, bör inte MCOP strömöverföringar verkligen bli långsammare än en konventionell TCP-ström, men de kommer att vara enklare och mer konsekventa att använda.

Det finns ingen anledning att basera mellanprogram för multimedia på Qt™. Genom att bestämma sig för det, och använda allt de där trevliga Qt™-strömmarna och andra saker, kan det lätt leda till att mellanprogram bara blir en sak för Qt™-(eller i själva verket bara KDE). Jag menar att om jag någonsin ser att GNOME också använder DCOP, eller någonting liknande, är det förstås bevisat att jag har fel.

Fastän jag vet att DCOP i grunden inte känner till de datatyper som det skickar, så att man skulle kunna använda DCOP utan Qt™, se hur det används i daglig KDE-användning: man skickar runt typer som QString, QRect, QPixmap, QCString, .... De här använder Qt™:s-serialisering. Så om någon väljer att stöda DCOP i ett GNOME-program, måste han antingen ange att han använder QString,... typer (även om han inte gör det), och emulera sättet som Qt™ använder för strömmar, eller så skulle han skicka runt andra sträng-, pixmap- och rect-typer, och på så sätt ändå inte kunna fungera ihop med KDE-program.

Nå, hur som helst var alltid aRts avsett att fungera med eller utan KDE, med eller utan Qt™, med eller utan X11, och kanske till och med med eller utan Linux® (och jag har inte ens några invändningar mot personer som anpassar det till operativsystem som inte är fria).

Min inställning är att komponenter som inte ingår i ett grafiskt gränssnitt ska skrivas oberoende av detta, för att möjliggöra att de delas mellan ett större antal utvecklare (och användare).

Jag inser att använda två IPC-protokoll kan vara obekvämt. Dessutom är båda två inte standardiserade. Av orsakerna som angivits ovan är det inte möjligt att byta till DCOP. Om det finns ett betydligt intresse av att hitta ett sätt att förena de två, så kan vi försöka. Vi skulle till och med kunna försöka få MCOP att prata IIOP, då skulle vi ha en CORBA ORB ;).

Jag pratade en del med Matthias Ettrich om framtiden med de två protokollen, och vi fann många sätt som saker kunde gå vidare. MCOP skulle till exempel kunna hantera meddelandekommunikationen i DCOP, och på så sätt föra protokollen närmare varandra.

Några möjliga lösningar skulle vara:

  • Skriva en portal mellan MCOP och DCOP (vilket bör vara möjligt, och skulle möjliggöra samkörning). Observera att det finns en experimentell prototyp, om du skulle vilja arbeta med det.

  • Integrera allt DCOP-användare förväntar sig i MCOP, och försöka bara använda MCOP - man skulle kunna lägga till en “man i mitten” möjlighet i MCOP också ;)

  • Basera DCOPMCOP istället för libICE, och långsamt börja integrera saker tätare tillsammans.

Den sämsta möjligheten är kanske inte att använda varje protokoll för allt det som det var avsett för (det finns några stora skillnader i målen med deras konstruktion), och inte försöka slå ihop dem till ett.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 7. aRts programmeringsgränssnitt
aRts programmeringsgränssnitt
Föregående
Nästa

Kapitel 7. aRts programmeringsgränssnitt

Översikt

aRts är inte enbart ett program, den tillhandahåller också ett antal olika programmeringsgränssnitt (API) för olika syften. I det här avsnittet, försöker jag beskriva "helhetsbilden", en snabb överblick av vad de här gränssnitten är tänkta att användas till, och hur de hänger samman.

Det finns en viktig distinktion som måste göras: De flesta gränssnitten är språk- och platsoberoende eftersom de är specificerade som mcopidl. Det här betyder att man egentligen kan använda den service som de tillhandahåller från vilket språk som helst, implementera dem i vilket språk som helst, och man behöver inte bry sig om ifall man pratar med lokala eller fjärrobjekt. Här är först en lista på dem:

core.idl

Grundläggande definitioner som bildar grunden i MCOP-funktionen, som själva protokollet, definitioner av objekt, handlaren, flödessystemet och så vidare.

artsflow.idl

De här innehåller flödessystemet som man använder för att ansluta ljudflöden, definitionen av Arts::SynthModule som är grunden för alla gränssnitt som har strömmar, och till slut några användbara ljudobjekt

kmedia2.idl

Här definieras Arts::PlayObject, ett objekt som kan spela upp en mediatyp. Mediaspelare som KDE:s mediaspelare noatun kommer att kunna spela upp vilka media som helst som har PlayObject. Därför är det vettigt att implementera PlayObject för olika format (som mp3, mpg video, midi, wav, ...) med det här som grund, och det finns redan många.

soundserver.idl

Här definieras ett gränssnitt för systemets ljudserver artsd. Gränssnittet benämns Arts::SoundServer, och implementerar funktioner som att ta emot strömmar från nätverket, spela samplingar, skapa andra egna aRts-objekt och så vidare. Nätverkstransparens är underförstådd eftersom MCOP används (som för allt övrigt här).

artsbuilder.idl

Den här modulen definierar grundläggande flödesfunktioner, dvs. kombinera enklare objekt till mer komplexa genom att definiera en graf som binder samman dem. Den definierar det grundläggande gränssnitten Arts::StructureDesc, Arts::ModuleDesc och Arts::PortDesc som innehåller en beskrivning av en struktur, modul och port. Det finns också ett sätt att skapa ett "levande nätverk av objekt" från de här förbindelserna och värdebeskrivningarna med användning av en fabrik.

artsmidi.idl

Den här modulen definierar grundläggande midi-funktioner, som objekt som skapar midi-händelser, vad en midi-händelse är, och Arts::MidiManager för att förbinda producenter och konsumenter av midi-händelser, och så vidare. Som alltid är nätverkstransparens underförstådd.

artsmodules.idl

Här finns diverse ytterligare filter, oscillatorer, ljudeffekter, fördröjningar och så vidare, allt som behövs för riktigt användbar signalbehandling, och för att bygga komplexa instrument och effekter från de här grundläggande byggblocken.

artsgui.idl

Det här tar hand om synliga objekt. Det definierar den grundläggande typen Arts::Widget som alla moduler med ett grafiskt gränssnitt utgår från. Det här åstadkommer oberoende av verktygslåda, och ... visuell redigering av det grafiska gränssnittet, och möjlighet att serialisera grafiska gränssnitt. Dessutom, eftersom de grafiska komponenterna har normala egenskaper, kan deras värden på ett rättframt sätt anslutas till vissa signalbehandlingsmoduler. (dvs. värdet av ett skjutreglage till klippning för ett filter). Som alltid, nätverkstransparent.

Där det är möjligt implementeras aRts själv med IDL. Å andra sidan finns det några språkspecifika programmeringsgränssnitt, som antingen använder enkel C++ eller C. Det är ofta förnuftigt att använda IDL-gränssnitt om möjligt, och de övriga gränssnitten när det är nödvändigt. Här är en lista på språkspecifika programmeringsgränssnitt:

KNotify, KAudioPlayer (ingår i libkdecore)

De här är KDE:s programmeringsgränssnitt för bekvämlighet med de enkla och väldigt vanliga fall, när man bara vill spela upp en sampling. Gränssnitten är enkel C++, Qt/KDE-optimerade, och så enkla som de kan vara.

libartsc

Enkelt C-gränssnitt för ljudservern. Mycket användbart för att anpassa gamla program.

libmcop

Här sker all magi som har med MCOP att göra. Biblioteket innehåller de grundläggande saker som behövs för att skriva ett enkelt MCOP-program, avsändaren, tidtagning, I/O-hantering, men också de interna funktioner som behövs för att själva MCOP-protokollet ska fungera.

libartsflow

Förutom implementeringen av artsflow.idl, några användbara verktyg för konvertering av samplingsfrekvens.

libqiomanager

Integration av MCOP i Qt:s händelsesnurra, när man skriver Qt-program som använder MCOP.

knotify
knotify

knotify

Ännu inte skrivet.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

kaudioplayer
kaudioplayer

kaudioplayer

Ännu inte skrivet.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

libkmid
libkmid

libkmid

Ännu inte skrivet.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

kmedia2
kmedia2

kmedia2

Ännu inte skrivet.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

ljudserver
ljudserver

ljudserver

Ännu inte skrivet.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

artsflow
artsflow

artsflow

Ännu inte skrivet.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

C API
C API

C API

Inledning

C-gränssnittet för aRts skapades för att göra det lätt att skriva och anpassa enkla C-program till aRts ljudserver. Det tillhandahåller flödesfunktioner (att skicka samplingsströmmar till artsd), antingen med eller utan blockering. För de flesta program tar man helt enkelt bort de få systemanrop som hanterar ljudenheten och byter ut dem mot lämpliga anrop till aRts.

Jag gjorde två anpassningar för att verifiera idén: mpg123 och quake. Du kan skaffa programfixarna härifrån. Bidra gärna med dina egna programfixar till underhållaren av aRts eller till programvarupaket för multimedia så att de kan integrera stöd för aRts i sin kod.

Snabbtur

Att skicka ljud till ljudservern med gränssnittet är mycket enkelt:

  1. infoga deklarationsfilen med #include <artsc.h>

  2. initiera gränssnittet med arts_init()

  3. skapa en ström med arts_play_stream()

  4. anpassa särskilda parametrar med arts_stream_set()

  5. skriva samplingsdata till strömmen med arts_write()

  6. stänga strömmen med arts_close_stream()

  7. frigöra gränssnittet med arts_free()

Här är ett exempel på ett litet program som visar det här:

#include <stdio.h>
#include <artsc.h>
int main()
{
    arts_stream_t stream;
    char buffer[8192];
    int bytes;
    int errorcode;

    errorcode = arts_init();
    if (errorcode < 0)
    {
        fprintf(stderr, "arts_init fel: %s\n", arts_error_text(errorcode));
        return 1;
    }

    stream = arts_play_stream(44100, 16, 2, "artsctest");

    while((bytes = fread(buffer, 1, 8192, stdin)) > 0)
    {
        errorcode = arts_write(stream, buffer, bytes);
        if(errorcode < 0)
        {
            fprintf(stderr, "arts_write fel: %s\n", arts_error_text(errorcode));
            return 1;
        }
    }

    arts_close_stream(stream);
    arts_free();

    return 0;
}

Att kompilera och länka: artsc-config

För att lätt kunna kompilera och länka program med aRts C-gränssnitt, finns verktyget artsc-config som känner till vilka bibliotek som man måste länka med och var deklarationsfilerna finns. Det anropas med

artsc-config --libs

för att ta reda på biblioteken och

artsc-config --cflags

för att ta reda på ytterligare C-kompilatorväljare. Exemplet ovan skulle ha kunnat kompileras med kommandoraden:

cc -o artsctest artsctest.c `artsc-config --cflags` `artsc-config --libs`

cc -o artsctest artsctest.c `artsc-config --cflags` `artsc-config --libs`

Biblioteksreferens

[ATT GÖRA: skapa dokumentation för artsc.h med kdoc]



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 8. aRts moduler
aRts moduler
Föregående
Nästa

Kapitel 8. aRts moduler

Inledning

Det här kapitlet beskriver alla standardmodulerna i aRts. En av de mest kraftfulla funktionerna i aRts är att moduler kan kopplas ihop till strukturer som implementerar nya funktioner som ljudeffekter och instrument.

Moduler delas upp i två kategorier. Syntesmoduler används för att implementera “rörmokeriet” som manipulerar multimediadataflöden för att skapa nya effekter, instrument, mixrar och program. Visuella moduler låter dig skapa ett grafiskt gränssnitt för att styra ljudstrukturer som byggs upp med syntesmodulerna.

Referens till syntesmoduler
Referens till syntesmoduler

Referens till syntesmoduler

Aritmetik + mixning

Synth_ADD


Synth_ADD

Den här adderar två signaler.

Synth_MUL


Synth_MUL

Den här multiplicerar signalen med en faktor. Du kan använda det här för att skala ner (0 < faktor < 1) eller upp (faktor > 1) signaler eller invertera signaler (faktor < 0). Observera att faktorn kan vara en signal och behöver inte vara konstant (t.ex. envelopper eller flyttalssignaler).

Synth_DIV


Synth_DIV

Den här dividerar signalen med en faktor. Du kan använda det här för att dividera en signal med en annan, eller ange invärde1 som 1, så får du inversen av invärde2 som utvärde. Försäkra dig om att invärde2 aldrig når 0, annars får du problem med division med noll.

Synth_MULTI_ADD


Synth_MULTI_ADD

Den här adderar ett godtyckligt antal signaler. Om du behöver summera vågformer som skapas av fyra olika oscillatorer, kan du till exempel ansluta alla deras utgångar till en Synth_MULTI_ADD-modul. Det här är effektivare än att använda tre Synth_ADD-moduler.

Synth_XFADE


Synth_XFADE

Den här övertonar två signaler. Om procentingången är -1, hörs bara vänstra signalen, om den är 1, hörs bara den högra. Om den är 0, hörs båda signalerna med samma volym.

Den här gör att du kan försäkra dig om att signalen stannar inom ett väldefinierat område. Om du har två signaler som är mellan -1 och 1 innan övertoningen, kommer de att vara i samma område efteråt.

Synth_AUTOPANNER

Motsatsen till övertoning. Den här tar en monosignal och delar den till en stereosignal. Den används för att automatiskt panorera insignalen mellan vänster och höger utgång. Det här gör mixningen mer levande. En standardtillämpning kan vara en gitarr- eller sololjud.

Anslut en LFO, till exempel en sinus eller sågtandsvåg till inlfo, och välj en frekvens mellan 0,1 och 5 Hz för att få en traditionell effekt eller ännu mer för specialeffekter (FX).

Bussar

Synth_BUS_UPLINK


Synth_BUS_UPLINK

En upplänk till en buss. Ange signaler till vänster och höger, och namnet på bussen som data ska skickas till på “buss” porten. Den kombinerade signalen från alla upplänkar med det här namnet hamnar på varje nerlänk på den “bussen”.

Synth_BUS_DOWNLINK


Synth_BUS_DOWNLINK

Hämtar (summan av) all data som skickas på en viss buss (med namnet du anger på “buss” porten).

Fördröjningar

Synth_DELAY



Den här fördröjer insignalen en viss tid. Tidsangivelsen måste vara mellan 0 och maxdelay för en fördröjning mellan 0 och maxdelay sekunder.

Den här sortens fördröjning kan inte användas i återmatningsstrukturer. Det här beror på att det är en varierbar fördröjning. Det går att ändra längden medan den kör, och även sätta den till noll. Men eftersom den egna utgången behövs för att beräkna nästa sampling i en återmatningsstruktur, kan en fördröjning med ett värde som kan gå ner till noll under syntes leda till en låsningssituation.

Använd CDELAY:er i sådana situationer, eller kombinera en kort konstant fördröjning (av 0,001 sekunder) med en variabel fördröjning.

Man kan också kombinera en CDELAY och en DELAY för att åstadkomma en fördröjning med variabel längd i en återkoppling. Försäkra dig bara om att du har med en CDELAY.

Synth_CDELAY


Synth_CDELAY

Den här fördröjer insignalen en viss tid. Tidsangivelsen måste vara större än 0 för en fördröjning av 0 sekunder eller mer. Fördröjningen är konstant under beräkningen, vilket betyder att den inte kan ändras.

Det här sparar beräkningstid eftersom ingen interpolation görs, och är användbart för rekursiva strukturer. Se beskrivningen ovan (Synth_DELAY).

Envelopper

Synth_ENVELOPE_ADSR


Synth_ENVELOPE_ADSR

Den här är ett klassiskt ADSR-envelopp, som betyder att du anger:

active

Om användaren håller nere tangenten just nu.

invalue

Insignalen.

attack

Tiden som ska förflyta mellan användaren trycker på tangenten och signalen når sin maximala amplitud (i sekunder).

decay

Tiden som ska förflyta mellan signalen nått sin maximala amplitud och signalen går tillbaka till någon konstant nivå (i sekunder).

sustain

Den konstanta nivån som hålls för signalen efteråt, till användaren släpper tangenten.

release

Tiden som ska förflyta efter användaren har släppt tangenten till signalen går ner till noll (i sekunder).

Du får den behandlade signalen som utvärde. När ASDR-enveloppen är klar, sätter den done till 1. Du kan använda det här för att tillhandahålla utgången “done” för ett instrument (som gör att instrumentstrukturen tas bort av MIDI-reläobjektet när ljudet väl har upphört).

Synth_PSCALE


Synth_PSCALE

Modulen Synth_PSCALE anpassar ljudflödet som skickas genom den från volymen 0 (tyst) till 1 (ursprunglig volym) tillbaka till 0 (tyst), enligt positionen (hämta positionen från en Synth_SEQUENCE). Positionen där toppen ska vara kan anges som top.

Att till exempel sätta top till 0,1 betyder att efter 10 % av tonen har spelats, har volymen nått maximalt värde, och börjar sedan avta.

Effekter

Synth_FREEVERB


Synth_FREEVERB

Det här är en efterklangseffekt. I den nuvarande implementeringen är det tänkt att skicka en stereosignal genom modulen, och den lägger till efterklangseffekten i signalen.

Notera

Det här betyder att den också kan användas inne i en StereoEffectStack.

Insignalen ska anslutas till (inleft, inright), och utsignalen blir (outleft, outright).

Parametrarna som du kan ställa in är:

roomsize

Storleken på rummet som efterklangseffekten simulerar (område: 0 .. 1, där 1 är det största möjliga rummet).

damp

Det här anger ett filter som gör att det simulerade rummet absorberar höga frekvenser (område 0 .. 1, där 1 betyder absorbera höga frekvenser i stor utsträckning).

wet

Storleken på efterklangsignalen (dvs. den del av signalen som ska ändras av filtret, och orsaka ett “vått” ljud, dvs. ett “efterklangsljud”).

dry

Storleken på ren signal som skickas igenom, som orsakar ett eko (eller kombinerad fördröjning) istället för en efterklangseffekt (område: 0 .. 1).

width

Storleken på utökad stereoeffekt som efterklangsalgoritmen lägger till i efterklangseffekten, för att göra efterklangsljudet bredare i stereoljudbilden (område 0 .. 1).

mode

[ATT GÖRA: Jag tror att om mode är 1, behåller efterklangen den nuvarande ljudbilden för ljudet, medan 0 är normal behandling]

Synth_TREMOLO


Synth_TREMOLO

Tremolomodulen modulerar amplituden enligt en LFO-vågform. Traditionellt använder man en sinusvåg, men varför begränsa sig? Vad man får är en mycket intensiv effekt som skär igenom de flesta arrangemang på grund av sitt stora dynamiska omfång. Tremoloeffekten är fortfarande en favoriteffekt bland gitarrister, även om den inte är så populär som på 1960-talet.

[ATT GÖRA: för närvarande implementeras detta som invalue + abs(inlfo) - kanske skulle det vara vettigare att implementera det som invalue * (1+inlfo*depth), där depth skulle vara en parameter mellan 0 .. 1 - det här bestäms efter KDE2.1. Om du har en kommentar, skicka e-post till aRts e-postlista ;). ]

Synth_FX_CFLANGER


Synth_FX_CFLANGER

En fläns är en tidsvariabel fördröjningseffekt. För att göra utveckling av komplexa flänseffekter enklare, tillhandahålls den här modulen som innehåller kärnan av en enkanals flänsenhet.

Den har följande portar:

invalue

Signalen som du vill behandla.

lfo

Helst en sinusvåg som modulerar fördröjningstiden inne i flänsen (-1 .. 1).

mintime

Minimala värdet för tiden inne i flänsen i millisekunder. Föreslagna värden: försök med något nära 1 ms. Använd helst värden < 1000 ms.

maxtime

Maximala värdet för tiden inne i flänsen i millisekunder. Föreslagna värden: försök med något nära 5 ms. Använd helst värden < 1000 ms.

outvalue

Utsignalen. Det är viktigt att du blandar den här med originalsignalen (innan flänsen) för att få den önskade effekten.

Tips

Du kan använda den här som en grund för köreffekter.

Filter

Synth_PITCH_SHIFT


Synth_PITCH_SHIFT

Den här tonhöjdsförändrande effekten ändrar frekvensen på insignalen utan att påverka hastigheten. En tillämpning av detta är att till exempel ändra tonhöjden på din röst medan du spelar in (och spelar upp) den i realtid.

Parametern speed är den relativa hastigheten som signalen spelas upp med. Så att med hastigheten två blir ljudet dubbelt så högt (dvs. en infrekvens på 440 Hz ger en utfrekvens på 880 Hz).

Parametern frequency används internt för att ändra mellan olika kornighet i signalen. Den är anpassningsbar, och beroende på valet kommer tonhöjdsförändringen låta mer eller mindre realistisk vid en viss användning. Ett bra värde att börja med är någonting i stil med 5 eller 10.

Synth_SHELVE_CUTOFF


Synth_SHELVE_CUTOFF

Filtrerar bort alla frekvenser över klippningsfrekvensen.

Synth_BRICKWALL_LIMITER


Synth_BRICKWALL_LIMITER

Den här modulen klipper en signal så att den passar i området [-1;1]. Den gör ingenting för att begränsa distorsionen som uppstår när en stark signal klipps av. Man kan använda det här som en ljudeffekt (till exempel för att skapa en något avklippt sinusvåg). Det är dock oftast en god idé att låta signalen gå genom ett lågpassfilter efteråt om du gör detta, för att få ljudet att låta mindre skärande.

Synth_STD_EQUALIZER


Synth_STD_EQUALIZER

Den här är ett trevligt byggblock för en parametriserbar tonkontroll. Dess parametrar är:

Invärde, utvärde

Signalen som filtreras av tonkontrollen.

low

Hur låga frekvenser ska ändras. Värdet anges i dB, medan 0 betyder att låga frekvenser inte ska ändras, skulle -6 betyda att de dämpas med 6 dB, och +6 betyder öka dem med 6 dB.

mid

Hur mittfrekvenser ska ändras av tonkontrollen i dB (se low).

high

Hur höga frekvenser ska ändras av tonkontrollen i dB (se low).

frekvens

Det här är mittfrekvensen för tonkontrollen i Hz, mittfrekvensen befinner sig omkring detta spektrum, med de låga och höga frekvenserna nedanför och ovanför. Observera att frekvensen inte kan vara högre än halva samplingsfrekvensen, oftast är den 22050 Hz, och inte lägre än 1 Hz.

q

Det här påverkar hur brett mittspektrat är. Det måste vara ett positivt tal > 0. Värdet ett är rimligt, högre värden på q betyder ett smalare spektrum av mittfrekvenser. Lägre värden än ett betyder ett bredare spektrum.

Synth_RC


Synth_RC

Ett dämpat resonansfilter som filtrerar alla frekvenser omkring något högsta värde. Det finns inget användbart sätt att ange en mittfrekvens (som inte skulle klippas), eftersom indata är två underliga konstanter f och b. Koden är mycket gammal, från synthesizerns tidigaste dagar, och kommer troligen att bytas ut mot ett nytt filter som har en frekvens och ett resonansvärde som parametrar.

Försök med något som liknar b=5, f=5 or b=10, f=10 or b=15, f=15 i alla fall.

Synth_MOOG_VCF


Synth_MOOG_VCF

Filtrerar bort alla frekvenser ovanför klippningsfrekvensen (det är ett 24 dB fyrpoligt filter, som filtrerar 24 dB per oktav ovanför klippningsfrekvensen), men tillhandahåller en ytterligare parameter för att anpassa filtrets resonans, där 0 betyder ingen resonans och 4 betyder självsvängning.

Midi + sekvensiering

Synth_MIDI_TEST


Synth_MIDI_TEST

Den här modulen laddar en instrumentstruktur från en fil, och registrerar sig som en midi-utgång med aRts MIDI-hanterare. Toner som skickas till den här utgången gör att instrumentröster skapas.

Notera

Du kan ställa in något sådant här på ett bekvämare sätt i artscontrol istället för manuellt i aRts-byggaren.

Synth_SEQUENCE



Spelar en sekvens av toner om och om igen. Tonerna anges i spårnotation, och separeras av semikolon. Ett exempel är A-3;C-4;E-4;C-4;. Hastigheten anges som sekunder per ton, så om du vill ange 120 slag per minut, anger du troligen 0,5 sekunder/ton, som 60 sekunder/0,5 sekunder per ton = 120 slag per minut.

Du kan ge varje ton en längd i förhållande till hastigheten genom att använda ett kolon efter tonen följt av längden. A-3:2;C-4:0.5;D-4:0.5;E-4; visar detta. Som du kan se, tenderar midi-tonsättningsprogram att ge mer bekvämlighet ;)

Synth_SEQUENCE ger ytterligare information om positionen för tonen som spelas just nu, där 0 betyder precis påbörjad och 1 betyder avslutad. Den här informationen kan man använda med Synth_PSCALE (se nedan).

Synth_SEQUENCE_FREQ



Den här modulen fungerar precis som Synth_SEQUENCE, med den enda skillnaden att du inte skriver in notnamn utan frekvenser.

Samplingar

Synth_PLAY_WAV


Synth_PLAY_WAV

Den här spelar en wav-fil. Den är bara tillgänglig om du har libaudiofile på datorn. Vågformsfilen spelas så fort modulen skapas.

Den stannar så fort den är klar, och done sätts till 1. Hastighetsparametern kan användas för att spela upp filen snabbare eller långsammare, där 1.0 är den normala (inspelade) hastigheten.

Ljud-I/O

Synth_PLAY


Synth_PLAY

Viktigt

Normalt behöver man inte den här modulen, om man inte skriver självständiga program. Inne i artsd, finns det redan en Synth_PLAY modul, och att skapa en till fungerar inte.

Modulen Synth_PLAY-matar ut ljudsignalen till ljudkortet. Vänster och höger kanal ska innehålla normaliserad indata för kanalerna. Om indata inte är mellan -1 och 1, får man klippning.

Som redan har nämnts, får det bara finnas en Synth_PLAY modul, eftersom den direkt kommer åt ljudkortet. Använd bussar för att blanda ihop mer än ett ljudflöde innan uppspelning. Använd modulen Synth_AMAN_PLAY för att få något som liknar en utmatning inne i artsd.

Observera att Synth_PLAY också kontrollerar tidbasen för hela strukturen. Det här betyder: ingen Synth_PLAY = ingen källa för tidbas = inget ljud. Så det behövs (exakt) ett Synth_PLAY objekt.

Synth_RECORD


Synth_RECORD

Viktigt

Normalt behöver man inte den här modulen, om man inte skriver självständiga program. Inne i artsd, finns det redan en Synth_RECORD modul, och att skapa en till fungerar inte.

Modulen Synth_RECORD spelar in en signal från ljudkortet. Vänster och höger kanal innehåller indata för kanalerna (mellan -1 och 1).

Som redan har nämnts, får det bara finnas en Synth_RECORD modul, eftersom den direkt kommer åt ljudkortet. Använd bussar för att använda det inspelade ljudflödet på mer än ett ställe. Använd modulen Synth_AMAN_RECORD för att få något som liknar en ingång inne i artsd. För att det här ska fungera måste artsd köra med full duplex aktiverad.

Synth_AMAN_PLAY


Synth_AMAN_PLAY

Modulen Synth_AMAN_PLAY-matar ut ljudsignalen. Det är bra (men inte nödvändigt) att utdata är en normaliserad signal (mellan -1 och 1).

Den här modulen använder ljudhanteraren för att ange var signalen spelas upp. Ljudhanteraren kan styras genom artscontrol. För att göra det mer intuitivt att använda, är det bra att namnge signalen som spelas upp. Det kan åstadkommas genom att ange title. En annan funktion i ljudhanteraren är att kunna komma ihåg var en signal spelades upp sist. För att kunna göra det här måste den kunna skilja på signaler. Därför ska man ange något unikt värde för autoRestoreID också.

Synth_AMAN_RECORD


Synth_AMAN_RECORD

Modulen Synth_AMAN_RECORD-spelar in en ljudsignal från en extern källa (dvs linje in/mikrofon) inne i artsd. Utdata kommer att vara en normaliserad signal (mellan -1 och 1).

Den här modulen använder ljudhanteraren för att ange var signalen spelas upp. Ljudhanteraren kan styras genom artscontrol. För att göra det mer intuitivt att använda, är det bra att namnge signalen som spelas upp. Det kan åstadkommas genom att ange title. En annan funktion i ljudhanteraren är att kunna komma ihåg var en signal spelades in sist. För att kunna göra det här måste den kunna skilja på signaler. Därför ska man ange något unikt värde för autoRestoreID också.

Synth_CAPTURE


Synth_CAPTURE

Modulen Synth_CAPTURE skriver en ljudsignal till en vågformsfil på hårddisken. Filen heter alltid /tmp/mcop-användarnamn/capture.wav

Tester

Synth_NIL


Synth_NIL

Den här gör ingenting. Den är mycket användbar i testsituationer.

Synth_DEBUG


Synth_DEBUG

Man kan använda den här för avlusning. Den skriver ut värdet för signalen invalue med regelbundna intervall (cirka 1 sekund), tillsammans med kommentaren som angivits. På det här sättet kan man ta reda på om vissa signaler förblir inom vissa områden, eller om de finns överhuvudtaget.

Synth_MIDI_DEBUG


Synth_MIDI_DEBUG

Man kan använda den här för att avlusa hur MIDI-händelser verkligen kommer in i aRts.

När en MIDI_DEBUG kör, skriver artsserver ut rader som:

201 100753.837585 on 0 42 127
202 101323.128355 off 0 42

Den första raden talar om att 100753 ms (dvs. 100 sekunder) efter MIDI_DEBUG startade, kom en MIDI-händelse "on" på kanal 0. Den här midi-händelsen hade anslagsstyrkan (volymen) 127, den högsta möjliga. Nästa rad visar midi-händelsen när tangenten släpps. [ATT GÖRA: det här fungerar inte för närvarande, få det att fungera, och gör det via MIDI-hanteraren].

Synth_DATA


Synth_DATA

Det här skapar en signal med ett konstant värde.

Oscillation & Modulation

Synth_FREQUENCY


Synth_FREQUENCY

Oscillatorer i aRts kräver inte en frekvens som indata, utan istället en position i vågformen. Positionen ska vara mellan 0 och 1, som i ett standardobjekt Synth_WAVE_SIN översätts till området 0 .. 2*Pi. För att skapa oscillerande värden från en frekvens, används en Synth_FREQUENCY modul.

Synth_FM_SOURCE


Synth_FM_SOURCE

Den här används för frekvensmodulering. Ange frekvensen med ingången frequency och anslut en annan signal till moduleringsingången. Ställ därefter in modlevel till någonting, säg 0,3. Frekvensen moduleras sedan med moduleringen. Prova det. Fungerar bra om man lägger till en återkoppling, vilket betyder att man tar en kombination av den fördröjda utsignalen från Synth_FM_SOURCE (man måste skicka det till en oscillator eftersom den bara fungerar som Synth_FREQUENCY) och någon annan signal för att få bra resultat.

Fungerar bra tillsammans med Synth_WAVE_SIN oscillatorer.

Vågformer

Synth_WAVE_SIN


Synth_WAVE_SIN

Sinusoscillator. Ange en pos signal från Synth_FREQUENCY eller Synth_FM_SOURCE som insignal, och få en sinusvåg som utsignal. Signalen pos anger positionen i vågformen, området 0 .. 1 omvandlas till 0 .. 2*Pi internt.

Synth_WAVE_TRI


Synth_WAVE_TRI

Triangelvågsoscillator. Ange en pos signal från Synth_FREQUENCY eller Synth_FM_SOURCE som insignal, och få en triangelvåg som utsignal. Signalen pos anger positionen i vågformen, området 0 .. 1 omvandlas till 0 .. 2*Pi internt. Var försiktig. Insignalen måste vara i området 0 .. 1 för att utsignalen ska ge bra resultat.

Synth_NOISE


Synth_NOISE

Brusgenerator. Den här skapar en slumpmässig signal mellan -1 och 1.

Synth_WAVE_SQUARE


Synth_WAVE_SQUARE

Fyrkantvågsoscillator. Ange en pos signal från Synth_FREQUENCY eller Synth_FM_SOURCE som insignal, och få en fyrkantvåg som utsignal. Signalen pos anger positionen i vågformen, området 0 .. 1 omvandlas till 0 .. 2*Pi internt. Var försiktig. Insignalen måste vara i området 0 .. 1 för att utsignalen ska ge bra resultat.

Synth_WAVE_SOFTSAW


Synth_WAVE_SOFTSAW

Mjuk sågtandsvåg, som liknar Synth_WAVE_TRI oscillatorn till utseende. Ange en pos signal från Synth_FREQUENCY eller Synth_FM_SOURCE som insignal, och få en mjuk sågtandsvåg som utsignal. Signalen pos anger positionen i vågformen, området 0 .. 1 omvandlas till 0 .. 2*Pi internt. Var försiktig. Insignalen måste vara i området 0 .. 1 för att utsignalen ska ge bra resultat.

Synth_WAVE_PULSE


Synth_WAVE_PULSE

Pulsoscillator. Andemeningen med den här modulens liknar den rektangulära oscillatorn (Synth_WAVE_RECT), men den tillhandahåller ett anpassningsbart upp/ner-förhållande, genom parametern dutycycle. Ange en pos signal från Synth_FREQUENCY eller Synth_FM_SOURCE som insignal, och få en pulsvåg som utsignal. Signalen pos anger positionen i vågformen, området 0 .. 1 omvandlas till 0 .. 2*Pi internt. Var försiktig. Insignalen måste vara i området 0 .. 1 för att utsignalen ska ge bra resultat.

Diverse

Synth_COMPRESSOR



Den här modulen reducerar det dynamiska omfånget hos en signal. Reduktion är till exempel användbart för att kompensera för de stora variationer i ljudstyrka när någon pratar i en mikrofon.

Så fort indatanivån överstiger en viss nivå (tröskeln) så reduceras signalen. Den multiplicerar helt enkelt allt ovanför tröskeln med ratio, som ska vara ett värde mellan 0 och 1. Till sist multipliceras hela signalen med utdatafaktorn.

Argumenten attack och release fördröjer starten och slutet på reduktionen. Använd det här om du till exempel fortfarande vill höra den starka början av en bastrumma. Argumenten anges i millisekunder, och en attack eller release på 0 ms är möjlig, men kan resultera i ett visst brus.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Referens till visuella moduler
Referens till visuella moduler

Referens till visuella moduler

ATT GÖRA när visuella moduler är "färdigare".



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 9. Ändra program för att passa aRts
Ändra program för att passa aRts
Föregående
Nästa

Kapitel 9. Ändra program för att passa aRts

Att använda artsdsp

Verktyget artsdsp, tidigare beskrivet, låter de flesta äldre ljudprogram som pratar direkt med ljudenheter fungera riktigt med aRts. Program som är skrivna för att använda Enlightenment Sound Daemon (esd) fungerar också i de flesta fall genom att köra esd med artsdsp.

Det här ger en bra lösning på kort sikt för att ändra befintliga program för KDE. Det här låter dock inte programmet direkt dra nytta av hela aRts kraftfulla funktioner, som att använda moduler och andra multimediatyper än digitalljud. Om programmet gör mer än att bara helt enkelt spela ljudfiler, är det oftast vettigt att lägga till inbyggt stöd för aRts i programmet.

Att använda aRts betyder också att programmet inte behöver göra så mycket arbete - det kan dra nytta av funktioner i aRts för att hantera saker som kodning för olika mediaformat och kontroll av ljudhårdvara.

Lägga till inbyggt stöd för aRts
Lägga till inbyggt stöd för aRts

Lägga till inbyggt stöd för aRts

När du använder aRts, finns det ett antal olika programmeringsgränssnitt (API) att välja bland. Beslutet om vilket som ska användas beror på ett antal olika faktorer, bland annat vilket sorts medietyp som används (ljud, MIDI, ljud-CD, etc.), de funktioner som krävs av gränssnittet, och om programmet är skrivet i C++. I de flesta fall bör valet vara ganska klart baserat på de nödvändiga funktionerna.

För flyttbarhet mellan plattformar kan inte program som måste kunna köra i andra miljöer än KDE förlita sig på att aRts är tillgängligt. Att använda en insticksprogramparadigm är ett bra sätt att stödja olika multimediamiljöer. Att göra ett insticksprogram-API öppet och dokumenterat (särskilt för program utan tillgång till källkod) har också fördelen att någon annan än programutvecklaren kan implementera insticksprogram till aRts.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 10. Att bidra till aRts
Att bidra till aRts
Föregående
Nästa

Kapitel 10. Att bidra till aRts

Hur du kan hjälpa till

aRts-projektet behöver hjälp från utvecklare att att lägga till stöd för aRts i befintliga multimediaprogram, skriva nya multimediaprogram och förbättra aRts möjligheter. Du behöver dock inte vara en utvecklare för att bidra. Vi behöver också hjälp från testare för att skicka in felrapporter, översättare för att översätta programtexten och dokumentationen till andra språk, grafiker för att skapa ikoner (särskilt för artsbuilder moduler), musiker för att skapa aRts-modulexempel, och författare för att skriva eller granska dokumentation.

E-postlistor
E-postlistor

E-postlistor

De flesta utvecklingsdiskussioner om aRts äger rum via två e-postlistor. Det här är stället att diskutera nya funktioner och implementeringsidéer och att fråga efter hjälp med problem.

KDE:s multimedia e-postlista är till för generella KDE multimediafrågor inklusive aRts samt multimediaprogram som Noatun och aKtion. Du kan prenumerera från webbsidan på http://www.kde.org/mailinglists.html eller skicka e-post med rubriken subscribe din-e-postadress till . Listan finns också arkiverad på http://lists.kde.org.

E-postlistan för aRts är till för frågor som enbart rör aRts, inklusive användning av aRts utanför KDE. För att prenumerera, skicka e-post till med meddelandetexten subscribe din-epostadress. Listan arkiveras på http://space.twc.de/~stefan/arts-archive.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kodningsstandarder
Kodningsstandarder

Kodningsstandarder

För att åstadkomma en konsekvent läsning av all källkod, är det viktigt att hålla kodningsstilen likadan i hela aRts källkod. Var snäll och försök skriva/formattera din källkod i enlighet med detta, även om du bara skriver en modul, eftersom det gör det enklare för olika personer att underhålla källkodsträdet, och lättare att kopiera delar av källkoden från en fil till en annan.

Namngivning av medlemsfunktioner

Qt™/Java™-stil. Det här betyder att stora bokstäver används för att markera nya ord, och att första bokstaven alltid är liten. Inga understreck.

Det här betyder till exempel:

createStructureDesc()
   updateWidget();
   start(); 
Klassmedlemmar

Klassmedlemmar har inte stora bokstäver, som till exempel menubar eller button.

När det finns funktioner som används för åtkomst, ska standarden som används vara enligt MCOP-sättet, dvs. om det finns en "long" medlem foo, som inte ska vara synlig, så skapas:

foo(long new_value);
   long foo(); 

funktioner för att hämta eller sätta ett värde. I detta fall, ska det riktiga värdet för foo lagras i _foo.

Klassnamn

Alla klasser ska ha stora bokstäver för varje ord, vilket betyder ModuleView, SynthModule. Alla klasser som hör till biblioteken ska använda aRts-namnrymden, som Arts::Soundserver.

Implementeringar av MCOP-klasser ska döpas Class_impl, som till exempel SoundServer_impl.

Parametrar

Parametrar har alltid små bokstäver.

Lokala variabler

Lokala variabler har alltid små bokstäver, och kan ha namn som i, p, x etc. om det passar.

Tabulatorbredd (skiftbredd)

Ett tabulatortecken är lika mycket som fyra blanktecken.

Mellanslag i uttryck

Normalt behöver du inte använda mellanslag i uttryck. Du kan i alla fall använda dem mellan operatorer och deras operander. Om du skriver ett mellanslag före en operator (t.ex. +), måste du också skriva ett mellanslag efter operatorn. Det enda undantaget från detta är uttryck som liknar listor (med ,), där du bara ska använda ett mellanslag efter ",", men inte före. Det är också ok att utelämna mellanslag här.

Följande exempel demonstrerar bra användning av mellanslag:

{
    int a,b;
    int c, d, e;
    int f = 4;

    a=b=c=d+e+f;
    a = b = c = d + e + f;

    if(a == 4) {
        a = b = c = (d+e)/2;
    }

    while(b<3)
        c--;

    arts_debug("%d\n", c);
}

Följande exempel demonstrerar hur man inte ska använda mellanslag. För funktionsanrop, efter if, while, for, switch och så vidare, skrivs inget mellanslag.

{
    // DÅLIGT: Om du skriver en lista, skriv bara mellanslag efter ","
    int a , b , c , d , e , f;

    // DÅLIGT: inte symmetrisk användning av mellanslag för = operatorn
    a= 5;

    // DÅLIGT: Om det anses vara en funktion, och inte följs av ett mellanslag
    if (a == 5) {   
    }

    // DÅLIGT: skriv inte ett mellanslag efter while
    while (a--)
        b++; 

    // DÅLIGT: Funktionsnamn följs inte av ett mellanslag
    arts_debug ("%d\n", c);

    // DÅLIGT: inte heller medlemsnamn
    Arts::Object o = Arts::Object::null ();
}
Namngivning av källkodsfiler

Källkodsfiler ska inte ha några stora bokstäver i namnet. De ska ha samma namn som klassen om de implementerar en enda klass. Deras filändelse ska vara .cc om de innehåller Qt™- och grafikoberoende kod, och .cpp om de innehåller Qt™- och grafikberoende kod. Implementeringsfiler för gränssnitt ska benämnas foo_impl, om Foo är gränssnittets namn.

IDL-filer ska benämnas på ett beskrivande sätt med tanke på den samling gränssnitt de innehåller, också helt med små bokstäver. I synnerhet är det inte bra att benämna en IDL-fil som klassen själv, eftersom .mcopclass-handlaren och typinfoposterna då kommer att kollidera.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 11. Framtida arbete
Framtida arbete
Föregående
Nästa

Kapitel 11. Framtida arbete

Det här avsnittet beskriver en del av det pågående arbetet med aRts. Utvecklingen går snabbt framåt, så den här informationen kan vara föråldrad. Du bör kontrollera listfilen TODO och arkiven för e-postlistorna för att ta reda på vilka nya funktioner som planeras. Delta gärna i ny konstruktion och implementering.

Det här är ett utkast som försöker ge dig en översikt av hur nya teknologier kommer att integreras i aRts. Det täcker följande:

  • Hur gränssnitt fungerar.

  • Avkodare - avkodning av mp3 eller wav-flöden till en form som gör att de kan användas som data.

  • Video.

  • Trådning.

  • Synkronisering.

  • Dynamisk utökning/maskering.

  • Dynamisk sammansättning.

  • GUI

  • MIDI

Det här är pågående arbete. Det bör dock kunna ge grunden om du vill titta på ny teknologi i aRts. Det bör ge dig en allmän idé om hur de här problemen kommer att attackeras. Korrigera gärna allt du ser här.

Saker som kommer att använda aRts-teknologi (så var snäll och koordinera ansträngningarna):

  • K-telefon (röst via IP)

  • Noatun (videospelare / ljudspelare)

  • artscontrol (styrprogram för ljudservern, och för mätare)

  • Brahms (musiksequencer)

  • Kaiman (KDE2 mediaspelare - kmedia2-anpassad)

  • mpglib/kmpg (mpg ljud- och videouppspelningsteknologi)

  • SDL (direktmedialager för spel, som ännu inte påbörjats men som kan vara trevligt)

  • Elektriska öron (upphovsmannen kontaktade mig - status okänd)

Hur gränssnitt fungerar

MCOP-gränssnitt är grunden för aRts-konceptet. De är den nätverkstransparenta motsvarigheten till C++ klasser. Så snart det är möjligt bör du rikta in din konstruktion mot gränssnitt. Ett gränssnitt består av fyra delar:

  • Synkrona strömmar

  • Asynkrona strömmar

  • Metoder

  • Egenskaper

De här kan blandas på vilket sätt du vill. Nya teknologier bör definieras med hjälp av gränssnitt. Läs avsnitten om asynkrona strömmar och synkrona strömmar, samt KMedia2-gränssnittet, som är bra exempel på hur sådana saker fungerar.

Gränssnitt specificeras i .idl-kod och körs genom mcopidl-kompilatorn. Man härleder Gränssnittsnamn_impl klassen för att implementera dem, och använder REGISTER_IMPLEMENTATION (Gränssnittsnamn_impl) för att infoga en objektimplementering i MCOP:s objektsystem.

Codec, dataavkodning
Codec, dataavkodning

Codec, dataavkodning

Kmedia2-gränssnittet låter dig bortse från att wav-filer, mp3-filer eller vad som helst består av dataflöden. Istället implementerar du bara metoder för att spela dem.

På så sätt kan du skriva en vågformsladdningsrutin på ett sätt så att du kan spela vågformsfiler (som PlayObject), men ingen annan kan använda din kod.

Asynkrona strömmar skulle vara alternativet. Man definierar ett gränssnitt som tillåter att datablock skickas in, och hämtas ut. Detta ser ut så här i MCOP:

interface Codec {
  in async byte stream indata;
  out async byte stream outdata;
};

Avkodare kan förstås också ange egenskaper för att skicka ut ytterligare data, som formatinformation.

interface ByteAudioCodec {
  in async byte stream indata;
  out async byte stream outdata;
  readonly attribute samplingRate, bits, channels;
};

Den här ByteAudioCodec kan till exempel anslutas till ett ByteStreamToAudio-objekt, för att skapa riktigt flytande ljud.

Andra typer av avkodare kan förstås innefatta att direkt skicka ut videodata, som

interface VideoCodec {
  in async byte stream indata;
  out video stream outdata;      /* observera: videoströmmar finns inte ännu */
};

Troligtvis bör ett avkodningskoncept användas istället för sättet “du vet hur det spelas upp med det gör inte jag” som till exempel WavPlayObject använder för närvarande. Någon måste dock sätta sig ner och experimentera lite innan ett programmeringsgränssnitt kan definieras.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Video
Video

Video

Min idé är att tillhandahålla video som asynkrona strömmar för någon inbyggd MCOP-datatyp som innehåller bilder. Den här datatypen har inte skapats än. Genom att göra detta, kan insticksprogram som hanterar video kopplas ihop på samma sätt som ljudinsticksprogram.

Det finns några saker som är viktiga att inte utelämna:

  • Det finns RGB och YUV färgrymder.

  • Formatet bör markeras i strömmen på något sätt.

  • Synkronisering är viktig.

Min idé är att lämna möjligheten att ändra implementeringen av VideoFrame-klassen öppen, så att den kan lagra grejor i ett delat minnessegment. Genom att göra detta kan till och med videoströmmar mellan olika processer bli möjligt utan alltför mycket problem.

För video är dock den vanliga situationen att alla saker är i samma process, från avkodningen till renderingen.

Jag har gjort en prototypimplementering av videoströmmar, som kan laddas ner härifrån. Det här behöver integreras med MCOP efter några experiment.

En rederingskomponent som stöder XMITSHM (med RGB och YUV) bör tillhandahållas. Martin Vogt talade om för mig att han arbetar på en sådan.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Trådning
Trådning

Trådning

För närvarande är MCOP helt och hållet en enda tråd. För video kanske vi inte längre kan komma undan trådar. Ok. Det finns några saker som ska hanteras med försiktighet:

  • SmartWrappers - de är inte trådsäkra på grund av osäker referensräkning och liknande.

  • Avsändaren / I/O - inte heller trådsäkra.

Vad jag i alla fall kan tänka mig är att göra utvalda moduler trådsäkra, för både synkrona och asynkrona strömmar. På det här sättet kan man schemalägga signalflödet på två eller flera processorer, med ett flödessystem som känner till trådar. Det här borde också hjälpa en hel del med ljud med multiprocessorer.

Hur det skulle fungera:

  • Flödessystemet bestämmer vilka moduler som ska beräkna vad, dvs:

    • videobilder (med metoden process_indata)

    • synkrona ljudflöden (calculateBlock)

    • andra asynkrona flöden, i huvudsak dataströmmar

  • Modulerna kan beräkna de här sakerna i egna trådar. För ljud är det vettigt att återanvända trådar (t.ex. hantera det med fyra trådar om det finns fyra processorer, även om 100 moduler kör). För video- och datauppackning, kan det vara bekvämare att ha en blockerande implementering i en egen tråd, som synkroniseras med resten av MCOP med flödessystemet.

  • Moduler får inte använda MCOP-funktioner (som fjärranrop) medan trådade operationer pågår.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Synkronisering
Synkronisering

Synkronisering

Video och MIDI (och ljud) kan kräva synkronisering. I grund och botten är det här tidsstämplar. Idén jag har är att bifoga tidsstämplar till de asynkrona strömmarna, genom att lägga till en tidsstämpel till varje paket. Om man skickar två videobilder, görs det helt enkelt som två paket (de är stora ändå), så att man kan ha två olika tidsstämplar.

Ljud ska ha underförstådda tidsstämplar, eftersom det är synkront.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Dynamisk sammansättning
Dynamisk sammansättning

Dynamisk sammansättning

Det bör vara möjligt att säga: En effekt FX består av de här enklare modulerna. FX bör se ut som en normal MCOP-modul (se maskering), men i själva verket bestå av andra moduler.

Det här krävs för aRts-byggaren.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

GUI
GUI

GUI

Alla komponenter i det grafiska gränssnittet kommer att vara MCOP-moduler. De bör ha egenskaper som storlek, etikett, färg, ... En RAD-byggare (aRts-byggaren) bör kunna sätta samman dem visuellt.

Det grafiska gränssnittet bör vara möjligt att spara genom att spara egenskaperna.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

MIDI
MIDI

MIDI

MIDI-grejorna kommer att implementeras som asynkrona strömmar. Det finns två alternativ, ett är att använda normala MCOP-strukturer för att definiera typerna och det andra är att introducera ytterligare egna typer.

Jag tror att normala strukturer kan räcka till, dvs något som:

struct MidiEvent {
  byte b1,b2,b3;
  sequence<byte> sysex;
}

Asynkrona strömmar bör stöda egna flödestyper.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 12. Referenser
Referenser
Föregående
Nästa

Kapitel 12. Referenser

http://multimedia.kde.org

Det här är den huvudsakliga webbplatsen för KDE-relaterad multimediainformation.

http://www.arts-project.org

Det här är aRts-projektets hemsida.

KDE 2.0 Development

Kapitel 14 i den här utgivna boken täcker multimedia, inklusive aRts. Den är tillgänglig i tryck eller på nätet med anteckningar på http://www.andamooka.org.

http://sound.condorow.net

Den här platsen har en uttömmande lista på ljud- och MIDI-program för Linux®.

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 13. Vanliga frågor
Vanliga frågor
Föregående
Nästa

Kapitel 13. Vanliga frågor

Det här avsnittet besvarar några frågor som ofta ställs om aRts.

Allmänna frågor

13.1. Stöder KDE mitt ljudkort för ljuduppspelning?
13.2. Jag kan inte spela wav-filer med artsd!
13.3. Jag hör ljud när jag är inloggad som root, men andra användare saknar ljud!
13.4. Det här hjälper för artsd, men vad gäller för KMix, KMid, KsCD etc.?
13.5. Vad kan jag göra om artsd inte startar eller kraschar när den kör?
13.6. Kan jag flytta på artsd (flytta kompilerade filer till en annan katalog)?
13.7. Kan jag kompilera aRts med gcc-3.0?
13.8. Vilka program kör med aRts?
13.1.

Stöder KDE mitt ljudkort för ljuduppspelning?

KDE använder aRts för att spela upp ljud, och aRts använder ljuddrivrutinerna i Linux® kärna, antingen OSS eller ALSA (med emulering av OSS). Om ditt ljudkort antingen stöds av ALSA eller OSS och är riktigt inställt (dvs. alla andra Linux®-program kan spela upp ljud), kommer det att fungera. Det finns dock några problem med specifik hårdvara, läs avsnittet om hårdvaruspecifika problem om du får problem med artsd på din dator.

Under tiden har också stöd för diverse andra plattformar lagts till. Här är en fullständig lista över hur den senaste versionen av aRts kan spela ljud. Om du har en plattform som inte stöds, fundera gärna på att anpassa aRts till din plattform.

aRts metod för ljud-I/OKommentar
paudStöd för AIX personliga ljudenhet (Personal Audio Device)
alsaLinux ALSA-0.5 och ALSA-0.9 drivrutiner
libaudioioStöd för det generella LibAudioIO-biblioteket som fungerar på Solaris
nasNAS ljudserver, användbar för X-terminaler med NAS-stöd
nullLjudenheten null, kastar bort ljudet utan att något hörs
ossOSS (Open Sound System) stöd (fungerar på Linux, olika BSD-versioner och andra plattformar med OSS-drivrutiner installerade)
tossTrådat OSS-stöd, som fungerar bättre i vissa fall då det vanliga OSS-stödet inte fungerar bra
sgiStöd för SGI Direct Media för IRIX
sunSolaris-stöd
13.2.

Jag kan inte spela wav-filer med artsd!

Kontrollera att artsd är länkad till libaudiofile (ldd artsd). Om den inte är det, ladda ner kdesupport, kompilera om allt, och det kommer att fungera.

13.3.

Jag hör ljud när jag är inloggad som root, men andra användare saknar ljud!

Rättigheterna för filen /dev/dsp påverkar vilka användare som har ljud. För att låta alla använda den, gör så här:

  1. Logga in som root.

  2. Öppna ett Konqueror-fönster.

  3. Gå till katalogen /dev.

  4. Klicka på filen dsp med höger musknapp, och välj egenskaper.

  5. Klicka på fliken Skydd.

  6. Markera rutorna Visa poster och Skriv poster i alla avdelningar.

  7. Klicka på Ok.

Du kan uppnå samma effekt i ett terminalfönster med kommandot chmod 666 /dev/dsp.

För att begränsa tillgången av ljud till särskilda användare kan du använda gruppskydd. För vissa Linux®-distributioner, till exempel Debian/Potato, ägs /dev/dsp redan av en grupp som heter audio, så allt du behöver göra är att lägga till användarna till den här gruppen.

13.4.

Det här hjälper för artsd, men vad gäller för KMix, KMid, KsCD etc.?

Det finns diverse andra enheter som tillhandahåller funktioner som ska kommas åt av multimediaprogram. Du kan behandla dem på samma sätt, antingen genom att göra dem tillgängliga för alla, eller använda grupper för att kontrollera åtkomsten. Här är en lista, som fortfarande kan vara ofullständig (dessutom om det finns flera enheter på formen midi0, midi1..., så finns bara 0-versionen med):

  • /dev/admmidi0

  • /dev/adsp0

  • /dev/amidi0

  • /dev/amixer0

  • /dev/audio

  • /dev/audio0

  • /dev/cdrom

  • /dev/dmfm0

  • /dev/dmmidi0

  • /dev/dsp

  • /dev/dsp0

  • /dev/midi0

  • /dev/midi0

  • /dev/midi00

  • /dev/midi00

  • /dev/mixer

  • /dev/mixer0

  • /dev/mpu401data

  • /dev/mpu401stat

  • /dev/music

  • /dev/rmidi0

  • /dev/rtc

  • /dev/sequencer

  • /dev/smpte0

  • /dev/sndstat

13.5.

Vad kan jag göra om artsd inte startar eller kraschar när den kör?

Försök först att använda de förvalda inställningarna i inställningscentralen (eller om du startar manuellt, ange inga extra väljare utom eventuellt -F10 -S4096 för latenstid). Särskilt full duplex fungerar troligen inte med diverse drivrutiner, så försök stänga av det.

Ett bra sätt att räkna ut varför artsd inte startar (eller kraschar när den kör) är att starta den manuellt. Öppna ett Konsole-fönster och skriv:

% artsd -F10 -S4096
>

Du kan också lägga till väljaren -l0, som skriver ut mer information om vad som händer, så här:

% artsd -l0 -F10 -S4096

Genom att göra detta får du förmodligen någon användbar information om varför den inte startade. Eller om den kraschar medan något särskilt pågår, kan du göra det och se “hur” den kraschar. Om du vill rapportera ett fel, kan en bakåtspårning skapad med gdb och/eller en strace hjälpa till att hitta problemet.

13.6.

Kan jag flytta på artsd (flytta kompilerade filer till en annan katalog)?

Du kan inte flytta aRts helt perfekt. Problemet är att artswrapper har platsen för artsd inkompilerad av säkerhetsskäl. Du kan i alla fall använda .mcoprc-filen (TraderPath/ExtensionPath posterna) för att åtminstone få en flyttad artsd att hitta sina komponenter. Se kapitlet om .mcoprc-filen för detaljer om hur man gör detta.

13.7.

Kan jag kompilera aRts med gcc-3.0?

Ett kort svar: nej, aRts fungerar inte om du kompilerar det med gcc-3.0.

Långt svar: i den officiella utgåvan av gcc-3.0, finns det två fel som påverkar aRts. Det första problemet med gcc-3.0, c++/2733, är ganska ofarligt (och har att göra med problem med asm-satsen). Det gör att convert.cc inte kan kompileras. Det har rättats i gcc-3.0 CVS, och kommer inte att vara ett problem med gcc-3.0.1 och senare. Ett sätt att gå förbi problemet har också lagts till i CVS-versionen av KDE/aRts.

Det andra problemet med gcc-3.0, c++/3145 (som orsakar felaktig kodgenerering för vissa fall av multipla virtuellt arv) är kritisk. Program som artsd kraschar helt enkelt när de startas om de har kompilerats med gcc-3.0. Även om vissa framsteg har gjorts i gcc-3.0 grenen när det här skrivs, kraschar fortfarande artsd väldigt ofta, oförutsägbart.

13.8.

Vilka program kör med aRts?

Självklart så fungerar alla program som ingår i KDE med aRts. Detta innefattar:

  • Noatun

  • aRts-byggare

  • aKtion

  • KMid

  • KMidi

  • KMix

  • KsCD

  • KDE-spel som KPoker och KTuberling

Vissa KDE-program som ännu inte ingår i KDE-utgåvor (t.ex. i kdenonbeta) stöder också aRts, inklusive:

  • Brahms

  • Kaboodle

  • Kdao

Följande program som inte hör till -KDE är kända för att fungera med aRts:

  • xmms (med aRts-insticksprogram)

  • Real Networks RealPlayer 8.0 (fungerar med artsdsp; inbyggt aRts-stöd undersöks)

Följande program är kända för att inte fungera med aRts:

  • inga

Se också svaren till frågorna i avsnittet om program som inte stöder aRts.

Det här avsnittet är ofullständigt. Om du har mer information om program som stöds eller inte, var vänlig skicka dem till upphovsmannen så att de kan läggas till här.

Program som inte stöder aRts

13.1. Så fort KDE kör, så kan inga andra program komma åt mitt ljudkort!
13.2. Du sa att den går till vänteläge efter 60 sekunder, det gör den inte för mig!
13.3. Hur kan jag köra gamla program som inte stöder aRts?
13.4. Jag kan inte köra artsdsp med något program. Den kraschar alltid!
13.5. Finns det teoretiska begränsningar med vissa program som förhindrar att de någonsin fungerar med artsdsp?
13.6. Vad kan jag göra om ett program inte fungerar med artsdsp?
13.7. Vad gäller för program skrivna för KDE 1.x?
13.8. Vad gäller för program som använder Enlightened Sound Daemon, ESD?
13.1.

Så fort KDE kör, så kan inga andra program komma åt mitt ljudkort!

Eftersom aRts-ljudservern som används av KDE kör, använder den ljudenheten. Om servern är oanvänd i 60 sekunder, går den till vänteläge och släpper enheten automatiskt.

13.2.

Du sa att den går till vänteläge efter 60 sekunder, det gör den inte för mig!

Om du startar artsd från KDE:s inställningscentral, är det förvalda värdet att gå till vänteläge efter 60 sekunder. Om du startar artsd från kommandoraden måste du använda väljaren -s för att ange väntelägesvärdet, annars är det förvalda beteendet att stänga av väntelägesfunktionen.

För närvarande går servern inte till vänteläge om full duplex används. Stäng av full duplex i inställningscentralen så går den till vänteläge. Att stänga av full duplex är i allmänhet en bra idé ändå, om du bara använder aRts för att spela upp ljud och inte för att spela in.

13.3.

Hur kan jag köra gamla program som inte stöder aRts?

Kör dem med artsdsp. Om du till exempel normalt skulle köra:

% mpg123 foo.mp3

använd istället:

% artsdsp mpg123 foo.mp3

Det här skickar ljudutmatning till aRts. Den här metoden kräver inte några ändringar i programmet. Den är ändå något av en ful snabbfix, och stöder ännu inte alla funktioner i ljudkortsenheten, så vissa program kanske inte fungerar.

13.4.

Jag kan inte köra artsdsp med något program. Den kraschar alltid!

Du behöver en aktuell version av glibc-bilblioteket. artsdsp fungerar inte tillförlitligt på vissa äldre Linux®-distributioner. Till exempel på Debian 2.1 (som är baserat på glibc 2.0) fungerar den inte, medan på Debian 2.2 (som är baserat på glibc 2.1.3), gör den det.

13.5.

Finns det teoretiska begränsningar med vissa program som förhindrar att de någonsin fungerar med artsdsp?

Nej. Att använda artsdsp kan resultera i något högre latenstider och CPU-användning än att använda aRts programmeringsgränssnitt direkt. Förutom det, ska alla program som inte fungerar anses som ett fel i artsdsp. Tekniken som används av artsdsp ska, om den är riktigt implementerad, tillåta varje program att fungera med den (inklusive stora program som Quake 3).

13.6.

Vad kan jag göra om ett program inte fungerar med artsdsp?

Du kan vänta på att artsd går till vänteläge eller använda kommandot artsshell suspend för att begära att servern ska gå till vänteläge. Du kommer bara kunna få servern att gå till vänteläge om inget aRts-program använder den för närvarande, och inga aRts-program kan köra medan servern är i vänteläge.

Om servern är upptagen ser ett grovt men effektivt sätt att bli av med den ut så här:

% killall artsd ; killall artswrapper
Starta nu ditt eget program.
% kcminit arts

Alla aRts-program som för närvarande kör kan krascha, när du väl avslutar servern.

13.7.

Vad gäller för program skrivna för KDE 1.x?

Om du kör KDE 1.x program, som spelar upp ljud via ljudservern i KDE 1, måste du köra kaudioserver för att det ska fungera. Du kan starta kaudioserver på samma sätt som andra program som inte stöder aRts:

% artsdsp kaudioserver

Du måste ha installerat kaudioserver (från samma källa där du skaffade KDE 1.x programmen). Den hör till KDE 1.x, inte KDE 2.

13.8.

Vad gäller för program som använder Enlightened Sound Daemon, ESD?

Det här problemet liknar fallet med kaudioserver. Sådana program kräver en esd-server som kör. Du kan starta esd via artsdsp, och alla program som stöder ESD ska fungera bra, så här:

% artsdsp esd

Nyare versioner av aRts ( >= 1.2.0) kan också använda Enlightened Sound Daemon istället för direkt åtkomst av ljudkortet. På kommandoraden kan du använda väljaren -a, på följande sätt

% artsd -a esd

för att få stöd för ESD. I stället, i KDE, kan du använda Inställningscentralen för att anpassa artsd att använda ESD, via Ljud -> Ljudserver -> Ljud I/O.

Latenstid

13.1. Ibland hör jag korta pauser när jag lyssnar på musik. Är detta ett fel?
13.2. Vad är effekten av svarstidsinställningen?
13.3. Finns det någonting annat jag kan göra för att undvika pauser?
13.4. Realtidsprioritet verkar inte få någon effekt för mig?
13.5. Varför tar artsd så mycket CPU-tid?
13.1.

Ibland hör jag korta pauser när jag lyssnar på musik. Är detta ett fel?

Det här är troligen inget fel, utan orsakas av det faktum att Linux® kärna inte är särskilt bra på realtidsschemaläggning. Det finns situationer då aRts inte kan hänga med i uppspelningen. Du kan dock aktivera realtidsrättigheter (via inställningscentralen), och använda en stor latenstidsinställning (som 250 ms eller så stor som möjligt), vilket bör förbättra situationen.

13.2.

Vad är effekten av svarstidsinställningen?

Hjälptexten för den här inställningen i inställningscentralen kan vara förvirrande. Ett lägre värde betyder att aRts reagerar snabbare på yttre händelser (dvs tiden det tar mellan ett fönster stängs och ljudet spelas av artsd). Den kommer också att använda mer CPU-resurser och vara mer benäget att orsaka pauser i ljudet.

13.3.

Finns det någonting annat jag kan göra för att undvika pauser?

För användare av IDE-enheter, kan man använda kommandot hdparm för att ställa in din IDE-enhet att använda DMA-läge. Ett varningens ord: Det här fungerar inte med all sorts hårdvara, och kan orsaka att man måste göra en hårdvaruåterställning, eller i ovanliga fall, förlust av data. Läs dokumentationen för kommandot hdparm för mer detaljer. Jag har använt följande kommando med lyckat resultat:

% hdparm -c1 -d1 -k1 -K1 /dev/hda

Du måste köra det här efter varje omstart, så du kanske vill lägga det i ett uppstartsskript för systemet (hur man gör detta är specifikt för varje distribution, på Debian Linux® läggs det oftast i /etc/rc.boot).

13.4.

Realtidsprioritet verkar inte få någon effekt för mig?

Kontrollera att artswrapper verkligen är installerad suid root, som det är meningen att den ska vara. Många distributioner (till exempel SuSE7.x) gör inte detta. Du kan kontrollera det med: ls -l $(which artswrapper). Bra:

% ls -l $(which artswrapper)
-rwsr-xr-x    1 root     root         4556 Sep 24 18:05 /opt/kde2/bin/artswrapper
Dåligt:
% ls -l $(which artswrapper)
-rwxr-xr-x    1 root     root         4556 Sep 24 18:05 /opt/kde2/bin/artswrapper
Om du inte har med s:et, kan du få det med:
% chown root $(which artswrapper)
% chmod 4755 $(which artswrapper)

Om du gör artswrapper SUID root, kommer det troligen förbättra kvaliteten på ljudåtergivningen genom att reducera uppehåll i musiken. Dock ökar det också risken att ett fel i koden, eller en användare med uppsåt att skada kan krascha eller skada datorn på något sätt. Dessutom, att prioritera hög ljudkvalitet på fleranvändardatorer kan orsaka försämrad prestanda för användare som försöker använda datorn på ett “produktivt” sätt.

13.5.

Varför tar artsd så mycket CPU-tid?

Kontrollera dina svarstidsinställningar. Dessutom är den nuvarande versionen inte egentligen optimerad. Det här kommer att bli bättre, och till dess kan inte någon riktig förutsägelse göras om hur snabb artsd kan vara.

Nätverkstransparens

13.1. Vad måste jag göra för att få nätverkstransparens?
13.2. Hur avlusar jag nätverkstransparens om det inte fungerar?
13.1.

Vad måste jag göra för att få nätverkstransparens?

Aktivera det i inställningscentralens inställningar för Ljudserver (Utbyt säkerhets- och referensinformation över X11-servern och Aktivera nätverkstransparens). Kopiera sedan din .mcoprc-fil till alla maskiner som du tänker använda nätverkstransparensen från. Logga in igen. Försäkra dig om att värddatorerna som ska samarbeta känner till varandras namn (dvs. de har namn som kan lösas upp eller finns i /etc/hosts).

Det här bör vara allt du behöver göra. Om det inte fungerar ändå, följer några ytterligare detaljer. aRts ljudserverprocess artsd ska bara köras på en värddator, den med ljudkortet där ljud ska spelas upp. Den kan startas automatiskt vid inloggning av KDE (om du anger det i inställningscentralen), eller manuellt med någonting i stil med:

% artsd -n -F 5 -S 8192

Väljaren -n anger nätverkstransparens, medan de övriga anpassar latenstider.

Din .mcoprc-fil måste innehålla den här raden:

GlobalComm=Arts::X11GlobalComm

för alla maskiner som är inblandade, för att nätverkstransparens ska fungera. Det är det här som aktiveras av inställningen Utbyt säkerhets- och referensinformation över X11-servern i inställningscentralen.

Till sist, i alla KDE-versioner i 2.0.x serien, finns det ett fel som visar sig om du inte har ett domännamn inställt. Klienter till artsd försöker hitta anslutningen via kombinationen av värddatornamn.domännamn. Om domännamnet är tomt, försöker de ansluta till värddatornamn. (observera den extra punkten). Att lägga till en post som ser ut så här i /etc/hosts (dvs orion. om värddatornamnet är orion) gör att man undviker problemet.

13.2.

Hur avlusar jag nätverkstransparens om det inte fungerar?

Om du har KDE:s källkod, gå till kdelibs/arts/examples, och kör make check för att kompilera några program, inklusive referenceinfo. Kör sedan

% ./referenceinfo global:Arts_SimpleSoundServer

Utmatningen anger värddatornamnet och porten som används av aRts. Till exempel, tcp:orion:1698 skulle betyda att alla klienter som försöker använda nätverkstransparens måste veta hur värddatorn orion kan nås.

Hårdvaruspecifika frågor

13.1. Vilken hårdvara fungerar artsd inte bra tillsammans med?
13.2. Varför finns det hårdvaruspecifika problem, och hur ser jag dem?
13.3. Vad är fel i drivrutinen om jag får problemet med för mycket CPU-last?
13.4. Vad är det för fel i drivrutinen om jag får det här felmeddelandet?
13.1.

Vilken hårdvara fungerar artsd inte bra tillsammans med?

Det verkar som om det finns några få Linux-drivrutiner som inte fungerar bra tillsammans med aRts för vissa versioner av kärnan. Läs först den här listan innan du rapporterar ett fel. Om du märker att informationen i listan inte är fullständig, tveka inte att tala om det för oss.

Linux-drivrutin/ljudkortFungerar inte medFungerar medAnmärkning
i810-drivrutin (Intel 810 + AC97 Audio)2.4.92.4.18, 2.2.20, kommersiell OSS-drivrutin, alsa-0.5.12a med OSS-emuleringdrivrutinen orsakar för mycket CPU-last (se nedan)
maestro 3/4-kretsar2.4.9?drivrutinen orsakar ibland överlast av processorn (se nedan)
aureal8820, aureal8830-drivrutiner från sourceforge2.4.17?drivrutinen orsakar felmeddelande / för mycket CPU-last (se nedan)
OSS kommersiell 3.9.4g med Aureal Vortex??systemet låser sig
ymfpci2.4.0, 2.4.122.4.17drivrutinen orsakar felmeddelande (se nedan)

13.2.

Varför finns det hårdvaruspecifika problem, och hur ser jag dem?

De vanliga problemen är att drivrutinen inte ger aRts tillräcklig eller tillräckligt noggrann information om när ljuddata ska skrivas. De flesta OSS-drivrutiner ger riktig information, men inte alla.

Du kan märka att vissa andra program (som xmms) inte behöver den här informationen, och därför fungerar på ett riktigt sätt till och med för din hårdvara. Men aRts behöver den här informationen, så artsd kan sluta fungera. Det här är fortfarande ett fel i drivrutinen, och inte i aRts.

Det finns två sorters beteende som artsd påvisar när den körs med en felaktig drivrutin. Antingen försöker den skicka ny data, men lyckas egentligen aldrig, vilket till slut leder till att för mycket CPU-last används, att detta rapporteras, och att den avslutas. Det andra problemet är att artsd kan få fel information om hur mycket data som ska skrivas. Då stoppar artsd med ett felmeddelande som:

artsd: audiosubsys.cc:458: void Arts::AudioSubSystem::handleIO(int):
Assertion `len == can_write' failed.
Aborted

13.3.

Vad är fel i drivrutinen om jag får problemet med för mycket CPU-last?

Oftast använder artsd anropet select() för att ta reda på när ny data ska skrivas. Därefter använder den anropet ioctl(...GETOSPACE...), för att ta reda på hur mycket data som ska skrivas. Till sist skriver den data.

Ett problem uppstår om artsd antingen alltid väcks, eller om det finns mycket lite data att skriva. OSS-dokumentationen anger att anropet select() bara väcker en process om det finns minst ett fragment att skriva. Om artsd väcks när det inte finns någon, eller mycket lite, data att skriva, till exempel en sampling, försöker den skriva småbitar med ljuddata, vilket kan bli mycket kostsamt, och till slut ge för mycket CPU-last.

För att rätta detta, ska drivrutinen bara väcka artsd om ett helt fragment kan skrivas.

13.4.

Vad är det för fel i drivrutinen om jag får det här felmeddelandet?

Oftast använder artsd anropet select() för att ta reda på när ny data ska skrivas. Därefter använder den anropet ioctl(...GETOSPACE...), för att ta reda på hur mycket data som ska skrivas. Till sist skriver den data.

Om artsd inte kan skriva så mycket data som anges av anropet ioctl, så stoppar den med felmeddelandet ovan. För att rätta detta, ska drivrutinen ange rätt storlek på det lediga utrymmet.

Övriga problem

13.1. Jag kan inte använda aRts-byggaren. Den kraschar när jag kör en modul!
13.1.

Jag kan inte använda aRts-byggaren. Den kraschar när jag kör en modul!

Den troligaste orsaken är att du använder gamla strukturer eller moduler som inte stöds i KDE 2 versionen. Tyvärr gäller dokumentationen på nätet aRts-0.3.4.1 som är helt föråldrad. Den oftast rapporterade kraschen är att om en struktur körs i aRts-byggaren fås felmeddelandet [artsd] Synth_PLAY: ljuddelsystemet används redan.

Du måste använda en Synth_AMAN_PLAY modul istället för Synth_PLAY och problemet försvinner. Se också aRts-byggarens hjälpfil (tryck på F1 i aRts-byggaren).

Senare versioner av aRts-byggaren (KDE 2.1 beta 1 och senare) levereras med ett antal exempel som du kan använda.

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Kapitel 14. aRts Copyright och licens
aRts Copyright och licens
Föregående
Nästa

Kapitel 14. aRts Copyright och licens

aRts programvara copyright 1998-2001 Stefan Westerfeld

Dokumentation copyright 1999-2001 Stefan Westerfeld och Jeff Tranter .

Översättning Stefan Asserhäll

Den här dokumentationen licensieras under villkoren i GNU Free Documentation License.

Alla bibliotek som ingår i aRts licensieras under villkoren i GNU Lesser General Public license. En överväldigande majoritet av koden i aRts finns i biblioteken, inklusive hela MCOP och ArtsFlow. Det här tillåter att biblioteken används för program som inte är fri eller öppen programvara om så önskas.

Det finns ett fåtal program (som artsd), som ges ut under villkoren i GNU General Public License. Eftersom det har funnits olika åsikter om det är tillåtet eller inte att länka GPL-program med Qt™, har jag också lagt till en uttrycklig anmärkning som tillåter det, som ett tillägg till GPL: tillåtelse ges också att länka det här programmet med Qt™-biblioteket, där Qt™ behandlas som ett bibliotek som normalt följer med operativsystemets kärna, vare sig detta är fallet eller inte.

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Appendix A. Installera aRts
Installera aRts
Föregående
Nästa

Appendix A. Installera aRts

För att kunna använda aRts måste du naturligtvis ha det installerat och köra det på systemet. Det finns två metoder att åstadkomma detta, som beskrivs i de följande avsnitten.

Installera en färdigkompilerad binärutgåva

Det snabbaste och enklaste sättet att få aRts körklart är att installera färdigkompilerade binärpaket för systemet. De flesta nyare Linux®-distributioner innehåller KDE, och om det är KDE 2.0 eller senare finns aRts med. Om KDE inte följer med installationen, kan det finnas tillgängligt för nerladdning från din operativsystemleverantör. Som ett alternativ kan det finnas tillgängligt från tredje part. Försäkra dig om att du använder paket som passar ihop med ditt operativsystem.

En grundläggande installation av KDE innehåller ljudservern, som låter de flesta program spela upp ljud. Om du vill ha hela uppsättningen med multimediaverktyg och program behöver du troligen installera ytterligare valfria paket.

Nackdelen med att använda färdigkompilerade binärfiler är att de kanske inte innehåller den senaste versionen av aRts. Det här är särskilt troligt om de tillhandahålls på CD-ROM, eftersom utvecklingstakten för aRts och KDE är sådan att CD-ROM utgåvor oftast inte kan hålla samma takt. Du kan också råka ut för att färdigkompilerade binärpaket inte är tillgängliga, om du har en mindre vanlig arkitektur eller operativsystemdistribution, och du måste därför använda den andra metoden.

Bygga från källkod
Bygga från källkod

Bygga från källkod

Även om det tar tid, är det mest flexibla sättet att bygga aRts att själv kompilera det från källkod. Det här försäkrar dig om att du har en version som är optimalt kompilerad för din systemuppsättning och låter dig bygga den senaste versionen.

Här har du två alternativ, du kan antingen installera den senaste stabila versionen som ingår i KDE eller du kan skaffa den senaste (men kanske instabila) versionen direkt från KDE-projektets CVS-arkiv. De flesta användare som inte utvecklar med aRts bör använda den stabila versionen. Du kan ladda ner den från ftp://ftp.kde.org eller en av de många spegelplatserna. Om du redan utvecklar aktivt med aRts vill du troligen använda CVS-versionen. Om du vill använda aRts utan KDE, kan du ladda ner en självständig utvecklingsversion från http://space.twc.de/~stefan/kde/arts-snapshot-doc.html.

Om du bygger från CVS, observera att vissa komponenter i aRts (dvs. de grundläggande centrala komponenterna inklusive ljudservern) finns i CVS-modulen kdelibs, medan ytterligare komponenter (t.ex. artsbuilder) ingår i kdemultimedia. Det här kan ändras i framtiden. Du kan också hitta en version i modulen kmusic, det är den gamla versionen (före KDE 2.0) som nu är föråldrad.

Kraven för att bygga aRts är i huvudsak likadana som för KDE. Konfigurationsskripten bör upptäcka systeminställningarna och ange om några nödvändiga komponenter saknas. Försäkra dig om att du har en fungerande ljuddrivrutin på systemet (antingen OSS/Free drivrutinen i kärnan, OSS-drivrutinen från 4Front Technologies, eller en ALSA-drivrutin med OSS-stöd).

Mer information om att ladda ner och installera KDE (inklusive aRts) finns i KDE:s vanliga frågor.



Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Appendix B. Introduktion till digitalljud
Introduktion till digitalljud
Föregående
Nästa

Appendix B. Introduktion till digitalljud

Digital sampling, filter, ljudeffekter, etc.

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Appendix C. Introduktion till MIDI
Introduktion till MIDI
Föregående
Nästa

Appendix C. Introduktion till MIDI

Ännu inte skrivet.

Föregående
Nästa
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Gloslista
Gloslista
Föregående

Gloslista

ALSA

Advanced Linux® Sound Architecture. En ljudkortsdrivrutin för Linux® som för närvarande inte ingår i standardkällkoden för kärnan.

aRts

Analog realtidssynthesizer. Namnet på den multimediaarkitektur/bibliotek/verktygslåda som används av KDE-projektet (observera den stora bokstaven)

BSD

Berkeley Software Distribution. Anger här ett av flera olika UNIX®-kompatibla operativsystem som har sitt ursprung i BSD UNIX®.

CORBA

Common Object Request Broker Architecture. En standard för att implementera objektorienterad fjärrkörning.

CVS

Concurrent Versions System. Ett konfigurationshanteringssystem för programvara som används av många programvaruprojekt inklusive KDE och aRts.

FFT

Fast Fourier Transform. En algoritm för att konvertera data från tidsdomänen till frekvensdomänen, som ofta används i signalbehandling.

Full duplex

Möjligheten hos ett ljudkort att samtidigt spela in och spela upp ljud.

GPL

GNU General Public License. En programvarulicens som skapats av Free Software Foundation, som definierar villkoren för att ge ut fri programvara.

GUI

Grafiskt användargränssnitt

IDL

Interface Definition Language. Ett format oberoende av programmeringsspråk för att definiera gränssnitt (metoder och data).

KDE

K skrivbordsmiljö. Ett projekt för att utveckla en fri grafisk skrivbordsmiljö för UNIX®-kompatibla system.

LGPL

GNU Lesser General Public License. En programvarulicens som skapats av Free Software Foundation, som definierar villkoren för att ge ut fri programvara, med mindre begränsningar än GPL som ofta används för programvarubibliotek.

MCOP

Multimedia COmmunication Protocol. Protokollet som används för kommunikation mellan aRts programmoduler, som har likheter med CORBA men är enklare och optimerat för multimedia.

MIDI

Musical Instrument Digital Interface. Ett standardprotokoll för kommunikation mellan elektroniska musikinstrument, anger också ofta filformatet som används för att lagra MIDI-kommandon.

OSS

Open Sound System. Ljuddrivrutinerna som ingår i Linux® kärna (ibland benämnda OSS/Free) eller en kommersiell version som säljs av 4Front Technologies.

Föregående
Hem


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team

Nästa
 


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team