Ior_xml

class Ior
  def method_missing(name, *args, **kw)
    keys = ''
    kw.each {|k,v| keys += ' %s="%s"' % [k, v] }
    arg = args.join(' ')
    '<%s%s>%s</%s>' % [name, keys, arg, name]
  end
end

o = Ior.new

fx = o.effect                       type: 'Reverb',
                                    wetDryMix: 0.5,
                                    roomSize: 0.5
fx = o.effects fx
bus = o.bus fx,                     busVolume: 0.5,
                                    output1Target: 'MAIN_OUTPUT',
                                    output2Target: 'AUX_STEREO_OUTPUT_1',
                                    output1Volume: 0.8,
                                    output2Volume: 0.5

require 'nokogiri'
puts Nokogiri::XML(bus)

# <?xml version="1.0"?>
# <bus busVolume="0.5" output1Target="MAIN_OUTPUT"
#    output2Target="AUX_STEREO_OUTPUT_1" output1Volume="0.8"
#    output2Volume="0.5">
#   <effects>
#     <effect type="Reverb" wetDryMix="0.5" roomSize="0.5"/>
#   </effects>
# </bus>

# ==========================================================

# Allows for stuff like this:

oo = Ior.new
bindings =  [ { groupIndex: 0,
                translationOutputMin: 0,
                translationOutputMax: 1 },
              { groupIndex: 1,
                translationOutputMin: 1,
                translationOutputMax: 0
}].map {|kw|
  oo.binding    type: :amp,
                level: :group,
                parameter: 'AMP_VOLUME',
                translation: :linear,
                **kw
}

puts Nokogiri::XML(oo.x *bindings)

# <?xml version="1.0"?>
# <x>
#   <binding type="amp" level="group" parameter="AMP_VOLUME"
#     translation="linear" groupIndex="0" translationOutputMin="0"
#     translationOutputMax="1"/>
#   <binding type="amp" level="group" parameter="AMP_VOLUME"
#     translation="linear" groupIndex="1" translationOutputMin="1"
#     translationOutputMax="0"/>
# </x>