more fixes to get the tests running without deprecations on 0.4 and 0.3

This commit is contained in:
Spencer Russell 2015-11-11 16:31:09 -05:00
parent 826fdafe5f
commit c4dfef9178
8 changed files with 110 additions and 111 deletions

View file

@ -1,21 +1,21 @@
language: cpp language: julia
compiler: compiler:
- clang - clang
notifications: notifications:
email: spencer.f.russell@gmail.com email: spencer.f.russell@gmail.com
env: julia:
- JULIAVERSION="julianightlies" - 0.3
- JULIAVERSION="juliareleases" - 0.4
before_install: # - nightly
- sudo add-apt-repository ppa:staticfloat/julia-deps -y # Fails with:
- sudo add-apt-repository ppa:staticfloat/$JULIAVERSION -y # LoadError: ccall: could not find function jl_read_sonames
- sudo apt-get update -qq -y # while loading /home/travis/.julia/v0.5/AudioIO/deps/build.jl, in expression starting on line 29
- sudo apt-get install libpcre3-dev julia -y
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
script: script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'Pkg.init()' - julia -e 'Pkg.init()'
- julia -e 'Pkg.add("BinDeps"); Pkg.checkout("BinDeps")' # latest master needed for Pacman support - julia -e 'Pkg.add("BinDeps"); Pkg.checkout("BinDeps")' # latest master needed for Pacman support
- julia -e 'Pkg.clone(pwd()); Pkg.build("AudioIO")' - julia -e 'Pkg.clone(pwd()); Pkg.build("AudioIO")'
- julia -e 'Pkg.test("AudioIO", coverage=true)' - julia -e 'Pkg.add("FactCheck")' # add FactCheck manually because we're not using Pkg.test()
- julia --code-coverage=user test/runtests.jl # Pkg.test disables inlining when enabling coverage, which kills our allocation tests
after_success: after_success:
- if [ $JULIAVERSION = "juliareleases" ]; then julia -e 'cd(Pkg.dir("AudioIO")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi - if [ $JULIAVERSION = "juliareleases" ]; then julia -e 'cd(Pkg.dir("AudioIO")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi

5
deps/build.jl vendored
View file

@ -1,4 +1,5 @@
using BinDeps using BinDeps
using Compat
@BinDeps.setup @BinDeps.setup
@ -26,5 +27,5 @@ end
provides(WinRPM.RPM, "libsndfile1", libsndfile, os = :Windows) provides(WinRPM.RPM, "libsndfile1", libsndfile, os = :Windows)
end end
@BinDeps.install [:libportaudio => :libportaudio, @BinDeps.install @compat(Dict(:libportaudio => :libportaudio,
:libsndfile => :libsndfile] :libsndfile => :libsndfile))

View file

@ -228,7 +228,7 @@ function play(arr::AudioBuf, args...)
end end
# If the array is the wrong floating type, convert it # If the array is the wrong floating type, convert it
@compat function play{T <: AbstractFloat}(arr::Array{T}, args...) function play{T <: AbstractFloat}(arr::Array{T}, args...)
arr = convert(AudioBuf, arr) arr = convert(AudioBuf, arr)
play(arr, args...) play(arr, args...)
end end
@ -306,7 +306,7 @@ export LinRamp
function render(node::LinRampRenderer, device_input::AudioBuf, info::DeviceInfo) function render(node::LinRampRenderer, device_input::AudioBuf, info::DeviceInfo)
# Resize buffer if (1) it's too small or (2) we've hit the end of the ramp # Resize buffer if (1) it's too small or (2) we've hit the end of the ramp
ramp_samples::Int = int(node.duration * info.sample_rate) ramp_samples::Int = round(Int, node.duration * info.sample_rate)
block_samples = min(ramp_samples, info.buf_size) block_samples = min(ramp_samples, info.buf_size)
if length(node.buf) != block_samples if length(node.buf) != block_samples
resize!(node.buf, block_samples) resize!(node.buf, block_samples)

View file

@ -1,7 +1,7 @@
typealias PaTime Cdouble typealias PaTime Cdouble
typealias PaError Cint typealias PaError Cint
typealias PaSampleFormat Culong typealias PaSampleFormat Culong
# PaStream is always used as an opaque type, so we're always dealing # PaStream is always used as an opaque type, so we're always dealing
# with the pointer # with the pointer
typealias PaStream Ptr{Void} typealias PaStream Ptr{Void}
typealias PaDeviceIndex Cint typealias PaDeviceIndex Cint
@ -23,7 +23,7 @@ const paInt8 = convert(PaSampleFormat, 0x10)
const paUInt8 = convert(PaSampleFormat, 0x20) const paUInt8 = convert(PaSampleFormat, 0x20)
# PaHostApiTypeId values # PaHostApiTypeId values
@compat const pa_host_api_names = ( @compat const pa_host_api_names = Dict(
0 => "In Development", # use while developing support for a new host API 0 => "In Development", # use while developing support for a new host API
1 => "Direct Sound", 1 => "Direct Sound",
2 => "MME", 2 => "MME",
@ -95,31 +95,31 @@ end
The stream is unidirectional, either inout or default output The stream is unidirectional, either inout or default output
see http://portaudio.com/docs/v19-doxydocs/portaudio_8h.html see http://portaudio.com/docs/v19-doxydocs/portaudio_8h.html
""" """
function Pa_OpenStream(device::PaDeviceIndex, function Pa_OpenStream(device::PaDeviceIndex,
channels::Cint, input::Bool, channels::Cint, input::Bool,
sampleFormat::PaSampleFormat, sampleFormat::PaSampleFormat,
sampleRate::Cdouble, framesPerBuffer::Culong) sampleRate::Cdouble, framesPerBuffer::Culong)
streamPtr::Array{PaStream} = PaStream[0] streamPtr::Array{PaStream} = PaStream[0]
ioParameters = Pa_StreamParameters(device, channels, ioParameters = Pa_StreamParameters(device, channels,
sampleFormat, PaTime(0.001), sampleFormat, PaTime(0.001),
Ptr{Void}(0)) Ptr{Void}(0))
if input if input
err = ccall((:Pa_OpenStream, libportaudio), PaError, err = ccall((:Pa_OpenStream, libportaudio), PaError,
(PaStream, Ref{Pa_StreamParameters}, Ptr{Void}, (PaStream, Ref{Pa_StreamParameters}, Ptr{Void},
Cdouble, Culong, Culong, Cdouble, Culong, Culong,
Ptr{PaStreamCallback}, Ptr{Void}), Ptr{PaStreamCallback}, Ptr{Void}),
streamPtr, ioParameters, Ptr{Void}(0), streamPtr, ioParameters, Ptr{Void}(0),
sampleRate, framesPerBuffer, 0, sampleRate, framesPerBuffer, 0,
Ptr{PaStreamCallback}(0), Ptr{Void}(0)) Ptr{PaStreamCallback}(0), Ptr{Void}(0))
else else
err = ccall((:Pa_OpenStream, libportaudio), PaError, err = ccall((:Pa_OpenStream, libportaudio), PaError,
(PaStream, Ptr{Void}, Ref{Pa_StreamParameters}, (PaStream, Ptr{Void}, Ref{Pa_StreamParameters},
Cdouble, Culong, Culong, Cdouble, Culong, Culong,
Ptr{PaStreamCallback}, Ptr{Void}), Ptr{PaStreamCallback}, Ptr{Void}),
streamPtr, Ptr{Void}(0), ioParameters, streamPtr, Ptr{Void}(0), ioParameters,
sampleRate, framesPerBuffer, 0, sampleRate, framesPerBuffer, 0,
Ptr{PaStreamCallback}(0), Ptr{Void}(0)) Ptr{PaStreamCallback}(0), Ptr{Void}(0))
end end
handle_status(err) handle_status(err)
streamPtr[1] streamPtr[1]
end end
@ -134,7 +134,7 @@ type Pa_AudioStream <: AudioStream
sbuffer_output_waiting::Integer sbuffer_output_waiting::Integer
parent_may_use_buffer::Bool parent_may_use_buffer::Bool
""" """
Get device parameters needed for opening with portaudio Get device parameters needed for opening with portaudio
default is input as 44100/16bit int, same as CD audio type input default is input as 44100/16bit int, same as CD audio type input
""" """
@ -150,7 +150,7 @@ type Pa_AudioStream <: AudioStream
root = AudioMixer() root = AudioMixer()
datatype = PaSampleFormat_to_T(sample_format) datatype = PaSampleFormat_to_T(sample_format)
sbuf = ones(datatype, framesPerBuffer) sbuf = ones(datatype, framesPerBuffer)
this = new(root, DeviceInfo(sample_rate, framesPerBuffer), this = new(root, DeviceInfo(sample_rate, framesPerBuffer),
show_warnings, stream, sample_format, sbuf, 0, false) show_warnings, stream, sample_format, sbuf, 0, false)
info("Scheduling PortAudio Render Task...") info("Scheduling PortAudio Render Task...")
if input if input
@ -170,7 +170,7 @@ function read_Pa_AudioStream(stream::Pa_AudioStream)
while stream.parent_may_use_buffer == false while stream.parent_may_use_buffer == false
sleep(0.001) sleep(0.001)
end end
buffer = deepcopy(stream.sbuffer) buffer = deepcopy(stream.sbuffer)
stream.parent_may_use_buffer = false stream.parent_may_use_buffer = false
return buffer return buffer
end end
@ -234,7 +234,7 @@ function portaudio_task(stream::PortAudioStream)
end end
""" """
Helper function to make the right type of buffer for various Helper function to make the right type of buffer for various
sample formats. Converts PaSampleFormat to a typeof sample formats. Converts PaSampleFormat to a typeof
""" """
function PaSampleFormat_to_T(fmt::PaSampleFormat) function PaSampleFormat_to_T(fmt::PaSampleFormat)
@ -276,7 +276,7 @@ function pa_input_task(stream::Pa_AudioStream)
end end
err = ccall((:Pa_ReadStream, libportaudio), PaError, err = ccall((:Pa_ReadStream, libportaudio), PaError,
(PaStream, Ptr{Void}, Culong), (PaStream, Ptr{Void}, Culong),
stream.stream, buffer, n) stream.stream, buffer, n)
handle_status(err, stream.show_warnings) handle_status(err, stream.show_warnings)
stream.sbuffer[1: n] = buffer[1: n] stream.sbuffer[1: n] = buffer[1: n]
stream.parent_may_use_buffer = true stream.parent_may_use_buffer = true
@ -303,12 +303,12 @@ function pa_output_task(stream::Pa_AudioStream)
end end
if (navail > 1) & (stream.parent_may_use_buffer == false) & if (navail > 1) & (stream.parent_may_use_buffer == false) &
(Pa_GetStreamWriteAvailable(stream.stream) < navail) (Pa_GetStreamWriteAvailable(stream.stream) < navail)
Pa_WriteStream(stream.stream, stream.sbuffer, Pa_WriteStream(stream.stream, stream.sbuffer,
navail, stream.show_warnings) navail, stream.show_warnings)
stream.parent_may_use_buffer = true stream.parent_may_use_buffer = true
else else
sleep(0.005) sleep(0.005)
end end
end end
catch ex catch ex
warn("Audio Output Task died with exception: $ex") warn("Audio Output Task died with exception: $ex")
@ -338,7 +338,7 @@ type PaHostApiInfo
defaultOutputDevice::PaDeviceIndex defaultOutputDevice::PaDeviceIndex
end end
@compat type PortAudioInterface <: AudioInterface type PortAudioInterface <: AudioInterface
name::AbstractString name::AbstractString
host_api::AbstractString host_api::AbstractString
max_input_channels::Int max_input_channels::Int

View file

@ -16,7 +16,7 @@ const SF_SEEK_SET = 0
const SF_SEEK_CUR = 1 const SF_SEEK_CUR = 1
const SF_SEEK_END = 2 const SF_SEEK_END = 2
@compat const EXT_TO_FORMAT = ( @compat const EXT_TO_FORMAT = Dict(
".wav" => SF_FORMAT_WAV, ".wav" => SF_FORMAT_WAV,
".flac" => SF_FORMAT_FLAC ".flac" => SF_FORMAT_FLAC
) )
@ -28,12 +28,6 @@ type SF_INFO
format::Int32 format::Int32
sections::Int32 sections::Int32
seekable::Int32 seekable::Int32
function SF_INFO(frames::Integer, samplerate::Integer, channels::Integer,
format::Integer, sections::Integer, seekable::Integer)
new(int64(frames), int32(samplerate), int32(channels), int32(format),
int32(sections), int32(seekable))
end
end end
type AudioFile type AudioFile
@ -45,7 +39,7 @@ samplerate(f::AudioFile) = f.sfinfo.samplerate
# AudioIO.open is part of the public API, but is not exported so that it # AudioIO.open is part of the public API, but is not exported so that it
# doesn't conflict with Base.open # doesn't conflict with Base.open
@compat function open(path::AbstractString, mode::AbstractString = "r", function open(path::AbstractString, mode::AbstractString = "r",
sampleRate::Integer = 44100, channels::Integer = 1, sampleRate::Integer = 44100, channels::Integer = 1,
format::Integer = 0) format::Integer = 0)
@assert channels <= 2 @assert channels <= 2
@ -66,11 +60,11 @@ samplerate(f::AudioFile) = f.sfinfo.samplerate
end end
filePtr = ccall((:sf_open, libsndfile), Ptr{Void}, filePtr = ccall((:sf_open, libsndfile), Ptr{Void},
(Ptr{Uint8}, Int32, Ptr{SF_INFO}), (Ptr{UInt8}, Int32, Ptr{SF_INFO}),
path, file_mode, &sfinfo) path, file_mode, &sfinfo)
if filePtr == C_NULL if filePtr == C_NULL
errmsg = ccall((:sf_strerror, libsndfile), Ptr{Uint8}, (Ptr{Void},), filePtr) errmsg = ccall((:sf_strerror, libsndfile), Ptr{UInt8}, (Ptr{Void},), filePtr)
error(bytestring(errmsg)) error(bytestring(errmsg))
end end
@ -132,7 +126,7 @@ Base.read(file::AudioFile) = Base.read(file, Int16)
function Base.write{T}(file::AudioFile, frames::Array{T}) function Base.write{T}(file::AudioFile, frames::Array{T})
@assert file.sfinfo.channels <= 2 @assert file.sfinfo.channels <= 2
nframes = int(length(frames) / file.sfinfo.channels) nframes = round(Int, length(frames) / file.sfinfo.channels)
if T == Int16 if T == Int16
return ccall((:sf_writef_short, libsndfile), Int64, return ccall((:sf_writef_short, libsndfile), Int64,
@ -180,7 +174,7 @@ end
typealias FilePlayer AudioNode{FileRenderer} typealias FilePlayer AudioNode{FileRenderer}
FilePlayer(file::AudioFile) = FilePlayer(FileRenderer(file)) FilePlayer(file::AudioFile) = FilePlayer(FileRenderer(file))
@compat FilePlayer(path::AbstractString) = FilePlayer(AudioIO.open(path)) FilePlayer(path::AbstractString) = FilePlayer(AudioIO.open(path))
function render(node::FileRenderer, device_input::AudioBuf, info::DeviceInfo) function render(node::FileRenderer, device_input::AudioBuf, info::DeviceInfo)
@assert node.file.sfinfo.samplerate == info.sample_rate @assert node.file.sfinfo.samplerate == info.sample_rate
@ -204,7 +198,7 @@ function render(node::FileRenderer, device_input::AudioBuf, info::DeviceInfo)
end end
end end
@compat function play(filename::AbstractString, args...) function play(filename::AbstractString, args...)
player = FilePlayer(filename) player = FilePlayer(filename)
play(player, args...) play(player, args...)
end end

View file

@ -1,6 +1,7 @@
module TestAudioIO module TestAudioIO
using FactCheck using FactCheck
using Compat
using AudioIO using AudioIO
import AudioIO.AudioBuf import AudioIO.AudioBuf
@ -43,32 +44,32 @@ facts("Array playback") do
f32 = convert(Array{Float32}, sin(phase)) f32 = convert(Array{Float32}, sin(phase))
test_stream = TestAudioStream() test_stream = TestAudioStream()
player = play(f32, test_stream) player = play(f32, test_stream)
@fact process(test_stream) => f32[1:TEST_BUF_SIZE] @fact process(test_stream) --> f32[1:TEST_BUF_SIZE]
end end
context("Playing Float64 arrays") do context("Playing Float64 arrays") do
f64 = convert(Array{Float64}, sin(phase)) f64 = convert(Array{Float64}, sin(phase))
test_stream = TestAudioStream() test_stream = TestAudioStream()
player = play(f64, test_stream) player = play(f64, test_stream)
@fact process(test_stream) => convert(AudioBuf, f64[1:TEST_BUF_SIZE]) @fact process(test_stream) --> convert(AudioBuf, f64[1:TEST_BUF_SIZE])
end end
context("Playing Int8(Signed) arrays") do context("Playing Int8(Signed) arrays") do
i8 = Int8[-127:127] i8 = Int8[-127:127;]
test_stream = TestAudioStream() test_stream = TestAudioStream()
player = play(i8, test_stream) player = play(i8, test_stream)
@fact process(test_stream)[1:255] => @fact process(test_stream)[1:255] -->
mse(convert(AudioBuf, linspace(-1.0, 1.0, 255))) mse(convert(AudioBuf, collect(linspace(-1.0, 1.0, 255))))
end end
context("Playing Uint8(Unsigned) arrays") do context("Playing UInt8(Unsigned) arrays") do
# for unsigned 8-bit audio silence is represented as 128, so the symmetric range # for unsigned 8-bit audio silence is represented as 128, so the symmetric range
# is 1-255 # is 1-255
ui8 = Uint8[1:255] ui8 = UInt8[1:255;]
test_stream = TestAudioStream() test_stream = TestAudioStream()
player = play(ui8, test_stream) player = play(ui8, test_stream)
@fact process(test_stream)[1:255] => @fact process(test_stream)[1:255] -->
mse(convert(AudioBuf, linspace(-1.0, 1.0, 255))) mse(convert(AudioBuf, collect(linspace(-1.0, 1.0, 255))))
end end
end end
@ -78,12 +79,12 @@ facts("AudioNode Stopping") do
play(node, test_stream) play(node, test_stream)
process(test_stream) process(test_stream)
stop(node) stop(node)
@fact process(test_stream) => zeros(AudioIO.AudioSample, TEST_BUF_SIZE) @fact process(test_stream) --> zeros(AudioIO.AudioSample, TEST_BUF_SIZE)
end end
facts("Audio Device Listing") do facts("Audio Device Listing") do
# there aren't any devices on the Travis machine so just test that this doesn't crash # there aren't any devices on the Travis machine so just test that this doesn't crash
@fact get_audio_devices() => issubtype(Array) @fact get_audio_devices() --> issubtype(Array)
end end
end # module TestAudioIO end # module TestAudioIO

View file

@ -1,5 +1,6 @@
module TestAudioIONodes module TestAudioIONodes
using Compat
using FactCheck using FactCheck
using AudioIO using AudioIO
import AudioIO: AudioSample, AudioBuf, AudioRenderer, AudioNode import AudioIO: AudioSample, AudioBuf, AudioRenderer, AudioNode
@ -10,7 +11,7 @@ include("testhelpers.jl")
# A TestNode just renders out 1:buf_size each frame # A TestNode just renders out 1:buf_size each frame
type TestRenderer <: AudioRenderer type TestRenderer <: AudioRenderer
buf::AudioBuf buf::AudioBuf
TestRenderer(buf_size::Integer) = new(AudioSample[1:buf_size]) TestRenderer(buf_size::Integer) = new(AudioSample[1:buf_size;])
end end
typealias TestNode AudioNode{TestRenderer} typealias TestNode AudioNode{TestRenderer}
@ -31,7 +32,7 @@ facts("Validating TestNode allocation") do
test = TestNode(test_info.buf_size) test = TestNode(test_info.buf_size)
# JIT # JIT
render(test, dev_input, test_info) render(test, dev_input, test_info)
@fact (@allocated render(test, dev_input, test_info)) => 16 @fact (@allocated render(test, dev_input, test_info)) --> 16
end end
#### AudioMixer Tests #### #### AudioMixer Tests ####
@ -43,16 +44,17 @@ facts("AudioMixer") do
context("0 Input Mixer") do context("0 Input Mixer") do
mix = AudioMixer() mix = AudioMixer()
render_output = render(mix, dev_input, test_info) render_output = render(mix, dev_input, test_info)
@fact render_output => AudioSample[] @fact render_output --> AudioSample[]
@fact (@allocated render(mix, dev_input, test_info)) => 48 # 0.4 uses 64 bytes, 0.3 uses 48
@fact (@allocated render(mix, dev_input, test_info)) --> less_than(65)
end end
context("1 Input Mixer") do context("1 Input Mixer") do
testnode = TestNode(test_info.buf_size) testnode = TestNode(test_info.buf_size)
mix = AudioMixer([testnode]) mix = AudioMixer([testnode])
render_output = render(mix, dev_input, test_info) render_output = render(mix, dev_input, test_info)
@fact render_output => AudioSample[1:test_info.buf_size] @fact render_output --> AudioSample[1:test_info.buf_size;]
@fact (@allocated render(mix, dev_input, test_info)) => 64 @fact (@allocated render(mix, dev_input, test_info)) --> 64
end end
context("2 Input Mixer") do context("2 Input Mixer") do
@ -61,17 +63,17 @@ facts("AudioMixer") do
mix = AudioMixer([test1, test2]) mix = AudioMixer([test1, test2])
render_output = render(mix, dev_input, test_info) render_output = render(mix, dev_input, test_info)
# make sure the two inputs are being added together # make sure the two inputs are being added together
@fact render_output => 2 * AudioSample[1:test_info.buf_size] @fact render_output --> 2 * AudioSample[1:test_info.buf_size;]
@fact (@allocated render(mix, dev_input, test_info)) => 96 @fact (@allocated render(mix, dev_input, test_info)) --> 96
# now we'll stop one of the inputs and make sure it gets removed # now we'll stop one of the inputs and make sure it gets removed
stop(test1) stop(test1)
render_output = render(mix, dev_input, test_info) render_output = render(mix, dev_input, test_info)
# make sure the two inputs are being added together # make sure the two inputs are being added together
@fact render_output => AudioSample[1:test_info.buf_size] @fact render_output --> AudioSample[1:test_info.buf_size;]
stop(mix) stop(mix)
render_output = render(mix, dev_input, test_info) render_output = render(mix, dev_input, test_info)
@fact render_output => AudioSample[] @fact render_output --> AudioSample[]
end end
end end
@ -81,25 +83,25 @@ facts("SinOSC") do
freq = 440 freq = 440
# note that this range includes the end, which is why there are # note that this range includes the end, which is why there are
# sample_rate+1 samples # sample_rate+1 samples
t = linspace(0, 1, int(test_info.sample_rate+1)) t = linspace(0, 1, round(Int, test_info.sample_rate+1))
test_vect = convert(AudioBuf, sin(2pi * t * freq)) test_vect = convert(AudioBuf, sin(2pi * t * freq))
context("Fixed Frequency") do context("Fixed Frequency") do
osc = SinOsc(freq) osc = SinOsc(freq)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@fact mse(render_output, test_vect[1:test_info.buf_size]) => @fact mse(render_output, test_vect[1:test_info.buf_size]) -->
lessthan(MSE_THRESH) lessthan(MSE_THRESH)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@fact mse(render_output, @fact mse(render_output,
test_vect[test_info.buf_size+1:2*test_info.buf_size]) => test_vect[test_info.buf_size+1:2*test_info.buf_size]) -->
lessthan(MSE_THRESH) lessthan(MSE_THRESH)
@fact (@allocated render(osc, dev_input, test_info)) => 64 @fact (@allocated render(osc, dev_input, test_info)) --> 64
stop(osc) stop(osc)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@fact render_output => AudioSample[] @fact render_output --> AudioSample[]
end end
context("Testing SinOsc with signal input") do context("Testing SinOsc with signal input") do
t = linspace(0, 1, int(test_info.sample_rate+1)) t = linspace(0, 1, round(Int, test_info.sample_rate+1))
f = 440 .- t .* (440-110) f = 440 .- t .* (440-110)
dt = 1 / test_info.sample_rate dt = 1 / test_info.sample_rate
# NOTE - this treats the phase as constant at each sample, which isn't strictly # NOTE - this treats the phase as constant at each sample, which isn't strictly
@ -112,14 +114,14 @@ facts("SinOSC") do
freq = LinRamp(440, 110, 1) freq = LinRamp(440, 110, 1)
osc = SinOsc(freq) osc = SinOsc(freq)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@fact mse(render_output, expected[1:test_info.buf_size]) => @fact mse(render_output, expected[1:test_info.buf_size]) -->
lessthan(MSE_THRESH) lessthan(MSE_THRESH)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@fact mse(render_output, @fact mse(render_output,
expected[test_info.buf_size+1:2*test_info.buf_size]) => expected[test_info.buf_size+1:2*test_info.buf_size]) -->
lessthan(MSE_THRESH) lessthan(MSE_THRESH)
# give a bigger budget here because we're rendering 2 nodes # give a bigger budget here because we're rendering 2 nodes
@fact (@allocated render(osc, dev_input, test_info)) => 160 @fact (@allocated render(osc, dev_input, test_info)) --> 160
end end
end end
@ -127,7 +129,7 @@ facts("AudioInput") do
node = AudioInput() node = AudioInput()
test_data = rand(AudioSample, test_info.buf_size) test_data = rand(AudioSample, test_info.buf_size)
render_output = render(node, test_data, test_info) render_output = render(node, test_data, test_info)
@fact render_output => test_data @fact render_output --> test_data
end end
facts("ArrayPlayer") do facts("ArrayPlayer") do
@ -135,13 +137,13 @@ facts("ArrayPlayer") do
v = rand(AudioSample, 44100) v = rand(AudioSample, 44100)
player = ArrayPlayer(v) player = ArrayPlayer(v)
render_output = render(player, dev_input, test_info) render_output = render(player, dev_input, test_info)
@fact render_output => v[1:test_info.buf_size] @fact render_output --> v[1:test_info.buf_size]
render_output = render(player, dev_input, test_info) render_output = render(player, dev_input, test_info)
@fact render_output => v[(test_info.buf_size + 1) : (2*test_info.buf_size)] @fact render_output --> v[(test_info.buf_size + 1) : (2*test_info.buf_size)]
@fact (@allocated render(player, dev_input, test_info)) => 192 @fact (@allocated render(player, dev_input, test_info)) --> 192
stop(player) stop(player)
render_output = render(player, dev_input, test_info) render_output = render(player, dev_input, test_info)
@fact render_output => AudioSample[] @fact render_output --> AudioSample[]
end end
context("testing end of vector") do context("testing end of vector") do
@ -150,7 +152,7 @@ facts("ArrayPlayer") do
player = ArrayPlayer(v) player = ArrayPlayer(v)
render(player, dev_input, test_info) render(player, dev_input, test_info)
render_output = render(player, dev_input, test_info) render_output = render(player, dev_input, test_info)
@fact render_output => v[test_info.buf_size+1:end] @fact render_output --> v[test_info.buf_size+1:end]
end end
end end
@ -158,35 +160,35 @@ facts("Gain") do
context("Constant Gain") do context("Constant Gain") do
gained = TestNode(test_info.buf_size) * 0.75 gained = TestNode(test_info.buf_size) * 0.75
render_output = render(gained, dev_input, test_info) render_output = render(gained, dev_input, test_info)
@fact render_output => 0.75 * AudioSample[1:test_info.buf_size] @fact render_output --> 0.75 * AudioSample[1:test_info.buf_size;]
@fact (@allocated render(gained, dev_input, test_info)) => 32 @fact (@allocated render(gained, dev_input, test_info)) --> 32
end end
context("Gain by a Signal") do context("Gain by a Signal") do
gained = TestNode(test_info.buf_size) * TestNode(test_info.buf_size) gained = TestNode(test_info.buf_size) * TestNode(test_info.buf_size)
render_output = render(gained, dev_input, test_info) render_output = render(gained, dev_input, test_info)
@fact render_output => AudioSample[1:test_info.buf_size] .* AudioSample[1:test_info.buf_size] @fact render_output --> AudioSample[1:test_info.buf_size;] .* AudioSample[1:test_info.buf_size;]
@fact (@allocated render(gained, dev_input, test_info)) => 48 @fact (@allocated render(gained, dev_input, test_info)) --> 48
end end
end end
facts("LinRamp") do facts("LinRamp") do
ramp = LinRamp(0.25, 0.80, 1) ramp = LinRamp(0.25, 0.80, 1)
expected = convert(AudioBuf, linspace(0.25, 0.80, int(test_info.sample_rate+1))) expected = convert(AudioBuf, collect(linspace(0.25, 0.80, round(Int, test_info.sample_rate+1))))
render_output = render(ramp, dev_input, test_info) render_output = render(ramp, dev_input, test_info)
@fact mse(render_output, expected[1:test_info.buf_size]) => @fact mse(render_output, expected[1:test_info.buf_size]) -->
lessthan(MSE_THRESH) lessthan(MSE_THRESH)
render_output = render(ramp, dev_input, test_info) render_output = render(ramp, dev_input, test_info)
@fact mse(render_output, @fact mse(render_output,
expected[(test_info.buf_size+1):(2*test_info.buf_size)]) => expected[(test_info.buf_size+1):(2*test_info.buf_size)]) -->
lessthan(MSE_THRESH) lessthan(MSE_THRESH)
@fact (@allocated render(ramp, dev_input, test_info)) => 64 @fact (@allocated render(ramp, dev_input, test_info)) --> 64
end end
facts("Offset") do facts("Offset") do
offs = TestNode(test_info.buf_size) + 0.5 offs = TestNode(test_info.buf_size) + 0.5
render_output = render(offs, dev_input, test_info) render_output = render(offs, dev_input, test_info)
@fact render_output => 0.5 + AudioSample[1:test_info.buf_size] @fact render_output --> 0.5 + AudioSample[1:test_info.buf_size;]
@fact (@allocated render(offs, dev_input, test_info)) => 32 @fact (@allocated render(offs, dev_input, test_info)) --> 32
end end
end # module TestAudioIONodes end # module TestAudioIONodes

View file

@ -1,19 +1,20 @@
module TestSndfile module TestSndfile
include("testhelpers.jl") using Compat
using AudioIO
using FactCheck using FactCheck
using AudioIO
import AudioIO: DeviceInfo, render, AudioSample, AudioBuf import AudioIO: DeviceInfo, render, AudioSample, AudioBuf
include("testhelpers.jl")
facts("WAV file write/read") do facts("WAV file write/read") do
fname = Pkg.dir("AudioIO", "test", "sinwave.wav") fname = Pkg.dir("AudioIO", "test", "sinwave.wav")
srate = 44100 srate = 44100
freq = 440 freq = 440
t = [0 : 2 * srate - 1] / srate t = collect(0 : 2 * srate - 1) / srate
phase = 2 * pi * freq * t phase = 2 * pi * freq * t
reference = int16((2 ^ 15 - 1) * sin(phase)) reference = round(Int16, (2 ^ 15 - 1) * sin(phase))
AudioIO.open(fname, "w") do f AudioIO.open(fname, "w") do f
write(f, reference) write(f, reference)
@ -21,12 +22,12 @@ facts("WAV file write/read") do
# test basic reading # test basic reading
AudioIO.open(fname) do f AudioIO.open(fname) do f
@fact f.sfinfo.channels => 1 @fact f.sfinfo.channels --> 1
@fact f.sfinfo.frames => 2 * srate @fact f.sfinfo.frames --> 2 * srate
actual = read(f) actual = read(f)
@fact length(reference) => length(actual) @fact length(reference) --> length(actual)
@fact reference => actual[:, 1] @fact reference --> actual[:, 1]
@fact samplerate(f) => srate @fact samplerate(f) --> srate
end end
# test seeking # test seeking
@ -41,21 +42,21 @@ facts("WAV file write/read") do
# convert to floating point because that's what AudioIO uses natively # convert to floating point because that's what AudioIO uses natively
expected = convert(AudioBuf, reference ./ (2^15)) expected = convert(AudioBuf, reference ./ (2^15))
buf = render(node, input, test_info) buf = render(node, input, test_info)
@fact expected[1:bufsize] => buf[1:bufsize] @fact expected[1:bufsize] --> buf[1:bufsize]
buf = render(node, input, test_info) buf = render(node, input, test_info)
@fact expected[bufsize+1:2*bufsize] => buf[1:bufsize] @fact expected[bufsize+1:2*bufsize] --> buf[1:bufsize]
end end
end end
facts("Stereo file reading") do facts("Stereo file reading") do
fname = Pkg.dir("AudioIO", "test", "440left_880right.wav") fname = Pkg.dir("AudioIO", "test", "440left_880right.wav")
srate = 44100 srate = 44100
t = [0 : 2 * srate - 1] / srate t = collect(0:(2 * srate - 1)) / srate
expected = int16((2^15-1) * hcat(sin(2pi*t*440), sin(2pi*t*880))) expected = round(Int16, (2^15-1) * hcat(sin(2pi*t*440), sin(2pi*t*880)))
AudioIO.open(fname) do f AudioIO.open(fname) do f
buf = read(f) buf = read(f)
@fact buf => mse(expected, 5) @fact buf --> mse(expected, 5)
end end
end end
@ -67,15 +68,15 @@ facts("Stereo file rendering") do
bufsize = 1024 bufsize = 1024
input = zeros(AudioSample, bufsize) input = zeros(AudioSample, bufsize)
test_info = DeviceInfo(srate, bufsize) test_info = DeviceInfo(srate, bufsize)
t = [0 : 2 * srate - 1] / srate t = collect(0 : 2 * srate - 1) / srate
expected = convert(AudioBuf, 0.5 * (sin(2pi*t*440) + sin(2pi*t*880))) expected = convert(AudioBuf, 0.5 * (sin(2pi*t*440) + sin(2pi*t*880)))
AudioIO.open(fname) do f AudioIO.open(fname) do f
node = FilePlayer(f) node = FilePlayer(f)
buf = render(node, input, test_info) buf = render(node, input, test_info)
@fact buf[1:bufsize] => mse(expected[1:bufsize]) @fact buf[1:bufsize] --> mse(expected[1:bufsize])
buf = render(node, input, test_info) buf = render(node, input, test_info)
@fact buf[1:bufsize] => mse(expected[bufsize+1:2*bufsize]) @fact buf[1:bufsize] --> mse(expected[bufsize+1:2*bufsize])
end end
end end