feep 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e59eb850a3b66b00df0a1f7e42523e7f1d7f6974
4
+ data.tar.gz: e032678907f285574b847199f530cd66a8eaa734
5
+ SHA512:
6
+ metadata.gz: 69e83b10a38ed0b4a7a3378fe874fc5054b57a4bb8ec38ec02eec736c4fb8a36e3958d2e6973a092f141e32b9300857b7e92f402a3c085a37f2308402c9f5de2
7
+ data.tar.gz: 545f7debf3dc9801a85a27fdba7f2531d1a682b78a22cf681add3674eda27a80dd3207dabc3c978c4fa4cf716d44e2284ca4cfecde8dd0b72c3ede03c125bcda
@@ -0,0 +1,4 @@
1
+ .idea/*
2
+ pkg/*
3
+ *.gem
4
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,60 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ feep (0.0.1)
5
+ os (~> 0.9, >= 0.9.6)
6
+ wavefile (= 0.6.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ byebug (3.5.1)
12
+ columnize (~> 0.8)
13
+ debugger-linecache (~> 1.2)
14
+ slop (~> 3.6)
15
+ coderay (1.1.0)
16
+ columnize (0.9.0)
17
+ debugger-linecache (1.2.0)
18
+ diff-lcs (1.2.5)
19
+ method_source (0.8.2)
20
+ os (0.9.6)
21
+ pry (0.10.1)
22
+ coderay (~> 1.1.0)
23
+ method_source (~> 0.8.1)
24
+ slop (~> 3.4)
25
+ pry (0.10.1-x64-mingw32)
26
+ coderay (~> 1.1.0)
27
+ method_source (~> 0.8.1)
28
+ slop (~> 3.4)
29
+ win32console (~> 1.3)
30
+ pry-byebug (3.0.1)
31
+ byebug (~> 3.4)
32
+ pry (~> 0.10)
33
+ rake (10.4.2)
34
+ rspec (3.2.0)
35
+ rspec-core (~> 3.2.0)
36
+ rspec-expectations (~> 3.2.0)
37
+ rspec-mocks (~> 3.2.0)
38
+ rspec-core (3.2.1)
39
+ rspec-support (~> 3.2.0)
40
+ rspec-expectations (3.2.0)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.2.0)
43
+ rspec-mocks (3.2.1)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.2.0)
46
+ rspec-support (3.2.2)
47
+ slop (3.6.0)
48
+ wavefile (0.6.0)
49
+ win32console (1.3.2)
50
+
51
+ PLATFORMS
52
+ ruby
53
+ x64-mingw32
54
+
55
+ DEPENDENCIES
56
+ bundler (~> 1.8)
57
+ feep!
58
+ pry-byebug (~> 3.0)
59
+ rake (~> 10.0)
60
+ rspec (>= 3.0)
@@ -0,0 +1,38 @@
1
+ # Feep
2
+
3
+ ## Wha?
4
+ Use the power of Ruby gems to make your computer [feep](http://dictionary.reference.com/browse/feep) (except more musically) using sweet [WAV-file-writing technology](http://wavefilegem.com) from [Joel Strait](https://github.com/jstrait). Works on both Windows and *nix (including OS X) as it uses the standard WAV format to do its bidding.
5
+
6
+ _Note:_ In order for the sound-playing magic to work on Windows, you will need [sounder](http://www.elifulkerson.com/projects/commandline-wav-player.php), a free command-line WAV file player on your system and in your path. Mac and *nix uses `afplay`, which should be built-in, but feel free to change either to something you already have or desire to install.
7
+
8
+ ## Why?
9
+
10
+ Besides a quick way to make some kind of noise, which I always appreciate, this could be used to tie into another Ruby script for an alert tone or maybe even some wicked cool command-line game that needs musical note sound effects. The opportunities are essentially endless.
11
+
12
+ ## How?
13
+
14
+ For now:
15
+ 1. `git clone git@github.com:michaelchadwick/feep`
16
+ 2. `cd feep`
17
+ 3. `gem build feep.gemspec`
18
+ 4. `gem install feep-0.0.1.gem`
19
+ 5. `bundle install`
20
+ 6. `feep`
21
+
22
+ Feep doesn't require any parameters, as it will play a 440Hz/A4 sine wave at 50% full volume for 1000 milliseconds unless you supply one of the below options. Feep will only save the resulting WAV file it creates if you specify the `-save` parameter.
23
+
24
+ The full usage looks like this:
25
+
26
+ `feep [-fn frequency|note_name|comma-delimited_frequencies_or_note_names] [-w waveform] [-v volume] [-d duration] [-save] [-loud]`
27
+
28
+ `-frequency|note_name|commad-delimted_frequences_or_note_names`: a number from 0 to 20000. You can try something bigger or smaller, but you may get odd results. You may also enter any note name from C0 to B9 (or even flats and sharps like C#6 or Eb5). You may also also enter some combination of these with commas between them and it'll play all of them together in a chord.
29
+
30
+ `-waveform`: a string equal to "sine", "square", "saw", "triangle", or "noise".
31
+
32
+ `-volume`: a number from 0.0 (silence (why would you do this?)) to 1.0 (blast it)
33
+
34
+ `-duration`: number of milliseconds for the sound to last
35
+
36
+ `-save`: save the resulting WAV file in the current directory. Will create it in the format of `waveform_frequency-in-Hz_volume_duration.wav`
37
+
38
+ `-loud`: displays note and file-making information
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ Dir.glob('tasks/**/*.rake').each(&method(:import))
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'feep'
5
+
6
+ USAGE_INSTRUCTIONS = ''
7
+
8
+ def parse_options
9
+ options = {:freq_or_note => '440.000', :waveform => 'sine', :volume => 0.5, :duration => 1000, :save => false, :loud => false}
10
+
11
+ optparse = OptionParser.new do |opts|
12
+ opts.banner = 'usage: feep [frequency|note_name|list_of_frequencies_or_note_names] [waveform] [volume] [duration] [save] [-loud]'
13
+
14
+ opts.on('-f', '-n', '--freq-or-note FREQUENCY|NOTE_NAME', 'One or more frequencies or note names to play at once, e.g. 440 or A4 or 220,440,880') do |f_or_n|
15
+ options[:freq_or_note] = f_or_n
16
+ end
17
+
18
+ opts.on('-w', '--wave WAVE_FORM_NAME', 'Waveform type to use for the sound') do |w|
19
+ options[:waveform] = w
20
+ end
21
+
22
+ opts.on('-a', '--amplitude MAX_AMPLITUDE', 'Amplitude/volume (0.0 - 1.0) to play the sound(s) at') do |a|
23
+ options[:volume] = a.to_f
24
+ end
25
+
26
+ opts.on('-d', '--duration DURATION', 'Duration in ms to play the sound(s)') do |d|
27
+ options[:duration] = d.to_i
28
+ end
29
+
30
+ opts.on('-s', '--save', 'Save the resulting WAV file in the current directory') do
31
+ options[:save] = true
32
+ end
33
+
34
+ opts.on('-l', '--loud', 'Displays information about note(s) being played') do
35
+ options[:loud] = true
36
+ end
37
+
38
+ opts.on('-v', '--version', 'Display version number and exit') do
39
+ puts "#{$0} #{Feep::VERSION}"
40
+ exit
41
+ end
42
+
43
+ opts.on( '-h', '--help', 'Display this screen and exit') do
44
+ puts opts
45
+ exit
46
+ end
47
+ end
48
+
49
+ USAGE_INSTRUCTIONS << optparse.to_s
50
+ optparse.parse!()
51
+
52
+ return options
53
+ end
54
+
55
+ def print_error(error)
56
+ case error
57
+ when OptionParser::InvalidOption
58
+ puts "feep: illegal option #{error.args.join(' ')}"
59
+ puts USAGE_INSTRUCTIONS
60
+ else
61
+ puts 'An unexpected error occurred while running Feep:'
62
+ puts " #{error}\n"
63
+ end
64
+ end
65
+
66
+ begin
67
+ options = parse_options()
68
+
69
+ Feep.new(options)
70
+ rescue => error
71
+ print_error(error)
72
+ exit(false)
73
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "feep/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'feep'
8
+ spec.version = Feep::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Michael Chadwick"]
11
+ spec.email = 'mike@codana.me'
12
+ spec.homepage = "http://rubygemspec.org/gems/feep"
13
+ spec.summary = %q{Make your computer feep with Ruby}
14
+ spec.description = %q{Use Ruby to make your computer beep at a certain frequency for a certain duration. Do it for fun, or add it to other programs for easy alert sounds.}
15
+
16
+ spec.files = `git ls-files`.split("\n")
17
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+ spec.license = 'MIT'
21
+
22
+ spec.add_runtime_dependency 'wavefile', '= 0.6.0'
23
+ spec.add_runtime_dependency 'os', '~> 0.9', '>= 0.9.6'
24
+
25
+ spec.add_development_dependency 'pry-byebug', '~> 3.0'
26
+ spec.add_development_dependency 'bundler', '~> 1.8'
27
+ spec.add_development_dependency 'rake', '~> 10.0'
28
+ spec.add_development_dependency 'rspec', '>= 3.0'
29
+ end
@@ -0,0 +1,213 @@
1
+ require 'wavefile'
2
+ require 'os'
3
+ require 'feep/constants'
4
+
5
+ class Feep
6
+
7
+ # main entry point
8
+ def initialize(options)
9
+ @options = options
10
+ configure_sound(options)
11
+ end
12
+
13
+ # convert midi notes to frequencies
14
+ def midi_to_freq(midi_note)
15
+ return 440.0 * (2.0 ** ((midi_note.to_f-69)/12))
16
+ end
17
+
18
+ # convert frequencies to midi notes
19
+ def freq_to_midi(freq)
20
+ return (69 + 12 * (Math.log2(freq.to_i.abs / 440.0))).round
21
+ end
22
+
23
+ # makes sure that whatever kind of sound was entered on the CLI
24
+ # it is now a frequency to feed into the sample data generator
25
+ def convert_note_to_freq(freq_or_note)
26
+ if freq_or_note.match(/[A-Za-z]/)
27
+ if NOTE_FREQ.has_key?(freq_or_note)
28
+ frequency = NOTE_FREQ[freq_or_note]
29
+ else
30
+ app_error(ERROR_MSG[:note_name])
31
+ end
32
+ else
33
+ frequency = freq_or_note
34
+ end
35
+
36
+ return frequency
37
+ end
38
+
39
+ # takes CLI options, massages them, and passes them to the
40
+ # sound generation methods
41
+ def configure_sound(options)
42
+ ### A. Check non-essential options
43
+ if !WAVE_TYPES.include?(options[:waveform])
44
+ app_error(ERROR_MSG[:wave_form])
45
+ end
46
+
47
+ # Convert ms to secs in order to multiply the sample rate by
48
+ duration_s = (options[:duration].to_f / 1000)
49
+
50
+ # Make the samples to write a nice integer
51
+ samples_to_write = (SAMPLE_RATE * duration_s).to_i
52
+
53
+ ### B. Set frequency/note, or group of frequencies/notes, to play
54
+
55
+ # Is it a chord or a note?
56
+ if options[:freq_or_note].include?(',')
57
+ # yes, it's a chord, so create threads
58
+ threads = []
59
+ options[:freq_or_note].split(',').each do |note|
60
+ sound_to_play = convert_note_to_freq(note)
61
+ output_filename = "#{options[:waveform]}_#{sound_to_play}Hz_#{options[:volume].to_f}_#{options[:duration].to_s}.wav"
62
+ threads << Thread.new {
63
+ play_note(sound_to_play.to_f, options[:waveform], options[:volume].to_f, options[:duration].to_i, samples_to_write, output_filename)
64
+ }
65
+ end
66
+ threads.each { |th| th.join }
67
+ else
68
+ # no, it's a single note
69
+ sound_to_play = convert_note_to_freq(options[:freq_or_note])
70
+ output_filename = "#{options[:waveform]}_#{sound_to_play}Hz_#{options[:volume].to_f}_#{options[:duration].to_s}.wav"
71
+ play_note(sound_to_play, options[:waveform], options[:volume].to_f, options[:duration].to_i, samples_to_write, output_filename)
72
+ end
73
+ end
74
+
75
+ # plays note using system wav file player
76
+ def play_sound(file, duration)
77
+ delimiter = OS.windows? ? ';' : ':'
78
+
79
+ system_apps = ENV['PATH'].split(delimiter).collect {|d| Dir.entries d if Dir.exists? d}.flatten
80
+
81
+ if OS.windows?
82
+ if system_apps.include? SNDPLAYER_WIN
83
+ display_text_beep(duration)
84
+ system("#{SNDPLAYER_WIN} #{file}")
85
+ else
86
+ puts "couldn't find #{SNDPLAYER_WIN}"
87
+ end
88
+ end
89
+
90
+ if OS.mac? || OS.linux?
91
+ if system_apps.include? SNDPLAYER_UNIX
92
+ display_text_beep(duration)
93
+ system("#{SNDPLAYER_UNIX} #{file}")
94
+ else
95
+ puts "couldn't find #{SNDPLAYER_UNIX}"
96
+ end
97
+ end
98
+ end
99
+
100
+ # displays a fun beep message
101
+ def display_text_beep(duration)
102
+ print 'Be'
103
+ 1.upto(duration) {|ms|
104
+ if ms % 100 == 0
105
+ print 'e'
106
+ end
107
+ }
108
+ puts 'ep!'
109
+ end
110
+
111
+ # removes the sound, unless marked to save
112
+ def remove_sound(file)
113
+ if !@options[:save]
114
+ if OS.windows?
115
+ system("del #{file}")
116
+ else
117
+ system("rm #{file}")
118
+ end
119
+ else
120
+ if @options[:loud]
121
+ info = WaveFile::Reader.info(file)
122
+ duration = info.duration
123
+ formatted_duration = duration.minutes.to_s.rjust(2, '0') << ':' <<
124
+ duration.seconds.to_s.rjust(2, '0') << ':' <<
125
+ duration.milliseconds.to_s.rjust(3, '0')
126
+ puts ""
127
+ puts "Created #{file}"
128
+ puts "---"
129
+ puts "Length: #{formatted_duration}"
130
+ puts "Format: #{info.audio_format}"
131
+ puts "Channels: #{info.channels}"
132
+ puts "Frames: #{info.sample_frame_count}"
133
+ puts "Sample Rate: #{info.sample_rate}"
134
+ end
135
+ end
136
+ end
137
+
138
+ # code from Joel Strait's nanosynth to generate raw audio
139
+ def create_sound(frequency, waveform, samples, volume, output_filename)
140
+ # Generate sample data for the given frequency, amplitude, and duration.
141
+ # Since we are using a sample rate of 44,100Hz, 44,100 samples are required for one second of sound.
142
+ samples = generate_sample_data(waveform.to_sym, samples, frequency.to_f, volume.to_f)
143
+
144
+ # Wrap the array of samples in a Buffer, so that it can be written to a Wave file
145
+ # by the WaveFile gem. Since we generated samples between -1.0 and 1.0, the sample
146
+ # type should be :float
147
+ buffer = WaveFile::Buffer.new(samples, WaveFile::Format.new(:mono, :float, 44100))
148
+
149
+ # Write the Buffer containing our samples to a 16-bit, monophonic Wave file
150
+ # with a sample rate of 44,100Hz, using the WaveFile gem.
151
+ WaveFile::Writer.new(output_filename, WaveFile::Format.new(:mono, :pcm_16, 44100)) do |writer|
152
+ writer.write(buffer)
153
+ end
154
+ end
155
+
156
+ # more code from Joel Strait's nanosynth (http://joe)
157
+ # The dark heart of NanoSynth, the part that actually generates the audio data
158
+ def generate_sample_data(wave_type, num_samples, frequency, max_amplitude)
159
+ position_in_period = 0.0
160
+ position_in_period_delta = frequency / SAMPLE_RATE
161
+
162
+ # Initialize an array of samples set to 0.0. Each sample will be replaced with
163
+ # an actual value below.
164
+ samples = [].fill(0.0, 0, num_samples)
165
+
166
+ num_samples.times do |i|
167
+ # Add next sample to sample list. The sample value is determined by
168
+ # plugging position_in_period into the appropriate wave function.
169
+ if wave_type == :sine
170
+ samples[i] = Math::sin(position_in_period * TWO_PI) * max_amplitude
171
+ elsif wave_type == :square
172
+ samples[i] = (position_in_period >= 0.5) ? max_amplitude : -max_amplitude
173
+ elsif wave_type == :saw
174
+ samples[i] = ((position_in_period * 2.0) - 1.0) * max_amplitude
175
+ elsif wave_type == :triangle
176
+ samples[i] = max_amplitude - (((position_in_period * 2.0) - 1.0) * max_amplitude * 2.0).abs
177
+ elsif wave_type == :noise
178
+ samples[i] = RANDOM_GENERATOR.rand(-max_amplitude..max_amplitude)
179
+ end
180
+
181
+ position_in_period += position_in_period_delta
182
+
183
+ # Constrain the period between 0.0 and 1.0.
184
+ # That is, keep looping and re-looping over the same period.
185
+ if(position_in_period >= 1.0)
186
+ position_in_period -= 1.0
187
+ end
188
+ end
189
+
190
+ return samples
191
+ end
192
+
193
+ # creates, plays, and removes note
194
+ def play_note(frequency, waveform, volume, duration, samples_to_write, output_filename)
195
+ if @options[:loud]
196
+ puts 'Playing note'
197
+ puts " frequency: #{frequency.to_f.abs}"
198
+ puts " midi: #{freq_to_midi(frequency)}"
199
+ puts " duration: #{duration}"
200
+ end
201
+ create_sound(frequency, waveform, samples_to_write, volume, output_filename)
202
+ play_sound(output_filename, duration)
203
+ remove_sound(output_filename)
204
+ end
205
+
206
+ # displays error, usage, and exits
207
+ def app_error(msg)
208
+ puts "#{File.basename($0).split(".")[0]}: #{msg}"
209
+ puts 'usage: feep [frequency|note_name|list_of_frequencies_or_note_names] [sine|square|saw|triangle|noise] [volume] [duration] [save]'
210
+ exit
211
+ end
212
+
213
+ end
@@ -0,0 +1,186 @@
1
+ class Feep
2
+ SNDPLAYER_WIN = 'sounder.exe'
3
+ SNDPLAYER_UNIX = 'afplay'
4
+ SAMPLE_RATE = 44100
5
+ TWO_PI = 2 * Math::PI
6
+ RANDOM_GENERATOR = Random.new
7
+ WAVE_TYPES = %w[sine square saw triangle noise]
8
+
9
+ NOTE_FREQ = Hash[
10
+ 'C0' => 16.351,
11
+ 'C#0' => 17.324,
12
+ 'Db0' => 17.324,
13
+ 'D0' => 18.354,
14
+ 'D#0' => 19.445,
15
+ 'Eb0' => 19.445,
16
+ 'E0' => 20.601,
17
+ 'F0' => 21.827,
18
+ 'F#0' => 23.124,
19
+ 'Gb0' => 23.124,
20
+ 'G0' => 24.499,
21
+ 'G#0' => 25.956,
22
+ 'Ab0' => 25.956,
23
+ 'A0' => 27.500,
24
+ 'A#0' => 29.135,
25
+ 'Bb0' => 29.135,
26
+ 'B0' => 30.868,
27
+ 'C1' => 32.703,
28
+ 'C#1' => 34.648,
29
+ 'Db1' => 34.648,
30
+ 'D1' => 36.708,
31
+ 'D#1' => 38.891,
32
+ 'Eb1' => 38.891,
33
+ 'E1' => 41.203,
34
+ 'F1' => 43.654,
35
+ 'F#1' => 46.249,
36
+ 'Gb1' => 46.249,
37
+ 'G1' => 48.999,
38
+ 'G#1' => 51.913,
39
+ 'Ab1' => 51.913,
40
+ 'A1' => 55.000,
41
+ 'A#1' => 58.270,
42
+ 'Bb1' => 58.270,
43
+ 'B1' => 61.375,
44
+ 'C2' => 65.406,
45
+ 'C#2' => 69.296,
46
+ 'Db2' => 69.296,
47
+ 'D2' => 73.416,
48
+ 'D#2' => 77.782,
49
+ 'Eb2' => 77.782,
50
+ 'E2' => 82.407,
51
+ 'F2' => 87.307,
52
+ 'F#2' => 92.499,
53
+ 'Gb2' => 92.499,
54
+ 'G2' => 97.999,
55
+ 'G#2' => 97.999,
56
+ 'Ab2' => 103.826,
57
+ 'A2' => 110.000,
58
+ 'A#2' => 116.541,
59
+ 'Bb2' => 116.541,
60
+ 'B2' => 123.471,
61
+ 'C3' => 130.813,
62
+ 'C#3' => 138.591,
63
+ 'Db3' => 138.591,
64
+ 'D3' => 146.832,
65
+ 'D#3' => 155.564,
66
+ 'Eb3' => 155.564,
67
+ 'E3' => 164.814,
68
+ 'F3' => 174.614,
69
+ 'F#3' => 184.997,
70
+ 'Gb3' => 184.997,
71
+ 'G3' => 195.998,
72
+ 'G#3' => 207.652,
73
+ 'Ab3' => 207.652,
74
+ 'A3' => 220.000,
75
+ 'A#3' => 233.082,
76
+ 'Bb3' => 233.082,
77
+ 'B3' => 246.942,
78
+ 'C4' => 261.626,
79
+ 'C#4' => 277.183,
80
+ 'Db4' => 277.183,
81
+ 'D4' => 293.665,
82
+ 'D#4' => 311.127,
83
+ 'Eb4' => 311.127,
84
+ 'E4' => 329.628,
85
+ 'F4' => 349.228,
86
+ 'F#4' => 369.994,
87
+ 'Gb4' => 369.994,
88
+ 'G4' => 391.995,
89
+ 'G#4' => 415.305,
90
+ 'Ab4' => 415.305,
91
+ 'A4' => 440.000,
92
+ 'A#4' => 466.164,
93
+ 'Bb4' => 466.164,
94
+ 'B4' => 493.883,
95
+ 'C5' => 523.251,
96
+ 'C#5' => 554.365,
97
+ 'Db5' => 554.365,
98
+ 'D5' => 587.330,
99
+ 'D#5' => 622.254,
100
+ 'Eb5' => 622.254,
101
+ 'E5' => 659.255,
102
+ 'F5' => 698.457,
103
+ 'F#5' => 739.989,
104
+ 'Gb5' => 739.989,
105
+ 'G5' => 783.991,
106
+ 'G#5' => 830.609,
107
+ 'Ab5' => 830.609,
108
+ 'A5' => 880.000,
109
+ 'A#5' => 932.328,
110
+ 'Bb5' => 932.328,
111
+ 'B5' => 987.767,
112
+ 'C6' => 1046.502,
113
+ 'C#6' => 1108.731,
114
+ 'Db6' => 1108.731,
115
+ 'D6' => 1174.659,
116
+ 'D#6' => 1244.508,
117
+ 'Eb6' => 1244.508,
118
+ 'E6' => 1318.510,
119
+ 'F6' => 1396.913,
120
+ 'F#6' => 1479.978,
121
+ 'Gb6' => 1479.978,
122
+ 'G6' => 1567.982,
123
+ 'G#6' => 1661.219,
124
+ 'Ab6' => 1661.219,
125
+ 'A6' => 1760.000,
126
+ 'A#6' => 1864.655,
127
+ 'Bb6' => 1864.655,
128
+ 'B6' => 1975.533,
129
+ 'C7' => 2093.005,
130
+ 'C#7' => 2217.461,
131
+ 'Db7' => 2217.461,
132
+ 'D7' => 2349.318,
133
+ 'D#7' => 2489.016,
134
+ 'Eb7' => 2489.016,
135
+ 'E7' => 2637.021,
136
+ 'F7' => 2793.826,
137
+ 'F#7' => 2959.956,
138
+ 'Gb7' => 2959.956,
139
+ 'G7' => 3135.964,
140
+ 'G#7' => 3322.438,
141
+ 'Ab7' => 3322.438,
142
+ 'A7' => 3520.000,
143
+ 'A#7' => 3729.310,
144
+ 'Bb7' => 3729.310,
145
+ 'B7' => 3951.066,
146
+ 'C8' => 4186.009,
147
+ 'C#8' => 4434.922,
148
+ 'Db8' => 4434.922,
149
+ 'D8' => 4698.636,
150
+ 'D#8' => 4978.032,
151
+ 'Eb8' => 4978.032,
152
+ 'E8' => 5274.042,
153
+ 'F8' => 5587.652,
154
+ 'F#8' => 5919.910,
155
+ 'Gb8' => 5919.910,
156
+ 'G8' => 6271.928,
157
+ 'G#8' => 6644.876,
158
+ 'Ab8' => 6644.876,
159
+ 'A8' => 7040.000,
160
+ 'A#8' => 7458.620,
161
+ 'Bb8' => 7458.620,
162
+ 'B8' => 7902.132,
163
+ 'C9' => 8372.018,
164
+ 'C#9' => 8869.844,
165
+ 'Db9' => 8869.844,
166
+ 'D9' => 9397.272,
167
+ 'D#9' => 9956.064,
168
+ 'Eb9' => 9956.064,
169
+ 'E9' => 10548.084,
170
+ 'F9' => 11175.304,
171
+ 'F#9' => 11839.820,
172
+ 'Gb9' => 11839.820,
173
+ 'G9' => 12543.856,
174
+ 'G#9' => 13289.752,
175
+ 'Ab9' => 13289.752,
176
+ 'A9' => 14080.000,
177
+ 'A#9' => 14917.240,
178
+ 'Bb9' => 14917.240,
179
+ 'B9' => 15804.264
180
+ ]
181
+
182
+ ERROR_MSG = Hash[
183
+ :note_name => 'Note name argument is invalid.',
184
+ :wave_form => 'Wave form type is invalid.'
185
+ ]
186
+ end
@@ -0,0 +1,3 @@
1
+ class Feep
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Feep do
4
+ subject { Feep.new }
5
+
6
+ describe '#play_sound' do
7
+ options = {
8
+ :freq_or_note => '440.000',
9
+ :waveform => 'sine',
10
+ :volume => 0.5,
11
+ :duration => 500,
12
+ :save => false,
13
+ :loud => false
14
+ }
15
+
16
+ it 'plays a sound with no options' do
17
+ expect(Feep.new(options)).to eq "sound played"
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1 @@
1
+ require 'feep'
@@ -0,0 +1,3 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: feep
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Chadwick
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: wavefile
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.6.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.6.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: os
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.9.6
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '0.9'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 0.9.6
47
+ - !ruby/object:Gem::Dependency
48
+ name: pry-byebug
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.8'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.8'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '3.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '3.0'
103
+ description: Use Ruby to make your computer beep at a certain frequency for a certain
104
+ duration. Do it for fun, or add it to other programs for easy alert sounds.
105
+ email: mike@codana.me
106
+ executables:
107
+ - feep
108
+ extensions: []
109
+ extra_rdoc_files: []
110
+ files:
111
+ - ".gitignore"
112
+ - Gemfile
113
+ - Gemfile.lock
114
+ - README.md
115
+ - Rakefile
116
+ - bin/feep
117
+ - feep.gemspec
118
+ - lib/feep.rb
119
+ - lib/feep/constants.rb
120
+ - lib/feep/version.rb
121
+ - spec/feep_spec.rb
122
+ - spec/spec_helper.rb
123
+ - tasks/rspec.rake
124
+ homepage: http://rubygemspec.org/gems/feep
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.4.5
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Make your computer feep with Ruby
148
+ test_files: []
149
+ has_rdoc: