Class: Audite

Inherits:
Object
  • Object
show all
Defined in:
lib/audite.rb

Defined Under Namespace

Classes: Events

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(buffer_size = 2**12, device_name = '') ⇒ Audite

Returns a new instance of Audite.



23
24
25
26
27
28
29
# File 'lib/audite.rb', line 23

def initialize(buffer_size = 2**12, device_name = '')
  @buffer_size = buffer_size
  @device_name = device_name
  @events = Events.new
  @stream = Portaudio.new(@buffer_size, @device_name)
  @song_list = []
end

Instance Attribute Details

#activeObject (readonly)

Returns the value of attribute active.



21
22
23
# File 'lib/audite.rb', line 21

def active
  @active
end

#eventsObject (readonly)

Returns the value of attribute events.



21
22
23
# File 'lib/audite.rb', line 21

def events
  @events
end

#fileObject (readonly)

Returns the value of attribute file.



21
22
23
# File 'lib/audite.rb', line 21

def file
  @file
end

#mp3Object (readonly)

Returns the value of attribute mp3.



21
22
23
# File 'lib/audite.rb', line 21

def mp3
  @mp3
end

#song_listObject (readonly)

Returns the value of attribute song_list.



21
22
23
# File 'lib/audite.rb', line 21

def song_list
  @song_list
end

#streamObject (readonly)

Returns the value of attribute stream.



21
22
23
# File 'lib/audite.rb', line 21

def stream
  @stream
end

#threadObject (readonly)

Returns the value of attribute thread.



21
22
23
# File 'lib/audite.rb', line 21

def thread
  @thread
end

Instance Method Details

#closeObject



70
71
72
73
# File 'lib/audite.rb', line 70

def close
  stream.close
  exit
end

#current_song_nameObject



57
58
59
# File 'lib/audite.rb', line 57

def current_song_name
  File.basename mp3.file
end

#forward(seconds = 2) ⇒ Object



188
189
190
# File 'lib/audite.rb', line 188

def forward(seconds = 2)
  seek(position + seconds)
end

#lengthObject



145
146
147
# File 'lib/audite.rb', line 145

def length
  @mp3 ? @mp3.length : 0
end

#length_in_secondsObject



180
181
182
# File 'lib/audite.rb', line 180

def length_in_seconds
  samples_to_seconds(length)
end

#levelObject



40
41
42
# File 'lib/audite.rb', line 40

def level
  @stream.rms
end

#load(files) ⇒ Object



106
107
108
109
110
# File 'lib/audite.rb', line 106

def load(files)
  files = [] << files unless Array === files
  files.each {|file| queue file }
  set_current_song
end

#positionObject



176
177
178
# File 'lib/audite.rb', line 176

def position
  samples_to_seconds(tell)
end

#process(status) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/audite.rb', line 44

def process(status)
  if [:done, :need_more].include? status
    request_next_song
    events.trigger(:complete)
  else
    events.trigger(:position_change, position)
  end

rescue => e
  $stderr.puts e.message
  $stderr.puts e.backtrace
end

#queue(song) ⇒ Object



121
122
123
# File 'lib/audite.rb', line 121

def queue song
  @song_list << Mpg123.new(song)
end

#queued_songsObject



125
126
127
# File 'lib/audite.rb', line 125

def queued_songs
  @song_list.map {|s| File.basename s.file }
end

#request_next_songObject



61
62
63
64
65
66
67
68
# File 'lib/audite.rb', line 61

def request_next_song
  if songs_in_queue?
    set_current_song
    start_stream
  else
    stop_stream
  end
end

#rewind(seconds = 2) ⇒ Object



184
185
186
# File 'lib/audite.rb', line 184

def rewind(seconds = 2)
  seek(position - seconds)
end

#samples_per_frameObject



137
138
139
# File 'lib/audite.rb', line 137

def samples_per_frame
  @mp3.spf
end

#samples_to_frames(samples) ⇒ Object



161
162
163
# File 'lib/audite.rb', line 161

def samples_to_frames(samples)
  samples / samples_per_frame
end

#samples_to_seconds(samples) ⇒ Object



157
158
159
# File 'lib/audite.rb', line 157

def samples_to_seconds(samples)
  samples_to_frames(samples) * time_per_frame
end

#seconds_to_frames(seconds) ⇒ Object



149
150
151
# File 'lib/audite.rb', line 149

def seconds_to_frames(seconds)
  seconds / time_per_frame
end

#seconds_to_samples(seconds) ⇒ Object



153
154
155
# File 'lib/audite.rb', line 153

def seconds_to_samples(seconds)
  seconds_to_frames(seconds) * samples_per_frame
end

#seek(seconds) ⇒ Object



165
166
167
168
169
170
171
172
173
174
# File 'lib/audite.rb', line 165

def seek(seconds)
  if @mp3
    samples = seconds_to_samples(seconds)

    if (0..length).include?(samples)
      @mp3.seek(samples)
      events.trigger(:position_change, position)
    end
  end
end

#set_current_songObject



116
117
118
119
# File 'lib/audite.rb', line 116

def set_current_song
  @mp3 = song_list.shift
  start_thread
end

#song_loaded?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/audite.rb', line 112

def song_loaded?
  !@mp3.nil?
end

#songs_in_queue?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/audite.rb', line 129

def songs_in_queue?
  !@song_list.empty?
end

#start_streamObject



75
76
77
78
79
80
81
82
# File 'lib/audite.rb', line 75

def start_stream
  unless @active || !song_loaded?
    @active = true
    @stream.start
    start_thread
    events.trigger(:toggle, @active)
  end
end

#start_threadObject



31
32
33
34
35
36
37
38
# File 'lib/audite.rb', line 31

def start_thread
  @thread ||= Thread.start do
    loop do
      process @stream.write_from_mpg(@mp3)
      @stream.wait
    end
  end
end

#stop_streamObject



84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/audite.rb', line 84

def stop_stream
  if @active
    @active = false
    if @thread.alive?
      @thread.kill
      @thread = nil
    end
    unless @stream.stopped?
      @stream.stop
      events.trigger(:toggle, @active)
    end
  end
end

#tellObject



141
142
143
# File 'lib/audite.rb', line 141

def tell
  @mp3 ? @mp3.tell : 0
end

#time_per_frameObject



133
134
135
# File 'lib/audite.rb', line 133

def time_per_frame
  @mp3.tpf
end

#toggleObject



98
99
100
101
102
103
104
# File 'lib/audite.rb', line 98

def toggle
  if @active
    stop_stream
  else
    start_stream
  end
end