Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
wiki:user:emrum:sfz_to_h2 [2013/03/26 22:54] newacctwiki:user:emrum:sfz_to_h2 [2015/11/08 16:24] – add some notes emrum
Line 8: Line 8:
 \\ \\
 \\ \\
 +Unfortunately this script is NOT flexible and requires a certain SFZ custom format (as in matchstr object below).
 \\ \\
 +\\
 +create an SFZ file in the same directory, with name 
 +\\
 +"drumkit.sfz"
 +\\
 +\\
 +
 +run the script:
 +\\
 +python sfz_to_h2.py
 +\\
 +\\
 +
 +
 +The SFZ file content format must be very close to this:
 +\\
 +\\
 +
 +
 +
 +<code python>
 +<region>  key=34  offset=0  lovel=0  hivel=127  sample=ogg/beats_01-34.oga
 +<region>  key=35  offset=0  lovel=0  hivel=127  sample=ogg/beats_06-50.oga
 +// c3 - bass drum 1
 +<region>  key=36  offset=0  lovel=0  hivel=127  sample=ogg/beats_06-38.oga
 +// c#3 - stick
 +<region>  key=37  offset=0  lovel=0  hivel=127  sample=ogg/beats_09-12.oga
 +// d3 - snare 1
 +<region>  key=38  offset=0  lovel=0  hivel=127  sample=ogg/beats_01-21.oga
 +</code>
 +
 +
 +
 +\\
 +\\
 +
 +\\
 +\\
 +Python Script:
 +\\
 +--
 \\ \\
  
Line 68: Line 110:
  
  
 +#!/usr/bin/python
 +# -*- coding: utf-8 -*-
  
 +
 +#import sys
 import re import re
 +import os, os.path
  
- + 
- +
 # ADJUST INPUT FILE NAME  (will not be modified) # ADJUST INPUT FILE NAME  (will not be modified)
 # #
 # #
 filename = 'drumkit.sfz' filename = 'drumkit.sfz'
 +
 +output_file = 'drumkit.h2.xml'
 # #
 ############################################################################# #############################################################################
- +  
- +  
 + 
 ############################################################################# #############################################################################
  
Line 88: Line 135:
  
 ############################################################################# #############################################################################
- +  
 + 
 # <region>  key=37  offset=0  lovel=0  hivel=127  sample=ogg/beats_09-12.oga  # <region>  key=37  offset=0  lovel=0  hivel=127  sample=ogg/beats_09-12.oga 
 + 
 # hydrogen 2 xml-file template  # hydrogen 2 xml-file template 
 + 
 h2tem_head = ''' h2tem_head = '''
 <drumkit_info> <drumkit_info>
- + 
  <name>Drumkit Name</name>  <name>Drumkit Name</name>
- + 
  <author>Author Name</author>  <author>Author Name</author>
- + 
  <license>License Info + License URL</license>  <license>License Info + License URL</license>
- + 
  <info> Information </info>  <info> Information </info>
- + 
  <instrumentList>  <instrumentList>
  '''  '''
 + 
 h2tem = ''' h2tem = '''
  <instrument>  <instrument>
  <id>%s</id>  <id>%s</id>
 + 
  <name>%s</name>  <name>%s</name>
 + 
  <filename>%s</filename>  <filename>%s</filename>
 + 
  <volume>0.900000</volume>  <volume>0.900000</volume>
  <isMuted>false</isMuted>  <isMuted>false</isMuted>
Line 123: Line 170:
  </instrument>  </instrument>
  '''  '''
 + 
 h2tem_foot = ''' h2tem_foot = '''
  </instrumentList>  </instrumentList>
 </drumkit_info> </drumkit_info>
  '''  '''
 + 
 # test string (part of an SFZ file) # test string (part of an SFZ file)
 matchstr = """ matchstr = """
Line 140: Line 187:
  <region>  key=38  offset=0  lovel=0  hivel=127  sample=ogg/beats_01-21.oga   <region>  key=38  offset=0  lovel=0  hivel=127  sample=ogg/beats_01-21.oga 
  """  """
- +  
 + 
 ############################################################################# #############################################################################
  
Line 147: Line 194:
  
 ############################################################################# #############################################################################
- +  
- +  
 + 
 fcont = '' fcont = ''
- +  
 + 
 def read_file(): def read_file():
  global fcont  global fcont
- + 
  # try:  # try:
