Sunday, October 28, 2007

Overview of the Interface and Protocol

Introduction
The interface is made up of one hardware component and three software components. The four components operate in accordance to a predetermined, custom protocol for delivering and receiving information relevant to the production of musical material from the host computer system to the Vectrex videogame console. The protocol is a description of the order and method of information flow from one place to another.



Limitations
The current prototype interface is considerably limited. It is restricted in the following ways.
  • Monophonic capability (ie. only one note can be played at a time out of a theoretically* possible three)
  • Four-bit pitch set (ie. only sixteen different pitches can be played out of a theoretically possible 4096)

However, it should be noted that the system is in its infancy in terms of development. The interface also incorporates some positive aspects. The reaction time of the interface is fast since only one byte of information is required to be sent and received successfully in order to generate a sound or a change in a sound. Secondly, the four-bit volume control allows for complex volume envelopes that are generated by a host computer program (see Software Overview: Host Computer Patch).

A number of data routing and control techniques will be implemented in order to overcome these limitations in the near future.



Software Overview: Host Computer Patch
The host computer patch acts as a mediator between MIDI data and the microcontroller stage (see: Software Overview: Microcontroller). The MIDI data may be played in by the user in real time or may be pre-sequenced or algorithmically generated in some fashion. The Max/MSP patch titled VECENV reacts to note on, note off and certain continuous control messages.

Each note on and note off event contains two important bytes of data – the velocity and the note number (pitch). For a note on event, the velocity will be a number between 1 and 127. For a corresponding note off event, the velocity will be 0. The pitch byte in both cases is a number between 0 and 127.

The patch examines the pitch byte of the incoming MIDI note and takes the modulo 15 value. This value then becomes the 4-bit frequency nibble that is eventually sent to the Vectrex console (see: Protocol Overview).

A non-zero velocity value from the incoming MIDI note triggers a 32-stage, 4-bit custom volume envelope. This envelope is represented graphically to the user in an editable form. A zero velocity value from the incoming MIDI note sets the output to 0. The data from the volume envelope forms the 4-bit volume nibble that is eventually sent to the Vectrex console (see: Protocol Overview).

