synthesize 1.1
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.
- data/CHANGELOG +1 -0
- data/LICENSE +1 -0
- data/Manifest +7 -0
- data/README +13 -0
- data/Rakefile +10 -0
- data/lib/synthesize.rb +135 -0
- data/synthesize.gemspec +31 -0
- metadata +81 -0
data/CHANGELOG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v1.0. Basic, no optimisations, etc
|
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
No license, do what you like.
|
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
This gem generates waveforms. Waveform data ranges from 1 to -1.
|
2
|
+
|
3
|
+
Example:
|
4
|
+
s = Synthesize.new(440, 1, 1) 440 Hz, Max Amplitude, 1 Second
|
5
|
+
s.square
|
6
|
+
|
7
|
+
f = File.new("square.wav", "w")
|
8
|
+
f.write(s.to_wav)
|
9
|
+
f.close
|
10
|
+
|
11
|
+
|
12
|
+
Thanks to Damien Karras for the algorithms!
|
13
|
+
http://en.wikibooks.org/wiki/Sound_Synthesis_Theory/Oscillators_and_Wavetables
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
Echoe.new('synthesize') do |e|
|
3
|
+
e.author = "James Whayman"
|
4
|
+
e.email = "whayman.jw@gmail.com"
|
5
|
+
e.description = "Produces basic waveforms, sine, square, sawtooth, triangle. White noise and silence included free!"
|
6
|
+
e.summary = "Generate basic waveforms (sine, square, sawtooth, triangle), white noise and silence."
|
7
|
+
e.version = "1.1"
|
8
|
+
e.url = "https://github.com/jwhayman/rSynthesize"
|
9
|
+
e.install_message = "`'~,.,~'`'~,.,~'`'~,.,~'`'~,.,~'"
|
10
|
+
end
|
data/lib/synthesize.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
#Synthesis
|
2
|
+
#Generate Basic Waveforms and Noise
|
3
|
+
|
4
|
+
class Synthesize
|
5
|
+
|
6
|
+
attr_accessor :waveform, :frequency, :amplitude, :duration, :channels, :sample_rate, :bits_per_sample
|
7
|
+
|
8
|
+
def initialize(frequency, amplitude, duration)
|
9
|
+
@frequency = frequency
|
10
|
+
@amplitude = amplitude
|
11
|
+
@duration = duration
|
12
|
+
@channels = 2
|
13
|
+
@sample_rate = 44100
|
14
|
+
@bits_per_sample = 16
|
15
|
+
end
|
16
|
+
|
17
|
+
def sin
|
18
|
+
step = (2 * Math::PI * @frequency).fdiv(@sample_rate)
|
19
|
+
phase = 0
|
20
|
+
@waveform = Array.new(@duration * @sample_rate)
|
21
|
+
@waveform.each_index do |i|
|
22
|
+
@waveform[i] = @amplitude * Math.sin(phase)
|
23
|
+
|
24
|
+
phase = phase + step
|
25
|
+
if phase > (2 * Math::PI)
|
26
|
+
phase = phase - (2 * Math::PI)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def square
|
32
|
+
step = (2 * Math::PI * @frequency).fdiv(@sample_rate)
|
33
|
+
phase = 0
|
34
|
+
@waveform = Array.new(@duration * @sample_rate)
|
35
|
+
@waveform.each_index do |i|
|
36
|
+
if phase < Math::PI
|
37
|
+
@waveform[i] = @amplitude
|
38
|
+
else
|
39
|
+
@waveform[i] = -@amplitude
|
40
|
+
end
|
41
|
+
|
42
|
+
phase = phase + step
|
43
|
+
if phase > (2 * Math::PI)
|
44
|
+
phase = phase - (2 * Math::PI)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def sawtooth
|
50
|
+
step = (2 * Math::PI * @frequency).fdiv(@sample_rate)
|
51
|
+
phase = 0
|
52
|
+
@waveform = Array.new(@duration * @sample_rate)
|
53
|
+
@waveform.each_index do |i|
|
54
|
+
@waveform[i] = @amplitude - (@amplitude.fdiv(Math::PI)) * phase
|
55
|
+
|
56
|
+
phase = phase + step
|
57
|
+
if phase > (2 * Math::PI)
|
58
|
+
phase = phase - (2 * Math::PI)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def triangle
|
64
|
+
step = (2 * Math::PI * @frequency).fdiv(@sample_rate)
|
65
|
+
phase = 0
|
66
|
+
@waveform = Array.new(@duration * @sample_rate)
|
67
|
+
@waveform.each_index do |i|
|
68
|
+
if phase < Math::PI
|
69
|
+
@waveform[i] = -@amplitude + (2 * @amplitude.fdiv(Math::PI)) * phase
|
70
|
+
else
|
71
|
+
@waveform[i] = 3 * @amplitude - (2 * @amplitude.fdiv(Math::PI)) * phase
|
72
|
+
end
|
73
|
+
|
74
|
+
phase = phase + step
|
75
|
+
if phase > (2 * Math::PI)
|
76
|
+
phase = phase - (2 * Math::PI)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def noise
|
82
|
+
@waveform = Array.new(@duration * @sample_rate)
|
83
|
+
@waveform.each_index do |i|
|
84
|
+
waveform[i] = rand(2) - 1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def silence
|
89
|
+
@waveform = Array.new(@duration * @sample_rate)
|
90
|
+
@waveform.each_index do |i|
|
91
|
+
waveform[i] = 0
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_wav
|
96
|
+
waveform = Array.new
|
97
|
+
|
98
|
+
@waveform.each do |w|
|
99
|
+
value = w * ((2**@bits_per_sample) / 2)
|
100
|
+
if value > 0
|
101
|
+
value = value - 1
|
102
|
+
elsif value < 0
|
103
|
+
value = value + 1
|
104
|
+
end
|
105
|
+
@channels.times do |c|
|
106
|
+
waveform.push(value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
block_align = (@bits_per_sample / 8) * @channels
|
111
|
+
bytes_per_second = block_align * @sample_rate
|
112
|
+
|
113
|
+
header = Array[
|
114
|
+
"RIFF", #Chunk ID
|
115
|
+
bytes_per_second * @duration + 44 - 8, #Chunk Data Size
|
116
|
+
"WAVE", #RIFF Type
|
117
|
+
"fmt ", #Chunk ID
|
118
|
+
16, #Chunk Data Size
|
119
|
+
1, #Compression Code
|
120
|
+
@channels, #Number of Channels
|
121
|
+
@sample_rate, #Sample Rate
|
122
|
+
bytes_per_second, #Bytes per Second
|
123
|
+
block_align, #Block Align
|
124
|
+
@bits_per_sample, #Significant Bits per Sample
|
125
|
+
"data", #Chunk ID
|
126
|
+
bytes_per_second * @duration] #Chunk Data Size
|
127
|
+
|
128
|
+
|
129
|
+
header_data = header.pack("A4VA4A4VvvVVvvA4V")
|
130
|
+
wav_data = waveform.pack("s*")
|
131
|
+
|
132
|
+
return header_data + wav_data
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
data/synthesize.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{synthesize}
|
5
|
+
s.version = "1.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["James Whayman"]
|
9
|
+
s.date = %q{2010-12-25}
|
10
|
+
s.description = %q{Produces basic waveforms, sine, square, sawtooth, triangle. White noise and silence included free!}
|
11
|
+
s.email = %q{whayman.jw@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/synthesize.rb"]
|
13
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "lib/synthesize.rb", "synthesize.gemspec"]
|
14
|
+
s.homepage = %q{https://github.com/jwhayman/rSynthesize}
|
15
|
+
s.post_install_message = %q{`'~,.,~'`'~,.,~'`'~,.,~'`'~,.,~'}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Synthesize", "--main", "README"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{synthesize}
|
19
|
+
s.rubygems_version = %q{1.3.7}
|
20
|
+
s.summary = %q{Generate basic waveforms (sine, square, sawtooth, triangle), white noise and silence.}
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
else
|
28
|
+
end
|
29
|
+
else
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: synthesize
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 13
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: "1.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- James Whayman
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-25 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Produces basic waveforms, sine, square, sawtooth, triangle. White noise and silence included free!
|
22
|
+
email: whayman.jw@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- CHANGELOG
|
29
|
+
- LICENSE
|
30
|
+
- README
|
31
|
+
- lib/synthesize.rb
|
32
|
+
files:
|
33
|
+
- CHANGELOG
|
34
|
+
- LICENSE
|
35
|
+
- Manifest
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- lib/synthesize.rb
|
39
|
+
- synthesize.gemspec
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: https://github.com/jwhayman/rSynthesize
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message: `'~,.,~'`'~,.,~'`'~,.,~'`'~,.,~'
|
45
|
+
rdoc_options:
|
46
|
+
- --line-numbers
|
47
|
+
- --inline-source
|
48
|
+
- --title
|
49
|
+
- Synthesize
|
50
|
+
- --main
|
51
|
+
- README
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 11
|
69
|
+
segments:
|
70
|
+
- 1
|
71
|
+
- 2
|
72
|
+
version: "1.2"
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project: synthesize
|
76
|
+
rubygems_version: 1.3.7
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Generate basic waveforms (sine, square, sawtooth, triangle), white noise and silence.
|
80
|
+
test_files: []
|
81
|
+
|