I have a JavaFX Tetris game that uses the MediaPlayer class to play music and sound effects. Specifically, in my SoundPlayer class that handles all audio, I load in the game's .wav files when game is started, and iterate each file, creating a Media object for each one, and then a MediaPlayer object for each Media object. The MediaPlayers, one for each sound, are stored in an array for future playback using the class's playSound method that accepts an integer argument that indicates the index of the MediaPlayer that corresponds to the desired sound effect. It works perfectly on windows and mac, but on my laptop that runs popOS, while it technically works, it has the following issues:
when the game launches, some sounds will play correctly, but after a few times of playing, the playback volume will become so quiet that you can barely hear it, even though the actual volume attribute of the MediaPlayer does not change
some sounds do not play the entire sound, only playing part of it.
The background music and most sounds work correctly, but for some, these issues occur. Here is my code for playing a sound when triggered by the game:
public void playSound(int index)
{
MediaPlayer mediaPlayer = mediaPlayerList[index];
mediaPlayer.stop();
mediaPlayer.seek(Duration.ZERO);
mediaPlayer.play();
}
This works perfectly on my other computers, but I only have this issue on my popOS laptop. Does anyone know if this is a Linux issue with the way Java.sound works, or if perhaps it is an issue with my laptop hardware? I have tried configuring the java.sound.config file to no avail and am at a loss.
As stated above, I have tried looking up fixes for java.sound config file and nothing I have found seems to work, so I am starting to think it might be an issue with my laptop, but I thought I would ask to see if anyone is aware of anything I may have missed. I am a CS student currently and this is my first attempt at a project using Java for audio playback, so I am fairly ignorant on how it works at a low level. Any help would be greatly appreciated if anyone is aware of any fixes or potential causes for this. Also, my audio driver is up to date and all other audio playback i have tried on this laptop works fine.
Initially, I was using the Java Sound API's Clip class to playback sound effects, and the audio playback worked correctly with Clips, but my issue with Clips was that when sounds were rapidly triggered by user input, as is frequently the case in my game, I found that audio skipped somewhat frequently likely due to my limited knowledge of multi-threading, so I decided to try out JavaFX's MediaPlayer instead, which is far more responsive and optimized, and as I said, works perfectly on my Windows machine and mac.....it is only having this issue on my Linux laptop. If it is any help, I am using openjdk-17....I don't know if this is an issue specifically with open-jdk vs oracle jdk, or something of that nature.
The open-source AudioCue library (obtainable via Maven) is basically a Clip
that has been written to support multi-threading. It should work for you, and is free to use.
There are multiple good points in the comments (which are supposed to be for asking questions and clarifications of the original post, afaik) that seem to me could well be listed as "answers. My answer here will duplicate some of those points.
For short cues, prefer a class which is just loaded one time only and can played back multiple times directly from memory: Clip
, AudioClip
, to classes which require reading from files or other forms of streaming: SourceDataLine
, MediaPlayer
.
The nice thing about AudioClip
is that it does support concurrent playback, unlike Clip
or the streaming playback methods. So, you can take the same AudioClip
and play it multiple times without first calling a stop
method and repositioning its playback position. Each iteration should play through to the end.
There was a time when some Linux operating systems would only allow a single sound source to play at a given moment, but that was quite a while ago. IDK if that might be the issue for the particular OS configuration you are testing. If it is, going back to the AudioCue
library I mentioned at the start, it has a class, AudioMixer
, for funneling all the sound cues into a single output line which would be a workaround for that situation.