// Persistence of Vision Ray Tracer Scene Description File
// File: random-music.pov
// Vers: 3.6
// Desc: create lilypond file with Pov-Ray
// Date: 3/06/2007
// Auth: Martial Rameaux
//
// put this 3 lines in your povscene.ini file
// +orandom-povImage.png +fn 
// Pre_Scene_Command="time.bat" 
// Post_Scene_Command="makescore.bat" 
//--------------------------------------------------------------------
#declare Instrument_1= "\"trumpet\""
#declare Instrument_2= "\"pizzicato strings\""
#declare Instrument_3= "\"electric bass (finger)\""
//--------------------------------------------------------------------
#version 3.6
global_settings { 
        assumed_gamma 2.2 
        noise_generator 1 
}
#include "colors.inc"
//--------------------------------------------------------------------
background {rgb 1} 
//--------------------------------------------------------------------
// Switch
#declare Render_Image=1;
#declare use_Eps_Tag_image=1;
#declare Nbre_de_notes = 65;
#declare Make_LilyPond_file=1;

#declare MusicFileName = "random-lyMusic.ly"    //sufix ly
#declare ImageFileName = "random-povImage.eps"  //sufix eps
//---------------------------------------------------------------------
// Notes and Key Array 
//----------------------------------------------------------------------
#declare NotesArray= array[14] {"g'","gis'","a'","bes'","r","c'","des'","d'","r","es'","e'","f'","fis'","b'"}    
#declare DimNotes= dimension_size( NotesArray, 1 );    
                                                                                                                 
#declare PatternArray=array[7]{ pigment{agate},pigment{crackle},pigment{leopard},pigment{onion},pigment{spiral2 7},pigment{wood},pigment{cells}} 
#declare DimPattern= dimension_size( PatternArray, 1 );    

//----------------------------------------------------------------------                                
// Random macros
//----------------------------------------------------------------------
#if(file_exists("time.txt"))      
    #fopen  fGraine  "time.txt" read   // ouverture du fichier Graine en mode lecture
    #read  (fGraine,Graine,Mult)        // lecture du nombre alléatoire
    #fclose fGraine                    // fermeture du fichier Seme en mode lecture
    #else #declare Graine=1;  #declare Mult=1; 
#end

#declare Seed = Graine/Mult*10000;

#macro Rand(Dim)
        #local Sortie= abs(Dim-(rand(Rd)*Dim));
        #debug  concat ("--------------------\n R : "str(Sortie,0,6),"\n")
        Sortie
#end
 
#macro Random(S)
        #local Rd=seed(S);
        #local R=rand(Rd);     
        R
#end

#declare Rd=seed(Seed); 
//----------------------------------------------------------------------console Control 
#debug  concat ("------------------------\n THE NOTE IS : " NotesArray[Rand(DimNotes)],"\n")
//----------------------------------------------------------------------

//RANDOMIZE TIME
#macro TimeNote() 
        #local TmpRand = 1-Rand(2);
        #if( TmpRand < 0.5 ) 
               #declare T= "8"; 
            #else  
               #declare T= "4";
        #end 
        T
#end


#macro TimeNote2(Seuil) 
        #local TmpRand = 1-Rand(2);
        #if( TmpRand < Seuil ) 
               #declare T= "8"; 
            #else  
               #declare T= "2";
        #end 
        T
#end

#macro TimeTuplet() 
        #local TmpRand = Rand(2);
        #if( TmpRand < 1.5 ) 
               #declare T= "4"; 
             #else  
                #declare T= "8";
        #end 
        T
#end

//Randomize Key
#macro RandKey() 
        #local TmpRand = Rand(2);
        #if( TmpRand < 1.9 ) 
                #declare Key = concat ("\\key c \\major ");
            #else 
                #declare Key = concat ("\\key c \\minor ");
        #end 
#end


//Randomize Time
#declare Randtmp = Rand(2);
#switch( Randtmp ) 
         #range (0,1)
                #declare Time= concat ("\n\\time 4/4 \n"); 
             #break 
         #range (1,1.8)      
               #declare Time= concat ("\n\\time 6/8 \n"); 
             #break 
         #else
         #declare Time= concat ("\n\\time 3/4 \n"); 
#end 

//-----------------------------------------------------------
// THE LILYPOND FILE
//-----------------------------------------------------------
#if(Make_LilyPond_file)
#fopen f_ly  MusicFileName  write // create lilypond file

//HEAD AND PARPER----------------------------------------------
#write (f_ly,concat ("\\version \"2.12.0\"\n"))
#write (f_ly,concat ("#(set-global-staff-size 16)\n"))

