How to play an audio in Julia?

would be great to see something like this folded into WAV

On Linux with PulseAudio I managed to play a function. Somehow the import is broken. Maybe it helps.

using WAV

include("~/.julia/packages/WAV/T2P9V/src/wavplay-pulse.jl")

t = 0.5
fs = 8000
x = 1:fs*t

f(f) = @. (sin(2*pi/fs*f*x)+sin(2*pi/fs*f*1.26*x)+sin(2*pi/fs*f*1.34*x))

s =  vcat(f.(rand([
523.251,
493.883,
466.164,
440.000,
415.305,
391.995,
369.994,
349.228,
329.628,
311.127,
293.665,
277.183,
261.626 ],100))...)
wavplay(s,fs)

You’ll have to uninstall WAV.jl if you want load to use LibSndFile instead, the issue is that the FileIO package prefers to use WAV so it will use that instead if it’s installed.

WAV is a separate package with a different maintainer from LibSndFile. WAV is a pure-Julia implementation of WAV file processing. LibSndFile can handle more file types but relies on a C library to do so.

Also, in case it’s not clear - I don’t maintain or use WAV.jl, it’s maintained by @dancasimiro. In addition to WAV file support it can play and record audio.

I maintain LibSndFile.jl and PortAudio.jl, which are separate packages for working with audio devices and files, respectively.

Besides the pure-Julia vs. binary library aspect, WAV.jl provides a more matlab-familiar interface and returns a tuple of an Array with the audio data and a sampling rate. LibSndFile returns a SampleBuf object, which is a wrapper around a raw array that includes the sample rate and some convenience functionality, like the widget display in Juno and Jupiter. I think WAV.jl has something similar, though maybe you need to call a function to show the widget.

3 Likes

thanks a lot for this. one question: since libsndfile.jl does what I need and works, how would i pull out the raw data values from a SampleBuf?

Can LibSndFile.jl save a .wav if WAV is not installed? I seem to be able to play files, but not save them when WAV is removed… so then the readme examples don’t work

You can do buf.data to get the underlying array from a samplebuf.

Libsndfile supports WAV files and doesn’t depend on WAV.jl.

If the readme example doesn’t work can you file an issue with the error you’re seeing?

thanks for this. I think more an issue with my understanding… the issue is more that I want an equivalent of WAV’s

y, fs, nbits, extra = wavread(“sound.wav”)

y2 = some processing of raw data via fft, filter, etc

wavwrite(y2, fs, 32,“sound2.wav” )

I can’t see from LibSndFile how to process the raw data and then save to .wav again. Maybe type conversion to FixedPointNumber ?

Yeah, I think the current design makes that harder than it needs to be. You’re correct that currently the way to do it is to convert to FixedPoint values before saving (assuming that your processing is giving your floats). Originally the idea was that I didn’t want LibSndFile to do any automatic conversion, so if you read a WAV file and then wrote the contents back to disk it would be a lossless process. In practice you are almost always end up wanting to work with floats so the defaults should probably reflect that.

See this issue with some of my thoughts on it:
https://github.com/JuliaAudio/LibSndFile.jl/issues/23

Sorry for all of the trouble with wavplay in WAV.jl. The mechanism that I used to detect libraries at runtime has broken over time. I could revert the complexity and always depend on the presence of pulse audio.

2 Likes

If you just want to play it, you can use Shell-command interpolation instead:

run(`vlc file.wav -Idummy`)

(Idummy runs VLC without GUI)

1 Like

If I add “using MFCC” below then I no longer see the sound player, does its use of WAV internally somehow override? I am able to convert to a sampleBuf and then I see the player but I cannot play anything lower than at 3k samplerate, not sure this is a bug or a limitation of the OSX audio engine player through juno.

The audio libraries are in much better shape now than when this question was asked originally. For people like me who are migrating from Matlab and might find this discourse discussion, there is a simple sound function in this package:
https://github.com/JeffFessler/Sound.jl.
It is currently just a wrapper around PortAudio functions.

6 Likes

the guys could put this feature in vscode.