sidtool 0.0.2 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c9e6e4a8741217ee0274bdb1b6fedb7f9c170bf89466b801ad8a1857a7cc59b
4
- data.tar.gz: f2c57a83771df5654ae6c5e257eeff3ec0d94ae1d9a8db94da58f5eed2e7dee8
3
+ metadata.gz: 18bb0264bfc225b9bf717f464da9e9abc46777a93d3edd5ef985244fcc7e609d
4
+ data.tar.gz: 9a9b61aee40dadb92111f5cfc3b12e85db24f37c98f33d3981244aa8e04a1097
5
5
  SHA512:
6
- metadata.gz: bf153ba88e818359ee5df8b32de316959c9215142416a29997b204cc4545210ae33efb01e0a60155c81b1251a398cfe81736e6e1dc08392cfec0396005a3278a
7
- data.tar.gz: 8533881bb398f17eb54ef530fe3bb23f24fe8bde3214c87ec994da8c35faaa10d4e372fffc99ffab3b23add8f15ce2e268150d1cfa4736afffc159c5b32d44c0
6
+ metadata.gz: d21cd9a7aa43ae31afb6173aac169182f2cf1836fa25314dfba2633c37fc5cab74fcd9ff174000e0749e9f98db4d856860110da049308c74b769b4f7cbef3084
7
+ data.tar.gz: 56423bc991f5d6e74c56205e438967fe9ad8a12c83f0955708c3c88eddb4dc6017cb2d28f1bcfd73d8d6faa73a028eb8c944fa38261d2ea3b540303f257c1645
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.5
4
+ * Bumped to mos6510 version 0.1.2 which depends on a version of mini_racer that supports
5
+ Ruby 3.1.
6
+
7
+ ## 0.0.4
8
+ * Bumped to mos6510 version 0.1.1 which depends on a version of mini_racer that can compile
9
+ and install on my machine.
10
+
11
+ ## 0.0.3
12
+ * Add midi support.
13
+
3
14
  ## 0.0.2
4
15
  * Process 15000 frames (10 minutes) instead of 1500 (half a minute) by default.
5
16
  * Only release a synth once. This fixes various sound effects that would just end up with a
data/Gemfile.lock CHANGED
@@ -1,20 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sidtool (0.0.2)
5
- mos6510 (~> 0.1.0)
4
+ sidtool (0.0.5)
5
+ mos6510 (~> 0.1.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  coderay (1.1.2)
11
11
  diff-lcs (1.3)
12
- libv8 (7.3.492.27.1-x86_64-darwin-18)
12
+ libv8-node (16.10.0.0-x86_64-darwin)
13
13
  method_source (0.9.2)
14
- mini_racer (0.2.6)
15
- libv8 (>= 6.9.411)
16
- mos6510 (0.1.0)
17
- mini_racer (~> 0.2.6)
14
+ mini_racer (0.6.2)
15
+ libv8-node (~> 16.10.0.0)
16
+ mos6510 (0.1.2)
17
+ mini_racer (~> 0.6.2)
18
18
  pry (0.12.2)
19
19
  coderay (~> 1.1.0)
20
20
  method_source (~> 0.9.0)
@@ -44,4 +44,4 @@ DEPENDENCIES
44
44
  sidtool!
45
45
 
46
46
  BUNDLED WITH
47
- 2.0.2
47
+ 2.1.4
data/README.md CHANGED
@@ -1,24 +1,36 @@
1
1
  # Sidtool
2
2
 
3
- Convert Commodore 64 SID music in the form of `.sid` files into other formats! This is still VERY
4
- much work in progress... the code is ugly and will probably create horrible results for you :-)
3
+ Convert Commodore 64 SID music in the form of `.sid` files into other formats!
5
4
 
6
- Basically, it's a massive hack made for fun and no profit.
7
-
8
- The vision, though, is to extract the actual information from `.sid` files, which are files storing
9
- music for the Commodore 64. This sounds like an easy task.
5
+ Basically, it's a massive hack made for fun and no profit. The vision, though, is to extract the
6
+ actual information from `.sid` files, which are files storing music for the Commodore 64.
10
7
 