#write (f_ly,
concat ("\\header{ 
title=\"Random's music'serial\"
composer=\"BandRand : povray.3.6\"  
arranger=\"Editor : LilyPond\"\n"
))

#if(use_Eps_Tag_image) 
    #write (f_ly,concat ( "Img= \\markup { \\epsfile #0 #60 #\""ImageFileName"\" }\n"))
    #write (f_ly,concat ( "tagline = \\markup { \\center-column { \\Img \"Pov-Ray Random music engraved by LilyPond 2.12.0\" }}\n}"))
#else
    #write (f_ly,concat ( "tagline = \"Pov-Ray Random music engraved by LilyPond 2.12.0\" \n}"))
#end
#write (f_ly,concat ("\n\\paper{ #(set-paper-size \"a4\") indent = 0\\mm line-width= 130\\mm page-count = #1 }\n\n"))

//Global------------------------------------------------------
RandKey() //Randomise Key
#write (f_ly,
concat ("Global = { 
\\override Score.BarNumber #'padding = #2
\\override Score.MetronomeMark #'padding = #3
\\tempo 4=120\n", Key,Time,"
}\n" ))

//Voice One----------------------------------------------------
#write (f_ly,concat ("MusI = \\new Voice 
\\with { \\remove \"Note_heads_engraver\"  \\consists \"Completion_heads_engraver\" \\remove \"Forbid_line_breaks_engraver\"}"
))
#write (f_ly,
concat ("{\n\\set Staff.midiInstrument = ",Instrument_1," \n\\clef \"G\"\n"))
#declare  i =0; 
#while ( i < Nbre_de_notes ) //Randomize Note
    #if( Rand(1) < 0.98 ) 
            #declare Note = concat (NotesArray[Rand(DimNotes)]TimeNote2(0.7));//concat (NotesArray[Rand(DimNotes)]TimeArray[Rand(DimTime)]);//#debug concat(Note,"\n")
      #else 
         #declare Tt = TimeTuplet();  
         #declare Note = concat ("\\times 2/3 { ",NotesArray[Rand(DimNotes)], Tt," ",NotesArray[Rand(DimNotes)], Tt," ",NotesArray[Rand(DimNotes)], Tt," }" );
    #end
    #write (f_ly,Note," ") 
  
    #if( mod(i,20) = 1 ) #write (f_ly,"\n") #end // new line
    #local i = i+1.30;
#end
#write (f_ly,"\\stopStaff\n}\n\n")


//Second Voice---------------------------------------------------
#write (f_ly,
concat (
"MusII = \\new Voice = \"V\"  
\\with { \\remove \"Note_heads_engraver\"  \\consists \"Completion_heads_engraver\" \\remove \"Forbid_line_breaks_engraver\"}"
))
#write (f_ly,"{\n\\set Staff.midiInstrument = ",Instrument_2," \\clef \"G\"\n")

#declare  i =0; 
#while ( i < Nbre_de_notes ) //Randomize Note
    #if( Rand(1) < 0.95 ) 
            #declare Note = concat (NotesArray[Rand(DimNotes)]TimeNote());//concat (NotesArray[Rand(DimNotes)]TimeArray[Rand(DimTime)]);//#debug concat(Note,"\n")
      #else 
         #declare Tt = TimeTuplet();  
         #declare Note = concat ("\\times 2/3 { ",NotesArray[Rand(DimNotes)], Tt," ",NotesArray[Rand(DimNotes)], Tt," ",NotesArray[Rand(DimNotes)], Tt," }" );
    #end
    #write (f_ly,Note," ") 
  
    #if( mod(i,20) = 1 ) #write (f_ly,"\n") #end // new line
    #local i = i+1;
#end
#write (f_ly,"\\stopStaff\n}\n\n")


//Third Voice---------------------------------------------------------
#write (f_ly,concat ("MusIII = \\new Voice 
\\with { \\remove \"Note_heads_engraver\"  \\consists \"Completion_heads_engraver\" \\remove \"Forbid_line_breaks_engraver\"}"
))
#write (f_ly,"{\n\\set Staff.midiInstrument = ",Instrument_3," \n\\clef \"F\" \n")

