Minim core
ugens
analysis
Name BitCrush
Description BitCrush is an effect that reduces the fidelity of the incoming signal. This results in a sound that is "crunchier" sounding, or "distorted".

Audio is represented digitally (ultimately) as an integral value. If you have 16-bit audio, then you can represent a sample value with any number in the range -32,768 to +32,767. If you bit-crush this audio to be 8-bit, then you effectively reduce it representation to -128 to +127, even though you will still represent it with a 16-bit number. This reduction in the fidelity of the representation essentially squares off the waveform, which makes it sound "crunchy". Try bit crushing down to 1-bit and see what you get!

Examples
/* bitCrushExample<br/>
 * This is an example of using a BitCrush UGen to modify the sound of an Oscil.
 * <p>
 * For more information about Minim and additional features, 
 * visit http://code.compartmental.net/minim/
 */

import ddf.minim.*;
import ddf.minim.ugens.*;

Minim minim;
AudioOutput out;

// this CrushInstrument will play a sine wave bit crushed
// to a certain bit resolution. this results in the audio sounding
// "crunchier".
class CrushInstrument implements Instrument
{
  Oscil sineOsc;
  BitCrush bitCrush;
  
  CrushInstrument(float frequency, float amplitude, float bitRes)
  {
    sineOsc = new Oscil(frequency, amplitude, Waves.SINE);
    
    // BitCrush takes the bit resolution for an argument
    bitCrush = new BitCrush(bitRes, out.sampleRate());
    
    sineOsc.patch(bitCrush);
  }
  
  // every instrument must have a noteOn( float ) method
  void noteOn(float dur)
  {
    bitCrush.patch(out);
  }
  
  // every instrument must have a noteOff() method
  void noteOff()
  {
    bitCrush.unpatch(out);
  }
}

// this CrushingInstrument will play a sine wave and then change the bit resulution of the BitCrush
// over time, based on a starting and ending resolution passed in.
class CrushingInstrument implements Instrument
{
  Oscil sineOsc;
  BitCrush bitCrush;
  Line crushLine;
  
  CrushingInstrument(float frequency, float amplitude, float hiBitRes, float loBitRes)
  {
    sineOsc = new Oscil(frequency, amplitude, Waves.SINE);
    bitCrush = new BitCrush(hiBitRes, out.sampleRate());
    crushLine = new Line(9.0, hiBitRes, loBitRes);
    
    // our Line will control the resolution of the bit crush
    crushLine.patch(bitCrush.bitRes);
    // patch the osc through the bit crush
    sineOsc.patch(bitCrush);
  }
  
  // called by the note manager when this instrument should play
  void noteOn(float dur)
  {
    // patch the bit crush to the output and active our Line when we want to have the note play
    crushLine.activate();
    bitCrush.patch(out);
  }
  
  // called by the note manager when this instrument should stop playing
  void noteOff()
  {
    // unpatch from the output to stop making sound
    bitCrush.unpatch(out);
  }
}

void setup()
{
  // initialize the drawing window
  size( 512, 200, P2D );

  // initialize the minim and out objects
  minim = new Minim( this );
  out = minim.getLineOut( Minim.MONO );
  
  // queue up some notes using the Crush Instrument
  // its arguments are sine wave frequency, amplitude, and bit crush resolution
  out.playNote(0.5, 2.6, new CrushInstrument( 392.0, 0.5, 16.0) );
  out.playNote(3.5, 2.6, new CrushInstrument( 370.0, 0.5, 4.0) );
  out.playNote(6.5, 2.6, new CrushInstrument( 261.6, 0.5, 3.0) );
  out.playNote(9.5, 2.6, new CrushInstrument( 247.0, 0.5, 2.0) );
  
  // queue up a Crushing Instrument, which will change the bit resolution over time
  // its arguments are sine frequency, amplitude, bit crush resolution start and end
  out.playNote(12.5, 10.0, new CrushingInstrument( 191.0, 0.5, 5.2, 1.0 ) );
}

// draw is run many times
void draw()
{
  // erase the window to black
  background( 0 );
  // draw using a white stroke
  stroke( 255 );
  // draw the waveforms
  for( int i = 0; i < out.bufferSize() - 1; i++ )
  {
    // find the x position of each buffer value
    float x1  =  map( i, 0, out.bufferSize(), 0, width );
    float x2  =  map( i+1, 0, out.bufferSize(), 0, width );
    // draw a line from one buffer position to the next for both channels
    line( x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
    line( x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
  }  
}
Constructors
BitCrush();
BitCrush(localBitRes, localBitRate);
Parameters
localBitRes   float: typically you'll want this in the range [1,16]
localBitRate   float: this must be in the range [1,outputSampleRate]
Fields
audio   The audio input is where audio that gets bit-crushed should be patched. However, you don't need to patch directly to this input, patching to the UGen itself will accomplish the same thing.

bitRate   Control the bit rate with another UGen by patching to bitRate. Values that make sense for this start at 1 and go up to whatever the sample rate of your AudioOutput are (typically 44100)

bitRes   Control the bit resolution with another UGen by patching to bitRes. Values that make sense for this start at 1 and go up to whatever the actual resolution of the incoming audio is (typically 16).

Methods
channelCount ( )   Returns the number of channels this UGen has been configured to generate.

getLastValues ( )   Return the last values generated by this UGen. This will most often be used by sub-classes when pulling data from their inputs.

patch ( )   Send the output of this UGen to another UGen, UGenInput, or AudioOutput.

printInputs ( )   Prints all inputs connected to this UGen (for debugging)

sampleRate ( )   Returns the sample rate of this UGen.

setBitRes ( )   Set the bit resolution directly.

setChannelCount ( )   Let this UGen know how many channels of audio you will be asking it for.

setSampleRate ( )   Set the sample rate for this UGen.

tick ( )   Generates one sample frame for this UGen.

unpatch ( )   Unpatch this UGen from an AudioOutput or other UGen.

Usage Web & Application
Related UGen