The VECENV patch includes a set of 16 presets containing information regarding the shape of the volume envelope. These presets can be accessed via the graphic user interface or by using MIDI Continuous Controller number 16 (General Purpose Slider #1). The range of data from 0 to 127 is scaled to a value between 0 and 15. This value sets the preset from 0 to 15. The default envelope shape preset is 0, which contains a value of 15 for the first step of the envelope and 0 for the remaining steps.

The user is able to alter the speed at which the volume envelope is read through. This is expressed in milliseconds per envelope step and a value from 10ms to 220ms is allowed. The speed parameter can be accessed via the graphic user interface or by using MIDI Continuous Controller number 17 (General Purpose Slider #2). The range of data from 0 to 127 is scaled to a value between 10ms and 220ms. The default speed value is 10ms.

The user is able to alter the length of the volume envelope. This parameter sets how many of the 32 steps are read through before either looping or muting occurs and is defined by a value between 0 and 31. The length parameter can be accessed via the graphic user interface or by using MIDI Continuous Controller number 18 (General Purpose Slider #3). The range of data from 0 to 127 is scaled to a value between 0 and 31. The default value for the length parameter is 31 (representing the full length of the volume envelope).

The user is able to set the volume envelope to loop mode. If the envelope is set to loop mode then the steps of the envelope will wrap-around indefinitely, so long as a note-off event has not been received. This allows for longer, held notes. The loop mode toggle can be accessed via the graphic user interface or by using MIDI Continuous Controller number 19 (General Purpose Slider #4). The range of data from 0 to 127 is scaled to either 0 (for values below 64) or 1 (for values above or equal to 64). If the resulting value is 0, then loop mode is set to off. If the resulting value is 1, then the loop mode is turned on. The loop mode is off by default.

The user is able to scale the output of the volume envelope by a number between 0 and 15. This parameter is called volume and allows for effective control over fade-ins, fade-outs and mixing levels for the Vectrex voice that is being played. The volume parameter can be accessed via the graphic user interface or by using MIDI Continuous Controller number 1 (Modulation). The range of data from 0 to 127 is scaled to a value between 0 and 15. The default value for the volume parameter is 15.

The following table summarises the current MIDI implementation of the VECENV patch.




Software Overview: Microcontroller

The microcontroller software acts as a mediator between the host computer Max/MSP patch VECENV and the bridging circuit (see: Hardware Overview: Bridging Circuit). The microcontroller software has been written in the Arduino environment for use with an Arduino NG or similar interfacing board. An Arduino allows for the translation of digital data into electrical signals.

The sketch (Arduino program) takes the data byte from the Max/MSP VECENV patch containing pitch and volume data and transfers it to the Vectrex via the bridging hardware using electrical states. It should be noted that pins 0 and 1 cannot be used within the Arduino program to send the byte to the Vectrex as these pins are used to transfer the information from the host computer. Thus, PORTB (pins 8 to 15) have to be used in conjunction with PORTD (pins 0 – 7), even though only eight bits are being set.

/*
VECENV TO VSOUNDER CONVERTER by Sebastian Tomczak 26 October 2007
*/

byte data;
// set up a space for data to be tranferred
void setup() {
// begin the setup function
Serial.begin(57600);
// open up a serial connection
DDRD = B11111110;
// set the direction of the PORTD pins (0 - 7)
DDRB = B00000011;
// set the direction for the PORTB pins (8 - 15)}
void loop() {
// begin the loop function
if(Serial.available() > 0) {
// if a serial byte has been received in the serial buffer, then...
data = Serial.read();
// read the byte into memory
PORTD = (data << portb =" (data">> 6) & B00000011;
// set the PORTB pins 0 - 1 to the most significant two bits}}

/* END */
Code 1: The Arduino Sketch



Hardware Overview: Bridging Hardware
The bridging hardware acts as a mediator between the micrcontroller software and the Vectrex itself (see Software Overview: Vectrex Binary). In essence, the interfacing hardware allows the Arduino board to send data to the Vectrex console by directly manipulating the controller ports that are usually used for player input. It is a very simple circuit and is summarised in the following table. Each arrow indicates a direct electrical connection.



** All Arduino pins are connected to ground via separate 30kΩ pull-down resistors . Resistors with a power rating of 0.25W and a tolerance of 5% should suffice for this application. Resistance values between 22kΩ and 100kΩ will suffice for this application.

*** Ground (pin 8) of the DB-9 connector 1 is connected to Arduino ground. 5V (pin 7) of the DB-9 connector 1 is connected to Arduino ground. The Arduino power selection jumper should be set to EXT for the use of an external power source.

**** Ground (pin 8) of the DB-9 connector 2 is connected to Arduino ground.


It should be noted that the ATMega168 microcontroller onboard the Arduino is powered via the outlets on the Vectrex controller. However, the FTDI Serial USB microchip onboard the Arduino is powered via the USB connection to the host computer USB bus. This allows for a reliable transmission of data from the host computer to the Arduino board via the incorporated FTDI microchip. This also allows for direct control of the Vectrex controller ports because the same power bus as the analog to digital circuitry inside the Vectrex powers the micrcontroller that is acting as a control mechanism.



Software Overview: Vectrex Binary
The Vectrex binary acts as a mediator between the bridging hardware and the sound chip of the Vectrex. It is a ROM (read-only memory) image titled VSOUNDER and is essentially a piece of software that the Vectrex console is able to use. The software takes the current state of the two controller ports and uses this state to manipulate the sound chip (programmable sound generator or PSG). The state of the two controller ports thus determines the sounds that the Vectrex creates.

The creation of this binary would not have been possible without the hard work of a number of individuals within the Vectrex community. In particular, the tutorials by both Chris Salomon and Christopher Tumber very were useful as was a triggering code example by Manu Pärssinen . Finally, it is only through the VecFlash hardware developed by Richard Hutchinson that the binary can be currently executed on an actual Vectrex machine (as opposed to an emulator). The source code was assembled in the AS09 assembler. Although a number of variants have been explored thus far, the basic structure and format of the assembly code is as follows.

; pulse wave control example
; by sebastian tomczak
; 26 october 2007
;
; setup bios functions as used in the program
waitrecal equ $f192
byte2sndchip equ $f256
clearsound equ $f272
readbuttons equ $f1ba
; header block
org 0 ; set memory position to zero
fcb $67,$20
fcc "gce 2007" ; copyright year
fcb $80 ; end copyright year string
fdb musa,$f850,$30b8 ; play header music
fcc "vsounder ex" ; program display title
fcb $80,$0 ; end program display title string
; initialise program
jsr readbuttons ; read buttons for initial values
jsr clearsound ; stop any sounds that might be playing
; main program
main jsr waitrecal ; resync
jsr readbuttons ; read buttons into ram
ldb $c80f ; retrieve current button state
andb #$0f ; bitmask least sig four bits
lda #$08 ; modify psg register
jsr byte2sndchip ; set psg register
ldb $c80f ; retrieve current button state
andb #$f0 ; bitmask (most sig four bits revealed)
lda #$00 ; modify psg register
jsr byte2sndchip ; set psg register
lda #01 ; modify psg register
ldb #01 ; data to register
jsr byte2sndchip ; set psg register
lda #$07 ; modify psg register 7 (mixer)
ldb $c807 ; get previous value for psg reg 7
andb #$fe ; turn on tone on voice 1
orb #$08 ; turn off noise on voice 1
jsr byte2sndchip ; set psg register
bra main ; branch back to main loop
musa fdb $fee,$fbe6 ; silent music for header block
fcb $0,$80 ; end silent music for header block
; end

Code 2: The VSOUNDER Source Code

In order to achieve the results heard in the work Extraction Point, a total of five Vectrex binaries were assembled and explored musically via MIDI data from the ProTools environment. Each variant introduced a different set of notes of noise shaping values.



Protocol Overview
The overall structure of the control flow is as follows.
  • MIDI data is sent to the Max/MSP patch VECENV
  • The Max/MSP patch VECENV generates the pitch and volume data that is sent to the Arduino board
  • The Arduino board sets the state of the interfacing hardware that is manipulating the controller ports on the Vectrex
  • The VSOUNDER Vectrex binary measures the state of the controller ports on the Vectrex.
  • The VSOUNDER Vectrex binary controls the sound chip of the Vectrex as determined by the controller ports

MIDI data is transformed into two four-bit nibbles (see: Software Overview: Host Computer Patch). These two nibbles form a byte as follows.


The high nibble (frequency) corresponds to the controller 2 buttons in the hardware tranfer of data. Button 1 corresponds to bit 4, button 2 corresponds to bit 5, button 3 corresponds to bit 6 and button 4 corresponds to bit 7.

The low nibble (volume) corresponds to the controller 1 buttons in the hardware tranfer of data. Button 1 corresponds to bit 0, button 2 corresponds to bit 1, button 3 corresponds to bit 2 and button 4 corresponds to bit 3.

The state of the controllers is read into a memory location $C80F. The data is represented as follows within this location.

The memory location $C80F is bitmasked† against $0F (00001111) in order to retrieve only the volume nibble. This value is then written to PSG (programmable sound generator) register†† eight. The lower four bits of this register set the volume of the voice one output of the Vectrex.

The memory location $C80F is bitmasked against $F0 (11110000) in order to retrieve only the frequency nibble. This value is then written to PSG register nine. The upper four bits of this register help to determine the frequency which is played by voice one of the Vectrex. Each of the three Vectrex voices can play 4096 different possible pitches. This is controlled by a twelve-bit number held in two registers. For voice one of the PSG, register one is the coarse-tuning register (most significant four bits of the twelve-bit value) and register zero is the fine-tuning register (the eight least significant bits of the twelve-bit value). Acceptable frequency ranges can be achieved by changing the four most significant bits of register zero in tandem with setting certain bits within register one.



Bibliography
Richard Hutchinson. “The VecFlash Multi Cart”. http://www.richard.hutchinson.dsl.pipex.com/new_page_1.htm. (Accessed 28 October 2007).

Manu Pärssinen. “Sound Triggering Example”. http://www.pelikonepeijoonit.net/vec/sound5.as9. (Accessed 28 October 2007).

Kevin Ross. “The Basics – Very Basic Circuits: The Pull-Up Resistor”. http://www.seattlerobotics.org/encoder/mar97/basics.html. (Accessed 28 October 2007).

Chris Salomon. “List of Vectrex ROM Function – Functionally Ordered”. http://playvectrex.com/designit/chrissalo/appendixa.htm#Functionally. (Accessed 28 October 2007).

Chris Salomon. “Vectrex Programming Tutorial”. http://playvectrex.com/designit/chrissalo/toc.htm. (Accessed 28 October 2007).

Christopher Tumber. “Introduction to Vectrex Programming”. http://playvectrex.com/designit/christumber/tutorial.htm. (Accessed 28 October 2007).

0 comments: