Hello,
(I am affraid my English is worth than the Google translation, apologize :()
This is my very first Prime program, and I have not yet the real Prime,
so please be kind to me.
The prime in France just begin to be selled it is difficult to find and
very expensive : 274 dollars on Amazon.
The point 3 is, to me, the most important.
Questions :
-1- to be tested on the real Prime : have to call twice CHOOSE in the main function ;
-2- to be tested on the real Prime : MOUSE never returns 5 as type ;
-3- how to add scales in ScaleList by program and save it ?
At this time have to edit the progam and construct it half tone by half tone ;
-4- it is ready for use EVAL on function stocked in ListPos(ii,5) eg KEYB_CLICK(2) for D key;
-5- have to manage a generic use of touch object List, generic construction of buttons and so on ;
-6- manage sub menu for major and minor, like the MATH -> Numbers ;
- ...
Hope the musicians will enjoy, fell free to give us ScaleList with plenty of scales and chords.
I shall try to make a touch program to make scales and chords easily, but how to save it ?
PLEASE rerplace the 3 B→R by the B->R function in the prime, don't how to put it in the forum.
Don't know why I have to put 2 CRLF ?
START COPY TO THE PRIME
// Scales and Chords for the HP Prime
// Copyright Didier STEINMETZ
// not for commercial use
// didier.steinmetz@gmail.com
// Date : july 2013
// Version beta 0.0
// Almost all in the module scope, because I plane to use the EVAL of function, like object method
// the notes name, can change for DO RE MI, can use the language environement variable
NoteNameList:={"C","C#","D","Eb","E","F","F#","G","G#","A","Bb","B"};
// create here the scales, given in half tone
// Just an example, 2 is ridiculous
ScaleList:={
{"Major",{2,2,1,2,2,2}},
{"Penta Maj",{2,3,2,2}}
};
ScaleLibList:={}; // the lib list to be displayed by CHOOSE
ScaleIndx:=1; // the index of the scale in ScaleList
SOrg:=0; // the fondamental of trhe scale
// the positions and actions of the touch objects
ListPos:={};
// return what have been touched, according to the ListPos
TouchObj()
BEGIN
local ii:=0,ll:={},ll2:={},xx:=0,yy:=0,tt:=0,found:=0;
if size(ListPos)>0 then
WHILE NOT(found) DO
ll:=MOUSE();
if size(ll(1))<>0 then
ll:=ll(1); // could use ll[i,j]
xx:=B→R(ll(1));
yy:=B→R(ll(2));
tt:=B→R(ll(5)); // would like to use the value 5, but nevr returned it ?
ii:=1; found:=0; ll2:={};
// search object in the list position, the first found is the good one,
// hence have to manage what is in front of the others
//if tt==5 then // end of click
while ii<= size(ListPos) and NOT(found) do
ll2:=ListPos(ii);
if xx>=ll2(1) and xx<=ll2(3) and yy>=ll2(2) and yy<=ll2(4) then
found:=1;
end;
ii:=ii+1;
end;
//end;
end;
END;
// ListPos(ii,5) could contain the fonction to be called via EVAL,
// tha's why the variables are in the module scope
if found then return ll2(5); end;
end;
return -1; // default or error code ...
END;
// ret the scales in halftone mod 12, given the fondamental and the scales in halftone
ScaleBuilt(SOrg,SIntvl)
BEGIN
Local SclaRes:={};
Local ii:=0,note:=0;
// if nothing in the scale then nothing
if size(SIntvl)>0 then
note:=SOrg;
SclaRes(1):=note mod 12;
For ii from 1 to size(SIntvl) do
note:=(note+SIntvl(ii)) mod 12;
SclaRes(ii+1):=note;
end;
end;
return SclaRes;
END;
// All the display is in there, to be discussed
Draw_KeyB() // ret the list of the activ positions
BEGIN
Local ii:=0,jj:=0,kk:=0,Xorg:=0,KFill:=0,OnOff:=0,LigneT:="";
Local ll:={};
// the keys width in pixels
Local WKWidth:=22, BKWidth:=11;
// the keys height in pixels
Local WKHeight:=80, BKHeight:=45;
// the White keys colors
Local WKEdge:=RGB(255,0,0),WKFill:=RGB(255,255,255);
// the Black keys colors
Local BKEdge:=RGB(0,0,0),BKFill:=RGB(0,0,0);
// the selection color
local KSelFill:=RGB(20,0,200);
// the KB origin
Local LeftKB:=6, TopKB:=10;
// the white keys list
local WKList:={0,2,4,5,7,9,11};
// the black keys list
local BKList:={1,3,-1,6,8,10};
// notes liste given in half tone modulo 12
Local ScaleNotes:={};
// the scale to be displayed
local ScaleL:=ScaleList(ScaleIndx);
// clear the screen (G0):
RECT_P(0,0,319,239,RGB(255,0,0),RGB(200,200,200));
// compute the scale notes
ScaleNotes:=ScaleBuilt(SOrg,ScaleL(2));
// the Scale title and the notes
TEXTOUT_P(ScaleL(1)+" en " + NoteNameList(SOrg+1),LeftKB,15+TopKB+WKHeight);
LigneT:="";
for ii from 1 to size(ScaleNotes) do LigneT:=LigneT + " " + NoteNameList(ScaleNotes(ii)+1); end;
TEXTOUT_P("The notes = " + LigneT,LeftKB,30+TopKB+WKHeight);
// the white first because the black are over
// the white Keys draw
OnOff:=0;
for ii from 0 to 23 do // 2 octaves
ll:={};
jj:=ii mod 12;
kk:=pos(WKList,(ii mod 12))-1;
if (ii mod 12)==SOrg then OnOff:=OnOff+1; end;
if kk>=0 then
KFill:=WKFill;
if ((ii mod 12)==SOrg) or ((OnOff==1) and (pos(ScaleNotes,(ii mod 12))>0)) then
KFill:=KSelFill;
end;
kk:=kk+ip(ii/12)*7;
Xorg:=LeftKB+kk*WKWidth;
RECT_P(Xorg, TopKB, Xorg+WKWidth, TopKB+WKHeight, WKEdge, KFill);
ll(0):=Xorg;ll(0):=TopKB;ll(0):=Xorg+WKWidth;ll(0):=TopKB+WKHeight;
//ll(0):="Key_Clic(" +jj+")";
ll(0):=jj;
ListPos(0):=ll;
end;
end;
// the black Keys draw
OnOff:=0;
for ii from 0 to 23 do
ll:={};
jj:=ii mod 12;
kk:=pos(BKList,(ii mod 12))-1;
if (ii mod 12)==SOrg then OnOff:=OnOff+1; end;
if kk>=0 then
KFill:=BKFill;
if ((ii mod 12)==SOrg) or ((OnOff==1) and (pos(ScaleNotes,(ii mod 12))>0)) then
KFill:=KSelFill;
end;
kk:=kk+ip(ii/12)*7;
Xorg:=LeftKB+(kk+1)*WKWidth-FLOOR(BKWidth/2);
RECT_P(Xorg, TopKB, Xorg+BKWidth, TopKB+BKHeight, BKEdge, KFill);
ll(0):=Xorg;ll(0):=TopKB;ll(0):=Xorg+BKWidth;ll(0):=TopKB+BKHeight;
//ll(0):="Key_Clic(" +jj+")";
ll(0):=jj;
ListPos(0):=ll;
end;
end;
// the buttons, just for demo, has to be rewriten in a function, etc.
ll:={};
RECT_P(LeftKB, 200, 50, 230, rgb(0,0,0), rgb(220,200,200));
ll(0):=LeftKB;ll(0):=200;ll(0):=50;ll(0):=230;
ll(0):=-1;
ListPos(0):=ll;
TEXTOUT_P("Scales",LeftKB+5,200);
ll:={};
RECT_P(60, 200, 110, 230, rgb(0,0,0), rgb(220,200,200));
ll(0):=60;ll(0):=200;ll(0):=110;ll(0):=230;
ll(0):=-2;
ListPos(0):=ll;
TEXTOUT_P("Quit",60+5,200);
// the Score, just a demo, To Be Done
for ii from 0 to 4 do
LINE_P(LeftKB,50+3*ii+TopKB+WKHeight,319-LeftKB,50+3*ii+TopKB+WKHeight,BKFill);
end;
RECT_P(LeftKB+20, 50+3*2+TopKB+WKHeight, LeftKB+20+4, 50+3*2+4+TopKB+WKHeight,BKFill, BKFill);
RECT_P(LeftKB+27, 50+3*2+2+TopKB+WKHeight, LeftKB+27+4, 50+3*2+4+2+TopKB+WKHeight,BKFill, BKFill);
// return the reverse because the objects has been added at the end of the list,
// because of the use of list(0):=, to add.
// other solution begin the scan by the end
ListPos:=reverse(ListPos);
END;
// returns the list of the lib of ScaleList, to be used in CHOOSE
ScaleInitLib4Choose()
BEGIN
Local LibList:={};
Local ii:=0,ll:={};
// get the lib of the Scales
For ii from 1 to Size(ScaleList) do
ll:=ScaleList(ii);
LibList(ii):=ll(1);
end;
Return LibList;
END;
// entry point, init and loop for touch and display management
EXPORT Scale_KeyB()
BEGIN
Local ii:=0,go:=0;
// init the lib for the choose
ScaleLibList:=ScaleInitLib4Choose();
go:=1;
// init the display
Draw_KeyB(); // all parameters in module scope
// loop while not quit button is pressed
While go do
SOrg:=TouchObj();
if SOrg==-2 then
go:=0; // quit
else
if SOrg== -1 then
// change the scale
SOrg:=0; // fondamental is C
// BUG ??? have to call CHOOSE twice ???
choose(ii,"Scales",ScaleLibList);
choose(ii,"Scales",ScaleLibList);
if NOT ii then
go:=0; // no scale choosen then quit
else
ScaleIndx:=ii;
end;
end;
Draw_KeyB(); // display
end;
end;
END;
Edited: 22 Oct 2013, 8:14 a.m.