View in color | View documentation | License |
Download script | History | Other scripts by: rebolek |
30-Apr 14:08 UTC
[0.192] 91.542k
[0.192] 91.542k
pm-101.rREBOL [
Title: {Sintezar PM-101 - Phase Manipulation Digital Synthesizer}
Date: 23-Jun-2006
Name: 'PM-101
Version: 0.4.0
File: %pm-101.r
Author: "Boleslav Brezovsky"
Email: "rebolek<>gmail<>com"
Purpose: "synthetiser"
library: [
level: 'intermediate
platform: 'all
type: [tool demo]
domain: [sound ui]
tested-under: [view 1.3.2 WXP]
support: none
license: none
see-also: none
]
History: [
0.4.0 23-Jun-2006 [
"FIRST PUBLIC RELEASE"
{Uses Ladislav's Include to be compatible with preprocessor. Now I can produce single file for easier distribution.}
"PLAY button crashed when sound buffer was empty."
"EXPORT-WAV button crashed on cancel"
"EXPORT button crashed on cancel"
"IMPORT button crashed on cancel"
{IMPORT crashed when trying to import non-sintezar file}
]
0.3.9 22-Feb-2006 {OSC basic volume set to -3dB to prevent possible clipping.
^-^-^-^-^-^-^-^-dB equations fixed, maximal gain is up to 12dB}
0.3.8 19-Sep-2005 {AMPs support +6dB gain, all AMP values shown in dB's.
^-^-^-^-^-^-^-^-FInalCrusher is fully working (freq. divider and bit resolution destroyer)}
0.3.7 18-Sep-2005 "GUI changes to support LFO's and FinalCrusher"
0.3.6 16-Sep-2005 {added: waveshaper with normaliser, RingModulator mode 2
^-^-^-^-^-^-^-^-fixed: DCA, resonance}
0.3.5 15-Sep-2005 {ENV button envelopes are always zoomed at 100%
^-^-^-^-^-^-^-^-!!!ADDED WAV Saver!!! Great moment for Sintezar! ;)}
0.3.4 14-Sep-2005 {Added: Pitch envelope (+/- 2 oct.), OSC SYNC (Hardsync)}
0.3.3 13-Sep-2005 {Octave/keyboard for pitch-selection is functional now.
^-^-^-^-^-^-^-^-Vibrato is working now, main DCA fixed.
^-^-^-^-^-^-^-^-SAVE/LOAD support all parameters (I hope ;) - Not all GUI facets are updated after load (knobs)}
0.3.2 12-Sep-2005 {main filter bug fixed!!! limiter was missing and freq/reso envs were exchanged
^-^-^-^-^-^-^-^-added: Main DCA, init/copy/paste envelope, sample window enhanced}
0.3.1 9-Sep-2005 {GUI changes, added progress bar, main filter bug still not fixed :/}
0.3.0 8-Sep-2005 {added: load, GUI update after load. fixed: main filter bug.}
0.2.5 6-Sep-2005 {save enhanced, envelope rates enhanced (1ms - 16s range exponencial instead of 0s-1s linear),
^-^-^-^-^-^-^-^-envelope refresh fixed (although button envelopes refresh still doesn't work)}
0.2.4 2-Sep-2005 {added: new mix mode - mix-ring, basic save, intro screen, toolbox, fixed: envelopes, gui changes}
0.2.3 1-Sep-2005 "added: ESE-eight step envelope, detune part"
0.2.2 28-Aug-2005 {added: mixer, ring modulator, make/play sound, fixed: envelopes}
0.2.1 26-Aug-2005 "added: phase stretching"
0.2.0 19-Aug-2005 {added: filter, more waves, window function, octave modulation}
0.1.0 15-Aug-2005 {phase distortion rewritten from scratch to make it casioCZ-like}
0.0.1 25-Jul-2005 "initial version"
]
references: [
[1] http://en.wikipedia.org/wiki/Phase_distortion_synthesis
[2] http://homepage.mac.com/synth_seal/html/cz1.html
[3] http://www.cosmosynthesizer.de/
]
notes: {
CasioCZ waves:
^-sawtooth (done)
^-square (done)
^-pulse (done)
^-double-sine (pending)
^-saw-pulse (done)
^-sine-sync (done)
^-*triangle (not available on CasioCZ, but done)
^-**waveforms are just my aproximation, not checked against original sampled CasioCZ waves
^-
CasioCZ windows:
^-sawtooth (done)
^-triangle (done)
^-trapezoid (done)
^-*saw-pulse (done, unofficial window)
^-*spike (pending, unofficial window)
^-
Octave modulation: CZ can combine two waveforms in a single DCO: DCO can alternatively playback two different waveforms. [2]
When the original wave is constituted by 2 waveforms (octave modulated), the window affects both waves. [2]
^-Thanks to implementation, when two same waveforms are used, window affects both waveforms together, so there's sound difference compared to one waveform.
^-
Envelopes - there is five of them (only ADSR at the moment, I'll write 8-stage ENV later)
^-DCO (pitch) envelope
^-DCW (phase distortion) envelope
^-DCF/cutoff envelope
^-DCF/resonance envelope
^-DCA envelope
Digital phase stretch - not found on CasioCZ - stretch waveform but cycle lenght is left
Mixer/Ring Modulator
^-PH101 supports Mix-Ring - it's ring modulator with second line (modulator) added to output, so it works both as carrier and modulator
}
missing: [
#1 'pending {(there are three types of RM on CasioCZ...let's see)}
#2 'pending {All Casio waves are missing. My waves are different. This is not a priority.}
#3 'done "vibrato"
#4 'fixed "there's probably some bug in main filter section"
#5 'fixed {save does not save global parameters - detune, length (vibrato)}
#6 'pending "save WAV"
#7 'pending "strange LED behavior when changing sample length"
#8 'pending {Math overfolw error where it shouldn't be (square waveh)}
#9 'pending "Reset phase before making new sound"
#10 'pending "Hard sync for DCO2"
]
]
if not exists? %sounds/ [
make-dir %sounds/
path: %sounds/
verbose: none
files: [%sounds/bassdrum.sin 392 %sounds/basskiller.sin 425 %sounds/blaum.sin 411 %sounds/cosi.sin 456 %sounds/elecguit.sin 529 %sounds/elecguit2.sin 554 %sounds/elecneguit.sin 453 %sounds/epiano.sin 448 %sounds/hardsync.rps 464 %sounds/horn.sin 475 %sounds/horn.wav 444 %sounds/organ.sin 407 %sounds/pluckpling.sis 416 %sounds/resobass.sin 493 %sounds/ressonator.sin 483 %sounds/trumpet.sin 425 %sounds/violin.sin 448 %sounds/violin2.sin 515 %sounds/wildpitcher.sin 403]
check: 1799181
if not exists? path [make-dir path]
archive: debase {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
zH/gmyQopXgGfCXZ16AUAAA==}
if check <> checksum archive [print ["Checksum failed" check checksum archive] halt]
foreach [file len] files [
if verbose [print [tab file]]
either len = 'DIR [
if not exists? file [make-dir/deep file]
] [
data: decompress copy/part as-binary archive len
archive: skip archive len
write/binary file data
]
]
]
toolbox-images: context [
new-project: first reduce load decompress 64#{
eJztl8EKgzAMhu99CsdeYOhBfAFfYuzgQYYM74Oxdx+zwiJpuqRaU6HJYSDL8v2l
38Cxe/TFMHb3/lRcq/JZlcX5ZdoVlYfzcB6mhy9BZexH1X5bAxvCWwpOG/zI/sS+
2BCec5DkZk6EODcMXwkcgbWZihBTDOpWz5dEug1GiO8zqSS81eLNUhnE2LawsA4l
+REWm3fyeXHaYaXuc9i/d1I+8yMk67M/wrrNCj6Lh8nNzdQH9bkBfTifG9QH8hnD
4wjJ+kzB11Mn7jMFb+r216n67MCGRy+NsK/PDmwK3h9Bw2cHNgc+EZ/9xvrh1X0O
g9d4f3b4LIUn3zE0fOb3H2x/hK3FgHv8ZThfwjVn3hg7D+dh5rB53z5iBFREfxgA
AA==
}
open-project: first reduce load decompress 64#{
eJztVksKg0AM3ecUll5AlOK+Cy9RunAhpRT3hdK7F80sIjFj5uNnislCUZ55b5KX
tmtebfbsmkd7ym5l8S6L7PyBOiAO8H+B8yG2qBwBnJNYt3IEMNK+1H0CXqRmRK4c
AYxMDe1qSFcJG7aKHn1FUiNh8wmj5PGeSuBvd0Ibg9KjT/j5G2P4WWJUOfcKVWU+
SAbsR3hEm1a41toE/sguhJ4/UA1BtF0lTNDWSwDJBkG0uQRxSDRR1n3OgLkNeDjQ
5hKQBeDFLyfA+G1uAxGsbw8NkL4qMfJsVRB4gra9GXYJM8YIcpXdbTMTZpdgDmxV
2gYstUEjAXgD1qLNG6CXIPpZI2GZCdNIGP0+u5Jf0hh28g5+5hLW8jOX4Onnna8h
u4Qk1hCXkNwawhD9nMQakpqR0BrSS9jtGrJLSGIN8UhuDRnaUhs0Efv/tiftIM0H
OAAM3/sPwwsyNn8YAAA=
}
save-project: first reduce load decompress 64#{
eJztmDEOwjAMRXefoogLVO0NGHoJxNChQgh1R0LcHQmWhtQ/32kyFNneUH/8X+K/
MI/3qbnN43U6NOe+e/Rdc3zKsKFc7GJQ7aekVeo0pFuYj+JWJ5uZNfMYIdN2IMaT
DU/FI1C2tYNWxHjyEiSxYfgI820HYu0yGARZMlgREpMTS6JZYhAyg6GKeQTBxjCC
OplBqJNn5iAqzxqC59mIsNc859GuTLYiJFJFXVgVMTZP5TlzcjGxahtv0rf64bcl
/onvhBgjZOa5vm2MUCLP1W3HCKXzXN12IMabpFUiz/Vtx8/AIHiey9rGCJ5nI4Ln
2YjgeS5rGyOY8xw8FbNJBWzHCIKNYQTP8/an4hF296fpf4rldXkDbAq9gX8YAAA=
}
make-sound: first reduce load decompress 64#{
eJztlD1u5DAMhXueYhZ7AVkjS3LpkTSXWGyRIggWi/QBgr178EgWNDRO5J0izfDr
aMl84t/r09/n05/Xp5fnH6dfPrz5cPr5Ttc77HH52y5fGkgOeDbHlj2YHCgNyBmy
h+IK9E8etAncJbtEkB1gEfm6ArKuGkF/KGagT8tgLuC+hB1Nkj1DNkklAH5g+Twm
vyNSdeA/ZY8cWs5gdmBzWSvJVRWXPCRX0P+orSAmQFyd2tguV7AwcQLlAqxHzmhk
Z6wGoEc5J2UFmiSuv9iNN0snzYxrQH6XMpAiLRWkBsi6Ipv8yCpqEfgAVg+0ziop
AHHNVzCiiPYkjSgiaX3X2VRAWoF4fAPbOpu6HS0b2brZyImtV7SRrSKZmsBIw96o
c29chPxF5BHjZs92/qlfAJ+vhDmDTW/zaDUbRz2F2ZOdC7Cd1C/APQ/ZvWm35BTA
ythoSwYhApUdGM+IpQDkR3tLko4mqTK6AOWCjJt8lh7m/tNh8AVIt2vHjjTJ4Q6T
IRVFZw80Ptu8AL08JzBlYH/B2r3OFq9emT/rIVm6N0byDOzvZCS5wHlagcoWkf0T
+AWbOePceXkaSQ6rB+JSD8vo91Z04EbCpEt4hWm0wgxl20oaUUR7kkZsqEn2ykbW
NV62A5Hvkv24/Lj89aF/vz8As15irdINAAA=
}
play-sound: first reduce load decompress 64#{
eJztlkFuwyAQRfecIlUvANgEWGJjX6LqIouoqqrsK1W9e/pnqISVkIASV6raeavI
Hs3nfyA+7N72m9fD7mX/sHnS/bvuN48fYr6h/mSzUYQHPzu59EAHILPyEUwKrDm5
VJ0EXEKelJ3B7Ij7Ti4255LyGjqQfszADGB9w/QEeHCI4Ewzi2FhKVuqPNvmyUXZ
2hEk7Mq7FB4Huci5Ptsq2UkR0dDM9rBVrItPrYmganKNohvd7oEciYpsF80lSVWT
Sw+cAX4LzAROj62oybakqMEw14PRAxuBMBpsqUYDkjI63OSmLq651aRIpGY5gcEB
q4HzRABKA5aiOzA5cGXNDXvbUXkJ2H4bgJ8BOeVMD1gF5ehEUKBmtQtFdP7PyE6R
BMAT6F/Q0H7xgwVyAN+Xfg/iAOpVLPd2dktuNVBpVSAQVgE3AsEilQTp6NOrUwQN
ky+b1FlA4r5+AMG7NEhQiqSUyI03SWaS6QBbkkdSSmTNbxK2ip2XvHuzRERNJM2T
S3Xmm+RyJHebXGxO94YDNYfkt34y/zev0Cw+n4/dHITu0g0AAA==
}
]
leds: load to block! decompress 64#{
eJzVlr0KwkAQhPt9ihNf4CSCqS3yEmKRIojI9YL47oraxFxmdvIH2YNt7ubbWW6L
TfWtCddUX5pNOO2K+yFsHxZHRK+4OPJj+BrjiBjjZHGmstotse3BCbaFr/LET2zP
c0iLzVBV8Wz4GuOIGONkcaay2i2x7cEJtruxvhmKcf8+OBt7hHBUjHADxJnKWrfU
NsdJtv9jfTNUOrLha4wjYoyTxZnK2J7cswcn2O7GrDNUfsoOy73iUbvB92CcvNK0
bKviTGW1W2LbgxNsC18l/POyMzTBPoRx8krTsj3BPqR2S2x7cILt2WboBVK1ya2X
DQAA
}
logo.png: load as-binary decompress 64#{
eJwBHwPg/IlQTkcNChoKAAAADUlIRFIAAABuAAAALQgCAAAAwPXJbgAAAARnQU1B
AACxjwv8YQUAAALWSURBVGhD7Zo7csJADED3uBwiZcqcgAvQ06dOS0tJSUfJpCGa
CIRYfSybDVmwPCoYW2h3n75mKCWvtgTeT98p0wjUjgArbX0zE2sKt/Ot5bKQnE5l
UA6HQjITeLfHTJTN3J4oE2UzAs0M2VF5PBYSXigjNfTO7X1+FpSnuhJlM3f1h/Lt
7TotNDvmIwz1h3K/9wYvYvL1paiBG+jypzdS2+0KiKq8Xp+1fFOXQmSj5HMit/Xx
UUh8Z08eM2k51T6WUdDBD6vVFcR2q6BcLAoIPAJBy+AGSRzcQCI3QHfQDl/oYipR
Xt4+EuU8onJyrfcTHOsGDGpqWZSLQskDQZtQiEEGLyfB7e/aCa4GfFWA+ezJ9Qf3
6iv4KIP9BJfg8wB8EeumvNQmBvrSW/+Akh/Y6qrgCVLDeMFzJsprB0R2FhHeDTFM
KAEhcwdRYirwkHFiHAzictDoQeRFwxAEJgrsp7sEn4ySYNHUtdmczwks4DMIGMci
SHdQhy7kAmqojz5zGFGBopmJFwQ/UX4XtWul5Wo+V/Islr9XDqLkS3BljKCqJuK7
P13qJM8VgiVVXauaIi1Tt4gSpea2RHkTthmVTgvp/JGd4JZXrd8r+YzJuzAvgtJm
1esD1b1boImymWv+DGWzHT6NoUTZzFU2SnyTQ/G7IT6N/47ZbPN9GUqUzfyRKJ8E
ZfBPTHiaoDJXUzFUdrhOZAl1MxHe418cI1YvOpGt0w6CynNHKflLIk408ZitPjue
RYMyKiObIR1pxFrxQVEZ2X2i9BJe5mzlbe7zRDkOpVoQI5WevqgmOH/q5Kbquarj
VedRLVvtrr6v5PyYVjO2Y1ptxzmSPF7kDiGT7JxW1h3KiC+cgJ0QKX6cVs0kUXr/
mQ+mvKwtE9xGRh6R4L1FpcVLFrdZJ3i8s92jqY53rxaV9wCyeqAz1fGB4Q9RRvL6
ZXT0tx3VsXlzkMDLhEVHB/kBkIiuI8JwoEkAAAAASUVORK5CYIJIk2nxHwMAAA==
}
sine.png: load as-binary decompress 64#{
eJzrDPBz5+WS4mJgYOD19HAJAtKiQMzPwQQkWyyEbYAUY3GQuxPDunMyL4EclnRH
X0cGho393H8SWYF8hWSPIF8Ghio1BoaGFgaGX0ChhhcMDKUGDAyvEhgYrGYwMIgX
zNkVCDIo2dPFMcTCf+vkQC4GBQ7nt8/u3ulxasoxVvro3GPuu3rFKptI0ULzlQ+z
hY6H1c9ITHxz0mDGGa73RQ6LPlvPmV7xzP/oZN0NmY9jv6Q6Lr4rOM/vu738tgff
H339+HpP1auL7w98Xr6cd8Ojje1uLg89gNYxeLr6uaxzSmgCAFN4UjvlAAAA
}
triangle.png: load as-binary decompress 64#{
eJzrDPBz5+WS4mJgYOD19HAJAtKiQMzPwQQkWyyEbYAUS7qjryMDw8Z+7j+JrEB+
uqeLY4iF/9LJkXwMihzO1ubfn/F0/mYzlagPiTvaNL9DwURIYGbVfwuFiLI3T0Xm
PlTvPNcvoR/4Q1ZBdU2LJGfGhKf7q1/tqj29aNZbrjlal1xuZt1fdfjTWv1pz20+
HL/WZbq/TuaQnfYT9ikHNnXyvT7lC7SSwdPVz2WdU0ITAKEvP8CwAAAA
}
pulse.png: load as-binary decompress 64#{
eJzrDPBz5+WS4mJgYOD19HAJAtKiQMzPwQQkWyyEbYAUS7qjryMDw8Z+7j+JrEC+
m6eLY4iFf/Kf///tmV0XNDY2Ch1h2CKnz2QlwM+QeUy9N1zszfeF6+XjfzDbdqiX
Odw7Lr+nxSn9x2v1CQ6aXn8OrDgo/48llfF2dNfGhjkZ+4EmMni6+rmsc0poAgBm
VS4QjwAAAA==
}
saw.png: load as-binary decompress 64#{
eJzrDPBz5+WS4mJgYOD19HAJAtKiQMzPwQQkWyyEbYAUS7qjryMDw8Z+7j+JrEB+
tKeLY4iF/9LJnnwMChzMr8//tXxUFNB06lLFYb/GDEWlJSGNZxiPC+/onjHN0sfy
ELPI0krxp1Z7Jl76u/5v/er7W+2lJFVnh3Qdtg9mOfpWfMqC+uVP5OzrZW7/Wrdd
ykJ03tzPz/xcgNYweLr6uaxzSmgCAD2dOcakAAAA
}
keyboard.png: load as-binary decompress 64#{
eJwBqAFX/olQTkcNChoKAAAADUlIRFIAAABjAAAARAgCAAAAGvAcTAAAAARnQU1B
AACxjwv8YQUAAAFfSURBVHhe7dvREoIwDERR/v+nFRQFEei2I8zIHF5JBbZ3kxRq
1zlyBW7bx86PLAblkfOB/aiTr958n8PAk++VUpuztT8TJ88TptJ5ohSlNhRorieY
whSmnvY5v0fhPu7jPu5bYUCP/qFAc6a0mpmkwxSmZgrknsojvXVJOxpKUerXvR+m
MIWpx0reF4e076MUpV4KNL9HXlQeTGEKU6tVKF9L5ZHc19j3yVPylDwlT628Gc2z
7xGRMrqMfvBKXu1T+9Q+tU/tK+1Nvsg35OcWp+9j9fHyyPfwfsiOUgddve0+C7Uv
/45y+UhK7TM9nh0xjGJLOw0xNSlQzCl59vnHSO6LHMV9hco7Zx9TmAoUqMq8mAoU
TfYlXL72RzpRivsqKhqmIgUwhakIlMI/4ZprlC4hkt9qpsKnmMJUoIDaV+GpQM8h
RJ6q0FSeiqjCFKYiUOp6VO6LRN3cc+XEtwJ3Q20XtjlRpMkAAAAASUVORK5CYIIA
8sGbqAEAAA==
}
stz-home: what-dir
sample-rate: 44100
sample-length: 44100
sample: make binary! 1000000
pitch: 440
oct: 1
vibrato-wave-length: 1
vibrato-phase: 0
vibrato-depth: 0
vibrato-amount: 0
knob-style: stylize/master [
knob: box 50x50 with [
colors: white
data: 0
outer-part: none
inner-part: none
guideline: 'outer
guideline-point: 25
angle: -45
inner-radius: 14
last-offset: 0x0
feel: make feel [
redraw: func [f a p] [
f/data: max 0 min 1 f/data
f/effect/draw/transform: min 225 max -45 f/data * 270 - 45
f/effect/draw: skip find f/effect/draw 'arc 4
f/effect/draw/1: to integer! f/data * 270
f/effect/draw: head f/effect/draw
]
engage: func [f a e] [
if not any [
all [f/data = 0 f/last-offset/y <= e/offset/y]
all [f/data = 1 f/last-offset/y >= e/offset/y]
] [
switch a [down [f/last-offset: e/offset]]
f/effect/draw/transform: min 225 max -45 f/effect/draw/transform + f/last-offset/y - e/offset/y
f/data: (f/effect/draw/transform + 45) / 270
f/effect/draw: skip find f/effect/draw 'arc 4
f/effect/draw/1: to integer! f/data * 270
f/effect/draw: head f/effect/draw
f/last-offset: e/offset
do-face f f/text
show f
]
]
]
multi: make multi [
color: func [face blk] [
face/colors: reduce switch length? blk [0 [[66.155.148 44.103.98 51.51.51 39.39.39 255.255.255]] 1 [[blk/1 blk/1 / 1.5 blk/1 blk/1 * 1.3 blk/1 blk/1 / 2.25]]
2 [[blk/1 blk/1 / 1.5 blk/2 blk/2 / 1.3 blk/1 / 2.25]]
3 [[blk/1 blk/1 / 1.5 blk/2 blk/2 / 1.3 blk/3]]
4 [[blk/1 blk/4 blk/2 blk/2 / 1.3 blk/3]]
5 [[blk/1 blk/4 blk/2 blk/5 blk/3]]
]
]
]
words: [
guideline [new/guideline: second args next args]
inner-radius [new/inner-radius: second args next args]
]
append init [
inner-radius: min inner-radius (size/x / 2) - 3
guideline-point: switch guideline [
inner [(size/x / 2) * 0.75]
outer [3]
]
effect: compose/deep [
draw [
line-width 2
line-cap round
pen (colors/1)
arc (size / 2) ((size / 2) - 1) 135 (data * 270) closed
circle (size / 2) inner-radius inner-radius
transform -45 (size / 2) 1 1 0x0
line (as-pair guideline-point size/y / 2) (as-pair (size/x / 2) - inner-radius - 1 size/y / 2)
line-width 1.5
line (as-pair guideline-point size/y / 2) (as-pair (size/x / 2) - inner-radius - 1 size/y / 2)
]
]
effect/draw/transform: (data * 270) - 45
angle: (data * 270) - 45
]
]
]
demo: layout [
styles knob-style across
knob 100x100 180.180.190 180.180.190 black inner-radius 30
knob 15x15 250.200.170 200.200.200 guideline 'inner inner-radius 7
knob 40x40 200.205.220 100.105.120 200.205.220 inner-radius 10
knob inner-radius 5
knob yellow gold orange inner-radius 17 guideline 'inner
knob yellow gold orange inner-radius 17 guideline 'outer
knob 100x100 180.180.190 white black inner-radius 30
]
stz-styles: stylize [
slider: slider 150x20 220.220.230 180.180.190
field: field 50x20 51.51.51 66.155.148 font-size 10 edge [size: 1x1 color: black] font-color 132.255.250 with [font: make font [offset: 0x0] para: make para [origin: 0x0 margin: 0x0]]
button: button 60x21 black black 132.255.250 effect [fit contrast 10] edge [size: 1x1 color: 132.255.250 effect: none] font-size 9 font-color 132.255.250
button-lfo: button 21x21 effect [draw [pen 180.0.0 text 3x3 "lfo" pen 90.0.0 line-width 2 line 0x0 21x21 line 0x20 20x0]]
text: text 89x20
inp-txt: txt 100 white gray bold
txt: txt 132.255.250 bold
tx: txt font-size 9 43x10 with [para: make para [origin: 0x0 margin: 0x0]]
radio: radio 15x9 with [images: reduce leds] edge [size: 1x1 color: 51.51.51]
radio-line: radio-line font-color 132.255.250 font-size 9 with [images: reduce leds]
check-line: check-line font-color 132.255.250 font-size 9 with [images: reduce leds]
bar: bar 110x1 66.155.148 edge [size: 0x0]
]
stylize/master [
toolpanel: panel with [
txt: ""
type: 'toolpanel
siz: 16
group: 0
closed?: no
color: none
edge: none
multi: make multi [
text: func [face blk] [
if pick blk 1 [
face/txt: first blk
face/texts: copy blk
]
]
]
words: [
closed [
new/closed?: yes
next args
]
group [
new/group: second args next args
]
]
]
tool: box with [
edge: make edge [size: 1x1 color: none effect: none]
type: 'tool
colors: reduce [none 132.255.250]
color: none
effect: [merge key 255.255.255]
feel: make feel [
engage: func [face action event] [
switch action [
time [if not face/state [face/blinker: not face/blinker]]
down [
face/state: on
if face/type = 'tool [
foreach fc face/parent-face/pane [
if equal? fc/type 'tool [fc/edge/color: fc/colors/1 fc/edge/effect: none]
]
]
face/edge/color: face/colors/2
face/edge/effect: 'ibevel
show face/parent-face
]
alt-down [face/state: on]
up [if face/state [do-face face face/text] face/state: off]
alt-up [if face/state [do-face-alt face face/text] face/state: off]
over [face/state: on]
away [face/state: off]
]
cue face action
show face
]
]
words: [
nt [
new/type: none
new/colors: [200.200.210 200.200.210]
next args
]
]
append init [
edge: make edge []
size: image/size + 2x2
]
]
]
to-AIFF: func [{converts SINTEZAR sound to AIFF using SINTEZAR values}
sample
bits
samples
sample-rate
/local COMM-chunk SSND-chunk FORM-chunk
] [
SSND-chunk: join load rejoin [
"#{"
"53534e44"
to-string to-hex bits / 8 * samples + 8
"0000000000000000"
"}"
] sample
COMM-chunk: load rejoin [
"#{"
"434f4d4d000000120001"
to-string to-hex samples
to-string skip to-hex bits 4
"400e"
to-string skip to-hex sample-rate 4
"000000000000"
"}"
]
FORM-chunk: load rejoin [
"#{"
"464F524D"
to-string to-hex (
4 + (length? COMM-chunk) + (length? SSND-chunk)
)
"41494646"
"}"
]
return join FORM-chunk (join COMM-chunk SSND-chunk)
]
Chunk-ID: "RIFF"
RIFF-Type-ID: "Wave"
itble4: func [n /local rslt] ["Integer To Binary Little Endian (4 bytes align)"
rslt: copy 64#{}
n: to string! to-hex n
forskip n 2 [insert rslt load rejoin ["#{" n/1 n/2 "}"]]
rslt
]
itble2: func [n /local rslt] ["Integer To Binary Little Endian (2 bytes align)"
rslt: copy 64#{}
n: to string! to-hex n
forskip n 2 [insert rslt load rejoin ["#{" n/1 n/2 "}"]]
copy/part rslt 2
]
wav-structure: func [smpl] [
to binary! rejoin [
to binary! "RIFF"
itble4 ((length? format-chunk) + (length? data-chunk smpl) + 4)
to binary! "WAVE"
format-chunk
data-chunk smpl
]
]
format-chunk: to binary! rejoin [
to binary! "fmt "
64#{EAA=}
64#{AAA=}
64#{AQA=}
64#{AQBErA==}
64#{AAAQsQ==}
64#{AgA=}
64#{BAA=}
64#{EAA=}
]
data-chunk: func [smpl] [
to binary! rejoin [
to binary! "data"
itble4 length? smpl
smpl
]
]
buffer: context [
length: 256
data: make block! length
init: does [
data: make block! length
]
fill: func [fnc] [
init
loop length [
insert tail data do fnc
data
]
]
]
pipe: context [
length: 256
data: make block! length
init: does [
data: make block! length
]
insert: func [value] [
insert tail data value
if (length? data) > length [
remove first data
]
]
]
convert: func [
{Converts sample value to 8 or 16 bit signed or unsigned binary value}
value "Sample value (-1..1)"
/bit16 /signed
] [
if bit16 [
if signed [
return load rejoin ["#{" to-string skip to-hex to-integer value * 32767.5 4 "}"]
]
return load rejoin ["#{" to-string skip to-hex to-integer 1 + value * 32767.5 4 "}"]
]
if signed [
return load rejoin ["#{" to-string to-hex to-integer value * 127.5 "}"]
]
to-binary (to-string (to-char (to-integer ((1 + value) * 127.5))))
]
if (false) [
foreach file [
%styles/knob.r
%styles/stz-styles.r
%styles/toolpanel.r
%tools/aiff.r
%tools/wav.r
%tools/buffer.r
%tools/convert.r
] [include file]
]
sndport: open sound://
~fnt-h1: make face/font [name: "arial black" size: 60]
~fnt-h2: make face/font [name: "arial black" size: 12]
~fnt-h3: make face/font [name: "arial black" size: 15]
~btn-chg: none
~fld-smplen: context [text: "1"]
modules: either exists? %modules/ [read %modules/] [copy []]
m-offset: 10x10
remove-each module modules [not equal? "r" last parse module "."]
forall modules [modules/1: to word! first parse modules/1 "."]
outputs: copy []
main-output: none
module-stack: copy []
modnr: 0
add-module: func [value] [
modnr: modnr + 1
either issue? prepared-modules [
do rejoin [%modules/ value ".r"]
] [
do select prepared-modules value
]
tmp: get to word! value
tmp-name: to word! rejoin [get in tmp 'name "-" modnr]
insert tail module-stack set tmp-name make tmp [id: tmp-name]
do get in get tmp-name 'init-gui
append outputs compose/deep [(tmp-name) [(get in get tmp-name 'output)]]
]
prepared-modules: copy [] unset
prepared-modules: ["ESE" [
ese: context [
name: "ESE"
info: "Envelope generator"
type: 'generator
id: none
input: none
output: 'envelope
value: 0
rates: [0 1 0 0 0 0 0 0]
levels: [0 1 1 0 0 0 0 0 0]
step: 1
steps: 0
length: sample-rate
position: 1
zoom: 1
export: does [
reduce ['rates head rates 'levels head levels]
]
main: func [/local rate level next-level tmp] [
either step = 9 [0] [
rate: rates/:step
level: levels/:step
next-level: levels/(step + 1)
step-length: (rate + 1 ** 14 / 1000 * sample-rate) + 1
step-pos: 0
repeat i step [step-pos: step-pos + (1 - rates/:i * sample-rate)]
tmp: ((steps / step-length) * (next-level - level)) + level
steps: steps + 1
if steps >= step-length [steps: 0 step: min 9 step + 1]
position: position + 1
value: tmp
]
]
~knb-rt1: ~knb-rt2: ~knb-rt3: ~knb-rt4: ~knb-rt5: ~knb-rt6: ~knb-rt7: ~knb-rt8:
~knb-lv1: ~knb-lv2: ~knb-lv3: ~knb-lv1: ~knb-lv5: ~knb-lv6: ~knb-lv7: ~knb-lv8:
~env-name:
~curve: none
gui: none
init-gui: does [
gui: layout/tight compose [
styles stz-styles
style knob knob 16x16 inner-radius 3
style tx txt white bold font-size 9 25x12 with [origin: 0x0 margin: 0x0]
backdrop 66.155.148 effect [gradient 0x-1 66.155.148 51.51.51]
across
origin 0x10
space 2x2
box 150x18 effect [merge gradmul 1x0 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 text 0x0 "ENVELOPE" vectorial]]
return
~curve: box 150x50 black effect [draw []] edge [size: 1x1 color: black]
slider 12x50 edge [size: 0x0] effect [merge luma -30] [zoom: (value * 9) + 1 show-curve]
across
return
box 10x10
return
space 2x2
tx 27 "rate"
~knb-rt1: knob 132.255.250 with [data: 0] [rates/1: value show-curve]
~knb-rt2: knob 132.255.250 with [data: 1] [rates/2: value show-curve]
~knb-rt3: knob 132.255.250 with [data: 0] [rates/3: value show-curve]
~knb-rt4: knob 132.255.250 with [data: 0] [rates/4: value show-curve]
~knb-rt5: knob 132.255.250 with [data: 0] [rates/5: value show-curve]
~knb-rt6: knob 132.255.250 with [data: 0] [rates/6: value show-curve]
~knb-rt7: knob 132.255.250 with [data: 0] [rates/7: value show-curve]
~knb-rt8: knob 132.255.250 with [data: 0] [rates/8: value show-curve]
box 10x5
return
tx 27 "level"
~knb-lv1: knob 51.51.51 with [data: 1] [levels/2: value show-curve]
~knb-lv2: knob 51.51.51 with [data: 1] [levels/3: value show-curve]
~knb-lv3: knob 51.51.51 with [data: 0] [levels/4: value show-curve]
~knb-lv4: knob 51.51.51 with [data: 0] [levels/5: value show-curve]
~knb-lv5: knob 51.51.51 with [data: 0] [levels/6: value show-curve]
~knb-lv6: knob 51.51.51 with [data: 0] [levels/7: value show-curve]
~knb-lv7: knob 51.51.51 with [data: 0] [levels/8: value show-curve]
~knb-lv8: knob 51.51.51 with [data: 0] [levels/9: value show-curve]
return
space 2x2
button 58 "init" [
either any [
equal? self module-stack/3/envelopes/1
equal? self module-stack/4/envelopes/1
] [
rates: [0 1 0 0 0 0 0 0]
levels: [0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]
] [
rates: copy [0 1 0 0 0 0 0 0]
levels: copy [0 1 1 0 0 0 0 0 0]
]
init-module
]
button 58 "copy" [clipboard-envelope/rates: copy rates clipboard-envelope/levels: copy levels]
button 58 "paste" [rates: copy clipboard-envelope/rates levels: copy clipboard-envelope/levels init-module]
]
show-curve
]
show-curve: has [old-wave-length old-position] [
old-step: step
old-steps: steps
old-position: position
old-sample-rate: sample-rate
step: 1
steps: 0
sample-rate: 60 / (length / sample-rate)
bluk: make face [size: 60x21 edge: none color: black effect: [draw []]]
bluk/effect/draw: compose [pen green line-width 2 line]
repeat i 60 [
position: i * (length / 60)
insert tail bluk/effect/draw as-pair i (-20 * main) + 20
]
if not none? ~btn-chg [
~btn-chg/image: to image! bluk
show ~btn-chg
]
step: 1
steps: 0
sample-rate: 14.8 * zoom
~curve/effect/draw: compose [
pen 0.0.0 line-width 0.75
fill-pen 0.92.28
box 0x0 (as-pair (to decimal! ~fld-smplen/text) * sample-rate 50)
pen green line-width 3 line
]
repeat i 148 [
position: i * (length / 148)
insert tail ~curve/effect/draw as-pair i (-48 * main) + 48
]
show ~curve
position: old-position
step: old-step
steps: old-steps
sample-rate: old-sample-rate
]
init-gui
init-module: does [
position: 1
steps: 0
step: 1
length: sample-length
repeat i 8 [
set in get bind to word! join "~knb-rt" i 'gui 'data pick rates i
set in get bind to word! join "~knb-lv" i 'gui 'data pick levels i + 1
]
show-curve
show self/gui
]
init-module
]
] "PHiDO2" [
switch-range: func [number blk] [
foreach [rfrom rto action] reduce blk [
if all [number >= rfrom number < rto] [return do action]
]
]
phido2: context [
name: "PHiDO2"
info: "Phase distortion oscillator"
type: 'generator
id: none
input: [DCW none feedback none amplitude none]
output: 'main
value: none
phase: 0
DCA: 0.707106781186548
DCW: 1
DPS: 0
ph: phw: 0
d1: d2: h: l: b: n: f1: q: 0
q1: q2: 1
f1: f2: 1
pole1: 0
wave-length: 400
windows: [
none [1]
sawtooth [1 - phw]
triangle [2 * either phw < 0.5 [phw] [1 - phw]]
trapezoid [either phw < 0.5 [1] [2 * (1 - phw)]]
saw-pulse [either phw < 0.5 [1 - (phw * 2)] [1]]
]
wins: copy []
forskip windows 2 [append wins to string! windows/1]
window: 'none
algorithms: [
sawtooth [
d: (1 - dcw) / 2
cosine 360 * case [0 < ph and (ph <= d) (ph / (2.0 * d))
d < ph and (ph <= 1) (((ph - d / (1 - d)) * 0.5 + 0.5))
]
]
new-sawtooth [
d: (1 - dcw) / 4 + 5E-2
sine 360 * do select reduce [0 < ph and (ph <= d) [ph / d / 4]
d < ph and (ph <= (1 - (d / 4))) [ph + 0.3 - d] (1 - (d / 4)) < ph and (ph <= 1) [0]
] true
]
square [
d: 1 / max 1E-24 (1 - dcw)
cosine 360 * case [0 < ph and (ph < 0.25) (ph * 4 ** d / 4)
0.25 <= ph and (ph <= 0.5) ((abs ph - 0.5) * 4 ** d / 4 + 0.5)
0.5 < ph and (ph <= 0.75) (ph * 4 - 2 ** d / 4 + 0.5)
0.75 < ph and (ph <= 1) ((abs ph - 1) * 4 ** d / 4 + 1)
]
]
pulse [
d: 0.875 * (1 - dcw) + 0.125
cosine 360 * case [0 < ph and (ph <= d) (ph / d)
d < ph and (ph <= 1) 0
]
]
saw-pulse [
d: 1 - dcw / 2 + 0.5
cosine 360 * case [0 < ph and (ph <= d) ph
d < ph and (ph <= 1) 1
]
]
sine-sync [
cosine 360 * ph * (1 + (15 * dcw))
]
triangle [
d: 1 - (dcw * 0.41111)
cosine 360 * case [0 < ph and (ph <= 0.25) (ph * 4 ** d / 4)
0.25 < ph and (ph <= 0.5) ((abs ph - 0.5) * 4 ** d / 4 + 0.5)
0.5 < ph and (ph <= 0.75) (ph * 4 - 2 ** d / 4 + 0.5)
0.75 < ph and (ph <= 1) ((abs ph - 1) * 4 ** d / 4 + 1)
]
]
no-wave [none]
]
algorithm: [sawtooth no-wave]
octave-modulation: true
curves: copy []
forskip algorithms 2 [append curves to string! algorithms/1]
filters: [
none [snd-value]
low-pass [q1 * l]
by-pass [q1 * b]
hi-pass [q1 * h]
notch [n]
]
filts: copy [] forskip filters 2 [append filts to string! filters/1]
filter: 'none
export: has [enves] [
enves: copy []
foreach env envelopes [append/only enves env/export]
reduce ['DCA DCA 'DCW DCW 'DPS DPS 'q q 'f1 f1 'wave-length wave-length 'window window 'algorithm head algorithm 'filter filter 'envelopes enves]
]
sync?: false
phaser: func [] [
sync?: false
phase: 1 / (wave-length * (2 ** vibrato-amount) * (4 ** (envelopes/1/value - 0.5 * -2))) + phase
if phase >= 1 [
sync?: true
phase: phase - 1
if not none? algorithm/2 [
octave-modulation: not octave-modulation
]
]
phase
]
envelopes: make block! 6
env-backup: make block! 6
loop 6 [append envelopes make ese []]
envelopes/1/rates: [0 1 0 0 0 0 0 0]
envelopes/1/levels: [0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]
foreach envelope envelopes [envelope/init-module envelope/init-gui]
init-envs: does [
foreach envelope envelopes [envelope/init-module]
]
dummy-env: context [main: [] value: 1]
dummy-envs: does [
env-backup: copy envelopes
envelopes: make block! 6
loop 6 [append envelopes make dummy-env []]
envelopes/1/value: 0.5
]
revert-envs: does [
envelopes: copy env-backup
]
init-envs
init-module: does [
if not none? algorithm/2 [
octave-modulation: not octave-modulation
]
~rot-flt/data: find head ~rot-flt/data to string! filter
~knb-dcw/data: ~fld-dcw/text: dcw
~knb-dps/data: ~fld-dps/text: dps
~knb-cut/data: ~fld-cut/text: f1
~knb-res/data: ~fld-res/text: q
~knb-dca/data: (square-root dca) / 2
~fld-dca/text: 20 * log-10 dca
repeat i 7 [set in get bind to word! join "~rw1" i 'gui 'data off]
set in get bind to word! join "~rw1" (index? find algorithms algorithm/1) + 1 / 2 'gui 'data on
repeat i 8 [set in get bind to word! join "~rw2" i 'gui 'data off]
set in get bind to word! join "~rw2" (index? find algorithms algorithm/2) + 1 / 2 'gui 'data on
repeat i 5 [set in get bind to word! join "~rwi" i 'gui 'data off]
set in get bind to word! join "~rwi" (index? find windows window) + 1 / 2 'gui 'data on
show gui
show-curve
init-envs
]
main: func [] [
ph: phaser
foreach env envelopes [env/main]
algo: pick algorithm octave-modulation
if equal? 'no-wave algo [algo: pick algorithm not octave-modulation]
either equal? 'no-wave algorithm/2 [
phw: ph
] [
phw: ph / 2 + either octave-modulation [0] [0.5]
]
dcws: dcw
dcw: dcw * envelopes/2/value
ph: min 1 (1.0 + (dps * envelopes/3/value)) ** 6 * ph
snd-value: 2 * ((do select windows window) * (((do select algorithms algo) - 1) / 2)) + 1
dcw: dcws
q1: 1 / max 1E-24 q * 3.0 * envelopes/5/value + 1.0
f2: sine (f1 * envelopes/4/value * 90.0)
d2: l: f2 * d1 + d2
h: snd-value - l - (q1 * d1)
d1: b: f2 * h + d1
n: h + l
value: min 1 max -1 envelopes/6/value * dca * (do select filters filter)
]
~knb-dcw: ~knb-dps: ~knb-cut: ~knb-res: ~knb-dca:
~fld-dcw: ~fld-dps: ~fld-cut: ~fld-res: ~fld-dca:
~txt-amp:
~dd1: ~dd2:
~b1: ~b2: ~b3: ~b4: ~b5: ~b6:
~rw11: ~rw12: ~rw13: ~rw14: ~rw15: ~rw16: ~rw17:
~rw21: ~rw22: ~rw23: ~rw24: ~rw25: ~rw26: ~rw27: ~rw28:
~rwi1: ~rwi2: ~rwi3: ~rwi4: ~rwi5:
~rot-flt:
~name:
~curve: none
waves.img: load as-binary decompress 64#{
eJwB/AID/YlQTkcNChoKAAAADUlIRFIAAAAjAAAAkQgCAAAAxrmWcAAAAAFzUkdC
AK7OHOkAAAAEZ0FNQQAAsY8L/GEFAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1
MAAA6mAAADqYAAAXcJy6UTwAAAJ6SURBVGhD7ZjrbsMgDIX7bHuyPcT+7WG7qFQJ
NQYfXyBL5CmaNtX1hy9wTB6PlT/P5/f2fP3+zHve4RTMVN4HqQQ0iceQJvG6pHCe
QArkQaQQnoLk5KlJZp6RZOC5SCpeAAnkhZFEXjBpwJtCYnkTSYQ3nbTzVsrti1U0
SfWo1HnzbMyedhRIUl2YzN5r3sre25siOyI74vNqddOOUInZcUask17POQ2K7zuY
E0j71RpcKW5GY0qS5k3JR/bqna89BcSCJUlM0cDgyF5bmNhSJSmgTr2SBJZKfuvm
iaP+rkzSamvPfp3YBihhHQS0c20zN2mZQQe5lJD124PZSYPlsx/9e5K4o1sDoxLe
jiQGtL//Yk6j9jNta7V7lniwKKE3JlzdF5FATFsOdfa8JFBzVRgSlqyEtjO+vZDJ
b6h2+fHI/Nn33N7ayYCgDZFRd+KCzZ6hNUakwmDXHkka+wojiY5EgzYTxiksgAS6
AM26+rR9ALoAzSAlHG+Xi5BUy1QZl/SM9GmQwCuQtGvU2h/Z035Ta38REpEr8d9T
77mImNrrhHgnQ5IWJqt7K/a2uUxHauPAI1OQnDMFSvKPFRAJSZFoI5NEF2CDCCQc
w95tR3NEe0dQbbXBJNKNSRuNuESe5MH00micLJGUkuXyb6gQR4hNDeu+N0IcITY7
zDgbIQyyz+R7rsppz3iL7CTNrQsY8jfUESGk+sigHVEAM34nyZPVG2evTNWTuq44
p6fRDF4JgFeNWB6959ZamSTp9Do7e2RgizrRjxt1b1qLJ62T3pBhYexEvmtELSJJ
nkxm9gKyV2Rx6pN1CqiTxwX43awTmCjWbHn21mjuH74rxHHG2MGHAAAAAElFTkSu
QmCCLDJbrvwCAAA=
}
windows.img: load as-binary decompress 64#{
eJzrDPBz5+WS4mJgYOD19HAJAtLKQBzNwQQky06tXgSkWNIdfR0ZGDb2c/9JZGVg
YOzzdHEMyXB+eyO677ACD+uFdblhZt0v7utsE+7s+LTlvalZkPYqj78rPgbyHlTp
P37u/Ouv0rV3658n1f2bV3h96n+PZ5/mvZrpXc5rc9X66urv2zYr2eW6vnm9a+XD
dVfcZaNLDwXkXyhu3pNZXv59SnHLYva5ETE2Hl6vsy4qL3Htn3ZmXqBRhbfQU0uP
Bc/VVs7brFKheOkC9xQp/ZhT9/alVXtnHc9h4uG9paTadjRjJYtGz+RfVyzcPDYv
UWjzKrJiaVZRmSi12Durq4b5xMSuFuNK/Rl3Z006YmRkNjWnp6F3qWhaG++S0rSO
rZPELydPfXLa5EZ0V4LXm+7qvKq+BXrbfG+vPn5udWyS9J9JLomrhfosPRSeKSvO
mL0kad6kHktvpmf6ZzcIZHa4etqKaZhGrAlJehh0rMyDc/fS2vic6MW7irnqwvsP
rXiwqipTxU6uP+e++5OJCVwGa2q2SK2xVeEWCpabt6oyq24Cf2TeJKt0vEbeVllp
7bF/8tt3O//P9H+v/sBK7i4wphg8Xf1c1jklNAEArsXPI9cBAAA=
}
gui: none
init-gui: does [
gui: layout/tight compose copy/deep [
styles knob-style
styles stz-styles
style text text 69x20 132.255.250
style field field 69x20
style knob knob 21x21 inner-radius 3
style radio radio 15x9 effect [merge alphamul 50]
origin 2x4
space 2x2
backdrop 33.77.74
panel [
~name: box 15x180
return
panel [
space 2x5
txt "WAVE"
box 37x148 effect [draw [image waves.img 0x0 35x146]] edge [size: 2x2 color: black]
return
txt "1"
box 5x5
panel [
space 5x9
~rw11: radio [algorithm/1: 'sawtooth show-curve] on
~rw12: radio [algorithm/1: 'square show-curve]
~rw13: radio [algorithm/1: 'pulse show-curve]
~rw14: radio [algorithm/1: 'square show-curve]
~rw15: radio [algorithm/1: 'saw-pulse show-curve]
~rw16: radio [algorithm/1: 'triangle show-curve]
~rw17: radio [algorithm/1: 'sine-sync show-curve]
]
return
txt "2"
box 5x5
panel [
space 5x9
~rw21: radio [algorithm/2: 'sawtooth show-curve]
~rw22: radio [algorithm/2: 'square show-curve]
~rw23: radio [algorithm/2: 'pulse show-curve]
~rw24: radio [algorithm/2: 'square show-curve]
~rw25: radio [algorithm/2: 'saw-pulse show-curve]
~rw26: radio [algorithm/2: 'triangle show-curve]
~rw27: radio [algorithm/2: 'sine-sync show-curve]
~rw28: radio [algorithm/2: 'no-wave show-curve] on
]
across
tx 80 "DCO......ENV/LFO"
return
~b1: button [~p4/pane: envelopes/1/gui ~btn-chg: ~b1 envelopes/1/init-module show ~p4]
button-lfo
]
]
return
bar 3x220
return
panel [
space 2x3
panel [
tx "window"
box 37x94 effect [draw [image windows.img 0x0 35x92]] edge [size: 2x2 color: black]
return
tx ""
box 5x0
panel [
space 5x9
~rwi1: radio [window: 'none show-curve] on
~rwi2: radio [window: 'sawtooth show-curve]
~rwi3: radio [window: 'triangle show-curve]
~rwi4: radio [window: 'trapezoid show-curve]
~rwi5: radio [window: 'saw-pulse show-curve]
]
]
bar 90x2
across
tx 30 "DCW"
~fld-dcw: tx 30 "1.0"
~knb-dcw: knob with [data: 1] [dcw: value ~fld-dcw/text: DCW show ~fld-dcw show-curve]
return
~b2: button [~p4/pane: envelopes/2/gui ~btn-chg: ~b2 envelopes/2/init-module show ~p4]
button-lfo
return
tx 30 "DPS"
~fld-dps: tx 30 "0.0"
~knb-dps: knob with [data: 0] [dps: value ~fld-dps/text: DPS show ~fld-dps show-curve]
return
~b3: button [~p4/pane: envelopes/3/gui ~btn-chg: ~b3 envelopes/3/init-module show ~p4]
button-lfo
]
return
bar 3x220
return
~curve: box 150x50 effect [merge luma -70 grid 15x6 0x2 66.155.148 draw []] edge [size: 1x1 color: black]
panel [
across
box 16x150 effect [merge gradmul 0x1 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 rotate -90 translate -47x-2 text 0x0 "DCF" vectorial]]
panel [
across
origin 10x2
space 2x2
tx 50x20 "Filter type" ~rot-flt: rotary 66.155.148 60x20 "none" "low-pass" "by-pass" "notch" "hi-pass" [filter: to word! value show-curve] font-size 10 edge [color: 66.155.148]
return
tx 30 "CUT"
~fld-cut: tx 30 "1.0"
~knb-cut: knob with [data: 1] [f1: value ~fld-cut/text: f1 show ~fld-cut show-curve]
return
~b4: button [~p4/pane: envelopes/4/gui ~btn-chg: ~b4 envelopes/4/init-module show ~p4]
button-lfo
return
tx 30 "RES"
~fld-res: tx 30 "0.0"
~knb-res: knob [q: value ~fld-res/text: value show ~fld-res show-curve]
return
~b5: button [~p4/pane: envelopes/5/gui ~btn-chg: ~b5 envelopes/5/init-module show ~p4]
button-lfo
return
tx 30 "DCA"
~fld-dca: tx 30 "-3.0"
~knb-dca: knob with [data: 0.42] [dca: value * 2 ** 2 ~fld-dca/text: either zero? dca ["-OO"] [round/to 20 * log-10 dca 1E-2] show ~fld-dca show-curve]
return
~b6: button [~p4/pane: envelopes/6/gui ~btn-chg: ~b6 envelopes/6/init-module show ~p4]
button-lfo
return
]
]
]
show-curve
]
show-curve: has [old-wave-length old-phase old-vibrato-amount] [
octave-modulation: true
old-wave-length: wave-length
old-phase: phase
old-vibrato-amount: vibrato-amount
dummy-envs
~curve/effect/draw: copy [pen green line-width 1.5 line]
phase: 0
wave-length: 75
repeat i 2 * wave-length [
insert tail ~curve/effect/draw as-pair i 23 + (-23 * main)
]
show ~curve
phase: old-phase
wave-length: old-wave-length
vibrato-amount: old-vibrato-amount
revert-envs
]
init-gui
]
] "RMX" [
average: func [blk /local tmp] [
tmp: 0
repeat i length? blk [tmp: tmp + blk/:i]
tmp / length? blk
]
RMX: context [
name: "RMX"
info: "Envelope generator"
type: 'effect
id: none
input: none
output: none
value: 0
osc1: none
osc2: none
dca: 1
shaper: 0.5
d1: d2: h: l: b: n: f1: q: 0
q: q1: q2: 1
f1: f2: 1
bit-res: none
freq-div: 1
div-value: 0
div-cache: copy []
modes: [
first-line [osc1]
second-line [osc2]
mix [(osc1 + osc2) / 2.0]
ring [osc1 * osc2]
ring2 [osc1 + 1.0 / 2.0 * (osc2 + 1.0 / 2.0) * 2.0 - 1.0]
mix-ring [(osc1 * osc2 + osc2) / 2.0]
noise [osc1 + (osc2 * (random 10000000.0) / 10000000.0) / 2.0]
]
mode: 'first-line
filters: [
none [snd-value]
low-pass [q1 * l]
by-pass [q1 * b]
hi-pass [q1 * h]
notch [n]
]
filts: copy [] forskip filters 2 [append filts to string! filters/1]
filter: 'none
export: has [enves] [
enves: reduce [module-stack/1/export module-stack/2/export module-stack/6/export]
reduce ['mode mode 'filter filter 'q q 'f1 f1 'envelopes enves]
]
main: func [/local tmp] [
vibrato-phase: 1 / vibrato-wave-length + vibrato-phase // 1.0
vibrato-amount: vibrato-depth * sine 360.0 * vibrato-phase
module-stack/1/main
module-stack/2/main
module-stack/3/main
if ~chk-sync/data and module-stack/3/sync? [module-stack/4/phase: 0]
module-stack/4/main
module-stack/6/main
osc1: module-stack/3/value
osc2: module-stack/4/value
snd-value: do select modes mode
q1: 1 / max 1E-24 q * 3.0 * module-stack/2/value + 1.0
f2: sine (f1 * module-stack/1/value * 90.0)
l: f2 * b + l
h: snd-value - l - (q1 * b)
b: f2 * h + b
n: h + l
value: dca * module-stack/6/value * min 1 max -1 do select filters filter
if ~chk-shaper/data [
absval: abs value
value: (1 / (shaper + 1.0 / 2.0)) * (sign? value) * case [
absval < shaper absval
absval > 1 (shaper + 1.0 / 2.0)
absval >= shaper (shaper + ((absval - shaper) / ((absval - shaper) / (1.0 - shaper) ** 2.0 + 1.0)))
]
]
if not none? bit-res [value: (to integer! value * (2 ** bit-res)) / (2 ** bit-res)]
insert tail div-cache value
if freq-div <= length? div-cache [div-value: average div-cache div-cache: copy []]
value: div-value
]
~t1: ~t2: ~t3:
~b1: ~b2: ~b3:
~knb-cut: ~knb-res: ~knb-dca:
~rot-flt:
~curve: none
gui: none
init-gui: does [
gui: layout/tight compose [
styles stz-styles
style knob knob 21x21 inner-radius 3
backdrop 66.155.148 effect [gradient 0x1 66.155.148 51.51.51]
origin 2
space 2x2
across
panel [
space 0x1
tx 85 "Line selection"
~rl1: radio-line "1" [mode: 'first-line] on
~rl2: radio-line "2" [mode: 'second-line]
~rl3: radio-line "1 + 2" [mode: 'mix]
~rl4: radio-line "1 + 1'"
] edge [size: 1x1 color: black]
panel [
style radio-line radio-line 70x13
space 0x0
tx 85 "Modulation"
~rm1: radio-line "no" [mode: 'mix] on
~rm2: radio-line "ring" [mode: 'ring]
~rm5: radio-line "ring2" [mode: 'ring2]
~rm3: radio-line "mix-ring" [mode: 'mix-ring]
~rm4: radio-line "noise" [mode: 'noise]
] edge [size: 1x1 color: black]
return
bar 180 return
box 150x18 effect [merge gradmul 1x0 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 text 0x0 "DCF + DCA" vectorial]]
return
tx 110 "Filter type"
~rot-flt: rotary 66.155.148 60x20 "none" "low-pass" "by-pass" "notch" "hi-pass" [filter: to word! value] font-size 10 edge [color: 66.155.148]
return
tx "CUTOFF" ~t1: tx "1" ~knb-cut: knob 132.255.250 [f1: value ~t1/text: round/to value 1E-2 show ~t1] with [data: 1]
~b1: button [~p4/pane: module-stack/1/gui ~btn-chg: ~b1 module-stack/1/init-module show ~p4] return
tx "RESO" ~t2: tx "0" ~knb-res: knob 132.255.250 [q: value ~t2/text: round/to value 1E-2 show ~t2] with [data: 0]
~b2: button [~p4/pane: module-stack/2/gui ~btn-chg: ~b2 module-stack/2/init-module show ~p4] return
tx "DCA" ~t3: tx "0.0" ~knb-dca: knob 132.255.250 [dca: value * 2 ** 2 value ~t3/text: either zero? dca ["-OO"] [round/to 20 * log-10 dca 1E-2] show ~t3] with [data: 0.5]
~b3: button [~p4/pane: module-stack/6/gui show ~p4 ~btn-chg: ~b3]
return
box 150x18 effect [merge gradmul 1x0 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 text 0x0 "FinalCrusher" vectorial]]
return
~chk-shaper: check-line "Waveshaper" 90 ~knb-wsh: knob 132.255.250 with [data: 0.5] [shaper: to decimal! value] return
~tx-bit: tx "Bit resolution: full" 90 knob with [data: 1] [either value = 1 [~tx-bit/text: "Bit resolution: full" bit-res: none] [bit-res: to integer! value * 25 ~tx-bit/text: join "Bit resolution: " bit-res] show ~tx-bit] 132.255.250 return
~tx-div: tx "Freq. divider: 1" 90 knob with [data: 1] [freq-div: to integer! 1 - value + 1 ** 6 ~tx-div/text: join "Freq. divider: " freq-div show ~tx-div] 132.255.250 return
]
]
init-gui
init-module: does [
repeat i 4 [set in get bind to word! join "~rl" i 'gui 'data off]
repeat i 4 [set in get bind to word! join "~rm" i 'gui 'data off]
switch mode [
first-line [~rl1/data: on]
second-line [~rl2/data: on]
mix [~rl3/data: on ~rm1/data: on]
ring [~rl3/data: on ~rm2/data: on]
mix-ring [~rl3/data: on ~rm3/data: on]
ring2 [~rl3/data: on ~rm5/data: on]
noise [~rl3/data: on ~rm4/data: on]
]
~rot-flt/data: find head ~rot-flt/data to string! filter
~knb-cut/data: ~t1/text: f1
~knb-res/data: ~t2/text: q
show self/gui
]
]
]]
add-module "ese"
add-module "ese"
add-module "phido2"
add-module "phido2"
add-module "rmx"
add-module "ese"
module-stack/1/init-module
module-stack/1/init-gui
module-stack/2/init-module
module-stack/2/init-gui
module-stack/6/init-module
module-stack/6/init-gui
detune-osc: has [freq] [
freq: sample-rate / module-stack/3/wave-length
freq: freq * (2 ** to integer! ~det-oct/text) * (1.0594630943593 ** to integer! ~det-not/text) * (1.00057778950655 ** to integer! ~det-cen/text)
module-stack/4/wave-length: sample-rate / freq
]
export-wav: does [
wav-sample: copy 64#{}
forall sauple [
insert tail wav-sample itble2 to integer! 32767 * sauple/1 - 1
]
wav: wav-structure wav-sample
attempt [write/binary first request-file/save wav]
]
export: does [
attempt [save/header first request-file/save reduce [
'OSC1 module-stack/3/export
'OSC2 module-stack/4/export
'MIX module-stack/5/export
'DETUNE reduce [~det-oct/text ~det-not/text ~det-cen/text]
'VIBRATO reduce [vibrato-depth vibrato-wave-length]
'PITCH reduce [pitch]
'LENGTH reduce [sample-length]
'SYNC reduce [~chk-sync/data]
] compose [
Title: "Sintezar PM-101 Sound"
Version: 0.0.1
Date: (now)
]]
]
import: has [tmp-preset osc1 osc1-envs osc2 osc2-envs mix] [
tmp-preset: attempt [load/header first request-file]
if found? find tmp-preset 'osc1 [
osc1-envs: last tmp-preset/osc1
osc1: head remove/part back back tail tmp-preset/osc1 2
foreach [word value] osc1 [set in module-stack/3 word value]
repeat i 6 [
module-stack/3/envelopes/:i/rates: osc1-envs/:i/rates
module-stack/3/envelopes/:i/levels: osc1-envs/:i/levels
]
module-stack/3/init-module
osc2-envs: last tmp-preset/osc2
osc2: head remove/part back back tail tmp-preset/osc2 2
foreach [word value] osc2 [set in module-stack/4 word value]
repeat i 6 [
module-stack/4/envelopes/:i/rates: osc2-envs/:i/rates
module-stack/4/envelopes/:i/levels: osc2-envs/:i/levels
]
module-stack/4/init-module
module-stack/1/rates: tmp-preset/mix/envelopes/1/rates
module-stack/1/levels: tmp-preset/mix/envelopes/1/levels
module-stack/2/rates: tmp-preset/mix/envelopes/2/rates
module-stack/2/levels: tmp-preset/mix/envelopes/2/levels
module-stack/6/rates: tmp-preset/mix/envelopes/3/rates
module-stack/6/levels: tmp-preset/mix/envelopes/3/levels
mix: head remove/part back back tail tmp-preset/mix 2
foreach [word value] mix [set in module-stack/5 word value]
module-stack/5/init-module
~det-oct/text: tmp-preset/detune/1
~det-not/text: tmp-preset/detune/2
~det-cen/text: tmp-preset/detune/3
show reduce [~det-oct ~det-not ~det-cen]
vibrato-depth: to decimal! tmp-preset/vibrato/1
~vib-dep/text: to string! tmp-preset/vibrato/1
vibrato-wave-length: to decimal! tmp-preset/vibrato/2
~vib-rat/text: sample-rate / vibrato-wave-length
show reduce [~vib-rat ~vib-dep]
pitch: tmp-preset/pitch/1
sample-length: tmp-preset/length/1
~fld-smplen/text: to string! sample-length / sample-rate
show ~fld-smplen
~chk-sync/data: first reduce tmp-preset/sync
show ~chk-sync
]
]
sauple: copy 64#{}
make-sound: does [
module-stack/3/wave-length: sample-rate / (oct * pitch)
freq: sample-rate / module-stack/3/wave-length
freq: freq * (2 ** to integer! ~det-oct/text) * (1.0594630943593 ** to integer! ~det-not/text) * (1.00057778950655 ** to integer! ~det-cen/text)
module-stack/4/wave-length: sample-rate / freq
module-stack/3/phase: 0
module-stack/4/phase: 0
vibrato-phase: 0
sample: make binary! sample-length
sauple: copy []
x: now/time/precise
loop sample-length [
module-stack/5/main
insert tail sample do rejoin ["#{" skip to-hex to integer! (module-stack/5/value + 1) * 32767.5 4 "}"]
insert tail sauple module-stack/5/value
if (length? sample) // 100 = 0 [~prog/data: (length? sauple) / sample-length show ~prog]
]
~ttt/text: now/time/precise - x
show ~ttt
~sample-window/effect/draw: copy [pen green fill-pen linear 0x0 0 100 90 1 1 red yellow green yellow red line-width 0.5 polygon 0x50]
length: 690
repeat i length [
insert tail ~sample-window/effect/draw as-pair i (pick sauple (length? sauple) / length * i) * -50 + 50
]
insert tail ~sample-window/effect/draw 690x50
show ~sample-window
module-stack/1/init-module
module-stack/2/init-module
module-stack/6/init-module
foreach env module-stack/3/envelopes [env/init-module]
foreach env module-stack/4/envelopes [env/init-module]
]
bold32: make face/font [style: 'bold size: 32]
bold12: make face/font [size: 12]
pitches: [
261.625565300616 293.66476791743 329.627556912897 349.228231433035 391.995435981787 440 493.883301256181
]
intro-image: to image! make face [
edge: none
color: none
size: 703x584
effect: [
merge
key 0.0.0
draw [
image-filter bilinear
image logo.png 170x110 510x110 550x270 130x270 0.0.0
image logo.png 180x100 500x100 540x280 140x280 0.0.0
image logo.png 190x90 490x90 530x290 150x290 0.0.0
]
blur sharpen blur contrast 50 blur sharpen blur
luma -30
colorize 132.255.250
]
]
synth: layout [
backdrop 51.51.51
styles stz-styles
styles knob-style
style text txt bold 132.255.250 font-size 11 with [origin: 0x0 margin: 0x0]
style knob knob 16x16 inner-radius 3 66.155.148 51.51.51 255.255.255
style button button 40x26 effect [merge multiply 30.50.50] edge [size: 2x2 color: 30.50.50] font-size 8
style tx txt white bold font-size 9 43x12 with [origin: 0x0 margin: 0x0]
style panel panel edge [color: 66.155.148 size: 0x0 effect: none]
style imag image 24x24 font-size 9 font-color 132.255.250 with [
font: make font [valign: 'bottom]
feel: make feel [
over: func [f a p] [
either a [
append f/effect [luma 100]
] [
remove back back tail f/effect 2
]
show f
]
engage: func [face action event] [
remove/part find face/effect 'luma 2
switch action [
time [if not face/state [face/blinker: not face/blinker]]
down [face/state: on]
alt-down [face/state: on]
up [if face/state [do-face face face/text] face/state: off]
alt-up [if face/state [do-face-alt face face/text] face/state: off]
over [face/state: on]
away [face/state: off]
]
cue face action
show face
]
]
]
origin 5
space 2x2
below
~p0: panel 120x442 [
size 118x440
styles stz-styles
style knob knob 16x16
style button button 40x21 effect [merge multiply 30.50.50] edge [size: 2x2 color: 30.50.50] font-size 8
backdrop 66.155.148 effect [gradient 0x-1 66.155.148 51.51.51 grid 0x0 66.155.148]
origin 0
space 0
across
image logo.png effect [key black colorize 132.255.250 blur]
return
text font-size 10 132.255.250 "phase manipulation digital synthesizer" 110x30
return
panel [
space 2x2
below
box 100x18 effect [merge gradmul 1x0 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 text 0x0 "detune" vectorial]]
panel [
tx 38x15 "OCT"
tx 38x15 "NOTE"
tx 38x15 "CENT"
return
~det-oct: tx 25x15 "0"
~det-not: tx 25x15 "0"
~det-cen: tx 25x15 "0"
return
knob with [data: 0.5] [~det-oct/text: to integer! value - 0.5 * 4 show ~det-oct detune-osc]
knob with [data: 0.5] [~det-not/text: to integer! value - 0.5 * 24 show ~det-not detune-osc]
knob with [data: 0.5] [~det-cen/text: to integer! value - 0.5 * 200 show ~det-cen detune-osc]
]
return
] edge [size: 0x0]
return
panel [
below
space 2x2
box 100x18 effect [merge gradmul 1x0 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 text 0x0 "vibrato" vectorial]]
panel [
styles stz-styles
space 28x2
tx 38x15 "RATE"
~vib-rat: field 50x15 "0" [vibrato-wave-length: sample-rate / (max 1E-24 to decimal! value) ~knb-vib-rat/data: (to decimal! value) / 1000 ** 0.1 show ~knb-vib-rat]
tx 38x15 "DEPTH"
~vib-dep: tx 50x15 "0"
space 30x17
return
~knb-vib-rat: knob [~vib-rat/text: round/to value ** 10 * 1000 1E-4 vibrato-wave-length: sample-rate / (max 1E-24 to decimal! ~vib-rat/text) show ~vib-rat detune-osc]
~knb-vib-dep: knob [~vib-dep/text: round/to vibrato-depth: value ** 3 1E-6 show ~vib-dep detune-osc]
] edge [size: 0x0]
toolpanel group 1 [
origin 0
space 0
across
tool sine.png
tool triangle.png
tool pulse.png
tool saw.png
]
] edge [size: 0x0]
return
~chk-sync: check-line "OSC SYNC"
return
radio [oct: 0.125] radio [oct: 0.25] radio [oct: 0.5] radio [oct: 1] on radio [oct: 2] radio [oct: 4] radio [oct: 8]
return
box 2x2 image keyboard.png effect [draw []] with [
feel: make feel [
engage: func [f a e] [
switch a [
down [
either e/offset/y > 41 [
pitch: (pick pitches 1 + to integer! e/offset/x / 14)
f/effect/draw: compose [pen red circle (as-pair 14 * (to integer! e/offset/x / 14) + 7 60) 5 5]
show f
] [
print "pultony"
]
]
]
]
]
]
] edge [size: 1x1 color: 66.155.148]
return
~p1: panel 376x220 []
~p2: panel 376x220 []
return
space 0
~p3: panel 182x280 []
~p4: panel 181x190 []
return
space 0
at 5x451 ~sample-window: box 687x104 51.51.51 effect [grid 43x25 0x12 33.78.74 grid 86x25 0x0 66.155.148 draw []] edge [size: 2x2 color: 66.155.148]
panel [
styles stz-styles
space 2
across
backdrop effect [gradient 0x-1 51.51.51 66.155.148]
imag toolbox-images/new-project effect [key white invert colorize 132.255.250 fit]
imag toolbox-images/open-project effect [key white colorize 132.255.250 fit] [import]
imag toolbox-images/save-project effect [key white colorize 132.255.250 fit] "rps" [export]
imag toolbox-images/save-project effect [key white colorize 132.255.250 fit] "wav" [export-wav]
imag toolbox-images/make-sound effect [key white invert colorize 132.255.250 fit] [make-sound]
imag toolbox-images/play-sound effect [key white invert colorize 132.255.250 fit] [
snd: make sound [rate: 44100 bits: 16 volume: 1 data: sample]
if not empty? sample [
insert sndport snd
wait []
]
]
tx "length" ~fld-smplen: field "1" [
sample-length: to integer! sample-rate * to decimal! value
module-stack/1/init-module
module-stack/2/init-module
module-stack/3/init-module
module-stack/4/init-module
module-stack/6/init-module
]
~ttt: tx white 100x12
~prog: progress 115 51.51.51 132.255.250 edge [size: 1x1]
]
at 0x0 image intro-image effect [
key 0.0.0
merge luma -70 blur blur blur contrast 50 blur blur blur luma -30 gradmul 0x-1 80.80.80 127.127.127
]
at 0x270 ~bb: box 698x100 effect [
draw [
line-width 0.5 pen 132.255.250 fill-pen linear 300x0 0 100 30 1 1 black white black white black white reflect font bold32 text 65x5 "Phase Manipulation Digital Synthesizer" vectorial
font bold12 text 500x45 "written by REBolek, (c) 2005" vectorial
pen 250.255.250 line-width 0.1
font bold12 text 280x80 "press here to continue" vectorial
]
emboss
colorize 132.255.250
] [remove/part back back tail synth/pane 2 show synth] with [
saved-area: true
rate: 0
feel: make feel [
n: 0
engage: func [face action event] [
switch action [
time [
n: n + 2
change skip face/effect/draw 6 as-pair n 0
change skip face/effect/draw 33 n // 10.0 / 5
]
down [face/state: on]
alt-down [face/state: on]
up [if face/state [do-face face face/text] face/state: off]
alt-up [if face/state [do-face-alt face face/text] face/state: off]
over [face/state: on]
away [face/state: off]
]
cue face action
show face
]
]
]
]
module-stack: head module-stack
~p1/pane: module-stack/3/gui
~p2/pane: module-stack/4/gui
~p3/pane: module-stack/5/gui
~p4/pane: module-stack/1/gui
~chk-sync/data: false
module-stack/3/~name/effect: [merge gradmul 0x1 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 rotate -90 translate -47x-2 text 0x0 "DCO1" vectorial]]
module-stack/4/~name/effect: [merge gradmul 0x1 black 127.127.127 draw [line-width 0.5 pen white fill-pen 132.255.250 font ~fnt-h3 rotate -90 translate -47x-2 text 0x0 "DCO2" vectorial]]
clipboard-envelope: copy [rates [] levels []]
melody-parser: does [
ot: now/time/precise
parse melody [
some [
set time tuple! ()
any [
set nt string! (note: nt)
| set nt 'none (note: none)
| set param word! set value number! ()
]
]
]
~t2/text: now/time/precise - ot show ~t2
]
view center-face synth Notes
|