sforkowany z mirror/rnsutils
Add even more SFZ operand support
Loop was added (but untested), sample cycling (but it prevents layering for the same instrument), pan, volume, transpose, complete amplification adshr.master
rodzic
6a1590bc9e
commit
fb441c46a8
|
@ -13,6 +13,9 @@ from .utils import guesstimate_audio_extension
|
|||
def second_to_renoise_time(duration):
|
||||
return math.pow(duration / 60., 1 / 3.) if duration else None
|
||||
|
||||
def db_to_renoise_volume(volume):
|
||||
return math.exp(volume / 8.68) if volume else None
|
||||
|
||||
class RenoiseSample(ObjectifiedElement):
|
||||
pass
|
||||
|
||||
|
@ -69,6 +72,12 @@ class RenoiseModulationSet(ObjectifiedElement):
|
|||
|
||||
|
||||
class RenoiseInstrument(object):
|
||||
OVERLAP_CYCLE = "Cycle"
|
||||
OVERLAP_ALL = "Play All"
|
||||
|
||||
LOOP_NONE = "Off"
|
||||
LOOP_FORWARD = "Forward"
|
||||
|
||||
FILTER_NONE = 0
|
||||
FILTER_CLEAN_HP = 5
|
||||
FILTER_CLEAN_LP = 1
|
||||
|
|
|
@ -25,7 +25,7 @@ import os
|
|||
import re
|
||||
from copy import deepcopy
|
||||
|
||||
from rnsutils.instrument import RenoiseInstrument, second_to_renoise_time
|
||||
from rnsutils.instrument import RenoiseInstrument, second_to_renoise_time, db_to_renoise_volume
|
||||
|
||||
__date__ = '2016-01-28'
|
||||
__updated__ = '2016-01-28'
|
||||
|
@ -143,6 +143,7 @@ class SfzToXrni(object):
|
|||
|
||||
renoise_instrument.root.find('GlobalProperties/*[Name="SF2 reverb"]').Value = 0
|
||||
renoise_instrument.root.find('GlobalProperties/*[Name="SF2 chorus"]').Value = 0
|
||||
renoise_instrument.root.SampleGenerator.KeyzoneOverlappingMode = RenoiseInstrument.OVERLAP_ALL
|
||||
|
||||
with open(sfz_filename, 'rt') as sfz_file:
|
||||
# convert instrument meta data
|
||||
|
@ -163,7 +164,7 @@ class SfzToXrni(object):
|
|||
if section_name == 'group':
|
||||
self.convert_section(section_name, section_content, renoise_default_sample,
|
||||
renoise_default_modulation_set, renoise_default_sample,
|
||||
renoise_default_modulation_set)
|
||||
renoise_default_modulation_set, renoise_instrument)
|
||||
continue
|
||||
|
||||
# convert sample meta data in xml
|
||||
|
@ -174,7 +175,7 @@ class SfzToXrni(object):
|
|||
renoise_sample.ModulationSetIndex = section_idx
|
||||
|
||||
self.convert_section(section_name, section_content, renoise_sample, renoise_modulation_set,
|
||||
renoise_default_sample, renoise_default_modulation_set)
|
||||
renoise_default_sample, renoise_default_modulation_set, renoise_instrument)
|
||||
|
||||
renoise_instrument.root.SampleGenerator.Samples.append(renoise_sample)
|
||||
renoise_instrument.root.SampleGenerator.ModulationSets.append(renoise_modulation_set)
|
||||
|
@ -224,14 +225,19 @@ class SfzToXrni(object):
|
|||
return math.pow(envelope_attenuation / 60., 1 / 3.) if envelope_attenuation else None
|
||||
|
||||
def convert_section(self, section_name, section_content, renoise_sample, renoise_modulation_set,
|
||||
renoise_default_sample, renoise_default_modulation_set):
|
||||
renoise_default_sample, renoise_default_modulation_set, renoise_instrument):
|
||||
|
||||
unused_keys = []
|
||||
|
||||
for key in section_content.keys():
|
||||
value = section_content[key]
|
||||
value = section_content[key].lower()
|
||||
if key == 'sample':
|
||||
renoise_sample.FileName = re.sub(r'\\+', r'/', value)
|
||||
|
||||
# remove first char if file separator
|
||||
if renoise_sample.FileName.pyval[0] in (r'/', r'\\'):
|
||||
renoise_sample.FileName = renoise_sample.FileName.pyval[1:]
|
||||
|
||||
# renoise_sample.Name = os.path.basename(value)
|
||||
elif key == 'lokey':
|
||||
renoise_sample.Mapping.NoteStart = sfz_note_to_midi_key(value)
|
||||
|
@ -243,14 +249,28 @@ class SfzToXrni(object):
|
|||
renoise_sample.Mapping.VelocityEnd = value
|
||||
elif key == 'pitch_keycenter':
|
||||
renoise_sample.Mapping.BaseNote = sfz_note_to_midi_key(value)
|
||||
elif key == 'ampeg_release':
|
||||
renoise_modulation_set.Devices.SampleAhdsrModulationDevice.Release.Value = second_to_renoise_time(
|
||||
float(value))
|
||||
elif key == 'ampeg_attack':
|
||||
renoise_modulation_set.Devices.SampleAhdsrModulationDevice.Attack.Value = second_to_renoise_time(
|
||||
float(value))
|
||||
elif key == 'ampeg_hold':
|
||||
renoise_modulation_set.Devices.SampleAhdsrModulationDevice.Hold.Value = second_to_renoise_time(
|
||||
float(value))
|
||||
elif key == 'ampeg_decay':
|
||||
renoise_modulation_set.Devices.SampleAhdsrModulationDevice.Decay.Value = second_to_renoise_time(
|
||||
float(value))
|
||||
elif key == 'ampeg_sustain':
|
||||
renoise_modulation_set.Devices.SampleAhdsrModulationDevice.Sustain.Value = 1 - float(value) / 100.
|
||||
elif key == 'ampeg_release':
|
||||
renoise_modulation_set.Devices.SampleAhdsrModulationDevice.Release.Value = second_to_renoise_time(
|
||||
float(value))
|
||||
elif key == 'tune':
|
||||
renoise_sample.Finetune = int(128 * float(value) / 100.)
|
||||
elif key == 'transpose':
|
||||
renoise_sample.Transpose = value
|
||||
elif key == 'volume':
|
||||
renoise_sample.Volume = db_to_renoise_volume(float(value))
|
||||
elif key == 'pan':
|
||||
renoise_sample.Panning = 0.5 + float(value) / 200.
|
||||
elif key == 'fil_type':
|
||||
if value.lower().startswith('lp'):
|
||||
renoise_modulation_set.FilterType = RenoiseInstrument.FILTER_CLEAN_LP
|
||||
|
@ -258,9 +278,32 @@ class SfzToXrni(object):
|
|||
renoise_modulation_set.FilterType = RenoiseInstrument.FILTER_CLEAN_HP
|
||||
else:
|
||||
renoise_modulation_set.FilterType = RenoiseInstrument.FILTER_NONE
|
||||
elif key == 'loop_mode':
|
||||
if value == 'one_shot':
|
||||
renoise_sample.LoopMode = RenoiseInstrument.LOOP_FORWARD
|
||||
else:
|
||||
renoise_sample.LoopMode = RenoiseInstrument.LOOP_NONE
|
||||
elif key == 'loop_start':
|
||||
renoise_sample.LoopStart = value
|
||||
elif key == 'loop_end':
|
||||
renoise_sample.LoopEnd = value
|
||||
elif key == 'seq_position':
|
||||
if int(value) > 1:
|
||||
logging.info("Switch the entire instrument to sample cycling")
|
||||
renoise_instrument.root.SampleGenerator.KeyzoneOverlappingMode = RenoiseInstrument.OVERLAP_CYCLE
|
||||
elif key == 'seq_length':
|
||||
pass
|
||||
elif key == 'group':
|
||||
logging.info("Ignoring mute group info")
|
||||
elif key == 'off_by':
|
||||
logging.info("Ignoring mute group info")
|
||||
else:
|
||||
unused_keys.append(key)
|
||||
|
||||
# disable loop when no loop duration was set
|
||||
if renoise_sample.LoopStart.pyval is None or renoise_sample.LoopEnd.pyval is None:
|
||||
renoise_sample.LoopMode = RenoiseInstrument.LOOP_NONE
|
||||
|
||||
if unused_keys and self.show_unused:
|
||||
sys.stderr.write(
|
||||
"Unused key(s) for section {}:\n{}\n".format(section_name,
|
||||
|
|
Ładowanie…
Reference in New Issue