home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-27 | 75.3 KB | 2,388 lines |
- (*-------------------------------------------------------------------------
- :Program. FMsynth.mod
- :Contents. 6 Operator FM-Syntheziser
- :Author. Christian Stiens
- :Address. Snail-Mail: E-Mail:
- :Address. Heustiege 2 UUCP: Christian_Stiens@ouzonix.bo.open.de
- :Address. D-59348 Lüdinghausen FIDO: 2:243/4802.25
- :Copyright. Giftware, © 93 Christian Stiens
- :Language. Oberon-2
- :Translator. Amiga Oberon 3.01d
- :History. V1.0, 26-Feb-93: first release
- :History. V1.1, 21-Jun-93: keymap now compatible with ProTracker
- :History. 21-Jun-93: sound can be > 99999 Bytes
- :History. 21-Jun-93: uses "setthresh" no more
- :History. 23-Jun-93: AutoCalc
- :History. 26-Jun-93: Chords
- :Imports. AudioSupport, IntuiSupport, MyFileReq, IntuiPointer
- -------------------------------------------------------------------------*)
-
- MODULE FMsynth;
-
- (* $JOIN sintab.o *)
-
- IMPORT
- arg := Arguments,
- as := AudioSupport,
- c := Conversions,
- cia := Cia,
- d := Dos,
- e := Exec,
- fr := MyFileReq,
- g := Graphics,
- hw := Hardware,
- I := Intuition,
- ie := InputEvent,
- ip := IntuiPointer,
- is := IntuiSupport,
- ffp := MathFFP,
- trans:= MathTrans,
- ol := OberonLib,
- rq := Requests,
- str := Strings,
- u := Utility,
- SYS := SYSTEM;
-
-
- CONST
- ver = "\o$VER: fmsynth 1.1 (26.6.93)";
-
- (* $DataChip+ *)
-
- beep = "\x00\x7F\x00\x80";
-
-
- TYPE
-
- Algorithm = STRUCT
- numLines : INTEGER;
- line : ARRAY 15 OF STRUCT mod,car: SHORTINT END;
- END;
-
- Operator = STRUCT
- scR : SHORTINT;
- scL : SHORTINT;
- r,l : ARRAY 4 OF SHORTINT;
- freq : REAL;
- outp : SHORTINT;
- mode : SHORTINT;
- END;
-
- LFO = STRUCT
- wave : SHORTINT; (* LFOWaves *)
- spd,del : SHORTINT;
- amd,pmd : SHORTINT;
- END;
-
-
- CONST
- maxPM = 5.0E5;
- intPerSec = 110;
-
-
- CONST
- numChords = 8;
-
- TYPE
- ChordTable = ARRAY numChords,3 OF REAL;
-
- CONST
- f0 = 1;
- f3 = 1.189207;
- f4 = 1.259921;
- f5 = 1.334840;
- f6 = 1.414214;
- f7 = 1.498307;
- f10 = 1.781797;
- f11 = 1.887749;
-
-
- CONST
- chordTable = ChordTable(f0,f0,f0,
- f0,f4,f7,
- f0,f3,f7,
- f0,f3,f6,
- f0,f5,f7,
- f0,f4,f10,
- f0,f4,f11,
- f0,f3,f10);
-
- CONST
- sin=0; tri=1; down=2; up=3; sqr=4; (* LFOWaves *)
- end=0; keyDown=1; keyUp=2; (* State *)
- poly=0; mono=1; (* Mode *)
- car=0; mod=1; none=2;
- ratio=0; fixed=1; (* Operator.mode *)
-
- pfH = {I.freeHoriz,I.propBorderless};
- pfV = {I.freeVert,I.propBorderless};
-
- (*----- Gadget-IDs -----*)
-
- O1=1;O2=2;O3=3;O4=4;O5=5;O6=6;SR=7;SL=8;
- R1=9;R2=10;R3=11;R4=12;L1=13;L2=14;L3=15;L4=16;
- OL=17;FR=18;WA=19;SP=20;DE=21;AM=22;PM=23;
- M1=24;M2=25;M3=26;M4=27;M5=28;M6=29;
- C1=30;C2=31;C3=32;C4=33;C5=34;C6=35;
- LN=36;RR=37;CS=38;TP=39;OS=40;OK=41;CA=42;
- B1=43;B2=44;B3=45;B4=46;B5=47;CL=48;
- OM=49;FB=50;MD=51;FL=52;PR=53;
-
-
- VAR (*--- Globals ----*)
-
- scr : I.ScreenPtr;
- scrtitle : ARRAY 80 OF CHAR;
- win,win2 : I.WindowPtr;
- req : I.RequesterPtr;
- rp : g.RastPortPtr;
- vp : g.ViewPortPtr;
- pal : BOOLEAN;
- oldfltstate : BOOLEAN;
- mes : I.IntuiMessage;
- menu : I.MenuPtr;
- me : d.ProcessPtr;
- oldWindowPtr : I.WindowPtr;
- filePath : e.STRING;
- file : d.FileHandlePtr;
- op : ARRAY 6 OF Operator;
- opNr : SHORTINT;
- lfo : LFO;
- lfoTab : ARRAY 256 OF SHORTINT;
- lfoPic : UNTRACED POINTER TO SYS.BYTE;
- lfoImg : I.ImagePtr;
- fmImg : I.ImagePtr;
- fmPic : UNTRACED POINTER TO SYS.BYTE;
- mixPic : UNTRACED POINTER TO SYS.BYTE;
- mixImg : I.ImagePtr;
- zifPic : UNTRACED POINTER TO SYS.BYTE;
- zifImg : I.ImagePtr;
- algo : Algorithm;
- isCarrier : ARRAY 6 OF BOOLEAN;
- output : INTEGER;
- maxoutp : INTEGER;
- disabled : BOOLEAN;
- key : ARRAY 128 OF SHORTINT;
- period : ARRAY 36 OF REAL;
- channel : ARRAY 36 OF SHORTINT;
- rRate : SHORTINT;
- mode : SHORTINT;
- soundBuf : SYS.ADDRESS;
- soundLen : LONGINT;
- lenHi : LONGINT;
- oneShotHi : LONGINT;
- repeatHi : LONGINT;
- shiftOct : INTEGER;
- chord : INTEGER;
- filter : BOOLEAN;
- autoCalc : BOOLEAN;
- transp : REAL;
- feedback : SHORTINT;
- int : e.Interrupt;
- intOn : BOOLEAN;
- volTemp : REAL;
- perTemp : REAL;
- Per : INTEGER;
- vol,per : ARRAY 4 OF REAL;
- deltaVol : REAL;
- state : ARRAY 4 OF SHORTINT;
- delay : ARRAY 4 OF INTEGER;
- lfoArg : ARRAY 4 OF INTEGER;
- lfoInc : INTEGER;
- i,id : INTEGER;
- lastCar : SHORTINT;
- lastMod : SHORTINT;
- lastWas : SHORTINT;
- flag : BOOLEAN;
- keyCode : INTEGER;
- selGad : I.GadgetPtr;
- actPropGad : I.GadgetPtr;
- code : INTEGER;
- octave : INTEGER;
- chan : SHORTINT;
- lockreq : I.Requester;
- sinTab ["_SinTab"] : ARRAY 8192 OF SHORTINT;
-
-
- (*----- Gadgets -----*)
-
- gadOp : ARRAY 7 OF I.GadgetPtr;
- gadEG : ARRAY 8 OF I.GadgetPtr; knobEG : ARRAY 8 OF I.Image;
- gadAlgM : ARRAY 7 OF I.GadgetPtr;
- gadAlgC : ARRAY 7 OF I.GadgetPtr;
- gadFreq : I.GadgetPtr;
- gadLen : I.GadgetPtr;
- gadOutp : I.GadgetPtr; knobOutp : I.Image;
- gadLFOs : I.GadgetPtr; knobLFOs : I.Image;
- gadLFOd : I.GadgetPtr; knobLFOd : I.Image;
- gadLFOa : I.GadgetPtr; knobLFOa : I.Image;
- gadLFOp : I.GadgetPtr; knobLFOp : I.Image;
- gadLFOw : I.GadgetPtr;
- gadScR : I.GadgetPtr; knobScR : I.Image;
- gadScL : I.GadgetPtr; knobScL : I.Image;
- gadRel : I.GadgetPtr; knobRel : I.Image;
- gadCalc : I.GadgetPtr;
- gadTsp : I.GadgetPtr;
- gadOffs : I.GadgetPtr; knobPlot : I.Image;
- gadOk : I.GadgetPtr;
- gadCncl : I.GadgetPtr;
- gadBuf : ARRAY 6 OF I.GadgetPtr;
- gadClr : I.GadgetPtr;
- gadFeed : I.GadgetPtr;
- gadFlt : I.GadgetPtr;
- gadMode : I.GadgetPtr;
- gadOM : I.GadgetPtr;
- gadPer : I.GadgetPtr;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE LFOPics; (* $EntryExitCode- *)
- BEGIN SYS.INLINE
- (03C00H,04200H,08100H,08100H,00081H,00081H,00042H,0003CH,
- 00800H,01400H,02200H,04101H,08082H,00044H,00028H,00010H,
- 08100H,0C180H,0A140H,09120H,08910H,08508H,08304H,08102H,
- 00102H,00306H,0050AH,00912H,01122H,02142H,04182H,08102H,
- 0FF00H,08100H,08100H,08100H,00102H,00102H,00102H,001FEH)
- END LFOPics;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE MixPics; (* $EntryExitCode- *)
- BEGIN SYS.INLINE(
- 0C5D2H, 0AA95H, 0AA95H, 0CE95H, 0AA95H, 0AA92H,
- 0EAB6H, 08AA5H, 0C935H, 08925H, 08AA5H, 08AB6H,
- 0A492H, 0EAD5H, 0EAD5H, 0AAB5H, 0AAB5H, 0A492H,
- 0C491H, 0AA8AH, 0AA84H, 0CA84H, 08A84H, 084E4H,
- 00490H, 00AD0H, 00AD0H, 00AB0H, 00AB0H, 00490H,
- 009DCH, 01510H, 01598H, 01510H, 01510H, 00910H)
- END MixPics;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Ziffern; (* $EntryExitCode- *)
- BEGIN SYS.INLINE(
- 0C000H, 0C000H, 0C000H, 0C000H, 0C000H, (* 0 *)
- 04000H, 0C000H, 04000H, 04000H, 04000H, (* 1 *)
- 0C000H, 04000H, 0C000H, 08000H, 0C000H, (* 2 *)
- 0C000H, 04000H, 0C000H, 04000H, 0C000H, (* 3 *)
- 08000H, 08000H, 0C000H, 04000H, 04000H, (* 4 *)
- 0C000H, 08000H, 0C000H, 04000H, 0C000H, (* 5 *)
- 0C000H, 08000H, 0C000H, 0C000H, 0C000H, (* 6 *)
- 0C000H, 04000H, 04000H, 04000H, 04000H, (* 7 *)
- 0C000H, 0C000H, 08000H, 0C000H, 0C000H, (* 8 *)
- 0C000H, 0C000H, 0C000H, 04000H, 0C000H) (* 9 *)
- END Ziffern;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE FMPic; (* $EntryExitCode- *)
- BEGIN SYS.INLINE(
- (* [0] *)
- 0FF80H,00007H,0F03FH,0FFFFH,0FFFFH,0FFFEH,01FFFH,0FFFFH,
- 0FFBFH,0FEF7H,0F7BFH,0FFFFH,0FFFFH,0F878H,0DFFFH,0FFFFH,
- 0FFBFH,0FFF1H,0E78FH,0FFFFH,0FFFFH,0F373H,0C7FFH,0FFFFH,
- 0FF9FH,0FF79H,0EF0FH,0FFFFH,0FFFFH,0E717H,0C7FFH,0FFFFH,
- 0FFCFH,08738H,0CF0FH,0FFFFH,0FFFFH,0CF17H,0C7FFH,0FFFFH,
- 0FFEFH,0833CH,0DF00H,01018H,07843H,09F03H,0C0FFH,0FFFFH,
- 0FFEFH,0803CH,01F0FH,0C7C3H,02319H,03FEBH,0C67FH,0FFFFH,
- 0FFEFH,0903EH,03F1FH,0EFE7H,08F3CH,07FE3H,0DF3FH,0FFFFH,
- 0FFEFH,0983EH,03F3FH,0EFE7H,09FFEH,01F03H,0FF9FH,0FFFFH,
- 0FFEFH,0F8BFH,07F3EH,047C3H,0BFFEH,01F03H,0FF8FH,0FFFFH,
- 0FFEFH,0F8BFH,0FF3FH,003C7H,01F7EH,01F03H,0EF8FH,0FFFFH,
- 0FFEFH,0F8B7H,0EF3FH,083E7H,01E3EH,01F1BH,0C78FH,0FFFFH,
- 0FFEFH,098B7H,0EF1FH,0C1EEH,01E3EH,01F1BH,0C78FH,0FFFFH,
- 0FFEFH,090B3H,0CF0FH,0E5FEH,01E3EH,01F1BH,0C78FH,0FFFFH,
- 0FFEFH,080B3H,0CF07H,0E0FEH,01E3EH,01F0BH,0C78FH,0FFFFH,
- 0FFCFH,08031H,08F33H,0E2FCH,01E3EH,01F63H,0C78FH,0FFFFH,
- 0FF9FH,0C071H,08F3BH,0E2FCH,01E3EH,01FE7H,0C78FH,0FFFFH,
- 0FFBFH,0E6F9H,09F9FH,0C27CH,03F3FH,00FCFH,0EFCFH,0FFFFH,
- 0FFBFH,0E2F8H,01F8FH,08078H,01E1EH,0078FH,0EFC7H,0FFFFH,
- 0FF80H,00200H,00000H,00378H,04000H,01000H,00007H,0FFFFH,
- 0FFE0H,00380H,00000H,00770H,06000H,01800H,00007H,0FFFFH,
- 0FFE0H,00380H,0F008H,007F0H,0F030H,03C08H,00007H,0FFFFH,
- 0FFFFH,0FFFFH,0FFFFH,0F7E0H,0FFFFH,0FFFFH,0FFFFH,0FFFFH,
- 0FFFFH,0FFFFH,0FFFFH,0F3C1H,0FFFFH,0FFFFH,0FFFFH,0FFFFH,
- 0FFFFH,0FFFFH,0FFFFH,0F801H,0FFFFH,0FFFFH,0FFFFH,0FFFFH,
- 0FFFFH,0FFFFH,0FFFFH,0FC03H,0FFFFH,0FFFFH,0FFFFH,0FFFFH,
- 0FFFFH,0FFFFH,0FFFFH,0FE07H,0FFFFH,0FFFFH,0FFFFH,0FFFFH,
- (* [1] *)
- 0007FH,0FFF8H,00FC0H,00000H,00000H,00001H,0E000H,00000H,
- 0007FH,0FFF8H,00FC0H,00000H,00000H,00787H,0E000H,00000H,
- 0007FH,0FFFCH,01FC0H,00000H,00000H,00F8FH,0E000H,00000H,
- 0007FH,0FFFCH,01FC0H,00000H,00000H,01F8FH,0E000H,00000H,
- 0003FH,0FFFEH,03F80H,00000H,00000H,03F8FH,0E000H,00000H,
- 0001FH,0CFFEH,03F9FH,0EFE7H,087BCH,07FFFH,0EF00H,00000H,
- 0001FH,0FFFFH,07FBFH,0FFFFH,0DFFEH,0FFF7H,0FF80H,00000H,
- 0001FH,0FC7FH,07FFFH,0FFFFH,0FFFFH,0FFF7H,0FFC0H,00000H,
- 0001FH,0FC7FH,0FFFFH,0FFFFH,0FFFFH,0FFF7H,0FFC0H,00000H,
- 0001FH,0FC7FH,0FFFFH,0FFFFH,0FFFFH,03F87H,0FFC0H,00000H,
- 0001FH,0FC7FH,0FFFFH,0EFFFH,0FFFFH,03F87H,0FFC0H,00000H,
- 0001FH,0FC7FH,0FFFFH,0E7FFH,0BFFFH,03F87H,0FFC0H,00000H,
- 0001FH,0FC7FH,0FFFFH,0F7FFH,0BF7FH,03F87H,0EFC0H,00000H,
- 0001FH,0FC7FH,0FFBFH,0F3FFH,03F7FH,03F87H,0EFC0H,00000H,
- 0001FH,0F87FH,0FFFFH,0F3FFH,03F7FH,03FF7H,0EFC0H,00000H,
- 0003FH,0E0FFH,0FFFFH,0F1FFH,03F7FH,03FFFH,0EFC0H,00000H,
- 0007FH,0F1FFH,0FFFFH,0F1FEH,07FFFH,0BFFFH,0FFE0H,00000H,
- 0007FH,0F1FFH,0FFFFH,0F1FEH,07FFFH,0BFFFH,0FFE0H,00000H,
- 0007FH,0F1FFH,0FFFFH,0E7FEH,07FFFH,09FFFH,0FFE0H,00000H,
- 0007FH,0F1FCH,03FDFH,0CFFCH,03F3FH,00FDFH,0FFE0H,00000H,
- 00000H,00000H,00000H,00FFCH,00000H,00000H,00000H,00000H,
- 00000H,00000H,00000H,00FF8H,00000H,00000H,00000H,00000H,
- 00000H,00000H,00000H,00FF8H,00000H,00000H,00000H,00000H,
- 00000H,00000H,00000H,00FF0H,00000H,00000H,00000H,00000H,
- 00000H,00000H,00000H,007E0H,00000H,00000H,00000H,00000H,
- 00000H,00000H,00000H,00000H,00000H,00000H,00000H,00000H,
- 00000H,00000H,00000H,00000H,00000H,00000H,00000H,00000H);
- END FMPic;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE VKnob; (* $EntryExitCode- *)
- BEGIN
- SYS.INLINE(
- 07800H,0FC00H,00000H,0FC00H,07800H,
- 0FC00H,0FC00H,0FC00H,0FC00H,0FC00H)
- END VKnob;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE HKnob; (* $EntryExitCode- *)
- BEGIN
- SYS.INLINE(
- 05000H,0D800H,0D800H,0D800H,0D800H,05000H,
- 0F800H,0F800H,0F800H,0F800H,0F800H,0F800H)
- END HKnob;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE ToChipMem(adr:e.ADDRESS; size:LONGINT; check:BOOLEAN): e.ADDRESS;
- VAR newAdr: e.ADDRESS;
- p1,p2: UNTRACED POINTER TO SYS.BYTE;
- BEGIN
- IF check & (e.chip IN e.TypeOfMem(adr)) THEN RETURN adr END;
- INCL(ol.MemReqs,e.chip);
- ol.New(newAdr,size);
- EXCL(ol.MemReqs,e.chip);
- p1 := adr; p2 := newAdr;
- e.CopyMem(p1^,p2^,size);
- RETURN newAdr
- END ToChipMem;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE LockWindow(win: I.WindowPtr);
- BEGIN
- I.InitRequester(lockreq);
- lockreq.width := 1;
- lockreq.height := 1;
- lockreq.backFill := SHORT(SHORT(g.ReadPixel(win.rPort,0,0)));
- IF ~ I.Request(SYS.ADR(lockreq),win) THEN HALT(20) END;
- END LockWindow;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE UnLockWindow(win:I.WindowPtr);
- BEGIN
- I.EndRequest(SYS.ADR(lockreq),win);
- END UnLockWindow;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Request(hail,pos,neg:ARRAY OF CHAR): BOOLEAN; (* $CopyArrays- *)
-
- VAR
- txt0,t : I.IntuiTextPtr;
- posGad : I.GadgetPtr;
-
- BEGIN
- IF req=NIL THEN
- txt0 := is.CreateIntuiText(2,0,g.jam1,0,10,NIL,"", is.CreateIntuiText(3,0,g.jam1,0,9,NIL,"",NIL));
- is.whitePen := 3; is.blackPen := 2;
- is.gadgetFrontPen := 3; is.gadgetBackPen := 1;
- gadOk := is.CreateBoolGadget(0,12,31,55,12," ",is.autoBorder,NIL,is.stdGad,is.stdAct+{I.endGadget});
- gadCncl := is.CreateBoolGadget(0,85,31,55,12," ",gadOk.gadgetRender,NIL,is.stdGad,is.stdAct+{I.endGadget});
- req := is.CreateRequester(85,75,150,50,0,0,is.autoBorder,txt0,{},1);
- is.AddReqGadget(req,gadOk);
- is.AddReqGadget(req,gadCncl);
- END;
- t := req.reqText; t.iText := SYS.ADR(hail); t.leftEdge := 76-SHORT(str.Length(hail))*4;
- t := t.nextText; t.iText := SYS.ADR(hail); t.leftEdge := 75-SHORT(str.Length(hail))*4;
- IF pos[0] # 0X THEN
- t := req.reqGadget.nextGadget.gadgetText;
- t.iText := SYS.ADR(pos); t.leftEdge := 29-SHORT(str.Length(pos))*4;
- END;
- t := req.reqGadget.gadgetText;
- t.iText := SYS.ADR(neg); t.leftEdge := 29-SHORT(str.Length(neg))*4;
- IF pos[0]=0X THEN
- posGad := req.reqGadget.nextGadget;
- req.reqGadget.nextGadget := NIL;
- END;
- IF ~I.Request(req,win) THEN RETURN TRUE END;
- REPEAT is.GetIMsg(win,mes,TRUE) UNTIL I.gadgetUp IN mes.class;
- IF pos[0]=0X THEN
- req.reqGadget.nextGadget := posGad
- END;
- RETURN mes.iAddress = gadOk;
- END Request;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE InitKnobs;
- VAR i:INTEGER;
- BEGIN
- (*--- VertKnobs ---*)
- knobOutp.leftEdge := 0;
- knobOutp.topEdge := 0;
- knobOutp.width := 6;
- knobOutp.height := 5;
- knobOutp.depth := 2;
- knobOutp.imageData := ToChipMem(SYS.VAL(SYS.ADDRESS,VKnob),20,TRUE);
- knobOutp.planePick := SHORTSET{0,1};
- knobOutp.planeOnOff := SHORTSET{};
- knobOutp.nextImage := NIL;
- FOR i:=0 TO 7 DO
- knobEG[i] := knobOutp
- END;
- knobScL := knobOutp;
- knobScR := knobOutp;
- (*--- HorizKnobs ---*)
- knobLFOs.leftEdge := 0;
- knobLFOs.topEdge := 0;
- knobLFOs.width := 5;
- knobLFOs.height := 6;
- knobLFOs.depth := 2;
- knobLFOs.imageData := ToChipMem(SYS.VAL(SYS.ADDRESS,HKnob),24,TRUE);
- knobLFOs.planePick := SHORTSET{0,1};
- knobLFOs.planeOnOff := SHORTSET{};
- knobLFOs.nextImage := NIL;
- knobLFOd := knobLFOs;
- knobLFOa := knobLFOs;
- knobLFOp := knobLFOs;
- knobPlot := knobLFOs;
- knobRel := knobLFOs;
- END InitKnobs;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE StringToReal(s: ARRAY OF CHAR; VAR x: REAL): BOOLEAN; (* $CopyArrays- *)
- VAR v,w,z : LONGINT;
- i : INTEGER;
- p : BOOLEAN;
- minus : BOOLEAN;
- f : REAL;
- BEGIN
- i := 0; v := 0; w := 0; p := FALSE; f := 1; minus := FALSE;
- WHILE (i < LEN(s)) & (s[i] # 0X) DO
- IF s[i] = "." THEN
- p := TRUE
- ELSIF s[i] = "-" THEN
- minus := TRUE
- ELSE
- IF (s[i] >= "0") & (s[i] <= "9") THEN
- z := ORD(s[i]) - ORD("0");
- IF p THEN f := f / 10; w := w * 10 + z ELSE v := v * 10 + z END;
- END;
- END; INC(i)
- END;
- x := v + w * f;
- IF minus THEN x := -x END;
- RETURN TRUE;
- END StringToReal;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE RealToString(x: REAL; VAR s: ARRAY OF CHAR; n: INTEGER): BOOLEAN;
- VAR i : INTEGER;
- w : REAL;
- v,f,z: LONGINT;
- flag : BOOLEAN;
- ovfl : BOOLEAN;
- zn : LONGINT;
- p : BOOLEAN;
-
- PROCEDURE Char(ch: CHAR);
- BEGIN
- IF i < LEN(s) THEN
- s[i] := ch;
- INC(i)
- ELSE
- IF ~p THEN ovfl := TRUE END;
- END;
- END Char;
-
- BEGIN (* RealToString *)
- i := 0; ovfl := FALSE; flag := FALSE; p := FALSE;
- IF x<0 THEN Char("-"); x:=-x END;
- zn := 1;
- WHILE n>0 DO zn := zn * 10; DEC(n) END;
- x := x + 0.5/zn; (* Round *)
- v := ENTIER(x);
- w := x - v; (* Trunc *)
- f := 1000000000;
- REPEAT
- z := v DIV f;
- IF z # 0 THEN flag := TRUE END;
- IF flag THEN Char(CHR(z+ORD("0"))) END;
- v := v - z * f; f := f DIV 10
- UNTIL f = 0;
- p := TRUE;
- Char(".");
- w := w * zn; v := ENTIER(w); f := zn;
- WHILE f >= 10 DO
- f := f DIV 10;
- z := v DIV f;
- Char(CHR(z+ORD("0")));
- v := v - z * f;
- END;
- IF i < LEN(s) THEN s[i] := 0X END;
- RETURN ~ ovfl
- END RealToString;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE IntPerSec(ints: INTEGER);
- VAR wert : INTEGER;
- eClock : LONGINT;
- BEGIN
- (* $RangeChk- $OvflChk- *)
- IF e.exec.libNode.version >= 37 THEN
- eClock := e.exec.eClockFrequency
- ELSE
- eClock := 712644;
- END;
- wert := SHORT(ENTIER(eClock/ints+0.5));
- hw.ciaa.talo := SHORT(SYS.VAL(INTEGER,SYS.VAL(SET,wert) * {0..7}));
- hw.ciaa.tahi := SHORT(SYS.LSH(wert,-8));
- INCL(hw.ciaa.cra,hw.craLoad);
- (* $RangeChk= $OvflChk= *)
- END IntPerSec;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetTimer(start: BOOLEAN);
- BEGIN
- IF start THEN
- IntPerSec(intPerSec);
- INCL(hw.ciaa.cra,hw.craStart)
- ELSE
- EXCL(hw.ciaa.cra,hw.craStart)
- END;
- END SetTimer;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Print(rp:g.RastPortPtr; x,y:INTEGER; str:ARRAY OF CHAR);
- (* $CopyArrays- *)
- VAR i:INTEGER;
- BEGIN
- i := 0;
- WHILE (i < LEN(str)) & (str[i] # 0X) DO INC(i) END;
- g.SetDrMd(rp,g.jam1);
- g.Move(rp,x+1,y+1);
- g.SetAPen(rp,2);
- g.Text(rp,str,i);
- g.SetAPen(rp,3);
- g.Move(rp,x,y);
- g.Text(rp,str,i);
- END Print;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Box(rp:g.RastPortPtr; x,y,a,b:INTEGER;
- out:BOOLEAN;fill:INTEGER);
- BEGIN
- IF fill >= 0 THEN
- g.SetAPen(rp,fill);
- g.RectFill(rp,x,y,x+a-1,y+b-1)
- END;
- IF out THEN g.SetAPen(rp,3) ELSE g.SetAPen(rp,2) END;
- g.Move(rp,x+a-1,y); g.Draw(rp,x,y); g.Draw(rp,x,y+b-1);
- IF out THEN g.SetAPen(rp,2) ELSE g.SetAPen(rp,3) END;
- g.Draw(rp,x+a-1,y+b-1); g.Draw(rp,x+a-1,y+1);
- END Box;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE PrintNumber(rp:g.RastPortPtr; x,y: INTEGER; num: INTEGER);
-
- VAR z: ARRAY 3 OF INTEGER;
- adr: UNTRACED POINTER TO SYS.BYTE;
- i,j: INTEGER;
- BEGIN
- z[2] := num DIV 100;
- z[1] := num MOD 100 DIV 10;
- z[0] := num MOD 10;
- IF num >= 100 THEN j := 3
- ELSIF num >= 10 THEN j := 2
- ELSE j := 1
- END;
- g.SetAPen(rp,1);
- CASE j OF
- 1: g.RectFill(rp,x-6,y,x-2,y+4) |
- 2: g.RectFill(rp,x-6,y,x-5,y+4)
- ELSE END;
- FOR i:=0 TO j-1 DO
- adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,Ziffern) + z[i]*10);
- e.CopyMem(adr^,zifPic^,10);
- I.DrawImage(rp,zifImg^,x-i*3,y);
- END;
- END PrintNumber;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Frame(rp:g.RastPortPtr; x,y,a,b:INTEGER);
- BEGIN
- g.Move(rp,x+a-1,y);
- g.Draw(rp,x,y); g.Draw(rp,x,y+b-1);
- g.Draw(rp,x+a-1,y+b-1); g.Draw(rp,x+a-1,y+1);
- END Frame;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE ResetChord;
- VAR i: INTEGER;
- item: I.MenuItemPtr;
- BEGIN
- chord := 0;
- I.ClearMenuStrip(win);
- FOR i := 0 TO numChords-1 DO
- item := I.ItemAddress(menu^,I.UIntToLong(I.FullMenuNum(2,1,i)));
- IF i=0 THEN INCL(item.flags,I.checked)
- ELSE EXCL(item.flags,I.checked) END;
- END;
- IF I.SetMenuStrip(win,menu^) THEN END;
- END ResetChord;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetUpMenu;
- CONST es = LONGSET{};
- BEGIN
- is.DefMenu("Project",8,0,7*8+2,10,TRUE);
-
- is.DefItem("Load Voice..",0, 0,128,10,0,es,"L",is.stdItem+{I.commSeq});
- is.DefItem("Save Voice..",0,10,128,10,0,es,"S",is.stdItem+{I.commSeq});
- is.DefItem("Save 8SVX..", 0,20,128,10,0,es,"V",is.stdItem+{I.commSeq});
- is.DefItem("New", 0,30,128,10,0,es,"N",is.stdItem+{I.commSeq});
- is.DefItem("About", 0,40,128,10,0,es," ",is.stdItem);
- is.DefSub( fmImg^, 60,10,170,30,0,es," ",{I.itemEnabled});
- is.DefSub(" Version 1.1, © 1993 ",60,40,170,10,0,es," ",is.stdItem-{I.highComp});
- is.DefSub(" by Christian Stiens ",60,50,170,10,0,es," ",is.stdItem-{I.highComp});
- is.DefSub(" Giftware ",60,60,170,10,0,es," ",is.stdItem-{I.highComp});
- is.DefSub(" All Rights Reserved ",60,70,170,10,0,es," ",is.stdItem-{I.highComp});
- is.DefItem("Quit", 0,50,128,10,0,es,"Q",is.stdItem+{I.commSeq});
-
- is.DefMenu("Operator",10*8,0,8*8+2,10,TRUE);
-
- is.DefItem("Init", 0, 0,85,10,0,es,"I",is.stdItem+{I.commSeq});
- is.DefItem("Store »",0,10,85,10,0,es," ",is.stdItem);
- is.DefSub("to 1",60, 0,35,10,0,es," ",is.stdItem);
- is.DefSub("to 2",60,10,35,10,0,es," ",is.stdItem);
- is.DefSub("to 3",60,20,35,10,0,es," ",is.stdItem);
- is.DefSub("to 4",60,30,35,10,0,es," ",is.stdItem);
- is.DefSub("to 5",60,40,35,10,0,es," ",is.stdItem);
- is.DefSub("to 6",60,50,35,10,0,es," ",is.stdItem);
- is.DefItem("Freqency »",0,20,85,10,0,es," ",is.stdItem);
- is.DefSub("Double",50, 0,80,10,0,es,"D",is.stdItem+{I.commSeq});
- is.DefSub("Halve ",50,10,80,10,0,es,"H",is.stdItem+{I.commSeq});
-
- is.DefMenu("Special",20*8,0,7*8+2,10,TRUE);
-
- is.DefItem("Algorithm »",0, 0,110,10,0,es," ",is.stdItem);
- is.DefSub("#0",63, 0,50,10,0,es,"0",is.stdItem+{I.commSeq});
- is.DefSub("#1",63,10,50,10,0,es,"1",is.stdItem+{I.commSeq});
- is.DefSub("#2",63,20,50,10,0,es,"2",is.stdItem+{I.commSeq});
- is.DefSub("#3",63,30,50,10,0,es,"3",is.stdItem+{I.commSeq});
- is.DefSub("#4",63,40,50,10,0,es,"4",is.stdItem+{I.commSeq});
- is.DefSub("#5",63,50,50,10,0,es,"5",is.stdItem+{I.commSeq});
- is.DefSub("#6",63,60,50,10,0,es,"6",is.stdItem+{I.commSeq});
- is.DefSub("#7",63,70,50,10,0,es,"7",is.stdItem+{I.commSeq});
- is.DefSub("#8",63,80,50,10,0,es,"8",is.stdItem+{I.commSeq});
- is.DefSub("#9",63,90,50,10,0,es,"9",is.stdItem+{I.commSeq});
-
- is.DefItem("Chord »",0,10,110,10,0,es," ",is.stdItem);
- is.itemLeftEdge := I.lowCheckWidth;
- is.DefSub("None",63, 0,48,10,0,-LONGSET{0}," ",is.stdItem+{I.checkIt,I.checked});
- is.DefSub("maj", 63,10,48,10,0,-LONGSET{1}," ",is.stdItem+{I.checkIt});
- is.DefSub("min", 63,20,48,10,0,-LONGSET{2}," ",is.stdItem+{I.checkIt});
- is.DefSub("dim", 63,30,48,10,0,-LONGSET{3}," ",is.stdItem+{I.checkIt});
- is.DefSub("sus4",63,40,48,10,0,-LONGSET{4}," ",is.stdItem+{I.checkIt});
- is.DefSub("7", 63,50,48,10,0,-LONGSET{5}," ",is.stdItem+{I.checkIt});
- is.DefSub("7maj",63,60,48,10,0,-LONGSET{6}," ",is.stdItem+{I.checkIt});
- is.DefSub("7min",63,70,48,10,0,-LONGSET{7}," ",is.stdItem+{I.checkIt});
-
- is.itemLeftEdge := 2;
- is.DefItem("Set Loop..", 0,20,110,10,0,es,"P",is.stdItem+{I.commSeq});
- is.DefItem("Fourier..", 0,30,110,10,0,es,"F",is.stdItem+{I.commSeq});
-
- is.itemLeftEdge := I.lowCheckWidth;
-
- is.DefItem("AutoCalc", 0,40,110,10,0,es,"A",is.stdItem+{I.commSeq,I.menuToggle,I.checkIt});
- menu := is.InstallMenuStrip(win);
- END SetUpMenu;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE DoFileRequest(text:ARRAY OF CHAR;VAR filePath:e.STRING):BOOLEAN; (* $CopyArrays- *)
- VAR ok:BOOLEAN;
- BEGIN
- ip.Busy(win);
- LockWindow(win);
- fr.defaultLeft := 10;
- IF CAP(text[0])#"S" THEN
- ok := fr.FileReqWin(text,filePath,win);
- ELSE
- ok := fr.FileReqWinSave(text,filePath,win);
- END;
- UnLockWindow(win);
- ip.Normal(win);
- RETURN ok;
- END DoFileRequest;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE AddGad(gad: I.GadgetPtr);
- BEGIN
- is.AddGadget(win,gad);
- END AddGad;
-
- (*------------------------------------------------------------------------*)
-
- VAR screenTags: u.Tags3;
-
-
- PROCEDURE NSProc (ns: I.ExtNewScreenPtr);
- BEGIN ns.extension := SYS.ADR(screenTags) END NSProc;
-
-
- PROCEDURE ^DrawKeyboard;
-
-
- PROCEDURE SetUpScreen;
-
- TYPE ColorType = ARRAY 4 OF INTEGER;
-
- VAR i,pos : INTEGER;
- strPtr : UNTRACED POINTER TO ARRAY 6 OF CHAR;
- scrHe : INTEGER;
- str : ARRAY 2 OF CHAR;
- dispInfo : g.DisplayInfo;
- BEGIN
- screenTags := u.Tags3(I.saPens,SYS.ADR("\xFF\xFF"),
- I.saDisplayID,g.defaultMonitorID+g.loresKey,
- u.done,u.done);
- scrtitle := "FMsynth oct: 1 name: ";
-
- IF I.int.libNode.version < 36 THEN
- pal := g.gfx.normalDisplayRows >= 256;
- ELSE
- IF g.GetDisplayInfoData(NIL,dispInfo,SIZE(dispInfo),g.dtagDisp,g.palMonitorID+g.loresKey) <= 0 THEN
- pal := FALSE
- ELSIF dispInfo.notAvailable # 0 THEN
- screenTags[1].data := g.ntscMonitorID+g.loresKey;
- pal := FALSE;
- ELSE
- screenTags[1].data := g.palMonitorID+g.loresKey;
- pal := TRUE;
- END;
- END;
- IF pal THEN scrHe := 256 ELSE scrHe := 200 END;
-
- scr := is.CreateScreen(scrtitle,(g.gfx.normalDisplayColumns-640) DIV 4,0,320,scrHe,2,{},NSProc);
- vp := SYS.ADR(scr.viewPort);
-
- g.LoadRGB4(vp,ColorType(0000H,0AAAH,0555H,0FFFH),4);
-
- win := is.CreateWindow("",0,11,320,scrHe-11,scr,
- LONGSET{I.borderless,I.backDrop,I.activate,I.noCareRefresh},
- LONGSET{I.gadgetDown,I.gadgetUp,I.mouseMove,I.rawKey,I.menuPick},
- NIL);
- ip.Normal(win);
- me.windowPtr := win;
- rp := win.rPort;
- InitKnobs;
- SetUpMenu;
- (*----------- BackGround -------------*)
- Box(rp,0,0,320,189,TRUE,1);
- (*----------- Operator ---------------*)
- Box(rp,8,5,214,85,FALSE,-1);
- Print(rp,13,13,"Operator");
- Print(rp,100,16,"1 2 3 4 5 6");
- FOR i:=1 TO 6 DO
- Box(rp,i*16+82,8,12,12,TRUE,-1);
- gadOp[i] := is.CreateBoolGadget(O1-1+i,i*16+82,8,12,12,"",NIL,NIL,is.stdGad,is.stdAct);
- AddGad(gadOp[i]);
- END;
- gadScR := is.CreatePropGadget(SR,16,29,6,40,0,128,SYS.ADR(knobScR),I.gadgHNone,is.stdAct+{I.followMouse},pfV);
- gadScL := is.CreatePropGadget(SL,28,29,6,40,0,128,SYS.ADR(knobScL),I.gadgHNone,is.stdAct+{I.followMouse},pfV);
- Print(rp,15,76,"R");
- Print(rp,27,76,"L");
- Print(rp,13,86,"KSc");
- AddGad(gadScR);
- AddGad(gadScL);
- FOR i := 0 TO 7 DO
- gadEG[i] := is.CreatePropGadget(R1+i,47+10*i+i DIV 4*6,29,6,40,0,128,SYS.ADR(knobEG[i]),I.gadgHNone,is.stdAct+{I.followMouse},pfV);
- str[0] := CHR(ORD("1")+i MOD 4); str[1] := 0X;
- Print(rp,gadEG[i].leftEdge-1,gadEG[i].topEdge+47,str);
- AddGad(gadEG[i]);
- END;
- Print(rp, 50,86,"Rate");
- Print(rp,100,86,"Lvl");
- gadOutp := is.CreatePropGadget(OL,147,29,6,40,0,128,SYS.ADR(knobOutp),I.gadgHNone,is.stdAct+{I.followMouse},pfV);
- AddGad(gadOutp);
- Print(rp,138,76,"Outp");
- Print(rp,138,86,"Lvl");
- gadFreq := is.CreateStrGadget(FR,166,40,48,8,6,"","",NIL,is.stdGad,is.stdAct+{I.stringRight});
- Box(rp,165,39,50,10,FALSE,0);
- AddGad(gadFreq);
- Print(rp,166,35,"Freq");
- gadOM := is.CreateBoolGadget(OM,177,65,25,12,"",NIL,NIL,is.stdGad,is.stdAct);
- Box(rp,177,65,25,12,TRUE,-1);
- AddGad(gadOM);
- Print(rp,178,61,"Mode");
- (*----------- Algorithm ----------*)
- Box(rp,8,94,124,90,FALSE,-1);
- Print(rp,13,102,"Algorithm");
- Print(rp,26,128,"1 2 3 4 5 6"); Print(rp,26,160,"1 2 3 4 5 6");
- FOR i := 1 TO 6 DO
- Box(rp,i*16+8,120,12,12,TRUE,-1);
- gadAlgM[i] := is.CreateBoolGadget(M1-1+i,i*16+8,120,12,12,"",NIL,NIL,is.stdGad,is.stdAct);
- AddGad(gadAlgM[i]);
- Box(rp,i*16+8,152,12,12,TRUE,-1);
- gadAlgC[i] := is.CreateBoolGadget(C1-1+i,i*16+8,152,12,12,"",NIL,NIL,is.stdGad,is.stdAct);
- AddGad(gadAlgC[i]);
- END;
- Print(rp,26,115,"Modulator"); Print(rp,26,175,"Carrier");
- (*------------- LFO -------------*)
- Box(rp,228,5,84,85,FALSE,-1);
- Print(rp,233,13,"LFO");
- gadLFOs := is.CreatePropGadget(SP,265,47,40,6,128,0,SYS.ADR(knobLFOs),I.gadgHNone,is.stdAct,pfH);
- gadLFOd := is.CreatePropGadget(DE,265,57,40,6,128,0,SYS.ADR(knobLFOd),I.gadgHNone,is.stdAct,pfH);
- gadLFOa := is.CreatePropGadget(AM,265,67,40,6,128,0,SYS.ADR(knobLFOa),I.gadgHNone,is.stdAct,pfH);
- gadLFOp := is.CreatePropGadget(PM,265,77,40,6,128,0,SYS.ADR(knobLFOp),I.gadgHNone,is.stdAct,pfH);
- Print(rp,235,52,"Spd"); Print(rp,235,62,"Del");
- Print(rp,235,72,"AMD"); Print(rp,235,82,"PMD");
- gadLFOw := is.CreateBoolGadget(WA,277,24,25,12,"",NIL,NIL,is.stdGad,is.stdAct);
- Box(rp,277,24,25,12,TRUE,-1);
- Print(rp,235,32,"Wave");
- AddGad(gadLFOs); AddGad(gadLFOd);
- AddGad(gadLFOa); AddGad(gadLFOp);
- AddGad(gadLFOw);
- (*------------ Sound ------------*)
- Box(rp,138,94,174,90,FALSE,-1);
- Print(rp,143,102,"Sound");
-
- gadCalc := is.CreateBoolGadget(CS,153,109,38,14,"",NIL,NIL,is.stdGad,is.stdAct);
- Box(rp,153,109,38,14,TRUE,-1);
- Print(rp,153+3,110+8,"Calc");
-
- gadLen := is.CreateStrGadget(LN,148,140,48+8,8,7,"","",NIL,is.stdGad,is.stdAct+{I.longint,I.stringRight});
- Box(rp,148-1,140-1,48+8+2,8+2,FALSE,0);
- Print(rp,148,135,"Size");
-
- gadTsp := is.CreateStrGadget(TP,148,165,48,8,6,"","",NIL,is.stdGad,is.stdAct+{I.stringRight});
- Box(rp,147,165-1,48+2,8+2,FALSE,0);
- Print(rp,148,160,"Transp");
-
- gadFeed := is.CreateStrGadget(FB,280,100,16,8,2,"","",NIL,is.stdGad,is.stdAct+{I.longint,I.stringRight});
- Box(rp,280-1,100-1,16+2,8+2,FALSE,0);
- Print(rp,210,100+6,"Feedback");
-
- gadPer := is.CreateStrGadget(PR,264,115,32,8,4,"","",NIL,is.stdGad,is.stdAct+{I.longint,I.stringRight});
- Box(rp,264-1,115-1,32+2,8+2,FALSE,0);
- Print(rp,210,115+6,"Period");
-
- gadMode := is.CreateBoolGadget(MD,268,130,25,12,"",NIL,NIL,is.stdGad,is.stdAct);
- Box(rp,268,130,25,12,TRUE,-1);
- Print(rp,210,130+8,"Mode");
-
- gadFlt := is.CreateBoolGadget(FL,268,145,25,12,"",NIL,NIL,is.stdGad,is.stdAct);
- Box(rp,268,145,25,12,TRUE,-1);
- Print(rp,210,145+8,"Filter");
-
- gadRel := is.CreatePropGadget(RR,264,165,40,6,128,0,SYS.ADR(knobRel),I.gadgHNone,is.stdAct,pfH);
- AddGad(gadRel);
- Print(rp,210,165+5,"RlRate");
-
- AddGad(gadLen);
- AddGad(gadCalc);
- AddGad(gadTsp);
- AddGad(gadFeed);
- AddGad(gadPer);
- AddGad(gadMode);
- AddGad(gadFlt);
- (*-------------------------------*)
- I.RefreshGadgets(gadOp[1],win,NIL);
- IF pal THEN DrawKeyboard END;
- END SetUpScreen;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE DrawKeyboard;
- CONST X=20; Y=204; H1=26; H2=15; N=5*7;
- VAR i: INTEGER;
- BEGIN
- Box(rp,0,190,320,55,TRUE,1);
- Box(rp,8,195,304,45,FALSE,-1);
- i := 0; WHILE i <= N DO
- g.SetAPen(rp,2);
- g.Move(rp,X+i*8,Y);
- g.Draw(rp,X+i*8,Y+H1);
- IF i < N THEN
- g.SetAPen(rp,3);
- g.RectFill(rp,X+1+i*8,Y,X+7+i*8,Y+H1);
- END;
- IF (i # 0) & (ABS((i-1) MOD 7-4) # 2) THEN
- g.SetAPen(rp,0);
- g.RectFill(rp,X-2+i*8,Y,X-2+4+i*8,Y+H2);
- END;
- INC(i) END;
- g.SetAPen(rp,2);
- g.Move(rp,X,Y); g.Draw(rp,X+280,Y);
- g.Move(rp,X,Y+H1); g.Draw(rp,X+280,Y+H1);
- END DrawKeyboard;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE MarkKey(nr: INTEGER; mark: BOOLEAN);
- TYPE
- Tab=ARRAY 12 OF INTEGER;
- CONST
- tab=Tab(0,4,8,12,16,24,28,32,36,40,44,48);
- VAR
- x,y: INTEGER;
- black: BOOLEAN;
- nrDIV12,nrMOD12: INTEGER;
- BEGIN
- (* $OvflChk- $RangeChk- $NilChk- *)
- IF (~pal) OR (nr < 0) OR (nr > 59) THEN RETURN END;
- SYS.SETREG(7,nr DIV 12);
- nrDIV12 := SHORT(SYS.REG(7));
- nrMOD12 := SHORT(SYS.ROT(SYS.REG(7),-16));
- black := nrMOD12 IN {1,3,6,8,10};
- x := 23 + nrDIV12 * 56 + tab[nrMOD12];
- IF black THEN y := 215 ELSE y := 225 END;
- IF black # mark THEN g.SetAPen(rp,0) ELSE g.SetAPen(rp,3) END;
- g.RectFill(rp,x,y,x+2,y+2);
- (* $OvflChk= $RangeChk= $NilChk= *)
- END MarkKey;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE CheckLine(m,c: SHORTINT);
- VAR
- i: INTEGER;
- found: BOOLEAN;
- BEGIN
- IF m <= c THEN RETURN END;
- found := FALSE;
- i := 1;
- WHILE (i <= algo.numLines) & ~ found DO
- IF (algo.line[i-1].mod=m) & (algo.line[i-1].car=c) THEN
- found := TRUE
- ELSE
- INC(i)
- END
- END;
- IF found THEN
- WHILE i<algo.numLines DO
- algo.line[i-1].mod := algo.line[i].mod;
- algo.line[i-1].car := algo.line[i].car;
- INC(i)
- END;
- DEC(algo.numLines)
- ELSE
- INC(algo.numLines);
- algo.line[i-1].mod := m;
- algo.line[i-1].car := c;
- END
- END CheckLine;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE GetCarrier;
- VAR c,i : INTEGER;
- mods : BOOLEAN;
- BEGIN
- output := 0;
- maxoutp := 0;
- FOR c := 0 TO 5 DO
- mods := FALSE;
- FOR i := 1 TO algo.numLines DO
- IF algo.line[i-1].mod = c THEN mods := TRUE END;
- END;
- isCarrier[c] := ~ mods;
- END;
- g.SetAPen(rp,1); g.RectFill(rp,24,164,115,168);
- g.SetAPen(rp,3);
- FOR c := 0 TO 5 DO
- IF isCarrier[c] THEN
- g.Move(rp,c*16+30,164);
- g.Draw(rp,c*16+30,167);
- INC(output,op[c].outp);
- IF op[c].outp > maxoutp THEN maxoutp := op[c].outp END;
- END;
- END;
- END GetCarrier;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE DrawAlgo;
- VAR i : INTEGER;
- BEGIN
- g.SetAPen(rp,1); g.RectFill(rp,24,132,115,151);
- g.SetAPen(rp,3);
- FOR i := 1 TO algo.numLines DO
- g.Move(rp,algo.line[i-1].mod*16+30,132);
- g.Draw(rp,algo.line[i-1].car*16+30,151);
- END;
- GetCarrier;
- IF feedback # 0 THEN
- g.Move(rp,5*16+30,132);
- g.Draw(rp,5*16+30,151);
- END;
- END DrawAlgo;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE NextLFOWave;
- VAR i,j : INTEGER;
- adr : UNTRACED POINTER TO SYS.BYTE;
- BEGIN
- IF lfo.wave=sqr THEN lfo.wave:=sin ELSE INC(lfo.wave) END;
- FOR i:=0 TO 255 DO
- CASE lfo.wave OF
- | sin:
- lfoTab[i] := -sinTab[i*32];
- | tri:
- CASE i DIV 64 OF
- | 0: lfoTab[i] := SHORT(i*2);
- |1,2: lfoTab[i] := SHORT(255-i*2);
- | 3: lfoTab[i] := SHORT(i*2-512);
- END;
- | down:
- lfoTab[i] := SHORT(i-128);
- | up:
- lfoTab[i] := SHORT(127-i);
- | sqr:
- lfoTab[i] := SHORT((i DIV 128) * 255 - 128);
- END;
- END;
- adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,LFOPics) + LONG(LONG(lfo.wave)) * 16);
- e.CopyMem(adr^,lfoPic^,16);
- I.DrawImage(rp,lfoImg^,gadLFOw.leftEdge+5,gadLFOw.topEdge+2)
- END NextLFOWave;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE BufLen(nr:INTEGER): LONGINT; (* 1 <= nr <= 5 *)
- BEGIN
- RETURN SYS.LSH(lenHi,5-nr);
- END BufLen;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Buffer(nr:INTEGER): SYS.ADDRESS; (* 1 <= nr <= 5 *)
- TYPE A = ARRAY 5 OF LONGINT;
- CONST tab = A(0,16,24,28,30);
- BEGIN
- RETURN SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,soundBuf) + tab[nr-1]*lenHi);
- END Buffer;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE LoopsOff;
- BEGIN
- oneShotHi := lenHi;
- repeatHi := 0;
- END LoopsOff;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE AllocMem(VAR buf: SYS.ADDRESS; size: LONGINT; chip: BOOLEAN);
- VAR oldReqs : LONGSET;
- BEGIN
- oldReqs := ol.MemReqs;
- ol.MemReqs := LONGSET{e.memClear};
- IF chip THEN INCL(ol.MemReqs,e.chip) END;
- ol.Allocate(buf,size);
- ol.MemReqs := oldReqs;
- END AllocMem;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE GetMem;
- VAR i : INTEGER;
- str : UNTRACED POINTER TO ARRAY 7 OF CHAR;
- err : BOOLEAN;
- n : SHORTINT;
- BEGIN
- IF soundLen > 253952 THEN soundLen := 253952 END;
- lenHi := soundLen DIV 31;
- IF ODD(lenHi) THEN DEC(lenHi) END;
- IF lenHi<4 THEN lenHi := 4 END;
- soundLen := lenHi * 31;
- str := is.GadgetText(gadLen);
- n := 6;
- IF soundLen<100000 THEN DEC(n) END;
- IF soundLen< 10000 THEN DEC(n) END;
- IF soundLen< 1000 THEN DEC(n) END;
- err := c.IntToStr(soundLen,str^,10,n," ");
- I.RefreshGList(gadLen,win,NIL,1);
- IF soundBuf # NIL THEN ol.Dispose(soundBuf) END;
- AllocMem(soundBuf,soundLen,TRUE);
- IF soundBuf=NIL THEN
- soundLen:=0;
- IF Request("No mem for buffer","","Cancel") THEN END;
- END;
- END GetMem;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE InitOp(nr: INTEGER);
- BEGIN
- op[nr].scR := 64;
- op[nr].scL := 64;
- op[nr].r[0] := 127;
- op[nr].r[1] := 0;
- op[nr].r[2] := 0;
- op[nr].r[3] := 0;
- op[nr].l[0] := 127;
- op[nr].l[1] := 0;
- op[nr].l[2] := 0;
- op[nr].l[3] := 0;
- op[nr].outp := 0;
- op[nr].freq := 1.0;
- op[nr].mode := ratio;
- END InitOp;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetREALGad(gad:I.GadgetPtr; x:REAL);
- VAR str : UNTRACED POINTER TO ARRAY 6 OF CHAR;
- v,n : INTEGER;
- BEGIN
- str := is.GadgetText(gad);
- IF RealToString(x,str^,4) THEN END;
- str^[5] := 0X;
- I.RefreshGList(gad,win,NIL,1);
- END SetREALGad;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE GetREALGad(gad:I.GadgetPtr; VAR x:REAL);
- VAR err: BOOLEAN;
- str: UNTRACED POINTER TO ARRAY 6 OF CHAR;
- BEGIN
- str := is.GadgetText(gad);
- IF ~ StringToReal(str^,x) THEN x := 1.0 END;
- x := ABS(x);
- END GetREALGad;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE ShowPot(rp:g.RastPortPtr; gad: I.GadgetPtr);
- VAR val : INTEGER;
- BEGIN
- val := 127-is.VertPot(gad,128);
- PrintNumber(rp,gad.leftEdge+4,gad.topEdge-6,val);
- END ShowPot;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetOp(nr: INTEGER);
-
- VAR
- i: INTEGER;
- adr: UNTRACED POINTER TO SYS.BYTE;
- gad: I.GadgetPtr;
-
- BEGIN
- adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,MixPics) + LONG(LONG(op[nr].mode)) * 12);
- e.CopyMem(adr^,mixPic^,12);
- I.DrawImage(rp,mixImg^,gadOM.leftEdge+5,gadOM.topEdge+3);
- FOR i := 1 TO 6 DO
- IF i=nr+1 THEN g.SetAPen(rp,3) ELSE g.SetAPen(rp,1) END;
- Frame(rp,i*16+81,7,14,14);
- Frame(rp,i*16+80,7,16,15);
- END;
- FOR i := 0 TO 3 DO
- gad := gadEG[i];
- is.SetProp(gad,win,NIL,0,127-op[nr].r[i],0,128);
- ShowPot(rp,gad);
- gad :=gadEG[4+i];
- is.SetProp(gad,win,NIL,0,127-op[nr].l[i],0,128);
- ShowPot(rp,gad);
- END;
- is.SetProp(gadScL, win,NIL,0,127-op[nr].scL ,0,128);
- is.SetProp(gadScR, win,NIL,0,127-op[nr].scR ,0,128);
- is.SetProp(gadOutp,win,NIL,0,127-op[nr].outp,0,128);
- ShowPot(rp,gadScL);
- ShowPot(rp,gadScR);
- ShowPot(rp,gadOutp);
- SetREALGad(gadFreq,op[nr].freq);
- END SetOp;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetLFO;
- BEGIN
- is.SetProp(gadLFOs,win,NIL,lfo.spd,0,128,0);
- is.SetProp(gadLFOd,win,NIL,lfo.del,0,128,0);
- is.SetProp(gadLFOa,win,NIL,lfo.amd,0,128,0);
- is.SetProp(gadLFOp,win,NIL,lfo.pmd,0,128,0);
- lfoInc := (LONG(lfo.spd)+1) * 64;
- IF lfo.wave=sin THEN lfo.wave:=sqr ELSE DEC(lfo.wave) END;
- NextLFOWave;
- END SetLFO;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetRR;
- BEGIN
- is.SetProp(gadRel,win,NIL,127-rRate,0,128,0);
- deltaVol:=(trans.Exp(0.05*rRate)-1.0)*0.112;
- END SetRR;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetFeedback;
- VAR str: UNTRACED POINTER TO ARRAY 2 OF CHAR;
- BEGIN
- IF feedback<0 THEN feedback:=0 END;
- IF feedback>7 THEN feedback:=7 END;
- str := is.GadgetText(gadFeed);
- str^[0] := CHR(feedback+ORD("0"));
- str^[1] := 0X;
- I.RefreshGList(gadFeed,win,NIL,1);
- DrawAlgo;
- END SetFeedback;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetFilter;
- VAR adr: UNTRACED POINTER TO SYS.BYTE;
- BEGIN
- as.Filter(filter);
- adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,MixPics) + 4 * 12);
- IF ~filter THEN adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,adr)+12) END;
- e.CopyMem(adr^,mixPic^,12);
- I.DrawImage(rp,mixImg^,gadFlt.leftEdge+5,gadFlt.topEdge+3)
- END SetFilter;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetMode;
- VAR adr: UNTRACED POINTER TO SYS.BYTE;
- BEGIN
- adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,MixPics) + 2 * 12);
- IF mode=poly THEN adr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,adr)+12) END;
- e.CopyMem(adr^,mixPic^,12);
- I.DrawImage(rp,mixImg^,gadMode.leftEdge+5,gadMode.topEdge+3)
- END SetMode;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetKeys;
- VAR i:INTEGER;
- BEGIN
- FOR i:=0 TO 127 DO key[i]:=-1 END;
- key[49]:=0; key[33]:=1; key[50]:=2; key[34]:=3; key[51]:=4;
- key[52]:=5; key[36]:=6; key[53]:=7; key[37]:=8; key[54]:=9; key[38]:=10;
- key[55]:=11;key[56]:=12;key[40]:=13;key[57]:=14;key[41]:=15;key[58]:=16;
- key[97]:=17;key[43]:=18;
- key[66]:=11;key[16]:=12;key[2] :=13;key[17]:=14;key[3]:=15; key[18]:=16;
- key[19]:=17;key[5] :=18;key[20]:=19;key[6] :=20;key[21]:=21;key[7] :=22;
- key[22]:=23;key[23]:=24;key[9] :=25;key[24]:=26;key[10]:=27;key[25]:=28;
- key[26]:=29;key[12]:=30;key[27]:=31;key[13]:=32;key[68]:=33;key[65]:=34;
- key[0] :=10;
- END SetKeys;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetPer;
- VAR i : INTEGER;
- p : REAL;
- str : UNTRACED POINTER TO ARRAY 4 OF CHAR;
- err : BOOLEAN;
- n : SHORTINT;
- BEGIN
- IF Per < 124 THEN Per := 124 END;
- IF Per > 999 THEN Per := 999 END;
- str := is.GadgetText(gadPer);
- err := c.IntToStr(Per,str^,10,3," ");
- I.RefreshGList(gadPer,win,NIL,1);
- FOR i := 35 TO 0 BY -1 DO
- IF i MOD 12 = 11 THEN p := Per ELSE p := p * 1.059463094 END;
- period[i] := p;
- END;
- END SetPer;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Muls (i{0},j{1}: INTEGER): LONGINT; (* $EntryExitCode- *)
- BEGIN
- SYS.INLINE(0C1C1H,04E75H); (* MULS D1,D0 ; RTS *)
- END Muls;
-
- (*---------------------------------------------------------------------*)
-
- PROCEDURE Inc(freq,faktor:REAL; okt:INTEGER; mode:SHORTINT): LONGINT;
- BEGIN
- (* $OvflChk- $RangeChk- *)
- IF mode=ratio THEN
- RETURN SYS.LSH(ENTIER(freq * faktor * transp * (65536.0*64.0) + 0.5),okt)
- ELSE (* mode=fixed *)
- RETURN ENTIER(freq*(0.738184*65536.0));
- END;
- (* $OvflChk= $RangeChk= *)
- END Inc;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE CalcSound();
-
- VAR
- i,j : INTEGER;
- b,k : INTEGER;
- arg : ARRAY 6 OF LONGINT;
- inc : ARRAY 6 OF LONGINT;
- d : ARRAY 6 OF INTEGER;
- a : ARRAY 6 OF LONGINT;
- l : LONGINT;
- y : SHORTINT;
- mod : ARRAY 6,8 OF SHORTINT;
- num : ARRAY 6 OF SHORTINT;
- phi : INTEGER;
- m,c : SHORTINT;
- ra : ARRAY 6,4 OF LONGINT;
- le : ARRAY 6,4 OF LONGINT;
- raTemp : LONGINT;
- leTemp : LONGINT;
- e : ARRAY 6 OF LONGINT;
- p : ARRAY 6 OF SHORTINT;
- outp : ARRAY 6 OF INTEGER;
- buf : INTEGER;
- bufs2Calc : INTEGER;
- part : INTEGER;
- parts2Calc : INTEGER;
- bufLen : LONGINT;
- bufPtr : UNTRACED POINTER TO SHORTINT;
- bufPtr2 : UNTRACED POINTER TO SHORTINT;
- rate : REAL;
- raSc : REAL;
- leSc : REAL;
- mlevel : INTEGER;
- fast : BOOLEAN;
-
- BEGIN
- (* $OvflChk- $RangeChk- $NilChk- *)
- GetCarrier;
- IF output = 0 THEN
- IF ~autoCalc THEN
- IF Request("No output level","","Cancel") THEN END;
- RETURN
- END;
- END;
- IF soundBuf = NIL THEN
- IF ~autoCalc & Request("No buffer","","Cancel") THEN END;
- RETURN
- END;
- SetTimer(FALSE);
- ip.Busy(win);
- LockWindow(win);
-
- IF output=0 THEN
- mlevel := 0;
- ELSE
- IF chord=0 THEN mlevel := 2080;
- ELSE mlevel := 680; END;
- mlevel := SHORT(ENTIER((mlevel / output) * maxoutp))
- END;
-
- FOR i := 0 TO 5 DO num[i] := -1 END;
-
- FOR i := 0 TO algo.numLines-1 DO
- m := algo.line[i].mod; c := algo.line[i].car;
- INC(num[c]); mod[c,num[c]] := m;
- END;
-
- fast := TRUE;
-
- FOR i := 0 TO 5 DO
- IF (op[i].outp#0)&((op[i].scR#64)OR(op[i].scL#64)OR(op[i].mode=fixed))
- THEN fast := FALSE
- END;
- END;
-
- IF fast THEN bufs2Calc := 1 ELSE bufs2Calc := 5 END;
-
- IF chord=0 THEN parts2Calc := 1 ELSE parts2Calc := 3 END;
-
- FOR buf := 1 TO bufs2Calc DO
-
- FOR i := 0 TO 5 DO
- raSc := trans.Pow(buf - 1, op[i].scR / 64 + 1);
- FOR j := 0 TO 3 DO
- le[i,j] := LONG(LONG(op[i].l[j])) * (128 * 65536);
- rate := (trans.Exp(0.08*op[i].r[j])-1) * 41218 * raSc;
- IF rate < 1.065353E+9 THEN ra[i,j] := ffp.Fix(rate);
- ELSE ra[i,j] := 1065353216; END;
- IF (j>0) & (op[i].l[j]<op[i].l[j-1]) THEN ra[i,j] := -ra[i,j] END;
- END;
- leSc := op[i].scL - 64;
- IF leSc >= 0 THEN leSc := 1 - leSc * (5-buf) / 256;
- ELSE leSc := 1 + leSc * (buf-1) / 256 END;
- outp[i] := SHORT(ffp.Fix(op[i].outp * leSc * 8 + 0.5));
- END;
-
- FOR part := 0 TO parts2Calc-1 DO
-
- FOR i := 0 TO 5 DO
- arg[i] := 0; p[i] := 0; e[i] := 0;
- inc[i] := Inc(op[i].freq,chordTable[chord,part],buf,op[i].mode);
- END;
-
- k := 0;
- bufPtr := Buffer(buf);
- bufLen := BufLen(buf);
-
- FOR l := 0 TO bufLen-1 DO
- IF k=0 THEN
- FOR i := 0 TO 5 DO
- raTemp := ra[i,p[i]]; leTemp := le[i,p[i]];
- INC(e[i],raTemp);
- IF raTemp < 0 THEN
- IF e[i] <= leTemp THEN
- e[i] := leTemp;
- IF p[i] < 3 THEN INC(p[i]) END;
- END;
- ELSIF raTemp > 0 THEN
- IF e[i] >= leTemp THEN
- e[i] := leTemp;
- IF p[i] < 3 THEN INC(p[i]) END;
- END;
- END;
-
- a[i] := Muls(SHORT(SYS.ROT(e[i],-16)),outp[i]);
-
- END;
- END;
- k := (k+1) MOD 16;
- b := 0;
- d[5] := 0;
-
- IF SHORT(SYS.ROT(a[5],-16))=0 THEN
- d[5] := 0
- ELSE
- i := feedback+1; REPEAT
- phi := SHORT(SYS.ROT(arg[5],-16)) + d[5];
- d[5] := SHORT(ASH(Muls(SHORT(SYS.ROT(a[5],-16)),LONG(sinTab[phi MOD 8192])),-3));
- DEC(i) UNTIL i=0;
- IF isCarrier[5] THEN INC(b,d[5]) END;
- END;
-
- INC(arg[5],inc[5]);
-
- i:=4; REPEAT
- IF SHORT(SYS.ROT(a[i],-16))=0 THEN
- d[i] := 0
- ELSE
- phi := SHORT(SYS.ROT(arg[i],-16));
- FOR j:=0 TO num[i] DO
- INC(phi,d[mod[i,j]])
- END;
- d[i] := SHORT(ASH(Muls(SHORT(SYS.ROT(a[i],-16)),LONG(sinTab[phi MOD 8192])),-3));
- IF isCarrier[i] THEN INC(b,d[i]) END;
- END;
- INC(arg[i],inc[i]);
- DEC(i) UNTIL i<0;
-
- y := SHORT(SHORT(SYS.ROT(Muls(b,mlevel),-16)));
-
- IF part=0 THEN bufPtr^ := y;
- ELSE INC(bufPtr^,y) END;
-
- bufPtr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,bufPtr)+1);
-
- END; (* FOR l *)
- END; (* FOR part *)
- END; (* FOR buf *)
-
- IF fast THEN
- FOR buf := 2 TO 5 DO
- bufPtr := Buffer(buf);
- bufPtr2 := Buffer(buf-1);
- bufLen := BufLen(buf);
- FOR l:=0 TO bufLen-1 DO
- bufPtr^ := bufPtr2^;
- bufPtr := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,bufPtr) +1);
- bufPtr2 := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,bufPtr2)+2);
- END;
- END;
- END;
-
- SetTimer(TRUE);
- UnLockWindow(win);
- ip.Normal(win);
-
- disabled := TRUE;
- as.PlaySound(3,SYS.ADR(beep),4,500,40,100);
- state[3] := end;
- disabled := FALSE;
-
- (* $OvflChk= $RangeChk= $NilChk= *)
- END CalcSound;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetLoop;
-
- VAR
- rp : g.RastPortPtr;
- mes : I.IntuiMessage;
- offs : LONGINT;
- last : LONGINT;
- pip : I.PropInfoPtr;
- mark1 : LONGINT;
- mark2 : LONGINT;
- mx : INTEGER;
- i,id : INTEGER;
- sGad : I.GadgetPtr;
- nr : INTEGER;
-
- (*···············································*)
-
- PROCEDURE Plot;
- VAR i,j : INTEGER;
- buf : UNTRACED POINTER TO SHORTINT;
- x : LONGINT;
- y : INTEGER;
- str : ARRAY 6 OF CHAR;
- err : BOOLEAN;
- m : LONGINT;
- BEGIN
- g.SetAPen(rp,1); g.RectFill(rp,6,26,313,93);
- g.RectFill(rp,122,12,208,22);
- IF (mark1 # 0) OR (mark2 # 0) THEN
- m := SYS.LSH(mark1,5-nr);
- x := (m-offs);
- buf:=Buffer(nr);
- buf:=SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,buf)+m);
- y:=buf^;
- err:=c.IntToStr(y,str,10,4," ");
- Print(rp,122,20,str);
- y := y DIV 4;
- g.SetAPen(rp,2); g.Move(rp,6,59-y); g.Draw(rp,313,59-y);
- IF (x>=0)&(x<=307) THEN g.Move(rp,SHORT(6+x),26);g.Draw(rp,SHORT(6+x),93) END;
- m := SYS.LSH(mark2,5-nr);
- x := (m-offs);
- buf:=Buffer(nr);
- buf:=SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,buf)+m);
- y:=buf^;
- err := c.IntToStr(y,str,10,4," ");
- Print(rp,176,20,str);
- y := y DIV 4;
- g.SetAPen(rp,0); g.Move(rp,6,59-y); g.Draw(rp,313,59-y);
- IF (x>=0)&(x<=307) THEN g.Move(rp,SHORT(6+x),26);g.Draw(rp,SHORT(6+x),93) END;
- END;
- buf := Buffer(nr);
-
- buf:=SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,buf)+offs);
-
- g.SetAPen(rp,3);
- i:=0;WHILE i<=307 DO
- IF i < BufLen(nr) THEN
- j := 59 - LONG(buf^) DIV 4;
- IF i=0 THEN g.Move(rp,i+6,j) ELSE g.Draw(rp,i+6,j) END;
- buf:=SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,buf)+1);
- END;
- INC(i)
- END;
- END Plot;
-
- (*···············································*)
-
- PROCEDURE GetLoop;
- BEGIN
- mark1:=oneShotHi;
- mark2:=mark1+repeatHi;
- IF mark1=lenHi THEN mark1:=0;mark2:=0 END;
- END GetLoop;
-
- (*···············································*)
-
- PROCEDURE SetLoop;
- VAR i : INTEGER;
- BEGIN
- IF mark1 >= lenHi THEN mark1:=lenHi-2 END;
- IF mark2 >= lenHi THEN mark2:=lenHi-2 END;
- IF (mark1=0) & (mark2=0) THEN
- oneShotHi := lenHi; repeatHi := 0;
- RETURN
- END;
- IF mark1<mark2 THEN oneShotHi:=mark1 ELSE oneShotHi:=mark2 END;
- repeatHi := ABS(mark1-mark2);
- END SetLoop;
-
- (*···············································*)
-
- PROCEDURE SetBuf;
- VAR hBody : LONGINT;
- i : INTEGER;
- BEGIN
- offs := 0;
- IF BufLen(nr) < 600 THEN
- hBody := 65535
- ELSE
- hBody := 19000000 DIV (BufLen(nr)-308);
- END;
- I.NewModifyProp(gadOffs^,win2,NIL,pfH,0,0,hBody,0,1);
- i := 1; WHILE i <= 5 DO
- IF i=nr THEN g.SetAPen(rp,3) ELSE g.SetAPen(rp,1) END;
- Frame(rp,i*16+49,107,14,14);
- Frame(rp,i*16+48,107,16,15);
- INC(i) END
- END SetBuf;
-
- (*···············································*)
-
- BEGIN (* SetLoop *)
- IF soundBuf=NIL THEN
- IF Request("No buffer","","Cancel") THEN END;
- RETURN;
- END;
- win2 := is.CreateWindow("Set Loop",0,50,320,126,scr,
- LONGSET{I.activate,I.windowClose,I.windowDrag,I.windowDepth,I.rmbTrap},
- LONGSET{I.gadgetUp,I.gadgetDown,I.closeWindow,I.mouseButtons},NIL);
- ip.Normal(win2);
- LockWindow(win);
- ip.Busy(win);
- rp := win2.rPort;
- Box(rp,0,11,320,115,TRUE,1); Box(rp,5,25,310,70,FALSE,-1);
- IF gadClr=NIL THEN gadClr:=is.CreateBoolGadget(CL,256,108,46,12,"",NIL,NIL,is.stdGad,is.stdAct) END;
- Box(rp,256,108,46,12,TRUE,-1);
- Print(rp,259,116,"Clear");
- is.AddGadget(win2,gadClr);
- Print(rp,220,116,"Loop");
-
- FOR i:=1 TO 5 DO
- IF gadBuf[i]=NIL THEN gadBuf[i]:=is.CreateBoolGadget(B1+i-1,50+i*16,108,12,12,"",NIL,NIL,is.stdGad,is.stdAct) END;
- Box(rp,50+i*16,108,12,12,TRUE,-1);
- is.AddGadget(win2,gadBuf[i]);
- END;
- Print(rp,12,116,"Octave");
- Print(rp,68,116,"1 2 3 4 5");
-
- IF gadOffs=NIL THEN gadOffs:=is.CreatePropGadget(OS,10,98,300,6,0,0,SYS.ADR(knobPlot),I.gadgHNone,is.stdAct,pfH) END;
- is.AddGadget(win2,gadOffs);
- I.RefreshGadgets(gadClr,win2,NIL);
- pip := gadOffs^.specialInfo;
- nr:=1;
- SetBuf;
- GetLoop;
- Plot;
- LOOP
- is.GetIMsg(win2,mes,TRUE);
- IF I.gadgetUp IN mes.class THEN
- sGad := mes.iAddress; id := sGad^.gadgetID;
- CASE id OF
- | B1..B5 : nr:=id-B1+1; GetLoop; SetBuf; Plot;
- | CL : mark1:=0; mark2:=0; SetLoop; Plot;
- ELSE
- END
- END;
- IF I.closeWindow IN mes.class THEN EXIT END;
- IF I.mouseButtons IN mes.class THEN
- mx := mes.mouseX-6;
- IF (mx>=0)&(mx<=307)&(mes.mouseY<95) THEN
- CASE mes.code OF
- I.selectDown: mark1:=2*SYS.LSH(offs+mx,nr-6); SetLoop; Plot|
- I.menuDown : mark2:=2*SYS.LSH(offs+mx,nr-6); SetLoop; Plot
- ELSE
- END;
- END;
- END;
- IF (I.gadgetDown IN mes.class) & (mes.iAddress=gadOffs) THEN
- LOOP
- is.GetIMsg(win2,mes,FALSE);
- last:=offs;
- offs := ENTIER(I.UIntToLong(pip^.horizPot)/65535.0 * (BufLen(nr)-308));
- IF offs > BufLen(nr)-308 THEN offs := BufLen(nr)-308 END;
- IF offs < 0 THEN offs := 0 END;
- IF offs#last THEN Plot END;
- IF I.gadgetUp IN mes.class THEN EXIT END;
- d.Delay(5);
- END
- END
- END;
- UnLockWindow(win);
- ip.Normal(win);
- is.DeleteWindow(win2); win2:=NIL
- END SetLoop;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE FourierAnalysis;
-
- VAR
- rp : g.RastPortPtr;
- mes : I.IntuiMessage;
- buf : UNTRACED POINTER TO ARRAY 50000 OF SHORTINT;
- f : ARRAY 64 OF REAL;
- max : REAL;
- i,k,inc,argA,argB,wert,h : INTEGER;
- a,b,bufArg,bufInc : LONGINT;
-
- BEGIN
- (* $RangeChk- $OvflChk- $NilChk- *)
- IF soundBuf=NIL THEN
- IF Request("No buffer","","Cancel") THEN END;
- RETURN;
- END;
- IF repeatHi=0 THEN
- IF Request("No loop","","Cancel") THEN END;
- RETURN;
- END;
- win2 := is.CreateWindow("Fourier-Analysis",20,50,280,116,scr,
- LONGSET{I.activate,I.windowClose,I.windowDrag,I.windowDepth},
- LONGSET{I.closeWindow},NIL);
- ip.Normal(win2);
- ip.Busy(win);
- LockWindow(win);
- rp := win2.rPort;
- Box(rp,0,11,280,105,TRUE,1); Box(rp,5,15,270,95,FALSE,-1);
- g.SetAPen(rp,2);
- buf := SYS.VAL(SYS.ADDRESS,SYS.VAL(LONGINT,soundBuf) + oneShotHi * 16);
- bufInc := repeatHi * 16 * 65536 DIV 128;
- inc := 64;
- max := 0;
- k := 1; WHILE k < 64 DO
- argA := 0;
- argB := 2048;
- bufArg := 0;
- a := 0; b := 0;
- i := 0; WHILE i < 128 DO
- wert := buf[SHORT(SYS.ROT(bufArg,-16))];
- INC(a,wert * sinTab[argA MOD 8192]);
- INC(b,wert * sinTab[argB MOD 8192]);
- INC(argA,inc);
- INC(argB,inc);
- INC(bufArg,bufInc);
- INC(i) END;
- f[k] := trans.Sqrt(a*1.0*a + b*1.0*b);
- IF f[k] > max THEN max := f[k] END;
- INC(inc,64);
- INC(k) END;
- IF max <= 1.0E-8 THEN max := 1 END;
- k := 1; WHILE k < 64 DO
- h := SHORT(ffp.Fix(f[k] / max * 80.0 + 0.5));
- IF h <= 0 THEN h := 1 END;
- g.RectFill(rp,10+k*4,102-(h-1),10+2+k*4,102);
- INC(k) END;
- is.GetIMsg(win2,mes,TRUE);
- UnLockWindow(win);
- ip.Normal(win);
- is.DeleteWindow(win2); win2:=NIL;
- (* $RangeChk= $OvflChk= $NilChk= *)
- END FourierAnalysis;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetLine(l,m,c: INTEGER);
- BEGIN
- algo.line[l-1].mod:=SHORT(m-1);
- algo.line[l-1].car:=SHORT(c-1);
- END SetLine;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Refresh;
- BEGIN
- SetOp(0);
- SetREALGad(gadTsp,transp);
- SetLFO;
- SetRR;
- SetFeedback;
- SetFilter;
- SetMode;
- SetPer;
- GetMem;
- END Refresh;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SetName(name: ARRAY OF CHAR); (* $CopyArrays- *)
- VAR voicename: e.STRING;
- i: LONGINT;
- BEGIN
- COPY(name,voicename);
- FOR i := str.Length(voicename)-1 TO 0 BY -1 DO
- CASE voicename[i] OF ".": voicename[i] := 0X | ":","/": str.Delete(voicename,0,i+1); i := -1 ELSE END;
- END;
- WHILE str.Length(voicename) < 16 DO str.AppendChar(voicename," ") END;
- e.CopyMem(voicename,scrtitle[21],16);
- I.SetWindowTitles(win,-1,SYS.ADR(scrtitle));
- END SetName;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE Save8SVX(filePath:ARRAY OF CHAR): BOOLEAN; (* $CopyArrays- *)
-
- TYPE
- Voice8Header = STRUCT
- oneShotHiSamples : LONGINT;
- repeatHiSamples : LONGINT;
- samplesPerHiCycle : LONGINT;
- samplesPerSec : INTEGER;
- ctOctave,sCompression : SHORTINT;
- volume : STRUCT hi,lo: INTEGER END;
- END;
-
- VAR
- vhdr : Voice8Header;
- bodySize : LONGINT;
- ok : BOOLEAN;
- i : INTEGER;
- size : LONGINT;
- len : LONGINT;
- buf : UNTRACED POINTER TO SYS.BYTE;
-
- BEGIN
- IF soundBuf=NIL THEN RETURN FALSE END;
-
- file := d.Open(filePath,d.oldFile);
- IF file#NIL THEN
- d.OldClose(file);
- IF ~Request("Overwrite file?","Ok","Cancel") THEN RETURN TRUE END;
- END;
-
- bodySize := (oneShotHi+repeatHi) * 31;
- file := d.Open(filePath,d.newFile);
- IF file=NIL THEN RETURN FALSE END;
- vhdr.oneShotHiSamples := oneShotHi;
- vhdr.repeatHiSamples := repeatHi;
- vhdr.samplesPerHiCycle := 0;
- vhdr.samplesPerSec := 8363;
- vhdr.ctOctave := 5;
- vhdr.sCompression := 0;
- vhdr.volume.hi := 1; vhdr.volume.lo := 0;
- ip.Busy(win);
- LOOP
- size := 4 + SIZE(vhdr)+8 + 22+8 + bodySize+8;
- IF (d.Write(file,"FORM",4)<4) OR
- (d.Write(file,size,4) <4) OR
- (d.Write(file,"8SVX",4)<4) THEN EXIT END;
- size := SIZE(vhdr);
- IF (d.Write(file,"VHDR",4)<4) OR
- (d.Write(file,size,4) <4) OR
- (d.Write(file,vhdr,SIZE(vhdr))<SIZE(vhdr)) THEN EXIT END;
- size := 22;
- IF (d.Write(file,"ANNO",4)<4) OR
- (d.Write(file,size,4) <4) OR
- (d.Write(file,"Generated by FMsynth\o\o",22)<22) THEN EXIT END;
- IF (d.Write(file,"BODY",4) <4) OR
- (d.Write(file,bodySize,4)<4) THEN EXIT END;
- i := 5; WHILE i >= 1 DO
- buf := Buffer(i);
- len := SYS.LSH(repeatHi+oneShotHi,5-i);
- IF d.Write(file,buf^,len) < len THEN EXIT END;
- DEC(i) END;
- ip.Normal(win);
- d.OldClose(file);
- RETURN TRUE;
- END;
- ip.Normal(win);
- d.OldClose(file);
- RETURN FALSE
- END Save8SVX;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SaveVoice(filePath:ARRAY OF CHAR):BOOLEAN; (* $CopyArrays- *)
-
- VAR i : INTEGER;
-
- PROCEDURE Write(dat: ARRAY OF SYS.BYTE): BOOLEAN; (* $CopyArrays- *)
- BEGIN RETURN d.Write(file,dat,LEN(dat)) < LEN(dat) END Write;
-
- BEGIN
- file := d.Open(filePath,d.oldFile);
- IF file#NIL THEN
- d.OldClose(file);
- IF ~Request("Overwrite file?","Ok","Cancel") THEN RETURN TRUE END;
- END;
-
- file := d.Open(filePath,d.newFile);
- IF file=NIL THEN RETURN FALSE END;
- ip.Busy(win);
- LOOP
- IF d.Write(file,"FMsy",4) < 4 THEN EXIT END;
- IF d.Write(file," 1.0",4) < 4 THEN EXIT END;
- FOR i := 0 TO 5 DO
- IF Write(op[i]) THEN EXIT END;
- END;
- IF Write(oneShotHi) OR
- Write(repeatHi) OR
- Write(algo) OR
- Write(lfo) OR
- Write(transp) OR
- Write(soundLen) OR
- Write(feedback) OR
- Write(filter) OR
- Write(mode) OR
- Write(Per) OR
- Write(rRate) THEN EXIT
- END;
- ip.Normal(win);
- d.OldClose(file);
- SetName(filePath);
- RETURN TRUE;
- END;
- d.OldClose(file);
- ip.Normal(win);
- RETURN FALSE;
- END SaveVoice;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE LoadVoice(filePath:ARRAY OF CHAR):BOOLEAN; (* $CopyArrays- *)
- VAR i : INTEGER;
- head: LONGINT;
-
- PROCEDURE Read(VAR dat: ARRAY OF SYS.BYTE): BOOLEAN;
- BEGIN RETURN d.Read(file,dat,LEN(dat)) < LEN(dat) END Read;
-
- BEGIN
- file := d.Open(filePath,d.oldFile);
- IF file=NIL THEN RETURN FALSE END;
- ip.Busy(win);
- LOOP
- IF d.Read(file,head,4) < 4 THEN EXIT END;
- IF head # SYS.VAL(LONGINT,"FMsy") THEN EXIT END;
- IF d.Read(file,head,4) < 4 THEN EXIT END;
- IF head # SYS.VAL(LONGINT," 1.0") THEN EXIT END;
-
- FOR i:=0 TO 5 DO
- IF Read(op[i]) THEN EXIT END;
- END;
- IF Read(oneShotHi) OR
- Read(repeatHi) OR
- Read(algo) OR
- Read(lfo) OR
- Read(transp) OR
- Read(soundLen) OR
- Read(feedback) OR
- Read(filter) OR
- Read(mode) OR
- Read(Per) OR
- Read(rRate) THEN EXIT
- END;
- ip.Normal(win);
- Refresh;
- d.OldClose(file);
- SetName(filePath);
- ResetChord;
- RETURN TRUE;
- END;
- d.OldClose(file);
- ip.Normal(win);
- Refresh;
- RETURN FALSE;
- END LoadVoice;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE New;
- VAR i: INTEGER;
- BEGIN
- FOR i:=0 TO 5 DO InitOp(i) END;
- algo.numLines := 0;
- transp := 1.0;
- shiftOct := 0;
- lfo.wave:=sin; lfo.spd:=0; lfo.del:=0; lfo.amd:=0; lfo.pmd:=0;
- lastWas:=none; flag:=FALSE;
- opNr:=0;
- soundLen := 15996;
- Per := 226;
- rRate:=127;
- feedback:=0;
- filter:=FALSE;
- mode:=poly;
- Refresh;
- LoopsOff;
- scrtitle[13] := CHR(shiftOct+ORD("1"));
- SetName("Unnamed");
- ResetChord;
- END New;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE SoundStop;
- VAR ch: SHORTINT;
- BEGIN
- FOR ch := as.left0 TO as.left1 DO
- as.StopSound(ch);
- state[ch] := end;
- END
- END SoundStop;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE CheckMenu;
- VAR menuCode,menuNr,itemNr,subNr:INTEGER;
- item:I.MenuItemPtr;
- changed: BOOLEAN;
- BEGIN
- changed := FALSE;
- menuCode:=mes.code;
- WHILE menuCode # I.menuNull DO
- item := I.ItemAddress(menu^,menuCode);
- menuNr := I.MenuNum(menuCode);
- itemNr := I.ItemNum(menuCode);
- subNr := I.SubNum(menuCode);
- CASE menuNr OF
- | 0:
- IF (itemNr=0) & DoFileRequest("Load Voice",filePath) THEN
- IF ~LoadVoice(filePath) & Request("Can't load voice","","Cancel") THEN END;
- END;
- IF (itemNr=1) & DoFileRequest("Save Voice",filePath) THEN
- IF ~SaveVoice(filePath) & Request("Can't save voice","","Cancel") THEN END;
- END;
- IF (itemNr=2) & DoFileRequest("Save 8SVX",filePath) THEN
- IF ~Save8SVX(filePath) & Request("Can't save sound","","Cancel") THEN END;
- END;
- IF (itemNr=3) & Request("Are you sure?","Yes","No") THEN New END;
- IF (itemNr=5) & Request("Really quit?","Ok","Cancel") THEN SoundStop; HALT(0) END;
- | 1:
- IF itemNr=0 THEN InitOp(opNr); SetOp(opNr) END;
- IF (itemNr=1) & (subNr>=0) & (subNr<=5) THEN
- op[subNr] := op[opNr];
- changed := TRUE;
- END;
- IF itemNr=2 THEN
- CASE subNr OF
- | 0: IF op[opNr].freq <= 49999.0 THEN
- op[opNr].freq:=op[opNr].freq*2;SetREALGad(gadFreq,op[opNr].freq);
- changed := TRUE;
- END;
- | 1: IF op[opNr].freq >= 0.0002 THEN
- op[opNr].freq:=op[opNr].freq/2;SetREALGad(gadFreq,op[opNr].freq);
- changed := TRUE;
- END;
- ELSE
- END
- END;
- | 2:
- IF itemNr=0 THEN
- CASE subNr OF
- | 0: algo.numLines:=0;
- | 1: algo.numLines:=3; SetLine(1,2,1); SetLine(2,4,3); SetLine(3,6,5);
- | 2: algo.numLines:=4; SetLine(1,2,1); SetLine(2,3,2); SetLine(3,5,4); SetLine(4,6,5);
- | 3: algo.numLines:=4; SetLine(1,2,1); SetLine(2,3,1); SetLine(3,4,3); SetLine(4,6,5);
- | 4: algo.numLines:=4; SetLine(1,2,1); SetLine(2,3,2); SetLine(3,4,2); SetLine(4,6,5);
- | 5: algo.numLines:=4; SetLine(1,2,1); SetLine(2,3,2); SetLine(3,4,3); SetLine(4,6,5);
- | 6: algo.numLines:=4; SetLine(1,2,1); SetLine(2,3,2); SetLine(3,5,4); SetLine(4,6,4);
- | 7: algo.numLines:=4; SetLine(1,2,1); SetLine(2,6,3); SetLine(3,6,4); SetLine(4,6,5);
- | 8: algo.numLines:=4; SetLine(1,2,1); SetLine(2,3,1); SetLine(3,5,4); SetLine(4,6,4);
- | 9: algo.numLines:=5; SetLine(1,2,1); SetLine(2,3,2); SetLine(3,4,3); SetLine(4,5,4); SetLine(5,6,5);
- ELSE
- END;
- DrawAlgo;
- changed := TRUE;
- END;
- IF itemNr=1 THEN
- IF (subNr >= 0) & (subNr < numChords) THEN chord := subNr END;
- END;
- IF itemNr=2 THEN SetLoop END;
- IF itemNr=3 THEN FourierAnalysis END;
- IF itemNr=4 THEN autoCalc := I.checked IN item.flags END;
- ELSE
- END;
- menuCode := item.nextSelect
- END;
- IF changed & autoCalc THEN CalcSound() END;
- END CheckMenu;
-
- (*------------------------------------------------------------------------*)
-
- (* $SaveRegs+ $StackChk- *)
-
- PROCEDURE InterruptProc;
- VAR volMod : INTEGER;
- perMod : INTEGER;
- ch : SHORTINT;
- BEGIN
- (* $NilChk- $OvflChk- $RangeChk- *)
- SYS.SETREG(13,SYS.REG(9));
- IF ~disabled THEN
- FOR ch:=as.left0 TO as.left1 DO
- IF delay[ch]>0 THEN DEC(delay[ch]) END;
- IF state[ch] # end THEN
- IF state[ch] = keyUp THEN
- vol[ch] := vol[ch]-deltaVol;
- IF vol[ch] <= 0.0 THEN
- vol[ch] := 0.0;
- state[ch] := end;
- END;
- END;
- volTemp := vol[ch];
- perTemp := per[ch];
- IF delay[ch]=0 THEN
- INC(lfoArg[ch],lfoInc);
- END;
- IF lfo.amd>0 THEN (* Modulate volume *)
- volTemp := volTemp * (1.0-lfo.amd*((128+LONG(lfoTab[SYS.LSH(lfoArg[ch],-8)]))/32768.0));
- END;
- IF lfo.pmd>0 THEN (* Modulate period *)
- perTemp := perTemp * (1.0+lfo.pmd*((128+LONG(lfoTab[SYS.LSH(lfoArg[ch],-8)]))/maxPM));
- END;
- volMod := SHORT(ffp.Fix(volTemp+0.5));
- perMod := SHORT(ffp.Fix(perTemp+0.5));
-
- as.ModifySound(ch,perMod,volMod);
- END;
- END;
- END;
- (* $NilChk= $OvflChk= $RangeChk= *)
- END InterruptProc;
-
- (* $StackChk= *)
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE HandleVertGad(gad: I.GadgetPtr; new:BOOLEAN): SHORTINT;
- VAR val: INTEGER;
- BEGIN
- val := 127-is.VertPot(gad,128);
- IF new THEN is.SetProp(gad,win,NIL,0,127-val,0,128) END;
- ShowPot(rp,gad);
- RETURN SHORT(val);
- END HandleVertGad;
-
- (*------------------------------------------------------------------------*)
-
- PROCEDURE HandleHorizGad(gad: I.GadgetPtr): SHORTINT;
- VAR val: INTEGER;
- BEGIN
- val := is.HorizPot(gad,128);
- is.SetProp(gad,win,NIL,val,0,128,0);
- RETURN SHORT(val);
- END HandleHorizGad;
-
- (*------------------------------------------------------------------------*)
-
- BEGIN
-
- (*
- win:=NIL; win2:=NIL; scr:=NIL; menu:=NIL; req:=NIL;
- gadOffs:=NIL; gadClr:=NIL;
- soundBuf := NIL; soundLen := 0;
- intOn:=FALSE;
- FOR i:=1 TO 5 DO gadBuf[i]:=NIL END;
- *)
- SYS.SETREG(0,SYS.ADR(ver));
- me := SYS.VAL(SYS.ADDRESS,ol.Me);
- oldWindowPtr := me.windowPtr;
- oldfltstate := as.CheckFilter();
-
- IF ol.OldSP.stackSize<4000 THEN HALT(d.error) END;
-
- lfoPic := ToChipMem(SYS.VAL(SYS.ADDRESS,LFOPics),16,FALSE);
- mixPic := ToChipMem(SYS.VAL(SYS.ADDRESS,MixPics),12,FALSE);
- lfoImg := is.CreateImage(0,0,16,8,1,lfoPic^,SHORTSET{1},SHORTSET{0},NIL);
- mixImg := is.CreateImage(0,0,16,6,1,mixPic^,SHORTSET{1},SHORTSET{0},NIL);
- fmPic := ToChipMem(SYS.VAL(SYS.ADDRESS,FMPic),864,TRUE);
- fmImg := is.CreateImage(27,0,117,27,2,fmPic^,SHORTSET{0,1},SHORTSET{},NIL);
- zifPic := ToChipMem(SYS.VAL(SYS.ADDRESS,Ziffern),10,FALSE);
- zifImg := is.CreateImage(0,0,2,5,1,zifPic^,SHORTSET{1},SHORTSET{0},NIL);
-
- as.SetPriority(20);
- IF (as.OpenChannel({as.left0 })<0) OR
- (as.OpenChannel({as.right0})<0) OR
- (as.OpenChannel({as.right1})<0) OR
- (as.OpenChannel({as.left1 })<0) THEN rq.Fail("Can't open audio channel") END;
-
-
- SetUpScreen;
- New;
- SetKeys;
-
- int.node.type := e.interrupt;
- int.node.pri := 0;
- int.node.name := NIL;
- int.data := SYS.REG(13);
- int.code := InterruptProc;
-
- SoundStop;
- chan:=as.left0;
-
- cia.base := e.OpenResource(cia.ciaaName);
- rq.Assert(cia.base # NIL,"Can't open ciaa.resource");
-
- rq.Assert(cia.AddICRVector(hw.ta,SYS.ADR(int))=NIL,"CIAA Timer A in use");
- hw.ciaa.cra := SHORTSET{};
- intOn:=TRUE;
-
- SetTimer(TRUE);
-
- is.msgFilter := LONGSET{I.mouseMove};
-
- LOOP
- is.GetIMsg(win,mes,TRUE);
-
- IF (I.rawKey IN mes.class) & ~(ie.repeat IN mes.qualifier) THEN
- code := mes.code;
- CASE code OF
- 64: SoundStop| (* Space *)
- 80..84: shiftOct := code-80; (* F1 - F5 *)
- scrtitle[13] := CHR(shiftOct+ORD("1"));
- I.SetWindowTitles(win,-1,SYS.ADR(scrtitle))|
- ELSE
- IF code<128 THEN (* Key down *)
- keyCode := key[code];
- IF keyCode >= 0 THEN
- octave := keyCode DIV 12 + shiftOct + 1;
- IF (octave<=5) & (soundBuf # NIL) THEN
- disabled := TRUE;
- per[chan] := period[keyCode];
- vol[chan] := 64.0;
- delay[chan] := LONG(lfo.del) * 2;
- lfoArg[chan]:= 0;
- perTemp := per[chan];
- volTemp := vol[chan];
- IF lfo.amd>0 THEN
- volTemp := volTemp * (1.0-lfo.amd*((128+LONG(lfoTab[0]))/32768.0));
- END;
- IF lfo.pmd>0 THEN
- perTemp := perTemp * (1.0+lfo.pmd*((128+LONG(lfoTab[0]))/maxPM));
- END;
- as.PlayLoopSound(chan,Buffer(octave),SYS.LSH(oneShotHi,5-octave),SYS.LSH(repeatHi,5-octave),SHORT(ffp.Fix(perTemp+0.5)),SHORT(ffp.Fix(volTemp+0.5)));
- state[chan] := keyDown;
- channel[keyCode] := chan;
- disabled := FALSE;
-
- IF mode=poly THEN
- CASE chan OF
- | as.left0: chan:=as.right0
- | as.right0: chan:=as.left1
- | as.right1: chan:=as.left0
- | as.left1: chan:=as.right1
- END;
- END;
- MarkKey(keyCode+shiftOct*12,TRUE);
- END
- END
- ELSE (* Key up *)
- keyCode := key[code-128];
- IF keyCode >= 0 THEN
- state[channel[keyCode]] := keyUp;
- MarkKey(keyCode+shiftOct*12,FALSE);
- END
- END
- END
-
- ELSIF I.menuPick IN mes.class THEN CheckMenu
-
- ELSIF I.mouseMove IN mes.class THEN
- IF (actPropGad # NIL) & (HandleVertGad(actPropGad,FALSE)=0) THEN END;
-
- ELSIF I.gadgetDown IN mes.class THEN
- actPropGad := mes.iAddress;
-
- ELSIF I.gadgetUp IN mes.class THEN
- selGad:=mes.iAddress; id:=selGad.gadgetID;
- CASE id OF
- | O1..O6: opNr := SHORT(id-O1);SetOp(opNr);
- | R1..R4: op[opNr].r[id-R1] := HandleVertGad(gadEG[id-R1],TRUE);
- IF autoCalc THEN CalcSound END;
- | L1..L4: op[opNr].l[id-L1] := HandleVertGad(gadEG[id-R1],TRUE);
- IF autoCalc THEN CalcSound END;
-
- | OL: op[opNr].outp := HandleVertGad(gadOutp,TRUE);
- IF autoCalc THEN CalcSound END;
-
- | SL: op[opNr].scL := HandleVertGad(gadScL,TRUE);
- IF autoCalc THEN CalcSound END;
-
- | SR: op[opNr].scR := HandleVertGad(gadScR,TRUE);
- IF autoCalc THEN CalcSound END;
-
- | FR: GetREALGad(gadFreq,op[opNr].freq);
- SetREALGad(gadFreq,op[opNr].freq);
- IF autoCalc THEN CalcSound END;
-
- | TP: GetREALGad(gadTsp,transp);
- SetREALGad(gadTsp,transp);
- IF autoCalc THEN CalcSound END;
-
- | M1..M6:
- lastMod := SHORT(id-M1);
- IF flag THEN
- IF lastWas=car THEN
- CheckLine(lastMod,lastCar);
- DrawAlgo;
- flag := FALSE;
- IF autoCalc THEN CalcSound END;
- END;
- ELSE
- flag := TRUE
- END;
- lastWas := mod;
- | C1..C6:
- lastCar := SHORT(id-C1);
- IF flag THEN
- IF lastWas=mod THEN
- CheckLine(lastMod,lastCar);
- DrawAlgo;
- flag := FALSE;
- IF autoCalc THEN CalcSound END;
- END;
- ELSE
- flag := TRUE
- END;
- lastWas := car;
- | WA: NextLFOWave;
- | SP: lfo.spd := HandleHorizGad(gadLFOs);
- lfoInc := (LONG(lfo.spd)+1)*64;
- | DE: lfo.del := HandleHorizGad(gadLFOd)
- | AM: lfo.amd := HandleHorizGad(gadLFOa)
- | PM: lfo.pmd := HandleHorizGad(gadLFOp)
- | CS: IF autoCalc THEN
- autoCalc := FALSE; CalcSound(); autoCalc := TRUE;
- ELSE
- CalcSound();
- END;
- | RR: rRate := SHORT(127-is.HorizPot(gadRel,128)); SetRR;
- | LN: soundLen := is.GadgetVal(gadLen); GetMem; LoopsOff;
- | FB: feedback := SHORT(SHORT(is.GadgetVal(gadFeed))); SetFeedback;
- IF autoCalc THEN CalcSound END;
-
- | OM: IF op[opNr].mode=ratio THEN
- op[opNr].mode:=fixed
- ELSE
- op[opNr].mode:=ratio
- END;
- SetOp(opNr);
- IF autoCalc THEN CalcSound END;
-
- | PR: Per := SHORT(is.GadgetVal(gadPer)); SetPer;
- | MD: IF mode=poly THEN mode := mono ELSE mode:=poly END; SetMode;
- | FL: filter := ~ filter; SetFilter;
- ELSE
- END
-
- END
- END;
-
- CLOSE
-
- me.windowPtr := oldWindowPtr;
- IF intOn THEN SetTimer(FALSE); cia.RemICRVector(hw.ta,SYS.ADR(int)) END;
- is.DeleteWindow(win);
- IF is.DeleteScreen(scr) THEN END;
- as.Filter(oldfltstate);
-
- END FMsynth.
-
-