Sound, Motion, Notation

Information and Art

Computers suggest something about information primacy. Through the simplest binary building blocks, they are able to accurately model complex systems, compress time and distance, and even make us question the nature of intelligence itself. Information may be more than processed data, it may be essence of thought and reality.

Artists are investigating the post-digital world in a myriad of ways. Some of the most powerful disregard the concept of "computer" and focus on a digital aesthetic that underlines the essence of the machine. Channa Horwitz's Sonakinatography series (1968-2012) is an exemplar. In spite of the fact that she had no formal training in mathematics or computer science, her work intuitively embodies both.

Enciphering Information

The key to my work is simplicity and complexity. I have been working with the premise that any complexity can be understood in it's simplest form. In my notations I am interested in breaking through the barrier of the different arts, because they all have a common language. In these notations I am searching for some connecting link to establish a clearer reality.1^1

~ Channa Horwitz (1974)

Work in the Sonakinatography series is generally created on a grid that is eight spaces wide. These grids can be of any length; Sonakinatography I, Composition III (pictured above) is one hundred sixty-eight rows long. Each enumerated space is filled with a square or a line:

Although Horwitz was not referencing the computer directly, this pattern can be interpreted as a set of instructions. Computers represent any given moment in time as a set of states that are either on or off, often thought of as 1 or 0. These simple building blocks are flexible enough to model the behavior of the subatomic universe in one moment and simulate acts of human creativity in another.

Code

Horowitz did not write the algorithm that generated Sonakinatography I, Composition III as a pattern of 1s and 0s. She followed a simple rule set conveyed to the viewer as a combination of graphs and natural language in the corner of the illustration.

The final image is the result of looping through this algorithm one hundred sixty-eight times. I'll reinterpret these instructions in Python and walk through the process she used, starting with the most basic elements of Sonakinatography, the square and the line.

import svgwrite
class Shape:
  yellow_green=svgwrite.rgb(0, 204, 0)   # Yellow Green
  green=svgwrite.rgb(0, 102, 0)          # Green
  blue=svgwrite.rgb(0, 0, 255)           # Blue
  blue_violet=svgwrite.rgb(127, 0, 255)  # Blue Violet
  red_violet=svgwrite.rgb(153, 0, 153)   # Red Violet
  red=svgwrite.rgb(204, 0, 0)            # Red
  orange=svgwrite.rgb(255, 128, 0)       # Orange
  yellow=svgwrite.rgb(255, 255, 0)       # Yellow
  color_grid = [yellow_green, green, blue, blue_violet, red_violet, red, orange, yellow]
  square_size = 20
  def scale_square(self, x, y):
    x -= 1 # Start the x-axis scaling at 0, not 1
    return ((x*self.square_size), (y*self.square_size))
  def __init__(self, instrument, beat = 1, max_beat = 1):
    self.color = (instrument['color'] - 1)
    self.x, self.y = self.scale_square(instrument['instrument'], beat)
    self.y = abs(self.y - (max_beat * self.square_size))
  def paint_square(self, canvas):
    canvas.add(canvas.rect((self.x, self.y), (self.square_size, self.square_size), fill=self.color_grid[self.color]))
  def paint_line(self, canvas):
    self.x = self.x + (self.square_size / 2) - 2
    canvas.add(canvas.rect((self.x, self.y), (3, self.square_size), fill=self.color_grid[self.color]))
def simple_shapes(shape1, shape2):
  dwg_shapes = svgwrite.Drawing('/results/dwg_shapes.svg', (160,20))
  Shape(shape1).paint_square(dwg_shapes)
  Shape(shape2).paint_line(dwg_shapes)
  return dwg_shapes
draw = simple_shapes({'color': 3, 'instrument': 2}, {'color': 4, 'instrument': 3})
draw.save()
0.3s
blue-nightPython

Each column, aka instrument in Horwitz's nomenclature, can convey eight unique states, represented by a color.

1. Yellow-Green
2. Green
3. Blue
4. Blue-Violet
5. Red-Violet
6. Red
7. Orange
8. Yellow

