0

i have a "Player" class, which is supposed to manage my global music player. This also works so far. The class is at the bottom, if you have any suggestions for improvement, feel free to give it to us.

I want to start a second song while the current song ends. So a FadeIn into the next song and a FadeOut from the current song, which makes the song quieter.

My approach at the moment is that one song is running in the "waveOutDevice1" object and the second one is waiting in the second object. And as soon as the current song is about to end, the second WavePlayer starts. But I don't know how I can react to it, as soon as the current song is about to end.

Do you have an idea or suggestions? With kind regards

my Player class:

public class Player
{
    #region Properties, Fields
    private IWavePlayer waveOutDevice1;
    private IWavePlayer waveOutDevice2;
    private AudioFileReader fileReader1;
    private AudioFileReader fileReader2;

    public AudioFile CurrentSong { get; private set; }
    public Playlist CurrentPlaylist { get; private set; }

    public List<AudioFile> lstPastSongs { get; private set; }

    public List<AudioFile> lstNextSongs { get; set; }

    public PlaybackState PlaybackState { get; private set; }

    public bool Muted { get; private set; }

    private float OldVolume = 0.0f;
    #endregion

    public Player()
    {
        this.lstNextSongs = new List<AudioFile>();
        this.lstPastSongs = new List<AudioFile>();
    }

    #region Methods
    public void Play(int index)
    {
        if (this.lstNextSongs.Count > 0 && index >= 0 && index < this.lstNextSongs.Count)
        {
            this.ResetFileReader();
            this.CurrentSong = this.lstNextSongs[index];
            this.CurrentPlaylist = this.CurrentSong.Playlist;
            this.lstNextSongs.RemoveAt(index);
            this.fileReader1 = new AudioFileReader(this.CurrentSong.Path);
            this.waveOutDevice1 = new WaveOut();
            this.waveOutDevice1.PlaybackStopped += WaveOutDevice1_PlaybackStopped;

            this.waveOutDevice1.Init(this.fileReader1);
            this.PlaybackState = PlaybackState.Playing;
            this.waveOutDevice1.Play();
        }
    }

    private void WaveOutDevice1_PlaybackStopped(object sender, StoppedEventArgs e)
    {
        this.Next();
    }

    private void ResetFileReader()
    {
        if (this.fileReader1 != null)
        {                
            this.fileReader1.Dispose();
            this.fileReader1 = null;
        }
        if (this.fileReader2 != null)
        {
            this.fileReader2.Dispose();
            this.fileReader2 = null;
        }
        if(this.waveOutDevice1 != null)
        {
            this.waveOutDevice1.Dispose();
            this.waveOutDevice1 = null;
        }
        if(this.waveOutDevice2 != null)
        {
            this.waveOutDevice2.Dispose();
            this.waveOutDevice2 = null;
        }
    }

    public void Pause()
    {
        if(this.waveOutDevice1 != null)
            if (this.waveOutDevice1.PlaybackState == PlaybackState.Playing)
                this.waveOutDevice1.Pause();
        if(this.waveOutDevice2 != null)
            if (this.waveOutDevice2.PlaybackState == PlaybackState.Playing)
                this.waveOutDevice2.Pause();
        this.PlaybackState = PlaybackState.Paused;
    }

    public void Continue()
    {
        if (this.waveOutDevice1 != null)
            if (this.waveOutDevice1.PlaybackState == PlaybackState.Paused)
                this.waveOutDevice1.Play();
        if (this.waveOutDevice2 != null)
            if (this.waveOutDevice2.PlaybackState == PlaybackState.Paused)
                this.waveOutDevice2.Play();
        this.PlaybackState = PlaybackState.Playing;
    }

