1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
| | # Copyright (C) all contributors <dtas-all@nongnu.org>
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
# frozen_string_literal: true
require 'yaml'
require_relative 'sox'
require_relative '../splitfx'
require_relative '../watchable'
class DTAS::Source::SplitFX < DTAS::Source::Sox # :nodoc:
MAX_YAML_SIZE = 512 * 1024
attr_writer :sox, :sfx
include DTAS::Watchable if defined?(DTAS::Watchable)
SPLITFX_DEFAULTS = SOX_DEFAULTS.merge(
"command" => "#{SOX_DEFAULTS["command"]} $FX",
"tryorder" => 3,
)
def initialize(sox = DTAS::Source::Sox.new)
command_init(SPLITFX_DEFAULTS)
@watch_extra = []
@sox = sox
end
def try(ymlfile, offset = nil, trim = nil)
@splitfx = @ymlhash = nil
st = File.stat(ymlfile)
return false if !st.file? || st.size > MAX_YAML_SIZE
# read 4 bytes first to ensure we have a YAML file with a hash:
buf = "".dup
File.open(ymlfile, "rb") do |fp|
return false if fp.read(4, buf) != "---\n"
buf << fp.read
end
sfx = DTAS::SplitFX.new
Dir.chdir(File.dirname(ymlfile)) do # ugh
@ymlhash = DTAS.yaml_load(buf)
@ymlhash['tracks'] ||= [ "t 0 default" ]
sfx.import(@ymlhash)
sfx.infile.replace(File.expand_path(sfx.infile))
end
@splitfx = sfx
@infile = ymlfile
sox = @sox.try(sfx.infile, offset, trim) or return false
rv = source_file_dup(ymlfile, offset, trim)
rv.sox = sox
rv.env = sfx.env
rv.sfx = sfx
rv
rescue => e
warn "#{e.message} (#{e.class})"
false
end
def __load_comments
if c = @ymlhash["comments"]
return c.each { |k,v| c[k] = v.to_s }
end
@sox.__load_comments
end
def command_string
@ymlhash["command"] || super
end
def src_spawn(player_format, rg_state, opts)
raise "BUG: #{self.inspect}#src_spawn called twice" if @to_io
e = @env.merge!(player_format.to_env)
@sfx.infile_env(e, @sox.infile)
# watch any scripts or files the command in the YAML file refers to
if c = @sfx.command
@sfx.expand_cmd(e, c).each do |f|
File.readable?(f) and @watch_extra << f
end
end
# allow users to specify explicit depdendencies to watch for edit
case extra = @ymlhash['deps']
when Array, String
@watch_extra.concat(Array(extra))
end
# make sure these are visible to the "current" command...
e["TRIMFX"] = trimfx
e["RGFX"] = rg_state.effect(self) || nil
e.merge!(@rg.to_env) if @rg
@pid = dtas_spawn(e, command_string, opts)
end
def to_hsh
to_hash.delete_if { |k,v| v == SPLITFX_DEFAULTS[k] }
end
def format
@sox.format
end
def samples!
@sox.samples!
end
def samples
@sox.samples
end
def duration
@sox.duration
end
def source_defaults
SPLITFX_DEFAULTS
end
def cuebreakpoints
@splitfx.cuebreakpoints
end
end
|