vizcore 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +66 -648
- data/docs/assets/playground-worker.js +373 -0
- data/docs/assets/playground.css +440 -0
- data/docs/assets/playground.js +652 -0
- data/docs/index.html +2 -1
- data/docs/playground.html +81 -0
- data/docs/shape_dsl.md +269 -0
- data/frontend/index.html +50 -2
- data/frontend/src/audio-inspector.js +9 -0
- data/frontend/src/custom-shape-param-controls.js +106 -0
- data/frontend/src/live-controls.js +219 -7
- data/frontend/src/main.js +703 -45
- data/frontend/src/mapping-target-selector.js +109 -0
- data/frontend/src/midi-learn.js +22 -2
- data/frontend/src/performance-monitor.js +137 -1
- data/frontend/src/renderer/engine.js +401 -11
- data/frontend/src/renderer/layer-manager.js +490 -75
- data/frontend/src/runtime-control-preset.js +44 -0
- data/frontend/src/scene-patches.js +159 -0
- data/frontend/src/shader-error-overlay.js +1 -0
- data/frontend/src/shape-editor-controls.js +157 -0
- data/frontend/src/visuals/geometry.js +425 -27
- data/frontend/src/visuals/image-renderer.js +19 -0
- data/frontend/src/visuals/particle-system.js +10 -0
- data/frontend/src/visuals/shape-renderer.js +488 -0
- data/frontend/src/visuals/spectrogram-renderer.js +14 -0
- data/frontend/src/visuals/svg-arc.js +104 -0
- data/frontend/src/visuals/text-renderer.js +13 -0
- data/frontend/src/websocket-client.js +6 -0
- data/lib/vizcore/analysis/adaptive_normalizer.rb +20 -2
- data/lib/vizcore/analysis/bpm_estimator.rb +18 -8
- data/lib/vizcore/analysis/feature_recorder.rb +117 -7
- data/lib/vizcore/analysis/feature_replay.rb +48 -9
- data/lib/vizcore/analysis/pipeline.rb +258 -9
- data/lib/vizcore/analysis/tap_tempo.rb +17 -2
- data/lib/vizcore/audio/calibration.rb +156 -0
- data/lib/vizcore/audio/file_input.rb +28 -0
- data/lib/vizcore/audio/input_manager.rb +36 -1
- data/lib/vizcore/audio/midi_input.rb +5 -0
- data/lib/vizcore/audio/ring_buffer.rb +22 -0
- data/lib/vizcore/audio.rb +1 -0
- data/lib/vizcore/cli/dsl_reference.rb +65 -9
- data/lib/vizcore/cli/plugin_checker.rb +93 -0
- data/lib/vizcore/cli/scene_diagnostics.rb +2 -2
- data/lib/vizcore/cli/scene_inspector.rb +35 -1
- data/lib/vizcore/cli/scene_validator.rb +573 -33
- data/lib/vizcore/cli/shader_template.rb +7 -2
- data/lib/vizcore/cli/shader_uniform_docs.rb +11 -0
- data/lib/vizcore/cli.rb +268 -15
- data/lib/vizcore/config.rb +40 -3
- data/lib/vizcore/control_preset.rb +29 -0
- data/lib/vizcore/deep_copy.rb +21 -0
- data/lib/vizcore/dsl/color_helpers.rb +155 -0
- data/lib/vizcore/dsl/engine.rb +219 -23
- data/lib/vizcore/dsl/layer_builder.rb +1072 -21
- data/lib/vizcore/dsl/layer_group_builder.rb +10 -12
- data/lib/vizcore/dsl/layout_helpers.rb +290 -0
- data/lib/vizcore/dsl/mapping_preset_builder.rb +41 -0
- data/lib/vizcore/dsl/mapping_resolver.rb +549 -13
- data/lib/vizcore/dsl/mapping_transform_builder.rb +50 -0
- data/lib/vizcore/dsl/midi_map_executor.rb +219 -23
- data/lib/vizcore/dsl/reaction_builder.rb +1 -0
- data/lib/vizcore/dsl/scene_builder.rb +83 -13
- data/lib/vizcore/dsl/shader_source_resolver.rb +1 -10
- data/lib/vizcore/dsl/style_builder.rb +3 -0
- data/lib/vizcore/dsl/timeline_builder.rb +91 -8
- data/lib/vizcore/dsl/transition_controller.rb +157 -18
- data/lib/vizcore/dsl.rb +2 -0
- data/lib/vizcore/layer_catalog.rb +5 -2
- data/lib/vizcore/plugin_asset_policy.rb +55 -0
- data/lib/vizcore/project_manifest.rb +12 -2
- data/lib/vizcore/renderer/render_sequence.rb +104 -13
- data/lib/vizcore/renderer/scene_frame_source.rb +190 -12
- data/lib/vizcore/renderer/scene_serializer.rb +38 -0
- data/lib/vizcore/renderer/snapshot.rb +4 -3
- data/lib/vizcore/renderer/snapshot_renderer.rb +641 -23
- data/lib/vizcore/scene_trust.rb +31 -0
- data/lib/vizcore/server/frame_broadcaster.rb +513 -18
- data/lib/vizcore/server/rack_app.rb +151 -4
- data/lib/vizcore/server/runner.rb +697 -82
- data/lib/vizcore/server/websocket_handler.rb +236 -14
- data/lib/vizcore/server.rb +21 -0
- data/lib/vizcore/shape.rb +742 -0
- data/lib/vizcore/sync/osc_message.rb +66 -9
- data/lib/vizcore/version.rb +1 -1
- data/lib/vizcore.rb +34 -0
- data/scripts/browser_capture.mjs +31 -2
- data/sig/vizcore.rbs +154 -4
- metadata +29 -3
|
@@ -4,37 +4,46 @@ module Vizcore
|
|
|
4
4
|
module Sync
|
|
5
5
|
# Minimal OSC 1.0 message parser for control sync.
|
|
6
6
|
class OscMessage
|
|
7
|
-
attr_reader :address, :arguments
|
|
7
|
+
attr_reader :address, :arguments, :timetag
|
|
8
8
|
|
|
9
9
|
# @param data [String]
|
|
10
|
-
# @return [Vizcore::Sync::OscMessage, nil]
|
|
10
|
+
# @return [Vizcore::Sync::OscMessage, Array<Vizcore::Sync::OscMessage>, nil]
|
|
11
11
|
def self.parse(data)
|
|
12
12
|
parser = Parser.new(data)
|
|
13
|
-
|
|
14
|
-
return nil unless address&.start_with?("/")
|
|
15
|
-
|
|
16
|
-
tags = parser.read_string
|
|
17
|
-
arguments = parser.read_arguments(tags)
|
|
18
|
-
new(address: address, arguments: arguments)
|
|
13
|
+
parser.parse_packet
|
|
19
14
|
rescue StandardError
|
|
20
15
|
nil
|
|
21
16
|
end
|
|
22
17
|
|
|
23
18
|
# @param address [String]
|
|
24
19
|
# @param arguments [Array]
|
|
25
|
-
|
|
20
|
+
# @param timetag [Float, nil]
|
|
21
|
+
def initialize(address:, arguments: [], timetag: nil)
|
|
26
22
|
@address = address
|
|
27
23
|
@arguments = Array(arguments)
|
|
24
|
+
@timetag = timetag
|
|
28
25
|
end
|
|
29
26
|
|
|
30
27
|
# @api private
|
|
31
28
|
class Parser
|
|
29
|
+
BUNDLE_SIGNATURE = "#bundle"
|
|
30
|
+
NTP_TO_UNIX_OFFSET = 2_208_988_800
|
|
31
|
+
|
|
32
32
|
# @param data [String]
|
|
33
33
|
def initialize(data)
|
|
34
34
|
@data = data.to_s.b
|
|
35
35
|
@offset = 0
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# @return [Vizcore::Sync::OscMessage, Array<Vizcore::Sync::OscMessage>, nil]
|
|
39
|
+
def parse_packet(default_timetag: nil)
|
|
40
|
+
signature_or_address = read_string
|
|
41
|
+
return nil unless signature_or_address
|
|
42
|
+
|
|
43
|
+
return parse_bundle if signature_or_address == BUNDLE_SIGNATURE
|
|
44
|
+
parse_message(signature_or_address, timetag: default_timetag)
|
|
45
|
+
end
|
|
46
|
+
|
|
38
47
|
# @return [String, nil]
|
|
39
48
|
def read_string
|
|
40
49
|
start = @offset
|
|
@@ -47,6 +56,42 @@ module Vizcore
|
|
|
47
56
|
value
|
|
48
57
|
end
|
|
49
58
|
|
|
59
|
+
def parse_bundle
|
|
60
|
+
bundle_timetag = parse_timetag(read_uint64)
|
|
61
|
+
messages = []
|
|
62
|
+
|
|
63
|
+
until @offset >= @data.bytesize
|
|
64
|
+
break if @offset + 4 > @data.bytesize
|
|
65
|
+
|
|
66
|
+
begin
|
|
67
|
+
message_size = read_int32
|
|
68
|
+
rescue StandardError
|
|
69
|
+
break
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
break if message_size <= 0
|
|
73
|
+
|
|
74
|
+
begin
|
|
75
|
+
message_data = read_bytes(message_size)
|
|
76
|
+
rescue StandardError
|
|
77
|
+
break
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
parsed = Parser.new(message_data).parse_packet(default_timetag: bundle_timetag)
|
|
81
|
+
messages.concat(Array(parsed))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
messages
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def parse_message(address, timetag: nil)
|
|
88
|
+
return nil unless address&.start_with?("/")
|
|
89
|
+
|
|
90
|
+
tags = read_string
|
|
91
|
+
arguments = read_arguments(tags)
|
|
92
|
+
OscMessage.new(address: address, arguments: arguments, timetag: timetag)
|
|
93
|
+
end
|
|
94
|
+
|
|
50
95
|
# @param tags [String, nil]
|
|
51
96
|
# @return [Array]
|
|
52
97
|
def read_arguments(tags)
|
|
@@ -86,6 +131,10 @@ module Vizcore
|
|
|
86
131
|
read_bytes(4).unpack1("g")
|
|
87
132
|
end
|
|
88
133
|
|
|
134
|
+
def read_uint64
|
|
135
|
+
read_bytes(8).unpack1("Q>")
|
|
136
|
+
end
|
|
137
|
+
|
|
89
138
|
def read_bytes(length)
|
|
90
139
|
raise ArgumentError, "OSC payload truncated" if @offset + length > @data.bytesize
|
|
91
140
|
|
|
@@ -94,6 +143,14 @@ module Vizcore
|
|
|
94
143
|
end
|
|
95
144
|
end
|
|
96
145
|
|
|
146
|
+
def parse_timetag(raw)
|
|
147
|
+
return nil if raw == 0
|
|
148
|
+
|
|
149
|
+
seconds = (raw >> 32) - NTP_TO_UNIX_OFFSET
|
|
150
|
+
fraction = raw & 0xFFFF_FFFF
|
|
151
|
+
seconds + (fraction / 4_294_967_296.0)
|
|
152
|
+
end
|
|
153
|
+
|
|
97
154
|
def align_offset
|
|
98
155
|
@offset += 1 while (@offset % 4).positive?
|
|
99
156
|
end
|
data/lib/vizcore/version.rb
CHANGED
data/lib/vizcore.rb
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "vizcore/version"
|
|
4
|
+
require_relative "vizcore/deep_copy"
|
|
4
5
|
require_relative "vizcore/errors"
|
|
5
6
|
require_relative "vizcore/layer_catalog"
|
|
7
|
+
require_relative "vizcore/plugin_asset_policy"
|
|
8
|
+
require_relative "vizcore/scene_trust"
|
|
9
|
+
require_relative "vizcore/shape"
|
|
6
10
|
require_relative "vizcore/dsl"
|
|
11
|
+
require_relative "vizcore/analysis"
|
|
12
|
+
require_relative "vizcore/audio"
|
|
7
13
|
require "pathname"
|
|
8
14
|
|
|
9
15
|
# Main namespace for the Vizcore runtime and DSL entrypoints.
|
|
@@ -28,6 +34,19 @@ module Vizcore
|
|
|
28
34
|
root.join("lib", "vizcore", "templates")
|
|
29
35
|
end
|
|
30
36
|
|
|
37
|
+
# @param command_available [#call, nil] optional command lookup for tests
|
|
38
|
+
# @return [Hash<Symbol, Boolean>] optional runtime feature availability
|
|
39
|
+
def self.features(command_available: nil)
|
|
40
|
+
command_available ||= method(:command_available?)
|
|
41
|
+
{
|
|
42
|
+
mic: feature_available? { Audio::PortAudioFFI.available? },
|
|
43
|
+
midi: feature_available? { Audio::MidiInput.available? },
|
|
44
|
+
ffmpeg: command_available.call("ffmpeg"),
|
|
45
|
+
browser_capture: root.join("scripts", "browser_capture.mjs").file? && command_available.call("node"),
|
|
46
|
+
fftw: feature_available? { Analysis::FFTProcessor.fftw_available? }
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
31
50
|
# Evaluate a Vizcore DSL definition block.
|
|
32
51
|
#
|
|
33
52
|
# @yield DSL configuration block (`audio`, `scene`, `midi_map`, etc.)
|
|
@@ -61,4 +80,19 @@ module Vizcore
|
|
|
61
80
|
description: description
|
|
62
81
|
)
|
|
63
82
|
end
|
|
83
|
+
|
|
84
|
+
def self.feature_available?
|
|
85
|
+
!!yield
|
|
86
|
+
rescue StandardError
|
|
87
|
+
false
|
|
88
|
+
end
|
|
89
|
+
private_class_method :feature_available?
|
|
90
|
+
|
|
91
|
+
def self.command_available?(command)
|
|
92
|
+
ENV.fetch("PATH", "").split(File::PATH_SEPARATOR).any? do |directory|
|
|
93
|
+
path = File.join(directory, command)
|
|
94
|
+
File.file?(path) && File.executable?(path)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
private_class_method :command_available?
|
|
64
98
|
end
|
data/scripts/browser_capture.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
const options = parseArgs(process.argv.slice(2));
|
|
5
5
|
|
|
6
6
|
if (!options.url) {
|
|
7
|
-
console.error("Usage: node scripts/browser_capture.mjs URL --out browser-capture.png [--selector #vizcore-canvas] [--wait 1000]");
|
|
7
|
+
console.error("Usage: node scripts/browser_capture.mjs URL --out browser-capture.png [--selector #vizcore-canvas] [--wait 1000] [--wait-for-frame]");
|
|
8
8
|
process.exit(1);
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -24,8 +24,11 @@ try {
|
|
|
24
24
|
await page.waitForTimeout(options.wait);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const element = page
|
|
27
|
+
const element = await resolveCaptureLocator(page, options.selector);
|
|
28
28
|
await element.waitFor({ state: "visible", timeout: 10000 });
|
|
29
|
+
if (options.waitForFrame) {
|
|
30
|
+
await waitForVizcoreFrame(page, options.frameTimeout);
|
|
31
|
+
}
|
|
29
32
|
await fs.mkdir(path.dirname(options.out), { recursive: true });
|
|
30
33
|
await element.screenshot({ path: options.out });
|
|
31
34
|
console.log(`Browser capture written: ${options.out}`);
|
|
@@ -33,6 +36,25 @@ try {
|
|
|
33
36
|
await browser.close();
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
async function resolveCaptureLocator(page, selector) {
|
|
40
|
+
const candidates = [...new Set([selector, "#vizcore-canvas", "canvas"].filter(Boolean))];
|
|
41
|
+
for (const candidate of candidates) {
|
|
42
|
+
const locator = page.locator(candidate).first();
|
|
43
|
+
if (await locator.count().catch(() => 0) > 0) {
|
|
44
|
+
return locator;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return page.locator(selector).first();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function waitForVizcoreFrame(page, timeout) {
|
|
51
|
+
await page.waitForFunction(
|
|
52
|
+
() => Number(document.body?.dataset?.vizcoreFrameCount || 0) > 0,
|
|
53
|
+
null,
|
|
54
|
+
{ timeout }
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
36
58
|
function parseArgs(args) {
|
|
37
59
|
const parsed = {
|
|
38
60
|
url: null,
|
|
@@ -41,6 +63,8 @@ function parseArgs(args) {
|
|
|
41
63
|
wait: 1000,
|
|
42
64
|
width: 1280,
|
|
43
65
|
height: 720,
|
|
66
|
+
waitForFrame: false,
|
|
67
|
+
frameTimeout: 10000,
|
|
44
68
|
};
|
|
45
69
|
|
|
46
70
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -60,6 +84,11 @@ function parseArgs(args) {
|
|
|
60
84
|
} else if (value === "--height") {
|
|
61
85
|
parsed.height = finiteNumber(args[index + 1], parsed.height);
|
|
62
86
|
index += 1;
|
|
87
|
+
} else if (value === "--wait-for-frame") {
|
|
88
|
+
parsed.waitForFrame = true;
|
|
89
|
+
} else if (value === "--frame-timeout") {
|
|
90
|
+
parsed.frameTimeout = finiteNumber(args[index + 1], parsed.frameTimeout);
|
|
91
|
+
index += 1;
|
|
63
92
|
} else if (!parsed.url) {
|
|
64
93
|
parsed.url = value;
|
|
65
94
|
}
|
data/sig/vizcore.rbs
CHANGED
|
@@ -4,8 +4,12 @@ module Vizcore
|
|
|
4
4
|
def self.root: () -> Pathname
|
|
5
5
|
def self.frontend_root: () -> Pathname
|
|
6
6
|
def self.templates_root: () -> Pathname
|
|
7
|
+
def self.features: (?command_available: untyped? command_available) -> Hash[Symbol, bool]
|
|
7
8
|
def self.define: () { () -> void } -> Hash[Symbol, untyped]
|
|
8
9
|
def self.plugin: (String | Symbol name) -> bool
|
|
10
|
+
def self.register_shape: (Symbol | String name, untyped renderer) -> Vizcore::Shape::Definition
|
|
11
|
+
| (Symbol | String name) { (Vizcore::Shape::DrawContext) -> untyped } -> Vizcore::Shape::Definition
|
|
12
|
+
def self.resolve_shape: (Symbol | String name) -> Vizcore::Shape::Definition?
|
|
9
13
|
def self.register_layer_capability: (
|
|
10
14
|
type: Symbol | String,
|
|
11
15
|
?aliases: Array[Symbol | String] aliases,
|
|
@@ -15,6 +19,94 @@ module Vizcore
|
|
|
15
19
|
) -> Vizcore::LayerCatalog::Capability
|
|
16
20
|
end
|
|
17
21
|
|
|
22
|
+
module Vizcore::Shape
|
|
23
|
+
SUPPORTED_PRIMITIVES: Array[Symbol]
|
|
24
|
+
|
|
25
|
+
def self.normalize_primitives: (untyped value, shape_name: untyped) -> Array[Hash[Symbol, untyped]]
|
|
26
|
+
def self.expand_custom_shape: (
|
|
27
|
+
untyped renderer,
|
|
28
|
+
params: Hash[Symbol | String, untyped],
|
|
29
|
+
?shape_id: Symbol | String? shape_id,
|
|
30
|
+
?layer_name: Symbol? layer_name,
|
|
31
|
+
?palette: Array[untyped] palette,
|
|
32
|
+
?audio: Hash[untyped, untyped] audio,
|
|
33
|
+
?time: Numeric time,
|
|
34
|
+
?frame: Integer frame,
|
|
35
|
+
?resolution: Array[untyped] resolution,
|
|
36
|
+
?globals: Hash[untyped, untyped] globals,
|
|
37
|
+
?shape_name: untyped shape_name
|
|
38
|
+
) -> Array[Hash[Symbol, untyped]]
|
|
39
|
+
def self.param_schema_for: (untyped renderer) -> Hash[Symbol, Hash[Symbol, untyped]]
|
|
40
|
+
|
|
41
|
+
class Definition < Struct[untyped]
|
|
42
|
+
attr_accessor name: Symbol?
|
|
43
|
+
attr_accessor renderer: untyped
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module ClassMethods
|
|
47
|
+
def param: (
|
|
48
|
+
Symbol | String name,
|
|
49
|
+
?default: untyped default,
|
|
50
|
+
?range: Range[Numeric]? | [Numeric, Numeric]? range,
|
|
51
|
+
?min: Numeric? min,
|
|
52
|
+
?max: Numeric? max,
|
|
53
|
+
?step: Numeric? step
|
|
54
|
+
) -> Hash[Symbol, untyped]
|
|
55
|
+
def shape_param_schema: () -> Hash[Symbol, Hash[Symbol, untyped]]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class DrawContext
|
|
59
|
+
attr_reader params: Hash[Symbol, untyped]
|
|
60
|
+
attr_reader shape_id: Symbol?
|
|
61
|
+
attr_reader layer_name: Symbol?
|
|
62
|
+
attr_reader palette: Array[untyped]
|
|
63
|
+
attr_reader audio: AudioContext
|
|
64
|
+
attr_reader time: Float
|
|
65
|
+
attr_reader frame: Integer
|
|
66
|
+
attr_reader resolution: Array[untyped]
|
|
67
|
+
attr_reader globals: Hash[Symbol, untyped]
|
|
68
|
+
|
|
69
|
+
def initialize: (
|
|
70
|
+
params: Hash[Symbol | String, untyped],
|
|
71
|
+
?param_schema: Hash[Symbol, Hash[Symbol, untyped]] param_schema,
|
|
72
|
+
?shape_id: Symbol | String? shape_id,
|
|
73
|
+
?layer_name: Symbol? layer_name,
|
|
74
|
+
?palette: Array[untyped] palette,
|
|
75
|
+
?audio: Hash[untyped, untyped] audio,
|
|
76
|
+
?time: Numeric time,
|
|
77
|
+
?frame: Integer frame,
|
|
78
|
+
?resolution: Array[untyped] resolution,
|
|
79
|
+
?globals: Hash[untyped, untyped] globals
|
|
80
|
+
) -> void
|
|
81
|
+
def param: (Symbol | String name, ?untyped default) -> untyped
|
|
82
|
+
def width: () -> untyped
|
|
83
|
+
def height: () -> untyped
|
|
84
|
+
def draw: () { () -> void } -> Array[Hash[Symbol, untyped]]
|
|
85
|
+
def shapes: () -> Array[Hash[Symbol, untyped]]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class AudioContext
|
|
89
|
+
def amplitude: () -> Float
|
|
90
|
+
def bass: () -> Float
|
|
91
|
+
def bass_peak: () -> Float
|
|
92
|
+
def mid: () -> Float
|
|
93
|
+
def mid_peak: () -> Float
|
|
94
|
+
def high: () -> Float
|
|
95
|
+
def high_peak: () -> Float
|
|
96
|
+
def fft: () -> Array[untyped]
|
|
97
|
+
def beat?: () -> bool
|
|
98
|
+
def beat_pulse: () -> Float
|
|
99
|
+
def beat_phase: () -> Float
|
|
100
|
+
def bar_phase: () -> Float
|
|
101
|
+
def bar_count: () -> Integer
|
|
102
|
+
def phrase_count: () -> Integer
|
|
103
|
+
def kick: () -> Float
|
|
104
|
+
def snare: () -> Float
|
|
105
|
+
def hihat: () -> Float
|
|
106
|
+
def bpm: () -> Float
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
18
110
|
module Vizcore::LayerCatalog
|
|
19
111
|
class Capability < Struct[untyped]
|
|
20
112
|
attr_accessor type: Symbol
|
|
@@ -117,10 +209,14 @@ module Vizcore::Analysis
|
|
|
117
209
|
|
|
118
210
|
class FeatureReplay
|
|
119
211
|
attr_reader metadata: Hash[Symbol, untyped]
|
|
212
|
+
attr_reader cursor: Integer
|
|
120
213
|
|
|
121
214
|
def initialize: (path: String | Pathname path) -> void
|
|
122
215
|
def call: (?Array[Float]? samples) -> Hash[Symbol, untyped]
|
|
123
216
|
def frame_count: () -> Integer
|
|
217
|
+
def seek: (Integer index) -> FeatureReplay
|
|
218
|
+
def seek_seconds: (Numeric seconds) -> FeatureReplay
|
|
219
|
+
def frame: (Integer index) -> Hash[Symbol, untyped]
|
|
124
220
|
end
|
|
125
221
|
end
|
|
126
222
|
|
|
@@ -155,7 +251,8 @@ module Vizcore::DSL
|
|
|
155
251
|
type scene = { name: Symbol, layers: Array[layer], ?theme: Symbol }
|
|
156
252
|
type style = { name: Symbol, params: Hash[Symbol, untyped] }
|
|
157
253
|
type theme = { name: Symbol, params: Hash[Symbol, untyped] }
|
|
158
|
-
type
|
|
254
|
+
type mapping_preset = { name: Symbol, mappings: Array[mapping] }
|
|
255
|
+
type timeline_entry = { at: Float, unit: Symbol, scene: Symbol, ?cue: Symbol }
|
|
159
256
|
type key_action = { type: Symbol, ?scene: String, ?control: Symbol }
|
|
160
257
|
type key_mapping = { key: String, action: key_action }
|
|
161
258
|
|
|
@@ -167,18 +264,28 @@ module Vizcore::DSL
|
|
|
167
264
|
def audio: (Symbol | String name, **untyped options) -> Array[Hash[Symbol, untyped]]
|
|
168
265
|
def style: (Symbol | String name) { () -> void } -> void
|
|
169
266
|
def theme: (Symbol | String name) { () -> void } -> void
|
|
267
|
+
def mapping: (Symbol | String name) { () -> void } -> void
|
|
170
268
|
def midi: (Symbol | String name, **untyped options) -> Array[Hash[Symbol, untyped]]
|
|
171
269
|
def audio_normalize: (?mode: Symbol | String mode, **untyped options) -> Hash[Symbol, untyped]
|
|
270
|
+
def audio_analysis: (**untyped options) -> Hash[Symbol, untyped]
|
|
172
271
|
def bpm: (Numeric value) -> Float
|
|
173
272
|
def bpm_lock: () -> bool
|
|
174
273
|
| (bool value) -> bool
|
|
175
274
|
def tap_tempo: (?key: Symbol | String key) -> Hash[Symbol, untyped]
|
|
176
275
|
def key: (Symbol | String value) { () -> void } -> void
|
|
177
276
|
def scene: (Symbol | String name, ?extends: Symbol | String? extends) { () -> void } -> void
|
|
178
|
-
def section: (Symbol | String name, bars: Integer bars, ?beats_per_bar: Integer beats_per_bar) { () -> void } -> void
|
|
277
|
+
def section: (Symbol | String name, bars: Integer bars, ?beats_per_bar: Integer beats_per_bar, ?loop: bool loop, ?hold: Numeric hold, ?outro: bool outro) { () -> void } -> void
|
|
179
278
|
def timeline: (?beats_per_bar: Integer beats_per_bar) { () -> void } -> void
|
|
180
279
|
def transition: (from: Symbol | String, to: Symbol | String) { () -> void } -> void
|
|
181
|
-
def midi_map: (
|
|
280
|
+
def midi_map: (
|
|
281
|
+
?note: Integer? note,
|
|
282
|
+
?cc: Integer? cc,
|
|
283
|
+
?pc: Integer? pc,
|
|
284
|
+
?channel: Integer? channel,
|
|
285
|
+
?relative: bool relative,
|
|
286
|
+
?deadband: Numeric? deadband,
|
|
287
|
+
?smooth: Numeric | bool | nil smooth
|
|
288
|
+
) { (*untyped) -> void } -> void
|
|
182
289
|
def set: (Symbol | String key, untyped value) -> untyped
|
|
183
290
|
def to_h: () -> Hash[Symbol, untyped]
|
|
184
291
|
end
|
|
@@ -224,6 +331,7 @@ module Vizcore::DSL
|
|
|
224
331
|
name: Symbol | String name,
|
|
225
332
|
?styles: Hash[Symbol, Hash[Symbol, untyped]] styles,
|
|
226
333
|
?themes: Hash[Symbol, Hash[Symbol, untyped]] themes,
|
|
334
|
+
?mapping_presets: Hash[Symbol, Array[mapping]] mapping_presets,
|
|
227
335
|
?layers: Array[layer] layers
|
|
228
336
|
) -> void
|
|
229
337
|
def evaluate: () ?{ () -> void } -> SceneBuilder
|
|
@@ -237,6 +345,7 @@ module Vizcore::DSL
|
|
|
237
345
|
def initialize: (
|
|
238
346
|
name: Symbol | String name,
|
|
239
347
|
?styles: Hash[Symbol, Hash[Symbol, untyped]] styles,
|
|
348
|
+
?mapping_presets: Hash[Symbol, Array[mapping]] mapping_presets,
|
|
240
349
|
?defaults: Hash[Symbol, untyped] defaults
|
|
241
350
|
) -> void
|
|
242
351
|
def evaluate: () ?{ () -> void } -> LayerGroupBuilder
|
|
@@ -267,6 +376,7 @@ module Vizcore::DSL
|
|
|
267
376
|
def initialize: (
|
|
268
377
|
name: Symbol | String name,
|
|
269
378
|
?styles: Hash[Symbol, Hash[Symbol, untyped]] styles,
|
|
379
|
+
?mapping_presets: Hash[Symbol, Array[mapping]] mapping_presets,
|
|
270
380
|
?defaults: Hash[Symbol, untyped] defaults
|
|
271
381
|
) -> void
|
|
272
382
|
def evaluate: () ?{ () -> void } -> LayerBuilder
|
|
@@ -276,6 +386,14 @@ module Vizcore::DSL
|
|
|
276
386
|
def file: (String | Pathname path) -> String
|
|
277
387
|
def circle: (**untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
278
388
|
def line: (**untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
389
|
+
def rect: (*untyped args, **untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
390
|
+
def polygon: (*untyped args, **untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
391
|
+
def polyline: (*untyped args, **untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
392
|
+
def path: (*untyped args, **untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
393
|
+
def bezier: (*untyped args, **untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
394
|
+
def star: (*untyped args, **untyped options) ?{ () -> void } -> Hash[Symbol, untyped]
|
|
395
|
+
def custom_shape: (untyped renderer, **untyped options) ?{ () -> void } -> (Array[Hash[Symbol, untyped]] | Hash[Symbol, untyped])
|
|
396
|
+
def group: (*untyped args, **untyped attrs) { () -> void } -> Array[Hash[Symbol, untyped]]
|
|
279
397
|
def draw: () { () -> void } -> Array[Hash[Symbol, untyped]]
|
|
280
398
|
def source: (Symbol | String value, **untyped options) -> (Symbol | source)
|
|
281
399
|
def count: (Integer value) -> Integer
|
|
@@ -299,6 +417,7 @@ module Vizcore::DSL
|
|
|
299
417
|
def color_shift: (Numeric value) -> Float
|
|
300
418
|
def palette: (*untyped colors) -> Array[String]
|
|
301
419
|
def use_style: (Symbol | String name) -> Hash[Symbol, untyped]
|
|
420
|
+
def use_mapping: (Symbol | String name) -> void
|
|
302
421
|
def param: (
|
|
303
422
|
Symbol | String name,
|
|
304
423
|
?default: Numeric? default,
|
|
@@ -311,12 +430,19 @@ module Vizcore::DSL
|
|
|
311
430
|
def react_to: (Hash[Symbol, untyped] | Symbol | String source_value) { () -> void } -> void
|
|
312
431
|
def amplitude: () -> source
|
|
313
432
|
def frequency_band: (Symbol | String name) -> source
|
|
433
|
+
def frequency_band_peak: (Symbol | String name) -> source
|
|
314
434
|
def sub: () -> source
|
|
435
|
+
def sub_peak: () -> source
|
|
315
436
|
def low: () -> source
|
|
437
|
+
def low_peak: () -> source
|
|
316
438
|
def bass: () -> source
|
|
439
|
+
def bass_peak: () -> source
|
|
317
440
|
def mid: () -> source
|
|
441
|
+
def mid_peak: () -> source
|
|
318
442
|
def high: () -> source
|
|
443
|
+
def high_peak: () -> source
|
|
319
444
|
def treble: () -> source
|
|
445
|
+
def treble_peak: () -> source
|
|
320
446
|
def fft_spectrum: () -> source
|
|
321
447
|
def onset: () -> source
|
|
322
448
|
| (Symbol | String band) -> source
|
|
@@ -331,6 +457,15 @@ module Vizcore::DSL
|
|
|
331
457
|
def beat_confidence: () -> source
|
|
332
458
|
def beat_pulse: () -> source
|
|
333
459
|
def beat_count: () -> source
|
|
460
|
+
def beat_phase: () -> source
|
|
461
|
+
def beat_2: () -> source
|
|
462
|
+
def beat_4: () -> source
|
|
463
|
+
def beat_8: () -> source
|
|
464
|
+
def beat_triplet: () -> source
|
|
465
|
+
def triplet: () -> source
|
|
466
|
+
def bar_phase: () -> source
|
|
467
|
+
def bar_count: () -> source
|
|
468
|
+
def phrase_count: () -> source
|
|
334
469
|
def bpm: () -> source
|
|
335
470
|
def to_h: () -> layer
|
|
336
471
|
end
|
|
@@ -355,8 +490,23 @@ module Vizcore::DSL
|
|
|
355
490
|
def to_h: () -> Hash[Symbol, untyped]
|
|
356
491
|
end
|
|
357
492
|
|
|
493
|
+
class MappingPresetBuilder
|
|
494
|
+
def initialize: (name: Symbol | String name, ?strict: bool strict) -> void
|
|
495
|
+
def evaluate: () ?{ () -> void } -> MappingPresetBuilder
|
|
496
|
+
def to_h: () -> mapping_preset
|
|
497
|
+
end
|
|
498
|
+
|
|
358
499
|
class MappingResolver
|
|
359
500
|
def initialize: () -> void
|
|
360
|
-
def resolve_layers: (
|
|
501
|
+
def resolve_layers: (
|
|
502
|
+
scene_layers: Array[Hash[Symbol, untyped]],
|
|
503
|
+
audio: Hash[Symbol, untyped],
|
|
504
|
+
?time: Numeric time,
|
|
505
|
+
?frame: Integer frame,
|
|
506
|
+
?resolution: Array[untyped] resolution,
|
|
507
|
+
?globals: Hash[untyped, untyped] globals,
|
|
508
|
+
?custom_shape_overrides: Hash[untyped, untyped] custom_shape_overrides,
|
|
509
|
+
?layer_param_overrides: Hash[untyped, untyped] layer_param_overrides
|
|
510
|
+
) -> Array[Hash[Symbol, untyped]]
|
|
361
511
|
end
|
|
362
512
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vizcore
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yudai Takada
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: faye-websocket
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '0.11'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0.13'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: '0.11'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '0.13'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: ffi
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -91,11 +97,16 @@ files:
|
|
|
91
97
|
- LICENSE.txt
|
|
92
98
|
- README.md
|
|
93
99
|
- docs/.nojekyll
|
|
100
|
+
- docs/assets/playground-worker.js
|
|
101
|
+
- docs/assets/playground.css
|
|
102
|
+
- docs/assets/playground.js
|
|
94
103
|
- docs/assets/site.css
|
|
95
104
|
- docs/assets/vizcore-demo.gif
|
|
96
105
|
- docs/assets/vizcore-poster.png
|
|
97
106
|
- docs/assets/vj-tunnel.js
|
|
98
107
|
- docs/index.html
|
|
108
|
+
- docs/playground.html
|
|
109
|
+
- docs/shape_dsl.md
|
|
99
110
|
- examples/README.md
|
|
100
111
|
- examples/assets/README.md
|
|
101
112
|
- examples/assets/complex_demo_loop.wav
|
|
@@ -129,8 +140,10 @@ files:
|
|
|
129
140
|
- exe/vizcore
|
|
130
141
|
- frontend/index.html
|
|
131
142
|
- frontend/src/audio-inspector.js
|
|
143
|
+
- frontend/src/custom-shape-param-controls.js
|
|
132
144
|
- frontend/src/live-controls.js
|
|
133
145
|
- frontend/src/main.js
|
|
146
|
+
- frontend/src/mapping-target-selector.js
|
|
134
147
|
- frontend/src/midi-learn.js
|
|
135
148
|
- frontend/src/performance-monitor.js
|
|
136
149
|
- frontend/src/plugin-runtime.js
|
|
@@ -139,16 +152,20 @@ files:
|
|
|
139
152
|
- frontend/src/renderer/layer-manager.js
|
|
140
153
|
- frontend/src/renderer/shader-manager.js
|
|
141
154
|
- frontend/src/runtime-control-preset.js
|
|
155
|
+
- frontend/src/scene-patches.js
|
|
142
156
|
- frontend/src/shader-error-overlay.js
|
|
143
157
|
- frontend/src/shader-param-controls.js
|
|
144
158
|
- frontend/src/shaders/builtins.js
|
|
145
159
|
- frontend/src/shaders/post-effects.js
|
|
160
|
+
- frontend/src/shape-editor-controls.js
|
|
146
161
|
- frontend/src/visual-regression.js
|
|
147
162
|
- frontend/src/visual-settings-preset.js
|
|
148
163
|
- frontend/src/visuals/geometry.js
|
|
149
164
|
- frontend/src/visuals/image-renderer.js
|
|
150
165
|
- frontend/src/visuals/particle-system.js
|
|
166
|
+
- frontend/src/visuals/shape-renderer.js
|
|
151
167
|
- frontend/src/visuals/spectrogram-renderer.js
|
|
168
|
+
- frontend/src/visuals/svg-arc.js
|
|
152
169
|
- frontend/src/visuals/text-renderer.js
|
|
153
170
|
- frontend/src/visuals/vj-effects.js
|
|
154
171
|
- frontend/src/websocket-client.js
|
|
@@ -167,6 +184,7 @@ files:
|
|
|
167
184
|
- lib/vizcore/analysis/tap_tempo.rb
|
|
168
185
|
- lib/vizcore/audio.rb
|
|
169
186
|
- lib/vizcore/audio/base_input.rb
|
|
187
|
+
- lib/vizcore/audio/calibration.rb
|
|
170
188
|
- lib/vizcore/audio/dummy_sine_input.rb
|
|
171
189
|
- lib/vizcore/audio/file_input.rb
|
|
172
190
|
- lib/vizcore/audio/fixture_input.rb
|
|
@@ -179,6 +197,7 @@ files:
|
|
|
179
197
|
- lib/vizcore/cli/doctor.rb
|
|
180
198
|
- lib/vizcore/cli/dsl_reference.rb
|
|
181
199
|
- lib/vizcore/cli/layer_docs.rb
|
|
200
|
+
- lib/vizcore/cli/plugin_checker.rb
|
|
182
201
|
- lib/vizcore/cli/scene_diagnostics.rb
|
|
183
202
|
- lib/vizcore/cli/scene_inspector.rb
|
|
184
203
|
- lib/vizcore/cli/scene_validator.rb
|
|
@@ -186,11 +205,15 @@ files:
|
|
|
186
205
|
- lib/vizcore/cli/shader_uniform_docs.rb
|
|
187
206
|
- lib/vizcore/config.rb
|
|
188
207
|
- lib/vizcore/control_preset.rb
|
|
208
|
+
- lib/vizcore/deep_copy.rb
|
|
189
209
|
- lib/vizcore/dsl.rb
|
|
210
|
+
- lib/vizcore/dsl/color_helpers.rb
|
|
190
211
|
- lib/vizcore/dsl/engine.rb
|
|
191
212
|
- lib/vizcore/dsl/file_watcher.rb
|
|
192
213
|
- lib/vizcore/dsl/layer_builder.rb
|
|
193
214
|
- lib/vizcore/dsl/layer_group_builder.rb
|
|
215
|
+
- lib/vizcore/dsl/layout_helpers.rb
|
|
216
|
+
- lib/vizcore/dsl/mapping_preset_builder.rb
|
|
194
217
|
- lib/vizcore/dsl/mapping_resolver.rb
|
|
195
218
|
- lib/vizcore/dsl/mapping_transform_builder.rb
|
|
196
219
|
- lib/vizcore/dsl/midi_map_executor.rb
|
|
@@ -202,6 +225,7 @@ files:
|
|
|
202
225
|
- lib/vizcore/dsl/transition_controller.rb
|
|
203
226
|
- lib/vizcore/errors.rb
|
|
204
227
|
- lib/vizcore/layer_catalog.rb
|
|
228
|
+
- lib/vizcore/plugin_asset_policy.rb
|
|
205
229
|
- lib/vizcore/project_manifest.rb
|
|
206
230
|
- lib/vizcore/renderer.rb
|
|
207
231
|
- lib/vizcore/renderer/frame_scheduler.rb
|
|
@@ -211,6 +235,7 @@ files:
|
|
|
211
235
|
- lib/vizcore/renderer/scene_serializer.rb
|
|
212
236
|
- lib/vizcore/renderer/snapshot.rb
|
|
213
237
|
- lib/vizcore/renderer/snapshot_renderer.rb
|
|
238
|
+
- lib/vizcore/scene_trust.rb
|
|
214
239
|
- lib/vizcore/server.rb
|
|
215
240
|
- lib/vizcore/server/frame_broadcaster.rb
|
|
216
241
|
- lib/vizcore/server/gallery_app.rb
|
|
@@ -220,6 +245,7 @@ files:
|
|
|
220
245
|
- lib/vizcore/server/runner.rb
|
|
221
246
|
- lib/vizcore/server/scene_dependency_watcher.rb
|
|
222
247
|
- lib/vizcore/server/websocket_handler.rb
|
|
248
|
+
- lib/vizcore/shape.rb
|
|
223
249
|
- lib/vizcore/sync.rb
|
|
224
250
|
- lib/vizcore/sync/osc_message.rb
|
|
225
251
|
- lib/vizcore/sync/osc_receiver.rb
|