JuliaAudio / PortAudio.jl

PortAudio wrapper for the Julia programming language, compatible with the JuliaAudio family of packages
Other
115 stars 20 forks source link

Support `sound` and `soundsc` #95

Closed JeffFessler closed 2 years ago

JeffFessler commented 2 years ago

Would the maintainers of this package be open to a PR that adds support for functions sound and soundsc to facilitate migration of code from Matlab to Julia?

Here's a draft of the code:

export sound, soundsc

"""
    sound(x::AbstractVector, S::Real)
Play monophonic audiosignal `x` at sampling rate `S` samples per second
through default audio output device using the `PortAudio` package.
"""
function sound(x::AbstractVector, S::Real)
    PortAudioStream(0, 2; samplerate=Float64(S)) do stream
        write(stream, x)
    end
end

"""
    sound(x::AbstractMatrix, S::Real)
Play stereo audiosignal `x` at sampling rate `S` samples per second
through default audio output device using the `PortAudio` package.
"""
function sound(x::AbstractMatrix, S::Real)
    size(x,2) == 2 || throw("size(x,2) = $(size(x,2)) is too many channels")
    PortAudioStream(0, 2; samplerate=Float64(S)) do stream
        write(stream, x)
    end
end

"""
    sound(x)
Play mono or stereo audio signal `x`
at default sampling rate 8192 samples per second
through default audio output device using the `PortAudio` package.
"""
sound(x::AbstractArray) = sound(x, 8192)

"""
    soundsc(x, S::Real)
Play mono or stereo audio signal `x`
at sampling rate `S` samples per second
through default audio output device using the `PortAudio` package,
after scaling `x` to have values in `(-1,1)`.
"""
soundsc(x::AbstractArray, S::Real) =
    sound(x * prevfloat(1.0) / maximum(abs, x), S)

"""
    soundsc(x)
Play mono or stereo audio signal `x`
at default sampling rate 8192 samples per second
through default audio output device using the `PortAudio` package,
after scaling `x` to have values in `(-1,1)`.
"""
soundsc(x::AbstractArray) = soundsc(x, 8192)
bramtayl commented 2 years ago

Have you seen SampleBuf in SampledSignals? https://github.com/JuliaAudio/SampledSignals.jl/blob/0d9954409d877f2bd74671d31fd1cdd7acc548c1/src/SampleBuf.jl#L11 that's a good way to do this. Maybe you could add a note in the README of SampledSignals for matlab users?

rob-luke commented 2 years ago

I don't think we want to necessarily mirror the syntax and functions from MATLAB. This is a common discussion in other packages too, and the conclusion is generally to do things the Julian way. Also we have many converts from python, C, etc.

JeffFessler commented 2 years ago

Have you seen SampleBuf in SampledSignals?

SampleBuf is a useful data type, but sound and soundsc are methods, not types. So my question is about adding the methods.

Your suggestion leads to a natural additional method:

sound(sb::SampleBuf) = sound(sb.data, sb.samplerate)

I don't think we want to necessarily mirror the syntax and functions from MATLAB.

Thanks for the quick reply. That's kind of what I figured, so I will pursue other avenues.

Perhaps at least this discussion will be helpful for other people trying to migrate.

rob-luke commented 2 years ago

Perhaps at least this discussion will be helpful for other people trying to migrate.

Absolutely, and please dont let me discourage you from making suggestions. Its great to see the package being used. And if you took time to find this solution, then we should address the issue. But maybe rather than adding functions, we could add a few really simple scripts to the examples directory to show these basics?

JeffFessler commented 2 years ago

PR #94 would help show those basics.

JeffFessler commented 2 years ago

For anyone who ends up here looking for a sound method, see https://github.com/JeffFessler/Sound.jl