
Ringtones is an interactive installation piece that generates algorithmic music based on any ten digit number dialed by a participant. Ten digits equates to ten billion unique phone numbers which means the phone is capable of creating ten billion unique pieces of music. In order to achieve this the phone's original circuitry was removed and a microcontroller was grafted into useful parts such as the keypad, hook, indicator light, and speaker. Basically, the microcontroller's program senses the state of the hook, waits for a phone number, then configures and plays the synthesis algorithm.
Ringtones has been exhibited at the 2008 Los Angeles Bent Festival, the 2008 Sound in Space Festival, and the 2009 UCSD Spring Music Festival.
Gallery
phone film crew | phone hacking | phone patron | ringtones close |
ringtones far | ringtones phone | uc installed | ucsd cpmc |
wall phone |
ringtones.cpp
1 /*============================================================================ 2 * Ringtones 3 * (c) Cooper Baker 2008 4 * [tab] is 4 spaces for this file 5 /*==========================================================================*/ 6 7 // include this header for arduino environment 8 9 10 //= PROTOTYPES =============================================================== 11 void setup( void ); 12 void loop( void ); 13 14 void composer( void ); 15 void song( void ); 16 void poll_keys( void ); 17 void dial_tone( void ); 18 void key_tone( float hertz, byte key_num ); 19 20 void tone( float hertz, float msec ); 21 void rest( float msec ); 22 23 void notewrap( int *note ); 24 void freqwrap( float *freq ); 25 26 void polytonic_scale( int note, int semitones, int iterations, float tone_msec, float pause_msec ); 27 void freq_scale( float freq, float freq_inc, int iterations, float tone_msec ); 28 void rand_freqs( float bot_freq, float top_freq, int iterations, float min_msec, float max_msec ); 29 void bounce_up( float freq, float initial_msec_length, float decrement_coeff ); 30 void bounce_down( float freq, float initial_msec_length, float decrement_coeff ); 31 void dyad_scale( int note, int interval, int scale_interval, int iterations, float msec_length ); 32 void freq_mirror( float freq, float initial_msec_length, float decrement_coeff ); 33 void num_melody( float tone_msec, float rest_msec, int octaves ); 34 35 //= VARIABLES ================================================================ 36 // These variables configure the i/o pins 37 byte key_pin[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 38 byte HOOK = 11; 39 byte SPEAKER = 12; 40 byte LED = 13; 41 42 // This array holds the state of each key 43 byte key_state[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 44 45 // More state variables below 46 byte on_hook = 0; 47 byte speaker_state = 0; 48 byte led_state = 0; 49 50 // Phone number variables 51 byte num[] = { 6,6,1, 4,7,8, 4,0,6,8 }; 52 byte num_index = 0; 53 54 // These variables are for the oscillator 55 double half_cyc_uc = 0; 56 unsigned int cycles_2x = 0; 57 58 // These are the keypad key frequencies 59 float dtmf[] = { 569.25, 476.5, 508.25, 536.75, 494.75, 526.5, 561.75, 515.25, 547, 582.25 }; 60 61 // This array defines a hertz value for each midi note 62 float midi_note[] = { 8.175799, 8.661957, 9.177024, 9.722718, 10.3, 10.913383, 11.562325, 12.25, 12.978271, 13.75, 14.567617, 15.433853, 16.351599, 17.323914, 18.354048, 19.445436, 20.601723, 21.826765, 23.124651, 24.5, 25.956543, 27.5, 29.135235, 30.867706, 32.703197, 34.647827, 36.708096, 38.890873, 41.203445, 43.65353, 46.249302, 49., 51.913086, 55., 58.27047, 61.735413, 65.406395, 69.295654, 73.416191, 77.781746, 82.406891, 87.30706, 92.498604, 97.998856, 103.826172, 110., 116.540939, 123.470825, 130.81279, 138.591309, 146.832382, 155.563492, 164.813782, 174.61412, 184.997208, 195.997711, 207.652344, 220., 233.081879, 246.94165, 261.62558, 277.182617, 293.664764, 311.126984, 329.627563, 349.228241, 369.994415, 391.995422, 415.304688, 440., 466.163757, 493.883301, 523.25116, 554.365234, 587.329529, 622.253967, 659.255127, 698.456482, 739.988831, 783.990845, 830.609375, 880., 932.327515, 987.766602, 1046.502319, 1108.730469, 1174.659058, 1244.507935, 1318.510254, 1396.912964, 1479.977661, 1567.981689, 1661.21875, 1760., 1864.655029, 1975.533203, 2093.004639, 2217.460938, 2349.318115, 2489.015869, 2637.020508, 2793.825928, 2959.955322, 3135.963379, 3322.4375, 3520., 3729.31, 3951.066406, 4186.009277, 4434.921875, 4698.63623, 4978.031738, 5274.041016, 5587.651855, 5919.910645, 6271.926758, 6644.875, 7040., 7458.620117, 7902.132812, 8372.018555, 8869.84375, 9397.272461, 9956.063477, 10548.082031, 11175.303711, 11839.821289, 12543.853516 }; 63 64 // This array keeps track of elapsed milliseconds 65 unsigned long msec[] = { 0, 0 }; 66 67 int elapsed = 0; 68 69 //= SETUP ==================================================================== 70 void 71 { 72 int i; 73 74 // sets up key pins as inputs and turns on pull-up resistors 75 for( i = 0 ; i < 10 ; i++ ) 76 { 77 pinMode( key_pin[ i ], INPUT ); 78 digitalWrite( key_pin[ i ], HIGH ); 79 } 80 81 // set hook pin to input and turn on pull-up resistor 82 pinMode( HOOK, INPUT ); 83 digitalWrite( HOOK, HIGH ); 84 85 // set up and init output pins 86 pinMode( SPEAKER, OUTPUT ); 87 pinMode( LED, OUTPUT ); 88 digitalWrite( SPEAKER, LOW ); 89 digitalWrite( LED, LOW ); 90 91 //play a 'ready' tone 92 for( i = 5000 ; i > 2000 ; i -= 333 ) 93 tone( i, 7 ); 94 for( i = 2000 ; i < 5000 ; i += 333 ) 95 tone( i, 7 ); 96 } 97 98 //= LOOP ===================================================================== 99 void 100 { 101 // this keeps track of millisecond values 102 msec[ 1 ] = msec[ 0 ]; 103 msec[ 0 ] = millis(); 104 105 // this block blinks the led every five seconds 106 if( msec[ 0 ] != msec[ 1 ] ) 107 { 108 elapsed++; 109 if( elapsed > 3933 ) 110 { 111 elapsed = 0; 112 digitalWrite( LED, 1 ); 113 delay( 66 ); 114 digitalWrite( LED, 0 ); 115 } 116 } 117 118 // poll the hook pin 119 on_hook = digitalRead( HOOK ); 120 121 while( !on_hook ) 122 { 123 // reset phone number memory 124 num_index = 0; 125 126 // acquire a ten digit phone number 127 while( num_index < 10 && !on_hook ) 128 { 129 poll_keys(); 130 on_hook = digitalRead( HOOK ); 131 if( num_index < 1 ) 132 dial_tone(); 133 } 134 135 // look for specific numbers 136 if( num[0]== 0 &&num[1]== 0 &&num[2]== 0 137 &&num[3]== 0 &&num[4]== 0 &&num[5]== 0 138 &&num[6]== 0 &&num[7]== 0 &&num[8]== 0 &&num[9]== 0 ) 139 { 140 song(); 141 } 142 else 143 { 144 rest( 500 ); 145 composer(); 146 rest( 1500 ); 147 } 148 149 // poll the hook pin 150 on_hook = digitalRead( HOOK ); 151 } 152 } 153 154 //= FUNCTIONS ================================================================ 155 156 // song() used to test settings of sound algorithms 157 void 158 { 159 bounce_up( 100, 100, 0.99); 160 } 161 162 // composer() sets algorithms' attributes and plays them 163 void 164 { 165 // increment and index variables 166 byte i, j; 167 byte a, b, c, d, e; 168 169 // this for loop acts as an index that increments through the phone number 170 for( i = 0 ; i < 10 ; i++ ) 171 { 172 // this block makes alternate indicies to get different parts of the phone number 173 a = i + 1; if( a > 9 ) a -= 9; 174 b = i + 2; if( b > 9 ) b -= 9; 175 c = i + 3; if( c > 9 ) c -= 9; 176 d = i + 4; if( d > 9 ) d -= 9; 177 e = i + 5; if( e > 9 ) e -= 9; 178 179 // this for loop plays groups of different sounds based on the phone number 180 for( j = 0 ; j <= num[ a ] ; j += 3 ) 181 { 182 // this switch chooses a series of sounds to play based on the current number 183 switch( num[ i ] ) 184 { 185 default: 186 187 case 0 : num_melody( ( num[ a ] + 4 ), ( num[ b ] + 1 ) * 2, num[ c ] * 0.5 ); 188 break; 189 190 case 1 : bounce_up( ( num[ a ] + 1 ) * 100, ( num[ b ] + 1 ) * 12, (float)( num[ c ] + 40 ) / 50 ); 191 bounce_down( ( num[ a ] + 1 ) * 1000, ( num[ b ] + 1 ) * 8, (float)( num[ c ] + 20 ) / 30 ); 192 break; 193 194 case 2 : bounce_down( ( num[ b ] + 1 ) * 1000, ( num[ c ] + 1 ) * 8, (float)( num[ d ] + 1 ) / 20 ); 195 polytonic_scale( num[ a ] + 48, num[ b ] - 4, num[ c ] + 10, ( num[ d ] + 1 ) * 3, ( num[ e ] + 1 ) * 20 ); 196 freq_mirror( ( num[ a ] + 1 ) * 150, ( num[ b ] + 1 ) * 7, (float)( num[ c ] + 20 ) / 30 ); 197 break; 198 199 case 3 : polytonic_scale( num[ a ] + 48, num[ b ] - 4, num[ c ] + 10, ( num[ d ] + 1 ) * 4, ( num[ e ] + 1 ) * 25 ); 200 freq_mirror( ( num[ b ] + 1 ) * 150, ( num[ c ] + 1 ) * 5, (float)( num[ d ] + 20 ) / 30 ); 201 break; 202 203 case 4 : freq_mirror( ( num[ b ] + 1 ) * 150, ( num[ c ] + 1 ) * 5, (float)( num[ d ] + 20 ) / 30 ); 204 dyad_scale( ( num[ b ] + 1 ) * 2 + 48, num[ c ] * 2 - 9, num[ d ] * 2 - 7, num[ e ] + 4, ( num[ a ] + 1 ) * 5 ); 205 polytonic_scale( num[ a ] + 48, num[ b ] - 4, num[ c ] + 10, ( num[ d ] + 1 ) * 3, ( num[ e ] + 1 ) * 20 ); 206 break; 207 208 case 5 : freq_scale( ( num[ a ] + 1 ) * 50, ( num[ b ] + 1 ) * 3, ( num[ c ] + 1 ) * 10, ( num[ d ] + 1 ) * 3 ); 209 dyad_scale( ( num[ b ] + 1 ) * 2 + 48, num[ c ] * 2 - 9, num[ d ] * 2 - 7, num[ e ] + 4, ( num[ a ] + 1 ) * 5 ); 210 rand_freqs( ( num[ a ] + 1 ) * 50, ( num[ b ] + 1 ) * 400, ( num[ c ] + 1 ) * 2, ( num[ c ] + 5 ) * 3, ( num[ d ] + 5 ) * 6 ); 211 break; 212 213 case 6 : freq_mirror( ( num[ b ] + 1 ) * 150, ( num[ c ] + 1 ) * 5, (float)( num[ d ] + 20 ) / 30 ); 214 polytonic_scale( num[ b ] + 32, num[ c ] - 4, num[ d ] + 11, ( num[ e ] + 1 ) * 3, ( num[ a ] + 1 ) * 20 ); 215 dyad_scale( ( num[ a ] + 1 ) * 2 + 24, num[ b ] * 2 - 9, num[ c ] * 2 - 7, num[ d ] + 4, ( num[ e ] + 1 ) * 5 ); 216 break; 217 218 case 7 : rand_freqs( ( num[ a ] + 1 ) * 50, ( num[ b ] + 1 ) * 100, ( num[ c ] + 1 ) * 2, ( num[ c ] + 10 ) * 2, ( num[ d ] + 3 ) * 6 ); 219 rand_freqs( ( num[ b ] + 1 ) * 50, ( num[ c ] + 1 ) * 250, ( num[ d ] + 1 ) * 2, ( num[ e ] + 10 ) * 2, ( num[ a ] + 3 ) * 6 ); 220 break; 221 222 case 8 : bounce_up( ( num[ a ] + 1 ) * 100, ( num[ b ] + 1 ) * 3, (float)( num[ c ] + 20 ) / 30 ); 223 freq_mirror( ( num[ a ] + 1 ) * 150, ( num[ b ] + 1 ) * 5, (float)( num[ c ] + 40 ) / 50 ); 224 bounce_down( (num[ a ] + 1 ) * 1000, ( num[ b ] + 1 ) * 3, (float)( num[ c ] + 20 ) / 30 ); 225 break; 226 227 case 9 : bounce_up( ( num[ a ] + 1 ) * 100, ( num[ b ] + 1 ) * 7, (float)( num[ c ] + 15 ) / 30 ); 228 rand_freqs( ( num[ a ] + 1 ) * 50, ( num[ b ] + 1 ) * 300, ( num[ c ] + 1 ) * 2, ( num[ c ] + 10 ) * 2, ( num[ d ] + 3 ) * 6 ); 229 break; 230 } 231 } 232 } 233 } 234 235 // looks for a pressed key 236 void 237 { 238 byte i = 0; 239 240 // this loop looks at each key 241 for( i = 0 ; i < 10 ; i++ ) 242 { 243 // if a key is pressed 244 if( !digitalRead( key_pin[ i ] ) ) 245 { 246 // debounce the switch 247 delay( 50 ); 248 249 // play a key tone 250 key_tone( dtmf[ i ], i ); 251 252 // store the key number 253 num[ num_index ] = i; 254 num_index++; 255 256 break; 257 } 258 } 259 } 260 261 // plays a tone while a key is depressed 262 void 263 { 264 // calculate microseconds per half wave cycle 265 half_cyc_uc = ( 1000000. / hertz ) * 0.5; 266 267 // turn on the led 268 digitalWrite( LED, 1 ); 269 270 // generate a tone while the key is depressed 271 while( !digitalRead( key_pin[ key_num ] ) ) 272 { 273 digitalWrite( SPEAKER, speaker_state ); 274 speaker_state = !speaker_state; 275 delayMicroseconds( (unsigned int)half_cyc_uc ); 276 } 277 278 // turn off the led 279 digitalWrite( LED, 0 ); 280 } 281 282 // plays a tone of arbitrary length 283 void 284 { 285 // calculate microseconds per half cycle of waveform 286 half_cyc_uc = ( 1000000. / hertz ) * 0.5; 287 288 // calculate number of half cycles to output 289 cycles_2x = ( msec * 1000. ) / half_cyc_uc; 290 291 // turn on the led 292 digitalWrite( LED, 1 ); 293 294 // generate the waveform 295 while( cycles_2x-- ) 296 { 297 digitalWrite( SPEAKER, speaker_state ); 298 speaker_state = !speaker_state; 299 delayMicroseconds( (unsigned int)half_cyc_uc ); 300 301 // poll the hook pin 302 on_hook = digitalRead( HOOK ); 303 } 304 305 // turn off the led 306 digitalWrite( LED, 0 ); 307 } 308 309 // plays the dial_tone 310 void 311 { 312 // sounds somewhat similar to the dtmf dialtone 313 float frequency = 371.0; 314 315 // calculate microseconds per half cycle of waveform 316 half_cyc_uc = ( 1000000. / frequency ) * 0.5; 317 318 // calculate number of half cycles to output 319 cycles_2x = ( 2 * 1000. ) / half_cyc_uc; 320 321 // generate the waveform 322 while( cycles_2x-- ) 323 { 324 digitalWrite( SPEAKER, speaker_state ); 325 speaker_state = !speaker_state; 326 delayMicroseconds( (unsigned int)half_cyc_uc ); 327 328 // poll the hook pin 329 on_hook = digitalRead( HOOK ); 330 } 331 } 332 333 // plays a rest of arbitrary length 334 void 335 { 336 // calculate length of silence 337 half_cyc_uc = ( 1000000. / 100 ) * 0.5; 338 cycles_2x = ( msec * 1000. ) / half_cyc_uc; 339 340 // rest for a bit 341 while( cycles_2x-- ) 342 { 343 if( on_hook ) 344 break; 345 delayMicroseconds( (unsigned int)half_cyc_uc ); 346 on_hook = digitalRead( HOOK ); 347 } 348 } 349 350 // wraps midi notes into midi range 351 void 352 { 353 if( *note > 127 ) *note -= 127; 354 if( *note < 0 ) *note += 127; 355 } 356 357 // wraps frequencies into human hearing range 358 void 359 { 360 if( *freq > 20000 ) *freq -= 19980; 361 if( *freq < 20 ) *freq += 19980; 362 } 363 364 // a polytonic scale of intervals 365 void 366 { 367 int i = 0; 368 for( i = 0 ; i < iterations ; i++ ) 369 { 370 if( on_hook ) 371 return; 372 tone( midi_note[ note ], tone_msec ); 373 note += semitones; 374 notewrap( ¬e ); 375 delayMicroseconds( (unsigned int)(pause_msec * 1000.) ); 376 } 377 } 378 379 // makes a linear set of incrementing frequencies 380 void 381 { 382 int i = 0; 383 for( i = 0 ; i < iterations ; i++ ) 384 { 385 if( on_hook ) 386 return; 387 tone( freq, tone_msec ); 388 freq += freq_inc; 389 freqwrap( &freq ); 390 } 391 } 392 393 // makes random frequencies in a specified range 394 void 395 { 396 int i = 0; 397 float freq_range = top_freq - bot_freq; 398 float msec_range = max_msec - min_msec; 399 float duration; 400 long int factorial = 1; 401 402 for( i = 0 ; i < 10 ; i++ ) 403 { 404 factorial *= num[i]; 405 } 406 407 randomSeed( factorial ); 408 409 for( i = 0 ; i < iterations ; i++ ) 410 { 411 if( on_hook ) 412 return; 413 duration = random( 999 ) * 0.001 * msec_range + min_msec; 414 tone( random( (int)freq_range ) + bot_freq , duration ); 415 duration = random( 999 ) * 0.001 * msec_range + min_msec; 416 rest( duration ); 417 } 418 } 419 420 // plays an ascending or descending scale of alternading dyads 421 void 422 { 423 int i; 424 int dyad; 425 426 for( i = 0 ; i < iterations ; i++ ) 427 { 428 if( on_hook ) 429 return; 430 tone( midi_note[ note ], msec_length ); 431 rest( msec_length * 0.5 ); 432 dyad = note + interval; 433 notewrap( &dyad ); 434 tone( midi_note[ dyad ], msec_length ); 435 rest( msec_length * 0.5 ); 436 note += scale_interval; 437 notewrap( ¬e ); 438 } 439 } 440 441 // increasingly shorter ascending tones tones with rests 442 void 443 { 444 float i; 445 446 for( i = initial_msec_length ; i > 1 ; i = i * decrement_coeff ) 447 { 448 if( on_hook ) 449 return; 450 tone( freq, i ); 451 rest( i ); 452 freq *= 1 + ( 1 - decrement_coeff ); 453 freqwrap( &freq ); 454 } 455 } 456 457 // increasingly shorter descending tones tones with rests 458 void 459 { 460 float i; 461 462 for( i = initial_msec_length ; i > 1 ; i = i * decrement_coeff ) 463 { 464 if( on_hook ) 465 return; 466 tone( freq, i ); 467 rest( i ); 468 freq *= decrement_coeff; 469 freqwrap( &freq ); 470 } 471 } 472 473 // frequencies moving apart from the initial frequency 474 void 475 { 476 float i; 477 float mirror_freq = freq; 478 479 for( i = initial_msec_length ; i > 1 ; i = i * decrement_coeff ) 480 { 481 if( on_hook ) 482 return; 483 tone( freq, i ); 484 rest( i ); 485 freq *= 1 + ( 1 - decrement_coeff ); 486 mirror_freq *= decrement_coeff; 487 freqwrap( &freq ); 488 freqwrap( &mirror_freq ); 489 tone( mirror_freq, i ); 490 rest( i ); 491 } 492 } 493 494 void 495 { 496 byte i, j; 497 byte duration[] = { 12, 8, 16, 6, 12, 4, 16, 6, 12, 8 }; 498 int note; 499 500 for( i = 0 ; i < octaves ; i++ ) 501 { 502 for( j = 0 ; j < 10 ; j++ ) 503 { 504 if( on_hook ) 505 return; 506 note = num[ j ] + 40 + ( 12 * i ); 507 notewrap( ¬e ); 508 tone( midi_note[ note ], tone_msec * duration[ num[ j ] ] ); 509 rest( rest_msec * duration[ 9 - num[ j ] ] ); 510 } 511 } 512 } 513 514 //= Main ======================================================================= 515 int 516 { 517 // init the arduino environment 518 init(); 519 520 // program-specific setup 521 setup(); 522 523 // infinite loop 524 spin: 525 loop(); 526 goto spin; 527 528 return 0; 529 } 530
[