Skip to content

Commit

Permalink
Support RAPT and unify default argment values of swipe and rapt
Browse files Browse the repository at this point in the history
with SPTK's pitch command
  • Loading branch information
r9y9 committed Oct 27, 2015
1 parent 654d89a commit 3ce74b6
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/SPTK.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ for fname in [
"lib",
"adaptive",
"conversions",
"excite",
"f0",
"mfcc",
"mgcep",
Expand Down
51 changes: 46 additions & 5 deletions src/f0.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,60 @@
# F0 estimation
### F0 estimation ###

function swipe(x::StridedVector{Cdouble}, fs, hopsize=80;
min::Float64=50.0,
max::Float64=800.0,
min::Float64=60.0,
max::Float64=240.0,
threshold::Float64=0.3,
otype::Int=1)
otype::Int=0)
if otype 0:2
throw(ArgumentError("unsupported otype: $otype, must be ∈ 0:2"))
end

expectedlen = div(length(x), hopsize) + 1
if min >= max || max >= fs/2
throw(ArgumentError("invalid min/max frequency parameters"))
end

expectedlen = ceil(Int, length(x) / hopsize)
f0 = Array(Cdouble, expectedlen)
ccall((:swipe, libSPTK), Void,
(Ptr{Cdouble}, Ptr{Cdouble}, Cint, Cint, Cint, Cdouble, Cdouble,
Cdouble, Cint),
x, f0, length(x), fs, hopsize, min, max, threshold, otype)
f0
end

function rapt(x::StridedVector{Cfloat}, fs, hopsize=80;
min::Float64=60.0,
max::Float64=240.0,
voice_bias::Float64=0.0,
otype::Int=0)
if otype 0:2
throw(ArgumentError("unsupported otype: $otype, must be ∈ 0:2"))
end

if min >= max || max >= fs/2 || min <= fs/10000.0
throw(ArgumentError("invalid min/max frequency parameters"))
end

frame_period = (hopsize / fs)::Float64
frame_period = trunc(0.5 + fs * frame_period) / fs
if frame_period > 0.1 || frame_period < 1/fs
throw(ArgumentError("frame period must be between [1/fs, 0.1]"))
end

expectedlen = ceil(Int, length(x) / hopsize)
f0 = Array(Cfloat, expectedlen)
ret = ccall((:rapt, libSPTK), Int,
(Ptr{Cfloat}, Ptr{Cfloat}, Cint, Cdouble, Cint, Cdouble, Cdouble,
Cdouble, Cint),
x, f0, length(x), fs, hopsize, min, max, voice_bias, otype)

if ret == 2
error("input range too small for analysis by get_f0")
elseif ret == 3
error("problem in init_dp_f0()")
end

@assert ret == 0

f0
end
61 changes: 55 additions & 6 deletions test/f0.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,65 @@
function test_f0()
function test_swipe()
println("test f0 estimation")
srand(98765)
dummy_input = rand(1024)

println("-- test_swipe")
f0 = swipe(dummy_input, 16000, 80)
@test length(f0) == div(length(dummy_input), 80) + 1
@test all(isfinite(f0))
@test all(f0 .>= 0)

for otype in [0, 1, 2]
for fs in [16000]
for hopsize in [40, 80, 160, 320]
f0 = swipe(dummy_input, fs, hopsize, otype=otype)
@test all(isfinite(f0))
otype == 0 && @test all(f0 .>= 0)
end
end
end

# invalid otype
@test_throws ArgumentError swipe(dummy_input, 16000, 80, otype=-1)
@test_throws ArgumentError swipe(dummy_input, 16000, 80, otype=-3)

# invalid min/max
@test_throws ArgumentError swipe(dummy_input, 16000, 80, min=60.0, max=60.0)
swipe(dummy_input, 16000, 80, min=60.0, max=7999.0)
@test_throws ArgumentError swipe(dummy_input, 16000, 80, min=60.0, max=8000.0)
end

function test_rapt()
println("test f0 estimation")
srand(98765)
dummy_input = rand(Float32, 1024)

println("-- test_rapt")
for otype in [0, 1, 2]
for fs in [16000]
for hopsize in [40, 80, 160, 320]
f0 = rapt(dummy_input, fs, hopsize, otype=otype)
@test all(isfinite(f0))
otype == 0 && @test all(f0 .>= 0)
end
end
end

fs = 16000

# invalid otype
@test_throws ArgumentError rapt(dummy_input, fs, 80, otype=-1)
@test_throws ArgumentError rapt(dummy_input, fs, 80, otype=-3)

# invalid min/max
@test_throws ArgumentError rapt(dummy_input, 16000, 80, min=60.0, max=60.0)
@test_throws ArgumentError rapt(dummy_input, 16000, 80, min=60.0, max=8000.0)

# valid frame period (corner case)
rapt(rand(Float32, 10000), fs, 1600)

# invalid frame_period
@test_throws ArgumentError rapt(dummy_input, fs, 1601)

# invalid input length (too small)
@test_throws Exception rapt(dummy_input[:100], fs, 80)
end

test_f0()
test_swipe()
test_rapt()

0 comments on commit 3ce74b6

Please sign in to comment.