home *** CD-ROM | disk | FTP | other *** search
/ Sound Sensations! / sound_sensations.iso / synth / synzap10 / sz.pas < prev    next >
Pascal/Delphi Source File  |  1990-04-15  |  32KB  |  945 lines

  1. { S Z . P A S
  2.   ===========
  3.   Synthe-Zap! timbre editor for Ad Lib* instrument files.
  4.  
  5.   Copyright (C) 1990 by J Meeks & Machina Sapiens.
  6.  
  7.   * Ad Lib is a trademark of Ad Lib, Inc.
  8.  
  9.   Thanks to Matthew Cooley for providing the format of the .INS file!
  10.  
  11.   Written using Turbo Pascal 5.5 by J Meeks, 03-03-90. }
  12.  
  13.  
  14.  
  15. program SZ;
  16.  
  17.  
  18. { The following directive ought to define Shareware to compile the fully
  19.   functional, registered version of Synthe/Zap!.  To compile the demo version
  20.   (without the ability to save instruments), instead define Demonstration. }
  21.  
  22. (*
  23. {$Define Shareware}
  24. *)
  25. {$Define Demonstration}
  26.  
  27. {$I Switches.Inc}
  28.  
  29.  
  30. uses
  31.   CRT, Graph, Printer,
  32.   JUtility, JString, JVideo, JGraph, JKeybd, JMouse, JPlaque, JButton, JKnob,
  33.   JFieldGr, JFile, JAdLib;
  34.  
  35.  
  36.  
  37. const
  38.   TestPitch:       array [1.. 2, 0.. 12] of PitchStr =
  39.                     (('c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'D', 'E', 'F',
  40.                       'G', 'A'),
  41.                      ('e``', 'f``', 'g``', 'a``', 'b``', 'c`', 'd`', 'e`',
  42.                       'f`', 'g`', 'a`', 'b`', 'c'));
  43.  
  44.  
  45. var
  46.   StafX0,
  47.   StafY0:          word;
  48.  
  49.   LastInstr:       Str8;
  50.  
  51.   LastLoadDef,
  52.   InstrDef:        DrvDataDescr;
  53.  
  54.   FirstLoad:       boolean;
  55.  
  56.   CurrClef:        byte;
  57.   UnderClef:       pointer;
  58.  
  59.   IntroPlq,
  60.   MainPlq:         Plaque;
  61.  
  62.   CarrBx,
  63.   ModuBx,
  64.   NameBx,
  65.   ModeBx,
  66.   StafBx,
  67.   VoicBx:          GrooveBox;
  68.  
  69.   CAttackRateKnb,
  70.   CDecayRateKnb,
  71.   CSustainLevKnb,
  72.   CReleaseRateKnb,
  73.   CFreqMultipKnb,
  74.   COutputLevelKnb,
  75.   CLevelScalKnb,
  76.   MAttackRateKnb,
  77.   MDecayRateKnb,
  78.   MSustainLevKnb,
  79.   MReleaseRateKnb,
  80.   MFreqMultipKnb,
  81.   MModFeedbackKnb,
  82.   MOutputLevelKnb,
  83.   MLevelScalKnb:   KnobLined;
  84.  
  85.   StopBtn:         OctagonButton;
  86.  
  87.   CSustainSndBtn,
  88.   CEnvScalingBtn,
  89.   CVibratoBtn,
  90.   CTremoloBtn,
  91.   MSustainSndBtn,
  92.   MEnvScalingBtn,
  93.   MVibratoBtn,
  94.   MTremoloBtn:     OnOffButton;
  95.  
  96.   NameBtn,
  97.   ModeBtn,
  98.   VoicBtn,
  99.   ClefBtn:         Button;
  100.  
  101.   NoteBtn:         array [0.. 12] of Button;
  102.  
  103.   CurrMode,
  104.   CurrVoice:       integer;
  105.  
  106.   I:               byte;
  107.   Key:             char;
  108.  
  109.  
  110.  
  111.  
  112. procedure DrawNote (I, LocX, LocY: word; Color: ScrnColor);
  113. var
  114.   NoteChar:        char;
  115.   SaveTextSet:     TextSettingsType;
  116.   SaveColor:       ScrnColor;
  117. begin
  118.   GetTextSettings (SaveTextSet);
  119.   SaveColor := GetColor;
  120.   SetTextJustify (LeftText, TopText);
  121.   SetTextStyle (DefaultFont, HorizDir, 1);
  122.   SetTextStyle (TriplexFont, HorizDir, 4);
  123.   SetColor (Color);
  124.   if (I <= 5) then
  125.     NoteChar := 'π'
  126.   else
  127.     NoteChar := 'Φ';
  128.   OutTextXY (LocX + 25 + 13 * I, LocY + 6 - 2 * I, NoteChar);
  129.   SetTextStyle (SaveTextSet.Font, SaveTextSet.Direction, SaveTextSet.CharSize);
  130.   SetTextJustify (SaveTextSet.Horiz, SaveTextSet.Vert);
  131.   SetColor (SaveColor);
  132. end;    { procedure DrawNote. }
  133.  
  134.  
  135.  
  136. procedure DrawClef (LocX, LocY: word; Color: ScrnColor);
  137. var
  138.   SaveTextSet:     TextSettingsType;
  139.   SaveColor:       ScrnColor;
  140. begin
  141.   GetTextSettings (SaveTextSet);
  142.   SaveColor := GetColor;
  143.   SetTextJustify (LeftText, TopText);
  144.   SetTextStyle (DefaultFont, HorizDir, 1);
  145.   SetTextStyle (TriplexFont, HorizDir, 4);
  146.   SetColor (Color);
  147.   case CurrClef of
  148.     Treble: OutTextXY (LocX + 5, LocY, '∩');
  149.     Bass:   OutTextXY (LocX + 5, LocY, 'ε');
  150.   end;
  151.   SetTextStyle (SaveTextSet.Font, SaveTextSet.Direction, SaveTextSet.CharSize);
  152.   SetTextJustify (SaveTextSet.Horiz, SaveTextSet.Vert);
  153.   SetColor (SaveColor);
  154. end;    { procedure DrawClef. }
  155.  
  156.  
  157.  
  158. { Display staff with G clef and notes user can use to play simple tunes for
  159.   testing the timbre being edited. }
  160.  
  161. procedure DrawStaff (LocX, LocY: word);
  162. var
  163.   SaveTextSet:     TextSettingsType;
  164.   SaveColor:       ScrnColor;
  165. begin
  166.   GetTextSettings (SaveTextSet);
  167.   SaveColor := GetColor;
  168.   SetTextJustify (LeftText, TopText);
  169.   SetTextStyle (DefaultFont, HorizDir, 1);
  170.   SetTextStyle (TriplexFont, HorizDir, 4);
  171.   { Staff & end bars. }
  172.   SetColor (LightBlue);
  173.   OutTextXY (LocX, LocY, '≡≡≡≡≡');
  174.   OutTextXY (LocX, LocY, '±');
  175.   OutTextXY (LocX + 200, LocY, '±');
  176.   { Ledger lines. }
  177.   HorzLine (LocX + 22, LocX + 36, LocY + 35);
  178.   HorzLine (LocX + 178, LocX + 192, LocY + 11);
  179.   { Save area that will be covered by clef (save this one time, then restore
  180.     every time a new clef needs to be drawn). }
  181.   GetMem (UnderClef, ImageSize (LocX + 5, LocY + 9, LocX + 18, LocY + 36));
  182.   GetImage (LocX + 5, LocY + 9, LocX + 19, LocY + 36, UnderClef^);
  183.   { Now draw clef. }
  184.   SetColor (Yellow);
  185.   OutTextXY (LocX + 5, LocY, '∩');
  186.   ClefBtn.Create (LocX + 5, LocY + 9, 13, 27);
  187.   { Notes and their associated (invisible) buttons. }
  188.   for I := 0 to 12 do begin
  189.     DrawNote (I, LocX, LocY, LightCyan);
  190.     { Use 10 in the next-to-last (width) parameter of this Create for dead
  191.       zones between note-buttons, 13 for buttons that run right up to one
  192.       another. }
  193.     NoteBtn [I].Create (LocX + 24 + 13 * I, LocY + 21 - 2 * I,
  194.      10, 28);
  195.   end;
  196.   SetTextStyle (SaveTextSet.Font, SaveTextSet.Direction, SaveTextSet.CharSize);
  197.   SetTextJustify (SaveTextSet.Horiz, SaveTextSet.Vert);
  198.   SetColor (SaveColor);
  199. end;    { procedure DrawStaff. }
  200.  
  201.  
  202. procedure Setup;
  203. const
  204.   S1 =             5;
  205.   S2 =             8;
  206.   S3 =             0;
  207.   S4 =             8;
  208. begin
  209.   EndSession := False;
  210.   FirstLoad := True;
  211.   LastInstr := 'PIANO1';
  212.   FillChar (InstrDef, SizeOf (InstrDef), 0);
  213.   FillChar (LastLoadDef, SizeOf (LastLoadDef), 0);
  214.   { Set up graphics. }
  215.   LoadBGIFont ('TripMusi.Chr');
  216.   DummyInt := GraphSetup;
  217.   { Set up mouse. }
  218.   MouseBtn := InitMouse;
  219.   SetMouseLimits (5, 1, 629, 334);
  220.   SetMousePos (280, 200);
  221.   MouseGraphCursor (MouseUpLftHandCurs);
  222.   ClearTo (SolidFill, DarkGray);
  223.  
  224.   { Initialize main plaque. }
  225.   MainPlq.Init  (10, 10, 620, 330, 16, Blue, LightBlue, Black, PlqRound);
  226.  
  227.   { Initialize groove boxes and attach items. }
  228.   CarrBx.Init  (25,  85, 290, 246, LightBlue, Black, Blue, LightBlue,
  229.    'Carrier',   TxHLeft);
  230.  
  231.   ModuBx.Init  (325, 85, 290, 246, LightBlue, Black, Blue, LightBlue,
  232.    'Modulator', TxHLeft);
  233.  
  234.   NameBx.Init  (25,  20, 116, 22,  LightBlue, Black, Blue, LightBlue,
  235.    'Name',      TxHLeft);
  236.   NameBtn.AttachToBox (NameBx);
  237.  
  238.   ModeBx.Init  (25,  52, 102, 22,  LightBlue, Black, Blue, LightBlue,
  239.    'Mode',      TxHLeft);
  240.   ModeBtn.AttachToBox (ModeBx);
  241.  
  242.   VoicBx.Init  (142, 52, 78,  22,  LightBlue, Black, Blue, LightBlue,
  243.    'Voice',     TxHLeft);
  244.   VoicBtn.AttachToBox (VoicBx);
  245.  
  246.   StafBx.Init  (236, 20, 240, 54,  LightBlue, Black, Blue, LightBlue,
  247.    'Test Play', TxHLeft);
  248.   StafX0 := StafBx.X + 19;
  249.   StafY0 := StafBx.Y + 5;
  250.  
  251.   { Initialize knobs & buttons. }
  252.   StopBtn.Init          (585,     24,      24,   LightRed, Black, Red,
  253.    White, Red,   LightRed);
  254.  
  255.   with CarrBx do begin
  256.     CSustainSndBtn.Init (X + 26,  Y + 65,  0, 0, LightMagenta, Black, Magenta,
  257.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, True);
  258.     CEnvScalingBtn.Init (X + 26,  Y + 85,  0, 0, LightMagenta, Black, Magenta,
  259.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, True);
  260.     CVibratoBtn.Init    (X + 26,  Y + 200, 0, 0, LightMagenta, Black, Magenta,
  261.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, False);
  262.     CTremoloBtn.Init    (X + 26,  Y + 220, 0, 0, LightMagenta, Black, Magenta,
  263.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, False);
  264.     CAttackRateKnb.Init  (0.0,  15.0, 1,  -150, +150, 16, X + 45,  Y + 40,
  265.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  266.     CDecayRateKnb.Init   (0.0,  15.0, 1,  -150, +150, 16, X + 110, Y + 40,
  267.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  268.     CSustainLevKnb.Init  (0.0,  15.0, 1,  -150, +150, 16, X + 175, Y + 40,
  269.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  270.     CReleaseRateKnb.Init (0.0,  15.0, 1,  -150, +150, 16, X + 240, Y + 40,
  271.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  272.     CFreqMultipKnb.Init  (0.0,  15.0, 1,  -150, +150, 16, X + 75,  Y + 130,
  273.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  274.     COutputLevelKnb.Init (0.0,  63.0, 1,  -150, +150, 64, X + 75,  Y + 175,
  275.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  276.     CLevelScalKnb.Init   (0.0,  3.0,  1,  -150, +150, 4,  X + 175, Y + 175,
  277.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  278.   end;
  279.   with ModuBx do begin
  280.     MSustainSndBtn.Init (X + 26,  Y + 65,  0, 0, LightMagenta, Black, Magenta,
  281.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, True);
  282.     MEnvScalingBtn.Init (X + 26,  Y + 85,  0, 0, LightMagenta, Black, Magenta,
  283.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, True);
  284.     MVibratoBtn.Init    (X + 26,  Y + 200, 0, 0, LightMagenta, Black, Magenta,
  285.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, False);
  286.     MTremoloBtn.Init    (X + 26,  Y + 220, 0, 0, LightMagenta, Black, Magenta,
  287.      White, Magenta, LightMagenta, Black, 'On', 'Off', TxHLeft, False);
  288.     MAttackRateKnb.Init  (0.0,  15.0, 1,  -150, +150, 16, X + 45,  Y + 40,
  289.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  290.     MDecayRateKnb.Init   (0.0,  15.0, 1,  -150, +150, 16, X + 110, Y + 40,
  291.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  292.     MSustainLevKnb.Init  (0.0,  15.0, 1,  -150, +150, 16, X + 175, Y + 40,
  293.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  294.     MReleaseRateKnb.Init (0.0,  15.0, 1,  -150, +150, 16, X + 240, Y + 40,
  295.      27, LightGreen, Black, Green, White, LightGreen, Green, White);
  296.     MFreqMultipKnb.Init  (0.0,  15.0, 1,  -150, +150, 16, X + 75,  Y + 130,
  297.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  298.     MModFeedbackKnb.Init (0.0,  7.0,  1,  -150, +150, 8,  X + 175, Y + 130,
  299.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  300.     MOutputLevelKnb.Init (0.0,  63.0, 1,  -150, +150, 64, X + 75,  Y + 175,
  301.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  302.     MLevelScalKnb.Init   (0.0,  3.0,  1,  -150, +150, 4,  X + 175, Y + 175,
  303.      22, LightGreen, Black, Green, White, LightGreen, Green, White);
  304.   end;
  305.  
  306.   CurrClef := Treble;
  307.  
  308.   MainPlq.Refresh;
  309.  
  310.   NameBx.Draw;
  311.   ModeBx.Draw;
  312.   VoicBx.Draw;
  313.   StafBx.Draw;
  314.   CarrBx.Draw;
  315.   ModuBx.Draw;
  316.   StopBtn.Normal;
  317.   DrawStaff (StafX0, StafY0);
  318.  
  319.   CAttackRateKnb.Draw;
  320.   CAttackRateKnb.Labl  (TxHCenter, TxVTop, 0, S1, LightCyan, 'Attack');
  321.   CDecayRateKnb.Draw;
  322.   CDecayRateKnb.Labl   (TxHCenter, TxVTop, 0, S1, LightCyan, 'Decay');
  323.   CSustainLevKnb.Draw;
  324.   CSustainLevKnb.Labl  (TxHCenter, TxVTop, 0, S1, LightCyan, 'Sustain');
  325.   CReleaseRateKnb.Draw;
  326.   CReleaseRateKnb.Labl (TxHCenter, TxVTop, 0, S1, LightCyan, 'Release');
  327.   CFreqMultipKnb.Draw;
  328.   CFreqMultipKnb.Labl  (TxHCenter, TxVTop, 0, S4, LightCyan, 'Freq Mult');
  329.   COutputLevelKnb.Draw;
  330.   COutputLevelKnb.Labl (TxHCenter, TxVTop, 0, S4, LightCyan, 'Out Level');
  331.   CLevelScalKnb.Draw;
  332.   CLevelScalKnb.Labl   (TxHCenter, TxVTop, 0, S4, LightCyan, 'Lev Scale');
  333.  
  334.   CSustainSndBtn.Normal;
  335.   CSustainSndBtn.Labl (TxHRight, TxVCenter, S2, S3, LightCyan,
  336.    'Sustain Sound');
  337.   CEnvScalingBtn.Normal;
  338.   CEnvScalingBtn.Labl (TxHRight, TxVCenter, S2, S3, LightCyan,
  339.    'Envelope Scaling');
  340.   CVibratoBtn.Normal;
  341.   CVibratoBtn.Labl    (TxHRight, TxVCenter, S2, S3, LightCyan,
  342.    'Pitch Vibrato');
  343.   CTremoloBtn.Normal;
  344.   CTremoloBtn.Labl    (TxHRight, TxVCenter, S2, S3, LightCyan,
  345.    'Amplitude Tremolo');
  346.  
  347.   MAttackRateKnb.Draw;
  348.   MAttackRateKnb.Labl  (TxHCenter, TxVTop, 0, S1, LightCyan, 'Attack');
  349.   MDecayRateKnb.Draw;
  350.   MDecayRateKnb.Labl   (TxHCenter, TxVTop, 0, S1, LightCyan, 'Decay');
  351.   MSustainLevKnb.Draw;
  352.   MSustainLevKnb.Labl  (TxHCenter, TxVTop, 0, S1, LightCyan, 'Sustain');
  353.   MReleaseRateKnb.Draw;
  354.   MReleaseRateKnb.Labl (TxHCenter, TxVTop, 0, S1, LightCyan, 'Release');
  355.   MFreqMultipKnb.Draw;
  356.   MFreqMultipKnb.Labl  (TxHCenter, TxVTop, 0, S4, LightCyan, 'Freq Mult');
  357.   MModFeedbackKnb.Draw;
  358.   MModFeedbackKnb.Labl (TxHCenter, TxVTop, 0, S4, LightCyan, 'Mod Feedback');
  359.   MOutputLevelKnb.Draw;
  360.   MOutputLevelKnb.Labl (TxHCenter, TxVTop, 0, S4, LightCyan, 'Out Level');
  361.   MLevelScalKnb.Draw;
  362.   MLevelScalKnb.Labl   (TxHCenter, TxVTop, 0, S4, LightCyan, 'Lev Scale');
  363.  
  364.   MSustainSndBtn.Normal;
  365.   MSustainSndBtn.Labl (TxHRight, TxVCenter, S2, S3, LightCyan,
  366.    'Sustain Sound');
  367.   MEnvScalingBtn.Normal;
  368.   MEnvScalingBtn.Labl (TxHRight, TxVCenter, S2, S3, LightCyan,
  369.    'Envelope Scaling');
  370.   MVibratoBtn.Normal;
  371.   MVibratoBtn.Labl    (TxHRight, TxVCenter, S2, S3, LightCyan,
  372.    'Pitch Vibrato');
  373.   MTremoloBtn.Normal;
  374.   MTremoloBtn.Labl    (TxHRight, TxVCenter, S2, S3, LightCyan,
  375.    'Amplitude Tremolo');
  376.  
  377.   CurrVoice := 0;
  378.   ClrKeyBuffer;
  379.  
  380. {$IfDef Shareware}
  381.   IntroPlq.Init (96, 98, 438, 203, 16, Brown, Yellow, Black, PlqRound);
  382. {$Else}
  383.   IntroPlq.Init (96, 93, 438, 233, 16, Brown, Yellow, Black, PlqRound);
  384. {$EndIf}
  385.  
  386.   with IntroPlq do
  387.     if (MemAvail > ImageSize (X, Y, X2, Y2)) then begin
  388.       IntroPlq.Draw;
  389.       OutTextXYThk (X + 16, Y + 6,  'Machina Sapiens presents', 3,
  390.        2, White, Black, TriplexFont);
  391.       OutTextXYThk (X + 16, Y + 26, 'Synthe¡Zap!', 4,
  392.        4, White, Black, TriplexFont);
  393.       OutTextXYThk (X + 16, Y + 72,
  394.        'Instrument Editor for Ad Lib* music synthesizer', 2, 1, White, Black,
  395.        DefaultFont);
  396.       LineThk (X + 16, Y + 89, X2 - 14, Y + 89, 2, Yellow, Black);
  397.       Copyright    (X + 16, Y + 97,  '1990 by J Meeks & Machina Sapiens',
  398.        2, White, Black);
  399.       SetColor (Yellow);
  400.       OutTextXY (X + 16, Y + 112,
  401.        '* Ad Lib is a trademark of Ad Lib, Inc.');
  402.       OutTextXY (X + 16, Y + 124,
  403.        'Synthe/Zap! and Machina Sapiens are trademarks of');
  404.       OutTextXY (X + 16, Y + 134,
  405.        'Machina Sapiens & J Meeks.');
  406. {$IfDef Shareware}
  407.       OutTextXY (X + 16, Y + 150,
  408.        'This is a registered shareware copy of Synthe/Zap!');
  409.       OutTextXY (X + 16, Y + 160,
  410.        'The author thanks you for supporting shareware and');
  411.       OutTextXY (X + 16, Y + 170,
  412.        'Machina Sapiens.  Please enjoy the program, and...');
  413.       OutTextXYThk (X + 16, Y + 184, 'ROCK ''n'' ROLL!   J Meeks', 2, 1,
  414.        White, Black, DefaultFont);
  415. {$Else}
  416.       OutTextXY (X + 16, Y + 150,
  417.        'This is a demonstration copy of the shareware');
  418.       OutTextXY (X + 16, Y + 160,
  419.        'program Synthe/Zap!  To receive the full version');
  420.       OutTextXY (X + 16, Y + 170,
  421.        '(which can save instrument definitions), please');
  422.       OutTextXY (X + 16, Y + 180,
  423.        'send $22.50 in check or money order to:');
  424.       OutTextXYThk (X + 38, Y + 194, 'J Meeks / Machina Sapiens',
  425.        2, 1, White, Black, DefaultFont);
  426.       OutTextXYThk (X + 38, Y + 205, '3808 Greenbay Rd #3',
  427.        2, 1, White, Black, DefaultFont);
  428.       OutTextXYThk (X + 38, Y + 216, 'Richmond, VA  23234',
  429.        2, 1, White, Black, DefaultFont);
  430.       SetTextStyle (TriplexFont, HorizDir, 4);
  431.       OutTextXY (X + 270, Y + 191, '≡≡≡');
  432.       OutTextXY (X + 270, Y + 191, '±');
  433.       OutTextXY (X + 299, Y + 191, '⌠');
  434.       OutTextXY (X + 381, Y + 191, '⌡');
  435.       SetTextStyle (DefaultFont, HorizDir, 1);
  436.       OutTextXYThk (X + 277, Y + 191, 'ε', 2, 4, White, Black, TriplexFont);
  437.       OutTextXYThk (X + 314, Y + 207, 'T', 2, 1, White, Black, DefaultFont);
  438.       OutTextXYThk (X + 322, Y + 209, 'H', 2, 1, White, Black, DefaultFont);
  439.       OutTextXYThk (X + 332, Y + 211, 'A', 2, 1, White, Black, DefaultFont);
  440.       OutTextXYThk (X + 342, Y + 213, 'N', 2, 1, White, Black, DefaultFont);
  441.       OutTextXYThk (X + 352, Y + 209, 'K', 2, 1, White, Black, DefaultFont);
  442.       OutTextXYThk (X + 362, Y + 207, 'S', 2, 1, White, Black, DefaultFont);
  443.       OutTextXYThk (X + 370, Y + 213, '!', 2, 1, White, Black, DefaultFont);
  444. {$EndIf}
  445.       repeat
  446.         ReadMouse;
  447.       until (KeyPressed or MsPressed);
  448.       IntroPlq.Remove;
  449.       ClrKeyBuffer;
  450.     end;
  451. end;    { procedure Setup. }
  452.  
  453.  
  454. function CompTimbre (First, Second: DrvDataDescr): boolean;
  455. var
  456.   CompOK:          boolean;
  457.  
  458. procedure CompLn (LeftNum, RightNum: integer);
  459. begin
  460.   if (LeftNum <> RightNum) then
  461.     CompOK := False;
  462. end;
  463.  
  464. begin
  465.   CompOK := True;
  466.   CompLn (First.Carrier.AttackRate,       Second.Carrier.AttackRate);
  467.   CompLn (First.Carrier.DecayRate,        Second.Carrier.DecayRate);
  468.   CompLn (First.Carrier.SustainLevel,     Second.Carrier.SustainLevel);
  469.   CompLn (First.Carrier.ReleaseRate,      Second.Carrier.ReleaseRate);
  470.   CompLn (First.Carrier.FreqMultiplier,   Second.Carrier.FreqMultiplier);
  471.   CompLn (First.Carrier.OutputLevel,      Second.Carrier.OutputLevel);
  472.   CompLn (First.Carrier.LevelScaling,     Second.Carrier.LevelScaling);
  473.   CompLn (First.Carrier.SustainSound,     Second.Carrier.SustainSound);
  474.   CompLn (First.Carrier.EnvScaling,       Second.Carrier.EnvScaling);
  475.   CompLn (First.Carrier.PitchVibrato,     Second.Carrier.PitchVibrato);
  476.   CompLn (First.Carrier.AmpVibrato,       Second.Carrier.AmpVibrato);
  477.   CompLn (First.Carrier.SynthTech,        Second.Carrier.SynthTech);
  478.   CompLn (First.Modulator.AttackRate,     Second.Modulator.AttackRate);
  479.   CompLn (First.Modulator.DecayRate,      Second.Modulator.DecayRate);
  480.   CompLn (First.Modulator.SustainLevel,   Second.Modulator.SustainLevel);
  481.   CompLn (First.Modulator.ReleaseRate,    Second.Modulator.ReleaseRate);
  482.   CompLn (First.Modulator.FreqMultiplier, Second.Modulator.FreqMultiplier);
  483.   CompLn (First.Modulator.OutputLevel,    Second.Modulator.OutputLevel);
  484.   CompLn (First.Modulator.LevelScaling,   Second.Modulator.LevelScaling);
  485.   CompLn (First.Modulator.SustainSound,   Second.Modulator.SustainSound);
  486.   CompLn (First.Modulator.EnvScaling,     Second.Modulator.EnvScaling);
  487.   CompLn (First.Modulator.PitchVibrato,   Second.Modulator.PitchVibrato);
  488.   CompLn (First.Modulator.AmpVibrato,     Second.Modulator.AmpVibrato);
  489.   CompLn (First.Modulator.SynthTech,      Second.Modulator.SynthTech);
  490.   CompTimbre := CompOK;
  491. end;    { procedure CompTimbre. }
  492.  
  493.  
  494.  
  495.  
  496. { Adjust all controls' settings and display images after loading a new
  497.   instrument. }
  498.  
  499. procedure TimbreToPanel;
  500. begin
  501.   with InstrDef do begin
  502.     ModeBx.Wipe;
  503.     if (CurrMode = MdPercussive) then
  504.       OutText ('Percussive')
  505.     else
  506.       OutText ('Melodic');
  507.  
  508.     VoicBx.Wipe;
  509.     if (CurrMode = MdPercussive) then
  510.       OutText (PercVoiceStr [CurrVoice])
  511.     else
  512.       OutText (MeloVoiceStr [CurrVoice]);
  513.  
  514.     with Carrier do begin
  515.       { Adjust all knobs' and buttons' settings. }
  516.       CAttackRateKnb.SetTo  (15 - AttackRate);
  517.       CDecayRateKnb.SetTo   (15 - DecayRate);
  518.       CSustainLevKnb.SetTo  (15 - SustainLevel);
  519.       CReleaseRateKnb.SetTo (15 - ReleaseRate);
  520.       CFreqMultipKnb.SetTo  (FreqMultiplier);
  521.       COutputLevelKnb.SetTo (63 - OutputLevel);
  522.       CLevelScalKnb.SetTo   (LevelScaling);
  523.       CSustainSndBtn.SetTo  (SustainSound <> 0);
  524.       CEnvScalingBtn.SetTo  (EnvScaling <> 0);
  525.       CVibratoBtn.SetTo     (PitchVibrato <> 0);
  526.       CTremoloBtn.SetTo     (AmpVibrato <> 0);
  527.     end;
  528.  
  529.     with Modulator do begin
  530.       MAttackRateKnb.SetTo  (15 - AttackRate);
  531.       MDecayRateKnb.SetTo   (15 - DecayRate);
  532.       MSustainLevKnb.SetTo  (15 - SustainLevel);
  533.       MReleaseRateKnb.SetTo (15 - ReleaseRate);
  534.       MFreqMultipKnb.SetTo  (FreqMultiplier);
  535.       MModFeedbackKnb.SetTo (ModFeedback);
  536.       MOutputLevelKnb.SetTo (63 - OutputLevel);
  537.       MLevelScalKnb.SetTo   (LevelScaling);
  538.       MSustainSndBtn.SetTo  (SustainSound <> 0);
  539.       MEnvScalingBtn.SetTo  (EnvScaling <> 0);
  540.       MVibratoBtn.SetTo     (PitchVibrato <> 0);
  541.       MTremoloBtn.SetTo     (AmpVibrato <> 0);
  542.     end;
  543.   end;
  544.  
  545.   { Now redraw all controls. }
  546.   CAttackRateKnb.Draw;
  547.   CDecayRateKnb.Draw;
  548.   CSustainLevKnb.Draw;
  549.   CReleaseRateKnb.Draw;
  550.   CFreqMultipKnb.Draw;
  551.   COutputLevelKnb.Draw;
  552.   CLevelScalKnb.Draw;
  553.  
  554.   CSustainSndBtn.Normal;
  555.   CEnvScalingBtn.Normal;
  556.   CVibratoBtn.Normal;
  557.   CTremoloBtn.Normal;
  558.  
  559.   MAttackRateKnb.Draw;
  560.   MDecayRateKnb.Draw;
  561.   MSustainLevKnb.Draw;
  562.   MReleaseRateKnb.Draw;
  563.   MFreqMultipKnb.Draw;
  564.   MModFeedbackKnb.Draw;
  565.   MOutputLevelKnb.Draw;
  566.   MLevelScalKnb.Draw;
  567.  
  568.   MSustainSndBtn.Normal;
  569.   MEnvScalingBtn.Normal;
  570.   MVibratoBtn.Normal;
  571.   MTremoloBtn.Normal;
  572.   LastLoadDef := InstrDef;
  573. end;    { procedure TimbreToPanel. }
  574.  
  575.  
  576. { Transfer knob and button settings to timbre descriptor. }
  577.  
  578. procedure PanelToTimbre (var Timb: DrvDataDescr);
  579. begin
  580.   with Timb.Carrier do begin
  581.     AttackRate :=     Trunc (15 - CAttackRateKnb.Value);
  582.     DecayRate :=      Trunc (15 - CDecayRateKnb.Value);
  583.     SustainLevel :=   Trunc (15 - CSustainLevKnb.Value);
  584.     ReleaseRate :=    Trunc (15 - CReleaseRateKnb.Value);
  585.     FreqMultiplier := Trunc (CFreqMultipKnb.Value);
  586.     OutputLevel :=    Trunc (63 - COutputLevelKnb.Value);
  587.     LevelScaling :=   Trunc (CLevelScalKnb.Value);
  588.     SustainSound :=   Ord (CSustainSndBtn.State);
  589.     EnvScaling :=     Ord (CEnvScalingBtn.State);
  590.     PitchVibrato :=   Ord (CVibratoBtn.State);
  591.     AmpVibrato :=     Ord (CTremoloBtn.State);
  592.   end;
  593.   with Timb.Modulator do begin
  594.     AttackRate :=     Trunc (15 - MAttackRateKnb.Value);
  595.     DecayRate :=      Trunc (15 - MDecayRateKnb.Value);
  596.     SustainLevel :=   Trunc (15 - MSustainLevKnb.Value);
  597.     ReleaseRate :=    Trunc (15 - MReleaseRateKnb.Value);
  598.     FreqMultiplier := Trunc (MFreqMultipKnb.Value);
  599.     ModFeedback :=    Trunc (MModFeedbackKnb.Value);
  600.     OutputLevel :=    Trunc (63 - MOutputLevelKnb.Value);
  601.     LevelScaling :=   Trunc (MLevelScalKnb.Value);
  602.     SustainSound :=   Ord (MSustainSndBtn.State);
  603.     EnvScaling :=     Ord (MEnvScalingBtn.State);
  604.     PitchVibrato :=   Ord (MVibratoBtn.State);
  605.     AmpVibrato  :=    Ord (MTremoloBtn.State);
  606.   end;
  607. end;    { procedure PanelToTimbre. }
  608.  
  609.  
  610. procedure SaveInstrument (OverLoadPlq: boolean);
  611. var
  612.   EntryPlq:        Plaque;
  613.   InstrName:       Str8;
  614.   YesOrNo:         Str1;
  615.   OKToSave:        boolean;
  616. begin
  617.   OKToSave := False;
  618.   HideMouse;
  619. {$IfDef Shareware}
  620.   PanelToTimbre (InstrDef);
  621.   if (OverLoadPlq) then
  622.     EntryPlq.Init (43, 87, 480, 60, 10, Red, LightRed, Black, PlqRound)
  623.   else
  624.     EntryPlq.Init (33, 81, 480, 60, 10, Red, LightRed, Black, PlqRound);
  625.   InstrName := LastInstr;
  626.   with EntryPlq do begin
  627.     EntryPlq.Draw;
  628.     SetColor (White);
  629.     OutTextXY (X + 20, Y + 10,
  630.      'Please enter the filename to save the instrument under:');
  631.     EditFieldGr (InstrName, 8, X + 30, Y + 25, White, Black, UpCaseSet,
  632.      [CR, Esc], TermBy);
  633.     if (TermBy = Esc) then begin
  634.       OutTextXY (X + 20, Y + 42, 'Aborting operation -- file not saved!');
  635.       Delay (1500);
  636.       EntryPlq.Remove;
  637.     end else begin
  638.       if (Exists (InstrName + '.Ins')) then begin
  639.         OutTextXY (X + 20, Y + 42,
  640.          'That file already exists -- replace it (Y or N)?');
  641.         YesOrNo := 'N';
  642.         EditFieldGr (YesOrNo, 1, X + 425, Y + 43, White, Black, ['Y', 'N'],
  643.          ['Y', 'N', CR], TermBy);
  644.         OKToSave := (TermBy = 'Y');
  645.         SetFillStyle (SolidFill, EntryPlq.FaceColor);
  646.         Bar (X + 20, Y + 40, X2 - 10, Y + 54);
  647.       end else
  648.         OKToSave := True;
  649.       if (OKToSave) then begin
  650.         SaveInsFile (InstrDef, CurrMode, CurrVoice, InstrName + '.Ins');
  651.         EntryPlq.Remove;
  652.         NameBx.Wipe;
  653.         OutText (InstrName + '.INS');
  654.         LastInstr := InstrName;
  655.       end else begin
  656.         OutTextXY (X + 20, Y + 42, 'Aborting operation -- file not saved!');
  657.         Delay (1500);
  658.         EntryPlq.Remove;
  659.       end;
  660.     end;
  661.   end;
  662. {$Else}
  663.   if (OverLoadPlq) then
  664.     EntryPlq.Init (43, 87, 515, 110, 10, Red, LightRed, Black, PlqRound)
  665.   else
  666.     EntryPlq.Init (33, 81, 515, 110, 10, Red, LightRed, Black, PlqRound);
  667.   with EntryPlq do begin
  668.     EntryPlq.Draw;
  669.     SetColor (Yellow);
  670.     OutTextXY (X + 20, Y + 10,
  671.      'This is the demonstration version of Synthe/Zap!  The only');
  672.     OutTextXY (X + 20, Y + 20,
  673.      'difference between the demo and the fully functional version');
  674.     OutTextXY (X + 20, Y + 30,
  675.      'is that this demo will not save your instruments.');
  676.     OutTextXY (X + 20, Y + 45,
  677.      'If you would like to have the fully functional shareware');
  678.     OutTextXY (X + 20, Y + 55,
  679.      'version, please send a check or money order for $22.50 to:');
  680.     OutTextXYThk (X + 38, Y + 70, 'J Meeks / Machina Sapiens',
  681.      2, 1, White, Black, DefaultFont);
  682.     OutTextXYThk (X + 38, Y + 81, '3808 Greenbay Rd #3',
  683.      2, 1, White, Black, DefaultFont);
  684.     OutTextXYThk (X + 38, Y + 92, 'Richmond, VA  23234',
  685.      2, 1, White, Black, DefaultFont);
  686.     repeat until (KeyPressed or MsPressed);
  687.     EntryPlq.Remove;
  688.   end;
  689. {$EndIf}
  690.   ClrKeyBuffer;
  691.   ShowMouse;
  692. end;    { procedure SaveInstrument. }
  693.  
  694.  
  695. procedure LoadInstrument;
  696. var
  697.   EntryPlq:        Plaque;
  698.   InstrName:       Str8;
  699.   YesOrNo:         Str1;
  700.   Aborted,
  701.   InputOK:         boolean;
  702. begin
  703.   HideMouse;
  704.   EntryPlq.Init (33, 81, 480, 60, 10, Red, LightRed, Black, PlqRound);
  705.   InputOK := False;
  706.   Aborted := False;
  707.   InstrName := LastInstr;
  708.  
  709.   EntryPlq.Draw;
  710.   with EntryPlq do begin
  711.     PanelToTimbre (InstrDef);
  712.     if ((not CompTimbre (InstrDef, LastLoadDef)) and (not FirstLoad)) then
  713.      begin
  714.       { Current instrument may need to be saved first! }
  715.       SetColor (White);
  716.       OutTextXY (X + 20, Y + 10, 'You have not yet saved the instrument that you''ve');
  717.       OutTextXY (X + 20, Y + 20, 'been working on.');
  718.       OutTextXY (X + 20, Y + 34, 'Do you want to save it now (Y or N)?');
  719.       YesOrNo := 'Y';
  720.       EditFieldGr (YesOrNo, 1, X + 325, Y + 34, White, Black, ['Y', 'N'],
  721.        ['Y', 'N', CR], TermBy);
  722.       if (TermBy <> 'N') then
  723.         SaveInstrument (True);
  724.       EntryPlq.Refresh;
  725.     end;
  726.  
  727.     repeat
  728.       SetColor (White);
  729.       OutTextXY (X + 20, Y + 10,
  730.        'Please enter the filename of the instrument to load:');
  731.       EditFieldGr (InstrName, 8, X + 30, Y + 25, White, Black, UpCaseSet,
  732.        [CR, Esc], TermBy);
  733.  
  734.       if (TermBy = Esc) then begin
  735.         OutTextXY (X + 20, Y + 42, 'Aborting operation -- no file loaded!');
  736.         Delay (1500);
  737.         InputOK := True;
  738.         Aborted := True;
  739.       end else
  740.         if (Exists (InstrName + '.Ins')) then begin
  741.           ReadInsFile (InstrDef, CurrMode, CurrVoice, InstrName + '.Ins');
  742.           NameBx.Wipe;
  743.           OutText (InstrName + '.INS');
  744.           LastInstr := InstrName;
  745.           InputOK := True;
  746.         end else begin
  747.           OutTextXY (X + 20, Y + 42,
  748.            'File not found!  Please try another name.');
  749.           Delay (1500);
  750.           EntryPlq.Refresh;
  751.           InputOK := False;
  752.         end;
  753.     until (InputOK or Aborted);
  754.   end;
  755.   EntryPlq.Remove;
  756.   FirstLoad := False;
  757.   ClrKeyBuffer;
  758.   TimbreToPanel;
  759.   LastLoadDef := InstrDef;
  760.   ShowMouse;
  761. end;    { procedure LoadInstrument. }
  762.  
  763.  
  764. procedure PlayTestNote (NoteVal: integer);
  765. begin
  766.   HideMouse;
  767.   DrawNote (I, StafX0, StafY0, Yellow);
  768.   ShowMouse;
  769.   PanelToTimbre (InstrDef);
  770.   SetTimbreImm (1, @InstrDef);
  771.   PlayNoteImm (1, NoteVal);
  772.   Delay (250);
  773.   ClrKeyBuffer;
  774.   StopNoteImm (1);
  775.   HideMouse;
  776.   DrawNote (I, StafX0, StafY0, LightCyan);
  777.   ShowMouse;
  778. end;    { procedure PlayTestNote. }
  779.  
  780.  
  781. function ClefNum: byte;
  782. begin
  783.   case CurrClef of
  784.     Treble:  ClefNum := 1;
  785.     Bass:    ClefNum := 2;
  786.   end;
  787. end;    { function ClefNum. }
  788.  
  789.  
  790. procedure TestNote (I: integer);
  791. begin
  792.   HideMouse;
  793.   DrawNote (I, StafX0, StafY0, Yellow);
  794.   ShowMouse;
  795.   PanelToTimbre (InstrDef);
  796.   SetTimbreImm (1, @InstrDef);
  797.   PlayNoteImm (1, InterpretNote (TestPitch [ClefNum, I]));
  798.   repeat until not (NoteBtn [I].Clicked (MsLeftBtn));
  799.   StopNoteImm (1);
  800.   HideMouse;
  801.   DrawNote (I, StafX0, StafY0, LightCyan);
  802.   ShowMouse;
  803. end;    { procedure TestNote. }
  804.  
  805.  
  806.  
  807. procedure TestChord (UseMouse: boolean);
  808. begin
  809.   HideMouse;
  810.   DrawClef (StafX0, StafY0, LightCyan);
  811.   ShowMouse;
  812.   PanelToTimbre (InstrDef);
  813.   SetTimbreImm (1, @InstrDef);
  814.   SetTimbreImm (2, @InstrDef);
  815.   SetTimbreImm (3, @InstrDef);
  816.   PlayNoteImm (1, InterpretNote (TestPitch [ClefNum, 1]));
  817.   PlayNoteImm (2, InterpretNote (TestPitch [ClefNum, 3]));
  818.   PlayNoteImm (3, InterpretNote (TestPitch [ClefNum, 5]));
  819.   if (UseMouse) then
  820.     repeat
  821.       ReadMouse;
  822.     until (MsNeither)
  823.   else
  824.     Delay (1000);
  825.   StopNoteImm (1);
  826.   StopNoteImm (2);
  827.   StopNoteImm (3);
  828.   HideMouse;
  829.   DrawClef (StafX0, StafY0, Yellow);
  830.   ShowMouse;
  831. end;    { procedure TestChord. }
  832.  
  833.  
  834.  
  835. procedure ConfirmQuit;
  836. var
  837.   ConfirmPlq:      Plaque;
  838.   YesOrNo:         Str1;
  839. begin
  840.   HideMouse;
  841.   ConfirmPlq.Init (370, 81, 235, 45, 10, Red, LightRed, Black, PlqRound);
  842.   with ConfirmPlq do begin
  843.     ConfirmPlq.Draw;
  844.     SetColor (White);
  845.     OutTextXY (X + 20, Y + 10, 'Are you certain you want ');
  846.     OutTextXY (X + 20, Y + 22, 'to quit (Y or N)?');
  847.     YesOrNo := 'N';
  848.     EditFieldGr (YesOrNo, 1, X + 170, Y + 26, White, Black, ['Y', 'N'],
  849.      ['Y', 'N', CR], TermBy);
  850.     EndSession := (TermBy = 'Y');
  851.     ConfirmPlq.Remove;
  852.   end;
  853.   if (not EndSession) then ShowMouse;
  854. end;    { procedure ConfirmQuit. }
  855.  
  856.  
  857. procedure Cleanup;
  858. begin
  859.   ClrKeyBuffer;
  860.   StopBtn.Highlight;
  861.   TestChord (False);
  862.   StopBtn.Normal;
  863.   Delay (350);
  864.   CloseGraph;
  865. end;    { procedure Cleanup. }
  866.  
  867.  
  868.  
  869. begin    { program SZ. }
  870.   Setup;
  871.   LoadInstrument;
  872.  
  873.   ShowMouse;
  874.   repeat
  875.     Key := NullChar;
  876.     if (KeyPressed) then begin
  877.       Key := ScanKey;
  878.       ClrKeyBuffer;
  879.     end;
  880.  
  881.     CAttackRateKnb.Adjust;
  882.     CDecayRateKnb.Adjust;
  883.     CSustainLevKnb.Adjust;
  884.     CReleaseRateKnb.Adjust;
  885.     CFreqMultipKnb.Adjust;
  886.     COutputLevelKnb.Adjust;
  887.     CLevelScalKnb.Adjust;
  888.     MAttackRateKnb.Adjust;
  889.     MDecayRateKnb.Adjust;
  890.     MSustainLevKnb.Adjust;
  891.     MReleaseRateKnb.Adjust;
  892.     MFreqMultipKnb.Adjust;
  893.     MModFeedbackKnb.Adjust;
  894.     MOutputLevelKnb.Adjust;
  895.     MLevelScalKnb.Adjust;
  896.  
  897.     CSustainSndBtn.Adjust (MsLeftBtn);
  898.     CEnvScalingBtn.Adjust (MsLeftBtn);
  899.     CVibratoBtn.Adjust (MsLeftBtn);
  900.     CTremoloBtn.Adjust (MsLeftBtn);
  901.     MSustainSndBtn.Adjust (MsLeftBtn);
  902.     MEnvScalingBtn.Adjust (MsLeftBtn);
  903.     MVibratoBtn.Adjust (MsLeftBtn);
  904.     MTremoloBtn.Adjust (MsLeftBtn);
  905.  
  906.     if ((NameBtn.Clicked (MsLeftBtn)) or (Key = F3Scan)) then
  907.       LoadInstrument;
  908.  
  909.     if ((NameBtn.Clicked (MsRightBtn)) or (Key = F2Scan)) then
  910.       SaveInstrument (False);
  911.  
  912.     if (ModeBtn.Clicked (MsLeftBtn)) then
  913.       { Do nothing for the time being. }  ;
  914.  
  915.     if ((ClefBtn.Clicked (MsLeftBtn)) or (Key = F4Scan)) then begin
  916.       { Switch to the next clef. }
  917.       case CurrClef of
  918.         Treble: CurrClef := Bass;
  919.         Bass:   CurrClef := Treble;
  920.       end;
  921.       HideMouse;
  922.       PutImage (StafX0 + 5, StafY0 + 9, UnderClef^, NormalPut);
  923.       TestChord (True);
  924.       DrawClef (StafX0, StafY0, Yellow);
  925.       ShowMouse;
  926.     end;
  927.  
  928.     if ((UpCase (Key) >= 'A') and (UpCase (Key) <= 'G')) then
  929.       PlayTestNote (InterpretNote (Key));
  930.     for I := 0 to 12 do
  931.       if (NoteBtn [I].Clicked (MsLeftBtn)) then
  932.         TestNote (I);
  933.  
  934.     if ((StopBtn.Clicked (MsRightBtn)) or (Key = Esc)) then
  935.       ConfirmQuit;
  936.  
  937.   until (EndSession);
  938.  
  939.   Cleanup;
  940. end.    { program SZ. }
  941.  
  942.  
  943.  
  944. { End file SZ.Pas. }
  945.