Giter Club home page Giter Club logo

wav.jl's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wav.jl's Issues

Incorrect size in header when using custom chunks

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 👍

Chunk padding not recognized

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.

wavread cannot access a sample number 59614786 or higher

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

[PkgEval] WAV may have a testing issue on Julia 0.4 (2014-09-29)

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.

On Julia 0.4

  • On 2014-09-28 the testing status was Tests pass.
  • On 2014-09-29 the testing status changed to 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

How to resolve Libdl error on MAC?

(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

TagBot trigger issue

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.

data=wavread(string) doesn't return Array

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.

Update WAV.jl REQUIRE (or version) in METADATA.jl

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.

Not able to read this wav file

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.

sample

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.

Writing floating point samples to a wav file

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...

Artifacts in sound played by wavplay

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

Option to avoid clamp in write_ieee_float_samples()

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:

  1. Gives users of WAV.jl the option of not clamping when writing IEEE floating-point format WAV files.
  2. Put the responsibility of clamping IEEE floating-point format WAV files on the rendering side, which makes WAV.jl less complex and easier to test.

"Too many open files" error in wavread

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.

Julia 0.4.1 - wavread gives error on 32-bit Linux

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

`wavplay(y, fs)` does not work

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

Cannot read 32-bits WAV files in MATLAB

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.

Add some support for reading from pipe

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!

subrange reads all samples

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.

is there an option to read into a mono?

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.

Slower loading because of GC issue

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)

wavwrite error

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

Reading wav files is extremely slow.

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.

Julia Package Description

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.

return type of fs

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,

wavplay example not working on Linux

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)

Read operations do not start at the start of the file

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.

Memory-mapping in `wavread`?

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.

InexactError() in converting unsigned and signed integers on the latest master

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.

Julia 0.5 wavplay broken on Debian Linux

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.

Affiliate this package with JuliaAudio

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?

wavplay for Windows: what needs to be done?

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

Issue with wavplay on Debian

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

Can't precompile on julia-0.5

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.

Attempted to use inside JuliaNB, got errors

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```

Support Julia v0.7?

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.

ArgumentError in wavappend

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

Playing with @async is blocking

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

wavread with subrange of step >1 gives wrong result

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

`wavappend()` doesn't update header in certain case

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).

Request: wavread() returns compression

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().

writes/reads int32 when should be float32

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)

Unable to write multiple LIST chunks

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.

Error reading wav file

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

wavread(..., format = "native")

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"?

Writing Float64 Array with 16 bits fails silently

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.

Writing pre-interleaved stereo recorded data results in a mono file at double fs rate

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.