vizcore 1.1.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/frontend/index.html +24 -2
  3. data/frontend/src/audio-inspector.js +9 -0
  4. data/frontend/src/live-controls.js +219 -7
  5. data/frontend/src/main.js +447 -57
  6. data/frontend/src/midi-learn.js +22 -2
  7. data/frontend/src/performance-monitor.js +137 -1
  8. data/frontend/src/renderer/engine.js +391 -10
  9. data/frontend/src/renderer/layer-manager.js +472 -71
  10. data/frontend/src/runtime-control-preset.js +44 -0
  11. data/frontend/src/scene-patches.js +159 -0
  12. data/frontend/src/shader-error-overlay.js +1 -0
  13. data/frontend/src/visuals/image-renderer.js +19 -0
  14. data/frontend/src/visuals/particle-system.js +10 -0
  15. data/frontend/src/visuals/shape-renderer.js +13 -0
  16. data/frontend/src/visuals/spectrogram-renderer.js +14 -0
  17. data/frontend/src/visuals/text-renderer.js +13 -0
  18. data/frontend/src/websocket-client.js +6 -0
  19. data/lib/vizcore/analysis/adaptive_normalizer.rb +20 -2
  20. data/lib/vizcore/analysis/bpm_estimator.rb +18 -8
  21. data/lib/vizcore/analysis/feature_recorder.rb +117 -7
  22. data/lib/vizcore/analysis/feature_replay.rb +48 -9
  23. data/lib/vizcore/analysis/pipeline.rb +258 -9
  24. data/lib/vizcore/analysis/tap_tempo.rb +17 -2
  25. data/lib/vizcore/audio/calibration.rb +156 -0
  26. data/lib/vizcore/audio/file_input.rb +28 -0
  27. data/lib/vizcore/audio/input_manager.rb +36 -1
  28. data/lib/vizcore/audio/midi_input.rb +5 -0
  29. data/lib/vizcore/audio/ring_buffer.rb +22 -0
  30. data/lib/vizcore/audio.rb +1 -0
  31. data/lib/vizcore/cli/dsl_reference.rb +64 -8
  32. data/lib/vizcore/cli/plugin_checker.rb +93 -0
  33. data/lib/vizcore/cli/scene_diagnostics.rb +2 -2
  34. data/lib/vizcore/cli/scene_inspector.rb +35 -1
  35. data/lib/vizcore/cli/scene_validator.rb +487 -39
  36. data/lib/vizcore/cli/shader_template.rb +7 -2
  37. data/lib/vizcore/cli/shader_uniform_docs.rb +11 -0
  38. data/lib/vizcore/cli.rb +268 -15
  39. data/lib/vizcore/config.rb +40 -3
  40. data/lib/vizcore/control_preset.rb +29 -0
  41. data/lib/vizcore/deep_copy.rb +21 -0
  42. data/lib/vizcore/dsl/color_helpers.rb +155 -0
  43. data/lib/vizcore/dsl/engine.rb +219 -23
  44. data/lib/vizcore/dsl/layer_builder.rb +278 -15
  45. data/lib/vizcore/dsl/layer_group_builder.rb +10 -12
  46. data/lib/vizcore/dsl/layout_helpers.rb +290 -0
  47. data/lib/vizcore/dsl/mapping_preset_builder.rb +41 -0
  48. data/lib/vizcore/dsl/mapping_resolver.rb +404 -22
  49. data/lib/vizcore/dsl/mapping_transform_builder.rb +50 -0
  50. data/lib/vizcore/dsl/midi_map_executor.rb +219 -23
  51. data/lib/vizcore/dsl/reaction_builder.rb +1 -0
  52. data/lib/vizcore/dsl/scene_builder.rb +83 -13
  53. data/lib/vizcore/dsl/shader_source_resolver.rb +1 -10
  54. data/lib/vizcore/dsl/style_builder.rb +3 -0
  55. data/lib/vizcore/dsl/timeline_builder.rb +91 -8
  56. data/lib/vizcore/dsl/transition_controller.rb +157 -18
  57. data/lib/vizcore/dsl.rb +2 -0
  58. data/lib/vizcore/layer_catalog.rb +1 -0
  59. data/lib/vizcore/plugin_asset_policy.rb +55 -0
  60. data/lib/vizcore/project_manifest.rb +12 -2
  61. data/lib/vizcore/renderer/render_sequence.rb +104 -13
  62. data/lib/vizcore/renderer/scene_frame_source.rb +179 -14
  63. data/lib/vizcore/renderer/scene_serializer.rb +38 -0
  64. data/lib/vizcore/renderer/snapshot.rb +4 -3
  65. data/lib/vizcore/renderer/snapshot_renderer.rb +134 -8
  66. data/lib/vizcore/scene_trust.rb +31 -0
  67. data/lib/vizcore/server/frame_broadcaster.rb +469 -23
  68. data/lib/vizcore/server/rack_app.rb +151 -4
  69. data/lib/vizcore/server/runner.rb +676 -82
  70. data/lib/vizcore/server/websocket_handler.rb +236 -14
  71. data/lib/vizcore/server.rb +21 -0
  72. data/lib/vizcore/shape.rb +39 -16
  73. data/lib/vizcore/sync/osc_message.rb +66 -9
  74. data/lib/vizcore/version.rb +1 -1
  75. data/lib/vizcore.rb +33 -0
  76. data/scripts/browser_capture.mjs +31 -2
  77. data/sig/vizcore.rbs +55 -4
  78. metadata +18 -3
