SHOW:
|
|
- or go back to the newest paste.
1 | - | local note_lookup_table = { |
1 | + | -- make global functions local for faster lookup |
2 | - | ['1000'] = '4', ['0100'] = '2', |
2 | + | local table = table |
3 | - | ['0010'] = '8', ['0001'] = '6', |
3 | + | local append, concat = table.insert, table.concat |
4 | - | ['1100'] = '1', ['1010'] = '7', |
4 | + | local string = string |
5 | - | ['1001'] = 'B', ['0110'] = 'A', |
5 | + | local sub, gsub, lower = string.sub, string.gsub, string.lower |
6 | - | ['0101'] = '3', ['0011'] = '9', |
6 | + | local find, match, gmatch = string.find, string.match, string.gmatch |
7 | - | ['1110'] = '<81>', ['0111'] = '<83>', |
7 | + | local ipairs, pairs = ipairs, pairs |
8 | - | ['1101'] = '<61>', ['1011'] = '<8B>', |
8 | + | |
9 | - | ['1111'] = '<19>', ['0000'] = '0', |
9 | + | local function file_search(filter, dir_path) |
10 | - | } |
10 | + | local function c_in(value, tab) |
11 | for _, v in pairs(tab) do | |
12 | - | function string:getFieldContents(field) |
12 | + | if v == value then return true end |
13 | - | local _, idx = self:find('#' .. field .. ':') |
13 | + | |
14 | - | local str = self:match('%b:;', idx) |
14 | + | return false |
15 | - | return str:sub(2, #str - 1) |
15 | + | |
16 | ||
17 | function string:split(sep) | |
18 | local sep, fields = sep or ":", {} | |
19 | local pattern = string.format("([^%s]+)", sep) | |
20 | self:gsub(pattern, function(c) fields[#fields+1] = c end) | |
21 | return fields | |
22 | - | table.insert(beat_notes, note_lookup_table[note]) |
22 | + | |
23 | - | table.insert(beat_notes, '') -- for possible note padding |
23 | + | |
24 | local fs = require 'lfs' | |
25 | local filter = string.lower(filter) or "*" | |
26 | local dir_path = dir_path or fs.currentdir() | |
27 | local extensions = filter:split(";") | |
28 | ||
29 | - | elseif note_count == 8 then |
29 | + | local files = {} |
30 | for _, path in ipairs(dir_path:split(";")) do | |
31 | for f in fs.dir(path) do | |
32 | - | beat_notes[1] = '['; table.insert(beat_notes, ']') |
32 | + | if f ~= "." and f ~= ".." then |
33 | local attr = fs.attributes(path..'\\'..f) | |
34 | - | beat_notes[1] = '('; table.insert(beat_notes, ')') |
34 | + | if attr.mode == "file" then |
35 | if filter=="*" or | |
36 | - | beat_notes[1] = '['; table.insert(beat_notes, ']') |
36 | + | c_in(lower(f:match('%.%w*$')), extensions) then |
37 | append(files, {path = path..'\\', name = f}) | |
38 | end | |
39 | - | beat_notes[1] = '{'; table.insert(beat_notes, '}') |
39 | + | elseif attr.mode == "directory" then |
40 | local subf = file_search(filter, path..'\\'..f) | |
41 | for _, v in ipairs(subf) do | |
42 | - | beat_notes[1] = '`'; table.insert(beat_notes, '\'') |
42 | + | append(files, {path = v.path, name = v.name}) |
43 | end | |
44 | - | beat_notes[1] = '{'; table.insert(beat_notes, '}') |
44 | + | end |
45 | end | |
46 | end | |
47 | - | beat_notes[1] = '`'; table.insert(beat_notes, '\'') |
47 | + | |
48 | return files | |
49 | - | beat_notes[1] = '`'; table.insert(beat_notes, '\'') |
49 | + | |
50 | ||
51 | local function processMeasure(measure) | |
52 | local note_lookup_table = { | |
53 | ['1000'] = '4', ['0100'] = '2', | |
54 | - | return table.concat(beat_notes) .. '\n' |
54 | + | ['0010'] = '8', ['0001'] = '6', |
55 | ['1100'] = '1', ['1010'] = '7', | |
56 | ['1001'] = 'B', ['0110'] = 'A', | |
57 | ['0101'] = '3', ['0011'] = '9', | |
58 | ['1110'] = '<81>', ['0111'] = '<83>', | |
59 | ['1101'] = '<61>', ['1011'] = '<8B>', | |
60 | ['1111'] = '<19>', ['0000'] = '0', | |
61 | - | local tmp = io.open(full_path .. '.sm') |
61 | + | } |
62 | local beat_notes = {''} -- reserve beat_notes[1] for opening tag if necessary | |
63 | local note_count = 0 | |
64 | ||
65 | for note in measure:gmatch('%d%d%d%d') do | |
66 | append(beat_notes, note_lookup_table[note]) | |
67 | append(beat_notes, '') -- for possible note padding | |
68 | note_count = note_count + 1 | |
69 | end | |
70 | ||
71 | - | if idx then |
71 | + | |
72 | - | changebpm = changebpm:sub(idx + 1) |
72 | + | |
73 | - | else |
73 | + | elseif note_count == 8 then |
74 | - | changebpm = '' |
74 | + | |
75 | for i=3, 25, 2 do beat_notes[i] = '0' end | |
76 | beat_notes[1] = '['; append(beat_notes, ']') | |
77 | elseif note_count == 16 then | |
78 | - | -- multiply all measures by 4 to convert to beat counts |
78 | + | beat_notes[1] = '('; append(beat_notes, ')') |
79 | - | local changebpm_str = {} |
79 | + | |
80 | - | if changebpm ~= '' then |
80 | + | beat_notes[1] = '['; append(beat_notes, ']') |
81 | - | for beat, bpm, comma in changebpm:gmatch('(%d+%.?%d*)%s*(=%s*%d+%.?%d*)(,?)') do |
81 | + | |
82 | - | table.insert(changebpm_str, string.format("%.3f", tonumber(beat) * 4)..bpm) |
82 | + | |
83 | - | if comma ~= '' then table.insert(changebpm_str, ',') end |
83 | + | beat_notes[1] = '{'; append(beat_notes, '}') |
84 | elseif note_count == 48 then | |
85 | for i=3, 97, 2 do beat_notes[i] = '000' end | |
86 | beat_notes[1] = '`'; append(beat_notes, '\'') | |
87 | elseif note_count == 64 then | |
88 | beat_notes[1] = '{'; append(beat_notes, '}') | |
89 | - | table.insert(file_contents, '#TITLE:' .. sm_file:getFieldContents('TITLE') .. ';\n') |
89 | + | |
90 | - | table.insert(file_contents, '#ARTIST:' .. sm_file:getFieldContents('ARTIST') .. ';\n') |
90 | + | |
91 | - | table.insert(file_contents, '#FILE:' .. sm_file:getFieldContents('MUSIC') .. ';\n') |
91 | + | beat_notes[1] = '`'; append(beat_notes, '\'') |
92 | - | table.insert(file_contents, '#BPM:' .. start_bpm .. ';\n') |
92 | + | |
93 | - | table.insert(file_contents, '#GAP:' .. tonumber(sm_file:getFieldContents('OFFSET')) * -1000 .. ';\n') |
93 | + | beat_notes[1] = '`'; append(beat_notes, '\'') |
94 | - | table.insert(file_contents, '#SAMPLESTART:' .. sm_file:getFieldContents('SAMPLESTART') .. ';\n') |
94 | + | |
95 | - | table.insert(file_contents, '#SAMPLELENGTH:' .. sm_file:getFieldContents('SAMPLELENGTH') .. ';\n\n') |
95 | + | |
96 | - | if changebpm ~= '' then |
96 | + | |
97 | - | table.insert(file_contents, '#CHANGEBPM:' .. table.concat(changebpm_str) .. ';\n') |
97 | + | |
98 | return concat(beat_notes) .. '\n' | |
99 | - | table.insert(file_contents, '#SINGLE:MANIAC:1:\n') |
99 | + | |
100 | ||
101 | - | do -- extract start of note data to end of file |
101 | + | ------------------------------------------------------------------------------------------------- |
102 | - | local _, idx = sm_file:find('%d+%.%d+%s*%:', idx) |
102 | + | |
103 | - | sm_file = sm_file:sub(idx + 1) |
103 | + | |
104 | -- open sm file to read contents into string | |
105 | local sm_file | |
106 | do | |
107 | - | table.insert(file_contents, processMeasure(measure)) |
107 | + | local tmp = io.open(full_path) |
108 | sm_file = tmp:read('*a') | |
109 | tmp:close() | |
110 | - | -- save converted file |
110 | + | |
111 | - | local dwi_file = io.open(full_path .. '.dwi', 'w') |
111 | + | |
112 | - | dwi_file:write(table.concat(file_contents)..'\n') |
112 | + | function string:getFieldContents(field) |
113 | - | dwi_file:close() |
113 | + | local _, idx = self:find('#'..field..':') |
114 | local str = self:match('%b:;', idx) | |
115 | return str:sub(2, #str - 1) | |
116 | - | smToDwi('test') |
116 | + | |
117 | ||
118 | local changebpm = sm_file:getFieldContents('BPMS') | |
119 | local start_bpm | |
120 | do -- separate first bpm and bpm changes | |
121 | start_bpm = changebpm:match('%d+%.?%d*%s*=%s*(%d+%.?%d*)') | |
122 | local _, idx = changebpm:find('%d+%.?%d*%s*=%s*%d+%.?%d*%s*,') | |
123 | ||
124 | if idx then changebpm = changebpm:sub(idx + 1) | |
125 | else changebpm = '' end | |
126 | end | |
127 | ||
128 | if changebpm then -- multiply all measures by 4 to convert to beats | |
129 | changebpm = changebpm:gsub('(%d+%.?%d*)(%s*=%s*%d+%.?%d*,?)', function(beat, bpm) | |
130 | return string.format('%.3f', beat * 4)..bpm | |
131 | end) | |
132 | end | |
133 | ||
134 | -- process common .sm file fields | |
135 | local file_contents = {} | |
136 | append(file_contents, '#TITLE:' .. sm_file:getFieldContents('TITLE') .. ';\n') | |
137 | append(file_contents, '#ARTIST:' .. sm_file:getFieldContents('ARTIST') .. ';\n') | |
138 | append(file_contents, '#FILE:' .. sm_file:getFieldContents('MUSIC') .. ';\n') | |
139 | append(file_contents, '#BPM:' .. start_bpm .. ';\n') | |
140 | append(file_contents, '#GAP:' .. tonumber(sm_file:getFieldContents('OFFSET')) * -1000 .. ';\n') | |
141 | append(file_contents, '#SAMPLESTART:' .. sm_file:getFieldContents('SAMPLESTART') .. ';\n') | |
142 | append(file_contents, '#SAMPLELENGTH:' .. sm_file:getFieldContents('SAMPLELENGTH') .. ';\n\n') | |
143 | if changebpm then | |
144 | append(file_contents, '#CHANGEBPM:' .. changebpm .. ';\n') | |
145 | end | |
146 | append(file_contents, '#SINGLE:MANIAC:1:\n') | |
147 | ||
148 | sm_file = sm_file:match(':.+$') -- extract start of note data to end of file | |
149 | ||
150 | for measure in sm_file:gmatch('.-[,;]') do | |
151 | append(file_contents, processMeasure(measure)) | |
152 | end | |
153 | ||
154 | do -- save converted file | |
155 | local contents = concat(file_contents) | |
156 | local dwi_file = io.open(full_path:gsub('%.%w*$', '.dwi'), 'w') | |
157 | dwi_file:write(contents..'\n') | |
158 | dwi_file:close() | |
159 | end | |
160 | end | |
161 | ||
162 | ------------------------------------------------------------------------------------------------- | |
163 | ||
164 | for _, file in ipairs(file_search('.sm;.ssc;.ds')) do | |
165 | smToDwi(file.path .. file.name) | |
166 | end |