Differences

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

Link to this comparison view

Next revision
Previous revision
wiki:user:emrum:sfz_to_h2 [2012/04/30 18:03] – created sfz to h2 script emrumwiki:user:emrum:sfz_to_h2 [2015/11/08 16:26] (current) 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>
 +
 +
 +
 +\\
 +\\
 +Note: hydrogen ignores midi notes (key=36) below NR. 36 (=bass drum) ! 
 +\\
 +\\
 +\\
 +Python Script:
 +\\
 +--
 \\ \\
  
Line 68: Line 111:
  
  
 +#!/usr/bin/python
 +# -*- coding: utf-8 -*-
  
-import sys + 
-import string+#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 90: Line 136:
  
 ############################################################################# #############################################################################
- +  
 + 
 # <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 125: Line 171:
  </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 142: Line 188:
  <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 149: Line 195:
  
 ############################################################################# #############################################################################
- +  
- +  
 + 
 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 178: Line 224:
  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 193: Line 239:
  #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 247: Line 294:
  # 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 274: Line 321:
  #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 322: Line 369:
  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 363: Line 423:
  
 ############################################################################# #############################################################################
- +  
- +  
- +  
 + 
 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.1335801789.txt.gz · Last modified: 2012/04/30 18:03 by emrum