    public void Next()
    {
        if(this.lstNextSongs.Count > 0)
        {
            if (this.CurrentSong != null)
                this.lstPastSongs.Add(this.CurrentSong);
            if (GlobalSettings.Shuffle)
            {
                System.Random random = new System.Random();
                int randomNumber = random.Next(0, this.lstNextSongs.Count - 1);
                this.Play(randomNumber);
            }
            else
                this.Play(0);
        }
        else
        {
            if(GlobalSettings.Replay)
                if(GlobalSettings.CurrentPlaylist != null)
                    for (int i = 0; i < GlobalSettings.CurrentPlaylist.panPlaylist.SongPlaylist.NumberOfSongs; i++)
                        this.lstNextSongs.AddRange(GlobalSettings.CurrentPlaylist.panPlaylist.SongPlaylist.AllSongs);
        }
    }

    public void Previous()
    {
        if(this.CurrentSong == null)
        {
            if(this.lstPastSongs.Count > 0)
            {
                this.lstNextSongs.Insert(0, this.lstPastSongs[this.lstPastSongs.Count - 1]);
                this.lstPastSongs.RemoveAt(this.lstPastSongs.Count - 1);
                this.Play(0);
            }
        }
        else
        {
            if(this.fileReader1 != null)
                this._Previous(this.waveOutDevice1, this.fileReader1);
            else if(this.fileReader2 != null)
                this._Previous(this.waveOutDevice2, this.fileReader2);
        }
    }

    private void _Previous(IWavePlayer waveOutDevice, AudioFileReader fileReader)
    {
        if (fileReader.CurrentTime.Seconds >= 10 || this.lstPastSongs.Count == 0)
        {
            waveOutDevice.Pause();
            fileReader.CurrentTime = new System.TimeSpan(0, 0, 0);
            waveOutDevice.Play();
        }
        else
        {
            this.lstNextSongs.Insert(0, this.CurrentSong);
            this.lstNextSongs.Insert(0, this.lstPastSongs[this.lstPastSongs.Count - 1]);
            this.lstPastSongs.RemoveAt(this.lstPastSongs.Count - 1);
            this.Play(0);
        }
    }

    public void SetVolume(int Volume)
    {
        if (Volume > -1 && Volume < 101)
        {

            float vol = (float)Volume / 100;
            if (this.fileReader1 != null)
                this.fileReader1.Volume = vol;
            if (this.fileReader2 != null)
                this.fileReader2.Volume = vol;
            this.Muted = false;
        }
    }

    public void Mute()
    {
        if(this.Muted)
        {
            if(this.fileReader1 != null)
            {
                this.fileReader1.Volume = this.OldVolume;
                this.Muted = false;
            }
            else if(this.fileReader2 != null)
            {
                this.fileReader2.Volume = this.OldVolume;
                this.Muted = false;
            }
        }
        else
        {
            this.Muted = true;
            if(this.fileReader1 != null)
            {
                this.OldVolume = this.fileReader1.Volume;
                this.fileReader1.Volume = 0;
            }
            else if(this.fileReader2 != null)
            {
                this.OldVolume = this.fileReader2.Volume;
                this.fileReader2.Volume = 0;
            }
        }
    }
    #endregion
}
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178

2 Answers2

0

If you can get the duration of the song when it starts playing, you can set a timer for duration - fadeInTime and start your fade when the timer fires.

theGleep
  • 1,179
  • 8
  • 14
0

Another approach is to use a single wave out device and MixingSampleProvider to add in the second song as a new input to the mixer as the first one is ending. You can do this by creating your own wrapper ISampleProvider whose Read method can keep accurate track of where you are up to.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • i´ve been sitting on a transition for a couple of hours now, but i cant seem to get it right. I also watched the project "MusicToCodeBy", the music runs at the same time, but songs with transitions one after the other, i cant get there. Do u have an example for me? – ExclusivAtom Oct 08 '17 at 14:49
  • I also watched the class "https://stackoverflow.com/questions/9468083/fading-sound-in-out-using-naudio" But the class didn't get me anywhere. – ExclusivAtom Oct 08 '17 at 15:03