#declare  i =0; 
#while ( i < Nbre_de_notes ) //Randomize Note
    #if( Rand(1) < 0.95 ) 
            #declare Note = concat (NotesArray[Rand(DimNotes)]TimeNote2(0.4));//concat (NotesArray[Rand(DimNotes)]TimeArray[Rand(DimTime)]);//#debug concat(Note,"\n")
      #else 
         #declare Tt = TimeTuplet();  
         #declare Note = concat ("\\times 2/3 { ",NotesArray[Rand(DimNotes)], Tt," ",NotesArray[Rand(DimNotes)], Tt," ",NotesArray[Rand(DimNotes)], Tt," }" );
    #end
    #write (f_ly,Note," ") 
  
    #if( mod(i,20) = 1 ) #write (f_ly,"\n") #end // new line
    #local i = i+1.30;
#end
#write (f_ly,"\\stopStaff\n}\n\n")

//STAFFs--------------------------------------------------------------- 
#write (f_ly,
concat ( 
"Musique = \\new ChoirStaff << 
{ \\Global \\MusI }
{ \\Global \\MusII }
{ \\Global  \\transpose c c, \\MusIII }
>>\n"
))

//SCORE----------------------------------------------------------------- 
#write (f_ly,concat ("\n\\score{\n \\Musique\n \\layout{}\n \\midi{}\n}"))

#fclose f_ly 
#end //Make_LilyPond_file
//End lilypond file

//----------------------------------------------------------------------
// Image according to Tomasz Sowinski
//----------------------------------------------------------------------
#if(Render_Image)
light_source { <1000, 1000, 2000> color White }
light_source { <1000, 1000,-2000> color White }

// the notes give the color 
#declare Sd=seed(abs(asc(NotesArray[Rand(DimNotes)])));
#declare ColorA=(1-<rand(Sd),rand(Sd),rand(Sd)>);
#declare ColorB=(1-<rand(Sd),rand(Sd),rand(Sd)>);
#declare ColorC=(1-<rand(Sd),rand(Sd),rand(Sd)>);

#declare my_tex = texture
{   
    pigment 
    {
      PatternArray[Rand(DimPattern)]
      color_map 
        {   [0.10 color (ColorA-Scarlet)*1.5      ]
            [0.20 color White ]
            [0.50 color (ColorB-SlateBlue)*1.5 ]
            [0.70 color White ]
            [1.00 color Black ]
        }
        scale .5//Random(1)
    }
    finish { phong 1 phong_size 1  metallic }
}

#declare imax =abs(asc(TimeNote()))/(Rand(DimNotes)*0.5);
#declare jmax =abs(asc(TimeNote()))/(Rand(DimNotes)*asc(TimeNote())*0.5);

#declare i = 0;
#declare j = 0;
#declare r = 0.5;
#declare y0 = 1.5;
#declare y1 = 1.5;

#macro vpos(dy, aa)
    #local av = vaxis_rotate(<r, dy, 0>, y, aa);
    <av.x, av.y, av.z>
#end

#declare Blob =
blob
{
    threshold 0.8
    #while (i < imax)
        cylinder
        {
            vpos( y0,  360 * i / imax)
            vpos(-y0, (115 + 65 * cos(2 * pi * clock)) + 360 * i / imax)
            1.25, 0.45
            translate z*i*0.5
            rotate z*i*pi*Random(120)
            rotate y*i*pi*Random(30)
        }
       
        #declare i = i + 1;
    #end // while
           
    #while ( j < imax)
        cylinder
        {
            vpos( y1,  180 * j / jmax)
            vpos(-y1, (115 * cos(2 * pi * clock)) + 360 * j / jmax)
            1.25, 0.45
            translate -x*j*0.5
            rotate z*i*pi*Random(120)
            rotate y*i*pi*Random(30)
        }
        #declare j = j + 1;
    #end // while
       
    no_shadow
    scale 0.55
    texture { my_tex }

    rotate z * 30 *imax 
    rotate x * 60 *jmax
    translate y
}

#declare i = 0;
#declare Blob=
 #while (i < imax)
   object{Blob translate y rotate z*i*360/imax}
   #declare i = i + 5;
 #end

#declare BoudingBlobMax= max_extent(Blob);
#declare BoudingBlobMin= min_extent(Blob);
#declare MaxPoint = max(abs(BoudingBlobMax.x),abs(BoudingBlobMax.y),abs(BoudingBlobMax.z),abs(BoudingBlobMin.x),abs(BoudingBlobMin.y),abs(BoudingBlobMin.z));

#declare PointdeVue= MaxPoint;

camera 
{
    location PointdeVue*<1,1,1.5>
    look_at  0
    right  x*image_width/image_height
}

object{Blob} 
#end //Render_Image
//------------------------------------------------------------------
// EOF
//------------------------------------------------------------------