Top Level Namespace

Defined Under Namespace

Modules: CMath, Math, Noyes, NoyesFilterDSL, NoyesJava Classes: Array, MockNoyesServer

Constant Summary collapse

TMAGIC =
'1.0 talkhouse'
TSTART =

The following constants are packed as 4 byte big-endian integers.

[0].pack('N')
TEND =

TAUDIO = [1].pack(‘N’)

[2].pack('N')
TBYE =
[3].pack('N')
TCEPSTRA =
[4].pack('N')
TA16_16 =
[5].pack('N')
TA16_44 =
[6].pack('N')

Instance Method Summary collapse

Instance Method Details

#file2pcm(file, bits, freq) ⇒ Object



1
2
3
4
5
6
7
8
9
# File 'lib/common/file2pcm.rb', line 1

def file2pcm file, bits, freq
  raw = `sox #{file} -s -B -r #{freq} -b #{bits} -t raw -`
  length = bits.to_i # bits
  max = 2**length-1
  mid = 2**(length-1)
  to_signed = proc {|n| (n>=mid) ? -((n ^ max) + 1) : n}
  unpacked = raw.unpack 'n*'
  unpacked.map{|d| to_signed[d].to_f}
end

#send_incremental_features(file, to_server, from_server, bits, freq) ⇒ Object

Use sox to convert a file of almost any common type int pcm. Not sure this works for anything beside 16 bits. Takes a file and two IO-like objects.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/common/send_incrementally.rb', line 20

def send_incremental_features file, to_server, from_server, bits, freq
  stats = {}
  nfilt = 40
  min_freq = 133.33334
  max_freq = 6855.4976
  nfft = 512
  shift = 160
  frame_size = 410
  preemphasizer = Preemphasizer.new 0.97
  segmenter = Segmenter.new frame_size, shift
  hamming_windower = HammingWindow.new frame_size
  power_spectrum_filter = PowerSpectrumFilter.new nfft
  mel_filter = MelFilter.new freq, nfft, nfilt, min_freq, max_freq
  compressor = LogCompressor.new
  discrete_cosine_transform = DCT.new 13, nfilt
  live_cmn = LiveCMN.new
  pcm = file2pcm file, bits, freq
  stats[:audio_length] = pcm.size/freq.to_f
  to_server.write TMAGIC
  to_server.write TSTART
  stats[:process_time] = 0
  pcm.each_slice 1230 do |data|
    process_time_start = Time.new
    data >>= preemphasizer
    data >>= segmenter
    next unless data
    data >>= hamming_windower
    data >>= power_spectrum_filter
    data >>= mel_filter
    data >>= compressor
    data >>= discrete_cosine_transform
    data >>= live_cmn
    stats[:process_time] += Time.new - process_time_start
    to_server.write TCEPSTRA
    to_server.write [data.size].pack('N')
    print '.'
    data.each {|cmn| to_server.write cmn.pack('g*')} 
    to_server.flush
  end
  to_server.write TEND
  to_server.write TBYE
  to_server.flush
  latency_start = Time.new
  stats[:transcript] = from_server.read
  stats[:latency] = Time.new - latency_start
  return stats
end

#send_incremental_pcm(file, to_server, from_server, depth, rate) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/common/send_incrementally.rb', line 68

def send_incremental_pcm file, to_server, from_server, depth, rate
  raw = `sox #{file} -s -B -r #{rate} -b #{depth} -t raw -` 
  to_server.write TMAGIC
  to_server.write TSTART
  chunk = raw.slice! 0, 1024
  while chunk.size > 0
    to_server.write TA16_16
    to_server.write [chunk.size/2].pack('N')
    to_server.write chunk
    print '.'
    to_server.flush
    chunk = raw.slice! 0, 1024
  end
  to_server.write TEND
  to_server.write TBYE
  to_server.flush
  from_server.read
end

#to_signed_short(n) ⇒ Object

Converts from unsigned to signed short. Ruby, strangely enough, doesn’t have network byte order short conversion for signed shorts.



13
14
15
16
17
18
# File 'lib/common/noyes_math.rb', line 13

def to_signed_short n
  length = 16 # bits
  max = 2**length-1
  mid = 2**(length-1)
  n>=mid ? -((n ^ max) + 1) : n
end