@@ -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.locator(options.selector).first();
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,6 +4,7 @@ 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
9
10
  def self.register_shape: (Symbol | String name, untyped renderer) -> Vizcore::Shape::Definition
@@ -87,11 +88,18 @@ module Vizcore::Shape
87
88
  class AudioContext
88
89
  def amplitude: () -> Float
89
90
  def bass: () -> Float
91
+ def bass_peak: () -> Float
90
92
  def mid: () -> Float
93
+ def mid_peak: () -> Float
91
94
  def high: () -> Float
95
+ def high_peak: () -> Float
92
96
  def fft: () -> Array[untyped]
93
97
  def beat?: () -> bool
94
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
95
103
  def kick: () -> Float
96
104
  def snare: () -> Float
97
105
  def hihat: () -> Float
@@ -201,10 +209,14 @@ module Vizcore::Analysis
201
209
 
202
210
  class FeatureReplay
203
211
  attr_reader metadata: Hash[Symbol, untyped]
212
+ attr_reader cursor: Integer
204
213
 
205
214
  def initialize: (path: String | Pathname path) -> void
206
215
  def call: (?Array[Float]? samples) -> Hash[Symbol, untyped]
207
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]
208
220
  end
209
221
  end
210
222
 
@@ -239,7 +251,8 @@ module Vizcore::DSL
239
251
  type scene = { name: Symbol, layers: Array[layer], ?theme: Symbol }
240
252
  type style = { name: Symbol, params: Hash[Symbol, untyped] }
241
253
  type theme = { name: Symbol, params: Hash[Symbol, untyped] }
242
- type timeline_entry = { at: Float, unit: Symbol, scene: Symbol }
254
+ type mapping_preset = { name: Symbol, mappings: Array[mapping] }
255
+ type timeline_entry = { at: Float, unit: Symbol, scene: Symbol, ?cue: Symbol }
243
256
  type key_action = { type: Symbol, ?scene: String, ?control: Symbol }
244
257
  type key_mapping = { key: String, action: key_action }
245
258
 
@@ -251,18 +264,28 @@ module Vizcore::DSL
251
264
  def audio: (Symbol | String name, **untyped options) -> Array[Hash[Symbol, untyped]]
252
265
  def style: (Symbol | String name) { () -> void } -> void
253
266
  def theme: (Symbol | String name) { () -> void } -> void
267
+ def mapping: (Symbol | String name) { () -> void } -> void
254
268
  def midi: (Symbol | String name, **untyped options) -> Array[Hash[Symbol, untyped]]
255
269
  def audio_normalize: (?mode: Symbol | String mode, **untyped options) -> Hash[Symbol, untyped]
270
+ def audio_analysis: (**untyped options) -> Hash[Symbol, untyped]
256
271
  def bpm: (Numeric value) -> Float
