Drawing Machine
January 30, 2008
Thesis Proposal
Ben Leduc-Mills
Spring 2008
1. THESIS STATEMENT – What problem are you taking on, or what project are you proposing? This should be expressed in one or two sentences, and should be as specific and clear as you can be at the time. We anticipate that you will re-write this statement in increasingly specific terms as your sense of the project progresses.
I propose to build a physical drawing machine with the ability to draw complex illustrations based on various forms of user input. I have two goals; make something meaningful, and to make something pretty.
2. PERSONAL STATEMENT – Why are you interested in this subject? When did your interest start, and why? What particularly fascinates you in this line of thought or type of project? What do you hope to gain from the experience? This should be one or two pages (250-500 words).
I became interested in building a drawing machine by asking myself what I wanted to create before my time at ITP was up. I wanted to build a physical object, I wanted it to be able to create works of some permanence, and I wanted it to be fun. Of the projects that came to mind, a drawing machine appealed to me for several reasons, apart from fulfilling the aforementioned criteria.
First of all, the act of making a drawing machine seemed feasible, given the skill set I have acquired at ITP. A drawing machine would incorporate elements of physical computing, programming, and artistic expression through a huge variety of user interactions, which leads me to the second point: the range of potential artistic expression available. A drawing machine has, like most machines, an input and an output. The great part about a drawing machine is that the input (the data that becomes the drawing), the method (the program that translates the data), and the output (the actual drawing tool), are all variable in interesting ways.
For example, the input could be the keypad of a telephone, a voice, or some text. The program itself can be varied in a infinite number of ways to interpret and output the data it gets (line width, dots, text), and finally, the machine itself can be varied to produce different results based on what drawing instrument are used.
3. RESEARCH – Provide at least four examples of projects, books, products, or technologies that serve as background, inspiration, irritation, or research for the Thesis.
Tristan Perich is an ITP alum who made a simple form of drawing machine during his time here. I was impressed with the combination of simple mechanism and complex result.
A drawing machine I found during preliminary research is somewhat similar to what I have in mind in terms of physical appearance: http://bea.st/sight/sketch/.
Pendulum drawings at the Exploratorium when I was a child.
Etch-a-sketch.
4. WORK DESCRIPTION – One paragraph to one page description of what it is you actually intend to make or do to pursue your Thesis. As with the Thesis Statement, this should be expressed as specifically as possible, with the specificity increasing over time.
Begin research of both the physical parts needed and the possible programming methods. What programs, interfaces, connections, etc. can be leveraged to create interesting results.
Continue to research. Get theory started, order parts, begin programming.
Continue to build. Start testing.
Continue testing, refine, start user testing.
Finish.
Social Software Week 1
January 27, 2008
Short Description: To add a gaming page to RapHappy.com, using the social aspects of the site to enhance the gaming experience.
1. Three Sites or services that have something in common with RapHappy:
Dopetracks.com – Another social networking site which allows users to record audio from their computers over music.
kSolo.com – A karaoke site which encourages social interaction by voting/rating, duets, and inviting friends.
myspace music – Allows users to host a profile and put original songs up for others to listen and respond to.
2. Three things that I hope users do with my project:
Use it. If no one uses it, does it really exist?
Have fun – RapHappy is irreverant and funny, (at least it’s supposed to be) and games are supposed to be fun, so if users do not have fun with the games, they are most likely a failure.
Be creative – One of the wonderful things about social games is that people may use them in unexpected ways. I hope to see some ingenuity from the community in their usage of the games.
3. Three things that could go wrong:
The interaction is unappealing, boring, repetitive, etc.
The concept itself of having games on a sites such as RapHappy is misguided and is not something that users will respond to.
The games page does not make good usage of the social aspects of the site, or of the information we have about the user.
A2Z, Week 1
January 26, 2008
For my first week’s assignment, I chose to take in some text from the Bible (genesis), parse the text into words, find all the references to ‘God’, and replace them with ‘Ben’. I then printed out the 3 words following all of the references into a new text file, with some humourous results.
The code:
// Word search and replace
// Ben Leduc-Mills
// Programming A2Z, Spring 08
// Based off of code by Daniel Shiffman import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class Blm272Week1 {
public static void main (String[] args) throws IOException {
// Create an input stream and file channel
// Using first arguemnt as file name to read in
FileInputStream fis = new FileInputStream(args[0]);
FileChannel fc = fis.getChannel();
// Read the contents of a file into a ByteBuffer
ByteBuffer bb = ByteBuffer.allocate((int)fc.size());
fc.read(bb);
fc.close();
// Convert ByteBuffer to one long String
String content = new String(bb.array());
//Split text by wherever there is a space
String[] words = content.split(" ");
System.out.println("Read " + words.length + " words from " + args[0]);
StringBuffer gods = new StringBuffer();
for (int i = 0; i < words.length; i+=2) {
if (words[i].equals("God")) {
gods.append(words[i] + " " + words[i+1] + " " + words[i+2] + " " + words[i+3] + "\n");
}
}
String output = gods.toString();
String ben = output.replace("God", "Ben");
// Create an output stream and file channel to write out a report
// (Also print out report to screen)
FileOutputStream fos = new FileOutputStream(args[1]);
FileChannel outfc = fos.getChannel();
// Convert content String into ByteBuffer and write out to file
bb = ByteBuffer.wrap(ben.getBytes());
outfc.write(bb);
outfc.close();
System.out.println("Reversed text written to " + args[1]);
}
}
And the results:
Ben said, Let there Ben divided the Ben called the light Ben said, Let there Ben called the dry Ben said, Let the Ben saw that it Ben said, Let the Ben saw that Ben said, Let the Ben made the beast Ben said, Let us Ben created man in Ben blessed them, and Ben said unto them, Ben said, Behold, I Ben ended his work Ben blessed the seventh Ben created Ben had Ben formed man of Ben to grow every Ben said, It is Ben formed every beast Ben had made. And Ben said unto the Ben said, Behold, the Ben made he him; 01:005:002 Ben after he begat Ben took him. 01:005:025 And Ben came in unto Ben said unto Noah, Ben commanded him, so Ben had commanded him: Ben made a wind Ben spake unto Noah, Ben said, This is Ben of Shem; and Ben talked with him, Ben unto thee, and Ben said unto Abraham, Ben said, Sarah thy Ben went up from Ben destroyed the cities Ben remembered Abraham, and Ben came to Abimelech Ben said unto him Ben caused me to Ben had commanded him. 01:021:005 Ben hath made me Ben said unto Abraham, Ben heard the voice Ben opened her eyes, Ben was with the Ben that thou wilt Ben did tempt Ben had told him. 01:022:004 Ben will provide himself Ben had told him Ben of the earth, Ben of my master Ben of my master Ben of my master Ben give thee of Ben of Isaac: the Ben will be with Ben hath judged me, Ben hearkened unto Leah, Ben hath given me Ben hath endued me Ben remembered Rachel, and Ben hearkened to her, Ben hath taken away Ben of Bethel, where Ben hath taken from Ben came to Laban Ben of Ben of my father, Ben of Nahor, the Ben of their Ben of my father Ben of my Ben and with men, Ben hath dealt graciously Ben said unto Jacob, Ben was upon the Ben said unto him, Ben said unto him, Ben Almighty: be fruitful Ben went up from Ben will shortly Ben is? 01:041:039 And Pharaoh Ben hath Ben be gracious unto Ben forbid that I Ben sent me before Ben of his father Ben spake unto Israel Ben hath shewed me Ben which fed me Ben shall be Ben of thy father,
Mobile Medic
December 10, 2007
Mobile Medic
In Short: An application designed to improve the effectiveness of medical personnel in developing nations.
Why: The growing expansion of mobile phones into poor areas is far outpacing that of any other communications technology; that fact together with the numerous problems facing overworked, understaffed, and undertrained medical personnel present a very important and exciting opportunity.
Background:
- Design for the other 90%
- Cell phone counseling in the Congo
- Blue Trunk Libraries (WHO)
- The global Health Library
The technical part (How it works):
- Asterisk (open-source telephony program)
- PHP (server – side programming language)
- MySQL (data base program)
Asterisk Code
Calling a PHP script using the Asterisk Gateway Interface (AGI)
[redial_blm272]
exten => s,1,Answer();
exten => s,n,AGI(/home/blm272/asterisk_agi/mobileMedic.php);
exten => t,1,Hangup();
The PHP script (AKA the Heavy Lifting)
#!/usr/local/bin/php -q
require('/var/lib/asterisk/agi-bin/phpagi.php');
//set time limit
set_time_limit(60);
// SQL Query Helper Function
function sqlQuery($query)
{
global $mySql;
$data = null;
$result = mysql_query($query, $mySql);
# This set's up an associative array (key->value pair) for all of the data returned
if (sizeof($result) > 0)
{
$num_fields = mysql_num_fields($result);
$row_cnt = 0;
while ($row_data = mysql_fetch_array($result)) {
for ($cnt = 0; $cnt < $num_fields; $cnt++) {
$field_name = mysql_field_name($result, $cnt);
$data[$row_cnt][$field_name] = $row_data[$cnt];
}
$row_cnt++;
}
}
return $data;
}
//Audio Files turned into variables for convenience
$welcomeAudio = "/home/blm272/asterisk_sounds/welcomeAudio"; //welcome, please enter PIN
$mainMenuAudio = "/home/blm272/asterisk_sounds/mainMenuAudio"; //say main menu options
$extensionAudio = "/home/blm272/asterisk_sounds/extensionAudio"; //ask for extension
// Create an AGI Object
$agi = new AGI();
// Predefined AGI Variables, send them to the Asterisk console for debugging
$agi->conlog($agi->request["agi_request"]);
$agi->conlog($agi->request["agi_channel"]);
$agi->conlog($agi->request["agi_language"]);
$agi->conlog($agi->request["agi_uniqueid"]);
$agi->conlog($agi->request["agi_callerid"]);
$agi->conlog($agi->request["agi_dnid"]);
$agi->conlog($agi->request["agi_rdnis"]);
$agi->conlog($agi->request["agi_context"]);
$agi->conlog($agi->request["agi_extension"]);
$agi->conlog($agi->request["agi_priority"]);
$agi->conlog($agi->request["agi_enhanced"]);
$agi->conlog($agi->request["agi_accountcode"]);
$agi->conlog($agi->request["agi_network"]);
$agi->conlog($agi->request["agi_network_script"]);
// Database connection variables
$hostname = "itp.nyu.edu";
$dbname = "blm272";
$username = "blm272";
$password = "kvibn+6";
// Connect to the database
$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
mysql_select_db($dbname, $mySql) or die(mysql_error());
//start dialplan
$agi->answer();
//$agi->wait(1);
//$agi->text2wav('Welcome to mobile medic. Please Enter Your PIN Number');
//$agi->stream_file($welcomeAudio); //answer and ask for pin (need to put in add new pin?)
//$agi->get_data($welcomeAudio);
$return = $agi->get_data($welcomeAudio);
$callerID = $agi->request["agi_callerid"];
if ($return['result'] > 0)
{
//$agi->get_data($welcomeAudio);
$extension = chr($return['result']);
$query ="INSERT INTO Voicemail (callerID, extension, time) VALUES ('" . $agi->request["agi_callerid"] ."', '" . $return['result'] . "', NOW())";
$insert_result = mysql_query($query, $mySql);
//$insert_result[2] = $extension;
//echo ($extension);
// Query the database to see if this caller has called before
$query = "SELECT id, extension, FROM Voicemail WHERE extension = '" . $return['result'] . "'";
$result = mysql_query($query, $mySql);
//$agi->say_number($ascii);
//$agi->text2wav('Thank you. Proceeding to Main Menu for'.' '.$agi->say_number($ascii));
echo ($result);
//$result = sqlQuery($query, $mySql);
if (sizeof($result) > 0)
{
//we got a result from the DB
$agi->conlog("Database ID: " . $result[0]['id']);
//play options menu and listen for response (get data = background)
$whereto = $agi->get_data($mainMenuAudio, 5000, 1);
if (is_numeric($whereto['result']))
{
$agi->conlog("Result: " . $whereto['result']);
$agi->say_number($whereto['result']);
//menu options start here
if ($whereto['result'] == 1) //emergency call to doctor
{
//ask for extension to call
$extension= $agi->get_data($extensionAudio); //max digits for extensions is 4
if(is_numeric($extension['result']))
{
$query = "SELECT doctorNumber, extension FROM Doctors WHERE extension = '". $extension['result'] . "'";
//Query DB to find doctor's number based on extension
//$query = "SELECT doctorNumber, extension FROM Doctors WHERE extension = '" . $extension['result'] . "'";
$result = SQLquery($query, $mySql);
//if (sizeof($result >0))
if (sizeof ($result > 0));
{
$agi->say_number($extension['result']);
//$docNum = 18312959612;
$docNum = $result[0]['doctorNumber'];
//$agi->say_number($result[0]['doctorNumber']);
$agi->exec('Dial', trim("SIP/itp_jnctn/" . $docNum . "|30|r"));
if (!$result)
{
die("Error " . mysql_errno() . " : " . mysql_error());
}
//$agi->goto("redial_blm272_sip","s",1);
}
}
}
elseif ($whereto['result'] == 2) //leave message in Doctor's VM, who then gets a text notification
{
//ask for extension to call
$extension= $agi->get_data($extensionAudio, 10000, 4); //max digits for extensions is 4
if(is_numeric($extension['result']))
{
$voicemail_location = "/home/blm272/asterisk_sounds/voicemail";
$callerID = $agi->request["agi_callerid"];
$record_file = $voicemail_location . time() . "vm" . $agi->request["agi_callerid"];
$agi->record_file($record_file, "WAV", "0123456789", 10000, 0, true, 5);
$query ="INSERT INTO Voicemail (callerID, record_file, time) VALUES ('" . $agi->request["agi_callerid"] . "', '" . $record_file . "', NOW())";
//$query = "insert into callers (caller_id, name_audio) values ('" . $agi->request["agi_callerid"] . "', '" . $record_file . "')";
$insert_result = mysql_query($query, $mySql);
$agi->stream_file($record_file);
if (!$result)
{
die("Error " . mysql_errno() . " : " . mysql_error());
}
}
else
{
//Timout
$agi->goto("redial_blm272","t",1);
}
}
elseif ($whereto['result'] == 3) //check messages from doctor
{
$testFile = "/home/blm272/asterisk_sounds/voicemail1197263266vm_blm272.wav";
$agi->stream_file($testFile);
$callerID = $agi->request["agi_callerid"];
$query = "SELECT callerID, record_file, time FROM Voicemail WHERE callerID = '". $agi->request["agi_callerid"] . "' ORDER BY time DESC";
$result = sqlQuery($query, $mySql);
if (sizeof($result) >0)
{
$agi->stream_file($result[0]['record_file']);
}
if (!$result)
{
die("Error " . mysql_errno() . " : " . mysql_error());
}
}
elseif ($whereto['result'] == 4) //exit (go back to PIN prompt via the dialplan)
{
function agi_goto($con='redial_blm272',$ext='s',$pri=1)
{
$this->goto($con, $ext, $pri);
}
}
else
{
// Timeout.. Probably (or send them back to the ask for PIN section...)
mysql_close ($mySql);
$agi->goto("redial_blm272","t",1);
}
}
}
}
?>
The PHP script sets up a gateway for asterisk and mysql to work together, forming a framework of user options based on dtmf input from any standard telephone. This includes calling out directly to a doctor based on extension, directly leaving a voice mail in a specific directory, and listening to your own voice messages, with more options to come soon.
This code is not quite fully functional, but its most of the way there. Any tips or questions are also welcome.
Ultimate Man-Purse : Results
November 26, 2007
So after much sewing and cutting, here’s what Hatti and I came up with for our re-design of the man-purse:
I’m particularly happy with the ID card holder on the strap and the waterproof umbrella holder pocket. I could see myself being really happy with these features in my bag, and almost everyone we talked to seemed equally positive about these changes.
Iteration Project – The Ultimate Man-Purse
October 22, 2007
Hatti Lim and I are working on a male version of Hatti’s urban purse for our iterative assignment in design workshop. The idea is to create some sort of mechanism that eases the gesture that men (typically living in a city) have to endure, by reaching around into the back pocket to take out their wallet (presumably to show an ID//for NYU??) while carrying a any sort of messenger style bag that could potentially be making the gesture more difficult. [Assuming you need a messenger bag to fit all the things you would need if you were carrying a backpack].
First of all, we looked at why the messeger bag was preferrable to the classic bookbag. What we noticed is that the ‘bookbag’ has many flaws for the urban dweller. First of all, it is not optimal for riding in subways- it makes up a good deal of space and is situated in the chest-level area; where people have the greatest girth (as far as body mass) and provides much discomfort for those in the train if the owner does not have the forethought to take off his bag and bring it down to his/her feet (where there are typically gaps between people for it to fit). Furthermore, if they do have the forethought to do so, it usually smacks a few bystanders along its way down, since the movement for taking off a backpack lends itself to those sort of incidents. Also, accessing items in a backpack is rather awkward and uncomfortable, having either to engage in the wrap-around gumby arm only to feel around blindly for what you are looking for..or even worse, the swing around and bringing it to the front (again, probably smacking a few poor neighbors in the process). Lastly, there are cultural stigmas that we associate with backpacks as being adolescant or unprofessional, etc. (I.E, you probably would not wear your backpack to a job interview or a bar for drinks after work). All of these reasons have led us to re-adapt the sling bag instead of the bookbag.
The first idea and main focus of our bag is to make use of the strap that run diagonally along your chest, since it is the portion of the bag the user would have easiest access to. We think that by adapting an elastic mechanism inside a pocket (a feature I actually stole from the arm portion of one of my snowboarding jackets) will be a good appropriation for the wallet. Also, Roger Tsai mentioned in class that he can never listen to an ipod in his backpack bc the headphones are too short, so it should be easy to fabricate another pocket along the front of the strap for an ipod as well.
Another feature we wish to add is the ability to make it slightly modular. While Hatti focused a lot on the pocket mechanisms, I was more concerned with the safety of his laptop and how a lot of uneccessary space is wasted on days that he decides not to carry it. So, we have decided to attempt a compartmentalization process where you can attach and detach portions (just 2 for now) of your bag to give the wearble a more modular approach. Wish us luck!
Midterm
October 18, 2007
So, I did an NHL score retrieval system, using asterisk, PHP, XML, and Festival.
Here’s the code, using Shawn’s XML parser code:
#!/usr/local/bin/php -q
<?PHP
require(‘/var/lib/asterisk/agi-bin/phpagi.php’);
// Create an AGI Object
$agi = new AGI();
class Myxml
{
var $tag;
var $value;
var $attributes;
var $next;
function xml2array($xml_string)
{
$Parser = xml_parser_create();
xml_parser_set_option($Parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($Parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($Parser, $xml_string, $Xml_Values);
xml_parser_free($Parser);
$XmlClass = array();
$LastObj = array();
$NowObj = &$XmlClass;
foreach($Xml_Values as $Xml_Key => $Xml_Value)
{
$Index = count($NowObj);
if ($Xml_Value["type"] == “complete”)
{
$NowObj[$Index] = new Myxml;
if (isset($Xml_Value["tag"]))
{
$NowObj[$Index]->tag = $Xml_Value["tag"];
}
else
{
$NowObj[$Index]->tag = “”;
}
if (isset($Xml_Value["value"]))
{
$NowObj[$Index]->value = $Xml_Value["value"];
}
else
{
$NowObj[$Index]->value = “”;
}
if (isset($Xml_Value["attributes"]))
{
$NowObj[$Index]->attributes = $Xml_Value["attributes"];
}
else
{
$NowObj[$Index]->attributes = “”;
}
}
else if ($Xml_Value["type"] == “open”)
{
$NowObj[$Index] = new Myxml;
if (isset($Xml_Value["tag"]))
{
$NowObj[$Index]->tag = $Xml_Value["tag"];
}
else
{
$NowObj[$Index]->tag = “”;
}
if (isset($Xml_Value["value"]))
{
$NowObj[$Index]->value = $Xml_Value["value"];
}
else
{
$NowObj[$Index]->value = “”;
}
if (isset($Xml_Value["attributes"]))
{
$NowObj[$Index]->attributes = $Xml_Value["attributes"];
}
else
{
$NowObj[$Index]->attributes = “”;
}
$NowObj[$Index]->next = array();
$LastObj[count($LastObj)] = &$NowObj;
$NowObj = &$NowObj[$Index]->next;
}
else if ($Xml_Value["type"] == “close”)
{
$NowObj = &$LastObj[count($LastObj) - 1];
unset($LastObj[count($LastObj) - 1]);
}
}
return $XmlClass;
}
function findElementByAttribute($xmlArray,$attribute_name,$attribute_value)
{
if (sizeof($xmlArray) > 0)
{
for ($i = 0; $i < sizeof($xmlArray); $i++)
{
if (is_array($xmlArray[$i]->attributes))
{
$attributes = $xmlArray[$i]->attributes;
foreach($attributes as $name => $value)
{
//echo $name . ” ” . $value . “\n”;
if ($name == $attribute_name && $value == $attribute_value)
{
return $xmlArray[$i];
}
}
}
if (isset($xmlArray[$i]->next))
{
$possible = findElementByAttribute($xmlArray[$i]->next,$attribute_name,$attribute_value);
if ($possible !== false)
{
return $possible;
}
}
}
}
else if (isset($xmlArray[0]->next))
{
//echo “really here”;
$possible = findElementByAttribute($xmlArray[0]->next,$attribute_name,$attribute_value);
if ($possible !== false)
{
return $possible;
}
}
return false;
}
/*function findElementByTag($xmlArray,$element)
{
//echo “looking for $element”;
if (sizeof($xmlArray) > 0)
{
for ($i = 0; $i < sizeof($xmlArray); $i++)
{
//echo “here”;
//echo “does ” . $xmlArray[$i]->tag . ” == ” . $element . “\n”;
if ($xmlArray[$i]->tag == $element)
{
return $xmlArray[$i];
}
else if (isset($xmlArray[$i]->next))
{
$possible = $this->findElementByTag($xmlArray[$i]->next,$element);
if ($possible !== false)
{
return $possible;
}
}
}
}
else if (isset($xmlArray[0]->next))
{
//echo “really here”;
$possible = $this->findElementByTag($xmlArray[0]->next,$element);
if ($possible !== false)
{
return $possible;
}
}
return false;
}*/
function findElementsByTag($xmlArray,$element)
{
//echo “Looking for ” . $element . “\n”;
$return_elements = array();
if (sizeof($xmlArray) > 0)
{
//echo “Size is greater than 0\n”;
for ($i = 0; $i < sizeof($xmlArray); $i++)
{
//echo “does ” . $xmlArray[$i]->tag . ” == ” . $element . “\n”;
if ($xmlArray[$i]->tag == $element)
{
$return_elements[sizeof($return_elements)] = $xmlArray[$i];
}
else if (isset($xmlArray[$i]->next))
{
$possible = $this->findElementsByTag($xmlArray[$i]->next,$element);
if (is_array($possible))
{
$return_elements = array_merge($return_elements,$possible);
}
}
}
}
else if (isset($xmlArray[0]->next))
{
//echo “Going to next \n”;
$possible = $this->findElementsByTag($xmlArray[0]->next,$element);
if (is_array($possible))
{
$return_elements = $possible;
}
}
return $return_elements;
}
}
exec(“echo ‘Robo Man is getting the scores from totally scored dot com’ | /usr/bin/text2wave -scale 1.5 -F 8000 -o /tmp/temp.wav”);
$agi->stream_file(“/tmp/temp”);
//$scores = array();
// Using Snoopy
// http://sourceforge.net/projects/snoopy/
//curl_setopt($ch, CURLOPT_URL, “http://feeds.feedburner.com/unmediated/”);
include “Snoopy.class.php”;
$snoopy = new Snoopy;
$snoopy->fetch(“http://www.totallyscored.com/rss/team/10/”);
exec(“echo ‘Robo man has got the feed and is parsing the scores’ | /usr/bin/text2wave -scale 1.5 -F 8000 -o /tmp/temp.wav”);
$agi->stream_file(“/tmp/temp”);
// Myxml defined above
$myxml = new Myxml();
$xml = $myxml->xml2array($snoopy->results);
$scores = $myxml->findElementsByTag($xml,”title”);
// For debugging
for ($i = 0; $i < sizeof($scores); $i++)
{
$score = $scores[$i]->value;
// echo “Was $score”;
//$score = preg_replace(‘/^\*$|^NHL$/’,”",$score);
$score = str_replace(“(NHL)”,”",$score);
$score = str_replace(“*”,”",$score);
$scores[$i]->value = $score;
// echo “now ” . $scores[$i]->value;
}
//$newScores = preg_replace(‘^\*$|^NHL$’, ‘/s’, $scores);
/*
exec(“echo ‘Robo man is preparing to speak the scores’ | /usr/bin/
text2wave -scale 1.5 -F 8000 -o /tmp/temp.wav”);
$agi->stream_file(“/tmp/temp”);
for ($i = 0; $i < sizeof($scores) && $i < 1; $i++)
{
$current_score = $scores[1]->value;
exec(“echo ‘$current_score’ | /usr/bin/text2wave -scale 1.5 -F 8000 -
o /tmp/temp.wav”);
$agi->stream_file(“/tmp/temp”);
}
*/
// For debugging
//for ($i = 0; $i < sizeof($headlines); $i++)
//{
//var_dump($headlines[$i]);
//echo “\n”;
//$title = $item[$s]->value;
//$scores[sizeof($scores)] = preg_replace(‘/[^0-9a-z\s\.]/i’,”",$scores[sizeof($scores)]);
//}
//$newScores = preg_replace(‘^\*$|^NHL$’, ‘/s’, $scores);
exec(“echo ‘Robo man is preparing to speak the scores’ | /usr/bin/text2wave -scale 1.5 -F 8000 -o /tmp/temp.wav”);
$agi->stream_file(“/tmp/temp”);
for ($i = 0; $i < sizeof($scores) && $i < 1; $i++)
{
$current_score = $scores[1]->value;
exec(“echo ‘$current_score’ | /usr/bin/text2wave -scale 1.5 -F 8000 -o /tmp/temp.wav”);
$agi->stream_file(“/tmp/temp”);
}
exit(0);
?>
More to come on the development and future plans and such.
Project 2 Documentation
October 17, 2007
Here’s the link to my presentation and documentation for my observation and response assignment. I was reasonably happy with the concept, although I wish my prototyping skills were a bit better, especially since I spent so long working on this one, reworking it from scratch at least three times. Oh well. Practice always helps. Enjoy.
Ritual, Vice, or Fetish – Observations and Thoughts
October 6, 2007
While observing the interaction between books and people, I realized quickly that my design ideas would focus down to one of three general options: changing the human, changing the book, or some combination of both.
What I mean by this is pretty simple.
Changing the human involves design solutions centered around the perspective of allowing the user (humans) to interact more comfortably with the books by designing something centered around the body. Essentially, by changing the form in which the user interacts with the book. Harnesses, gloves, stands, and the like.
Changing the book, then, involves looking at the design possibilities generated from changing the actual form of the book itself. Is the current rectanglular shape really the most human-centered form? How can the text be displayed efficiently while still improving the ease of use? Is it a technological solution, or simply a form solution? Changing materials and information technologies all come into play here.
And finally, perhaps the answer lies in both worlds; the marriage of a human component and a book component creating the ultimate reading experience. Some kind of modular systemic design solution seems like a very interesting and challenging possibility.
This final design possibility seems the most promising – both the book and the human have been in their current forms for so long that it would seem a whole new interface would be necessary to affect serious change. So I am currently researching what has been done in this and closely related areas, as well as advances in relevant material and information technology, to see if an elegant solution presents itself.
Ritual, Vice, or Fetish (Design Workshop Project 2)
September 29, 2007
For this assignment we have to do some observation and needfinding surrounding a group or activity, analyze it, and offer some design solutions.
I have decided to pursue the book as my subject of scrutiny. The basic design, use, and function of books has not significantly changed since the invention of modern typesetting and binding practices. Yet people are reading less and less, and reading can still be an unwieldy process. Ever try reading lying down? Clearly something can be done besides insisting that everyone read on their computer 100% of the time.
This shall be my challenge.


