How to play an audio in Julia?

Since AudioIO.jl is unmaintained and LibSndFile.jl isn’t working well.

There is another “famous” Julia’s audio module?

I have an audio in .ogg or .mp3 (any format). I want to read and play it.

3 Likes

Even WAV.jl have problem.

All these packages are difficult to install. They don’t have docs and even adding many dependencies manually they crash.

There is another good package?

1 Like

From the issue you posted it looks like there’s some issues with your environment that are holding FFTW.jl back to an older version, which is causing you problems. I’d suggest installing into a fresh environment, or posting the results of pkg> status and perhaps folks can help you debug your environment. (use ] to get to the pkg> prompt).

1 Like

Here:

(v1.3) pkg> status
    Status `~/.julia/environments/v1.3/Project.toml`
  [c52e3926] Atom v0.11.3
  [247af7c9] AudioIO v0.0.0 #master (https://github.com/ssfrr/AudioIO.jl)
  [6e4b80f9] BenchmarkTools v0.4.3
  [336ed68f] CSV v0.5.18
  [c5f51814] CUDAdrv v4.0.4
  [be33ccc6] CUDAnative v2.6.0
  [5ae59095] Colors v0.9.6
  [861a8166] Combinatorics v1.0.0
  [34da2185] Compat v2.2.0
  [3a865a2d] CuArrays v1.5.0
  [a93c6f00] DataFrames v0.19.4
  [e30172f5] Documenter v0.24.2
  [7a1cc6ca] FFTW v1.0.1
  [5789e2e9] FileIO v1.1.0
  [c43c736e] Genie v0.22.7 #master (https://github.com/GenieFramework/Genie.jl)
  [7073ff75] IJulia v1.20.2
  [4e3cecfd] ImageShow v0.2.1
  [682c06a0] JSON v0.21.0
  [e5e0dc1b] Juno v0.7.2
  [194296ae] LibPQ v1.0.5
  [39abe10b] MySQL v0.7.1
  [91a5bcdd] Plots v0.28.2
  [295af30f] Revise v2.3.2
  [8149f6b0] WAV v1.0.3
┌ Warning: Some packages (indicated with a red arrow) are not downloaded, use `instantiate` to instantiate the current environment
└ @ Pkg.Display /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Pkg/src/Display.jl:233
1 Like

Even after removing AudioIO.

(v1.3) pkg> rm FFTW
  Updating `~/.julia/environments/v1.3/Project.toml`
  [7a1cc6ca] - FFTW v1.0.1
  Updating `~/.julia/environments/v1.3/Manifest.toml`
 [no changes]

(v1.3) pkg> add FFTW
 Resolving package versions...
  Updating `~/.julia/environments/v1.3/Project.toml`
  [7a1cc6ca] + FFTW v1.0.1
  Updating `~/.julia/environments/v1.3/Manifest.toml`
 [no changes]

When I install FFTW. Julia gets version 1.0.1.

I discovered that Julia has a virtual env. So I tried:

(v1.3) pkg> activate teste
Activating new environment at `~/progs/virtual_env/teste/Project.toml`

(teste) pkg> status
    Status `~/progs/virtual_env/teste/Project.toml`
  (empty environment)

(teste) pkg> add FFTW
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
 Resolving package versions...
  Updating `~/progs/virtual_env/teste/Project.toml`
  [7a1cc6ca] + FFTW v1.1.0

And installed version of FFTW was v1.1.0, and LibSndFile v2.2.0.

So as @ssfrr said. Should be something fixing FFTW. But what?

1 Like

If you run

pkg> update
pkg> rm FFTW
pkg> add FFTW@1.1.0

What do you get? I think (though I’m not 100% sure) that this should show what is holding FFTW back. Note that if the command works then it will pin FFTW at version 1.1.0 forever, which you probably don’t want long-term, so you should run pkg> free FFTW afterwards to un-pin the version.

The other guidance here is that as you’ve discovered Julia has per-project environment support built-in. It’s good practice to have a separate environment for each thing you’re working on, so you don’t end up with a big cluster of packages, which makes this sort of thing more of a problem. That said, I realize it’s not very satisfying to run into this issue and then not have a clear path to fixing it.

2 Likes

This:

(v1.3) pkg> add FFTW@1.1.0
 Resolving package versions...
ERROR: Unsatisfiable requirements detected for package GPUArrays [0c68f7d7]:
 GPUArrays [0c68f7d7] log:
 ├─possible versions are: [0.3.0-0.3.4, 0.4.0-0.4.2, 0.5.0, 0.6.0-0.6.1, 0.7.0-0.7.2, 1.0.0-1.0.4, 2.0.0] or uninstalled
 ├─restricted by compatibility requirements with CuArrays [3a865a2d] to versions: 2.0.0
 │ └─CuArrays [3a865a2d] log:
 │   ├─possible versions are: [0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.6.0-0.6.2, 0.7.0-0.7.3, 0.8.0-0.8.1, 0.9.0-0.9.1, 1.0.0-1.0.2, 1.1.0, 1.2.0-1.2.1, 1.3.0, 1.4.0-1.4.7, 1.5.0] or uninstalled
 │   └─restricted to versions 1.5.0 by an explicit requirement, leaving only versions 1.5.0
 └─restricted by compatibility requirements with AbstractFFTs [621f4979] to versions: [0.3.0-0.3.4, 0.4.0-0.4.2, 0.5.0, 0.6.0-0.6.1, 0.7.0-0.7.2, 1.0.0-1.0.4] or uninstalled — no versions left
   └─AbstractFFTs [621f4979] log:
     ├─possible versions are: [0.3.0-0.3.2, 0.4.0-0.4.1, 0.5.0] or uninstalled
     ├─restricted by compatibility requirements with CuArrays [3a865a2d] to versions: [0.4.0-0.4.1, 0.5.0]
     │ └─CuArrays [3a865a2d] log: see above
     └─restricted by compatibility requirements with FFTW [7a1cc6ca] to versions: 0.5.0
       └─FFTW [7a1cc6ca] log:
         ├─possible versions are: [0.1.0-0.1.2, 0.2.0-0.2.4, 0.3.0, 1.0.0-1.0.1, 1.1.0] or uninstalled
         └─restricted to versions 1.1.0 by an explicit requirement, leaving only versions 1.1.0

OK - it seems the problem is with GPUArrays.jl, which has a fix for this in master but it hasn’t been released yet. I just bumped that issue to see if the maintainers can tag a release.

When I remove CuArrays and update.

AbstractFFTs and FFTW go to v0.5.0 and v1.1.0.

When I install LibSndFile the version installed is v2.2.0.

Great - glad you found a fix.

For future google-ability @kristoffer.carlsson wrote a script that can dump packages that are being held back, which might help debugging this sort of thing:
https://gist.github.com/KristofferC/7c8048e2ee9aaa465966caeb98c1446a

3 Likes
using FileIO: load, save, loadstreaming, savestreaming
import LibSndFile
y, fs = load("FILE")

How to play this audio? With PortAudio?

1 Like

@ssfrr,

I can only install PortAudio manually, as you can see:

(test) pkg> add PortAudio
ERROR: The following package names could not be resolved:
 * PortAudio (not found in project, manifest or registry)
Please specify by known `name=uuid`.

(test) pkg> add https://github.com/JuliaAudio/PortAudio.jl
  Updating git-repo `https://github.com/JuliaAudio/PortAudio.jl`
[ Info: Assigning UUID d9fd0e0d-4c11-50a6-a479-0c8901481c1e to PortAudio
  Updating git-repo `https://github.com/JuliaAudio/PortAudio.jl`
 Resolving package versions...
  Updating `~/codigos/julia/SintetizadorVoz/src/recursos/test/Project.toml`
  [d9fd0e0d] + PortAudio v0.0.0 #master (https://github.com/JuliaAudio/PortAudio.jl)
  Updating `~/codigos/julia/SintetizadorVoz/src/recursos/test/Manifest.toml`
  [9e28174c] + BinDeps v0.8.10
  [e1450e63] + BufferedStreams v1.0.0
  [2e619515] + Expat_jll v2.2.7+0
  [0862f596] + HTTPClient v0.2.1
  [d9be37ee] + Homebrew v0.7.1
  [b27032c2] + LibCURL v0.5.2
  [522f3ed2] + LibExpat v0.6.0
  [2ec943e9] + Libz v1.0.0
  [d9fd0e0d] + PortAudio v0.0.0 #master (https://github.com/JuliaAudio/PortAudio.jl)
  [f6d8bcc6] + RingBuffers v1.2.0
  [30578b45] + URIParser v0.4.0
  [c17dfb99] + WinRPM v0.4.2

When I put add PortAudio gets an error.

@ssfrr,

When I use the PortAudio, I get:

julia> using PortAudio
[ Info: Precompiling PortAudio [d9fd0e0d-4c11-50a6-a479-0c8901481c1e]
ERROR: LoadError: syntax: extra token "PortAudioDevice" after end of expression
Stacktrace:
 [1] top-level scope at /home/ronneesley/.julia/packages/PortAudio/GCzTX/src/PortAudio.jl:49
 [2] include at ./boot.jl:328 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1105
 [4] include(::Module, ::String) at ./Base.jl:31
 [5] top-level scope at none:2
 [6] eval at ./boot.jl:330 [inlined]
 [7] eval(::Expr) at ./client.jl:425
 [8] top-level scope at ./none:3
in expression starting at /home/ronneesley/.julia/packages/PortAudio/GCzTX/src/PortAudio.jl:49
ERROR: Failed to precompile PortAudio [d9fd0e0d-4c11-50a6-a479-0c8901481c1e] to /home/ronneesley/.julia/compiled/v1.3/PortAudio/cmSSf_4TLhK.ji.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] compilecache(::Base.PkgId, ::String) at ./loading.jl:1283
 [3] _require(::Base.PkgId) at ./loading.jl:1024
 [4] require(::Base.PkgId) at ./loading.jl:922
 [5] require(::Module, ::Symbol) at ./loading.jl:917

I use this small utility function to play audio I have in memory, may be useful to someone, replace totem for your audio player of choice

using WAV
function WAV.wavplay(x::AbstractArray,fs)
    path = "/tmp/a.wav"
    wavwrite(x,path,Fs=fs)
    @info "Wrote to file $path"
    Threads.@spawn run(`totem $path`)
end
6 Likes

While LibSndFile has been updated for 1.3, PortAudio is still in-progress. There are a number of issues with binary packaging that I’ve been working through, but haven’t had time to get it fully wrapped up. It should more-or-less work on the julia1 branch (do pkg> add PortAudio#julia1 but it’s been in-progress for a while.

If you use the Atom editor with Juno (which I recommend in general because it’s a really nice experience for editing/running julia code), then LibSndFile will display as playable audio:

I think you should get something similar if you use Jupyter, though I haven’t tested.

On Linux and OSX, WAV.jl has some functionality to do playback, but I haven’t used it.

5 Likes

it seems to be unmaintained… i.e. there is a long standing issue about playback that has had no attention

Yeah, progress has been sporadic, though things have moved along a bit. Now folks can use master rather than a random branch, and it also uses the new BinaryBuilder-based C binaries. Which issue are you referring to?

There are still some segfaults I need to work through and some build-system issues to add support for various audio backends (most notably PulseAudio devices don’t seem to be recognized by the ALSA backend for some reason).

I was meaning this one:

https://github.com/dancasimiro/WAV.jl/issues/77

is there any work around?

also, thanks for the tip about LibSndFile, it works great!

I think I spoke too soon: there was a recompile, and now the example you gave above doesn’t produce a sound player in Juno anymore. I instead get some type information:

Also, I checked and it doesn’t produce a player in jupyter.