internal async Task <MediaStreamSample> GetNextSampleAsync(CancellationToken cancelToken)
        {
            if (sampleProvider == null)
            {
                sampleProvider = AudioProviderFactory.GetAudioProvider(shoutcastStream.AudioInfo.AudioFormat);
            }

            //todo check for internet connection and socket connection as well

            cancelToken.ThrowIfCancellationRequested();

            MediaStreamSample sample = null;
            uint sampleLength        = 0;


            //if metadataPos is less than sampleSize away from metadataInt
            if (shoutcastStream.serverSettings.RequestSongMetdata && (shoutcastStream.metadataInt - metadataPos <= sampleProvider.GetSampleSize() &&
                                                                      shoutcastStream.metadataInt - metadataPos > 0))
            {
                //parse part of the frame.
                byte[] partialFrame = new byte[shoutcastStream.metadataInt - metadataPos];
                var    read         = await socket.LoadAsync(shoutcastStream.metadataInt - metadataPos);

                if (read == 0 || read < partialFrame.Length)
                {
                    //disconnected.
                    throw new ShoutcastDisconnectionException();
                }

                await socket.ReadBytesAsync(partialFrame);

                metadataPos += shoutcastStream.metadataInt - metadataPos;
                Tuple <MediaStreamSample, uint> result = await sampleProvider.ParseSampleAsync(this, socket, partial : true, partialBytes : partialFrame).ConfigureAwait(false);

                sample       = result.Item1;
                sampleLength = result.Item2;

                cancelToken.ThrowIfCancellationRequested();
            }
            else
            {
                await HandleMetadataAsync(cancelToken);

                Tuple <MediaStreamSample, uint> result = await sampleProvider.ParseSampleAsync(this, socket).ConfigureAwait(false);

                sample       = result.Item1;
                sampleLength = result.Item2;

                cancelToken.ThrowIfCancellationRequested();

                if (sample == null || sampleLength == 0) //OLD bug: on RELEASE builds, sample.Buffer causes the app to die due to a possible .NET Native bug
                {
                    //MediaStreamSource.NotifyError(MediaStreamSourceErrorStatus.DecodeError);
                    //deferral.Complete();
                    //return;
                    return(null);
                }
                else
                {
                    if (shoutcastStream.serverSettings.RequestSongMetdata)
                    {
                        metadataPos += sampleLength;
                    }
                }
            }

            return(sample);
        }