--- title: "Parakeet" id: 64653 type: "computer_media" slug: "parakeet" url: "http://localhost/computer_media/parakeet/" markdown_url: "http://localhost/computer_media/parakeet.md" published_at: "2026-03-06T14:55:28+00:00" modified_at: "2026-03-30T21:44:37+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A self-looping generative sound program that drives the AY-3-8912 chip through random frequency sweeps, noise bursts, and probabilistic pauses to create endless ambient tones." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Music" slug: "music" taxonomy: "genre" url: "http://localhost/type/music/" media_contents: - id: 64613 title: "CATS Library Tape 10" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-10/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Parakeet%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" media_type_tags: "Music" --- # Parakeet This program generates procedurally randomised synthesiser sounds using the SOUND statement, which maps directly to the AY-3-8912 sound chip. The first section (lines 10–50) produces a sweeping tone by iterating through a randomly determined frequency range with a random step value, then cuts the envelope. Lines 60–80 introduce probabilistic branching: a one-in-two chance of a random pause and a one-in-four chance of jumping to a second sound routine, otherwise looping via RUN. The second section (lines 90–160) creates percussive noise bursts by configuring the noise channel (register 6) and mixing registers, with randomised envelope period and shape values, separated by short busy-wait loops using empty FOR–NEXT. Both sections ultimately loop back with RUN, making the program a continuous generative ambient sound machine. *** ## Program Structure The program divides into two distinct sound-generation blocks, connected by probabilistic branching: 1. **Sweep section (lines 10–80):** Configures the AY chip’s tone channel, sweeps through a random frequency range, then either loops (`RUN`) or falls through to the noise section. 2. **Noise burst section (lines 90–160):** Generates rhythmic noise pulses with randomised envelope parameters inside a double FOR–NEXT loop, then unconditionally restarts via `RUN`. ## AY-3-8912 Register Usage The `SOUND` keyword on the TS2068 writes directly to AY-3-8912 registers. The following registers are referenced: | Register | Function | Used at lines | | --- | --- | --- | | 0 (fine pitch) | Channel A tone period low byte | 30 | | 6 | Noise period | 120 | | 7 | Mixer control (enable/disable tone & noise per channel) | 10, 120, 150 | | 8 | Channel A amplitude / envelope flag | 10, 120, 150 | | 9 | Channel B amplitude | 10, 120, 150 | | 10 | Channel C amplitude | 10, 120, 150 | | 11 | Envelope period fine | 30, 120 | | 12 | Envelope period coarse | 30, 50, 120 | | 13 | Envelope shape / cycle | 30, 50, 120 | Line 10 sets the mixer (`7,62`) to enable all tone outputs while muting noise, and silences channels B and C. Line 50 halts the envelope by writing `12,1;13,0`. Line 150 restores a silent mixer state after the noise bursts. ## Sweep Mechanism (Lines 20–40) The `FOR I` loop at line 20 computes a random start value `INT(RND*75)+25` (range 25–99), a random end value `INT(RND*75)+20` (range 20–94), and a step of `INT(RND*4)*2-5`. The step expression yields values from the set {−5, −3, −1, 1} depending on `INT(RND*4)` ∈ {0,1,2,3}, meaning the sweep can ascend or descend. A step of 0 is impossible because the even multiples are offset by −5 giving only odd and negative-odd results. Each iteration writes the loop variable `I` to register 0 (channel A fine pitch) while holding the envelope period and shape constant, producing an audible glide effect on the tone channel. ## Probabilistic Flow Control (Lines 60–80) Two independent random branches control program flow after the sweep: - Line 60: 50% probability of a `PAUSE` lasting between 1 and 60 frames (~0.02–1.2 seconds at 50 Hz), adding irregular timing. - Line 70: 25% probability of jumping to the noise section at line 90; otherwise line 80 executes `RUN`, restarting the entire program and re-seeding randomness from the existing R register state. Using `RUN` rather than `GO TO 10` is a deliberate idiom: it clears variables and re-enters the program from scratch, which also resets any BASIC overhead but preserves the pseudo-random sequence implicitly via elapsed time affecting `RND`. ## Noise Burst Section (Lines 90–160) The outer loop `FOR J=RND*1 TO RND*10` at line 90 iterates a random number of times (the non-integer bounds are handled by BASIC’s standard loop rules; the count is effectively 0 to ~10). Inner loops at lines 100–110 and 130–140 are empty busy-wait delays, their duration randomised by `INT(RND*4)` and `INT(RND*10)` respectively. Line 120 is the core noise event: register 6 sets noise period to 16; register 7 value 7 enables noise on all three channels while disabling tone; registers 8–10 all set to 16 enable hardware envelope control for all channels. The envelope period coarse (`11, 300+INT(RND*10)`) gives a slowly varying period around 300–309. Register 12 receives either 0 or 1 via `INT(((RND*2)+.5)/2)`, and register 13 selects envelope shape 0 or 8 via `INT(RND*2)*8`, toggling between a single-decay and a continuous-repeat envelope. ## Notable Techniques and Anomalies - The `SOUND` statement’s semicolon-separated register pairs allow an entire chip configuration to be written in a single BASIC statement, minimising interpreter overhead during time-sensitive sound setup. - Empty `FOR K … NEXT K` loops (lines 100–110, 130–140) serve as deterministic busy-wait delays — a common TS2068 idiom where `PAUSE` resolution (one frame) is too coarse. - The expression `INT(((RND*2)+.5)/2)` on line 120 is an unusual way to produce a biased coin: it yields 0 when `RND < 0.5` and 1 otherwise, equivalent to simply `INT(RND*2)`, suggesting either stylistic preference or a copy/transcription artifact. - Both sections terminate with unconditional `RUN` (lines 80 and 170), ensuring the program never halts during normal execution paths. ## Source Code ``` 10 SOUND 7,62;8,16;9,0;10,0 20 FOR I=INT (RND*75)+25 TO INT (RND*75)+20 STEP INT (RND*4)*2-5 30 SOUND 0,I;11,32;12,100;13,2 40 NEXT I 50 SOUND 12,1;13,0 60 IF INT (RND*2)=1 THEN PAUSE INT ((RND*60)+1) 70 IF INT (RND*4)=1 THEN GO TO 90 80 RUN 90 FOR J=RND*1 TO RND*10 100 FOR K=0 TO INT (RND*4) 110 NEXT K 120 SOUND 6,16;7,7;8,16;9,16;10,16;11,300+INT (RND*10);12,INT (((RND*2)+.5)/2);13,INT (RND*2)*8 130 FOR K=0 TO INT (RND*10) 140 NEXT K 150 SOUND 7,63;8,0;9,0;10,0 160 NEXT J 170 RUN ```