forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sound.jl
169 lines (148 loc) · 5.54 KB
/
sound.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
## -*-Julia-*-
## Test suite for Julia's sound module
require("../extras/sound.jl")
require("../extras/options.jl")
import Sound.*
import OptionsMod.*
# These float array comparison functions are from dists.jl
function absdiff{T<:Real}(current::AbstractArray{T}, target::AbstractArray{T})
@assert all(size(current) == size(target))
max(abs(current - target))
end
function reldiff{T<:Real}(current::T, target::T)
abs((current - target)/(bool(target) ? target : 1))
end
function reldiff{T<:Real}(current::AbstractArray{T}, target::AbstractArray{T})
@assert all(size(current) == size(target))
max([reldiff(current[i], target[i]) for i in 1:numel(target)])
end
## Test wavread and wavwrite
wav_header_size = 36
## Generate some wav files for writing and reading
for fs = (8000,11025,22050,44100,48000,96000,192000), nbits = (8,16,24,32), nsamples = convert(Array{Int}, [0, logspace(1, 4, 4)]), nchans = 1:4
## Test wav files
## The tolerance is based on the number of bits used to encode the file in wavwrite
tol = nbits < 32 ? 2.0 / (2^nbits - 1) : 2.0 / eps(Float32)
in_data = rand(nsamples, nchans)
@assert max(in_data) <= 1.0
@assert min(in_data) >= -1.0
io = memio()
wavwrite(in_data, io, @options Fs=fs nbits=nbits)
flush(io)
## Check that the data length makes sense
data_length = nsamples * nchans * nbits / 8
file_size = position(io)
# add "8" for the RIFF + size fields
@assert file_size == wav_header_size + data_length + 8
## Check for the common header identifiers
seek(io, 0)
@assert read(io, Uint8, 4) == b"RIFF"
@assert read(io, Uint32) == file_size - 8
@assert read(io, Uint8, 4) == b"WAVE"
## Check that wavread works on the wavwrite produced memory
seek(io, 0)
sz = wavread(io, @options format="size")
@assert sz == (nsamples, nchans)
seek(io, 0)
out_data, out_fs, out_nbits, out_extra = wavread(io)
@assert length(out_data) == nsamples * nchans
@assert size(out_data, 1) == nsamples
@assert size(out_data, 2) == nchans
@assert typeof(out_data) == Array{Float64, 2}
@assert out_fs == fs
@assert out_nbits == nbits
@assert out_extra == None
@assert absdiff(out_data, in_data) < tol
## test the "subrange" option.
if nsamples > 0
seek(io, 0)
# Don't convert to Int, test if passing a float (nsamples/2) behaves as expected
subsamples = min(10, nsamples / 2)
out_data, out_fs, out_nbits, out_extra = wavread(io, @options subrange=subsamples)
@assert length(out_data) == subsamples * nchans
@assert size(out_data, 1) == subsamples
@assert size(out_data, 2) == nchans
@assert typeof(out_data) == Array{Float64, 2}
@assert out_fs == fs
@assert out_nbits == nbits
@assert out_extra == None
@assert absdiff(out_data, in_data[1:int(subsamples), :]) < tol
seek(io, 0)
sr = convert(Int, min(5, nsamples / 2)):convert(Int, min(23, nsamples - 1))
out_data, out_fs, out_nbits, out_extra = wavread(io, @options subrange=sr)
@assert length(out_data) == length(sr) * nchans
@assert size(out_data, 1) == length(sr)
@assert size(out_data, 2) == nchans
@assert typeof(out_data) == Array{Float64, 2}
@assert out_fs == fs
@assert out_nbits == nbits
@assert out_extra == None
@assert absdiff(out_data, in_data[sr, :]) < tol
end
end
## Test native encoding of 8 bits
for nchans = (1,2,4)
in_data_8 = reshape(typemin(Uint8):typemax(Uint8), int(256 / nchans), nchans)
io = memio()
wavwrite(in_data_8, io)
flush(io)
seek(io, 0)
out_data_8, fs, nbits, extra = wavread(io, @options format="native")
@assert fs == 8000
@assert nbits == 8
@assert extra == None
@assert in_data_8 == out_data_8
end
## Test native encoding of 16 bits
for nchans = (1,2,4)
in_data_16 = reshape(typemin(Int16):typemax(Int16), int(65536 / nchans), nchans)
io = memio()
wavwrite(in_data_16, io)
flush(io)
seek(io, 0)
out_data_16, fs, nbits, extra = wavread(io, @options format="native")
@assert fs == 8000
@assert nbits == 16
@assert extra == None
@assert in_data_16 == out_data_16
end
## Test native encoding of 24 bits
for nchans = (1,2,4)
in_data_24 = convert(Array{Int32}, reshape(-63:64, int(128 / nchans), nchans))
io = memio()
wavwrite(in_data_24, io)
flush(io)
seek(io, 0)
out_data_24, fs, nbits, extra = wavread(io, @options format="native")
@assert fs == 8000
@assert nbits == 24
@assert extra == None
@assert in_data_24 == out_data_24
end
## Test encoding 32 bit values
for nchans = (1,2,4)
in_data_single = convert(Array{Float32}, reshape(linspace(-1.0, 1.0, 128), int(128 / nchans), nchans))
io = memio()
wavwrite(in_data_single, io)
flush(io)
seek(io, 0)
out_data_single, fs, nbits, extra = wavread(io, @options format="native")
@assert fs == 8000
@assert nbits == 32
@assert extra == None
@assert in_data_single == out_data_single
end
## Test encoding 32 bit values outside the valid range
for nchans = (1,2,4)
nsamps = int(128 / nchans)
in_data_single = convert(Array{Float32}, reshape(-63:64, nsamps, nchans))
io = memio()
wavwrite(in_data_single, io)
flush(io)
seek(io, 0)
out_data_single, fs, nbits, extra = wavread(io, @options format="native")
@assert fs == 8000
@assert nbits == 32
@assert extra == None
@assert [clamp(in_data_single[i, j], float32(-1), float32(1)) for i = 1:nsamps, j = 1:nchans] == out_data_single
end