tef-animation 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+
2
+ require_relative 'BaseSequence.rb'
3
+ require_relative 'EventCollector.rb'
4
+
5
+ require_relative 'SheetSequence.rb'
6
+
7
+ module TEF
8
+ module Sequencing
9
+ class Player
10
+ def initialize()
11
+ @activeSequences = {}
12
+ @sequenceMutex = Mutex.new
13
+
14
+ @post_exec_cbs = []
15
+
16
+ @collector = EventCollector.new()
17
+
18
+ @retryCollecting = false
19
+
20
+ @playThread = Thread.new do
21
+ _run_play_thread()
22
+ end
23
+
24
+ @playThread.abort_on_exception = true
25
+ end
26
+
27
+ def after_exec(&block)
28
+ @post_exec_cbs << block if block_given?
29
+ end
30
+
31
+ def []=(key, program)
32
+ @sequenceMutex.synchronize do
33
+ if @activeSequences[key]
34
+ @activeSequences[key].teardown
35
+ end
36
+
37
+ if program.is_a? Sheet
38
+ puts "Inited sheet with start at #{Time.now()}"
39
+ program = SheetSequence.new(Time.now(), 1, sheet: program)
40
+ end
41
+
42
+ @activeSequences[key] = program
43
+ @retryCollecting = true
44
+ end
45
+
46
+ @playThread.run();
47
+
48
+ program
49
+ end
50
+
51
+ def delete(key)
52
+ @sequenceMutex.synchronize do
53
+ if @activeSequences[key]
54
+ @activeSequences[key].teardown
55
+ end
56
+
57
+ @activeSequences.delete key
58
+ @retryCollecting = true
59
+ @playThread.run();
60
+ end
61
+ end
62
+
63
+ def [](key)
64
+ @activeSequences[key]
65
+ end
66
+
67
+ private def _run_play_thread()
68
+ loop do
69
+ @sequenceMutex.synchronize do
70
+ @retryCollecting = false
71
+ @activeSequences.delete_if { |k, seq| seq.state == :torn_down }
72
+ @activeSequences.each { |k, seq| seq.append_events @collector }
73
+ end
74
+
75
+ if @collector.has_events?
76
+ @collector.wait_until_event
77
+ else
78
+ Thread.stop
79
+ end
80
+
81
+ if @retryCollecting
82
+ @collector.restart
83
+ else
84
+ @collector.execute!
85
+ @post_exec_cbs.each(&:call)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,33 @@
1
+
2
+
3
+ module TEF
4
+ module Sequencing
5
+ class Sheet
6
+ attr_accessor :start_time
7
+ attr_accessor :end_time
8
+
9
+ attr_accessor :tempo
10
+
11
+ attr_reader :setup_block
12
+ attr_reader :teardown_block
13
+
14
+ def initialize()
15
+ @start_time = 0;
16
+ @end_time = nil;
17
+
18
+ @tempo = nil
19
+
20
+ @setup_block = nil;
21
+ @teardown_block = nil;
22
+ end
23
+
24
+ def sequence(&block)
25
+ @setup_block = block;
26
+ end
27
+
28
+ def teardown(&block)
29
+ @teardown_block = block;
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,138 @@
1
+
2
+ require_relative 'BaseSequence.rb'
3
+ require_relative 'Sheet.rb'
4
+
5
+ module TEF
6
+ module Sequencing
7
+ class SheetSequence < BaseSequence
8
+ def initialize(offset, slope, **options)
9
+ super(offset, slope, **options);
10
+
11
+ raise ArgumentError, 'Sheet must be supplied!' unless options[:sheet]
12
+
13
+ @sheet = options[:sheet]
14
+
15
+ if @sheet.tempo
16
+ @slope *= @sheet.tempo / (60 * (options[:top_slope] || 1))
17
+ end
18
+
19
+ @start_time = @sheet.start_time
20
+ @end_time = @sheet.end_time
21
+
22
+ @notes = []
23
+ @latest_note_time = nil;
24
+
25
+ @subprograms = []
26
+
27
+ @active_music = []
28
+ end
29
+
30
+ def setup()
31
+ super();
32
+
33
+ if block = @sheet.setup_block
34
+ instance_exec(@opts_hash[:sheet_options], &block)
35
+ end
36
+
37
+ return unless @end_time.nil?
38
+ @end_time = (@notes[-1]&.dig(:time) || 0) + 0.01
39
+ end
40
+
41
+ def teardown()
42
+ return unless @state == :running
43
+
44
+ if block = @sheet.teardown_block
45
+ instance_eval(&block)
46
+ end
47
+
48
+ @subprograms.each(&:teardown)
49
+
50
+ @active_music.each { |pid| Process.kill('QUIT', pid); }
51
+
52
+ @subprograms = nil;
53
+ @notes = nil;
54
+
55
+ super();
56
+ end
57
+
58
+ def at(time, **options, &block)
59
+ @latest_note_time = time;
60
+
61
+ options[:sequence] = SheetSequence if options[:sheet]
62
+
63
+ if prog = options[:sequence]
64
+ options[:slope] ||= 1
65
+ options[:top_slope] = @slope
66
+
67
+ prog = prog.new(time, options[:slope], **options)
68
+
69
+ i = @subprograms.bsearch_index { |s| s.parent_start_time > prog.parent_start_time }
70
+ @subprograms.insert((i || -1), prog);
71
+
72
+ return
73
+ end
74
+
75
+ new_event = {
76
+ time: time,
77
+ code: block,
78
+ instance: self,
79
+ }
80
+
81
+ i = @notes.bsearch_index { |e| e[:time] > time }
82
+ @notes.insert((i || -1), new_event);
83
+ end
84
+
85
+ def after(time, **options, &block)
86
+ at(time + (@latest_note_time || 0) , **options, &block);
87
+ end
88
+
89
+ def play(music_piece, volume = 0.3)
90
+ play_pid = spawn(*%W{play -q --volume #{volume} #{music_piece}});
91
+
92
+ Thread.new do
93
+ @active_music << play_pid
94
+ Process.wait(@active_music)
95
+ @active_music.delete play_pid
96
+ end
97
+
98
+ play_pid
99
+ end
100
+
101
+ def kill(pid)
102
+ Process.kill('QUIT', pid);
103
+ end
104
+
105
+ def overload_append_events(collector)
106
+ i = 0
107
+ loop do
108
+ next_program = @subprograms[i]
109
+ break if next_program.nil?
110
+ break if collector.event_time &&
111
+ (collector.event_time < next_program.parent_start_time)
112
+
113
+ next_program.append_events collector
114
+
115
+ if next_program.state == :torn_down
116
+ @subprograms.delete_at i
117
+ else
118
+ i += 1
119
+ end
120
+ end
121
+
122
+ i = @notes.bsearch_index { |e| e[:time] > collector.start_time }
123
+ return unless i
124
+
125
+ note_time = @notes[i][:time]
126
+
127
+ next_note = @notes[i];
128
+ loop do
129
+ collector.add_event next_note;
130
+
131
+ next_note = @notes[i += 1]
132
+ break unless next_note
133
+ break if next_note[:time] != note_time
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,11 @@
1
+
2
+ require_relative 'Animation/Animation_Handler.rb'
3
+ require_relative 'Animation/Eyes.rb'
4
+
5
+ require_relative 'ParameterStack/Stack.rb'
6
+
7
+ require_relative 'ProgramSelection/ProgramSelector.rb'
8
+ require_relative 'ProgramSelection/SequenceCollection.rb'
9
+ require_relative 'ProgramSelection/SoundCollection.rb'
10
+
11
+ require_relative 'Sequencing/SequencePlayer.rb'
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tef-animation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - TheSystem
8
+ - Xasin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2020-05-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: tef-furcoms
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: xasin-logger
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0.1'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.1'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rubocop
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 0.77.0
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 0.77.0
56
+ description: A Ruby gem to animate and sequence the "Synth"-Line TEF modules.
57
+ email:
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - lib/tef/Animation/Animatable.rb
64
+ - lib/tef/Animation/Animation_Handler.rb
65
+ - lib/tef/Animation/Color.rb
66
+ - lib/tef/Animation/Coordinate.rb
67
+ - lib/tef/Animation/Eyes.rb
68
+ - lib/tef/Animation/Value.rb
69
+ - lib/tef/ParameterStack/Override.rb
70
+ - lib/tef/ParameterStack/Stack.rb
71
+ - lib/tef/ProgramSelection/ProgramID.rb
72
+ - lib/tef/ProgramSelection/ProgramSelector.rb
73
+ - lib/tef/ProgramSelection/SequenceCollection.rb
74
+ - lib/tef/ProgramSelection/SoundCollection.rb
75
+ - lib/tef/Sequencing/BaseSequence.rb
76
+ - lib/tef/Sequencing/EventCollector.rb
77
+ - lib/tef/Sequencing/SequencePlayer.rb
78
+ - lib/tef/Sequencing/Sheet.rb
79
+ - lib/tef/Sequencing/SheetSequence.rb
80
+ - lib/tef/animation.rb
81
+ homepage:
82
+ licenses:
83
+ - GPL-3.0
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.5.2.1
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: TEF Animation and Sequencing code
105
+ test_files: []