This series of instructions will generate the first row of Sonakinatography I, Composition III:

canvas = svgwrite.Drawing('/results/canvas.svg', (160,20))
Shape({'color': 1, 'instrument': 1}).paint_square(canvas)
Shape({'color': 2, 'instrument': 2}).paint_line(canvas)
Shape({'color': 3, 'instrument': 3}).paint_line(canvas)
Shape({'color': 4, 'instrument': 4}).paint_line(canvas)
Shape({'color': 5, 'instrument': 5}).paint_line(canvas)
Shape({'color': 6, 'instrument': 6}).paint_line(canvas)
Shape({'color': 7, 'instrument': 7}).paint_line(canvas)
Shape({'color': 8, 'instrument': 8}).paint_line(canvas)
canvas.save()
0.2s
throbbing-silencePython

Remix this article, change the numbers above, and rerun the code cell to generate your own unique results.

Quantitative Art

There are282^8or256256unique states for each row in Sonakinatography I, Composition III. This is a quantitative characteristic where all possibilities are knowable. Horwitz created complete pieces with this quality, such as And Then There Were None (1978). This flip book features an 8x8 grid on every page. On the first page, every bottom square is filled in. The squares move vertically one column at a time, page by page, until all have animated off the top edge of the book.

John F. Simon, Jr.'s Every Icon (1997-present) demonstrates the expansive possibilities of Horwitz's ideas when translated from a book to a computer. The version included in this article has been running since January 14, 1997, 9:00:00 pm. Every Icon will make every black and white computer icon possible on a 32x32 grid within the next several trillion years, if run continuously.2^2

<div id="header" style="background-color:#FFFFFF;text-align:center">
	<h1 style="margin-bottom:10px;">Every Icon</h1>
</div>
<div id="iconCanvas" style="background-color:#FFFFFF;height:500px;width:500px;float:left;">
	<p id="EveryIcon">
    <canvas id="myCanvas" width="500" height="450"></canvas>
  </p>
</div>
<script>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var	Icon_Size = 32;
  var Icon_wid = 12;
  var Icon_hgt = 12;
  var	canvas_x_offset = 50;
  var canvas_y_offset = 0;
  var Icon_State = new Array(Icon_Size*Icon_Size);
  var id = 0;
  var	max_id = 1;
  var starting_date  	= 	 Date.UTC( 1997, 00, 14, 21, 00, 00 );
      var	current_date	= 	 new Date();
  current_date = current_date.getTime();
  var elapsed_time_millisecs = current_date - starting_date;
  var iconsPerMilliSecond;
  var	start_timer, end_timer;
  var setup_counter = 0;
  var Num_Tested = 500;
  setup_animation();
  init_icon();
  setup_icon(0);
    start_timer = 	new Date();
    start_timer = start_timer.getTime();
  context.fillStyle = "red";
  context.font = "bold 16px Arial";
  context.fillText("Measuring Display Speed and Updating Icon", 75, 420);
  time_circuit();
  function time_circuit()
  {
    if( setup_counter <= Num_Tested )
    {
      Increment_Icon();
        paintIcon();
        draw_grid();
        setup_counter++;
          requestAnimFrame(function() {
          time_circuit();
        });
    }
    else
    {
      context.fillStyle = '#ffffff';
      context.fillRect( 50, 400, 400, 75);
      end_timer = 	new Date();
      end_timer = 	end_timer.getTime();
      millisecs_elapsed = end_timer -  start_timer;
      iconsPerMilliSecond = Num_Tested/millisecs_elapsed;
    if(elapsed_time_millisecs > 0 )
    setup_icon(elapsed_time_millisecs * iconsPerMilliSecond);
    animateIcon();
    }
  }
  function animateIcon()
    {
        Increment_Icon();
        paintIcon();
        draw_grid();
     requestAnimFrame(function() {
          animateIcon();
        });
 }
  function init_icon()
  {
    for( var m=0; m<Icon_Size; m++)
    {
      for( var n=0; n<Icon_Size; n++)
      {
        Icon_State[ (m*Icon_Size) + n ] 	= 0;
        }
    }
  }
 <!-- Given a decimal number (usually the starting position) -->
  <!-- Setup the icon to reflect that number and start counting from there-->
  function  setup_icon( decimal_num )
  {
    var	remainder;
    <!-- beo is the binary_exponential_order  -->
    var  beo = 0;
    <!-- Start with order 0 - the least significant digit-->
    <!-- is the number odd? Then that pixle goes on-->
    <!-- Shift the number right (divide by two...the >> operator did not work here on long types )-->
    <!-- Check again on the new digit at one order up-->
    <!-- Repeat until every digit is checked  - number is divided away-->
    while( decimal_num >= 1 )
    {
      decimal_num = Math.floor(decimal_num);
      remainder = decimal_num % 2.000000000;
      if( Math.abs(remainder) == 1)
      {
        Icon_State[ beo ] = 1;
      }
      decimal_num /= 2.0;
      beo++;
    }
    max_id = beo;
    id = beo;
  }
  function draw_grid()
  {
      var m = 0;
      context.lineWidth = 1;
  context.strokeStyle = '#000000';
  for( m=0; m<=Icon_Size; m++)
  {
      context.beginPath();
        context.moveTo(canvas_x_offset + (m*Icon_wid), canvas_y_offset);
        context.lineTo(canvas_x_offset +(m*Icon_wid),  canvas_y_offset +(Icon_Size*Icon_wid));
        context.stroke();
        context.beginPath();
    context.moveTo(canvas_x_offset,canvas_y_offset + (m*Icon_hgt));
    context.lineTo(canvas_x_offset+(Icon_Size*Icon_hgt),canvas_y_offset +(m*Icon_hgt));
    context.stroke();
     }
   }
function paintIcon()
  {
  var temp_counter = 0;
  var m=0;
  var n=0;
  context.lineWidth = 1;
  out:
  for(  m=0; m<Icon_Size ; m++)
    {
      for(  n=0; n<Icon_Size ; n++)
      {
        if( Icon_State[(m*Icon_Size) + n ] == 1 )
      {
        context.strokeStyle = '#000000';
        context.fillStyle = '#000000';
        context.fillRect(canvas_x_offset+((n*Icon_wid)+1),canvas_y_offset+((m*Icon_hgt)+1), Icon_wid-1, Icon_hgt-1);
      }
      else
      {
        context.strokeStyle = '#000000';
        context.fillStyle = '#ffffff';
        context.fillRect(canvas_x_offset + ((n*Icon_wid)+1),canvas_y_offset+((m*Icon_hgt)+1), Icon_wid-1, Icon_hgt-1);
      }
      if( temp_counter >= max_id ) break out;
      temp_counter++;
    }
      }
  }
function Increment_Icon()
  {
    var carry_bit  = 0;
    id 		= 1;
    if ( Icon_State[ 0 ] 	== 0 )
       Icon_State[ 0 ]  	= 1;
    else
    {
      Icon_State[ 0 ]  = 0;
      carry_bit = 1;
      <!-- Propogate numbers  -->
      while ( carry_bit == 1 )
      {
        if( Icon_State[ id ] == 1 )
        {
          Icon_State[ id ] = 0;
          id++;
        }
        else
        {
          Icon_State[ id ] = 1;
          carry_bit = 0;
        }
      }
    }
    if( id > max_id ) max_id = id;
  }
  function setup_animation()
  {
    window.requestAnimFrame = (function(callback) {
      return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function(callback) {
        window.setTimeout(callback, 1000 / 60);
        };
      })();
  }
</script>
Shift+Enter to run
HTML

Games can also share these characteristics. Perfectly quantitative games are those featuring perfect information, where all players know the state of all pieces. Poker does qualify, for example, but Connect Four does.

Many games featuring perfect information do not allow for a complete quantitative analysis because they are too complex. The version of Connect Four pictured above was built for the Texas Instrument 99/4a home computer in 1979. The computer was not powerful enough to consider every possible outcome from the first move but could still challenge a human player. Today's expert players, however, cannot triumph over a contemporary computer opponent. John Tromp "solved" Connect Four in 1995 when he developed software capable of considering all 4,531,985,219,092 possible states regardless of the starting point, thus sketching a complete quantitative picture of the game.34^3\,^4

These huge numbers beguile the mind. Channa Horwitz's And Then There Were None can be held in your hand, complete within the space and time of human existence. Much of Horwitz's work remains compelling because she worked on a human scale; her minimalist restraint was a quality that she felt gave her freedom.5^5

Structure

Advancing the Beat

Horwitz uses musical terms when laying out the grid. In Sonakinatography I, Composition III, instruments 1-8 line the x-axis while beats line the y-axis starting at 1. Beats progress indefinitely in whole number intervals. With the terminology in hand - beats, instruments, and colors - it's easy to parse the key Horwitz provides on the artwork itself:

Each instrument follows the number and color grid in a vertical direction forward & backward repeating for desire time duration
 NUMBER GRID - 2 3 4 5 6 7 8 1
               3 4 5 6 7 8 1 2
               4 5 6 7 8 1 2 3
               5 6 7 8 1 2 3 4
               6 7 8 1 2 3 4 5
               7 8 1 2 3 4 5 6
               8 1 2 3 4 5 6 7
               1 2 3 4 5 6 7 8
               | | | | | | | |
INSTRUMENT # - 1 2 3 4 5 6 7 8
               L             H
               O <---------> I
               W    SCALE    G
                             H

Horwitz's supplied algorithm tells us all we need to recreate the piece. The algorithm starts on the bottom row of the number grid: 1 2 3 4 5 6 7 8, represented above. Each number in the number grid represents the duration of the beat. For example:

  • Instrument #1 has a duration of 1 beat in the first position and then has a duration of 8 beats in the second position.

  • Instrument #2 establishes a duration of 2 beats in the first position and then has a duration of 1 beat in the second position.

The position of each instrument does not advance until all beats are counted. When the position of an instrument advances, so does its color.

  • Instrument #1, which starts as 1 - Yellow-Green in the first column, has a duration of 1 beat. After it advances to the next vertical position, the color moves one step lower on the scale. Since there is nothing lower than 1, the algorithm circles around to 8 - Yellow.

  • Instrument #2, which starts as 2 - Green in the second column, has a duration of 2 beats. After two beats, it advances to the next vertical position and encounters a 1 and the color moves one step lower on the scale from 2 - Green to 1 -Yellow-Green.

After nine beats, the state of the algorithm looks like this:

           9 - 1 . . 1 1 . . .
           8 - . . . . . . . 1
           7 - . . . 1 . . 1 .
           6 - . . 1 . . 1 . .
           5 - . . 1 . 1 . . .
           4 - . . . 1 . . . .
           3 - . 1 1 . . . . .
           2 - . 1 . . . . . .
           1 - 1 . . . . . . .
               | | | | | | | |
INSTRUMENT # - 1 2 3 4 5 6 7 8

The resulting image:

Consider Instrument #3. It starts at 3 - Blue, then 2 - Green, and finally 1 - Yellow-Green. The colors are generated like so:

Instrument3:321Beats 1-321Beats 4, 51Beat 6Instrument\,3: \underbrace{3\,2\,1}_\text{Beats 1-3} \overbrace{2\,1}^\text{Beats 4, 5} \underbrace{1}_\text{Beat 6}

Horwitz's simple notation of beats, squares, and rests (non-squares) obscures its expressive power. Sonakinatography I, Composition III has been directly expressed in the mediums of dance, installation art, and music. Furthermore, Sonakinatography semiotics unintentionally anticipates music production software that appears over a decade later.

Beats and Instruments in Music

The arrival of Cubase 1.0 (1989) on the Atari ST forever changed how music is made. Colorful blocks of music are arranged on a grid of beats that intersect a vertical selection of instruments. The arrangement bears a resemblance of Horwitz's time-based algorithms.

