Advertisement
Guest User

Video mixer idea

a guest
Feb 1st, 2015
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.31 KB | None | 0 0
  1. // =========================================================================
  2. // VIDEO MIXER IDEA
  3. // processing doodle by /u/frumperino
  4. // 2014-01-31
  5. // =========================================================================
  6. // Disclaimer:
  7. // This software is hostile to all forms of life and civilization
  8. // * It does not do what it says on the tin.
  9. // * You almost certainly shouldn't use it for your project.
  10. // * It is released as-is to public domain without any form of warranty.
  11. // =========================================================================
  12.  
  13. int sw = 640;
  14. int sh = 480;
  15. Mixer mainMixer;
  16. float videoHz = 30;
  17.  
  18. void setup()
  19. {
  20.    //sw = displayWidth;
  21.    //sh = displayHeight;
  22.    size(sw,sh,P3D);
  23.    frameRate(videoHz);
  24.    frame.setResizable(true);
  25.    mainMixer = new Mixer();
  26.    mainMixer.setChannel(2,new PT_pattern1());
  27.    mainMixer.setChannel(3,new PT_pattern2());
  28.  
  29.    mainMixer.setBlender(1,new BL_circleWipe()); // add circle wipe to mixer blender slot 1
  30.    
  31.    mainMixer.setFader(new SG_osc(0.25));  // replace mixer handle with 0.25 Hz oscillator
  32.    mainMixer.selectChannel(2);
  33.    mainMixer.selectChannel(3);
  34.    mainMixer.selectBlender(1);
  35.    mainMixer.initialize(g);
  36. }
  37.  
  38. boolean sketchFullScreen()
  39. {
  40.   return false;
  41. }
  42.  
  43. void keyPressed()
  44. {
  45.   mainMixer.nextBlender();
  46. }
  47.  
  48. void draw()
  49. {
  50.   mainMixer.iterate();
  51.   mainMixer.draw(g,0);
  52. }
  53.  
  54. // ====================================================
  55. // INTERFACES
  56. // ====================================================
  57.  
  58. // contract for plug-in Painter classes
  59. interface Painter
  60. {
  61.   // must have an initialize function which will be called when a pattern is first invoked or screen resolution changes.
  62.   void initialize(PGraphics gr);          
  63.  
  64.   // must have a draw function which paints to a provided PGraphics object.
  65.   // the phase argument (0..1) is only used when painter is used as alpha mask provider
  66.   // in a crossfade function.
  67.   void draw(PGraphics gr, float phase);
  68.  
  69.   void iterate(); // animate / recompute the pattern
  70. }
  71.  
  72. // contract for plug-in Signal Provider classes
  73. // used for things like fader handles (but can be oscillators, glitchers, etc)
  74. interface SignalProvider
  75. {
  76.   float get();   // a signal value between 0 and 1 (don't iterate underlying function)
  77.   float iterate();  // animate / recompute the signal function (and return it)
  78. }
  79.  
  80. abstract class Blender implements Painter
  81. {
  82.   public void initialize(PGraphics gr) {}
  83.   public void iterate() {}
  84. }
  85.  
  86. abstract class Pattern implements Painter
  87. {
  88.   public void initialize(PGraphics gr) {}
  89.   public void iterate() {}
  90. }
  91.  
  92. // ====================================================
  93. // MIXER
  94. // ====================================================
  95.  
  96. // the mixer itself is a Painter (allows for nesting!)
  97. class Mixer implements Painter
  98. {
  99.   HashMap<Integer,Painter> channels;
  100.   HashMap<Integer,Painter> blenders;
  101.   int sw, sh;
  102.   PGraphics pg1;
  103.   PGraphics pg2;
  104.   PGraphics pgB;
  105.   int selectedBlenderIndex = 0;
  106.   int selectedChannelIndex = 0;
  107.   int previousChannelIndex = 0;
  108.   SignalProvider fader;
  109.    
  110.   public void initialize(PGraphics gr)
  111.   {
  112.     pg1 = createGraphics(gr.width,gr.height,P3D);
  113.     pg2 = createGraphics(gr.width,gr.height,P3D);
  114.     pgB = createGraphics(gr.width,gr.height,P3D);
  115.     sw = gr.width;
  116.     sh = gr.height;
  117.     Painter cp = selectedChannel();
  118.     if (cp != null) cp.initialize(gr);
  119.  
  120.     cp = previousChannel();
  121.     if (cp != null) cp.initialize(gr);
  122.  
  123.     cp = selectedBlender();
  124.     if (cp != null) cp.initialize(gr);
  125.   }
  126.  
  127.   public Mixer()
  128.   {
  129.     channels = new HashMap<Integer,Painter>();
  130.     blenders = new HashMap<Integer,Painter>();
  131.     setChannel(0, new PT_solid(0xFF000000));
  132.     setChannel(1, new PT_colorBars());
  133.     setBlender(0, new BL_flat());
  134.     selectBlender(0);
  135.     selectChannel(0);
  136.     fadeTo(1,1000);
  137.   }
  138.  
  139.   public Painter getChannel(int channelIndex)
  140.   {
  141.     if (channels.size() > 0)
  142.     {
  143.       if (channels.containsKey(channelIndex))
  144.       {
  145.         return channels.get(channelIndex);
  146.       }
  147.     }
  148.     return null;
  149.   }
  150.  
  151.   public Painter getBlender(int blenderIndex)
  152.   {
  153.     if (blenders.size() > 0)
  154.     {
  155.       if (blenders.containsKey(blenderIndex))
  156.       {
  157.         return blenders.get(blenderIndex);
  158.       }
  159.     }
  160.     return null;
  161.   }
  162.  
  163.   public Painter selectedChannel()
  164.   {
  165.     return getChannel(selectedChannelIndex);
  166.   }
  167.  
  168.   public Painter previousChannel()
  169.   {
  170.     return getChannel(previousChannelIndex);
  171.   }
  172.  
  173.   public Painter selectedBlender()
  174.   {
  175.     return getBlender(selectedBlenderIndex);
  176.   }
  177.  
  178.   public int numChannels()
  179.   {
  180.     return channels.size();
  181.   }
  182.  
  183.   public int numBlenders()
  184.   {
  185.     return blenders.size();
  186.   }
  187.  
  188.   public void selectChannel(int channelIndex)
  189.   {
  190.     previousChannelIndex = selectedChannelIndex;
  191.     selectedChannelIndex = channelIndex % channels.size();
  192.   }
  193.  
  194.   public void selectBlender(int blenderIndex)
  195.   {
  196.     this.selectedBlenderIndex = blenderIndex % blenders.size();
  197.   }
  198.  
  199.   public void nextBlender()
  200.   {
  201.     this.selectedBlenderIndex++;
  202.     this.selectedBlenderIndex %= blenders.size();
  203.   }
  204.  
  205.   public void fadeTo(int channelIndex, int transitionMS)
  206.   {
  207.     selectChannel(channelIndex);
  208.     SG_linearFader f = new SG_linearFader(0);
  209.     setFader(f);
  210.     f.fadeTo(1,transitionMS);
  211.   }
  212.  
  213.   public void snapTo(int channelIndex)
  214.   {
  215.     fadeTo(channelIndex,0);
  216.   }
  217.  
  218.   public void setChannel(int channelIndex, Painter channel)
  219.   {
  220.     this.channels.put(channelIndex,channel);
  221.   }
  222.  
  223.   public void setFader(SignalProvider fader)
  224.   {
  225.     this.fader = fader;
  226.   }
  227.  
  228.   public void setBlender(int blenderIndex, Painter blender)
  229.   {
  230.     this.blenders.put(blenderIndex, blender);
  231.    
  232.   }
  233.  
  234.   void draw(PGraphics gr, float phase)
  235.   {
  236.     gr.beginDraw();
  237.      float f = fader.get();
  238.      if (f < 0.9999)
  239.      {
  240.        selectedBlender().draw(pgB,f);
  241.        previousChannel().draw(pg1,0);
  242.        selectedChannel().draw(pg2,0);
  243.        
  244.        PImage img = pg2.get();
  245.        img.mask(pgB.get());
  246.  
  247.        gr.image(pg1,0,0);
  248.        gr.image(img,0,0);
  249.      }
  250.      else
  251.      {
  252.        // draw selected channel to main
  253.        selectedChannel().draw(gr,0);    
  254.      }
  255.      gr.endDraw();
  256.   }
  257.  
  258.   public void iterate()
  259.   {
  260.      fader.iterate();
  261.      selectedBlender().iterate();
  262.      selectedChannel().iterate();
  263.      if(fader.get() < 0.9999)
  264.      {
  265.        previousChannel().iterate();
  266.      }
  267.   }
  268.  
  269.  
  270. }
  271.  
  272. // ====================================================
  273. // SIGNAL PROVIDERS
  274. // Used to control a mixer or anything else
  275. // ====================================================
  276.  
  277. class SG_constant implements SignalProvider
  278. {
  279.   float value = 0;
  280.  
  281.   public SG_constant(float value)
  282.   {
  283.      this.value = value < 0 ? 0 : value > 1 ? 1 : value;
  284.   }
  285.  
  286.   public float iterate()
  287.   {
  288.     return get();
  289.   }
  290.  
  291.   public float get()
  292.   {
  293.     return this.value;
  294.   }
  295. }
  296.  
  297. class SG_linearFader implements SignalProvider
  298. {
  299.     float actualPos = 0;
  300.     float deltaPos = 0;
  301.     float defaultPos = 0;
  302.     float startPos = 0;
  303.     int totalSteps = 0;
  304.     int stepCount = 0;
  305.     public SG_linearFader(float initialPos)
  306.     {
  307.       this.actualPos = initialPos;
  308.       this.defaultPos = initialPos;
  309.     }
  310.    
  311.     public void setHandle(float pos)
  312.     {
  313.       this.actualPos = pos < 0 ? 0 : pos > 1 ? 1 : pos;
  314.     }
  315.    
  316.     // fade handle to specific position
  317.     // transition time in milliseconds
  318.     public void fadeTo(float targetPos, int transitionMS)
  319.     {
  320.        this.startPos = this.actualPos;
  321.        this.totalSteps = round( transitionMS * videoHz / 1000 );
  322.        this.deltaPos = targetPos - actualPos;
  323.        this.stepCount = 0;
  324.        if (transitionMS == 0)
  325.        {
  326.          this.actualPos = 1;
  327.        }
  328.     }
  329.    
  330.     public void reset()
  331.     {
  332.       this.actualPos = this.defaultPos;
  333.     }
  334.    
  335.     public float get()
  336.     {
  337.       return actualPos;
  338.     }  
  339.    
  340.     public float iterate()
  341.     {
  342.       if (stepCount < totalSteps)
  343.       {
  344.         stepCount++;
  345.         actualPos = startPos + deltaPos * ((float) stepCount / totalSteps);
  346.       }
  347.       return actualPos;
  348.     }
  349. }
  350.  
  351. class SG_osc implements SignalProvider
  352. {
  353.   float value = 0;
  354.   int cycle = 1000;
  355.   int counter = 0;
  356.   float multiplier = 0;
  357.  
  358.   public SG_osc(float cycleHz)
  359.   {
  360.     value = 0;
  361.     counter = 0;
  362.     cycle = 1000;
  363.     multiplier = 0;
  364.     setFrequency(cycleHz);
  365.   }
  366.  
  367.   public void setFrequency(float hz)
  368.   {
  369.     if (hz > 0)
  370.     {
  371.       cycle = round ( videoHz / hz );
  372.       multiplier = 2 * PI;
  373.     }
  374.     else
  375.     {
  376.       cycle = 0;
  377.       multiplier = 0;
  378.     }
  379.   }
  380.  
  381.   public float get()
  382.   {
  383.     return value;
  384.   }
  385.  
  386.   public float iterate()
  387.   {
  388.     counter++;
  389.     counter %= cycle;
  390.     float phase = (float) counter / (cycle-1);
  391.     value = 0.5 + 0.5 * cos (phase * multiplier);
  392.     return value;
  393.   }
  394. }
  395.  
  396. // ====================================================
  397. // BLENDER CLASSES
  398. // These provide greyscale alpha mask images used in pattern transitions
  399. // ====================================================
  400.  
  401. // flat greyscale basic crossfader
  402. class BL_flat extends Blender
  403. {
  404.    public void draw(PGraphics gr, float phase)
  405.    {
  406.      gr.beginDraw();
  407.       int y = round (phase * 255);
  408.       gr.background( y < 0 ? 0 : y > 255 ? 255 : y);
  409.       gr.endDraw();
  410.    }
  411. }
  412.  
  413. // circle wipe with sharp edges(from middle of screen outwards)
  414. class BL_circleWipe extends Blender
  415. {
  416.    float diag;
  417.    float cx,cy;
  418.    
  419.    @Override
  420.    public void initialize(PGraphics gr)
  421.    {
  422.      // find screen diagonal
  423.       diag = sqrt(gr.width * gr.width + gr.height * gr.height);
  424.       cx = 0.5 * gr.width;
  425.       cy = 0.5 * gr.height;
  426.    }
  427.    
  428.    public void draw(PGraphics gr, float phase)
  429.    {
  430.      gr.beginDraw();
  431.      gr.background(0);
  432.      gr.fill(0xFF);
  433.      gr.noStroke();
  434.      gr.ellipseMode(CENTER);
  435.      gr.ellipse(cx,cy,diag*phase,diag*phase);
  436.      gr.endDraw();
  437.    }
  438. }
  439.  
  440. // ====================================================
  441. // PATTERN CHANNEL CLASSES
  442. // Actual image generators
  443. // ====================================================
  444.  
  445.  // baseline color bars painter class used as test picture (channel 0)
  446.  
  447. class PT_colorBars extends Pattern
  448. {
  449.   int ofs = 0;
  450.   int div = 1000;
  451.   int wrap = 1000;
  452.  
  453.   @Override
  454.   public void initialize(PGraphics gr)
  455.   {
  456.     ofs = 0;
  457.     wrap = gr.width;
  458.     div = wrap / 8;
  459.   }
  460.  
  461.   void draw(PGraphics gr, float phase)
  462.   {
  463.     gr.beginDraw();
  464.     for (int x=0;x<wrap;x++)
  465.     {
  466.       int dx = (x+ofs) % wrap;
  467.       int n = dx / div;
  468.       int cb = 255 * ( n & 0x01 );
  469.       int cr = 255 * ( (n >> 1) & 0x01 );
  470.       int cg = 255 * ( (n >> 2) & 0x01 );
  471.       int c = 0xFF000000 | cb | (cg << 8) | (cr << 16);
  472.       gr.stroke(c);
  473.       gr.line(x,0,x,gr.height);
  474.     }
  475.     gr.endDraw();
  476.   }
  477.  
  478.   @Override
  479.   public void iterate()
  480.   {
  481.     ofs++;
  482.     ofs %= wrap;
  483.   }
  484. }
  485.  
  486. // solid pattern used as default channel 1 (black)
  487.  
  488. class PT_solid extends Pattern
  489. {
  490.   color c;
  491.  
  492.   public PT_solid(color col)
  493.   {
  494.     this.c = col;
  495.   }
  496.  
  497.   void draw(PGraphics gr, float phase)
  498.   {
  499.     gr.beginDraw();
  500.     gr.background(c);
  501.     gr.endDraw();
  502.   }
  503. }
  504.  
  505. // user patterns
  506. // --------------------------------------------------
  507.  
  508. class PT_pattern1 implements Painter
  509. {
  510.    public void initialize(PGraphics gr)
  511.    {
  512.    }
  513.  
  514.    public void draw(PGraphics gr, float phase)
  515.    {
  516.      gr.beginDraw();
  517.      gr.background(0xFFCC0000);
  518.      gr.fill(0x88FF9900);
  519.      for (int i=0;i<50;i++)
  520.      {
  521.        gr.rect(random(gr.width), random(gr.height), random(100), random(100));
  522.      }
  523.      gr.endDraw();
  524.    }
  525.    
  526.    public void iterate() {}
  527. }
  528.  
  529. class PT_pattern2 implements Painter
  530. {
  531.  
  532.   /**
  533.  * Bouncy Bubbles  
  534.  * based on code from Keith Peters.
  535.  *
  536.  * Multiple-object collision.
  537.  */
  538.  
  539.   int numBalls = 12;
  540.   float spring = 0.05;
  541.   float gravity = 0.03;
  542.   float friction = -0.9;
  543.   Ball[] balls = new Ball[numBalls];
  544.  
  545.  
  546.   class Ball
  547.   {
  548.    
  549.     float x, y;
  550.     float diameter;
  551.     float vx = 0;
  552.     float vy = 0;
  553.     int id;
  554.     Ball[] others;
  555.    
  556.     Ball(float xin, float yin, float din, int idin, Ball[] oin)
  557.     {
  558.       x = xin;
  559.       y = yin;
  560.       diameter = din;
  561.       id = idin;
  562.       others = oin;
  563.     }
  564.    
  565.     void collide()
  566.     {
  567.       for (int i = id + 1; i < numBalls; i++) {
  568.         float dx = others[i].x - x;
  569.         float dy = others[i].y - y;
  570.         float distance = sqrt(dx*dx + dy*dy);
  571.         float minDist = others[i].diameter/2 + diameter/2;
  572.         if (distance < minDist) {
  573.           float angle = atan2(dy, dx);
  574.           float targetX = x + cos(angle) * minDist;
  575.           float targetY = y + sin(angle) * minDist;
  576.           float ax = (targetX - others[i].x) * spring;
  577.           float ay = (targetY - others[i].y) * spring;
  578.           vx -= ax;
  579.           vy -= ay;
  580.           others[i].vx += ax;
  581.           others[i].vy += ay;
  582.         }
  583.       }  
  584.     }
  585.    
  586.     void move()
  587.     {
  588.       vy += gravity;
  589.       x += vx;
  590.       y += vy;
  591.       if (x + diameter/2 > width) {
  592.         x = width - diameter/2;
  593.         vx *= friction;
  594.       }
  595.       else if (x - diameter/2 < 0) {
  596.         x = diameter/2;
  597.         vx *= friction;
  598.       }
  599.       if (y + diameter/2 > height) {
  600.         y = height - diameter/2;
  601.         vy *= friction;
  602.       }
  603.       else if (y - diameter/2 < 0) {
  604.         y = diameter/2;
  605.         vy *= friction;
  606.       }
  607.     }
  608.    
  609.     void display(PGraphics gr)
  610.     {
  611.       gr.ellipse(x, y, diameter, diameter);
  612.     }
  613.   }
  614.    
  615.    void initialize(PGraphics gr)
  616.    {
  617.        for (int i = 0; i < numBalls; i++)
  618.        {
  619.          balls[i] = new Ball(random(gr.width), random(gr.height), random(30, 70), i, balls);
  620.        }
  621.    }
  622.  
  623.    void draw(PGraphics gr, float phase)
  624.    {
  625.      gr.beginDraw();
  626.      gr.background(0xFF000099);
  627.      gr.noStroke();
  628.      gr.fill(0x9999CCFF);
  629.      for (int i = 0; i < numBalls; i++)
  630.      {
  631.       balls[i].collide();
  632.       balls[i].move();
  633.       balls[i].display(gr);  
  634.      }
  635.      gr.endDraw();
  636.    }
  637.    
  638.     void iterate() {}
  639.  
  640. }
  641.  
  642. /*
  643. // template - fill in the blanks
  644. class PT_patternX implements Painter
  645. {
  646.    public void initialize(PGraphics g)
  647.    {
  648.    }
  649.  
  650.    public void draw(PGraphics g, float phase)
  651.    {
  652.    }
  653.  
  654.    public void iterate()
  655.    {
  656.    }
  657.  
  658. }
  659. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement