beep
beep copied to clipboard
Method for closing the context and hence releasing the device
The audio device never releases after calling speaker.Init()
I suggest to extract the following code from Init():
if player != nil {
done <- struct{}{}
player.Close()
context.Close()
}
to a separated public method.
What do you think?
BTW, great work! This pkg is the cornerstone of a project I'm working on
Hi! Thanks for the suggestion! The usefulness of this suggestion depends on whether it is actually necessary to close the device before the program exits.
I'm not sure about that, but I'll try and research when I get home. If you research first, that would help too :)
And I'm glad you find this package useful :). Btw, don't call speaker.Init every time you play something. It's likely that you don't do it, I just see so much of it on GitHub that I decided to tell whoever I can :D
Hi Michal,
I've got this idea because my app runs on the same machine along with a Spotify client and after calling speaker.Init(), the device get locked for my process and never releases even after stream ends. It's only when I close the process that Spotify is able to use the device again.
So I've searched the code for the cause and I've figured that only when calling `context.close()', the driver (alsa in my case) releases the sound device.
But if only speaker.Init() opens the context again and one should not call it multiple times than maybe speaker.Play() should assert that context is opened instead of speaker.Init() and I still need speaker.Close() or something like that to release the device by calling context.Close()
I hope that I talk sense. Otherwise, please guide me through to a solution and I'll do whatever needed. I'll share my still pre-mature project soon, btw.
Thanks!
Hm, that's pretty interesting. Beep uses Oto for accessing audio hardware and I made the ALSA driver for it, so I'm familiar with it :D. The ALSA driver asks for the "default" device, which should mean that it gets supplied a virtual device that gets mixed with the sounds from all other applications. In other words: it shouldn't block audio from other apps.
I'm still not home, so I can't test whether that actually works, but I'll do that ASAP when I get there.
But other than that, yeah, this function would probably have its uses in some specific settings. Would you be up for adding it yourself in a PR? ;)
Sure. With pleasure.
Although you are probably right about my usage of alsa device on the machine.
Thanks! Make sure to document it that it's not necessary to call the function at all, it's there just for the special purposes of releasing a device if your system doesn't do proper mixing.
👍
@faiface @avivklas I can confirm that I am seeing the same audio channel blocking issue on Linux (Linux 5.3.0-7648-generic).
Here's an example where I'm using fuser to determine user-space processes using /dev/snd/* and I'm running Spotify
USER PID ACCESS COMMAND
/dev/snd/controlC0: yelkalay 2321 F.... pulseaudio
/dev/snd/controlC1: yelkalay 2321 F.... pulseaudio
/dev/snd/pcmC0D0p: yelkalay 2321 F...m pulseaudio
F in the third line refer to the device being open for writing and m a memory mapped file/shared lib.
When I run my Beep/Go binary called soundmachine I get the following:
USER PID ACCESS COMMAND
/dev/snd/controlC0: yelkalay 2321 F.... pulseaudio
yelkalay 8960 F.... soundmachine
/dev/snd/controlC1: yelkalay 2321 F.... pulseaudio
/dev/snd/pcmC0D0p: yelkalay 8960 F...m soundmachine
/dev/snd/timer: yelkalay 8960 f.... soundmachine
Should Beep/Oto be keeping /dev/snd/timer open? The f access state on the last line of that previous example refers to an "open" file - which presumably is blocked from being used by any other process. A post in the ALSA mailing list states that in general userspace applications shouldn't be doing anything to /dev/snd/timer
Haven't had time to dig through code to see why this happening but perhaps this can clue both of you into why this is happening.
Looks like @avivklas added speaker.Close() in 641d0bf5c48b1888225b21de45d612399f05e17b which resolves this issue.
Any chance we can add another tutorial to the Wiki briefly going over why this is an issue and how to get around it?
In this case every time I call speaker.Close() I'll need to reinitialize the player via speaker.Init()
This issue is somewhat related to https://github.com/hajimehoshi/oto/issues/54