- f = file( filename, 'rb'+ f = open( filename, 'rb'
- fcont = f.read()+ fcont = str( f.read()
  f.close()  f.close()
- +  
 + 
 def create_match_dic( mat ): def create_match_dic( mat ):
 + 
  #print "match : ", mat  #print "match : ", mat
- + 
  if type( mat ) is tuple:  if type( mat ) is tuple:
  m1 = mat[0]  m1 = mat[0]
Line 176: Line 223:
  print( "Error in create_match_dic() - mat is neither tuple nor string ")  print( "Error in create_match_dic() - mat is neither tuple nor string ")
  return   return 
- + 
  dd = {}  dd = {}
- + 
  s2 = m2.split(' ')  s2 = m2.split(' ')
  for k in s2:  for k in s2:
- + 
  ss = k.strip()  ss = k.strip()
- + 
  if ss != '':  if ss != '':
- + 
  s3 = ss.split('=')   s3 = ss.split('=')
  if len(s3) > 1:  if len(s3) > 1:
Line 191: Line 238:
  #end  #end
  #end  #end
- + 
  # note: m1 is set, if there is a comment   # note: m1 is set, if there is a comment 
  # before the <region> word in the sfz file  # before the <region> word in the sfz file
- + 
  dd['comment'] = m1  dd['comment'] = m1
- + 
  #print " Dic : ", dd  #print " Dic : ", dd
- + 
  return dd  return dd
- +  
- +  
 + 
 def process_file(): def process_file():
- + 
  ins_id = '0'  ins_id = '0'
  name = 'bass drum 1'  name = 'bass drum 1'
  filename = 'flac/beats_08-19.flac'  filename = 'flac/beats_08-19.flac'
- + 
  ret = ''  ret = ''
 + 
  # common variables  # common variables
- + 
  # match with comment  # match with comment
  #rawstr_c = r"""\/\/\s?(.*)\s?\n\<region\>(.*)"""  #rawstr_c = r"""\/\/\s?(.*)\s?\n\<region\>(.*)"""
  rawstr_c = r"""\/\/\s?(.*)\s?\n\<region\>([^\<]*)"""  rawstr_c = r"""\/\/\s?(.*)\s?\n\<region\>([^\<]*)"""
- + 
  # match without comment  # match without comment
  #rawstr_n = r"""\<region\>(.*)"""  #rawstr_n = r"""\<region\>(.*)"""
  rawstr_n = r"""\<region\>([^\<]*)"""  rawstr_n = r"""\<region\>([^\<]*)"""
- + 
  # embedded_rawstr = r"""(?mx)\<region\>(.*)"""  # embedded_rawstr = r"""(?mx)\<region\>(.*)"""
   
- matchstr = fcont + global fcont 
- + matchstr = str( fcont ) 
 + 
  # use a compile object  # use a compile object
  re_comp_n = re.compile( rawstr_n,  re.MULTILINE| re.VERBOSE |re.DOTALL )  re_comp_n = re.compile( rawstr_n,  re.MULTILINE| re.VERBOSE |re.DOTALL )
  re_comp_c = re.compile( rawstr_c,  re.MULTILINE| re.VERBOSE |re.DOTALL )  re_comp_c = re.compile( rawstr_c,  re.MULTILINE| re.VERBOSE |re.DOTALL )
-  +  
-  +  
-  +  
-  +  
- + 
  # first process matches _with_ comment  # first process matches _with_ comment
  #####################################  #####################################
- + 
  # search pattern  # search pattern
  #match_obj = re_comp_c.search(matchstr)  #match_obj = re_comp_c.search(matchstr)
- matches =  re_comp_c.findall(matchstr) + matches =  re_comp_c.findall( matchstr )
  #print matches  #print matches
  #dir( matches )  #dir( matches )
Line 245: Line 293:
  # Retrieve group(s) from match_obj  # Retrieve group(s) from match_obj
  #all_groups = match_obj.groups()  #all_groups = match_obj.groups()
- + 
  # a dic with instrument-id as key and another dic as value,   # a dic with instrument-id as key and another dic as value, 
  # containing name-value mappings for a region  # containing name-value mappings for a region
  all_mat = {}  all_mat = {}
- + 
  for mat in matches:  for mat in matches:
  # matches with comment  # matches with comment
- + 
  # mDic has name-value mappings for a single region  # mDic has name-value mappings for a single region
  mDic = create_match_dic( mat )  mDic = create_match_dic( mat )
- + 
  ins_id = mDic['key'] # 0  ins_id = mDic['key'] # 0
  all_mat[ ins_id ] = mDic  all_mat[ ins_id ] = mDic
 + 
  # end for(mat)  # end for(mat)
-  +  
-  +  
-  +  
- + 
  # now process matches _without_ comment  # now process matches _without_ comment
  #####################################  #####################################
 + 
  # search pattern  # search pattern
  #match_obj = re_comp_n.search(matchstr)  #match_obj = re_comp_n.search(matchstr)
Line 272: Line 320:
  #print matches  #print matches
  #dir( matches )  #dir( matches )
- + 
  # Retrieve group(s) from match_obj  # Retrieve group(s) from match_obj
  #all_groups = match_obj.groups()  #all_groups = match_obj.groups()
- + 
  for mat in matches:  for mat in matches:
  # matches without comment  # matches without comment
- + 
  mDic = create_match_dic( mat )  mDic = create_match_dic( mat )
- + 
  ins_id = mDic['key'] # 0  ins_id = mDic['key'] # 0
- + 
  if mDic['comment'] == '':  if mDic['comment'] == '':
  mDic['comment'] = 'Sample: ' + mDic['sample']  mDic['comment'] = 'Sample: ' + mDic['sample']
-  +  
- if all_mat.has_key( ins_id ):+ if ins_id in all_mat:
  pass  pass
  # region was processed in previous match round (with comments)  # region was processed in previous match round (with comments)
  else:  else:
  all_mat[ ins_id ] = mDic  all_mat[ ins_id ] = mDic
- + 
  # end for(mat)  # end for(mat)
-  +  
-  +  
-  +  
-  +  
- keys = all_mat.keys()+ keys = list(all_mat.keys())
  # sort regions (found matches) by instrument id  # sort regions (found matches) by instrument id
  keys.sort()  keys.sort()
- + 
  sorted_out_dic = {}  sorted_out_dic = {}
  last_id = 0  last_id = 0
- + 
  for k in keys:  for k in keys:
  mDic = all_mat[ k ]  mDic = all_mat[ k ]
- + 
  ins_id = mDic['key'] # 0  ins_id = mDic['key'] # 0
  ins_id_nr = int(ins_id)  ins_id_nr = int(ins_id)
  name = mDic['comment'] # bass drum 1  name = mDic['comment'] # bass drum 1
  filename = mDic['sample'] # flac/beats_08-19.flac  filename = mDic['sample'] # flac/beats_08-19.flac
- + 
  if int(ins_id) < 36:  if int(ins_id) < 36:
  #  #
Line 320: Line 368:
  sorted_out_dic[ ins_id ] = mDic  sorted_out_dic[ ins_id ] = mDic
  continue  continue
- + 
  #last_id = ins_id_nr  #last_id = ins_id_nr
- + 
  temx = h2tem % ( last_id, name, filename )  temx = h2tem % ( last_id, name, filename )
  ret += temx  ret += temx
  last_id += 1  last_id += 1
-  +  
-  +  
- keys = sorted_out_dic.keys()+ keys = list(sorted_out_dic.keys())
  # sort regions (found matches) by instrument id  # sort regions (found matches) by instrument id
  keys.sort()  keys.sort()
  for k in keys:  for k in keys:
  mDic = sorted_out_dic[ k ]  mDic = sorted_out_dic[ k ]
- + 
  last_id += 1  last_id += 1
- + 
  ins_id = mDic['key'] # 0  ins_id = mDic['key'] # 0
  ins_id_nr = last_id # int( ins_id) + last_id  ins_id_nr = last_id # int( ins_id) + last_id
  name = mDic['comment'] # bass drum 1  name = mDic['comment'] # bass drum 1
  filename = mDic['sample'] # flac/beats_08-19.flac  filename = mDic['sample'] # flac/beats_08-19.flac
- + 
  temx = h2tem % ( str(ins_id_nr), name, filename )  temx = h2tem % ( str(ins_id_nr), name, filename )
  ret += temx  ret += temx
 + 
 + 
 + 
 + # FINAL OUTPUT
 + #
 + output_text = h2tem_head + ret + h2tem_foot
   
 + # print( out )
   
 + global output_file
 + # output_file = 'drumkit.h2.xml'
   
-FINAL OUTPUT + if os.path.exists( output_file ): 
-+ print( 'NOTE: File NOT written. File %s already exists. ' % output_file ) 
- print h2tem_head ret + h2tem_foot + else: 
-  + f = open( output_file, 'w+b'
 + f.write( bytes( output_text, 'UTF-8' )) 
 + f.write( output_text.encode('UTF-8') ) 
 + f.close() 
 +
 + print( 'Output file written: ' output_file )
  
  
Line 361: Line 422:
  
 ############################################################################# #############################################################################
- +  
- +  
- +  
 + 
 def main(): def main():
- + 
  read_file()  read_file()
- + 
  process_file()  process_file()
-  +  
- +  
- +  
 + 
 if __name__ == '__main__': if __name__ == '__main__':
  main()  main()
- +  
- +  
- +  
- +  
 + 
 k = """ k = """
 // 35 Acoustic Bass Drum // 35 Acoustic Bass Drum
wiki/user/emrum/sfz_to_h2.txt · Last modified: 2015/11/08 16:26 by emrum