Startsidan  ▸  Texter  ▸  Teknikblogg

Anders Hesselbom

Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.

Kapitlet om ljud i min kommande bok om Commodore 128

2023-11-29

Första utkastet av sjunde kapitlet av min bok om Commodore 128 publiceras här för den som vill rätta eller kommentera. Maila mig, SMS:a mig eller skriv en kommentar här. Glöm inte att meddela om du vill ha ett erkännande i boken för din kommentar. Avgränsningen är enkla ljudeffekter, inte musik eller mer avancerade ljudeffekter, då dessa har var sitt kapitel avsatt.

Ljud

Commodore 128 har ungefär samma kapacitet till ljud som Commodore 64. I datorn finns en avancerad synthesizer innehållande tre röster och fyra vågformer. Vågformerna är triangel, sågtand, fyrkantsvåg och brus. Fyrkantsvågen har ställbar pulsbredd, vilket ger möjlighet till stora variationer.

Till skillnad från Commodore 64, tillåter Commodore 128 att man använder BASIC-kommandon för att åt datorns ljudkapacitet. Kommandot SOUND ger dig möjlighet att spela ljud i någon av de tre kanalerna, i valfri frekvens under valfri tid. Kommandot har även stöd för att böja frekvensen[1] på tonen ljudet som spelar.

Tre argument är obligatoriska. Dessa är val av röst (1, 2 eller 3), val av frekvens (0 till 65535) och längd (angivet i sextiondels sekunder). Använd endast dessa tre argument, spelas en rak ton med i en fyrkantsvåg med en neutral inställning på pulsbredden. Följande spelar tonen A under en sekund:

SOUND 1,3800,60

Du som kan musikteori kanske noterar att 3800 inte är jämt delbart med 220, och det beror på att frekvensangivelsen (det andra argumentet) ligger på en egen skala som inte stämmer med faktisk svängningshastighet.

Argumenten identifieras av sin ordning. Samtliga argument är:

  1. Kanal (1, 2 eller 3)
  2. Val av frekvens (0 till 65535)
  3. Längd (antal sekunder genom 60)
  4. Frekvensändring (0 = upp, 1 = ned, 2 = upp och ned)
  5. Låg frekvens (vid frekvensändring, också 0 till 65535)
  6. Hastighet vid frekvensändring (stegstorlek, också 0 till 65535)
  7. Vågform (0 till 3, se sida 28 i detta kapitel)
  8. Pulsbredd (0 till 4096, se sida 29 i detta kapitel)

Bara genom att läsa argumentlistan så förstår vi att kommandot SOUND är ganska kompetent. Men vi ser också att det saknas en hel del kapacitet innan vi kan säga att vi har en komplett synthesizer, inte minst ADSR[2]-inställningar.

Argumenten identifieras av sin ordning

Låt säga att jag vill spela samma ljud som tidigare, men jag vill ange vågformens pulsbredd. Igen, pulsbredd kommer att förklaras på sida 30, men för nu behöver du bara förhålla dig till att jag vill ange den. Att anropa SOUND med argument 1, 2, 3 (som tidigare) och 8 (pulsbredd), utan att ange något där emellan, innebär att jag anger fem kommatecken för att tala om att det är just det åttonde argumentet jag vill ange.

SOUND 1,3800,60,,,,2,50

Du bör nu höra ett A, fast med en lite förändrad karaktär på ljudet.

Frekvensändring

Oavsett om du vill böja en ton uppåt, nedåt eller oscillera (upp och ned), så måste du ange den högsta frekvensen som argument 2 och den lägsta frekvensen som argument 5.

Om du vill gå upp en oktav från låga A till höga A, kan du skriva följande kommando:

SOUND 1,3800,60,0,1900,32

Kanal 1, hög tonhöjd är 3800, längd är en sekund, riktning är uppåt, låg tonhöjd är 1900, frekvensändringens hastighet är 32.

Ett problem med att böja toner uppåt är att det andra argumentet faktiskt inte bara är den höga frekvensen, utan även startfrekvensen. Ljudet du hör från ovanstående kommando klättrar en oktav (från 1900), men avslöjar målfrekvensen (3800) under en mycket kort stund.

Om vi ändrar riktning från 0 (upp) till 1 (ned) så spelas frekvensändringen helt felfritt, eftersom vi lämnar startfrekvensen till målfrekvensen som är argument 5.

SOUND 1,3800,60,1,1900,32

Men när jobbet är slutfört, så återstartas det, vilket kan höras i slutet på ovanstående ljud. Det kan man vända till sin fördel, om man vill sätta ljud på t.ex. ett rymdskepp som upprepat skjuter med laser på en fiende:

SOUND 1,8000,60,1,3000,700

Man kan riktigt se laserstrålarna färdas genom rymden!

Nu har vi testat att böja en ton uppåt (riktning 0) och nedåt (riktning 1). Genom att välja att oscillera kan du skapa ljud som låter som larmtoner, som t.ex. detta:

SOUND 1,12000,360,2,9000,64

Kanal 1, tonjöjd är 12000, längden är sex sekunder, riktning är upp och ned, låg tonhöjd är 9000, frekvensändringens hastighet är 64.

Vågformer

Vågformen beskriver ljudets mest basala karaktär. Commodore 128 kan återge fyra olika vågformer. Dessa är:

  • 0: Triangel (mjuka ljud som xylofon eller flöjt)
  • 1: Sågtand (en klang liknande dragspel eller gitarr)
  • 2: Fyrkant med variabel pulsbredd (lite vassare ljud som trumpet eller piano)
  • 3: Brus (ofta slagverk)

