Ejemplo n.º 1
0
        /// <summary>
        /// Starts a loop. The playback must be activated.
        /// </summary>
        /// <param name="loop">Loop to apply</param>
        public void StartLoop(Loop loop)
        {
            if (Playlist == null || Playlist.CurrentItem == null || Playlist.CurrentItem.Channel == null)
                return;

            if (loop.Segments.Count == 0)
                return;

            long positionBytes = loop.Segments[_currentSegmentIndex].PositionBytes;
            long nextPositionBytes = 0;
            var segment = loop.GetNextSegmentForPlayback(_currentSegmentIndex);
            if (segment != null)
                nextPositionBytes = segment.PositionBytes;

            if (Playlist.CurrentItem.AudioFile.FileType == AudioFileFormat.FLAC && Playlist.CurrentItem.AudioFile.SampleRate > 44100)
            {
                // Divide by 1.5 (I don't really know why, but this works for 48000Hz and 96000Hz. Maybe a bug in BASS with FLAC files?)
                positionBytes = (long)((float)positionBytes / 1.5f);
            }

#if !IOS && !ANDROID
            if (_device.DriverType == DriverType.WASAPI)
            {
                BassWasapi.BASS_WASAPI_Stop(true);
                BassWasapi.BASS_WASAPI_Start();
            }
#endif

            // Remove any sync callback
            RemoveSyncCallbacks();

            // Get file length
            long length = Playlist.CurrentItem.Channel.GetLength();
            _mixerChannel.Lock(true);

            // Set position for the decode channel (needs to be in floating point)
            Playlist.CurrentItem.Channel.SetPosition(positionBytes * 2);
            _fxChannel.SetPosition(0); // Clear buffer
            _mixerChannel.SetPosition(0);

            // Set sync
            _syncProcLoop = new PlayerSyncProc();
#if IOS
            _syncProcLoop.SyncProc = new SYNCPROC(LoopSyncProcIOS);
#else
            _syncProcLoop.SyncProc = new SYNCPROC(LoopSyncProc);
#endif

            if (_mixerChannel is MixerChannel)
            {
                var mixerChannel = _mixerChannel as MixerChannel;
                _syncProcLoop.Handle = mixerChannel.SetSync(_fxChannel.Handle, BASSSync.BASS_SYNC_POS | BASSSync.BASS_SYNC_MIXTIME, (nextPositionBytes - positionBytes) * 2, _syncProcLoop.SyncProc);
            }
            else
            {
                _syncProcLoop.Handle = _mixerChannel.SetSync(BASSSync.BASS_SYNC_POS | BASSSync.BASS_SYNC_MIXTIME, (nextPositionBytes - positionBytes) * 2, _syncProcLoop.SyncProc);
            }

            // Set new callback (length already in floating point)
            SetSyncCallback((length - (nextPositionBytes * 2))); // + buffered));

            // Set offset position (for calulating current position)
            _positionOffset = positionBytes;
            _mixerChannel.Lock(false);
            _currentLoop = loop;
        }