<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "https://www.web3d.org/specifications/x3d-3.3.dtd">
<X3D profile='Immersive'  version='3.3 xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation =' https://www.web3d.org/specifications/x3d-3.3.xsd ' >
<head>
<meta name='titlecontent='Keyboard.x3d'/>
<meta name='descriptioncontent='Synthesizer keyboard that creates a playable synthesizer keyboard. Each key on the keyboard has a sound and touch sensor associated with it. Touching a key triggers the touch sensor, which triggers the sound.'/>
<meta name='creatorcontent='David R. Nadeau'/>
<meta name='translatorcontent='Don Brutzman'/>
<meta name='createdcontent='1 July 1998'/>
<meta name='translatedcontent='2 February 2014'/>
<meta name='modifiedcontent='20 October 2019'/>
<meta name='referencecontent='originals/keybd.wrl'/>
<meta name='referencecontent=' http://www.siggraph.org/s98 '/>
<meta name='referencecontent=' http://www.siggraph.org/s98/conference/courses/18.html '/>
<meta name='referencecontent=' http://www.sdsc.edu/~moreland/courses/Siggraph98/vrml97/slides/mt0345.htm '/>
<meta name='referencecontent=' http://www.sdsc.edu/~moreland/courses/Siggraph98/vrml97/vrml97.htm '/>
<meta name='referencecontent=' https://www.web3d.org/x3d/content/examples/X3dResources.html '/>
<meta name='identifiercontent=' https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/Keyboard.x3d '/>
<meta name='generatorcontent='Vrml97ToX3dNist, http://ovrt.nist.gov/v2_x3d.html'/>
<meta name='generatorcontent='X3D-Edit, https://savage.nps.edu/X3D-Edit'/>
<meta name='licensecontent=' ../license.html'/>
</head>
<!--

to top <!-- Event Graph ROUTE Table shows event connections -->
 
<!-- Index for DEF nodes: A5, As5, B5, BlackKey, C4, C5, Cs4, D4, Ds4, E4, F4, Fs4, G4, Gs4, PitchA5, PitchAs5, PitchB5, PitchC4, PitchC5, PitchCs4, PitchD4, PitchDs4, PitchE4, PitchF4, PitchFs4, PitchG4, PitchGs4, WhiteKey

Index for Viewpoint node: Viewpoint_1
-->
<Scene>
<!-- Things to experiment with... -->
<!-- Use a Script to trigger sounds on **Mouse button down** not up. Huh, you say? Well, a TouchSensor generates a touch time event on mouse down, not up. Since means that sounds triggered by a TouchSensor seem to happen late... they happen when you release the mouse button, not when you press it. But, a TouchSensor sends a TRUE on it's isActive output on mouse down. So, you could route that into a Script node and grab the associated time stamp, then send THAT out as an event to start the sound. This will remove the lag and make sounds more responsive. -->
<WorldInfo info='"Copyright (c) 1997, David R. Nadeau"title='Synthesizer keyboard'/>
<Viewpoint description='Entry vieworientation='1.0 0.0 0.0 -0.785position='0.875 1.5 1.5'/>
<NavigationInfo headlight='false'/>
<DirectionalLight direction='1.0 -2.0 -0.5'/>
<Transform>
<Shape DEF='WhiteKey'>
<Appearance>
<Material diffuseColor='1.0 1.0 1.0'/>
</Appearance>
<Box size='0.23 0.1 1.5'/>
</Shape>
<!-- ROUTE information for C4 node:  [from touchTime to PitchC4.set_startTime ] -->
<TouchSensor DEF='C4'/>

<Sound maxBack='100.0maxFront='100.0'> </Sound>
</Transform>
<Transform translation='0.125 0.1 -0.375'>
<Shape DEF='BlackKey'>
<Appearance>
<Material diffuseColor='0.4 0.4 0.4'/>
</Appearance>
<Box size='0.2 0.1 0.75'/>
</Shape>
<!-- ROUTE information for Cs4 node:  [from touchTime to PitchCs4.set_startTime ] -->
<TouchSensor DEF='Cs4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchCs4 node:  [from Cs4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchCs4pitch='1.059'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='0.25 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for D4 node:  [from touchTime to PitchD4.set_startTime ] -->
<TouchSensor DEF='D4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchD4 node:  [from D4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchD4pitch='1.122'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='0.375 0.1 -0.375'>
<Shape USE=' BlackKey'/>
<!-- ROUTE information for Ds4 node:  [from touchTime to PitchDs4.set_startTime ] -->
<TouchSensor DEF='Ds4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchDs4 node:  [from Ds4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchDs4pitch='1.189'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='0.5 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for E4 node:  [from touchTime to PitchE4.set_startTime ] -->
<TouchSensor DEF='E4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchE4 node:  [from E4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchE4pitch='1.26'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='0.75 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for F4 node:  [from touchTime to PitchF4.set_startTime ] -->
<TouchSensor DEF='F4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchF4 node:  [from F4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchF4pitch='1.335'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='0.875 0.1 -0.375'>
<Shape USE=' BlackKey'/>
<!-- ROUTE information for Fs4 node:  [from touchTime to PitchFs4.set_startTime ] -->
<TouchSensor DEF='Fs4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchFs4 node:  [from Fs4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchFs4pitch='1.414'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='1.0 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for G4 node:  [from touchTime to PitchG4.set_startTime ] -->
<TouchSensor DEF='G4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchG4 node:  [from G4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchG4pitch='1.498'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='1.125 0.1 -0.375'>
<Shape USE=' BlackKey'/>
<!-- ROUTE information for Gs4 node:  [from touchTime to PitchGs4.set_startTime ] -->
<TouchSensor DEF='Gs4'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchGs4 node:  [from Gs4.touchTime to set_startTime ] -->
<AudioClip DEF='PitchGs4pitch='1.587'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='1.25 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for A5 node:  [from touchTime to PitchA5.set_startTime ] -->
<TouchSensor DEF='A5'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchA5 node:  [from A5.touchTime to set_startTime ] -->
<AudioClip DEF='PitchA5pitch='1.682'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='1.375 0.1 -0.375'>
<Shape USE=' BlackKey'/>
<!-- ROUTE information for As5 node:  [from touchTime to PitchAs5.set_startTime ] -->
<TouchSensor DEF='As5'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchAs5 node:  [from As5.touchTime to set_startTime ] -->
<AudioClip DEF='PitchAs5pitch='1.782'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='1.5 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for B5 node:  [from touchTime to PitchB5.set_startTime ] -->
<TouchSensor DEF='B5'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchB5 node:  [from B5.touchTime to set_startTime ] -->
<AudioClip DEF='PitchB5pitch='1.888'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
<Transform translation='1.75 0.0 0.0'>
<Shape USE=' WhiteKey'/>
<!-- ROUTE information for C5 node:  [from touchTime to PitchC5.set_startTime ] -->
<TouchSensor DEF='C5'/>