11
8
  `.sid` files contain actual Commodore 64 machine code that writes to registers corresponding to the
12
9
  Commodore 64 sound chip, the SID (Sound Interface Device). Which means that in order to play back a
13
10
  `.sid` file like it would sound on an actual Commodore 64, you will have to simulate both the
14
11
  processor and the sound chip.
15
12
 
16
- This project does not attempt to simulate the SID chip to produce authentic sounds - lots of those
17
- players already exist - but instead has a very simple implementation that produces data that can be
18
- used to play back the songs. You know, almost as notes.
13
+ This project does not attempt to produce an authentic playback of the sounds - lots of those
14
+ players already exist - but instead lets you export a Commodore 64 song into a format that lets
15
+ you edit and experiment with the song. Want to change the instruments? Go ahead. Want to take out
16
+ parts of the song and use in other projects? You can do that. Want to just listen to your favourite
17
+ Commodore 64 song played back by a piano? Definitely do that!
18
+
19
+ ## Supported Output Formats
20
+
21
+ ### Ruby
22
+
23
+ You can get a simple Ruby file which defines a list of synths to play at certain points in time.
24
+ This can be used to play back the music in [Sonic Pi](https://sonic-pi.net) (see below), or you
25
+ can write a Ruby script to do your own post-processing.
19
26
 
20
- Currently the only output format is a Ruby file which defines a list of synths to play at certain
21
- points in time. This can be used to play back the music in [Sonic Pi](https://sonic-pi.net).
27
+ ### Midi
28
+
29
+ If you just want to listen to a `.sid` file, the easiest way is to export to midi file format and
30
+ open the file in a player such as [VLC](https://www.videolan.org/vlc/index.html). However, if you
31
+ want to further edit the result, import the file in a music editor such as GarageBand on a Mac.
32
+ Then you can use all of the tools provided by your music editor to change instruments and rearrange
33
+ the song.
22
34
 
23
35
  ## Limitations
24
36
 
@@ -46,16 +58,20 @@ Show information, like the author and number of songs in a file:
46
58
 
47
59
  $ sidtool --info <input file>
48
60
 
49
- Convert the default song from a file to a Ruby list:
61
+ Convert the default song from a `.sid` file to a midi file:
62
+
63
+ $ sidtool --out <output file> --format midi <input file>
64
+
65
+ Convert the default song from a file to a Ruby list (`--format ruby` is the default):
50
66
 
51
67
  $ sidtool --out <output file> <input file>
52
68
 
53
- The output can then be used to play back the music, for example in Sonic Pi:
69
+ The Ruby output can then be used to play back the music, for example in Sonic Pi:
54
70
 
55
71
  ```ruby
56
72
  load '<path to your output file from before>'
57
73
 
58
- previous_frame = 1
74
+ previous_frame = 0
59
75
  ::SYNTHS.each do |synth|
60
76
  current_frame = synth[0]
61
77
  frames_to_sleep = current_frame - previous_frame
data/bin/sidtool CHANGED
@@ -4,12 +4,17 @@ require 'mos6510'
4
4
  require 'optparse'
5
5
 
6
6
  DEFAULT_FRAMES_TO_PROCESS = 15000
7
+ EXPORTERS = {
8
+ 'ruby' => Sidtool::RubyFileWriter,
9
+ 'midi' => Sidtool::MidiFileWriter
10
+ }
7
11
 
8
12
  params = {}
9
13
  OptionParser.new do |parser|
10
14
  parser.banner = 'Usage: sidtool [options] <intputfile.sid>'
11
15
 
12
16
  parser.on('-i', '--info', 'Show file information')
17
+ parser.on('--format FORMAT', 'Output format, "ruby" (default) or "midi"')
13
18
  parser.on('-o', '--out FILENAME', 'Output file (Ruby array)')
14
19
  parser.on('-s', '--song NUMBER', Integer, 'Song number to process (defaults to the start song in the file)')
15
20
  parser.on('-f', '--frames NUMBER', Integer, "Number of frames to process (default #{DEFAULT_FRAMES_TO_PROCESS})")
@@ -32,6 +37,10 @@ output_file = params[:out]
32
37
  show_info = !!params[:info]
33
38
  raise 'Either provide -i or -o, or I have nothing to do!' unless output_file || show_info
34
39
 
40
+ format = params[:format] || EXPORTERS.keys.first
41
+ exporter_class = EXPORTERS[format]
42
+ raise "Invalid format: #{format}. Valid formats: #{EXPORTERS.keys.join(', ')}" unless exporter_class
43
+
35
44
  song = params[:song] || sid_file.start_song
36
45
  raise 'Song must be at least 1' if song < 1
37
46
  raise "File only has #{sid_file.songs} songs" if song > sid_file.songs
@@ -74,11 +83,5 @@ if output_file
74
83
 
75
84
  STDERR.puts("Processed #{frames} frames")
76
85
 
77
- File.open(output_file, 'w') do |file|
78
- file.puts '::SYNTHS = ['
79
- Sidtool::STATE.synths.each do |synth|
80
- file.puts synth.to_a.inspect + ','
81
- end
82
- file.puts ']'
83
- end
86
+ exporter_class.new(sid.synths_for_voices).write_to(output_file)
84
87
  end
@@ -0,0 +1,198 @@
1
+ module Sidtool
2
+ class MidiFileWriter
3
+ DeltaTime = Struct.new(:time) do
4
+ def bytes
5
+ quantity = time
6
+ seven_bit_segments = []
7
+ while true
8
+ seven_bit_segments << (quantity & 127)
9
+ quantity = quantity >> 7
10
+ break if quantity == 0
11
+ end
12
+ result = seven_bit_segments.reverse.map { |segment| segment | 128 }
13
+ result[-1] &= 127
14
+ result
15
+ end
16
+ end
17
+
18
+ TrackName = Struct.new(:name) do
19
+ def bytes
20
+ [
21
+ 0xFF, 0x03,
22
+ name.length,
23
+ *name.bytes
24
+ ]
25
+ end
26
+ end
27
+
28
+ TimeSignature = Struct.new(:numerator, :denominator_power_of_two, :clocks_per_metronome_click, :number_of_32th_nodes_per_24_clocks) do
29
+ def bytes
30
+ [
31
+ 0xFF, 0x58, 0x04,
32
+ numerator,
33
+ denominator_power_of_two,
34
+ clocks_per_metronome_click,
35
+ number_of_32th_nodes_per_24_clocks
36
+ ]
37
+ end
38
+ end
39
+
40
+ KeySignature = Struct.new(:sharps_or_flats, :is_major) do
41
+ def bytes
42
+ [
43
+ 0xFF, 0x59, 0x02,
44
+ sharps_or_flats,
45
+ is_major ? 0 : 1
46
+ ]
47
+ end
48
+ end
49
+
50
+ EndOfTrack = Struct.new(:nothing) do
51
+ def bytes
52
+ [
53
+ 0xFF, 0x2F, 0x00
54
+ ]
55
+ end
56
+ end
57
+
58
+ ProgramChange = Struct.new(:channel, :program_number) do
59
+ def bytes
60
+ raise "Channel too big: #{channel}" if channel > 15
61
+ raise "Program number is too big: #{program_number}" if program_number > 255
62
+ [
63
+ 0xC0 + channel,
64
+ program_number
65
+ ]
66
+ end
67
+ end
68
+
69
+ NoteOn = Struct.new(:channel, :key) do
70
+ def bytes
71
+ raise "Channel too big: #{channel}" if channel > 15
72
+ raise "Key is too big: #{key}" if key > 255
73
+ [
74
+ 0x90 + channel,
75
+ key,
76
+ 40 # Default velocity
77
+ ]
78
+ end
79
+ end
80
+
81
+ NoteOff = Struct.new(:channel, :key) do
82
+ def bytes
83
+ raise "Channel too big: #{channel}" if channel > 15
84
+ raise "Key is too big: #{key}" if key > 255
85
+ [
86
+ 0x80 + channel,
87
+ key,
88
+ 40 # Default velocity
89
+ ]
90
+ end
91
+ end
92
+
93
+ def initialize(synths_for_voices)
94
+ @synths_for_voices = synths_for_voices
95
+ end
96
+
97
+ def write_to(path)
98
+ tracks = @synths_for_voices.map { |synths| build_track(synths) }
99
+
100
+ File.open(path, 'wb') do |file|
101
+ write_header(file)
102
+ tracks.each_with_index { |track, index| write_track(file, track, "Voice #{index + 1}") }
103
+ end
104
+ end
105
+
106
+ def build_track(synths)
107
+ waveforms = [:tri, :saw, :pulse, :noise]
108
+
109
+ track = []
110
+ current_frame = 0
111
+ synths.each do |synth|
112
+ channel = waveforms.index(synth.waveform) || raise("Unknown waveform #{synth.waveform}")
113
+ track << DeltaTime[synth.start_frame - current_frame]
114
+ track << NoteOn[channel, synth.tone]
115
+ current_frame = synth.start_frame
116
+
117
+ current_tone = synth.tone
118
+ synth.controls.each do |start_frame, tone|
119
+ track << DeltaTime[start_frame - current_frame]
120
+ track << NoteOff[channel, current_tone]
121
+ track << DeltaTime[0]
122
+ track << NoteOn[channel, tone]
123
+ current_tone = tone
124
+ current_frame = start_frame
125
+ end
126
+
127
+ end_frame = [current_frame, synth.start_frame + (FRAMES_PER_SECOND * (synth.attack + synth.decay + synth.sustain_length)).to_i].max
128
+ track << DeltaTime[end_frame - current_frame]
129
+ track << NoteOff[channel, current_tone]
130
+
131
+ current_frame = end_frame
132
+ end
133
+
134
+ track
135
+ end
136
+
137
+ private
138
+ def write_header(file)
139
+ # Type
140
+ file << 'MThd'
141
+
142
+ # Length
143
+ write_uint32(file, 6)
144
+
145
+ # Format
146
+ write_uint16(file, 1)
147
+
148
+ # Number of tracks
149
+ write_uint16(file, 3)
150
+
151
+ # Division
152
+ # Default tempo is 120 BPM - 120 quarter-notes per minute. Which is 2 quarter-notes per second. If we then define
153
+ # 25 ticks per quarter-note, we end up with a timing of 50 ticks per second.
154
+ write_uint16(file, 25)
155
+ end
156
+
157
+ def write_track(file, track, name)
158
+ track_with_metadata = [
159
+ DeltaTime[0], TrackName[name],
160
+ DeltaTime[0], TimeSignature[4, 2, 24, 8],
161
+ DeltaTime[0], KeySignature[0, 0],
162
+
163
+ DeltaTime[0], ProgramChange[0, 1], # Triangular - maps to piano
164
+ DeltaTime[0], ProgramChange[1, 25], # Saw - maps to guitar
165
+ DeltaTime[0], ProgramChange[2, 33], # Pulse - maps to bass
166
+ DeltaTime[0], ProgramChange[3, 41] # Noise - maps to strings
167
+ ] +
168
+ track +
169
+ [
170
+ DeltaTime[0], EndOfTrack[]
171
+ ]
172
+ track_bytes = track_with_metadata.flat_map(&:bytes)
173
+
174
+ # Type
175
+ file << 'MTrk'
176
+
177
+ # Length
178
+ write_uint32(file, track_bytes.length)
179
+
180
+ file << track_bytes.pack('c' * track_bytes.length)
181
+ end
182
+
183
+ def write_uint32(file, value)
184
+ bytes = [(value >> 24) & 255, (value >> 16) & 255, (value >> 8) & 255, value & 255]
185
+ file << bytes.pack('cccc')
186
+ end
187
+
188
+ def write_uint16(file, value)
189
+ bytes = [(value >> 8) & 255, value & 255]
190
+ file << bytes.pack('cc')
191
+ end
192
+
193
+ def write_byte(file, value)
194
+ bytes = [value & 255]
195
+ file << bytes.pack('c')
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,17 @@
1
+ module Sidtool
2
+ class RubyFileWriter
3
+ def initialize(synths_for_voices)
4
+ @synths_for_voices = synths_for_voices
5
+ end
6
+
7
+ def write_to(path)
8
+ File.open(path, 'w') do |file|
9
+ file.puts '::SYNTHS = ['
10
+ @synths_for_voices.flatten.sort_by(&:start_frame).each do |synth|
11
+ file.puts synth.to_a.inspect + ','
12
+ end
13
+ file.puts ']'
14
+ end
15
+ end
16
+ end
17
+ end
data/lib/sidtool/sid.rb CHANGED
@@ -2,7 +2,6 @@ module Sidtool
2
2
  class Sid
3
3
  def initialize
4
4
  @voices = [Voice.new, Voice.new, Voice.new]
5
- @synths = []
6
5
 
7
6
  @frequency_low = @frequency_high = 0
8
7
  @pulse_low = @pulse_high = 0
@@ -44,5 +43,9 @@ module Sidtool
44
43
  def stop!
45
44
  @voices.each(&:stop!)
46
45
  end
46
+
47
+ def synths_for_voices
48
+ @voices.map(&:synths)
49
+ end
47
50
  end
48
51
  end
data/lib/sidtool/state.rb CHANGED
@@ -1,11 +1,9 @@
1
1
  module Sidtool
2
2
  class State
3
3
  attr_accessor :current_frame
4
- attr_accessor :synths
5
4
 
6
5
  def initialize
7
6
  @current_frame = 0
8
- @synths = []
9
7
  end
10
8
  end
11
9
  end
data/lib/sidtool/synth.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  module Sidtool
2
2
  class Synth
3
- attr_writer :waveform
4
- attr_writer :attack
5
- attr_writer :decay
6
- attr_writer :release
3
+ attr_reader :start_frame
4
+ attr_accessor :waveform
5
+ attr_accessor :attack
6
+ attr_accessor :decay
7
+ attr_reader :sustain_length
8
+ attr_accessor :release
9
+ attr_reader :controls
7
10
 
8
11
  def initialize(start_frame)
9
12
  @start_frame = start_frame
@@ -48,10 +51,13 @@ module Sidtool
48
51
  end
49
52
 
50
53
  def to_a
51
- tone = sid_frequency_to_nearest_midi(@frequency)
52
54
  [@start_frame, tone, @waveform, @attack.round(3), @decay.round(3), @sustain_length.round(3), @release.round(3), @controls]
53
55
  end
54
56
 
57
+ def tone
58
+ sid_frequency_to_nearest_midi(@frequency)
59
+ end
60
+
55
61
  private
56
62
  def sid_frequency_to_nearest_midi(sid_frequency)
57
63
  actual_frequency = sid_frequency_to_actual_frequency(sid_frequency)
@@ -1,3 +1,3 @@
1
1
  module Sidtool
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.5'
3
3
  end
data/lib/sidtool/voice.rb CHANGED
@@ -7,41 +7,43 @@ module Sidtool
7
7
  attr_writer :control_register
8
8
  attr_writer :attack_decay
9
9
  attr_writer :sustain_release
10
+ attr_reader :synths
10
11
 
11
12
  def initialize
12
13
  @frequency_low = @frequency_high = 0
13
14
  @pulse_low = @pulse_high = 0
14
15
  @attack_decay = @sustain_release = 0
15
16
  @control_register = 0
16
- @synth = nil
17
+ @current_synth = nil
18
+ @synths = []
17
19
  end
18
20
 
19
21
  def finish_frame
20
22
  if gate
21
- if @synth&.released?
22
- @synth.stop!
23
- @synth = nil
23
+ if @current_synth&.released?
24
+ @current_synth.stop!
25
+ @current_synth = nil
24
26
  end
25
27
 
26
28
  if frequency > 0
27
- if !@synth
28
- @synth = Synth.new(STATE.current_frame)
29
- STATE.synths << @synth
29
+ if !@current_synth
30
+ @current_synth = Synth.new(STATE.current_frame)
31
+ @synths << @current_synth
30
32
  end
31
- @synth.frequency = frequency
32
- @synth.waveform = waveform
33
- @synth.attack = attack
34
- @synth.decay = decay
35
- @synth.release = release
33
+ @current_synth.frequency = frequency
34
+ @current_synth.waveform = waveform
35
+ @current_synth.attack = attack
36
+ @current_synth.decay = decay
37
+ @current_synth.release = release
36
38
  end
37
39
  else
38
- @synth&.release!
40
+ @current_synth&.release!
39
41
  end
40
42
  end
41
43
 
42
44
  def stop!
43
- @synth&.stop!
44
- @synth = nil
45
+ @current_synth&.stop!
46
+ @current_synth = nil
45
47
  end
46
48
 
47
49
  private
data/lib/sidtool.rb CHANGED
@@ -2,6 +2,8 @@ require 'sidtool/version'
2
2
 
3
3
  module Sidtool
4
4
  require 'sidtool/file_reader'
5
+ require 'sidtool/ruby_file_writer'
6
+ require 'sidtool/midi_file_writer'
5
7
  require 'sidtool/synth'
6
8
  require 'sidtool/voice'
7
9
  require 'sidtool/sid'
data/sidtool.gemspec CHANGED
@@ -12,13 +12,15 @@ Gem::Specification.new do |spec|
12
12
  spec.homepage = 'https://github.com/olefriis/sidtool'
13
13
  spec.license = 'MIT'
14
14
 
15
+ spec.required_ruby_version = '>= 2.3'
16
+
15
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
18
  f.match(%r{^(test|spec|features)/})
17
19
  end
18
20
  spec.executables = 'sidtool'
19
21
  spec.require_paths = ['lib']
20
22
 
21
- spec.add_dependency 'mos6510', '~> 0.1.0'
23
+ spec.add_dependency 'mos6510', '~> 0.1.2'
22
24
  spec.add_development_dependency 'bundler', '~> 2.0'
23
25
  spec.add_development_dependency 'rake', '~> 10.0'
24
26
  spec.add_development_dependency 'rspec', '~> 3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidtool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ole Friis Østergaard
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-01 00:00:00.000000000 Z
11
+ date: 2022-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mos6510
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.0
19
+ version: 0.1.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.0
26
+ version: 0.1.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.12.2
83
- description:
83
+ description:
84
84
  email:
85
85
  - olefriis@gmail.com
86
86
  executables:
@@ -101,6 +101,8 @@ files:
101
101
  - bin/sidtool
102
102
  - lib/sidtool.rb
103
103
  - lib/sidtool/file_reader.rb
104
+ - lib/sidtool/midi_file_writer.rb
105
+ - lib/sidtool/ruby_file_writer.rb
104
106
  - lib/sidtool/sid.rb
105
107
  - lib/sidtool/state.rb
106
108
  - lib/sidtool/synth.rb
@@ -111,7 +113,7 @@ homepage: https://github.com/olefriis/sidtool
111
113
  licenses:
112
114
  - MIT
113
115
  metadata: {}
114
- post_install_message:
116
+ post_install_message:
115
117
  rdoc_options: []
116
118
  require_paths:
117
119
  - lib
@@ -119,15 +121,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
121
  requirements:
120
122
  - - ">="
121
123
  - !ruby/object:Gem::Version
122
- version: '0'
124
+ version: '2.3'
123
125
  required_rubygems_version: !ruby/object:Gem::Requirement
124
126
  requirements:
125
127
  - - ">="
126
128
  - !ruby/object:Gem::Version
127
129
  version: '0'
128
130
  requirements: []
129
- rubygems_version: 3.0.1
130
- signing_key:
131
+ rubygems_version: 3.3.3
132
+ signing_key:
131
133
  specification_version: 4
132
134
  summary: Convert SID tunes to other formats
133
135
  test_files: []