Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wavplay example not working on Linux #77

Closed
ntjess opened this issue Jul 21, 2019 · 16 comments
Closed

wavplay example not working on Linux #77

ntjess opened this issue Jul 21, 2019 · 16 comments

Comments

@ntjess
Copy link

ntjess commented Jul 21, 2019

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)

@minecraft2048
Copy link

Same:

julia> wavplay(sig2,48000)
ERROR: MethodError: no method matching wavplay(::Array{Real,1}, ::Int64)
Closest candidates are:
  wavplay(::Any) at /home/minato/.julia/packages/WAV/aZBXG/src/WAV.jl:38
Stacktrace:
 [1] top-level scope at REPL[22]:1

julia> versioninfo()
Julia Version 1.2.0
Commit c6da87ff4b (2019-08-20 00:03 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, skylake)

@mgkuhn
Copy link
Contributor

mgkuhn commented Nov 26, 2019

I suspect the entire __init__() function in src/WAV.jl no longer works. It expects

module WAV
    WAV
end

to throw an UndefVarError exception, but under Julia 1.3 it just returns Main.WAV instead. As a result, "wavplay-pulse.jl" or "wavplay-audioqueue.jl" are never included now and therefore their wavplay() methods remain undefined.

The entire way in which __init__() includes source code at runtime, as the result of testing for the presence of a shared library, seems much more appropriate for an interpreted language than for compiled Julia. This programming style currently causes the Julia parser to be invoked each time WAV is loaded!

I think the entire __init__() function should be removed and this OS dependency should instead be dealt with at compile time, as described under Handling operating system variation in the Julia manual.

There should also be test cases for wavplay(). (They are currently commented out.)

@Ronneesley
Copy link

Same:

julia> wavplay(y, fs)
ERROR: MethodError: no method matching wavplay(::Array{Float64,2}, ::Float32)
Closest candidates are:
  wavplay(::Any) at /home/ronneesley/.julia/packages/WAV/T2P9V/src/WAV.jl:38
Stacktrace:
 [1] top-level scope at REPL[19]:1

@kalvotom
Copy link

kalvotom commented Mar 6, 2020

I have stumbled into this too.

julia> versioninfo()
Julia Version 1.3.1
Commit 2d5741174c (2019-12-30 21:36 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, broadwell)

@spirosbax
Copy link

Not working on my system either. Same error message as previously mentioned.

julia> versioninfo()  
Julia Version 1.4.0  
Commit b8e9a9ecc6 (2020-03-21 16:36 UTC)  
Platform Info:  
  OS: Linux (x86_64-pc-linux-gnu)  
  CPU: AMD A10-7850K Radeon R7, 12 Compute Cores 4C+8G  
  WORD_SIZE: 64  
  LIBM: libopenlibm  
  LLVM: libLLVM-8.0.1 (ORCJIT, bdver3)  

@AshtonSBradley
Copy link

Not just a linux issue. Same problem on:

julia> versioninfo()
Julia Version 1.4.0
Commit b8e9a9ecc6 (2020-03-21 16:36 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin18.6.0)
  CPU: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 4

@spirosbax
Copy link

spirosbax commented Apr 30, 2020

For the last couple of hours I have been trying to fix this issue. A dirty fix is to directly include the wavplay-pulse.jl file. Then wavplay works (at least for me). In my testing the __init__ function also works as expected, meaning it detects the libpulse library and it includes wavplay-pulse.jl. But for some weird reason the wavplay definition inside the wavplay-pulse.jl does not get reexported. Maybe someone with more experience can give me a push ?

@spirosbax
Copy link

spirosbax commented Apr 30, 2020

I suspect the entire __init__() function in src/WAV.jl no longer works. It expects

module WAV
    WAV
end

to throw an UndefVarError exception, but under Julia 1.3 it just returns Main.WAV instead. As a result, "wavplay-pulse.jl" or "wavplay-audioqueue.jl" are never included now and therefore their wavplay() methods remain undefined.

The entire way in which __init__() includes source code at runtime, as the result of testing for the presence of a shared library, seems much more appropriate for an interpreted language than for compiled Julia. This programming style currently causes the Julia parser to be invoked each time WAV is loaded!

I think the entire __init__() function should be removed and this OS dependency should instead be dealt with at compile time, as described under Handling operating system variation in the Julia manual.

There should also be test cases for wavplay(). (They are currently commented out.)

In my testing UndefVarError is returned and __init__ works as expected. The exception would not be thrown only if WAV had been previously defined, which it shouldn't .

But I think you are right about the include statements inside it. OS handling should probably be written in a different way.

@dancasimiro
Copy link
Owner

I have not checked recently, but the tests used to blow up the online CI tools. The tests failed hard due to lacking audio hardware.

@dancasimiro
Copy link
Owner

It is entirely possible that this pattern is incompatible with modern Julia. The code was written a long time ago. I am open to different approaches. There might be other packages available today that render audio more portably.

@AshtonSBradley
Copy link

AshtonSBradley commented May 1, 2020

this does a great job at generating a player in Juno, Jupyter, but it reverts to WAV if WAV is installed, and then stops producing a player

https://github.com/JuliaAudio/LibSndFile.jl

also, WAV.jl is needed to easily load raw data from a .wav. So for example, to load, manipulate and then play, I first install WAV, then, load and manipulate data and save. Then I unstall WAV and play the new .wav file...

@dancasimiro
Copy link
Owner

dancasimiro commented May 25, 2020

It doesn't look like LibSndFile.jl can reproduce audio. Additionally, PortAudio is not working in Julia 1.4.2. Should I revert the runtime checking and assume that pulse audio is available @ntjess?

@AshtonSBradley: What are you using to play the WAV file (in your last comment above)?

I did not know about this long thread: https://discourse.julialang.org/t/how-to-play-an-audio-in-julia/31881/30

@spirosbax
Copy link

Not just a linux issue. Same problem on:

julia> versioninfo()
Julia Version 1.4.0
Commit b8e9a9ecc6 (2020-03-21 16:36 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin18.6.0)
  CPU: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 4

On macOS you should include the wavplay-audioqueue.jl file with include("./wavplay-audioqueue.jl")

@AshtonSBradley
Copy link

AshtonSBradley commented May 29, 2020

By itself, LibSndFile.jl does play audio from WAV files. In Juno and Jupyter it generates a player on load, like this:
Screen Shot 2020-05-29 at 6 19 49 PM

but the issue is that if you have WAV installed, then LibSndFile tries to use that for WAV files, and then the player no longer appears. So the WAV interaction of LibSndFile currently breaks its player...

@contradict
Copy link
Contributor

I see one possible resolution here is to remove wavplay entirely ( #77 ), but I just created #85 , which fixes wavplay for linux.

The problem described above by @AshtonSBradley is an important one, and is due to both LibSndFile.jl and WAV.jl registering themselves with FileIO.jl. WAV.jl takes precedence (I'm still not sure why) and ends up being called for load. The load method registered by LibSndFile returns a SampledSignals.SampleBufobject, that object knows how to create the player in Juno and Jupyter. The object returned by WAV.jl does not implement this method.

However, the SampleBuf object does not implement audio playback in stand-alone applications or at the REPL, so removing it would disable REPL sound playback.

To play audio in a browser-based UI when WAV.jl is installed, you can wrap the output of wavread or FileIO.load in a SampleBuf like this:

using WAV
using SampledSignals
samples, fs = wavread("/usr/share/sounds/purple/alert.wav");
buf = SampleBuf{Float64, 2}(samples, fs)

@dancasimiro
Copy link
Owner

Fixed by #85

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants