rubySC 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,112 +1,106 @@
1
+ require_relative 'intervalles.rb'
2
+ require_relative 'motif.rb'
3
+
1
4
  class Melodie
2
5
 
3
- attr_reader :dessinRythmique, :dessinMelodique
6
+ include Intervalles
7
+ include Motif
8
+
9
+ attr_reader :dessinRythmique, :dessinMelodique, :analyse
4
10
 
5
11
  def initialize
6
- @dessinMelodique = creerMelodie
7
- @dessinRythmique = creerRythme @dessinMelodique
12
+
8
13
  @@nbMel=0
14
+ @analyse={}
15
+
16
+ @dessinMelodique = creerMelodie
17
+ self.analyser
18
+ @dessinRythmique = self.creerRythme
19
+
9
20
  end
10
-
11
- def mettreVoix instrument="default"
12
- @@nbMel+=1
13
- Voix.new "melodie#{@@nbMel}",
14
- ({:instrument => instrument,
15
- :degree => @dessinMelodique,
16
- :dur => @dessinRythmique})
17
21
 
18
- end
19
22
 
23
+ def enclencher instrument="default"
24
+ p "instrument sera #{instrument}"
25
+ @@nbMel+=1
26
+ Voix.new "melodie#{@@nbMel}",
27
+ ({:instrument => instrument,
28
+ :degree => @dessinMelodique,
29
+ :dur => @dessinRythmique})
20
30
  end
21
31
 
32
+ def analyser
22
33
 
23
- def creerMelodie nbNote=rand(10..30)
34
+ @analyse["motifs"]=squeletteMotivique @dessinMelodique
35
+ @analyse["intervalles"]=squeletteIntervallique @dessinMelodique
36
+
37
+ end
24
38
 
25
- Array.new (nbNote) do |note|
26
- note=[0,0,1,1,2,3,3,3,3,4,4,4,4,5,6].sample #manière un peu bourrine de "pondérer" les notes possibles
39
+
40
+
41
+ def creerRythme options={:intervalles=>1, :motifs=>1}
42
+
43
+ tmp=[]
44
+ l=lambda {|x|
45
+ unless options[x].nil?
46
+ tmp<<@analyse[x.to_s].map(&options[x].method(:*))
47
+ end}
48
+
49
+ options.each { |k,v|
50
+ l.call k }
51
+
52
+ result=[]
53
+ (@dessinMelodique.size-1).times do |i|
54
+ result << tmp.map{ |row| row[i] }.reduce(&:+)
27
55
  end
28
- end
29
56
 
30
- def transpose melodie, deCombien
31
- melodie.map { |e| e+= deCombien }
32
- end
57
+ return result
33
58
 
34
- def melodieCachee melUn, melDeux
59
+ end
35
60
 
36
- i=0
37
- tmpDeux=melUn.map {|x|
38
- if x == melDeux[i] then i +=1 ; true
39
- else false
40
- end
41
- }
42
- p tmpDeux
61
+ def vitesse
43
62
 
44
- if tmpDeux.count(true) == melDeux.size
45
- then tmpDeux
46
- else nil end
47
63
  end
48
64
 
49
- #grand moment de désarroi algorithmique
50
65
 
51
- # def creerMelodie squeletteRythmique, urMelodie=["c","b","a","g","f","e","d","c"]
66
+ #quelques raccourcis
52
67
 
68
+ def inter
69
+ intervalles @dessinMelodique
70
+ end
53
71
 
54
- # squeletteRythmique.last=3 #déjà ça c'est réglé
55
- # squeletteRythmique.reverse!
72
+ def interAbs
73
+ intervallesAbs @dessinMelodique
74
+ end
56
75
 
57
- # melodie=[]
76
+ def interRel note=0
77
+ intervallesMel @dessinMelodique, note
78
+ end
58
79
 
59
- # notePrincipale
60
- # noteSecondaire
61
- # noteOrnementale
62
80
 
81
+ def detectDoublons
82
+ @dessinMelodique.map.with_index(1) { |e, i|
83
+ unless i==@dessinMelodique.size
84
+ @dessinMelodique[i] - @dessinMelodique[i-1] == 0 ? true : false
85
+ end }[0..-2]
86
+ end
63
87
 
64
- # UnVersUn = lambda { noteOrnementale+=1}
65
- # UnVersDeux = lambda { |a| orner squeletteRythmique(a.index-noteOrnementale) }
66
- # UnVersTrois
67
- # DeuxversUn
68
- # DeuxVersDeux
69
- # DeuxVersTrois
70
- # TroisVersUn
71
- # TRoisVersDeux
72
- # TroisVErsTRois
73
88
 
74
- # niveauUn=squeletteRythmique.each_cons(2) { |a,b|
75
- # case b
76
- # when 1
77
- # case a
78
- # when 1
79
- # UnVersUn.call
80
- # when 2
81
- # UnVersDeux.call
82
- # when 3
83
- # UnVersTrois.call
84
- # end
85
- # when 2
86
- # case a
87
- # when 1
88
- # DeuxVersUn.call
89
- # when 2
90
- # DeuxVersDeux.call
91
- # when 3
92
- # DeuxVersTrois.call
93
- # end
94
- # when 3
95
- # case a
96
- # when 1
97
- # TroisVersUn.call
98
- # when 2
99
- # TroisVersDeux.call
100
- # when 3
101
- # TroisVersTrois.call
102
- # end
89
+ end
90
+
103
91
 
104
92
 
93
+ def creerMelodie nbNote=rand(10..30)
105
94
 
106
- # melodie.reverse!
95
+ Array.new (nbNote) do |note|
96
+ note=[0,0,1,1,2,3,3,3,3,4,4,4,4,5,6].sample #manière un peu bourrine de "pondérer" les notes possibles
97
+ end
98
+ end
107
99
 
100
+ def transpose melodie, deCombien
101
+ melodie.map { |e| e+= deCombien }
102
+ end
108
103
 
109
- # end
110
104
 
111
105
  def rejoindre noteDepart, noteArrivee, nbTemps
112
106
 
@@ -146,32 +140,3 @@ trille = lambda { tmp= [note-1, note, note+1, note] }
146
140
  end
147
141
 
148
142
  end
