Proyecto Piano3DLT
~~~~~~~~~~~~~~~~~~
Prototype "modelosteclas"
Draw a piano keyboard and hand in pyramidal perspective,
with rotation and panning control, and "move" a midi file
End user has full control over:
- two axis rotation, though mouse dragging
- camera opening angle, through mouse wheel
Version 0.3.6
Changelog from 0.3.5:
- do some code and comments minor cleanup
- really code angle calculation from MIDI events, but not
using piece-wise-linear, but making instantaneous
key pressing and releasing
Changelog from 0.3.4:
- Calculate each frame's key depression angle from MIDI events
Originally wishing to calculate those angles
as piece-wise linear function, with a minimum of 0,
"maximun" -PI/64, starting to depress a fixed number of
MIDI ticks before NOTE_ON event, and starting to lift
the same fixed number of ticks before NOTE_OFF event.
Now, that objective is marked PENDING (see 0.3.5 changelog).
Initially, nor calculating those ticks before as a function
of velocity or aftertouch, neither calculating possible
interaction between succesive and time-next pressing of the
same key. Already thinkinh about future interpolating
"time-zoom" when very slow motion movement is required.
Changelog from 0.3.3:
- fix key depression angle index just before rotation
- fix initial A key shape
- add cool effect in key depression angle
- load MIDI file bwv577.mid (located in sketch directory ) NOTE_ON/OFF messages
- set static pieceTotalTime and midiTotalTicks for that piece, not from midi header
Changelog from 0.3.2:
- pressedKeyAngle: array of key depression angle, starting in A0 -> C8
- keyType: black or white keys location and order
- remove physical unused keyboard parameters until needed again
- arranging and grouping of parameters and variables
- enlarge reference axis
- keyLocation: octave key position data; still no actual algorithm change
Changelog from 0.3.1:
- define frames, total time and update time slider
- key rotation: remove D key rotation and set frame based key rotation
Changelog from 0.3.0:
- add time slider in serparate window (from controlp5 library examples)
Changelog from 0.2.3:
- add primitive left hand model
- remove toolbar and time slide
Changelog from 0.2.2:
- add bottom toolbar and experimental time slide
- experimental "pulsation" (rotation) of all D keys
Changelog from 0.2.1:
- position change with left button, angle change with right
- experimental "pulsation" (rotation) of all D keys
Changelog from 0.2.0:
- draw 5 octaves and adjust initial
Changelog from 0.1.1:
- code and comments translated into english
/
/*********************
import libraries *
/
/* control window */
import controlP5.*;
/* MIDI file reading */
import javax.sound.midi.Sequencer;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.InvalidMidiDataException;
import java.io.IOException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Track;
import javax.sound.midi.ShortMessage;
/**************************************************************
point of view and near parameters
/
/* field of view */
float fov = PI/2;
/* X angle of scene rotation */
float angleX=0;
float previousAngleX=angleX;
/* Y angle of scene rotation */
float angleY=PI/3+PI/2;
float previousAngleY=angleY;
/* X scene pan */
float positionX=0;
float previousPositionX=positionX;
/* Y scene pan */
float positionY=0;
float previousPositionY=positionY;
/* auxiliary variables for angle rotation when dragging */
boolean locked=false;
int baseY;
int difY;
int baseX;
int difX;
/***********************************
Hand parameters and variables *
/
/* hand model parameters, finger numbering starts with thumb=0 */
/* horizontal angles */
/* thumb first */
/* initialise fingers slightly (bout 11ยบ) flexed */
float[] rightHandFingerHorizAngle = {
-PI/16, -PI/16, -PI/16, -PI/16, -PI/16
};
float[] leftHandFingerHorizAngle = {
-PI/16, -PI/16, -PI/16, -PI/16, -PI/16
};
/* vertical angles, "upper" angles first */
float[][] rightHandFingerVertAngle = {
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16}
};
float[][] leftHandFingerVertAngle = {
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16},
{ -PI/16, -PI/16, -PI/16, -PI/16, -PI/16}
};
/* hand dimensions, thumb=0, segment most near to palm=0 */
/* initially assume symmetric hands */
float[][] fingerSegmentWidth = {
{0,0,0}, /* initially ignore thumb */
{20,19,18},
{20,19,18},
{19,18,17},
{16,14,15},
};
float[][] fingerSegmentHeight = {
{0,0,0}, /* initially ignore thumb */
{20,17,15},
{19,19,15},
{18,18,15},
{16,15,14},
};
float[][] fingerSegmentLength = {
{0,0,0}, /* initially ignore thumb */
{50,30,20},
{55,40,25},
{55,35,23},
{50,25,20},
};
/***************************************
Keyboard parameters and variables *
/
/* reference location for keys
starting in C# respect to C
and endding in next octave C
respect to this octave's last B
/
float[] keyLocation = {
12.0, /* C# */
10.0, /* D */
19.0, /* D# */
3.0, /* E */
22.0, /* F */
10.5, /* F# */
11.5, /* G */
15.5, /* G# */
6.5, /* A */
20.5, /* A# */
1.5, /* B */
22.0 /* C */
};
String[] keyType = {
"w", /* C */
"b", /* C# */
"w", /* D */
"b", /* D# */
"w", /* E */
"w", /* F */
"b", /* F# */
"w", /* G */
"b", /* G# */
"w", /* A */
"b", /* A# */
"w", /* B */
};
/* first key in standard 88 key keyboard */
int initialKey = 9;
/******************************************
time/frames parameters and variables *
/
/* time and frames, in seconds */
float pieceTotalTime = 172; /* for bwv577 while we learn how to read midi header */
int theFrameRate=30;
int pieceTotalFrames = (int) (pieceTotalTime*theFrameRate);
int nowFrame=0;
int midiTotalTicks=123444 + 1; /* for bwv577 while we learn how to read midi header */
/******************************
key rotation in each frame *
to be calculated from midi *
file
/
ArrayList allFramesKeyAngles = new ArrayList();
/* initially, a fixed value, not derived from velocity */
/* time taken for the key to be pressed from angle 0 to max angle */
int attackTimeTicks=30;
/* ticks taken for the key to be restored to rest position */
int releaseTimeTicks=30;
/**********************************************
control windows parameters and variables *
/
ControlP5 controlP5;
ControlWindow controlWindow;
Controller mySlider;
public int sliderValue = 40;
/***********************
MIDI file variables *
/
ArrayList pieceNotes;
/**************************************************************
environment setup
/
void setup() {
size(800, 600, P3D);
frameRate(theFrameRate);
/* control elements in separate window */
controlP5 = new ControlP5(this);
controlP5.setAutoDraw(false);
controlWindow = controlP5.addControlWindow("controlP5window",100,100,400,200);
controlWindow.hideCoordinates();
controlWindow.setUpdateMode(ControlWindow.ECONOMIC);
controlWindow.frameRate(1);
controlWindow.setDrawBackground(false);
controlWindow.setBackground(color(40));
mySlider = controlP5.addSlider("sliderValue",0,pieceTotalFrames,40,40,100,10);
mySlider.setWindow(controlWindow);
/* define function for mouse wheel */
addMouseWheelListener(new java.awt.event.MouseWheelListener() {
public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) {
mouseWheel(evt.getWheelRotation());
}});
/* load MIDI file, initially at 30 BPM, because we don't know the actual rate! */
pieceNotes = loadMidi("bwv577.mid", 30.0);
/* reserve space for rotation vectors for all frames */
int reservedFrames = reserveRotationVectors();
println("Reserved frames: "+ reservedFrames);
/* loop through chronologic note events and set key rotation angles */
int assignedNotes = assignRotationVectors();
println("Assigned Notes: "+ assignedNotes);
}
/* reserve space for key rotation vectors for all frames */
int reserveRotationVectors() {
int f;
for (f=0; f
Source code: modelosteclas_v0_3_6
Built with Processing