A
download rubber.rb
Language: Ruby
LOC: 263
Project Info
Snd
Server: SourceForge
Type: cvs
SourceForge\s\snd\snd\cvs‑snd\
   _new_snd-test.rb
   _sndlib.h
   aclocal.m4
   analog-filter.scm
   audinfo.c
   audio.c
   autosave.scm
   bess.rb
   bess.scm
   bess1.rb
   bess1.scm
   bird.rb
   bird.scm
   clm-ins.rb
   clm-ins.scm
   clm-strings.h
   clm.c
   clm.h
   clm23.scm
   clm2xen.c
   clm2xen.h
   cmn-glyphs.lisp
   config.guess
   config.h.in
   config.rpath
   config.sub
   configure.ac
   debug.scm
   dlocsig.rb
   draw.rb
   draw.scm
   dsp.rb
   dsp.scm
   edit-menu.scm
   edit123.scm
   effects-utils.scm
   effects.rb
   env.rb
   env.scm
   enved.scm
   eval-c.scm
   event.scm
   examp.rb
   examp.scm
   extensions.rb
   extensions.scm
   fade.scm
   fft-menu.scm
   fix-optargs.scm
   fmv.scm
   freeverb.rb
   freeverb.scm
   gettext.h
   gl.c
   grani.scm
   gtk-effects.scm
   gtk-popup.scm
   gui.scm
   headers.c
   help-snd-fm.pd
   help-snd.pd
   HISTORY.Snd
   hooks.rb
   hooks.scm
   index.rb
   index.scm
   inf-snd.el
   io.c
   jcrev.scm
   ladspa-help.scm
   ladspa.scm
   makefile.in
   makefile.no-gettext
   maraca.rb
   maraca.scm
   marks-menu.scm
   marks.rb
   marks.scm
   maxf.rb
   maxf.scm
   midi.c
   misc.scm
   mix-menu.scm
   mix.rb
   mix.scm
   mixer.scm
   moog.scm
   musglyphs.rb
   musglyphs.scm
   nb.rb
   nb.scm
   new-backgrounds.scm
   new-buttons.scm
   new-effects.scm
   new-icons.scm
   noise.rb
   noise.scm
   old-mac-audio.c
   old-snd.spec
   oo.scm
   oscope.scm
   panic.scm
   pd-add.scm
   pd-any.scm
   pd-fm.scm
   pd-global.scm
   pd-inout.scm
   pd-local.scm
   pd-mozilla.scm
   pd-send_receive.scm
   peak-env.scm
   piano.rb
   piano.scm
   play.rb
   play.scm
   poly.rb
   poly.scm
   popup.rb
   popup.scm
   prc95.rb
   prc95.scm
   pvoc.rb
   pvoc.scm
   README.Snd
   rgb.rb
   rgb.scm
   rmsgain.scm
   rt-compiler.scm
   rt-engine.scm
   rt-examples.scm
   rt.tex
   rtio.rb
   rtio.scm
   rubber.rb
   rubber.scm
   saw.c
   singer.rb
   singer.scm
   snd-0.h
   snd-1.h
   snd-axis.c
   snd-chn.c
   snd-completion.c
   snd-dac.c
   snd-data.c
   snd-draw.c
   snd-edits.c
   snd-env.c
   snd-error.c
   snd-fft.c
   snd-file.c
   snd-file.h
   snd-find.c
   snd-g0.h
   snd-g1.h
   snd-gchn.c
   snd-gdraw.c
   snd-gdrop.c
   snd-genv.c
   snd-gfft.c
   snd-gfile.c
   snd-gfind.c
   snd-ghelp.c
   snd-gl.scm
   snd-glistener.c
   snd-gmain.c
   snd-gmenu.c
   snd-gmix.c
   snd-gprefs.c
   snd-gprint.c
   snd-grec.c
   snd-gregion.c
   snd-gsnd.c
   snd-gtk.scm
   snd-gutils.c
   snd-gxbitmaps.c
   snd-gxcolormaps.c
   snd-gxen.c
   snd-gxutils.c
   snd-help.c
   snd-hobbit.scm
   snd-io.c
   snd-kbd.c
   snd-ladspa.c
   snd-listener.c
   snd-main.c
   snd-marks.c
   snd-menu.c
   snd-menu.h
   snd-mix.c
   snd-motif.scm
   snd-nogui.c
   snd-nogui0.h
   snd-nogui1.h
   snd-prefs.c
   snd-print.c
   snd-rec.c
   snd-rec.h
   snd-region.c
   snd-run.c
   snd-select.c
   snd-sig.c
   snd-snd.c
   snd-strings.h
   snd-trans.c
   snd-utils.c
   snd-x0.h
   snd-x1.h
   snd-xchn.c
   snd-xdraw.c
   snd-xdrop.c
   snd-xen.c
   snd-xenv.c
   snd-xfft.c
   snd-xfile.c
   snd-xfind.c
   snd-xhelp.c
   snd-xlistener.c
   snd-xm.rb
   snd-xmain.c
   snd-xmenu.c
   snd-xmix.c
   snd-xprefs.c
   snd-xprint.c
   snd-xrec.c
   snd-xref.c
   snd-xregion.c
   snd-xsnd.c
   snd-xutils.c
   snd-xxen.c
   snd.1
   Snd.ad
   snd.c
   Snd.gtkrc
   snd.h
   snd.spec
   snd_conffile.scm
   snd_pd_external.c
   snd_pd_external.h
   snd4.scm
   snd5.scm
   snd6.scm
   snd7.scm
   sndctrl.c
   sndinfo.c
   sndlib-strings.h
   sndlib.h.in
   sndlib2xen.c
   sndlib2xen.h
   sndplay.c
   sndrecord.c
   sndwarp.scm
   sound.c
   special-menu.scm
   spectr.rb
   spectr.scm
   strad.rb
   strad.scm
   TODO.Snd
   track-colors.scm
   v.rb
   v.scm
   vct.c
   vct.h
   ws.rb
   ws.scm
   xen.c
   xen.h
   xg-x11.h
   xm-enved.rb
   xm-enved.scm
   zip.rb
   zip.scm