Popular computers like the Atari ST introduced millions of people to the kind of thinking it takes to operate and create computationally. Cubase leveraged this conceptual change and the machine's visual power to drive a new kind of notation that has become the standard for music production.

Horwitz's art embodies how the digital world changes our processes, which in turns changes how we think and what we value: In my notations I am interested in breaking through the barrier of the different arts, because they all have a common language. The language I use in my notations is applicable to some aspect of each of the arts. In these notations I am searching for some connecting link to establish a clearer reality.1^1

The musicality of Sonakinatography can perhaps best be appreciated when set in motion.

def reset_instrument(instrument):
  if instrument['color'] == 1:
    instrument['color'] = 8
  else:
    instrument['color'] -= 1
  instrument['countdown'] = instrument['color']
  return instrument
def build_row(canvas, grid_objects, beat, max_beat):
  for instrument in grid_objects:
    instrument['countdown'] -= 1
    shape = Shape(instrument, beat, max_beat)
    if instrument['countdown'] == 0:
      shape.paint_square(canvas)
      instrument = reset_instrument(instrument)
    else:
      shape.paint_line(canvas)
def build_columns(canvas, grid_objects, max_beat):
  beat = 0
  while beat < max_beat:
    beat += 1
    build_row(canvas, grid_objects, beat, max_beat)
def build_matrix(max_beat):
  dwg = svgwrite.Drawing('/results/sonakinatography.svg', (300,1700))
  grid_objects = [{'color': 1, 'countdown': 1, 'instrument': 1},
                  {'color': 2, 'countdown': 2, 'instrument': 2},
                  {'color': 3, 'countdown': 3, 'instrument': 3},
                  {'color': 4, 'countdown': 4, 'instrument': 4},
                  {'color': 5, 'countdown': 5, 'instrument': 5},
                  {'color': 6, 'countdown': 6, 'instrument': 6},
                  {'color': 7, 'countdown': 7, 'instrument': 7},
                  {'color': 8, 'countdown': 8, 'instrument': 8}]
  build_columns(dwg, grid_objects, max_beat)
  return dwg
drawing2 = build_matrix(60)
drawing2.save()
0.5s
round-glitterPython

Variations

Quantitative art shares important characteristics with computation itself. Even as he was laying the foundations for computer science, Alan Turing noticed the relationship between code and data. Different contexts (data) will yield different results when the machine executes the instruction (code). Simple changes can yield an outsized influence when generating quantitative art. The dozens of variations of Sonakinatography are both familiar and uniquely beautiful:

Sonakinatography I, Composition III was freshly interpreted and performed in 2015 as dance and light by Ellen Davis:

Haroon Mirza’s 2015 sound installation, A Chamber for Horwitz: Sonakinatography Transcriptions in Surround Sound, is another recent example:

Horwitz's restraint and commitment to minimalist simplicity has generated work that spans both time and media. It is hard to imagine any present or future artist working without ever having used a computer. Horwitz's organic interpretation of computation predicted a coming age without being directly influenced, which makes Sonakinatography a wholly unique work.

Appendix

Special thanks to Kim Burgas, Thalassa Balanis at the Lisson Gallery, and The Museum of Modern Art Library.

1^1McCoy, Ann, “Channa Davis Horwitz: An Interview,” Journal. The Los Angeles Institute of Contemporary Art, October 1974. Periodical.

2^2"In John Simon's Art, Everything Is Possible." The New York Times. The New York Times Company, 17 April 1997. Web. 25 February 2019, numeral.com/articles/041797mirapaul/041797mirapaul.html

3^3Tromp, John, Connect-4 Data Set, February 4, 1995

4^4Tromp, John. “Number of Legal 7 X 6 Connect-Four Positions after n Plies.” The On-Line Encyclopedia of Integer Sequences, 23 May 2012. Web. 25 February 2019, oeis.org/A212693.

5^5Horwitz, Channa. "Sonakinatography Artist Statement." Lisson Gallery.

Runtimes (2)