2014年12月5日金曜日

実験コード





#!/usr/local/bin/ruby19
# -*- coding: utf-8 -*-
#データの前処理は以下の通り
#sox input.mp3 -t raw -B -e floating-point -b 32 -c 1 -r 96000 input.raw

'In maxima
F:96000;
C:0.1;
H(z,p,c):=(z-1)*(z+1)/((z-c*exp(p*%i*%pi))*(z-c*exp(-p*%i*%pi)))*p;
define(G(f,p,c), 10*log(10)*log(abs( H(exp(-1*%i*2*%pi*f/F),2*p/F, 1- (1-C)*p/F*2 ))));
plot2d([G(x,63,C),G(x,160,C),G(x,400,C),G(x,1000,C),G(x,2500,C),G(x,6250,C),G(x,16000,C)] , [x,20,22000],[logx]);


係数
a0: 1
a1: 0
a2: -1
b1: 2*c*cos(%pi*p)
b2: -c^2
'

class LPF
def initialize
@rate=0.9
@outValue=0.0
end
attr_accessor :rate,:outValue;
def put(v)
@outValue=(1.0-@rate)*v+@rate*@outValue;
return @outValue
end

def putp(v)
@outValue=v if(@outValue<v)
@outValue=(1.0-@rate)*v+@rate*@outValue;
return @outValue
end
end
class BPF
def initialize
@N=2
@inValue=[0.0,0.0]
@outValue=[0.0,0.0]
end
def set(p,c)
#$stderr.puts "set p=#{p} c=#{c}"
@b1=2.0*c*Math::cos(Math::PI*p)
@b2=-c*c
@gain=p
end
def out()
return @outValue[0]*@gain
end
def put(v)
o= v - @inValue[1] + @b1*@outValue[0] + @b2*@outValue[1]
@outValue[1]=@outValue[0]
@inValue[1]=@inValue[0]
@outValue[0]=o
@inValue[0]=v
return o * @gain;
end
end
class MSG7
def initialize
@F=96000.0
@C=0.1
@BINSIZE=@F/100; #30Hzで取り込むなら @F/30を指定
@count=0
@bpf=Array.new
[63,160,400,1000,2500,6250,16000].each do |f|
p= 2*f/@F;
c= 1- (1-@C)*f/@F*2
@bpf.push(BPF.new)
@bpf[-1].set(p,c)
end


@lpf=Array.new
@bpf.size.times { @lpf.push(LPF.new) }
@peak=Array.new
@peak.fill(0.0,0,@bpf.size())
end
def put(v)
@bpf.size.times do |i|
tmp=@bpf[i].put(v).abs
@peak[i]=tmp if(@peak[i]<tmp)
end
@count += 1
return nil if @count < @BINSIZE


ret=Array.new(@bpf.size)
@bpf.size.times do |i|
ret[i]=@lpf[i].putp(@peak[i]);
end
@peak.fill(0.0,0,@bpf.size())
@count=0
return ret
end
end

msg=MSG7.new
llpf=LPF.new
llpf.rate=0.85

while(true) do
data=$stdin.read(4*96000/10)
break if (data==nil)
data.unpack("g*").each do |d|
ret=msg.put(d)
next if ret == nil
#ここでretにMSG7EQの出力が入る
m=1.0
a=0.0
ret[-5..-1].each { |r| m *= r ;a+= r} #低周波はあまり信用できないはず
v=m
v=m/(a**2 + 1.0E-100) #綺麗に正規化まではしない。音量と相関値との中間ぐらいの特徴量
r=[v,llpf.putp(v)]
puts r.join("\t")
end
end






0 件のコメント:

コメントを投稿