Dessa fyra vågformer utgör grunden för de olika musikinstrument som din dator kan återge. Detta program spelar upp två sekunder från varje ljud, där fyrkantsvågen återges i sitt grundutförande med en pulsbredd på 2048:

10 FOR A=0 TO 3
20 SOUND 1,3800,120,,,,A
30 SLEEP 3
40 NEXT
Rad 10 räknar från 0 till 3, vilket innebär att rad 20 och 30 körs fyra gånger. Rad 20 spelar en ton i två sekunder som byggs upp av de fyra vågformer som din Commodore kan återge. Rad 30 pausar och rad 40 upprepar.

När du kör programmet så kommer du att höra fyra vågformer, som spelas upp i turordning. Förutom dessa fyra vågformer, kan din Commodore 128 ändra ljudets karaktär rejält när vågform 2 (fyrkant) används, för fyrkantsvågen har variabel pulsbredd.

Pulsbredd

Pulsbredden anger förhållandet mellan impulsens höga och låga värde. Fyrkantens värde består i sitt ursprungsförhållande av lika lång hög som låg impuls, vilket skapar denna figur:

+------------------------------------------------+
|    ----    ----    ----    ----    ----    ----|
|                                                |
|----    ----    ----    ----    ----    ----    |
+------------------------------------------------+

Detta motsvara alltså den ursprungliga pulsbredden 2048. 0 är lägst och 4096 är högst. Du kan skriva in följande kommando för att höra den ursprungliga pulsbredden:

SOUND 1,3800,60,,,,2,2048

Halverar du talet 2048 (alltså om du anger 1024) får du följande kurva:

+------------------------------------------------+
|  ------  ------  ------  ------  ------  ------|
|                                                |
|--      --      --      --      --      --      |
+------------------------------------------------+

Testa genom att skriva:

SOUND 1,3800,60,,,,2,1024

Ljudet är nästan identiskt med det ljud du hade fått av att istället addera hälften (1024) ursprungspulsbredden (2048):

SOUND 1,3800,60,,,,2,3072

Det motsvarar följande vågform:

+------------------------------------------------+
|      --      --      --      --      --      --|
|                                                |
|------  ------  ------  ------  ------  ------  |
+------------------------------------------------+

Testa gärna att skriva program som varierar pulsbredden!

Ljudstyrka

Kommandot VOL påverkar ljudstyrkan både för pågående ljud och efterföljande ljud. VOL accepterar ett argument som är ett tal mellan 0 och 15, där 0 betyder absolut tystnad och 15 betyder högsta möjliga ljud. Ett för högt eller för lågt värde ger felet illegal quantity. Följande program använder VOL för att oscillera ljudstyrkan:

10 SOUND 1,12000,360,2,9000,64
20 FOR T=0 TO 8
30 FOR A=15 TO 0 STEP -1
40 VOL A 50 FOR P=0 TO 10:NEXT
60 NEXT A
70 FOR A=0 TO 15
80 VOL A
90 FOR P=0 TO 10:NEXT 100 NEXT A
110 NEXT T
Rad 10 startar ett larmljud.

Rad 20 säger att volymoscillering ska ske 9 gånger (0 till 8).

Rad 30-60 sänker volymen med en kort paus (rad 50).

Rad 70-100 höjer volymen.
Rad 110 hoppar tillbaka till rad 30 så länge T är mindre än eller lika med 8.


Inför de kommande två kapitlen om musik och om avancerade ljudeffekter, så kan det vara bra att veta när datorn spelar ett ljud direkt, och när datorn väntar. Grundregeln är att datorn väntar med att spela upp ett ljud, tills det ljud som spelas ljust nu är färdigt, givet att det nya ljudet begärs i en kanal som redan spelar ett ljud. Det innebär följande:

Kommandot SOUND sätter processorn i arbete utan att blockera BASIC-tolken, vilket vi tidigare sett i kapitlet om sprites. Skillnaden här är att om din dator satts i arbete att spela ett ljud i en sekund på en viss kanal, och stöter på ett kommando som ger datorn i uppdrag att spela en ny ton i samma kanal, så väntar BASIC-tolken på att pågående uppdrag ska vara utfört innan nästa uppdrag påbörjas. Vi kan studera detta genom att titta på följande program som spelar ett C dur-ackord i en kanal. Det kommer inte att fungera. Istället för att höra ett ackord, så hör vi en ton i taget spelas upp (C, E och G). Vi väljer full ljudstyrka.

10 VOL 15
20 SOUND 1,8900,120,,,,1
30 SOUND 1,11100,120,,,,1
40 SOUND 1,13500,120,,,,1

Orsaken är att kanal 1 inte kan spela något annat än C innan den är färdig. Och när den är färdig, och börjar spela ett E, så kan den inte spela nästa ton innan den har spelat färdigt E. Lösningen är att spela varje ton i C dur-ackordet i var sin kanal, så här:

10 VOL 15
20 SOUND 1,8900,120,,,,1
30 SOUND 2,11100,120,,,,1
40 SOUND 3,13500,120,,,,1

Om nya instruktioner att spela ljud inkommer, väntar din dator med att utföra dem tills ackordet är färdigt. Men det finns undantag, vilket vi tittar på i kapitlet om avancerade ljudeffekter.


[1] På engelska: Pitch bend.

[2] Attack, Decay, Sustain, Release – se kapitlet om ordförklaringar (appendix B).

Categories: Commodore

Leave a Reply

Your email address will not be published. Required fields are marked *



En kopp kaffe!

Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!

Bjud på en kopp kaffe!

Om...

Kontaktuppgifter, med mera, finns här.

Följ mig

Twitter Instagram
GitHub RSS

Public Service

Folkbildning om public service.

Hem   |   linktr.ee/hesselbom   |   winsoft.se   |   80tal.se   |   Filmtips