I’m trying to play audio in another thread using WAV.jl via @Threads.spawn .
I do run julia with multiple threads via --threads parameter.
(referenced data: SnakeGameCollection/common_data at main · karna48/SnakeGameCollection · GitHub)
It works in a normal program:
import WAV
struct Sound
fs
y
filename
function Sound(filename::String)
y, fs = WAV.wavread(filename)
new(fs, y, filename)
end
end
function play(sound::Sound)
println("start playing ", sound.filename)
WAV.wavplay(sound.y, sound.fs)
println("end playing ", sound.filename)
end
function load_play(filename::String)
y, fs = WAV.wavread(filename)
WAV.wavplay(y, fs)
end
sound_die = Sound(joinpath("..", "common_data", "die.wav"))
sound_eat = Sound(joinpath("..", "common_data", "eat.wav"))
Threads.@spawn play(sound_die)
for i in 1:10
println("main thread sleeps!")
sleep(1)
play(sound_eat)
end
However in my ModernGL/GLFW app it does not work, it freezes when it’s trying to access any member of Sound structure, even the filename::String. But the variant with loading the file inside the thread and then playing it works.
The minimal example:
import WAV
using ModernGL, GLAbstraction, GLFW
const GLA = GLAbstraction
struct Sound
fs
y
filename
function Sound(filename::String)
y, fs = WAV.wavread(filename)
new(fs, y, filename)
end
end
function play(sound::Sound)
println("start playing ", sound.filename)
WAV.wavplay(sound.y, sound.fs)
println("end playing ", sound.filename)
end
function load_play(filename::String)
y, fs = WAV.wavread(filename)
WAV.wavplay(y, fs)
end
g_keys = Dict() # GLFW.GetKey did not work for me
window = GLFW.Window(name="sound not working ModernGL/GLFW", resolution=(800, 600))
GLA.set_context!(window)
glClearColor( 0.7, 0.7, 1, 0 )
GLFW.SetKeyCallback(window, (_, key, scancode, action, mods) -> begin
if action == GLFW.PRESS
g_keys[key] = true
else
g_keys[key] = false
end
end)
sound_die = Sound(joinpath("..", "common_data", "die.wav"))
sound_eat = Sound(joinpath("..", "common_data", "eat.wav"))
while !GLFW.WindowShouldClose(window)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
GLFW.SwapBuffers(window)
GLFW.PollEvents()
if get(g_keys, GLFW.KEY_ESCAPE, false)
GLFW.SetWindowShouldClose(window, true)
end
if get(g_keys, GLFW.KEY_P, false)
@Threads.spawn load_play(joinpath("..", "common_data", "die.wav"))
g_keys[GLFW.KEY_P] = false
end
if get(g_keys, GLFW.KEY_K, false)
@Threads.spawn play(sound_die)
g_keys[GLFW.KEY_K] = false
end
if get(g_keys, GLFW.KEY_O, false)
@Threads.spawn load_play(joinpath("..", "common_data", "eat.wav"))
g_keys[GLFW.KEY_O] = false
end
if get(g_keys, GLFW.KEY_L, false)
@Threads.spawn play(sound_eat)
g_keys[GLFW.KEY_L] = false
end
if get(g_keys, GLFW.KEY_SPACE, false)
println("SPACE!")
end
end
GLFW.DestroyWindow(window)
Can GLFW somehow change how threads can access their data?