Class: Vizcore::Server::Runner
- Inherits:
-
Object
- Object
- Vizcore::Server::Runner
- Defined in:
- lib/vizcore/server/runner.rb
Overview
Bootstraps Rack/Puma, audio pipeline, scene reload, and MIDI runtime.
Constant Summary collapse
- DEFAULT_PROFILE_NAME =
"default".freeze
Instance Method Summary collapse
-
#initialize(config, manifest: nil, initial_profile: nil, output: $stdout) ⇒ Runner
constructor
A new instance of Runner.
-
#run ⇒ void
Run server lifecycle until interrupted.
- #warn_if_sample_rate_mismatch(input_manager) ⇒ Object
Constructor Details
#initialize(config, manifest: nil, initial_profile: nil, output: $stdout) ⇒ Runner
Returns a new instance of Runner.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/vizcore/server/runner.rb', line 24 def initialize(config, manifest: nil, initial_profile: nil, output: $stdout) @config = config @manifest = manifest @available_profiles = derive_available_profiles @active_profile = normalize_profile_name(initial_profile) @active_scene_file = active_scene_file_for_profile(@active_profile) @output = output @shader_source_resolver = Vizcore::DSL::ShaderSourceResolver.new @scene_catalog_mutex = Mutex.new @scene_catalog = [] @scene_watcher = nil @osc_schedule_mutex = Mutex.new @osc_schedule_threads = [] @osc_runtime_active = false @midi_runtime = nil @osc_runtime = nil @broadcaster = nil @runtime_globals_mutex = Mutex.new @runtime_globals = {} @live_controls = { "blackout" => default_live_control_state, "freeze" => default_live_control_state } end |
Instance Method Details
#run ⇒ void
This method returns an undefined value.
Run server lifecycle until interrupted.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/vizcore/server/runner.rb', line 54 def run validate_scene_file! validate_public_bind_settings! validate_feature_settings! validate_control_preset_settings! validate_plugin_asset_settings! validate_audio_settings! definition = load_definition_for_profile(@active_profile) control_preset = load_control_preset timeline_entry = initial_timeline_entry(definition) scene = initial_scene(definition) || fallback_scene broadcaster = nil app = RackApp.new( frontend_root: Vizcore.frontend_root, audio_source: runtime_audio_source, audio_file: runtime_audio_file, scene_names: scene_names_for(definition), tap_tempo_key: @tap_tempo_key, key_mappings: key_mappings_for(definition), globals: runtime_globals_snapshot, control_preset: control_preset, control_preset_path: @config.control_preset, plugin_assets: @config.plugin_assets, projector_mode: @config.projector_mode, runtime_status_provider: -> { runtime_status_payload } ) server = Puma::Server.new(app, nil, min_threads: 0, max_threads: 4) server.add_tcp_listener(@config.host, @config.port) server.run input_manager = build_input_manager warn_if_sample_rate_mismatch(input_manager) broadcaster = FrameBroadcaster.new( scene_name: scene[:name].to_s, scene_layers: scene[:layers], scene_catalog: definition[:scenes], transitions: definition[:transitions], initial_timeline_entry: timeline_entry, input_manager: input_manager, analysis_pipeline: replay_pipeline, noise_gate: @config.noise_gate, audio_normalize: audio_normalize_settings(definition), bpm: bpm_setting(definition), bpm_lock: bpm_lock_setting(definition), onset_sensitivity: analysis_setting(definition, :onset_sensitivity, 1.0), fft_preview_bins: analysis_setting(definition, :fft_bins, Vizcore::Analysis::Pipeline::DEFAULT_FFT_PREVIEW_BINS), peak_hold_frames: analysis_setting(definition, :peak_hold_frames, 0), silence_reset_frames: analysis_setting(definition, :silence_reset_frames, Vizcore::Analysis::Pipeline::SILENCE_RESET_FRAMES), error_reporter: ->() { @output.puts() } ) @broadcaster = broadcaster configure_runtime_for_definition(definition: definition, broadcaster: broadcaster) replace_scene_catalog(definition[:scenes]) if file_transport_enabled? broadcaster.sync_transport(playing: false, position_seconds: 0.0) end broadcaster.start (broadcaster) @midi_runtime = start_midi_runtime(definition, broadcaster) @osc_runtime = start_osc_runtime(broadcaster) @scene_watcher = start_scene_watcher( broadcaster, definition: definition, scene_file: active_scene_file ) do |reloaded_definition| @midi_runtime = refresh_midi_runtime(@midi_runtime, reloaded_definition, broadcaster) end if @config.reload? @output.puts("Vizcore server listening at http://#{@config.host}:#{@config.port}") @output.puts("Projector output: http://#{@config.host}:#{@config.port}/projector") @output.puts("Control panel: http://#{@config.host}:#{@config.port}/control") @output.puts("Scene: #{scene[:name]}") @output.puts("Hot reload: #{@config.reload? ? 'enabled' : 'disabled'}") @output.puts("Audio playback: http://#{@config.host}:#{@config.port}/audio-file") if file_transport_enabled? @output.puts("Feature replay: #{@config.feature_file}") if feature_replay? @output.puts("OSC sync: udp://#{@config.host}:#{@config.osc_port}") if @osc_runtime @output.puts("Press Ctrl+C to stop.") wait_for_interrupt ensure Vizcore::Server::WebSocketHandler. stop_osc_runtime(@osc_runtime) stop_midi_runtime(@midi_runtime) @scene_watcher&.stop broadcaster&.stop server&.stop(true) end |
#warn_if_sample_rate_mismatch(input_manager) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/vizcore/server/runner.rb', line 142 def warn_if_sample_rate_mismatch(input_manager) return unless input_manager.respond_to?(:status) status = input_manager.status return unless status[:sample_rate_mismatch] requested = status[:requested_sample_rate] actual = status[:sample_rate] return unless requested && actual @output.puts( "Warning: requested audio sample rate #{requested} does not match device sample rate #{actual}; " \ "analysis will use #{actual}." ) end |