257
272
  def bpm_lock: () -> bool
258
273
  | (bool value) -> bool
259
274
  def tap_tempo: (?key: Symbol | String key) -> Hash[Symbol, untyped]
260
275
  def key: (Symbol | String value) { () -> void } -> void
261
276
  def scene: (Symbol | String name, ?extends: Symbol | String? extends) { () -> void } -> void
262
- 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
263
278
  def timeline: (?beats_per_bar: Integer beats_per_bar) { () -> void } -> void
264
279
  def transition: (from: Symbol | String, to: Symbol | String) { () -> void } -> void
265
- def midi_map: (?note: Integer? note, ?cc: Integer? cc, ?pc: Integer? pc) { (*untyped) -> void } -> void
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
266
289
  def set: (Symbol | String key, untyped value) -> untyped
267
290
  def to_h: () -> Hash[Symbol, untyped]
268
291
  end
@@ -308,6 +331,7 @@ module Vizcore::DSL
308
331
  name: Symbol | String name,
309
332
  ?styles: Hash[Symbol, Hash[Symbol, untyped]] styles,
310
333
  ?themes: Hash[Symbol, Hash[Symbol, untyped]] themes,
334
+ ?mapping_presets: Hash[Symbol, Array[mapping]] mapping_presets,
311
335
  ?layers: Array[layer] layers
312
336
  ) -> void
313
337
  def evaluate: () ?{ () -> void } -> SceneBuilder
@@ -321,6 +345,7 @@ module Vizcore::DSL
321
345
  def initialize: (
322
346
  name: Symbol | String name,
323
347
  ?styles: Hash[Symbol, Hash[Symbol, untyped]] styles,
348
+ ?mapping_presets: Hash[Symbol, Array[mapping]] mapping_presets,
324
349
  ?defaults: Hash[Symbol, untyped] defaults
325
350
  ) -> void
326
351
  def evaluate: () ?{ () -> void } -> LayerGroupBuilder
@@ -351,6 +376,7 @@ module Vizcore::DSL
351
376
  def initialize: (
352
377
  name: Symbol | String name,
353
378
  ?styles: Hash[Symbol, Hash[Symbol, untyped]] styles,
379
+ ?mapping_presets: Hash[Symbol, Array[mapping]] mapping_presets,
354
380
  ?defaults: Hash[Symbol, untyped] defaults
355
381
  ) -> void
356
382
  def evaluate: () ?{ () -> void } -> LayerBuilder
@@ -391,6 +417,7 @@ module Vizcore::DSL
391
417
  def color_shift: (Numeric value) -> Float
392
418
  def palette: (*untyped colors) -> Array[String]
393
419
  def use_style: (Symbol | String name) -> Hash[Symbol, untyped]
