dancasimiro / wav.jl Goto Github PK
View Code? Open in Web Editor NEWJulia package for working with WAV files
License: Other
Julia package for working with WAV files
License: Other
In wavwrite
, the length of the data chunk is used for both the header and the data chunk size.
data_length::UInt32 = size(samples, 1) * block_align
# ...
WAV.write_standard_header(io, data_length) # < here
# ...
WAV.write(io, b"data")
WAV.write_le(io, data_length)
WAV.write_data(io, fmt, samples)
This results in an incorrect size in the header in the case where custom chunks have been supplied.
The fix looks something like this:
data_length::UInt32 = size(samples, 1) * block_align
# (4 byte id + 4 byte length + data length) for each custom chunk
extra_length = 8 * length(chunks) + sum([length(c) for (_, c) in chunks])
# ...
WAV.write_standard_header(io, data_length + extra_length) # < add extra length here
# ...
WAV.write(io, b"data")
WAV.write_le(io, data_length) # < this bit stays the same
WAV.write_data(io, fmt, samples)
Thanks for your work on this package, it's fantastic 👍
currently on Julia v1.0 the version installed with Pkg.add("WAV.jl")
fails to load with an error related to Libdl. It looks like fixes for this issue were merged into master dc23ad1 but no new release has been tagget yet, so they're not available when installing the package.
The current parser assumes that the data fields in a (sub)chunk fills up the entire chunk size. I have encountered WAV files with chunk padding, that means the next chunk starts only after a few unused padding bytes. Before reading the next subchunk header, you should explicitly seek to the next subchunk start as indicated by the actual chunk size in the chunk header instead on relying on things lining up.
When accessing a subrange in a WAV file, wavread errors when the sample number is 59614786 or higher. (This seems large, but I routinely have to deal with 60 minute WAV files sampled at 50 000 Hz, meaning that there are 180 000 000 samples in the file.)
Here is an example of a function call that generates the error.
seekstart(infile)
wave, _, _, _ = wavread(infile, subrange=59614784:59614786, format="native")
In the call above infile
is an open WAV file sampled at 24 000 Hz with a total of 76392005 16-bit samples. If I make the following call, there is no error, and wavread
works normally.
seekstart(infile)
wave, _, _, _ = wavread(infile, subrange=59614784:59614785, format="native")
Here is the error message produced by the first call to wavread
(above) in a Jupyter notebook.
InexactError: check_top_bit(Int64, 18446744073709551614)
Stacktrace:
[1] throw_inexacterror(f::Symbol, #unused#::Type{Int64}, val::UInt64)
@ Core ./boot.jl:602
[2] check_top_bit
@ ./boot.jl:616 [inlined]
[3] toInt64
@ ./boot.jl:677 [inlined]
[4] Int64
@ ./boot.jl:752 [inlined]
[5] convert
@ ./number.jl:7 [inlined]
[6] cconvert
@ ./essentials.jl:396 [inlined]
[7] skip
@ ./iostream.jl:43 [inlined]
[8] read_pcm_samples(io::IOStream, chunk_size::UInt32, fmt::WAVFormat, subrange::UnitRange{Int64})
@ WAV ~/.julia/packages/WAV/eEWw6/src/WAV.jl:332
[9] read_data(io::IOStream, chunk_size::UInt32, fmt::WAVFormat, format::String, subrange::UnitRange{Int64})
@ WAV ~/.julia/packages/WAV/eEWw6/src/WAV.jl:608
[10] wavread(io::IOStream; subrange::UnitRange{Int64}, format::String)
@ WAV ~/.julia/packages/WAV/eEWw6/src/WAV.jl:801
[11] top-level scope
@ In[78]:2
[12] eval
@ ./boot.jl:360 [inlined]
[13] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
PackageEvaluator.jl is a script that runs nightly. It attempts to load all Julia packages and run their tests (if available) on both the stable version of Julia (0.3) and the nightly build of the unstable version (0.4). The results of this script are used to generate a package listing enhanced with testing results.
Tests pass.
Tests fail, but package loads.
Tests pass.
means that PackageEvaluator found the tests for your package, executed them, and they all passed.
Tests fail, but package loads.
means that PackageEvaluator found the tests for your package, executed them, and they didn't pass. However, trying to load your package with using
worked.
This error on Julia 0.4 is possibly due to recently merged pull request JuliaLang/julia#8420.
This issue was filed because your testing status became worse. No additional issues will be filed if your package remains in this state, and no issue will be filed if it improves. If you'd like to opt-out of these status-change messages, reply to this message saying you'd like to and @IainNZ will add an exception. If you'd like to discuss PackageEvaluator.jl please file an issue at the repository. For example, your package may be untestable on the test machine due to a dependency - an exception can be added.
Test log:
>>> 'Pkg.add("WAV")' log
INFO: Installing WAV v0.3.0
INFO: Package database updated
>>> 'using WAV' log
Julia Version 0.4.0-dev+842
Commit e5d8c1a (2014-09-29 06:50 UTC)
Platform Info:
System: Linux (x86_64-unknown-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
LAPACK: libopenblas
LIBM: libopenlibm
LLVM: libLLVM-3.3
>>> test log
ERROR: InexactError()
in write_pcm_samples at /home/idunning/pkgtest/.julia/v0.4/WAV/src/WAV.jl:570
in write_data at /home/idunning/pkgtest/.julia/v0.4/WAV/src/WAV.jl:620
in wavwrite at /home/idunning/pkgtest/.julia/v0.4/WAV/src/WAV.jl:743
in anonymous at no file:151
in include at ./boot.jl:245
in include_from_node1 at loading.jl:128
in process_options at ./client.jl:285
in _start at ./client.jl:354
in _start_3B_3625 at /home/idunning/julia04/usr/bin/../lib/julia/sys.so
while loading /home/idunning/pkgtest/.julia/v0.4/WAV/test/runtests.jl, in expression starting on line 148
INFO: Testing WAV
=================================[ ERROR: WAV ]=================================
failed process: Process(`/home/idunning/julia04/usr/bin/julia /home/idunning/pkgtest/.julia/v0.4/WAV/test/runtests.jl`, ProcessExited(1)) [1]
================================================================================
INFO: No packages to install, update or remove
ERROR: WAV had test errors
in error at error.jl:21
in test at pkg/entry.jl:719
in anonymous at pkg/dir.jl:28
in cd at ./file.jl:20
in cd at pkg/dir.jl:28
in test at pkg.jl:68
in process_options at ./client.jl:213
in _start at ./client.jl:354
in _start_3B_3625 at /home/idunning/julia04/usr/bin/../lib/julia/sys.so
>>> end of log
(v1.0) pkg> test WAV
Testing WAV
Status /var/folders/63/pvzb2kfx2cg8_g2m5pchdwrh0000gn/T/tmpK4A6dT/Manifest.toml
[5789e2e9] FileIO v1.0.1
[8149f6b0] WAV v0.9.0
[2a0f44e3] Base64 [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Base64
]
[ade2ca70] Dates [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Dates
]
[8ba89e20] Distributed [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Distributed
]
[b77e0a4c] InteractiveUtils [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/InteractiveUtils
]
[76f85450] LibGit2 [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/LibGit2
]
[8f399da3] Libdl [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Libdl
]
[37e2e46d] LinearAlgebra [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/LinearAlgebra
]
[56ddb016] Logging [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Logging
]
[d6f4376e] Markdown [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Markdown
]
[44cfe95a] Pkg [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Pkg
]
[de0858da] Printf [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Printf
]
[3fa0cd96] REPL [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/REPL
]
[9a3f8284] Random [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Random
]
[ea8e919c] SHA [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/SHA
]
[9e88b42a] Serialization [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Serialization
]
[6462fe0b] Sockets [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Sockets
]
[8dfed614] Test [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Test
]
[cf7118a7] UUIDs [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/UUIDs
]
[4ec0a83e] Unicode [/Applications/Julia-1.0.app/Contents/Resources/julia/bin/../share/julia/stdlib/v1.0/Unicode
]
ERROR: LoadError: InitError: UndefVarError: Libdl not defined
Stacktrace:
[1] init() at /Users/Tony/.julia/packages/WAV/npPEy/src/WAV.jl:12
[2] _include_from_serialized(::String, ::Array{Any,1}) at ./loading.jl:627
[3] macro expansion at ./logging.jl:312 [inlined]
[4] _require_search_from_serialized(::Base.PkgId, ::String) at ./loading.jl:698
[5] _require(::Base.PkgId) at ./loading.jl:931
[6] require(::Base.PkgId) at ./loading.jl:852
[7] macro expansion at ./logging.jl:311 [inlined]
[8] require(::Module, ::Symbol) at ./loading.jl:834
[9] include at ./boot.jl:317 [inlined]
[10] include_relative(::Module, ::String) at ./loading.jl:1038
[11] include(::Module, ::String) at ./sysimg.jl:29
[12] include(::String) at ./client.jl:388
[13] top-level scope at none:0
during initialization of module WAV
in expression starting at /Users/Tony/.julia/packages/WAV/npPEy/test/runtests.jl:3
ERROR: Package WAV errored during testing
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
For data = wavread(string)
, I expect the type of data
to be Array{Float64,2}
. Instead, the type of data
is (Array{Float64,2},Uint32,Uint16,UnionType)
.
To work around this problem, I have been doing this: data, _ = wavread(string)
, where _
is a throw-away variable, which causes Julia to unpack the tuple.
I suspect you could avoid this problem by changing:
const result = wavread(io, subrange=subrange, format=format)
close(io)
return result
to:
const samples, sample_rate, nbits, opt = wavread(io, subrange=subrange, format=format)
close(io)
return (samples, sample_rate, nbits, opt)
I am new to Julia, so I could be wrong.
The version currently in METADATA.jl (and therefore installed by Pkg/Pkg2) does not work with recent versions of Julia. Either the REQUIRE file should be updated (add Julia 0.1.0 as a requirement, maybe?) or the package should be updated to work with newer versions.
I tried reading the attached wav file, but it did not work. I am able to read other .wav files. GitHub does not allow for attaching wav files, so I changed the extension to .png. You will need to rename the attached file back to .wav.
I'm running Julia 0.3.5 in JuliaBox. I also had the same trouble running Julia 0.3.3 in linux.
Steps to reproduce:
julia> using WAV
julia> y = wavread("sample.wav")
Error message:
in read! at iostream.jl:196
in wavread at /home/juser/.julia/v0.3/WAV/src/WAV.jl:645
in wavread at /home/juser/.julia/v0.3/WAV/src/WAV.jl:668
I typed the above because copy/paste isn't working from JuliaBox.
I don't think that there is anything wrong with the file. I am able to read it in Adobe Audition and Audacity.
I verified that I can download the posted sample.png, rename to sample.wav and that it is still readable in Adobe Audition.
This .wav file is 16-bit mono at a sampling rate of 24kHz.
I appreciate the work you're doing here. I would greatly appreciate the resolution of this issue.
This is actually a question, not an issue...
I'm a bit confused about the second table in the wavwrite
section of the documentation (the table about floating point values). What does the "Output Format" column of this table mean? For example, based on the second row of that table, I thought that if I passed a vector of doubles (y data) to the wavwrite
function with nbits=16, the function would convert the y data to 16 bit integers, mapping the y data range to the range -32768:32767 before writing the data to the output file. However, if I try to do that, I get the following error message:
ERROR: 16 bits is not supported for WAVE_FORMAT_IEEE_FLOAT.
Of course I can do the conversion to Int16 myself before calling wavwrite
, but in that case I don't know what the last column of the table means. Right after the table, one can read:
"Floating point (single and double precision) values are written to the file unaltered. The library will not modify the data range or representation."
This suggests that I do have to do the conversion myself before calling wavwrite
...
Hi Dan,
It might be good to mention FLAC.jl under Other Julia Audio Packages in READM.md.
In particular this package has a nice simple mmap() based WAV interface:
https://github.com/dmbates/FLAC.jl/blob/master/src/WAV.jl
I'm hearing an artifact (a buzzing sound) when I play a sinusoid using wavplay. However, when I write the signal to a .wav file and use another player, the sound is clean.
julia> using WAV
julia> Ta=1/16000;
julia> t=0:Ta:2;
julia> s=0.45sin.(2πt1000);
julia> wavplay(s,1/Ta)
No artifact using wavwrite(s, "test.wav", Fs=1/Ta)
I'm on an 2012 iMac with MacOS 10.13.6
I need to be able to write 32-bit and 64-bit IEEE floating-point format WAV files with values outside the [-1,1] range. The WAV format supports this, and I have been exchanging such files for a long time between Python and REAPER.
In WAV.jl, I see that this function clamps values in such files to [-1, 1] with no user option:
function write_ieee_float_samples(io::IO, samples, floatType)
When rendering such files to a digital-to-analog converter (DAC), I can see the need for clamping. In my case, however, there is further processing of the WAV file before the DAC. This clamping causes a severe distortion for me in many cases. I propose solving the problem in one of these ways:
If I loop through a directory with a large number of wav files using
for s in readdir()
x = wavread(s)
end
after about 200 or so files, I get a "Too many open files" error in wavread at /Users/cupcake/.julia/WAV/src/WAV.jl:392. This error doesn't seem to be consistent however. Sometimes I am able to read thousands of files with no problem. I'm not sure if this issue in specific to the WAV package, Julia, or my own incorrect usage, but I thought I'd report it here. Thanks.
Using Julia 0.4.1, any call to wavread
on an existing WAV file (or at least on all the files I've tried so far) results in the following:
ERROR: InexactError()
in convert at int.jl:172
in read_pcm_samples at /home/me/.julia/v0.4/WAV/src/WAV.jl:237
in read_data at /home/me/.julia/v0.4/WAV/src/WAV.jl:499
in wavread at /home/me/.julia/v0.4/WAV/src/WAV.jl:618
in anonymous at /home/me/.julia/v0.4/WAV/src/WAV.jl:628
in open at iostream.jl:114
in wavread at /home/me/.julia/v0.4/WAV/src/WAV.jl:627
I'm trying to this package by running an example written in README.md
using WAV
fs = 8e3
t = 0.0:1/fs:prevfloat(1.0)
f = 1e3
y = sin.(2pi * f * t) * 0.1
wavwrite(y, "example.wav", Fs=fs)
y, fs = wavread("example.wav")
y = sin.(2pi * 2f * t) * 0.1
wavappend(y, "example.wav")
y, fs = wavread("example.wav")
wavplay(y, fs)
However, wavplay(y, fs)
does not work due to the following error
julia> wavplay(y, fs)
ERROR: MethodError: no method matching wavplay(::Array{Float64,2}, ::Float32)
Closest candidates are:
wavplay(::Any) at /Users/terasakisatoshi/.julia/packages/WAV/T2P9V/src/WAV.jl:38
Stacktrace:
[1] top-level scope at REPL[11]:1
Here is my environment:
julia> versioninfo()
Julia Version 1.5.0
Commit 96786e22cc (2020-08-01 23:44 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin18.7.0)
CPU: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
JULIA_EDITOR = code
JULIA_NUM_THREADS = 16
If I write a wav file in Julia as follows:
fs = 48000
nbits = 32
ns = (rand(24000,2) - 0.5)/100
wavwrite(ns, "wsnd_PCM.wav", Fs=fs, nbits=nbits, compression=WAVE_FORMAT_PCM)
wavwrite(ns, "wsnd_IEEE.wav", Fs=fs, nbits=nbits, compression=WAVE_FORMAT_IEEE_FLOAT)
it cannot be read either in Python through the scipy.io.wavfile.read function, or in MATLAB. MATLAB returns the following error: "Error using wavread (line 165)
Invalid Wave File. Reason: Data compression format (Format #65534) is not
supported.". The Python error is less clear. While this may not be a bug in WAV.jl, it would be nice to have full interoperability between WAV.jl, the scipy functions and the MATLAB ones.
Hello,
I think it is great there is WAV file reading support in Julia.
For my current application I need to process audio data that is dynamically modified on the unix pipeline. Typically the modification happens with sox
, and I want to add modifications (or read the pipeline) with Julia.
With a little trick you can read from an IO
buffer that basically is a `cmd`
function Base.skip(::Base.Process, Uint64) end
or even from a pipeline(`cmd1`, `cmd2`)
with an additional
function Base.skip(::Base.ProcessChain, Uint64) end
assuming we won't actually want to skip data on the pipeline.
However, when the cmd can't predict the wav length and can't seek back to fix it (as you can't on a unix pipeline), tricking readwav
this way fails because it is trying to consume more data than available. E.g., with a cmd=`sox -t wav - -t wav - speed 1.1`
sox WARN wav: Length in output .wav header will be wrong since can't seek to fix it
ERROR: LoadError: EOFError: read end of file
Stacktrace:
[1] unsafe_read(::Base.PipeEndpoint, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:810
Sox actually warns about the trouble with the header being wrong, but still, since this is a still a common pattern in, e.g, Kaldi, it would be nice if wavread
could be modified in a way that it can read from a pipeline, and fix the length afterwards.
I currently add a "sox -t wav - -t raw -r16000 -"
on the pipeline I am reading from and then use reinterpret(Int16, read(pipeline([`$p` for p in pipe]...))) / 32768
, effectively not using WAV.jl
at all, which is a bit of a shame.
So support for reading from a pipeline would be great!
wavread appears to read the entire file, even if a subrange is specified. this makes it difficult to work with .wav files that are too big to fit into memory.
I am working on porting a project that just analyzes the mono singles of audio samples..
Not sure how it was done in Python, but now trying to just get a working copy of my workflow into Julialang.. is there a quick way to indicate I want to read the wav into a mono?
Thanks for this library, I haven't found a lot of audio processing other than this library.
should probably mention in the documentation the existence of similar functionality provided by https://github.com/ssfrr/AudioIO.jl. their license is GPL b/c of the dependence on http://www.mega-nerd.com/libsndfile/.
I tried (saving and) loading as in issue #52
and:
julia> @time y2, fs = wavread("test.wav");
1.144121 seconds (564.27 k allocations: 223.779 MiB, 16.12% gc time, 76.35% compilation time)
julia> @time y2, fs = wavread("test.wav");
0.156857 seconds (60 allocations: 190.738 MiB, 18.48% gc time)
julia> @time y2, fs = wavread("test.wav");
0.232146 seconds (60 allocations: 190.738 MiB, 43.91% gc time)
julia> @time y2, fs = wavread("test.wav");
0.143521 seconds (60 allocations: 190.738 MiB, 10.43% gc time)
a)
The first load is slower (and precompiling can presumably be improved, I know about that, see recent blog post; for now only filing an issue so not forgotten).
b)
After first run (no longer compilation overhead) still doesn't match Python:
a = time(); y, fs = read("test.wav"); time() - a
0.06549859046936035
Loading speed may not be to critical, but I assume this is not a constant factor (excepting first run overhead) and grows linearly with file size? Since it's seems to be a GC issue (at first I thought variable load on my machine) I think at least it's not an issue after loading (simply a memory buffer, and using/playing/accessing it shouldn't trigger GC?).
Do you hink it might be a simple issue to fix and/or memory mapping file could help? At least it's no longer "40 times slower" :) I'm on v"1.7.0-DEV.386", it was slightly faster than Julia 1.5.
julia> @time using WAV
0.431934 seconds (433.26 k allocations: 28.546 MiB, 2.52% gc time, 1.76% compilation time)
I get the following error when I attempt to write a wav file previosly read with wavread
> using WAV
> snd, fs, nbits = wavread("snd.wav")
> wavwrite(snd, "wsnd.wav")
ERROR: no method wavwrite(Array{Float64,2},IOStream,Int64,Int64,Uint16)
in wavwrite at /home/sam/.julia/WAV/src/WAV.jl:434
in wavwrite at /home/sam/.julia/WAV/src/WAV.jl:446
Suppose I create a test file. about 3 minutes of 440Hz sine at 48kHz sampling rate
using WAV;
y = sin.((0:9999999)/48000*2pi*440);
wavwrite(y, "test.wav", Fs=48000)
Let's load it.
julia> @time y2, fs = wavread("test.wav")
4.120818 seconds (30.00 M allocations: 572.200 MiB, 5.97% gc time)
Now let's load this file into GNU Octave.
octave:1> tic(); [y, fs] = audioread('test.wav'); toc()
Elapsed time is 0.173757 seconds.
Let's try SciPy.
In [1]: from scipy.io.wavfile import read
In [2]: from time import time
In [3]: a = time(); y, fs = read("test.wav"); time() - a
Out[3]: 0.12526440620422363
WAV.jl is around 40 times slower than both.
I have Julia 0.6.2 and WAV.jl 0.9.0.
Currently, the "Available Package" list in the Julia docs lists the WAV packages with the description:
Julia package for working with WAV files
It would be nice if it had the word "audio" or "sound" in it, since those are the words I was using to find a way to play sounds from Julia. Some thing like the following would be easier to find by searching:
Julia package for working with the WAV audio file format.
I would make a pull request to update that, but I guess that would be to Metadata, and this seems like a more appropriate place to suggest this.
Hello,
Much more a feature request than an issue.
I wonder if there is any particular reason to make the return type of Fs
to be Uint
. I use WAV a lot for i/o, but I seem to be converting Fs
to Floatingpoint all the time. For one thing, Julia's default representation of Uint's (hexadecimal) isn't really handy in interactive use---I'd like to see 44100 or 16000 or whatever.
Cheers,
Package documentation indicates I should be able to run the following code without issue, provided libpulse-simple is available on my machine:
using WAV;
w, Fs = wavread("myWavFile.wav");
wavplay(w, Fs);
However, I receive the following error after this attempt in the REPL:
w, Fs = wavread("myWavFile.wav")
([-0.00191915 0.00196099; -0.00176525 -0.00658834; … ; -4.05312e-6 9.17912e-6; -1.19209e-7 5.96047e-7], 48000.0f0, 0x0018, WAVChunk[WAVChunk(Symbol("fmt "), UInt8[0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x65, 0x04, 0x00, 0x06, 0x00, 0x18, 0x00])])
julia> wavplay(w, Fs)
ERROR: MethodError: no method matching wavplay(::Array{Float64,2}, ::Float32)
Closest candidates are:
wavplay(::Any) at MY_DIR/.julia/packages/WAV/aZBXG/src/WAV.jl:38
Stacktrace:
[1] top-level scope at none:0
Output of versionInfo():
Julia Version 1.1.1
Commit 55e36cc308 (2019-05-16 04:10 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: AMD A6-9220e RADEON R4, 5 COMPUTE CORES 2C+3G
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, btver1)
When I pass an open IOStream to wavread
or read_header
, it generates an error if the file is not at the top. This is problematic if I have already done something with the file or if I have already called another of the WAV functions with the file. The workaround is to call seekstart(filehandle)
before calling the WAV function. I suggest that you call seekstart
at the beginning of the functions to avoid this issue.
When wavread
is called on a file it seems worthwhile memory-mapping the samples in the file. I don't have experience WAV file other than in PCM encoding but certainly for them memory-mapping seems much faster than reading the file as in read_pcm_samples
.
julia> Pkg.test("WAV")
INFO: Testing WAV
ERROR: LoadError: InexactError()
in convert at int.jl:155
in read_pcm_samples at /home/ryuichi/.julia/v0.4/WAV/src/WAV.jl:249
in read_data at /home/ryuichi/.julia/v0.4/WAV/src/WAV.jl:530
in wavread at /home/ryuichi/.julia/v0.4/WAV/src/WAV.jl:661
in anonymous at no file:205
in include at ./boot.jl:249
in include_from_node1 at loading.jl:128
in process_options at ./client.jl:319
in _start at ./client.jl:403
while loading /home/ryuichi/.julia/v0.4/WAV/test/runtests.jl, in expression starting on line 199
==========================[ ERROR: WAV ]===========================
failed process: Process(`/home/ryuichi/julia/usr/bin/julia --check-bounds=yes --code-coverage=none --color=yes /home/ryuichi/.julia/v0.4/WAV/test/runtests.jl`, ProcessExited(1)) [1]
===================================================================
julia> versioninfo()
Julia Version 0.4.0-dev+3050
Commit db1093e* (2015-02-02 14:12 UTC)
Platform Info:
System: Linux (x86_64-linux-gnu)
CPU: Intel(R) Core(TM)2 Duo CPU E7400 @ 2.80GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Penryn)
LAPACK: libopenblas
LIBM: libopenlibm
LLVM: libLLVM-3.3
I'm using WAV.jl v0.4.1. Perhaps this failure is revealed by the change JuliaLang/julia#9789.
I'm running WAV.jl on Julia 0.5 and Debian Jessie (8.6), and get the following error messages when attempting to run 'wavplay':
julia> wavplay(y, fs)
ERROR: MethodError: no method matching unsafe_convert(::Type{Ptr{Void}}, ::Int64)
Closest candidates are:
unsafe_convert{T}(::Type{Ptr{Void}}, ::Base.RefValue{T}) at refpointer.jl:49 unsafe_convert{T}(::Type{Ptr{Void}}, ::Base.RefArray{T,A<:AbstractArray,R}) at refpointer.jl:73
unsafe_convert(::Type{Ptr{Void}}, ::IOStream) at iostream.jl:27 ... in wavplay(::Array{Float64,1}, ::Int64) at /home/pvt/.julia/v0.5/WAV/src/wavplay-pulse.jl:16
I do have libpulse-dev installed.
In looking for audio read and write packages in Julia, I quickly found https://github.com/JuliaAudio. It seems like this package is however a better fit for me than anything I found there, but it was a little random/accidental that I found WAV.jl. I was thinking that this package would be much more discoverable if it was affiliated with JuliaAudio - is there motivation to make this happen?
Hello. It would be great if wavplay
works on windows machines just like on Macs and linux boxes. In README.md, it says that there is not a native backend for windows yet, but what needs to be done here? MATLAB can play audio files on windows, but I really want to use julia instead.
Thanks!
BVPs
When I try to use wavplay, I get the message that it is not currently implemented on Linux. I thought this was the case on Windows and that it worked fine on Linux? Or am I mistaken there?
I'm running Julia 0.4.5 on Debian Sid, in case that helps
Hi,
I consistently get this error when loading WAV in julia-0.5-rc1:
using WAV
INFO: Precompiling module WAV...
ERROR: Failed to precompile WAV to /Users/david/.julia/lib/v0.5/WAV.ji
in compilecache(::String) at ./loading.jl:505
in require(::Symbol) at ./loading.jl:364
I can't tell whether it is a WAV or a julia-0.5 problem, other packages don't give pre-compilation errors, but is occurs only in julia-0.5.
I've re-installed METADATA and WAV, but to no avail.
On my first attempt to start using WAV
, getting an series of errors when utilized within JuliaNB
Code in notebook
# Add package to read audio files
Pkg.add("WAV")
using WAV
Output
INFO: Package WAV is already installed
INFO: Precompiling module WAV.
WARNING: Module Compat with uuid 22742543754153 is missing from the cache.
This may mean module Compat does not support precompilation but is imported by a module that does.
ERROR: LoadError: Declaring __precompile__(false) is not allowed in files that are being precompiled.
Stacktrace:
[1] _require(::Symbol) at ./loading.jl:455
[2] require(::Symbol) at ./loading.jl:405
[3] include_from_node1(::String) at ./loading.jl:576
[4] include(::String) at ./sysimg.jl:14
[5] anonymous at ./<missing>:2
while loading /Users/emcp/.julia/v0.6/FileIO/src/FileIO.jl, in expression starting on line 5
ERROR: LoadError: Failed to precompile FileIO to /Users/emcp/.julia/lib/v0.6/FileIO.ji.
Stacktrace:
[1] compilecache(::String) at ./loading.jl:710
[2] _require(::Symbol) at ./loading.jl:463
[3] require(::Symbol) at ./loading.jl:405
[4] include_from_node1(::String) at ./loading.jl:576
[5] include(::String) at ./sysimg.jl:14
[6] anonymous at ./<missing>:2
while loading /Users/emcp/.julia/v0.6/WAV/src/WAV.jl, in expression starting on line 8
Failed to precompile WAV to /Users/emcp/.julia/lib/v0.6/WAV.ji.
Stacktrace:
[1] compilecache(::String) at ./loading.jl:710
[2] _require(::Symbol) at ./loading.jl:497
[3] require(::Symbol) at ./loading.jl:405
[4] include_string(::String, ::String) at ./loading.jl:522```
I don't think there are any released versions of WAV.jl that support Julia 0.7, which makes it harder to migrate any code that uses this package. The typical migration path is v0.6.4 -> v0.7 -> fix deprecations -> v1.0, but that's not possible if WAV.jl doesn't support v0.7.
Would you be willing to drop the required version to 0.7? I don't think there's any downside to doing so.
Hello, I was trying to run the first example in your Readme. However, it seems to break when using wavappend. I get this error message:
julia> wavappend(y, "example.wav")
ERROR: ArgumentError: invalid open mode: rwa
in open at ./iostream.jl:112
Hey Daniel,
I have a MWE for my problem:
using WAV
y, fs = wavread("sound.wav")
@async wavplay(y, fs)
while true println("async!") end
I would expect to see multiple "async!"
messages, but I see only one. Any thoughs?
Thanks
See the following example, where I have overloaded getindex
on a LazyWAVFile
to do wavread(path, format="native", ind)
julia> f[1:10] # Correct
10-element Array{Int16,1}:
-15
-8
-4
-19
-3
-4
-12
-2
-17
-4
julia> f[1:2:10] # Incorrect, but no error message
5-element Array{Int16,1}:
-15
-8
-4
-19
-3
julia> f[collect(1:2:10)] # If range is collected to an array, result is correct
5-element Array{Int16,1}:
-15
-4
-3
-12
-17
Hi, everyone.
It seems that the function WAV.wavappend
doesn't update the header information in the following case:
import WAV
x1 = rand(16000)
x2 = rand(16000)
WAV.wavwrite(x1, "test.wav", Fs=16000, nbits=16, compression=WAV.WAVE_FORMAT_PCM)
WAV.wavappend(x2, "test.wav")
The code above correctly appends the data; however, when opening the file with, e.g., Audacity, the program reads the first part of the wave file containing x1
only. I think that the header is not updated correctly. It might have something to do with the compression.
By the way: I'm using Julia-0.6.3 (Windows & Linux).
I prefer to use wavread() with format="double". Sometimes, my processing depends on the compression format of the WAV file read. nbits provides this information for most cases, but not for the 32-bit case. This is because PCM and floating-point are both possible for 32 bits.
I request that wavread() returns compression
as an additional value. For backwards compatibility, it may be best to return it as the last value so it can be ignored by the parent code. The returned compression
value may be useful for a subsequent call to wavwrite().
the documentation says that writing single precision floating points with nbits set to 32 should yield an output format of single, and that reading that file back in with format set to native should yield singles. yet when doing so i get int32s:
julia> tmp=rand(Float32,(10,2))
10x2 Array{Float32,2}:
0.109329 0.989609
0.257236 0.85028
0.217792 0.777978
0.017634 0.908059
0.156419 0.856639
0.895819 0.0867863
0.654237 0.463306
0.65422 0.0102742
0.52785 0.570494
0.805634 0.950643
julia> wavwrite(tmp,"foo.wav"; nbits=32)
IOStream()
julia> y, fs, nbits, extra = wavread("foo.wav"; format="native")
(
10x2 Array{Int32,2}:
234782656 2125169024
552409408 1825961856
467705728 1670695168
37868812 1950040832
335908000 1839618816
1923755904 186372160
1404963968 994941248
1404926336 22063738
1133548928 1225126400
1730085504 2041490816,
0x00001f40,0x0020,None)
julia> y, fs, nbits, extra = wavread("foo.wav")
(
10x2 Array{Float64,2}:
0.109329 0.989609
0.257236 0.85028
0.217792 0.777978
0.017634 0.908059
0.156419 0.856639
0.895819 0.0867863
0.654237 0.463306
0.65422 0.0102742
0.52785 0.570494
0.805634 0.950643 ,
0x00001f40,0x0020,None)
With the current API it's not possible to write multiple chunks of the same type. This is needed e.g. for writing a .wav file that contains both a LIST chunk for the INFO chunk and another one for the cue points.
I propose that wavwrite
be updated as follows:
wavwrite(samples::AbstractArray, io::IO; Fs=8000, nbits=0, compression=0,
chunks::Vector{Tuple{Symbol, Array{UInt8,1}}}=Tuple{Symbol, Array{UInt8,1}}[])
This would allow multiple LIST chunks to be written, and also allow the order of chunks written to be specified (at the moment it depends on Julia's hashing) but it will be a breaking change to the API. We'll have to change wavread
as well - we can make it return a Vector{Tuple{Symbol, Array{UInt8,1}}
or a Dict{Symbol, Vector{Any}}
where the entries in the dictionary are vectors containing all the chunks with a particular ID. I'd tend to go with the first option because it means you could read/write chunks without having to convert between the two types.
@dancasimiro if you approve of this change then I'm happy to implement and test it. If not, let me know your thoughts on other options.
Hey, I'm trying to use wavread and getting an error.
I have a wav file with these properties.
$ soxi recording.wav
Input File : 'recording.wav'
Channels : 2
Sample Rate : 44100
Precision : 16-bit
Duration : 00:00:14.86 = 655360 samples = 1114.56 CDDA sectors
File Size : 2.62M
Bit Rate : 1.41M
Sample Encoding: 16-bit Signed Integer PCM
When I try to read it I get an error.
julia> WAV.wavread("recording.wav")
ERROR: no method <<(Uint64,Float64)
in read_pcm_samples at /Users/steveo/.julia/WAV/src/WAV.jl:219
in read_data at /Users/steveo/.julia/WAV/src/WAV.jl:269
in wavread at /Users/steveo/.julia/WAV/src/WAV.jl:378
in wavread at /Users/steveo/.julia/WAV/src/WAV.jl:395
in wavread at /Users/steveo/.julia/WAV/src/WAV.jl:399
The README
file indicates that one possible value for the wavread
format
argument is "native"
but I don't see that value occurring anywhere in the code. There are checks for "double"
and for "size"
as values of format
but it seems that any value other than those two is taken as "native"
.
I would like to use the package to load .wav files extracted from CDDA format. As WAV files these are simple 16-bit PCM encoding of 2 channels sampled at 41000 Hz. I just want the PCM samples to convert to FLAC. In the end, however, I avoided the package because it takes a very long time to return the native format. The read_pcm_samples
function is very slow for returning the native format and I suspect that there is some unnecessary conversion taking place. In trying to see what happens when format = "native"
I couldn't find that.
Is it expected that any format
value other than "double"
or "size"
will be interpreted as "native"
?
when I attempt writing the following array:
using WAV
fs = 48000
nbits = 16
ns = (rand(24000,2) - 0.5)/100
wavwrite(ns, "wsnd.wav", Fs=fs, nbits=nbits)
a 0-bytes wav file is created without warnings regarding bit depth. If I set nbits
to 32 it works. I think WAV.jl should either perform an automatic conversion of the Float64 array to a smaller bit depth or at least warn the user that it is necessary to specify nbits=32
for writing Float64 arrays.
I've been using WAV.jl to test some features added to Audio,IO.jl (single stream recording and playback) and ran into a problem with the usual way stereo is recorded on some devices.
If an audio stream is recorded in stereo, the result is generally a single interleaved stream, so the data in the array is not put into a 2D array. But wavwrite(() then interprets the data as a mono recording when writing the file.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.