• fullscreen
  • EverySong.pde
  • SongIterator.pde
  • import ddf.minim.*;
    
    AudioOutput out;
    SongIterator songIterator;
    
    float[] chromatic = new float[]{
      440, 466.16, 493.88, 523.25, 554.37, 587.33, 622.25, 659.26, 698.46, 739.99, 783.99, 830.61};
    
    float[] fifth = new float[] {
      440, 659.26};
      
    float[] maj3 = new float[] {
      440, 554.37, 659.26};
      
    float[] majm7 = new float[] {
      440, 554.37, 659.26, 783.99};
      
    float[] mm7 = new float[] {
      440, 523.25, 659.26, 783.99};
    
    float[] notes;
    
    float[][] scales = {chromatic, fifth, maj3, majm7, mm7};
    
    PFont font;
    
    int border = 5;
    
    void setup() {
      size(640, 360, P2D);
      frameRate(30);
      
      notes = chromatic;
      
      font = loadFont("04b24-32.vlw");
      textFont(font, 32);
      textAlign(RIGHT, BOTTOM);
      textMode(SCREEN);
    }
    
    boolean audio = false;
    void draw() {
      background(255);
      if(!audio) {
        startAudio();
      } else {
        float ws = width / (float) (1 + ((songIterator.current.bitLength() - 1) / notes.length));
        float hs = height / (float) notes.length;
      
        fill(0);
        for(int i = 0; i < songIterator.current.bitLength(); i++)
          if(songIterator.current.testBit(i))
            rect((i / notes.length) * ws, (i % notes.length) * hs, ws, hs);
      
        fill(255, 0, 0);
        text(songIterator.current.toString(), width - border, height - border); 
      }
    }
    
    Minim minim;
    void startAudio() {
      minim = new Minim(this);
      out = minim.getLineOut(minim.MONO, 1024);
      songIterator = new SongIterator(44100, notes, 32);
      out.addSignal(songIterator);
      audio = true;
    }
    
    void stop() {
      out.close();
      super.stop();
    }
    
    import java.math.*;
    
    class SongIterator implements AudioSignal {
      long time;
      BigInteger current;
      int sampleRate, sampleLength, samplePosition,
        noteLength, notePosition,
        fadeLength;
      float[] notes;
      float[] fade;
      SongIterator(int sampleRate, float[] notes, int fadeLength) {
        this.sampleRate = sampleRate;
        this.fadeLength = fadeLength;
        reset(notes);
      }
      void reset(float[] notes) {
        this.notes = notes;  
        sampleLength = (int) Math.ceil(sampleRate / notes[0]);
        time = 0;
        samplePosition = 0;
        notePosition = 0;
        current = new BigInteger("1");
        fade = new float[fadeLength];
        
        float normalize =  TWO_PI / sampleRate;
        for(int i = 0; i < notes.length; i++)
          this.notes[i] *= normalize;
      }
      void random(int bits) {
        current = new BigInteger(bits, new Random());
      }
      void generate(float[] samp) {
        boolean resync = false;   
        for(int i = 0; i < samp.length; i++) {   
          int total = current.bitLength();
          noteLength = (int) Math.ceil((float) total / notes.length);
         
          if(samplePosition < fadeLength) {
            float fadeValue = (float) samplePosition / fadeLength;
            samp[i] = (getSample(time) * fadeValue) + ((1 - fadeValue) * fade[samplePosition]);
          } else {
            samp[i] = getSample(time);
          }
          time++;
        
          samplePosition++;
          if(samplePosition % sampleLength == 0) {
            for(int j = 0; j < fadeLength; j++)
              fade[j] = getSample(time + j);
            
            samplePosition = 0;
            notePosition++;
            if(notePosition % noteLength == 0) {
              notePosition = 0;
              current = current.add(BigInteger.ONE);
            }
          }
        }
      }
      float getSample(long time) {
        float sample = 0;
        float on = 0;
        for(int i = notes.length * notePosition; i < notes.length * (notePosition + 1); i++) {
          int ai = i % notes.length;
          if(current.testBit(i)) {
            sample += sin(notes[ai] * time);
            on++;
          }
        }            
        return sample / on;
      }
      void generate(float[] left, float[] right) {
        generate(left);
        generate(right);
      }
    }
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Kyle McDonald

    Every Song

    Add to Faves Me Likey@! 4
    You must login/register to add this sketch to your favorites.

    Plays every song as quickly as possible, using the 12 chromatic notes.

    Mariano Crivelli
    10 Mar 2009
    Wow great! I'd love to be able to make such great things :P
    Greetins from Argentina :D
    Myer Nore
    12 Mar 2009
    Totally Amazing. Permutations or Combinations? What are the details in a nutshell?
    Kyle McDonald
    14 Mar 2009
    Mariano: Thanks for New York :)

    Myer: In a nutshell, start with 0 in binary and count up. The first 12 digits describe which notes the first chord contains. The next 12 digits describe which notes the next chord contains, etc.
    Brendan Flynn
    3 May 2012
    thats manic :)
    You need to login/register to comment.