149
-
150
-
151
-
152
- #analyse rythmique basique
153
- # si intervalle grand => pt d'appui
154
- # si note conjointes et/ou similaire => plus rapide
155
- #pour l'instant, pas de note d'approche
156
-
157
-
158
- def creerRythme melodie=nil #analyse
159
-
160
- if melodie.nil?
161
- return RubySC_CONST::Rythmes.sample
162
- end
163
-
164
- rythme = intervallesMel melodie
165
- rythme.map! { |inter|
166
- case inter.abs
167
- when 1
168
- note = 1
169
-
170
- else
171
- note=2
172
- end
173
- }
174
- rythme << 4
175
-
176
- end
177
-
@@ -0,0 +1,73 @@
1
+ module Motif
2
+
3
+ def detectPattern melodie, filtreLongueur=3
4
+
5
+
6
+ mel=(convertirABC melodie).join
7
+
8
+
9
+ siz = mel.length
10
+ tmp = []
11
+
12
+ (0..siz-1).each do |n|
13
+ (n..siz-1).each do |i|
14
+ tmp << mel[n..i]
15
+ end
16
+ end
17
+ tmp.to_set
18
+
19
+ result=Hash.new
20
+ tmp.each_with_index { |e, i|
21
+ result[tmp[i]]=(mel.scan /#{tmp[i]}/).size
22
+ }
23
+
24
+
25
+ return result.select { |k,v| k.size>=filtreLongueur and v > 1}
26
+
27
+ end
28
+
29
+ def convertirABC melodie, setChiffres=['c','d','e','f','g','a','b','c']
30
+
31
+ toutDansOctave melodie
32
+ return melodie.map { |e|
33
+ e= setChiffres[e]
34
+ }
35
+ end
36
+
37
+ def squeletteMotivique melodie
38
+
39
+ mel=(convertirABC melodie).join
40
+ patterns=detectPattern melodie, 1
41
+
42
+ #on met en exergue les plus longs patterns qui se répètent
43
+ patterns=patterns.keys.group_by(&:size).reverse_each { |k,v|
44
+ v.each {|i|
45
+ mel.gsub!(/#{i}/, (k.to_s)*i.size)
46
+ }
47
+ }
48
+
49
+ mel.gsub!(/[^\d]/, '0')
50
+
51
+ return mel.chars.map(&:to_i)
52
+
53
+ end
54
+
55
+
56
+ # transforme une melodie reduite autour de quelques valeurs neg et pos
57
+ # en une melodie uniquement positive
58
+ # RQ : on ne transforme pas 7 en "0" !!
59
+ def toutDansOctave grille, modulo=7
60
+
61
+ return grille.map { |e|
62
+ if e > modulo and e > 0
63
+ e-(modulo * (e/modulo))
64
+ elsif e < 0 and e > modulo
65
+ (modulo * (e/modulo))-e
66
+ else
67
+ e.abs
68
+ end
69
+ }
70
+
71
+ end
72
+
73
+ end
@@ -9,18 +9,6 @@ module RubySC_CONST
9
9
  ## Quelques constantes, notamment pour les rythmes, c'est toujours
10
10
  ## plus pratique
11
11
 
12
- ## Je n'ai mis que les rythmes qui me semblaient
13
- ## les plus connus
14
- Rythmes = []
15
-
16
- ## Rythmes à 3 notes
17
- Rythmes << Pavanne=[2,1,1]
18
- Rythmes << Syncopette=[1,2,1]
19
-
20
- Rythmes << Sicilienne=[3,1,2]
21
- Rythmes << Chabada=[3,2,1]
22
-
23
- Rythmes << Tresillo=[3,3,2]
24
12
 
25
13
  #########
26
14
 
@@ -143,31 +131,3 @@ module Echelle
143
131
  end
144
132
 
145
133
  end
146
-
147
- module Rythme
148
-
149
- def self.Tempo vitesse
150
- SC.send "TempoClock.default.tempo = #{vitesse}"
151
- end
152
-
153
- ## s'occupe du premier chiffre de la propriété "dur", c-à-d la vitesse
154
- def self.mesure mesure, *voix
155
- voix.each do |v|
156
- tmp = SC.listeVoix[v.to_s].dur
157
- tmp[0] = mesure
158
- SC.set true, ({ "dur" => tmp }), v
159
- end
160
- end
161
-
162
- ## s'occupe du deuxième chiffre de la propriété "dur", c-à-d la
163
- ## gestalt rythmique.
164
-
165
- def self.formule formule, *voix
166
- voix.each do |v|
167
- tmp = SC.listeVoix[v.to_s].dur
168
- tmp[1] = formule
169
- SC.set true, ({ "dur" => tmp }), v
170
- end
171
- end
172
-
173
- end
@@ -0,0 +1,82 @@
1
+ module Rythme
2
+
3
+
4
+ ## Je n'ai mis que les rythmes qui me semblaient
5
+ ## les plus connus
6
+ Rythmes = []
7
+
8
+ ## Rythmes à 3 notes
9
+ Rythmes << Pavanne=[2,1,1]
10
+ Rythmes << Syncopette=[1,2,1]
11
+
12
+ Rythmes << Sicilienne=[3,1,2]
13
+ Rythmes << Chabada=[3,2,1]
14
+
15
+ Rythmes << Tresillo=[3,3,2]
16
+
17
+
18
+ def funkyser
19
+
20
+ #replace [cll] par betedecll
21
+ end
22
+
23
+ def calculDernierTemps formuleRythmique, nbMesure=4
24
+
25
+ tmp=formuleRythmique.reduce(&:+)
26
+ lastValue=0
27
+ if tmp%nbMesure !=0
28
+ until tmp%nbMesure==0
29
+ lastValue+=1
30
+ tmp+=lastValue
31
+ end
32
+ end
33
+ return formuleRythmique << lastValue
34
+ end
35
+
36
+
37
+ def creerRythme melodie=nil #analyse
38
+
39
+ if melodie.nil?
40
+ return RubySC_CONST::Rythmes.sample
41
+ end
42
+
43
+ rythme = intervallesMel melodie
44
+ rythme.map! { |inter|
45
+ case inter.abs
46
+ when 1
47
+ note = 1
48
+
49
+ else
50
+ note=2
51
+ end
52
+ }
53
+ rythme << 4
54
+
55
+ end
56
+
57
+
58
+ def self.tempo vitesse
59
+ SC.send "TempoClock.default.tempo = #{vitesse}"
60
+ end
61
+
62
+ ## s'occupe du premier chiffre de la propriété "dur", c-à-d la vitesse
63
+ def self.mesure mesure, *voix
64
+ voix.each do |v|
65
+ tmp = SC.listeVoix[v.to_s].dur
66
+ tmp[0] = mesure
67
+ SC.set true, ({ "dur" => tmp }), v
68
+ end
69
+ end
70
+
71
+ ## s'occupe du deuxième chiffre de la propriété "dur", c-à-d la
72
+ ## gestalt rythmique.
73
+
74
+ def self.formule formule, *voix
75
+ voix.each do |v|
76
+ tmp = SC.listeVoix[v.to_s].dur
77
+ tmp[1] = formule
78
+ SC.set true, ({ "dur" => tmp }), v
79
+ end
80
+ end
81
+
82
+ end
@@ -1,3 +1,3 @@
1
1
  module RubySC
2
- VERSION = "0.6.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -4,8 +4,8 @@
4
4
 
5
5
  class Voix
6
6
 
7
- attr_accessor :information, :degree, :octave, :marche, :scale, :amp, :instrument, :name
8
- attr_reader :dur
7
+ attr_accessor :information, :degree, :octave, :marche, :scale, :amp, :instrument, :name
8
+ attr_reader :adsr, :dur
9
9
  def initialize nom=nil, options={}
10
10
 
11
11
  @information=nil ## cette information sert juste à stocker tout ce
@@ -23,7 +23,15 @@ class Voix
23
23
 
24
24
  SC.listeVoix[@name]=self
25
25
 
26
- self.setDuree options["dur"]
26
+ @information="en pause \n"
27
+ self.setDuree options[:dur]
28
+
29
+ @adsr=[]
30
+ if options[:adsr].nil?
31
+ then self.setADSR 0.2,1,0.9,0.4
32
+ else
33
+ selfADSR options[:adsr]
34
+ end
27
35
 
28
36
  if options[:degree].nil?
29
37
  then @degree=Array.new(rand(1..5)) do |x| x=rand(12) end
@@ -31,62 +39,67 @@ class Voix
31
39
  @degree=options[:degree]
32
40
  end
33
41
 
34
- if options["octave"].nil?
42
+ if options[:octave].nil?
35
43
  then @octave=4
36
44
  else
37
- @octave=options["octave"]
45
+ @octave=options[:octave]
38
46
  end
39
47
 
40
- if options["scale"].nil?
48
+ if options[:scale].nil?
41
49
  then @scale = "major"
42
50
  else
43
- @scale=options["scale"]
51
+ @scale=options[:scale]
44
52
  end
45
- if options["amp"].nil?
53
+ if options[:amp].nil?
46
54
  then @amp = "Pwhite(0.2,0.8)"
47
55
  else
48
- @amp=options["amp"]
56
+ @amp=options[:amp]
49
57
  end
50
58
 
51
- if options["instrument"].nil?
59
+ if options[:instrument].nil?
52
60
  then @instrument = "default"
61
+ p "pan!"
53
62
  else
54
- @instrument=options["instrument"].to_s
63
+ self.setInstrument options[:instrument]
55
64
  end
56
65
 
57
66
  if options[:dur]
58
67
  self.setDuree options[:dur]
59
68
  end
60
- self.setMarche options["marche"]
69
+
61
70
  SC.updateScore
62
71
 
63
72
  end
64
73
 
65
- def set options
66
- options.each do |key, value|
67
- if value.is_a? Symbol
68
- value=value.to_s
69
- end
70
- case key
71
- when "dur"
72
- self.setDuree value
73
- when "marche"
74
- self.setMarche value
75
- else
76
- self.instance_variable_set "@#{key}", value
77
- end
78
- end
74
+
75
+ def setADSR atk, dec, sus, rel
76
+
77
+ @adsr=[(atk/1.0), (dec/1.0), (sus/1.0), (rel/1.0)]
79
78
  SC.updateScore
79
+
80
80
  end
81
81
 
82
- def setMarche intervalles
83
- if intervalles.nil?
84
- @root=0
82
+ def setInstrument instrument
83
+
84
+ if instrument.is_a? Symbol
85
+ @information = "le sample utilisé actuellement est #{instrument} \n"
86
+ SC.sample instrument.to_s
87
+ @instrument="sampler"
85
88
  else
86
- @root="Pstutter(#{self.degree.size}, Pseq(#{intervalles}, inf))"
87
- end
89
+ @instrument=instrument
90
+ end
91
+
88
92
  end
89
93
 
94
+
95
+ # def setMarche intervalles
96
+ # if intervalles.nil?
97
+ # @root=0
98
+ # else
99
+ # @root="Pstutter(#{self.degree.size}, Pseq(#{intervalles}, inf))"
100
+ # end
101
+ # end
102
+
90
103
  def setDuree (duree)
91
104
 
92
105
  if duree.nil?
@@ -127,9 +140,9 @@ class Voix
127
140
  end
128
141
 
129
142
  def play
143
+ SC.updateScore
130
144
  SC.play @name
131
- @information="en train de jouer".colorize (:blue)
132
-
145
+ @information="en train de jouer"
133
146
  end
134
147
 
135
148
  end