420
+ def use_mapping: (Symbol | String name) -> void
394
421
  def param: (
395
422
  Symbol | String name,
396
423
  ?default: Numeric? default,
@@ -403,12 +430,19 @@ module Vizcore::DSL
403
430
  def react_to: (Hash[Symbol, untyped] | Symbol | String source_value) { () -> void } -> void
404
431
  def amplitude: () -> source
405
432
  def frequency_band: (Symbol | String name) -> source
433
+ def frequency_band_peak: (Symbol | String name) -> source
406
434
  def sub: () -> source
435
+ def sub_peak: () -> source
407
436
  def low: () -> source
437
+ def low_peak: () -> source
408
438
  def bass: () -> source
439
+ def bass_peak: () -> source
409
440
  def mid: () -> source
441
+ def mid_peak: () -> source
410
442
  def high: () -> source
443
+ def high_peak: () -> source
411
444
  def treble: () -> source
445
+ def treble_peak: () -> source
412
446
  def fft_spectrum: () -> source
413
447
  def onset: () -> source
414
448
  | (Symbol | String band) -> source
@@ -423,6 +457,15 @@ module Vizcore::DSL
423
457
  def beat_confidence: () -> source
424
458
  def beat_pulse: () -> source
425
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
426
469
  def bpm: () -> source
427
470
  def to_h: () -> layer
428
471
  end
@@ -447,6 +490,12 @@ module Vizcore::DSL
447
490
  def to_h: () -> Hash[Symbol, untyped]
448
491
  end
449
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
+
450
499
  class MappingResolver
451
500
  def initialize: () -> void
452
501
  def resolve_layers: (
@@ -455,7 +504,9 @@ module Vizcore::DSL
455
504
  ?time: Numeric time,
456
505
  ?frame: Integer frame,
457
506
  ?resolution: Array[untyped] resolution,
458
- ?globals: Hash[untyped, untyped] globals
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
459
510
  ) -> Array[Hash[Symbol, untyped]]
460
511
  end
461
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.1.0
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
@@ -146,6 +152,7 @@ files:
146
152
  - frontend/src/renderer/layer-manager.js
147
153
  - frontend/src/renderer/shader-manager.js
148
154
  - frontend/src/runtime-control-preset.js
155
+ - frontend/src/scene-patches.js
149
156
  - frontend/src/shader-error-overlay.js
150
157
  - frontend/src/shader-param-controls.js
151
158
  - frontend/src/shaders/builtins.js
@@ -177,6 +184,7 @@ files:
177
184
  - lib/vizcore/analysis/tap_tempo.rb
178
185
  - lib/vizcore/audio.rb
179
186
  - lib/vizcore/audio/base_input.rb
187
+ - lib/vizcore/audio/calibration.rb
180
188
  - lib/vizcore/audio/dummy_sine_input.rb
181
189
  - lib/vizcore/audio/file_input.rb
182
190
  - lib/vizcore/audio/fixture_input.rb
@@ -189,6 +197,7 @@ files:
189
197
  - lib/vizcore/cli/doctor.rb
190
198
  - lib/vizcore/cli/dsl_reference.rb
191
199
  - lib/vizcore/cli/layer_docs.rb
200
+ - lib/vizcore/cli/plugin_checker.rb
192
201
  - lib/vizcore/cli/scene_diagnostics.rb
193
202
  - lib/vizcore/cli/scene_inspector.rb
194
203
  - lib/vizcore/cli/scene_validator.rb
@@ -196,11 +205,15 @@ files:
196
205
  - lib/vizcore/cli/shader_uniform_docs.rb
197
206
  - lib/vizcore/config.rb
198
207
  - lib/vizcore/control_preset.rb
208
+ - lib/vizcore/deep_copy.rb
199
209
  - lib/vizcore/dsl.rb
210
+ - lib/vizcore/dsl/color_helpers.rb
200
211
  - lib/vizcore/dsl/engine.rb
201
212
  - lib/vizcore/dsl/file_watcher.rb
202
213
  - lib/vizcore/dsl/layer_builder.rb
203
214
  - lib/vizcore/dsl/layer_group_builder.rb
215
+ - lib/vizcore/dsl/layout_helpers.rb
216
+ - lib/vizcore/dsl/mapping_preset_builder.rb
204
217
  - lib/vizcore/dsl/mapping_resolver.rb
205
218
  - lib/vizcore/dsl/mapping_transform_builder.rb
206
219
  - lib/vizcore/dsl/midi_map_executor.rb
@@ -212,6 +225,7 @@ files:
212
225
  - lib/vizcore/dsl/transition_controller.rb
213
226
  - lib/vizcore/errors.rb
214
227
  - lib/vizcore/layer_catalog.rb
228
+ - lib/vizcore/plugin_asset_policy.rb
215
229
  - lib/vizcore/project_manifest.rb
216
230
  - lib/vizcore/renderer.rb
217
231
  - lib/vizcore/renderer/frame_scheduler.rb
@@ -221,6 +235,7 @@ files:
221
235
  - lib/vizcore/renderer/scene_serializer.rb
222
236
  - lib/vizcore/renderer/snapshot.rb
223
237
  - lib/vizcore/renderer/snapshot_renderer.rb
238
+ - lib/vizcore/scene_trust.rb
224
239
  - lib/vizcore/server.rb
225
240
  - lib/vizcore/server/frame_broadcaster.rb
226
241
  - lib/vizcore/server/gallery_app.rb