protected override void Play(Playback play) { int channel = -1; bool setChannel = false; if (!play.VirtualChannel.Equals(Sound.GLOBAL_VIRTUAL_CHANNEL)) { if (channels.TryGetValue(play.VirtualChannel, out int vc)) { SDL_mixer.Mix_HaltChannel(vc); channels.Remove(play.VirtualChannel); } setChannel = true; } channel = SDL_mixer.Mix_PlayChannel(-1, play.Sound.GetChunk(), play.Loop ? -1 : 0); if (channel == -1) { Logger.Error("Sound", $"Failed to play sound '{play.Sound}', no more channels available"); } else { SDL_mixer.Mix_ChannelFinished(channelFinished); Logger.Info("Sound", $"Playing sound '{play.Sound}' on channel {channel} ({play.VirtualChannel})"); } byte dist; if (play.Location.X != 0 || play.Location.Y != 0) { float v = 255.0f * (CalcDist(lastPos, play.Location) / soundFallOff); v = Math.Min(Math.Max(v, 0.0f), 255.0f); dist = (byte)v; } else { dist = 0; } SetChannelPosition(channel, 0, dist); if (setChannel) { channels[play.VirtualChannel] = channel; } playback[channel] = play; }