2929import javax .sound .sampled .AudioSystem ;
3030import java .io .InputStream ;
3131import java .net .URL ;
32+ import java .util .ArrayList ;
3233import java .util .HashMap ;
3334import java .util .List ;
3435import java .util .Map ;
35- import java .util .concurrent .CopyOnWriteArrayList ;
3636
3737public class BassSoundSystem extends SoundSystem {
3838
@@ -51,11 +51,15 @@ public static BassSoundSystem createPlayback(final int maxSounds) {
5151
5252
5353 private final Map <String , Integer > soundSamples = new HashMap <>();
54- private final List <Integer > playingChannels = new CopyOnWriteArrayList <>();
54+ private final List <Integer > playingChannels = new ArrayList <>();
5555 private Thread shutdownHook ;
5656
5757 @ SuppressWarnings ("FieldCanBeLocal" )
58- private final BassLibrary .SYNCPROC channelFreeSync = (handle , channel , data , user ) -> this .playingChannels .remove ((Integer ) channel );
58+ private final BassLibrary .SYNCPROC channelFreeSync = (handle , channel , data , user ) -> {
59+ synchronized (this ) {
60+ this .playingChannels .remove ((Integer ) channel );
61+ }
62+ };
5963
6064 private BassSoundSystem (final int maxSounds ) {
6165 super (maxSounds );
@@ -93,14 +97,12 @@ private BassSoundSystem(final int maxSounds) {
9397 }
9498
9599 @ Override
96- public void playSound (final String sound , final float pitch , final float volume , final float panning ) {
100+ public synchronized void playSound (final String sound , final float pitch , final float volume , final float panning ) {
97101 if (!this .soundSamples .containsKey (sound )) return ;
98102
99103 if (this .playingChannels .size () >= this .maxSounds ) {
100104 if (!BassLibrary .INSTANCE .BASS_ChannelFree (this .playingChannels .remove (0 ))) {
101- if (BassLibrary .INSTANCE .BASS_ErrorGetCode () != BassLibrary .BASS_ERROR_HANDLE ) {
102- this .checkError ("Could not free audio channel" );
103- }
105+ this .checkError ("Could not free audio channel" , BassLibrary .BASS_ERROR_HANDLE );
104106 }
105107 }
106108
@@ -126,15 +128,13 @@ public void playSound(final String sound, final float pitch, final float volume,
126128 this .checkError ("Could not set audio channel end sync" );
127129 }
128130 if (!BassLibrary .INSTANCE .BASS_ChannelStart (channel )) {
129- if (BassLibrary .INSTANCE .BASS_ErrorGetCode () != BassLibrary .BASS_ERROR_START ) {
130- this .checkError ("Could not play audio channel" );
131- }
131+ this .checkError ("Could not play audio channel" );
132132 }
133133 this .playingChannels .add (channel );
134134 }
135135
136136 @ Override
137- public void stopSounds () {
137+ public synchronized void stopSounds () {
138138 if (!BassLibrary .INSTANCE .BASS_Stop ()) {
139139 this .checkError ("Could not stop sound system" );
140140 }
@@ -145,7 +145,7 @@ public void stopSounds() {
145145 }
146146
147147 @ Override
148- public void close () {
148+ public synchronized void close () {
149149 if (this .shutdownHook != null ) {
150150 Runtime .getRuntime ().removeShutdownHook (this .shutdownHook );
151151 this .shutdownHook = null ;
@@ -159,12 +159,12 @@ public void close() {
159159 }
160160
161161 @ Override
162- public String getStatusLine () {
162+ public synchronized String getStatusLine () {
163163 return "Sounds: " + this .playingChannels .size () + " / " + this .maxSounds + ", BASS CPU Load: " + (int ) BassLibrary .INSTANCE .BASS_GetCPU () + "%" ;
164164 }
165165
166166 @ Override
167- public void setMasterVolume (final float volume ) {
167+ public synchronized void setMasterVolume (final float volume ) {
168168 if (!BassLibrary .INSTANCE .BASS_SetConfig (BassLibrary .BASS_CONFIG_GVOL_STREAM , (int ) (volume * 10000 ))) {
169169 this .checkError ("Could not set master volume" );
170170 }
@@ -192,9 +192,14 @@ private int loadAudioFile(final InputStream inputStream) {
192192 }
193193 }
194194
195- private void checkError (final String message ) {
195+ private void checkError (final String message , final int ... allowedErrors ) {
196196 final int error = BassLibrary .INSTANCE .BASS_ErrorGetCode ();
197197 if (error != BassLibrary .BASS_OK ) {
198+ for (int ignoreError : allowedErrors ) {
199+ if (error == ignoreError ) {
200+ return ;
201+ }
202+ }
198203 throw new RuntimeException ("BASS error: " + message + " (" + error + ")" );
199204 }
200205 }
0 commit comments