<Sound maxBack='100.0maxFront='100.0'>
<!-- ROUTE information for PitchC5 node:  [from C5.touchTime to set_startTime ] -->
<AudioClip DEF='PitchC5pitch='2.0'
  url=' "tone1.wav" "https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/tone1.wav" ' />
</Sound>
</Transform>
< ROUTE  fromNode=' C4' fromField='touchTime' toNode=' PitchC4' toField='set_startTime'/>
< ROUTE  fromNode=' Cs4' fromField='touchTime' toNode=' PitchCs4' toField='set_startTime'/>
< ROUTE  fromNode=' D4' fromField='touchTime' toNode=' PitchD4' toField='set_startTime'/>
< ROUTE  fromNode=' Ds4' fromField='touchTime' toNode=' PitchDs4' toField='set_startTime'/>
< ROUTE  fromNode=' E4' fromField='touchTime' toNode=' PitchE4' toField='set_startTime'/>
< ROUTE  fromNode=' F4' fromField='touchTime' toNode=' PitchF4' toField='set_startTime'/>
< ROUTE  fromNode=' Fs4' fromField='touchTime' toNode=' PitchFs4' toField='set_startTime'/>
< ROUTE  fromNode=' G4' fromField='touchTime' toNode=' PitchG4' toField='set_startTime'/>
< ROUTE  fromNode=' Gs4' fromField='touchTime' toNode=' PitchGs4' toField='set_startTime'/>
< ROUTE  fromNode=' A5' fromField='touchTime' toNode=' PitchA5' toField='set_startTime'/>
< ROUTE  fromNode=' As5' fromField='touchTime' toNode=' PitchAs5' toField='set_startTime'/>
< ROUTE  fromNode=' B5' fromField='touchTime' toNode=' PitchB5' toField='set_startTime'/>
< ROUTE  fromNode=' C5' fromField='touchTime' toNode=' PitchC5' toField='set_startTime'/>
</Scene>
</X3D>
<!--

to top <!-- Event Graph ROUTE Table shows event connections -->
 
<!-- Index for DEF nodes: A5, As5, B5, BlackKey, C4, C5, Cs4, D4, Ds4, E4, F4, Fs4, G4, Gs4, PitchA5, PitchAs5, PitchB5, PitchC4, PitchC5, PitchCs4, PitchD4, PitchDs4, PitchE4, PitchF4, PitchFs4, PitchG4, PitchGs4, WhiteKey

Index for Viewpoint node: Viewpoint_1
-->

Event Graph ROUTE Table entries with 13 ROUTE connections total, showing X3D event-model relationships for this scene.

Each row shows an event cascade that may occur during a single timestamp interval between frame renderings, as part of the X3D execution model.

A5
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchA5
AudioClip
set_startTime
SFTime


As5
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchAs5
AudioClip
set_startTime
SFTime


B5
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchB5
AudioClip
set_startTime
SFTime


C4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchC4
AudioClip
set_startTime
SFTime


C5
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchC5
AudioClip
set_startTime
SFTime


Cs4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchCs4
AudioClip
set_startTime
SFTime


D4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchD4
AudioClip
set_startTime
SFTime


Ds4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchDs4
AudioClip
set_startTime
SFTime


E4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchE4
AudioClip
set_startTime
SFTime


F4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchF4
AudioClip
set_startTime
SFTime


Fs4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchFs4
AudioClip
set_startTime
SFTime


G4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchG4
AudioClip
set_startTime
SFTime


Gs4
TouchSensor
touchTime
SFTime

ROUTE
event to
(1)
PitchGs4
AudioClip
set_startTime
SFTime



-->

<!-- Online at
https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/KeyboardIndex.html -->
<!-- Version control at
https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Siggraph98Course/Keyboard.x3d -->

<!-- Color legend: X3D terminology <X3dNode DEF='idName' field='value'/> matches XML terminology <XmlElement DEF='idName' attribute='value'/>
(Light-blue background: event-based behavior node or statement) (Grey background inside box: inserted documentation) (Magenta background: X3D Extensibility)
-->

to top <!-- For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints. -->