# rubber.rb -- Translation of rubber.scm

# Translator/Author: Michael Scholz <scholz-micha@gmx.de>
# Last: Tue Mar 18 02:35:11 CET 2003
# Version: $Revision: 1.2 $

# module Rubber (see rubber.scm)
#  add_named_mark(samp, name, snd, chn)
#  derumble_sound(*args)
#  sample_sound(*args)
#  unsample_sound(*args)
#  crossings()
#  env_add(s0, s1, samps)
#  rubber_sound(*args)

require "examp"

module Rubber
  doc "#{self.class} #{self.name} is the translation of rubber.scm.\n"
  
  $zeros_checked = 8
  $extension = 10.0
  $show_details = false
  
  def add_named_mark(samp, name, snd = false, chn = false)
    m = add_mark(samp.round, snd, chn)
    set_mark_name(m, name)
    m
  end

  def derumble_sound(*args)
    snd = (args[0] or false)
    chn = (args[1] or false)
    old_length = frames(snd, chn)
    pow2 = (log([old_length, srate(snd)].min) / log(2)).ceil
    fftlen = (2 ** pow2).round
    flt_env = [0.0, 0.0, 32.0 / srate(snd), 0.0, 40.0 / srate(snd), 1.0, 1.0, 1.0]
    filter_sound(flt_env, fftlen, snd, chn)
    set_frames(old_length, snd, chn)
  end

  def sample_sound(*args)
    snd = (args[0] or false)
    chn = (args[1] or false)
    src_sound(1.0 / $extension, 1.0, snd, chn) unless $extension == 1.0
  end

  def unsample_sound(*args)
    snd = (args[0] or false)
    chn = (args[1] or false)
    src_sound($extension, 1.0, snd, chn) unless $extension == 1.0
  end

  def crossings
    crosses = 0
    sr0 = make_sample_reader(0)
    samp0 = next_sample(sr0)
    len = frames()
    sum = 0.0
    last_cross = 0
    silence = $extension * 0.001
    (0...len).each do |i|
      samp1 = next_sample(sr0)
      if samp0 <= 0.0 and samp1 > 0.0 and (i - last_cross) > 4 and sum > silence
        crosses += 1
        last_cross = i
        sum = 0.0
      end
      sum += samp0.abs
      samp0 = samp1
    end
    crosses
  end

  def env_add(s0, s1, samps)
    data = make_vct(samps.round)
    x = 1.0
    xinc = 1.0 / samps
    sr0 = make_sample_reader(s0.round)
    sr1 = make_sample_reader(s1.round)
    (0...samps).each do |i|
      data[i] = x * next_sample(sr0) + (1.0 - x) * next_sample(sr1)
      x += xinc
    end
    data
  end

  def rubber_sound(*args)
    stretch = args[0]
    snd = (args[1] or false)
    chn = (args[2] or false)
    as_one_edit(lambda do | |
                  derumble_sound(snd, chn)
                  sample_sound(snd, chn)
                  crosses = crossings()
                  cross_samples = make_vct(crosses)
                  cross_weights = make_vct(crosses)
                  cross_marks = make_vct(crosses)
                  cross_periods = make_vct(crosses)
                  sr0 = make_sample_reader(0, snd, chn)
                  samp0 = next_sample(sr0)
                  len = frames()
                  sum = 0.0
                  last_cross = 0
                  cross = 0
                  silences = 0
                  silence = $extension * 0.001
                  (0...len).each do |i|
                    samp1 = next_sample(sr0)
                    if samp0 <= 0.0 and samp1 > 0.0 and (i - last_cross) > 4 and sum > silence
                      last_cross = i
                      sum = 0.0
                      cross_samples[cross] = i
                      cross += 1
                    end
                    sum += samp0.abs
                    samp0 = samp1
                  end
                  (0...(crosses - 1)).each do |i|
                    start = cross_samples[i]
                    autolen = 0
                    s0 = start
                    pow2 = (log($extension * (srate() / 40.0)) / log(2)).ceil
                    fftlen = (2 ** pow2).round
                    len4 = fftlen / 4
                    data = make_vct(fftlen)
                    reader = make_sample_reader(s0.round)
                    (0...fftlen).each do |j| data[j] = next_sample(reader) end
                    autocorrelate(data)
                    autolen = 0
                    (1...len4).each do |j|
                      if data[j] < data[j + 1] and data[j + 1] > data[j + 2]
                        autolen = j * 2
                        break
                      end
                    end
                    next_start = start + autolen
                    min_i = i + 1
                    min_samps = (cross_samples[min_i] - next_start).abs
                    ((i + 2)...[crosses, i + $zeros_checked].min).each do |k|
                      dist = (cross_samples[k] - next_start).abs
                      if dist < min_samps
                        min_samps = dist
                        min_i = k
                      end
                    end
                    current_mark = min_i
                    current_min = 0.0
                    s0 = start
                    s1 = cross_samples[current_mark]
                    len = autolen
                    sr0 = make_sample_reader(s0.round)
                    sr1 = make_sample_reader(s1.round)
                    ampsum = 0.0
                    diffsum = 0.0
                    (0...len).each do |dummy|
                      samp0 = next_sample(sr0)
                      samp1 = next_sample(sr1)
                      ampsum += samp0.abs
                      diffsum += (samp1 - samp0).abs
                    end
                    if diffsum == 0.0
                      current_min = 0.0
                    else
                      current_min = diffsum / ampsum
                    end
                    min_samps = 0.5 * current_min
                    top = [crosses - 1, current_mark, i + $zeros_checked].min
                    ((i + 1)...top).each do |k|
                      wgt = 0.0
                      s0 = start
                      s1 = cross_samples[k]
                      len = autolen
                      sr0 = make_sample_reader(s0.round)
                      sr1 = make_sample_reader(s1.round)
                      ampsum = 0.0
                      diffsum = 0.0
                      (0...len).each do |dummy|
                        samp0 = next_sample(sr0)
                        samp1 = next_sample(sr1)
                        ampsum += samp0.abs
                        diffsum += (samp1 - samp0).abs
                      end
                      if diffsum == 0.0
                        wgt = 0.0
                      else
                        wgt = diffsum / ampsum
                      end
                      if wgt < min_samps
                        min_samps = wgt
                        min_i = k
                      end
                    end
                    unless current_mark == min_i
                      cross_weights[i] = 1000.0
                    else
                      cross_weights[i] = current_min
                      cross_marks[i] = current_mark
                      cross_periods[i] = cross_samples[current_mark] - cross_samples[i]
                    end
                  end
                  len = frames(snd, chn)
                  adding = (stretch > 1.0)
                  samps = ((stretch - 1.0).abs *  len).round
                  needed_samps = (adding ? samps : [len, samps * 2].min)
                  handled = 0
                  mult = 1
                  curs = 0
                  weigths = cross_weights.length
                  edits = make_vct(weigths)
                  until curs == weigths or handled >= needed_samps
                    best_mark = -1
                    old_handled = handled
                    cur = 0
                    curmin = cross_weights[0]
                    cross_weights.each_with_index do |cross_w, i|
                      if cross_w < curmin
                        cur = i
                        curmin = cross_w
                      end
                    end
                    best_mark = cur
                    handled += cross_periods[best_mark].round
                    if (handled < needed_samps) or
                       ((handled - needed_samps) < (needed_samps - old_handled))
                      edits[curs] = best_mark
                      curs += 1
                    end
                    cross_weights[best_mark] = 1000.0
                  end
                  mult = (needed_samps / handled).ceil if curs >= weigths
                  changed_len = 0
                  weights = cross_weights.length
                  (0...curs).each do |i|
                    break if changed_len > samps
                    best_mark = edits[i].round
                    beg = cross_samples[best_mark]
                    next_beg = cross_samples[cross_marks[best_mark].round]
                    len = cross_periods[best_mark]
                    if len > 0
                      if adding
                        new_samps = env_add(beg, next_beg, len)
                        if $show_details
                          add_named_mark(beg, format("%d:%d", i, (len / $extension).round))
                        end
                        insert_samples(beg, len, new_samps)
                        if mult > 1
                          (1...mult).each do |k| insert_samples(beg + k * len, len, new_samps) end
                        end
                        changed_len += mult * len
                        (0...weights).each do |j|
                          curbeg = cross_samples[j]
                          if curbeg > beg
                            cross_samples[j] = curbeg + len
                          end
                        end
                      else
                        message("trouble at %d: %d of %d", i, beg, frames()) if beg >= frames()
                        if $show_details
                          add_named_mark(beg - 1, format("%d:%d", i, (len / $extension).round))
                        end
                        delete_samples(beg, len)
                        changed_len += len
                        fin = beg + len
                        (0...weights).each do |j|
                          curbeg = cross_samples[j]
                          if curbeg > beg
                            if curbeg < fin
                              cross_periods[j] = 0
                            else
                              cross_samples[j] = curbeg - len
                            end
                          end
                        end
                      end
                    end
                  end
                  message("wanted: %d, got %d", samps.round, changed_len.round) if $show_details
                  unsample_sound(snd, chn)
                  if $show_details
                    message("%f -> %f (%f)",
                            frames(snd, chn, 0), frames(snd,chn),
                            (stretch * frames(snd, chn, 0)).round)
                  end
                end, "(rubber_sound(#{args.join(', ')})")
  end
end

# rubber.rb ends here

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us