Advertisement
Guest User

dwi converter

a guest
Jul 19th, 2013
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local note_lookup_table = {
  2.     ['1000'] = '4',    ['0100'] = '2',
  3.     ['0010'] = '8',    ['0001'] = '6',
  4.     ['1100'] = '1',    ['1010'] = '7',
  5.     ['1001'] = 'B',    ['0110'] = 'A',
  6.     ['0101'] = '3',    ['0011'] = '9',
  7.     ['1110'] = '<81>', ['0111'] = '<83>',
  8.     ['1101'] = '<61>', ['1011'] = '<8B>',
  9.     ['1111'] = '<19>', ['0000'] = '0',
  10. }
  11.  
  12. function string:getFieldContents(field)
  13.     local _, idx = self:find('#' .. field .. ':')
  14.     local str = self:match('%b:;', idx)
  15.     return str:sub(2, #str - 1)
  16. end
  17.  
  18. local function processMeasure(measure)
  19.     local beat_notes = {''} -- reserve beat_notes[1] for opening tag if necessary
  20.     local note_count = 0
  21.     for note in measure:gmatch('%d%d%d%d') do
  22.         table.insert(beat_notes, note_lookup_table[note])
  23.         table.insert(beat_notes, '') -- for possible note padding
  24.         note_count = note_count + 1
  25.     end
  26.  
  27.     if note_count == 4 then
  28.         for i=3, 9, 2 do beat_notes[i] = '0' end -- add appropriate note padding
  29.     elseif note_count == 8 then
  30.     elseif note_count == 12 then
  31.         for i=3, 25, 2 do beat_notes[i] = '0' end
  32.         beat_notes[1] = '['; table.insert(beat_notes, ']')
  33.     elseif note_count == 16 then
  34.         beat_notes[1] = '('; table.insert(beat_notes, ')')
  35.     elseif note_count == 24 then
  36.         beat_notes[1] = '['; table.insert(beat_notes, ']')
  37.     elseif note_count == 32 then
  38.         for i=3, 65, 2 do beat_notes[i] = '0' end
  39.         beat_notes[1] = '{'; table.insert(beat_notes, '}')
  40.     elseif note_count == 48 then
  41.         for i=3, 97, 2 do beat_notes[i] = '000' end
  42.         beat_notes[1] = '`'; table.insert(beat_notes, '\'')
  43.     elseif note_count == 64 then
  44.         beat_notes[1] = '{'; table.insert(beat_notes, '}')
  45.     elseif note_count == 96 then
  46.         for i=3, 193, 2 do beat_notes[i] = '0' end
  47.         beat_notes[1] = '`'; table.insert(beat_notes, '\'')
  48.     elseif note_count == 192 then
  49.         beat_notes[1] = '`'; table.insert(beat_notes, '\'')
  50.     else
  51.         return nil -- invalid note count
  52.     end
  53.  
  54.     return table.concat(beat_notes) .. '\n'
  55. end
  56.  
  57. local function smToDwi(full_path)
  58.     -- open sm file to read contents into string
  59.     local sm_file
  60.     do
  61.         local tmp = io.open(full_path .. '.sm')
  62.         sm_file = tmp:read('*a')
  63.         tmp:close()
  64.     end
  65.  
  66.     local changebpm = sm_file:getFieldContents('BPMS')
  67.     local start_bpm
  68.     do -- separate first bpm and bpm changes
  69.         start_bpm = changebpm:match('%d+%.?%d*%s*=%s*(%d+%.?%d*)')
  70.         local _, idx = changebpm:find('%d+%.?%d*%s*=%s*%d+%.?%d*%s*,')
  71.         if idx then
  72.             changebpm = changebpm:sub(idx + 1)
  73.         else
  74.             changebpm = ''
  75.         end
  76.     end
  77.  
  78.     -- multiply all measures by 4 to convert to beat counts
  79.     local changebpm_str = {}
  80.     if changebpm ~= '' then
  81.         for beat, bpm, comma in changebpm:gmatch('(%d+%.?%d*)%s*(=%s*%d+%.?%d*)(,?)') do
  82.             table.insert(changebpm_str, string.format("%.3f", tonumber(beat) * 4)..bpm)
  83.             if comma ~= '' then table.insert(changebpm_str, ',') end
  84.         end
  85.     end
  86.  
  87.     -- process common .sm file fields
  88.     local file_contents = {}
  89.     table.insert(file_contents, '#TITLE:'         .. sm_file:getFieldContents('TITLE')                    .. ';\n')
  90.     table.insert(file_contents, '#ARTIST:'        .. sm_file:getFieldContents('ARTIST')                   .. ';\n')
  91.     table.insert(file_contents, '#FILE:'          .. sm_file:getFieldContents('MUSIC')                    .. ';\n')
  92.     table.insert(file_contents, '#BPM:'           .. start_bpm                                            .. ';\n')
  93.     table.insert(file_contents, '#GAP:'           .. tonumber(sm_file:getFieldContents('OFFSET')) * -1000 .. ';\n')
  94.     table.insert(file_contents, '#SAMPLESTART:'   .. sm_file:getFieldContents('SAMPLESTART')              .. ';\n')
  95.     table.insert(file_contents, '#SAMPLELENGTH:'  .. sm_file:getFieldContents('SAMPLELENGTH')             .. ';\n\n')
  96.     if changebpm ~= '' then
  97.         table.insert(file_contents, '#CHANGEBPM:' .. table.concat(changebpm_str)                          .. ';\n')
  98.     end
  99.     table.insert(file_contents, '#SINGLE:MANIAC:1:\n')
  100.  
  101.     do -- extract start of note data to end of file
  102.         local _, idx = sm_file:find('%d+%.%d+%s*%:', idx)
  103.         sm_file = sm_file:sub(idx + 1)
  104.     end
  105.  
  106.     for measure in sm_file:gmatch('.-[,;]') do
  107.         table.insert(file_contents, processMeasure(measure))
  108.     end
  109.  
  110.     -- save converted file
  111.     local dwi_file = io.open(full_path .. '.dwi', 'w')
  112.     dwi_file:write(table.concat(file_contents)..'\n')
  113.     dwi_file:close()
  114. end
  115.  
  116. smToDwi('test')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement