I’ve also tried removing the channel.send(nil), and in that case the sound was played. However, the whole program will stuck at the fiber and done will never be printed.
Try changing Nil to Int32 and sending 1 instead? I can’t remember where, but I remember reading somewhere that a channel with nil is indistinguishable from a closed channel, which might be why receive immediately passes.
I might be wrong though, on my phone and can’t verify :P
In my opinion, the sound is played ‘separately’ from the main thread.
But, when the done is printed, the program exits, and sound playing is ‘interupted’.
So there is a message saying AL lib: (EE) alc_cleanup: 1 device not closed
If nothing (the nil) is not sent into the channel like this:
require "crsfml/audio"
channel = Channel(Nil).new
spawn do
sound = SF::Sound.new SF::SoundBuffer.from_file "/home/freeze-dolphin/Documents/arcaea_4.0.255c_assets/app-data/story/vn/res/glassRain.ogg"
sound.play
# channel.send(nil)
end
channel.receive
puts "done"
The channel will never receive and the sound is played correctly. And the program will stuck at channel.receive, done won’t be printed.
When the music is over, done is not printed as well. But this time if you type ^C to end the program, no AL lib: (EE) alc_cleanup: 1 device not closed will be printed.
That’s not problem with Crystal concurrency, but what you are doing is invoking async operation which runs its own thread (external to crystal), so using a spawn doesn’t make any difference.
you should be invoking Sound#status in a loop with some delay and when you library is done with playing, you can continue with your current logic of sending some value to Channel.
so pseudo code like below
......
loop do
break if sound.status == SoundSource::Status::Stopped
sleep some_duration
end
........