From b393e9273feeaa4ca39dc3ca3468d5cded03e772 Mon Sep 17 00:00:00 2001 From: Jeff Fessler Date: Tue, 16 Apr 2024 21:41:04 -0400 Subject: [PATCH] Update vocoder --- docs/lit/examples/01-overview.jl | 26 +++++----------- docs/lit/examples/02-vocoder.jl | 52 ++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/lit/examples/01-overview.jl b/docs/lit/examples/01-overview.jl index 6a97b71..d1f40de 100644 --- a/docs/lit/examples/01-overview.jl +++ b/docs/lit/examples/01-overview.jl @@ -3,9 +3,6 @@ This page illustrates the Julia package [`Sound`](https://github.com/JeffFessler/Sound.jl). - -This page was generated from a single Julia file: -[01-overview.jl](@__REPO_ROOT_URL__/01-overview.jl). =# #srcURL @@ -29,31 +26,22 @@ was to provide a simple way to hear audio signals in Julia. S = 8192 # sampling rate in Hz x = 0.7*cos.(2π*(1:S÷2)*440/S) y = 0.8*sin.(2π*(1:S÷2)*660/S) -sound(x, S) # monophonic +isinteractive() && sound(x, S) # monophonic # stereo: -sound([x y], S) +isinteractive() && sound([x y], S) # scale to unit amplitude: -soundsc([x y], S) +isinteractive() && soundsc([x y], S) # Using `SampleBuf` may provide some convenience. S = 8192 # sampling rate in Hz -x = 0.7*cos.(2π*(1:S÷2)*440/S) -y = 0.8*sin.(2π*(1:S÷2)*660/S) +x = 0.7 * cos.(2π*(1:S÷2)*440/S) +y = 0.8 * sin.(2π*(1:S÷2)*660/S) sb = SampleBuf([x y], S) # stereo data -sound(sb) - - -# ### Reproducibility - -# This page was generated with the following version of Julia: - -io = IOBuffer(); versioninfo(io); split(String(take!(io)), '\n') - +isinteractive() && sound(sb) -# And with the following package versions -import Pkg; Pkg.status() +include("../../../inc/reproduce.jl") diff --git a/docs/lit/examples/02-vocoder.jl b/docs/lit/examples/02-vocoder.jl index 5fc0429..ec5eec5 100644 --- a/docs/lit/examples/02-vocoder.jl +++ b/docs/lit/examples/02-vocoder.jl @@ -1,11 +1,10 @@ #= # [Phase Vocoder](@id 02-vocoder) -This page illustrates the phase vocoder feature of the Julia package +This page illustrates the +[phase vocoder](https://en.wikipedia.org/wiki/Phase_vocoder) +feature of the Julia package [`Sound`](https://github.com/JeffFessler/Sound.jl). - -This page was generated from a single Julia file: -[02-vocoder.jl](@__REPO_ROOT_URL__/02-vocoder.jl). =# #srcURL @@ -18,6 +17,7 @@ This page was generated from a single Julia file: using Sound: phase_vocoder, soundsc, hann using DSP: spectrogram using MIRTjim: jim, prompt +using Plots: plot using InteractiveUtils: versioninfo @@ -36,8 +36,9 @@ to stretch time (by the default factor of 2). S = 8192*2^2 x1 = cos.(2π*400*(1:2S)/S) .* hann(2S) -x2 = cos.(2π*300*(1:S)/S).^3 .* hann(S) # nonlinearity for harmonics -x = [x1; x2] # 2-note song +x2 = cos.(2π*300*(1:S)/S) .* hann(S) +x3 = cos.(2π*500*(1:S)/S).^3 .* hann(S) # nonlinearity for harmonics +x = [x1; x2; x3] # 4-note song y = phase_vocoder(x, S) length(x), length(y) @@ -45,26 +46,37 @@ length(x), length(y) sx = spectrogram(x / maximum(abs, x); fs=S) sy = spectrogram(y / maximum(abs, y); fs=S) dB = x -> max(log10.(x), -10) -fun = (s) -> jim(s.time, s.freq, dB.(s.power)', aspect_ratio=:auto, - ylims = (0,1800), color=:viridis, clim = (-10,0), - yticks = 0:300:1800, yflip=false, - xlabel="time", ylabel="freq", +fun = (s) -> jim(s.time, s.freq, dB.(s.power)', aspect_ratio = :auto, + color = :viridis, clim = (-10,0), yflip = false, + yaxis = ("freq", (0,1800), 0:300:1800), + xlabel="time", prompt = false, ) -jim(fun(sx), fun(sy)) +p0 = jim(fun(sx), fun(sy)) # listen to before/after: -soundsc([x; y], S) - - -# ### Reproducibility - -# This page was generated with the following version of Julia: +isinteractive() && soundsc([x; y], S) -io = IOBuffer(); versioninfo(io); split(String(take!(io)), '\n') +#= +The following time plots +show the original signal +and the time-stretched version. +Clearly something is awry. +=# +p1 = plot((1:length(x))/S, x, label="x(t) original", + xaxis = ("t [s]", (0, 4), 0:4), + yaxis = ("", (-1, 1), -1:1), + size = (600, 300), +) +ymax = ceil(maximum(abs, y)) # why not "1" ? +p2 = plot((1:length(y))/S, y, label="y(t) processed", + xaxis = ("t [s]", (0, 8), 0:2:8), + yaxis = ("", (-1, 1).*ymax, (-1:1)*ymax), + size = (600, 300), +) +p12 = plot(p1, p2; layout=(2,1)) -# And with the following package versions -import Pkg; Pkg.status() +include("../../../inc/reproduce.jl")