/
main.lua
146 lines (125 loc) · 4.85 KB
/
main.lua
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
require "exs24"
require "util/process_slicer"
local function sample_path(instrument_path, instrument_filename, sample_filename)
-- Samples in the current path
if io.exists(instrument_path .. sample_filename) then
return instrument_path
end
-- GarageBand instrument
-- i.e. "Sampler/Sampler Instruments/Puremagnetik/Eight Bit/" ->
-- "Sampler/Sampler Files/Puremagnetik Samples/Eight Bit"
if instrument_path:find("Sampler Instruments") then
local garageband_path = instrument_path:gsub(
"(%w+)/Sampler Instruments/(%w+)/(%w+)",
"%1/Sampler Files/%2 Samples/%3"
)
if io.exists(garageband_path .. sample_filename) then
return garageband_path
end
end
-- Logic instrument
-- i.e. "Logic/Sampler Instruments/Puremagnetik/alphaSynth" ->
-- "GarageBand/Instrument Library/Sampler/Sampler Files/Puremagnetik Samples/alphaSynth"
if instrument_path:find("Logic") then
local logic_path = instrument_path:gsub(
"(%w*)Logic/Sampler Instruments/(%w+)/(%w+)",
"%1/GarageBand/Instrument Library/Sampler/Sampler Files/%2 Samples/%3"
)
if io.exists(logic_path .. sample_filename) then
return logic_path
end
end
-- Sample From Mars
-- i.e. "DX100 From Mars/Logic EXS/DX100 From Mars/Leads/Box Cello.exs" ->
-- "DX100 From Mars/WAV/Box Cello"
if instrument_path:find("Logic EXS") then
local mars_path = instrument_path:gsub(
"(%w+)/Logic EXS/.+",
"%1/WAV/"
) .. instrument_filename:gsub("(.+)\.exs", "%1/")
if io.exists(mars_path .. sample_filename) then
return mars_path
end
end
return renoise.app():prompt_for_path("Sample files for " .. instrument_filename .. ":")
end
local function import_samples(instrument, exs, sample_path)
local missing_samples = 0
for k,zone in pairs(exs.zones) do
if exs.samples[zone.sample_index + 1] then
local exs_sample = exs.samples[zone.sample_index + 1]
if io.exists(sample_path .. exs_sample.file_name) then
local sample = instrument:insert_sample_at(#instrument.samples + 1)
if sample.sample_buffer:load_from(sample_path .. exs_sample.file_name) == true then
sample.name = exs_sample.name
-- todo: volume must be 0 - 4, what range is the exs using?
-- exs is using a twos complement byte so it has to be within -128 -127?
sample.volume = 1
sample.fine_tune = math.max(math.min(zone.fine_tuning, 127), -127)
sample.panning = math.max(math.min((zone.pan / 200) + .5, 1.0), 0.0)
sample.oneshot = zone.oneshot
sample.sample_mapping.base_note = math.max(math.min(zone.key, 119), 0)
sample.sample_mapping.note_range = {
math.max(math.min(zone.key_low, 119), 0),
math.min(119, zone.key_high)
}
sample.sample_mapping.velocity_range = {zone.velocity_low, zone.velocity_high}
sample.loop_start = zone.loop_start + 1
sample.loop_end = zone.loop_end - 1
if zone.reverse then
sample.loop_mode = sample.LOOP_MODE_REVERSE
end
end
else
missing_samples = missing_samples + 1
end
else
missing_samples = missing_samples + 1
end
renoise.app():show_status(string.format("Importing EXS24 instrument (%d%%)...",((k/#exs.zones))*100))
coroutine.yield()
end
renoise.app():show_status("Importing Logic EXS24 instrument complete")
if missing_samples ~= 0 then
renoise.app():show_warning(string.format("%d samples could not be found", missing_samples))
end
end
local function import_exs(path)
renoise.app():show_status("Importing EXS24 instrument...")
local exs = load_exs(path)
if exs == false then
renoise.app():show_error("The EXS24 instrument could not be loaded")
table.clear(exs)
return false
end
if #exs.zones == 0 then
renoise.app():show_status("The EXS24 instrument did not contain any zones")
table.clear(exs)
return true
end
if #exs.samples == 0 then
renoise.app():show_status("The EXS24 instrument did not contain any samples")
table.clear(exs)
return true
end
local last_slash_pos = path:match"^.*()/"
local instrument_filename = path:sub(last_slash_pos + 1)
local instrument_path = path:sub(1, last_slash_pos)
local instrument = renoise.song().selected_instrument
instrument:clear()
instrument.name = instrument_filename:sub(1, -5)
local sample_path = sample_path(instrument_path, instrument_filename, exs.samples[1].file_name)
if not sample_path then
renoise.app():show_error("The EXS24 sample path could not be found")
end
local process = ProcessSlicer(import_samples, instrument, exs, sample_path)
process:start()
return true
end
if renoise.tool():has_file_import_hook("instrument", {"exs"}) == false then
renoise.tool():add_file_import_hook({
category = "instrument",
extensions = {"exs"},
invoke = import_exs
})
end