tef-animation 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []